From 73ffdcf0feca8c984eff7ad7674197c2d6602d53 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 6 Nov 2021 06:55:34 +0800 Subject: [PATCH 01/57] (cargo-release) start next development iteration 4.1.5-alpha.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 43d0c981b..acd2db85c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "handlebars" -version = "4.1.4" +version = "4.1.5-alpha.0" authors = ["Ning Sun "] description = "Handlebars templating implemented in Rust." license = "MIT" From 7a92497f9f35f2feec9b61e765d60501ca5c6896 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 16 Nov 2021 22:44:01 +0800 Subject: [PATCH 02/57] fix: add support for single quote string literal --- src/grammar.pest | 12 +++++++++--- src/grammar.rs | 3 +++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/grammar.pest b/src/grammar.pest index 250d9d213..2c68b876b 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -15,13 +15,19 @@ literal = { string_literal | null_literal = @{ "null" ~ !symbol_char } boolean_literal = @{ ("true"|"false") ~ !symbol_char } number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } -json_char = { +json_char_double_quote = { !("\"" | "\\") ~ ANY | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) } -string_inner = @{ json_char* } -string_literal = ${ "\"" ~ string_inner ~ "\"" } +json_char_single_quote = { + !("'" | "\\") ~ ANY + | "\\" ~ ("'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") + | "\\" ~ ("u" ~ ASCII_HEX_DIGIT{4}) +} +string_inner_double_quote = @{ json_char_double_quote* } +string_inner_single_quote = @{ json_char_single_quote* } +string_literal = ${ ("\"" ~ string_inner_double_quote ~ "\"") | ("'" ~ string_inner_single_quote ~ "'") } array_literal = { "[" ~ literal? ~ ("," ~ literal)* ~ "]" } object_literal = { "{" ~ (string_literal ~ ":" ~ literal)? ~ ("," ~ string_literal ~ ":" ~ literal)* ~ "}" } diff --git a/src/grammar.rs b/src/grammar.rs index fd3ec09ae..d2f4150fd 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -203,6 +203,7 @@ mod test { "{{exp 1}}", "{{exp \"literal\"}}", "{{exp \"literal with space\"}}", + "{{exp 'literal with space'}}", r#"{{exp "literal with escape \\\\"}}"#, "{{exp ref}}", "{{exp (sub)}}", @@ -211,6 +212,8 @@ mod test { "{{exp {}}}", "{{exp key=1}}", "{{exp key=ref}}", + "{{exp key='literal with space'}}", + "{{exp key=\"literal with space\"}}", "{{exp key=(sub)}}", "{{exp key=(sub 0)}}", "{{exp key=(sub 0 key=1)}}", From b0e8d4755f32c8a7e97ac7a16a8edd4a6dec67bd Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 16 Nov 2021 22:55:58 +0800 Subject: [PATCH 03/57] chore: use liberapay as primary sponsing source --- .github/FUNDING.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 7598546ef..eade1bf6f 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,5 +1,5 @@ github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: Sunng +patreon: open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel @@ -7,4 +7,3 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl liberapay: Sunng issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username -custom: ['https://www.buymeacoffee.com/Sunng'] From 41b3423c6ff062d6032bcba0ad5cc986b529c3ef Mon Sep 17 00:00:00 2001 From: Keita Urashima Date: Wed, 17 Nov 2021 03:55:34 +0900 Subject: [PATCH 04/57] Fix broken link in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ea5664522..6afd46cf9 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,7 @@ And using it in your template: {{hex 16}} ``` -By default, handlebars-rust ships [additional helpers](https://github.com/sunng87/handlebars-rust/blob/master/src/helpers/helper_boolean.rs#L5) +By default, handlebars-rust ships [additional helpers](https://github.com/sunng87/handlebars-rust/blob/master/src/helpers/helper_extras.rs#L6) (compared with original js version) that is useful when working with `if`. From 8926460fbd17080f8c5e882a3b886aba822d16e9 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 17 Nov 2021 22:30:54 +0800 Subject: [PATCH 05/57] doc: update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c05b3ec2f..5c5e555e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [Unreleased](https://github.com/sunng87/handlebars-rust/compare/4.1.4...Unreleased) - ReleaseDate + +* [Fixed] Single-quote string literal is supported, again [#475] + ## [4.1.4](https://github.com/sunng87/handlebars-rust/compare/4.1.3...4.1.4) - 2021-11-06 * [Fixed] Corrected empty line stripping strategy [#473] From 3d8fc48ba5bd25ce61b066fd5fd88fd44c6f9144 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 17 Nov 2021 22:31:06 +0800 Subject: [PATCH 06/57] (cargo-release) version 4.1.5 --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c5e555e4..3c9924b40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [Unreleased](https://github.com/sunng87/handlebars-rust/compare/4.1.4...Unreleased) - ReleaseDate +## [4.1.5](https://github.com/sunng87/handlebars-rust/compare/4.1.4...4.1.5) - 2021-11-17 * [Fixed] Single-quote string literal is supported, again [#475] diff --git a/Cargo.toml b/Cargo.toml index acd2db85c..1cdda0f9d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "handlebars" -version = "4.1.5-alpha.0" +version = "4.1.5" authors = ["Ning Sun "] description = "Handlebars templating implemented in Rust." license = "MIT" diff --git a/src/lib.rs b/src/lib.rs index b2730f5f4..844fde91e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/handlebars/4.1.4")] +#![doc(html_root_url = "https://docs.rs/handlebars/4.1.5")] #![cfg_attr(docsrs, feature(doc_cfg))] //! # Handlebars //! From 574009f6c24dd0eed934b1a27131fd96a716e107 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 17 Nov 2021 22:31:42 +0800 Subject: [PATCH 07/57] (cargo-release) start next development iteration 4.1.6-alpha.0 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1cdda0f9d..59e60d47a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "handlebars" -version = "4.1.5" +version = "4.1.6-alpha.0" authors = ["Ning Sun "] description = "Handlebars templating implemented in Rust." license = "MIT" From a55a62bd95873ad7884c9ff02c8a03df6b413790 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 23 Nov 2021 21:19:39 +0800 Subject: [PATCH 08/57] feat: update pprof --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 59e60d47a..cce4d9a09 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] } chrono = { version = "0.4.19", features = ["serde"] } [target.'cfg(unix)'.dev-dependencies] -pprof = { version = "0.5", features = ["flamegraph", "protobuf"] } +pprof = { version = "0.6", features = ["flamegraph", "protobuf"] } [features] dir_source = ["walkdir"] From 4363a1670d0f85fa2af13ac1455f82dead78bc71 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Thu, 2 Dec 2021 23:03:57 +0800 Subject: [PATCH 09/57] feat: Add From for Context [#477] --- src/context.rs | 6 ++++++ src/registry.rs | 3 +-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/context.rs b/src/context.rs index f4b502e0d..20581aad0 100644 --- a/src/context.rs +++ b/src/context.rs @@ -223,6 +223,12 @@ impl Context { } } +impl From for Context { + fn from(data: Json) -> Context { + Context { data } + } +} + #[cfg(test)] mod test { use crate::block::{BlockContext, BlockParams}; diff --git a/src/registry.rs b/src/registry.rs index eaa12897d..7cde7271d 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -987,8 +987,7 @@ mod test { .unwrap(); assert_eq!( "0123", - reg.render_with_context("t0", &Context::wraps(&data).unwrap()) - .unwrap() + reg.render_with_context("t0", &Context::from(data)).unwrap() ); } From e67a6ff5aec75601807784d0362daccaa20a3594 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 3 Dec 2021 23:31:22 +0800 Subject: [PATCH 10/57] doc: update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c9924b40..8e190724d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Change Log +## [Unreleased](https://github.com/sunng87/handlebars-rust/compare/4.1.5...Unreleased) - ReleaseDate + +* [Added] Create `Context` from owned `serde_json::Value` [#477] + ## [4.1.5](https://github.com/sunng87/handlebars-rust/compare/4.1.4...4.1.5) - 2021-11-17 * [Fixed] Single-quote string literal is supported, again [#475] From b1b0b9eb28a8fcb77152043a3500065b98744ab7 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 3 Dec 2021 23:35:44 +0800 Subject: [PATCH 11/57] (cargo-release) version 4.1.6 --- CHANGELOG.md | 2 +- Cargo.toml | 2 +- src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e190724d..57a181b21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [Unreleased](https://github.com/sunng87/handlebars-rust/compare/4.1.5...Unreleased) - ReleaseDate +## [4.1.6](https://github.com/sunng87/handlebars-rust/compare/4.1.5...4.1.6) - 2021-12-03 * [Added] Create `Context` from owned `serde_json::Value` [#477] diff --git a/Cargo.toml b/Cargo.toml index cce4d9a09..82b48b299 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "handlebars" -version = "4.1.6-alpha.0" +version = "4.1.6" authors = ["Ning Sun "] description = "Handlebars templating implemented in Rust." license = "MIT" diff --git a/src/lib.rs b/src/lib.rs index 844fde91e..1def62146 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![doc(html_root_url = "https://docs.rs/handlebars/4.1.5")] +#![doc(html_root_url = "https://docs.rs/handlebars/4.1.6")] #![cfg_attr(docsrs, feature(doc_cfg))] //! # Handlebars //! From a3e276cd185595321df68e69e909beae26b557c5 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Sat, 4 Dec 2021 06:29:02 +0800 Subject: [PATCH 12/57] chore: update release.toml --- release.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release.toml b/release.toml index e0f365aa1..6ee7a8383 100644 --- a/release.toml +++ b/release.toml @@ -1,4 +1,6 @@ sign-commit = true +sign-tag = true +dev-version = true pre-release-replacements = [ {file="CHANGELOG.md", search="Unreleased", replace="{{version}}", prerelease=false}, {file="CHANGELOG.md", search="ReleaseDate", replace="{{date}}", prerelease=false}, From 630c7803573bd4a824c082cd4ae33bdc3c53a9c3 Mon Sep 17 00:00:00 2001 From: Matt Kantor Date: Sun, 5 Dec 2021 14:15:54 -0500 Subject: [PATCH 13/57] test: add a (failing) test using identifiers starting with numbers These test cases capture the issue called out in #450. The handling of identifiers which start with numbers diverges from the official JavaScript implementation of Handlebars. It's especially bad for cases like `{{eq 1a}}`, which validly parses as `{{eq 1 a}}`! --- src/render.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/render.rs b/src/render.rs index a5070a0d3..c2879ad99 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1117,3 +1117,37 @@ fn test_zero_args_heler() { "Output name: first_name not resolved" ); } + +#[test] +fn test_identifiers_starting_with_numbers() { + let mut r = Registry::new(); + + assert!(r + .register_template_string("r1", "{{#if 0a}}true{{/if}}") + .is_ok()); + let r1 = r.render("r1", &json!({"0a": true})).unwrap(); + assert_eq!(r1, "true"); + + assert!(r.register_template_string("r2", "{{eq 1a 1}}").is_ok()); + let r2 = r.render("r2", &json!({"1a": 2, "a": 1})).unwrap(); + assert_eq!(r2, "false"); + + assert!(r + .register_template_string("r3", "0: {{0}} {{#if (eq 0 true)}}resolved from context{{/if}}\n1a: {{1a}} {{#if (eq 1a true)}}resolved from context{{/if}}\n2_2: {{2_2}} {{#if (eq 2_2 true)}}resolved from context{{/if}}") // YUP it is just eq that barfs! is if handled specially? maybe this test should go nearer to specific helpers that fail? + .is_ok()); + let r3 = r + .render("r3", &json!({"0": true, "1a": true, "2_2": true})) + .unwrap(); + assert_eq!( + r3, + "0: true \n1a: true resolved from context\n2_2: true resolved from context" + ); + + // these should all be errors: + assert!(r.register_template_string("r4", "{{eq 1}}").is_ok()); + assert!(r.register_template_string("r5", "{{eq a1}}").is_ok()); + assert!(r.register_template_string("r6", "{{eq 1a}}").is_ok()); + assert!(r.render("r4", &()).is_err()); + assert!(r.render("r5", &()).is_err()); + assert!(r.render("r6", &()).is_err()); +} From 07723496862bd654d48132243dd7448100033c08 Mon Sep 17 00:00:00 2001 From: Matt Kantor Date: Sun, 5 Dec 2021 14:22:55 -0500 Subject: [PATCH 14/57] fix: correctly parse identifiers which start with numbers Fixes #450. --- src/grammar.pest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/grammar.pest b/src/grammar.pest index 2c68b876b..6abf620a5 100644 --- a/src/grammar.pest +++ b/src/grammar.pest @@ -14,7 +14,7 @@ literal = { string_literal | null_literal = @{ "null" ~ !symbol_char } boolean_literal = @{ ("true"|"false") ~ !symbol_char } -number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? } +number_literal = @{ "-"? ~ ASCII_DIGIT+ ~ "."? ~ ASCII_DIGIT* ~ ("E" ~ "-"? ~ ASCII_DIGIT+)? ~ !symbol_char } json_char_double_quote = { !("\"" | "\\") ~ ANY | "\\" ~ ("\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t") From 0baed5b66456b728edeaa5f4da08b061f46a0bee Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 28 Dec 2021 17:00:23 +0800 Subject: [PATCH 15/57] Add periodic CI --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 048c67427..73cd12821 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: CI on: - # Only run when merging to master, or open/synchronize/reopen a PR. + schedule: [{cron: "0 13 * * *"}] push: branches: - master From 9be61dc054bc97d26cbba82e14959bc12ec4fef3 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 28 Dec 2021 21:45:08 +0800 Subject: [PATCH 16/57] fix: update msrv to 1.51 --- .github/workflows/main.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 73cd12821..961f6a85d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -72,6 +72,6 @@ jobs: - uses: actions/checkout@v2 - uses: actions-rs/toolchain@v1 with: - toolchain: "1.50" + toolchain: "1.51" override: true - run: cargo build --all-features diff --git a/README.md b/README.md index 6afd46cf9..bfd622f26 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ book](https://doc.rust-lang.org/book/). [![](https://img.shields.io/crates/d/handlebars.svg)](https://crates.io/crates/handlebars) [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Docs](https://docs.rs/handlebars/badge.svg)](https://docs.rs/crate/handlebars/) -![rustc](https://img.shields.io/badge/rustc-1.50+-lightgray.svg) +![rustc](https://img.shields.io/badge/rustc-1.51+-lightgray.svg) [![Donate](https://img.shields.io/badge/donate-liberapay-yellow.svg)](https://liberapay.com/Sunng/donate) ## Getting Started From 34fb76d8b4050939b96a6656c6bcbef9241d5d1f Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Mon, 27 Dec 2021 08:40:30 +0800 Subject: [PATCH 17/57] feat: add rust-embed support as template source --- Cargo.toml | 1 + src/registry.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 82b48b299..34504e7c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ serde = "1.0.0" serde_json = "1.0.39" walkdir = { version = "2.2.3", optional = true } rhai = { version = "1", optional = true, features = ["sync", "serde"] } +rust-embed = { version = "6.3.0", optional = true } [dev-dependencies] env_logger = "0.9" diff --git a/src/registry.rs b/src/registry.rs index 7cde7271d..9061a9559 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -30,6 +30,9 @@ use rhai::Engine; #[cfg(feature = "script_helper")] use crate::helpers::scripting::ScriptHelper; +#[cfg(feature = "rust-embed")] +use rust_embed::RustEmbed; + /// This type represents an *escape fn*, that is a function whose purpose it is /// to escape potentially problematic characters in a string. /// @@ -322,6 +325,25 @@ impl<'reg> Registry<'reg> { Ok(()) } + /// Register templates using a RustEmbed type + #[cfg(feature = "rust-embed")] + #[cfg_attr(docsrs, doc(cfg(feature = "rust-embed")))] + pub fn register_embed_templates(&mut self) -> Result<(), TemplateError> + where + E: RustEmbed, + { + for item in E::iter() { + let file_name = item.as_ref(); + if let Some(file) = E::get(file_name) { + let data = file.data; + + let tpl_content = String::from_utf8_lossy(data.as_ref()); + self.register_template_string(&file_name.to_owned(), tpl_content)?; + } + } + Ok(()) + } + /// Remove a template from the registry pub fn unregister_template(&mut self, name: &str) { self.templates.remove(name); From 62ebdb0cb6ee87310c53379697a1cdbdbe151014 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Mon, 27 Dec 2021 22:16:24 +0800 Subject: [PATCH 18/57] test: Add test for rustembed --- tests/embed.rs | 26 ++++++++++++++++++++++++++ tests/templates/hello.hbs | 1 + 2 files changed, 27 insertions(+) create mode 100644 tests/embed.rs create mode 100644 tests/templates/hello.hbs diff --git a/tests/embed.rs b/tests/embed.rs new file mode 100644 index 000000000..fe91cc1db --- /dev/null +++ b/tests/embed.rs @@ -0,0 +1,26 @@ +#[macro_use] +extern crate serde_json; + +use handlebars::Handlebars; + +#[test] +#[cfg(feature = "rust-embed")] +fn test_embed() { + use rust_embed::RustEmbed; + + #[derive(RustEmbed)] + #[folder = "tests/templates/"] + #[include = "*.hbs"] + struct Templates; + + let mut hbs = Handlebars::new(); + hbs.register_embed_templates::().unwrap(); + + assert_eq!(1, hbs.get_templates().len()); + + let data = json!({ + "name": "Andy" + }); + + assert_eq!(hbs.render("hello.hbs", &data).unwrap(), "Hello, Andy\n"); +} diff --git a/tests/templates/hello.hbs b/tests/templates/hello.hbs new file mode 100644 index 000000000..a2344af53 --- /dev/null +++ b/tests/templates/hello.hbs @@ -0,0 +1 @@ +Hello, {{name}} From 725bf45a65f6d96b7dc94ba9d6e0c583c84b1198 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 28 Dec 2021 21:56:00 +0800 Subject: [PATCH 19/57] doc: add docstring for rustembed method --- src/registry.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/registry.rs b/src/registry.rs index 9061a9559..cc59675fa 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -325,7 +325,20 @@ impl<'reg> Registry<'reg> { Ok(()) } - /// Register templates using a RustEmbed type + /// Register templates using a + /// [RustEmbed](https://github.com/pyros2097/rust-embed) type + /// + /// File names from embed struct are used as template name. + /// + /// ```skip + /// #[derive(RustEmbed)] + /// #[folder = "templates"] + /// struct Assets; + /// + /// let mut hbs = Handlebars::new(); + /// hbs.register_embed_templates::(); + /// ``` + /// #[cfg(feature = "rust-embed")] #[cfg_attr(docsrs, doc(cfg(feature = "rust-embed")))] pub fn register_embed_templates(&mut self) -> Result<(), TemplateError> From a2905d5c389b9ebc9a7cde8add5a5c1230760ab1 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 28 Dec 2021 22:04:40 +0800 Subject: [PATCH 20/57] doc: Add doc for template loading features in front page --- src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1def62146..a50603dda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,6 +166,14 @@ //! # } //! ``` //! +//! #### Additional features for loading template from +//! +//! * Feature `dir_source` enables template loading +//! `register_templates_directory` from given directory. +//! * Feature `rust-embed` enables template loading +//! `register_embed_templates` from embedded resources in rust struct +//! generated with `RustEmbed`. +//! //! ### Rendering Something //! //! Since handlebars is originally based on JavaScript type system. It supports dynamic features like duck-typing, truthy/falsey values. But for a static language like Rust, this is a little difficult. As a solution, we are using the `serde_json::value::Value` internally for data rendering. From 0bee0424d5246f9d1086d6e2afd59530fa21a24a Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Tue, 28 Dec 2021 22:19:36 +0800 Subject: [PATCH 21/57] fix: LS on windows causing failed test --- tests/embed.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/embed.rs b/tests/embed.rs index fe91cc1db..019f27db9 100644 --- a/tests/embed.rs +++ b/tests/embed.rs @@ -22,5 +22,8 @@ fn test_embed() { "name": "Andy" }); - assert_eq!(hbs.render("hello.hbs", &data).unwrap(), "Hello, Andy\n"); + assert_eq!( + hbs.render("hello.hbs", &data).unwrap().trim(), + "Hello, Andy" + ); } From 6b518e81c145ab2b8a584678e9177858760cba09 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Wed, 29 Dec 2021 22:28:15 +0800 Subject: [PATCH 22/57] doc: update changelog for recent features --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57a181b21..8555af31a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Change Log +## [Unreleased](https://github.com/sunng87/handlebars-rust/compare/4.1.6...Unreleased) - ReleaseDate + +* [Added] RustEmbed support for loading templates from [#484] +* [Fixed] Parser support for variables begins with digit [#479] +* [Changed] Update MSRV to 1.51 due to dependency changes + ## [4.1.6](https://github.com/sunng87/handlebars-rust/compare/4.1.5...4.1.6) - 2021-12-03 * [Added] Create `Context` from owned `serde_json::Value` [#477] From 9ae9f249059e16ae8ec60a9a0960d4291ce268d2 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 31 Dec 2021 14:12:53 +0800 Subject: [PATCH 23/57] test: add test case for partial indent issue #482 --- tests/partial_indent.rs | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/partial_indent.rs diff --git a/tests/partial_indent.rs b/tests/partial_indent.rs new file mode 100644 index 000000000..db0322c5a --- /dev/null +++ b/tests/partial_indent.rs @@ -0,0 +1,49 @@ +use handlebars::*; +use serde_json::json; + +#[test] +fn test_partial_indent() { + let outer = r#" {{> inner inner_solo}} + +{{#each inners}} + {{> inner}} +{{/each}} + + {{#each inners}} + {{> inner}} + {{/each}} +"#; + let inner = r#"name: {{name}} +"#; + + let mut hbs = Handlebars::new(); + + hbs.register_template_string("inner", inner).unwrap(); + hbs.register_template_string("outer", outer).unwrap(); + + let result = hbs + .render( + "outer", + &json!({ + "inner_solo": {"name": "inner_solo"}, + "inners": [ + {"name": "hello"}, + {"name": "there"} + ] + }), + ) + .unwrap(); + + assert_eq!( + result, + r#" name: inner_solo + + name: hello + name: there + + name: hello + name: there +"# + ); +} +// Rule::partial_expression should not trim new lines by default From 3625618355185ade9e99204f1655accf4e6ee08d Mon Sep 17 00:00:00 2001 From: Matt Kantor Date: Sat, 1 Jan 2022 15:36:00 -0500 Subject: [PATCH 24/57] fix: correct a typo in RenderContext Debug impl --- src/render.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/render.rs b/src/render.rs index c2879ad99..76ce7cfcd 100644 --- a/src/render.rs +++ b/src/render.rs @@ -277,7 +277,7 @@ impl<'reg, 'rc> fmt::Debug for RenderContextInner<'reg, 'rc> { .field("partial_block_stack", &self.partial_block_stack) .field("root_template", &self.root_template) .field("current_template", &self.current_template) - .field("disable_eacape", &self.disable_escape) + .field("disable_escape", &self.disable_escape) .finish() } } From d95ea1945724d72ad840ed874a694180d74bf596 Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Mon, 3 Jan 2022 21:06:05 +0800 Subject: [PATCH 25/57] fix: keep indent by default to partial expression #482 --- src/partial.rs | 47 +++++++++++++++++++++++++++++++++++++++ src/template.rs | 18 ++++++++++++--- tests/partial_indent.rs | 49 ----------------------------------------- 3 files changed, 62 insertions(+), 52 deletions(-) delete mode 100644 tests/partial_indent.rs diff --git a/src/partial.rs b/src/partial.rs index 06ded5cdb..1aa68c85a 100644 --- a/src/partial.rs +++ b/src/partial.rs @@ -357,4 +357,51 @@ foofoofoo"#, hbs.render_template(tpl1, &json!({})).unwrap() ); } + + #[test] + fn test_partial_indent() { + let outer = r#" {{> inner inner_solo}} + +{{#each inners}} + {{> inner}} +{{/each}} + + {{#each inners}} + {{> inner}} + {{/each}} +"#; + let inner = r#"name: {{name}} +"#; + + let mut hbs = Registry::new(); + + hbs.register_template_string("inner", inner).unwrap(); + hbs.register_template_string("outer", outer).unwrap(); + + let result = hbs + .render( + "outer", + &json!({ + "inner_solo": {"name": "inner_solo"}, + "inners": [ + {"name": "hello"}, + {"name": "there"} + ] + }), + ) + .unwrap(); + + assert_eq!( + result, + r#" name: inner_solo + + name: hello + name: there + + name: hello + name: there +"# + ); + } + // Rule::partial_expression should not trim leading indent by default } diff --git a/src/template.rs b/src/template.rs index ce35a93de..f8cac3dcd 100644 --- a/src/template.rs +++ b/src/template.rs @@ -389,6 +389,7 @@ impl Template { template_stack: &mut VecDeque