Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The global and local scope of a variable #128

Open
GiggleLiu opened this issue Oct 19, 2020 · 4 comments
Open

The global and local scope of a variable #128

GiggleLiu opened this issue Oct 19, 2020 · 4 comments

Comments

@GiggleLiu
Copy link
Contributor

GiggleLiu commented Oct 19, 2020

Current parser will search for local scope first and then the global scope, e.g.

julia> render("{{#l}}{{first}}{{second}}{{/l}}{{first}}", Dict("l"=>("x"=>"y"), "first"=>"z"))
"xyz"

Is it possible to invoke the global variable when names clash? e.g. with a !

julia> render("{{#l}}{{!first}}{{second}}{{/l}}{{first}}", Dict("l"=>("x"=>"y"), "first"=>"z"))
"zyz"

Note:
In my using case, I wish to identity the (global) variables that a user need to provide by inspecting the string only. Which means the global variables used in the local context should be identified. In Mustache.js, the global variables can not be accessed, see: janl/mustache.js#399 .

@GiggleLiu GiggleLiu changed the title The scope of variable The global and local scope of a variable Oct 19, 2020
@jverzani
Copy link
Owner

Hmm, I think this would require modifying lookup in context.jl. In glancing at the code the default is fairly baked in, but let me think about it.

@jverzani jverzani mentioned this issue Oct 20, 2020
@jverzani
Copy link
Owner

Can you check if #129 does what you want? I used ~ in place of !, but with this PR the following works:

julia> render("{{#l}}{{~first}}{{second}}{{/l}}{{first}}", Dict("l"=>("x"=>"y"), "first"=>"z"))
"zyz"

julia> render("{{#l}}{{first}}{{second}}{{/l}}{{first}}", Dict("l"=>("x"=>"y"), "first"=>"z"))
"xyz"

I'm not sure I implemented it properly, so some testing would be nice.

@jverzani
Copy link
Owner

This example exposed an issue with using Pair elements in a view. They were passed off to the catch all and so first matches the fieldname first in the pair. It seems that pairs should parallel a dictionary, though, where the variable should match the key and return the paired value. I made that the default going forward, but special cased the use of first and second for now.

Without that change, this example wasn't working:

tpl = mt"""
{{#:one}}
{{#:two}}
{{~:x}}
{{/:two}}
{{/:one}}
"""
d = Dict(:two=>(:x=>3), :x=>2)
render(tpl, one=d) # "2\n"
render(tpl, one=d, x=1) # "1\n"
tpl = mt"""
{{#:one}}
{{#:two}}
{{:x}}
{{/:two}}
{{/:one}}
"""
render(tpl, one=d, x=1) # "3\n"

@GiggleLiu
Copy link
Contributor Author

Nice, I am happy with the PR, it solves my issue. It would be good to put the above examples in the tests to help people understand.

Regarding your concern, I think

d = Dict(:two=>Dict(:x=>3), :x=>2)

is more intuitive.
But it does not harm to allow both.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants