sailfish/docs/en/site/search/search_index.json

1 line
20 KiB
JSON

{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Welcome to Sailfish Documentation! Sailfish is a simple, small, and extremely fast template engine for Rust. This documentation guides you how to get started with sailfish. This documentation mainly focuses on concepts of the library, general usage, and template syntax. If you've read this documentation and need more specific information, you might want to read the sailfish API docs . Why Sailfish ? There are many libraries for template rendering in Rust. Among those libraries, sailfish aims at rapid development and rapid rendering . Sailfish has many features that other libraries might not support. Write a Rust code directly inside templates, supporting many Rust syntax (struct definition, closure, macro invocation, etc.) Built-in filters Minimal dependencies (<15 crates in total) Extremely fast (See benchmarks ) Template rendering is always type-safe because templates are statically compiled. Syntax highlighting ( vscode , vim ) Upcoming features Since sailfish is on early stage of development, there are many upcoming features that is not supported yet. You can find many RFC s in my repository. These RFC include: Template trait (which does not consume itself) Template inheritance (block, partials, etc.) If you have any idea about them or want to implement that feature, please send a comment on the issue! License Copyright \u00a9 2020 Ryohei Machida This project is MIT licensed","title":"Welcome"},{"location":"#welcome-to-sailfish-documentation","text":"Sailfish is a simple, small, and extremely fast template engine for Rust. This documentation guides you how to get started with sailfish. This documentation mainly focuses on concepts of the library, general usage, and template syntax. If you've read this documentation and need more specific information, you might want to read the sailfish API docs .","title":"Welcome to Sailfish Documentation!"},{"location":"#why-sailfish","text":"There are many libraries for template rendering in Rust. Among those libraries, sailfish aims at rapid development and rapid rendering . Sailfish has many features that other libraries might not support. Write a Rust code directly inside templates, supporting many Rust syntax (struct definition, closure, macro invocation, etc.) Built-in filters Minimal dependencies (<15 crates in total) Extremely fast (See benchmarks ) Template rendering is always type-safe because templates are statically compiled. Syntax highlighting ( vscode , vim )","title":"Why Sailfish ?"},{"location":"#upcoming-features","text":"Since sailfish is on early stage of development, there are many upcoming features that is not supported yet. You can find many RFC s in my repository. These RFC include: Template trait (which does not consume itself) Template inheritance (block, partials, etc.) If you have any idea about them or want to implement that feature, please send a comment on the issue!","title":"Upcoming features"},{"location":"#license","text":"Copyright \u00a9 2020 Ryohei Machida This project is MIT licensed","title":"License"},{"location":"getting-started/","text":"Getting Started Prepare the template file Create a new directory named templates in the same directory as Cargo.toml . Copy the following contents and paste it to a new file named templates/hello.stpl . < html > < body > <% for msg in & messages { %> < div > <%= msg %> </ div > <% } %> </ body > </ html > Now your project structure should be like this: Cargo.toml src/ (Source files) templates/ hello.stpl Render the template Import the sailfish crates: use sailfish :: TemplateOnce ; Define the template struct to be rendered: #[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait #[template(path = \"hello.stpl\" )] // specify the path to template struct HelloTemplate { // data to be passed to the template messages : Vec < String > , } Render the data with render_once() method. fn main () { let ctx = HelloTemplate { messages : vec ! [ String :: from ( \"foo\" ), String :: from ( \"bar\" )], }; // Now render templates with given data println! ( \"{}\" , ctx . render_once (). unwrap ()); } That's it! You can find more examples in the example directory in the sailfish repository.","title":"Getting Started"},{"location":"getting-started/#getting-started","text":"","title":"Getting Started"},{"location":"getting-started/#prepare-the-template-file","text":"Create a new directory named templates in the same directory as Cargo.toml . Copy the following contents and paste it to a new file named templates/hello.stpl . < html > < body > <% for msg in & messages { %> < div > <%= msg %> </ div > <% } %> </ body > </ html > Now your project structure should be like this: Cargo.toml src/ (Source files) templates/ hello.stpl","title":"Prepare the template file"},{"location":"getting-started/#render-the-template","text":"Import the sailfish crates: use sailfish :: TemplateOnce ; Define the template struct to be rendered: #[derive(TemplateOnce)] // automatically implement `TemplateOnce` trait #[template(path = \"hello.stpl\" )] // specify the path to template struct HelloTemplate { // data to be passed to the template messages : Vec < String > , } Render the data with render_once() method. fn main () { let ctx = HelloTemplate { messages : vec ! [ String :: from ( \"foo\" ), String :: from ( \"bar\" )], }; // Now render templates with given data println! ( \"{}\" , ctx . render_once (). unwrap ()); } That's it! You can find more examples in the example directory in the sailfish repository.","title":"Render the template"},{"location":"installation/","text":"Installation In order to use sailfish templates, you have add two dependencies in your Cargo.toml . [dependencies] sailfish = \"0.5.0\" Feature Flags Sailfish accepts the following feature flags Feature Description derive enable derive macros (enabled by default) json enable json filter perf-inline Add more #[inline] attributes. This may improve rendering performance, but generates a bit larger binary (enabled by default)","title":"Installation"},{"location":"installation/#installation","text":"In order to use sailfish templates, you have add two dependencies in your Cargo.toml . [dependencies] sailfish = \"0.5.0\"","title":"Installation"},{"location":"installation/#feature-flags","text":"Sailfish accepts the following feature flags Feature Description derive enable derive macros (enabled by default) json enable json filter perf-inline Add more #[inline] attributes. This may improve rendering performance, but generates a bit larger binary (enabled by default)","title":"Feature Flags"},{"location":"options/","text":"Configuration Derive options You can control the rendering behaviour via template attribute. #[derive(TemplateOnce)] #[template(path = \"template.stpl\" , escape = false)] struct TemplateStruct { .. . } template attribute accepts the following options. path : path to template file. This options is always required. escape : Enable HTML escaping (default: true ) delimiter : Replace the '%' character used for the tag delimiter (default: '%') rm_whitespace : try to strip whitespaces as much as possible without collapsing HTML structure (default: false ). This option might not work correctly if your templates have inline script tag. You can split the options into multiple template attributes. #[derive(TemplateOnce)] #[template(path = \"template.stpl\" )] #[template(delimiter = '?')] #[template(rm_whitespace = true)] struct TemplateStruct { .. . } Configuration file Sailfish allows global and local configuration in a file named sailfish.toml . Sailfish looks for this file in same directory as Cargo.toml and all parent directories. If, for example, Cargo.toml exists in /foo/bar/baz directory, then the following configuration files would be scanned in this order. /foo/bar/baz/sailfish.toml /foo/bar/sailfish.toml /foo/sailfish.toml /sailfish.toml If a key is specified in multiple configuration files, the value in the deeper directory takes precedence over ancestor directories. If a key is specified in both configuration file and derive options, then the value specified in the derive options takes precedence over the configuration file. Configuration file format Configuration files are written in the TOML 0.5 format. Here is the default configuration: template_dirs = [ \"templates\" ] escape = true delimiter = \"%\" [optimizations] rm_whitespace = false You can specify another template directory in template_dirs option. Other options are same as derive options. You can also embed environment variables in template_dirs paths by wrapping the variable name with ${ and } like ${MY_ENV_VAR} : template_dirs = [ \"${CI}/path/to/project/${MYVAR}/templates\" ]","title":"Configuration"},{"location":"options/#configuration","text":"","title":"Configuration"},{"location":"options/#derive-options","text":"You can control the rendering behaviour via template attribute. #[derive(TemplateOnce)] #[template(path = \"template.stpl\" , escape = false)] struct TemplateStruct { .. . } template attribute accepts the following options. path : path to template file. This options is always required. escape : Enable HTML escaping (default: true ) delimiter : Replace the '%' character used for the tag delimiter (default: '%') rm_whitespace : try to strip whitespaces as much as possible without collapsing HTML structure (default: false ). This option might not work correctly if your templates have inline script tag. You can split the options into multiple template attributes. #[derive(TemplateOnce)] #[template(path = \"template.stpl\" )] #[template(delimiter = '?')] #[template(rm_whitespace = true)] struct TemplateStruct { .. . }","title":"Derive options"},{"location":"options/#configuration-file","text":"Sailfish allows global and local configuration in a file named sailfish.toml . Sailfish looks for this file in same directory as Cargo.toml and all parent directories. If, for example, Cargo.toml exists in /foo/bar/baz directory, then the following configuration files would be scanned in this order. /foo/bar/baz/sailfish.toml /foo/bar/sailfish.toml /foo/sailfish.toml /sailfish.toml If a key is specified in multiple configuration files, the value in the deeper directory takes precedence over ancestor directories. If a key is specified in both configuration file and derive options, then the value specified in the derive options takes precedence over the configuration file.","title":"Configuration file"},{"location":"options/#configuration-file-format","text":"Configuration files are written in the TOML 0.5 format. Here is the default configuration: template_dirs = [ \"templates\" ] escape = true delimiter = \"%\" [optimizations] rm_whitespace = false You can specify another template directory in template_dirs option. Other options are same as derive options. You can also embed environment variables in template_dirs paths by wrapping the variable name with ${ and } like ${MY_ENV_VAR} : template_dirs = [ \"${CI}/path/to/project/${MYVAR}/templates\" ]","title":"Configuration file format"},{"location":"syntax/filters/","text":"Filters Filters are used to format the rendered contents. Example: Template Result message: <%= \"foo \\n bar\" | dbg %> message: &quot; foo\\nbar &quot; Note Since dbg filter accepts <T: std::fmt::Debug> types, that type isn't required to implement Render trait. That means you can pass the type which doesn't implement Render trait. Syntax Apply filter and HTML escaping <%= expression | filter %> Apply filter only <%- expression | filter %> Built-In Filters Built-In filters can be found in sailfish::runtime::filter module.","title":"Filters"},{"location":"syntax/filters/#filters","text":"Filters are used to format the rendered contents. Example: Template Result message: <%= \"foo \\n bar\" | dbg %> message: &quot; foo\\nbar &quot; Note Since dbg filter accepts <T: std::fmt::Debug> types, that type isn't required to implement Render trait. That means you can pass the type which doesn't implement Render trait.","title":"Filters"},{"location":"syntax/filters/#syntax","text":"Apply filter and HTML escaping <%= expression | filter %> Apply filter only <%- expression | filter %>","title":"Syntax"},{"location":"syntax/filters/#built-in-filters","text":"Built-In filters can be found in sailfish::runtime::filter module.","title":"Built-In Filters"},{"location":"syntax/includes/","text":"Includes You can also include another template inside templates using include! macro. Consider the following example. templates/header.stpl < meta charset = \"UTF-8\" > < meta name = \"viewport\" content = \"width=device-width, initial-scale=1.0\" /> < meta name = \"format-detection\" content = \"telephone=no\" > < link rel = \"icon\" type = \"image/x-icon\" href = \"favicon.ico\" > templates/index.stpl < html > < head > <% include ! ( \"./header.stpl\" ); %> </ head > < body > Main contents </ body > </ html > Then you can see the header.stpl is embedded in the output. < html > < head > < meta charset = \"UTF-8\" > < meta name = \"viewport\" content = \"width=device-width, initial-scale=1.0\" /> < meta name = \"format-detection\" content = \"telephone=no\" > < link rel = \"icon\" type = \"image/x-icon\" href = \"favicon.ico\" > </ head > < body > Main contents </ body > </ html > Like std::include! macro in Rust, the provided path is interpreted as a relative path to the current template file. Warning The path format is platform-specific. You must use \\ character as a separator on Windows.","title":"Includes"},{"location":"syntax/includes/#includes","text":"You can also include another template inside templates using include! macro. Consider the following example. templates/header.stpl < meta charset = \"UTF-8\" > < meta name = \"viewport\" content = \"width=device-width, initial-scale=1.0\" /> < meta name = \"format-detection\" content = \"telephone=no\" > < link rel = \"icon\" type = \"image/x-icon\" href = \"favicon.ico\" > templates/index.stpl < html > < head > <% include ! ( \"./header.stpl\" ); %> </ head > < body > Main contents </ body > </ html > Then you can see the header.stpl is embedded in the output. < html > < head > < meta charset = \"UTF-8\" > < meta name = \"viewport\" content = \"width=device-width, initial-scale=1.0\" /> < meta name = \"format-detection\" content = \"telephone=no\" > < link rel = \"icon\" type = \"image/x-icon\" href = \"favicon.ico\" > </ head > < body > Main contents </ body > </ html > Like std::include! macro in Rust, the provided path is interpreted as a relative path to the current template file. Warning The path format is platform-specific. You must use \\ character as a separator on Windows.","title":"Includes"},{"location":"syntax/overview/","text":"Template Syntax Overview Tags <% %> : Inline tag, you can write Rust code inside this tag <%= %> : Evaluate the Rust expression and outputs the value into the template (HTML escaped) <%- %> : Evaluate the Rust expression and outputs the unescaped value into the template <%# %> : Comment tag <%% : Outputs a literal '<%' Condition <% if messages . is_empty () { %> < div > No messages </ div > <% } %> loop <% for ( i , msg ) in messages . iter () . enumerate () { %> < div > <%= i %> : <%= msg %> </ div > <% } %> Includes <% include ! ( \"path/to/template\" ); %> Filters <%= message | upper %> { \"id\": <%= id %> \"comment\": <%- comment | json %> }","title":"Overview"},{"location":"syntax/overview/#template-syntax-overview","text":"","title":"Template Syntax Overview"},{"location":"syntax/overview/#tags","text":"<% %> : Inline tag, you can write Rust code inside this tag <%= %> : Evaluate the Rust expression and outputs the value into the template (HTML escaped) <%- %> : Evaluate the Rust expression and outputs the unescaped value into the template <%# %> : Comment tag <%% : Outputs a literal '<%'","title":"Tags"},{"location":"syntax/overview/#condition","text":"<% if messages . is_empty () { %> < div > No messages </ div > <% } %>","title":"Condition"},{"location":"syntax/overview/#loop","text":"<% for ( i , msg ) in messages . iter () . enumerate () { %> < div > <%= i %> : <%= msg %> </ div > <% } %>","title":"loop"},{"location":"syntax/overview/#includes","text":"<% include ! ( \"path/to/template\" ); %>","title":"Includes"},{"location":"syntax/overview/#filters","text":"<%= message | upper %> { \"id\": <%= id %> \"comment\": <%- comment | json %> }","title":"Filters"},{"location":"syntax/tags/","text":"Tags Code block You can write Rust statement inside <% %> tag. Template Result <% let mut total = 0 ; for i in 1 .. { total += i ; if i > 100 { break ; } } %> < div > total = <%= total %> </ div > < div > total = 105 </ div > Note Make sure that you cannot omit braces, parenthesis, and semicolons. Sailfish is smart enough to figure out where the code block ends, so you can even include %> inside Rust comments or string literals. Template Result <% /* Tag does not ends at %>! */ %> If you need to simply render <% character, you can escape it, or use evaluation block (described below). Template Result <%% is converted into <%- \"<%\" %> character. <% is converted into <% character Although almost all Rust statement is supported, the following statements inside templates may cause a strange compilation error. Function/Macro definition that render some contents impl item Macro call which defines some local variable. Macro call which behaviour depends on the path to source file Generator expression (yield) Evaluation block Rust expression inside <%= %> tag is evaluated and the result will be rendered. Template Result <% let a = 1 ; %><%= a + 2 %> 3 If the result contains &\"'<> characters, sailfish replaces these characters with the equivalent html. If you want to render the results without escaping, you can use <%- %> tag or configure sailfish to not escape by default . Template Result < div > <%- \"<h1>Hello, World!</h1>\" %> </ div > < div > < h1 > Hello, World! </ h1 > </ div > Note Evaluation block does not return any value, so you cannot use the block to pass the render result to another code block. The following code is invalid. <% let result = %><%= 1 %><% ; %>","title":"Tags"},{"location":"syntax/tags/#tags","text":"","title":"Tags"},{"location":"syntax/tags/#code-block","text":"You can write Rust statement inside <% %> tag. Template Result <% let mut total = 0 ; for i in 1 .. { total += i ; if i > 100 { break ; } } %> < div > total = <%= total %> </ div > < div > total = 105 </ div > Note Make sure that you cannot omit braces, parenthesis, and semicolons. Sailfish is smart enough to figure out where the code block ends, so you can even include %> inside Rust comments or string literals. Template Result <% /* Tag does not ends at %>! */ %> If you need to simply render <% character, you can escape it, or use evaluation block (described below). Template Result <%% is converted into <%- \"<%\" %> character. <% is converted into <% character Although almost all Rust statement is supported, the following statements inside templates may cause a strange compilation error. Function/Macro definition that render some contents impl item Macro call which defines some local variable. Macro call which behaviour depends on the path to source file Generator expression (yield)","title":"Code block"},{"location":"syntax/tags/#evaluation-block","text":"Rust expression inside <%= %> tag is evaluated and the result will be rendered. Template Result <% let a = 1 ; %><%= a + 2 %> 3 If the result contains &\"'<> characters, sailfish replaces these characters with the equivalent html. If you want to render the results without escaping, you can use <%- %> tag or configure sailfish to not escape by default . Template Result < div > <%- \"<h1>Hello, World!</h1>\" %> </ div > < div > < h1 > Hello, World! </ h1 > </ div > Note Evaluation block does not return any value, so you cannot use the block to pass the render result to another code block. The following code is invalid. <% let result = %><%= 1 %><% ; %>","title":"Evaluation block"}]}