Giter VIP home page Giter VIP logo

tinytemplate's People

Contributors

5225225 avatar ardcore avatar bheisler avatar dkasak avatar heroickatora avatar makoconstruct avatar zzau13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

tinytemplate's Issues

TinyTemplate object not thread safe? How to synchronize?

I want to use TinyTemplate for an Actix Web application, but I run into problems making my TinyTemplate object lazy_static because it does not have the Sync trait. Is it possible to add that or is there a technical reason for that? I could understand that a mutable TinyTemplate object could add a template while another thread calls the render function but why can't two threads use the render function at the same time when they have non-mut reference? Is it recommended to just recreate a new TinyTemplate object every time render() is used or is it faster to reuse the same object and add some synchronization code? Or should I clone the object once for each CPU core and use some kind of pool? Is it possible to share a pointer to just the render() function and use that in a thread safe manner?
Sorry if those are basic questions, I'm still new to Rust, but TinyTemplate works very well for my use case but right now I recreate the TinyTemplate every time I need it and wonder if I'm doing it wrong.

Is it possible to change the default formater?

Hi,

TinyTemplate looks ideal for a use-case I have.

The problem is, that I will not generate HTML, so the default formatter that does HTML escaping is a big problem for me (I don't want to add " | unescaped" to every value usage).

Is there a way to change the default formatter?

I looked at the source code and it seems this is not possible. But I'm a Rust beginner, so maybe I'm missing something.

Compile error

When compiling a project that uses criterion, which has tinytemplate as a dependency, I get this compilation error when cargo tries to build it:

error: unknown `doc` attribute `Hidden`
  --> <SNIP>/tinytemplate-1.2.0/src/error.rs:44:11
   |
44 |     #[doc(Hidden)]
   |           ^^^^^^

error: aborting due to previous error

error: could not compile `tinytemplate`

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

My version of Cargo is cargo 1.52.0-nightly (572e20153 2021-02-24).

Panic with malformed template {#}

Reproduction:

fn main() {
    let data = "{#}";

    let mut tpl = tinytemplate::TinyTemplate::new();

    let _ = tpl.add_template("template", data);
}

Gives

thread 'main' panicked at 'begin <= end (2 <= 1) when slicing `{#}`', /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/tinytemplate-1.2.1/src/compiler.rs:59:31
stack backtrace:
   0: rust_begin_unwind
             at /rustc/952fdf2a1119affa1b37bcacb0c49cf9f0168ac8/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/952fdf2a1119affa1b37bcacb0c49cf9f0168ac8/library/core/src/panicking.rs:92:14
   2: core::str::slice_error_fail
   3: core::str::traits::<impl core::slice::index::SliceIndex<str> for core::ops::range::Range<usize>>::index
             at /rustc/952fdf2a1119affa1b37bcacb0c49cf9f0168ac8/library/core/src/str/traits.rs:214:21
   4: core::str::traits::<impl core::ops::index::Index<I> for str>::index
             at /rustc/952fdf2a1119affa1b37bcacb0c49cf9f0168ac8/library/core/src/str/traits.rs:64:9
   5: tinytemplate::compiler::TemplateCompiler::compile
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/tinytemplate-1.2.1/src/compiler.rs:59:31
   6: tinytemplate::template::Template::compile
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/tinytemplate-1.2.1/src/template.rs:124:27
   7: tinytemplate::TinyTemplate::add_template
             at /home/jess/.cargo/registry/src/github.com-1ecc6299db9ec823/tinytemplate-1.2.1/src/lib.rs:189:24
   8: scratchPpQmmMhHJ::main
             at ./main.rs:6:13
   9: core::ops::function::FnOnce::call_once
             at /rustc/952fdf2a1119affa1b37bcacb0c49cf9f0168ac8/library/core/src/ops/function.rs:227:5

I'll make a PR to add the fuzzing harness I used to find this, so you can run it yourself with cargo-fuzz.

`@index` does not work with formatters

I try to use custom formatter with index like this: { @index | my_formtter } .

When I try to render the template it fails with the following message

Failed to find value '@index' from path '@index'.

If I remove formatter everything works as expected.

Allow indices as part of a path?

It looks like path traversal currently uses serde_json::Value::get, which supports both string keys for maps and numeric keys for arrays. However, TinyTemplate only invokes the string lookup, so any lookup on an array will fail; this is particularly a hassle for tuples, which serde_json::Value represents as arrays.

This can be fixed by attempting to parse the path element as a usize and using that for value lookup if name lookup fails; doing it only on name lookup failure means that any situations where a map is being constructed with string keys that happen to be parseable as usize will continue to work.

I have a PR ready if this approach sounds reasonable :)

how to handle multiple contexts

I have an HTML template to display resource objects, however I have some global context as well.
In JavaScript I would just merge the objects but that is not as easy in a typed language such as Rust.
What is the best way to use multiple context objects with a single template?

failed to parse template

my template:

{{< hint [info] >}}
TKTK
{{< /hint >}}

I don't want the {{ to be parsed by tinytemplate, it's for another parser

Drop `serde_json`

TinyTemplate converts the context structure to serde_json::Value internally so that it can look up values by string keys. This introduces a dependency on serde_json even though we don't really do any JSON serialization. If TinyTemplate had its own version of Value which could be constructed by a custom serde serializer, we could drop serde_json and only depend on serde.

This is not a high priority for Criterion.rs (which depends on serde_json anyway). I would be happy to accept a pull request though.

different syntax for variables

right now I'm using

{ thing }

to print a variable, but this is colliding with LaTeX blocks in my text. Is it possible to change that to something like

<[ thing ]>

Loop over root element

I have a vector of structures, which I want to format. Unfortunately I can't access the root element to loop over it: {{ for item in ??? }} {item.field} {{ endfor }}. Is it possible? What template should I write?

Support iterating over maps/objects

Thank you for this very nice project. I love the simple and low-dependency philosophy.

Somewhat not in that vein: what would you think about supporting iteration over maps/objects? Currently iteration is restricted to arrays. Following the standard syntax in other templating languages, it could look something like this:

{{ for key, value in guests }}
The key is {key} and the value is {value}
{{ endfor }}

I poked around the code to see what the implementation would be like, and I think it would be straightforward (I would do it):

  • We would add a new instruction similar to PushIterationContext. Perhaps PushObjectIterationContext(Path<'template>, &'template str, &'template str) where the enum payload is (path to the map, key variable name, value variable name).

  • In the compiler, the parse_for function would be changed to split the key name on ,, and then construct either a array iteration spec (no commas), an object iteration spec (1 comma) or an error (2 or more commas).

  • The new instruction would have to be implemented in template.rs. This would follow array iteration, probably with a new ContextElement.

Project dead?

Is the project dead?

Just asking...

Anybody aware of good alternatives?

Feature Request: Iterate on integer values

I think it'd be useful to be able to loop over an integer value, as well as the existing array functionality.

Example:

Context:
{
  depth: 3,
  text: "Test"
}

Template:
"{{ for i in depth }}\t{{ endfor }} {text}"

CVE-2023-38497: World writable files in crate

$ find ~/.cargo/ -perm /002                                                    
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/.github/workflows/ci.yml
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/.gitignore
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/CHANGELOG.md
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/CONTRIBUTING.md
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/Cargo.toml.orig
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/LICENSE-APACHE
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/LICENSE-MIT
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/README.md
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/benches/benchmarks.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/compiler.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/error.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/instruction.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/lib.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/syntax.rs
/home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tinytemplate-1.2.1/src/template.rs

This indicates that this crate has world writable permissions. This has been fixed in cargo (CVE-2023-38497), but that will not help for people using older versions of rust than 1.71.1 (e.g. stuck on old versions provided by their Linux distro, etc).

As such, it would be beneficial to fix this in the package as well.

How to customize placeholders?

My project contains a large number of {}/{{}}-like strings (such as in CSS or FreeMarker), and I can't escape them all with .

Is there a way to customize the placeholder symbols, for example, I want to use <%xxxxxx%> instead of {xxxxxx}, so I don't have to modify existing files?

distributed crate has source files marked as executable

the distributed crate for tinytemplate appears to have almost all files marked as executable:

$ wget -O - -q 'https://crates.io/api/v1/crates/tinytemplate/1.2.1/download' | tar tvz
-rwxrwxrwx 1000/1000      1249 2021-01-03 14:00 tinytemplate-1.2.1/.github/workflows/ci.yml
-rwxrwxrwx 1000/1000        30 2019-01-26 09:01 tinytemplate-1.2.1/.gitignore
-rwxrwxrwx 1000/1000      1912 2021-03-03 18:56 tinytemplate-1.2.1/CHANGELOG.md
-rwxrwxrwx 1000/1000      2629 2019-01-26 09:01 tinytemplate-1.2.1/CONTRIBUTING.md
-rwxrwxrwx 1000/1000       596 2021-03-03 18:56 tinytemplate-1.2.1/Cargo.toml.orig
-rw-r--r-- 0/0            1183 1969-12-31 19:00 tinytemplate-1.2.1/Cargo.toml
-rwxrwxrwx 1000/1000     10847 2019-01-26 09:01 tinytemplate-1.2.1/LICENSE-APACHE
-rwxrwxrwx 1000/1000      1057 2019-01-26 09:01 tinytemplate-1.2.1/LICENSE-MIT
-rwxrwxrwx 1000/1000      4724 2021-01-03 15:43 tinytemplate-1.2.1/README.md
-rwxrwxrwx 1000/1000      1469 2019-01-26 09:01 tinytemplate-1.2.1/benches/benchmarks.rs
-rwxrwxrwx 1000/1000     27364 2021-01-03 15:28 tinytemplate-1.2.1/src/compiler.rs
-rwxrwxrwx 1000/1000      7313 2021-03-03 18:54 tinytemplate-1.2.1/src/error.rs
-rwxrwxrwx 1000/1000      3382 2021-01-03 15:28 tinytemplate-1.2.1/src/instruction.rs
-rwxrwxrwx 1000/1000      8460 2021-01-03 14:53 tinytemplate-1.2.1/src/lib.rs
-rwxrwxrwx 1000/1000      6721 2021-01-03 14:53 tinytemplate-1.2.1/src/syntax.rs
-rwxrwxrwx 1000/1000     33095 2021-01-03 15:37 tinytemplate-1.2.1/src/template.rs
-rw-r--r-- 0/0              74 1969-12-31 19:00 tinytemplate-1.2.1/.cargo_vcs_info.json
$ 

typically, source code files are not marked as executable.

On debian systems, this causes executable-not-elf-or-script lintian warnings for the rust-tinytemplate-dev package.

I'm not sure how you're generating the crates for tinytemplate, but it looks like they could be generated in a way that avoids setting the execute bit on each source file.

Clarification on runtime loading of strings

Hey!

The documentation mentions the following:

Although it is possible to use TinyTemplate with template strings loaded at runtime, this is not recommended.

What is the reason behind this? I am currently looking for a fast and rather lightweight templating engine that allows branching as well and after tinkering around with this crate, it seems to work perfectly.

Can't use templating in files with curly braces {}

I'm not sure if this is specific to the file I was working with or if it applies to all file that use curly braces, but I wanted to bring it up anyway.

It seems TinyTemplate uses just opening and closing curly braces { } to denote places to insert values into the template file.

I'm working on a project that generates a JavaScript project workspace and needs to insert some values into a few default JS files. However, when I try to use a JS file as a template, the TinyTemplate errors out, telling me that a matching curly brace is missing.

I have some JS like this:

const myObj = { 
  projectName: "{project_name}"
};

TinyTemplate should insert the value of project_name into this JS object, but TinyTemplate sees the opening brace of myObj as as signaling the start of an injection point for the templating engine and then breaks when it sees the first opening brace of the actual injection point.

Personally, I'd love to use TinyTemplate for my project because I really only need minimal templating capabilities so other options would bloat out my app unnecessarily. Are there any plans in the future to make TinyTemplate compatible with JavaScript files and other formats that use curly braces extensively?

Panic on escaped opening curly braces

Adding a template with an escaped opening curly brace, \{, causes a panic by core::str::slice_error_fail originating from tinytemplate::compiler::TemplateCompiler::compile.

Minimal test case:

use tinytemplate::TinyTemplate;

static TEMPLATE: &str = r#"hello \{world}"#;

fn main() {
    let mut tt = TinyTemplate::new();
    tt.add_template("template", TEMPLATE).expect("Unable to add template");
}

The panic isn't caused by expect, as shown in the backtrace.

Backtrace:

thread 'main' panicked at 'byte index 8 is out of bounds of `{world}`', src/libcore/str/mod.rs:2010:9
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: rust_begin_unwind
             at src/libstd/panicking.rs:312
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
   8: core::str::slice_error_fail
             at src/libcore/str/mod.rs:0
   9: tinytemplate::compiler::TemplateCompiler::compile
  10: tinytemplate::TinyTemplate::add_template
  11: test_case::main
  12: std::rt::lang_start::{{closure}}
  13: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:297
  14: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:87
  15: std::rt::lang_start_internal
             at src/libstd/panicking.rs:276
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  16: main
  17: __libc_start_main
  18: _start

This has been tested on both cargo 1.34.0 (6789d8a0a 2019-04-01) and cargo 1.36.0-nightly (759b6161a 2019-05-06).

Example does not compile

Thank you for your crate!
I tried to use it and cargo/rustc didn't seem to find the Serialize trait. I then tried to copy your example in the README.md and it also failed to compile (i did add the dependencies you mentioned):

   Updating crates.io index
   Compiling proc-macro2 v1.0.18
   Compiling ryu v1.0.5
   Compiling serde v1.0.114
   Compiling unicode-xid v0.2.1
   Compiling syn v1.0.33
   Compiling serde_json v1.0.56
   Compiling itoa v0.4.6
   Compiling serde_derive v1.0.114
   Compiling quote v1.0.7
   Compiling tinytemplate v1.1.0
   Compiling tttest v0.1.0 (/tmp/tttest)
error[E0463]: can't find crate for `serde`
 --> src/main.rs:8:10
  |
8 | #[derive(Serialize)]
  |          ^^^^^^^^^ can't find crate
  |
  = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
error: could not compile `tttest`.

To learn more, run the command again with --verbose.

I assume that serde_derive does not contain the Traits necessary to compile this, so instead of depending on serde_derive, the README should use serde = { version = "1.0", features = ["derive"] }, as written in serdes documentation. It then follows that the example code should use

use serde::Serialize;

instead of

#[macro_use]
extern crate serde_derive;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.