OK, actually, that's not nearly half as bad. Variables contained in a 
module 

include("src/Ejl_str.jl")
using Ejl


module _
  couñtry = "España"
  lang = "en"
end


function render_template()
  tpl_data = ejl"""
<% if _.lang == "en" :>
Hello from me, ...
<: else :>
Hola
<: end %>


%= _.couñtry == "España" ? "Olé" : "Aye"
moo
"""


  include_string(join(tpl_data, "\n"))
  join(____output, "\n")
end


render_template() |> println

Hello from me, ...


Olé
moo


duminică, 14 august 2016, 11:20:37 UTC+2, Adrian Salceanu a scris:
>
> Thanks
>
> Yes, I've thought about a few ways to mitigate some of these issues: 
>
> 1. in the app I can setup a module (like Render) and evaluate into this 
> module exclusively. 
> Hence, another approach might be to have some helper methods that setup 
> the variables in the module and then eval the template itself inside the 
> module too (must try though). So something in the lines of: 
> set(:foo, "foo")
> set(:bar, [1, 2, 3])
> parse_tpl(ejl"""$(foo) and $(bar)""")
> # all the above gets parsed in Render
>
> 2. break the parsing in 2 steps: 
> a. reading the template string and parse it to generated Julia code (as 
> strings) (an array of Julia code lines) - cache it 
> b. (load strings from cache and) eval the code together with the vars 
>
> ===
>
> Another approach (which is how it's done in one of the Ruby templating 
> engine) is to generate a full function definition, whose body parses the 
> template and takes the variables as params. And then eval and execute the 
> function with its params. However, I'm still struggling with the 
> metaprogramming API as for instance parse() chokes on multiple lines, and I 
> couldn't find a functional equivalent of a quote ... end blocks. But I'm 
> hoping include_string() will do the trick (must test though). 
>
>
> sâmbătă, 13 august 2016, 15:20:01 UTC+2, Yichao Yu a scris:
>>
>>
>>
>> On Sat, Aug 13, 2016 at 8:06 PM, Adrian Salceanu <[email protected]> 
>> wrote:
>>
>>> That's pretty difficult as my goal is to use embedded Julia as the 
>>> templating language. Similar to Ruby's ERB, ex: 
>>> http://www.stuartellis.eu/articles/erb/
>>>
>>> So say in the template I have something like 
>>>
>>> <% if foo == "bar" %>
>>> Bar
>>> <% else %>
>>> Baz
>>> <% end %>
>>>
>>> The idea is to use Julia itself to parse the code block and Julia will 
>>> raise an error is foo is not defined. So I can't really look it up. 
>>>
>>
>> It's ok to use the julia syntax and parser but it's a pretty bad idea to 
>> use the julia runtime to actually evaluating the expression, and absolutely 
>> not by making them reference to local variables.
>>
>> For a start you are not allowed to reference local variables by names 
>> anyway.
>> You also shouldn't allow reference to/overwrite of other local variables 
>> (i.e. the template namespace should be fully isolated and independent of 
>> any scope in the template engine).
>>
>> Since you want to eval, it seems that efficiency is not an issue, in 
>> which case you can create an anonymous module and eval/create globals in 
>> that module. This should also be reasonably fast if you are only using the 
>> template once.
>>
>> If you want to use it multiple time and compile the template, you should 
>> then scan for variable references in the expressions and process it from 
>> there.
>>  
>>
>>>
>>> I can either do 
>>>
>>> <% if _[:foo] == "bar" %> 
>>>
>>> or 
>>>
>>> <% if _(:foo) == "bar" %>
>>>
>>> but it's not that nice. 
>>>
>>>
>>> sâmbătă, 13 august 2016, 13:24:18 UTC+2, Yichao Yu a scris:
>>>>
>>>>
>>>>
>>>> On Sat, Aug 13, 2016 at 7:13 PM, Adrian Salceanu <[email protected]> 
>>>> wrote:
>>>>
>>>>> Thanks
>>>>>
>>>>> It's for a templating engine. The user creates the document (a string) 
>>>>> which contains interpolated variables placeholders and markup. When the 
>>>>> template is rendered, the placeholders must be replaced with the 
>>>>> corresponding values from the dict.
>>>>>
>>>>> The lines in the template are eval-ed and so Julia will look for the 
>>>>> variables in the scope. So the vars should be already defined.
>>>>>
>>>>
>>>> You should explicitly look up those variables in the dict instead.
>>>>  
>>>>
>>>>>
>>>>> Yes, ultimately I can force the user to use a dict (or rather a 
>>>>> function for a bit of semantic sugar) - which is preferable from a 
>>>>> performance perspective, but less pretty end error prone from the user 
>>>>> perspective.
>>>>
>>>>
>>>>
>>

Reply via email to