nickel-org / rust-mustache Goto Github PK
View Code? Open in Web Editor NEWmustache template library for rust
License: Other
mustache template library for rust
License: Other
Hi, thanks for the great work on this library. I'm new to mustache, but as I understand it, data is supposed to be automatically passed to nested partials. This doesn't seem to be working correctly with rust-mustache
though.
Neither the original rust-mustache nor rustache are being actively maintained, making this project the only 'reasonable' alternative. Consider making it a standalone repository to emphasize this fact.
This would mean we can write directly to a String, which isn't possible with the io::Write trait since the bytes aren't guaranteed to be valid utf-8
rust-mustache should either offer an option to turn off (or on) HTML escapment, or simply not provide this capability.
cc @cburgdorf
This is the main repository for mustache, so it really should stop being considered a forked from https://github.com/SimonPersson/rust-mustache, and ultimately my repository https://github.com/erickt/rust-mustache. Can one of the owners of this repository file a support ticket to turn this into a normal repository? I've already filed a ticket to make https://github.com/erickt/rust-mustache a child repository from this project.
This is undocumented and gives very strange errors of File doesn't exist
when I pass it something like Path::new("Makefile"
.
It seems that rust-mustache is missing some spec compliance tests, such as triple-mustache and & interactions with the implicit iterator (see mustache/spec#82). rust-mustache fails in this case, with, 'expect map: [""]'.
Additionally, mustache is supposed to look into parents whenever a missing variable is encountered, but rust-mustache does not seem to do so.
(From section Variables in mustache(5): "The most basic tag type is the variable. [...] If there is no name key, the parent contexts will be checked recursively. If the top context is reached and the name key is still not found, nothing will be rendered.").
Also see the specs compliance test for interpolation:
" 2) Walk the context stack from top to bottom, finding the first context
that is a) a hash containing the name as a key OR b) an object responding
to a method with the given name." (https://github.com/mustache/spec/blob/master/specs/interpolation.yml)
Also, "If the top context is reached and the name key is still not found, nothing will be rendered." should mean that the current behavior for rust-mustache is incorrect since it errors out instead of rendering an empty string when the context is changed by the beginning of a section.
Example failure cases:
<html>
<body>
{{#payload.list}}
{{{.}}}
{{/payloadlist}}
{{#payload.list}}
{{&.}}
{{/payload.list}}
{{#payload.list}}
{{payload.test}}
{{/payload.list}}
{{#payload.list}}
{{test}}
{{/payload.list}}
</body>
</html>
With data equivalent to something like the following:
payload: { list: { "<p>hello</p>", "<p>world</p>" }, test: "hello world" }
In my quest to remove all duplicates from our crate tree at work, I would like to bump log
in mustache
. Would you consider adding new maintainers to review and merge PRs?
Given a template such as this one:
{{# some_var }}
some text {{{ some_var }}}
{{/ some_var }}
and using
let mut data = HashMap::new();
data.insert("some_var", "some value");
as the data passed to the compiled template, I am receiving the following panic:
thread 'main' panicked at 'bug: unexpected value StrVal(some value). Please report this issue on GitHub if you find an input that triggers this case.'
A code search in the repo yields the following lines in src/template.rs
as the culprit:
match self.find(path, stack) {
None => {}
Some(value) => {
match *value {
Bool(true) => {
try!(self.render(wr, stack, children));
}
Bool(false) => {}
VecVal(ref vs) => {
for v in vs.iter() {
stack.push(v);
try!(self.render(wr, stack, children));
stack.pop();
}
}
Map(_) => {
stack.push(value);
try!(self.render(wr, stack, children));
stack.pop();
}
Fun(ref fcell) => {
let f = &mut *fcell.borrow_mut();
let tokens = try!(self.render_fun(src, otag, ctag, f));
try!(self.render(wr, stack, &tokens));
}
OptVal(ref val) => {
if let Some(ref val) = *val {
stack.push(val);
try!(self.render(wr, stack, children));
stack.pop();
}
}
_ => bug!("unexpected value {:?}", value),
}
}
};
Now, the spec doesn't quite specify a clear behaviour on whether string values are to be interpreted as "thruthy", "falsey" or whether this decision is up to the host language's interpretation of this question. Now, in either case, either some filtering at template-compile-time should be done, or strings should be explicitly handled.
I can provide a fix for this (I suggest handling strings as true
), but I'd like to know how the authors/maintainers see this issue.
I tried to create Reddit style nested comment, so I have this:
file: index.mustache
<div>Content: <br />
{{#contents}}
{{>content}}
{{/contents}}
</div>
file: content.mustache
<div id="Responder-{{key}}" style="display: none;">
<!-- some code -->
</div>
{{#responses}}
{{>content}}
{{/responses}}
</div>
when rendering, the root element is rendered as expected, but then every nested render will keep adding space around the {{key}}
:
render result:
root:
<div id="Responder-1" style="display: none;">
nested level 1 :
<div id="Responder- 2 " style="display: none;">
nested level 2 :
<div id="Responder- 3 " style="display: none;">
nested level 3 :
<div id="Responder- 4 " style="display: none;">
Is this behavior expected? Or there is another way?
This program:
extern crate mustache;
use std::io;
use mustache::MapBuilder;
fn main() {
let template = mustache::compile_str("{{ok}}").unwrap();
let data = MapBuilder::new()
.insert_bool("ok", true)
.build();
template.render_data(&mut io::stdout(), &data).unwrap();
println!();
}
fails with the following error:
thread 'main' panicked at 'bug: render_utag: unexpected value Bool(true).
Please report this issue on GitHub if you find an input that triggers this case.',
/home/justin/.cargo/registry/src/github.com-1ecc6299db9ec823/mustache-0.9.0/src/template.rs:224:25
Instead, I expect it to produce:
true
My thoughts:
render_utag
, but why should this be unescaped?Currently, if rendering to the provided io::Write object fails, the program will panic. To avoid this, the user must render to a buffer (that shouldn't fail), then copy the buffer to a file (which might fail for various reasons). The render_data() method and associated methods in RenderContext should not call unwrap() and instead should bubble up io::Errors.
It seems template fail to render entirely if they contain Option<String>
even so if that particular property isn't even used in the template. What's the reasoning behind that?
It fails with:
Error: Problem rendering template: "unsupported type"
/cc @Ryman
For my project (https://github.com/ayourtch/rsp10)
I would like to embed into the framework code the default formatting of the html elements, which implies that any partial under html/* would need to be loaded from within the framework rather than the file on disk..
Is that something that you might consider interesting to merge ? If no - then please discard the rest of this text :-)
If yes:
In particular, I plan to refactor out this bit: https://github.com/nickel-org/rust-mustache/blob/master/src/compiler.rs#L66..L90
Into something more pluggable.
One option seems to make a PartialsMap a trait, and abstract both the HashMap and the code to supply the text of the partials in there..
Another option is to allow to specify a closure Fn(&str)->Result, which would be called first and return Err to trigger the current behavior of loading from files...
Is either of these two acceptable ? Or there is some other approach ?
Thanks!
When you do a release to crates.io please push a tag for the corresponding revision to git. You can use cargo-release
to handle this for you automatically.
I'm building a very basic command line parser for mustache templates, it just wraps this library in StructOpt.
It would be nice to report an error if someone tried to render the template without giving all of the required variables.
Crates.io points to mustache.nickel.org, which seems to be non-existent.
Needed for nickel-org/nickel.rs#345
It'd be good to support serde
in templates, it doesn't look like this crate has any serialisable structs of its own, so it shouldn't be necessary to add dependencies on syntex
.
It would be nice to be able to do something along the lines of
template.escape(false).render(...)
Writing 3 curly braces gets tiresome when one expects this behaviour everywhere.
I'm building a map like this:
let data = mustache::MapBuilder::new()
.insert_str("test", "<test_&_string<")
.build();
And the generated string looks like this:
<test_&_string<
instead of like this:
<test_&_string>
I'm not sure if this is a bug or if there is a configuration of the builder that I'm missing.
Hi,
the link to the documentation page is broken:
I've created a minimal repro case to reproduce this panic, which requests I file an issue:
thread 'main' panicked at 'bug: render_utag: unexpected value VecVal([]). Please report this issue on GitHub if you find an input that triggers this case.', C:\Users\...\.cargo\registry\src\github.com-1ecc6299db9ec823\mustache-0.9.0\src\template.rs:224:25
[package]
name = "mustache-bug-repo"
version = "0.1.0"
edition = "2018"
[dependencies]
mustache = "=0.9.0"
fn main() {
let template = mustache::compile_str("{{authors}}").unwrap();
let data = mustache::MapBuilder::new()
.insert_vec("authors", |v| v)
.build();
let r = template.render_data_to_string(&data).unwrap();
}
When using a partial with indentation, only the first line is indented; the rest of the partial is rendered unindented. However, partials must inherit indentation as described in the spec, so I think this is a bug?
Here's a minimal example to reproduce the issue:
#[macro_use]
extern crate serde_derive;
use maplit::hashmap;
use std::io;
#[derive(Serialize)]
struct Person {
name: String,
}
fn main() {
let template = mustache::compile_path("greet_all.mustache").unwrap();
let people = hashmap! { "people" => vec![
Person { name: "Alice".to_string() },
Person { name: "Bob".to_string() },
]};
template.render(&mut io::stdout(), &people).unwrap();
println!();
}
Given templates:
{{! greet.mustache }}
hello {{{name}}}
nice to see you today
{{! greet_all.mustache }}
{{#people}}
{{> greet}}
{{/people}}
It should print:
hello Alice
nice to see you today
hello Bob
nice to see you today
But prints:
hello Alice
nice to see you today
hello Bob
nice to see you today
I don't see a way to trim trailing commas. I imagine it should be like this, but for it to work I need to evaluate the value prior to removing the trailing comma. Over in the OpenAPI generator, I can do {{^-last}},{{/-last}} to avoid printing the comma in the first place, but that does not work here.
.insert_fn("trim-trailing-comma", move |value| {
if value.ends_with(',') {
let mut chars = value.chars();
chars.next_back();
chars.as_str().to_string()
} else {
value.to_string()
}
})
From @viperscape:
let s = "hello {{}}";
let template = mustache::compile_str(s);
task '<main>' panicked at 'index out of bounds: the len is 0 but the index is 0', ~/.cargo/git/checkouts/rust-mustache-b850d4795ca6321d/master/src/lib.rs:1
An unknown error occurred
I've verified this panic is still happening.
like
let mut users: Vec<User> = ver![];
users.push(user1);
users.push(user2);
let mut data = HashMap::<&str, _>::new();
data.insert("users", users);
return res.render("views/posts.tpl",&data);
{{#users}}
{{name}}
{{/users}}
Calling mustache::compile_path(Path::new("foo.bar.mustache"))
will instead try to open "foo.mustache"
.
This is due to the updates to mustache::compile_path
interfering with the use of set_extension
in mustache::Context::compile_path
Hi and first of all thanks for your library! I had some issue with rustache so I am happy to see that there is an alternative. This said I was wondering if you could improve the example in a way to explain
a) how to define the template directory
b) how to achieve something as simple as rustache::render_file("path/to/template.html", data);
is this done by template.render ? not very clear
c) call me old fashion but I plan to use this to display data fetched from a database. These would go a long way for real time use !
In short (mostly my fault probably ..new to rust) from the current docs I don't really understand how to get up and running(which in mustache should be define the template, pass the data, render it).
If any of the dev team needs someone to sponsor (aka pay) for the time to write them I would be happy to support the project.
I'm trying to render a nested vector and I'm having no joy. The following code produces an error on v0.7 and an empty vector on HEAD:
let template = mustache::compile_str("{{#.}}{{#.}}{{.}}{{/.}}{{/.}}");
let data = vec![vec!["val1", "val2"]];
let mut r = Vec::new();
template.render(&mut r, &data).unwrap();
assert_eq!(r, b"val1val2");
As far as I can tell, this is valid Mustache syntax, though admittedly I am new to the game. Btw the error on v0.7 is panicked at 'expected map: [""]'
, if that is meaningful to someone?
Cheers!
Hello! I see this crate has some outstanding crates. I've got a little time to help maintain the project again, so I was wondering if I could get permission to merge in some of the outstanding pull requests?
for example, I want it to render output through user input, so I must have a way to know which name I need.
Do the recent changes merit creating a 0.8.1 version? The most recent commit would help with some bugs we have.
Getting a panic when I try to print the entire object. The object is a map of with value foo: bar
{{#cloud2}}
{{.}}
{{/cloud2}}
thread 'main' panicked at 'bug: render_utag: unexpected value Map({"foo": StrVal(bar)}). Please report this issue on GitHub if you find an input that triggers this case.', /usr/local/rust/registry/src/github.com-1ecc6299db9ec823/mustache-0.9.0/src/template.rs:224:25
If you take a template like this: {{#my_fn}} {{foo}} {{/my_fn}}
And build it with:
MapBuilder::new()
.insert_str("foo", "hello")
.insert_fn("my_fn", move |input| {
println!("{:?}", input);
format!("")
});
The value of input
is {{foo}}
instead of hello
as expected.
I don't really know what the specs say, but with the Javascript implementation the inside of function tags being processed as well.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.