January 02, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to yazd | On Thursday, 2 January 2014 at 06:59:04 UTC, yazd wrote: > How much of this is done at compile-time? Strictly speaking, just the generation of the code that writes the template to the output buffer. E.g, the code above simulating the Rails form helper would be lowered to code approximately equivalent to this (but with more fluff to add line numbers, and expose some needed hooks for the context): ``` void Temple(OutputStream __buff, TempleContext __context = null) { //... //struct FormHelper, etc //... // The actual rendering into a buffer code auto __buff_tmp_0 = form_for("/shorten", "", (f) { __buff.put("Shorten a URL: "); __buff.put(to!string( f.field_for("url") )); __buff.put(to!string( f.submit("Shorten URL") )); }); __buff.put(__buff_tmp_0); auto __buff_tmp_1 = form_for("/person", "person", (f) { __buff.put("Name: "); __buff.put(to!string( f.field_for("name") )); __buff.put("Age: "); __buff.put(to!string( f.field_for("age") )); __buff.put("DOB: "); __buff.put(to!string( f.field_for("date_of_birth", "date") )); __buff.put(to!string( f.submit )); }); __buff.put(__buff_tmp_1); } ``` >I would guess that > the code is compiled but it is evaluated on each render. Is that correct? Is there a way to force compile-time evaluation of at least part of the template which does not depend on a runtime value? Yes, generated templates themselves can be executed with CTFE (just had to make a small modification to ArrayOutputAppender, which has been pushed), as long as they don't take a context. The reason for this is that std.variant.Variant isn't CTFEable, because it uses memcpy in opAssign. I'd consider that a Phobos bug; perhaps there is a way to make std.variant CTFE compatible? That'd allow for a much wider (and more useful) range of templates to be evaluated at compile time. Anyways, here's a working compile time evaluated, compile time generated template: ``` string templeToString(TempleFuncType* func, TempleContext context = null) { auto accum = new AppenderOutputStream; (*func)(accum, context); return accum.data; } unittest { alias render = Temple!q{ <% if(true) { %> Bort <% } else { %> No bort! <% } %> <% auto a = capture(() { %> inside a capture block <% }); %> Before capture <%= a %> After capture }; const result = templeToString(&render); static assert(isSameRender(result, ` Bort Before capture inside a capture block After capture `)); } ``` |
January 02, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dylan Knutson | On 2014-01-02 02:12, Dylan Knutson wrote: > It didn't before, because of how the semantics of eRuby syntax works, > but now it does! It seemed like an important thing to support... > > Here's an example mimicking a subset of Rails' `form_for` helper: > [Snip] Nice. Do you have any concept of safe vs unsafe strings? -- /Jacob Carlborg |
January 02, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thursday, 2 January 2014 at 10:59:27 UTC, Jacob Carlborg wrote:
> On 2014-01-02 02:12, Dylan Knutson wrote:
>
>> It didn't before, because of how the semantics of eRuby syntax works,
>> but now it does! It seemed like an important thing to support...
>>
>> Here's an example mimicking a subset of Rails' `form_for` helper:
>> [Snip]
>
> Nice. Do you have any concept of safe vs unsafe strings?
No, but that's been on the to-do list. I feel like safe vs. unsafe strings are tied heavily with the escaping of unsafe strings, which is specific to a language, so I think the best way to go about this is to provide:
- A way to define custom "string" types (like a struct wrapping a string tracking if it's safe or not)
- Callbacks for processing all of the string-ey things written to the output buffer, to decide if something should be escaped or not.
|
January 03, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Thursday, 2 January 2014 at 10:59:27 UTC, Jacob Carlborg wrote: > Nice. Do you have any concept of safe vs unsafe strings? That's a really good idea... [the day passes by] Support implemented in v0.5.0: https://github.com/dymk/temple#filter-policies FilterPolicies allow the developer to insert hooks for when an expression is appended to the buffer. This can be overloaded for different types of expressions, letting concepts like Tainted strings (e.g. your safe vs. unsafe strings) to be implemented. I added an example to the README showing a simple example of this. |
January 03, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dylan Knutson | On 2014-01-03 09:39, Dylan Knutson wrote: > That's a really good idea... > [the day passes by] > > Support implemented in v0.5.0: > https://github.com/dymk/temple#filter-policies > > FilterPolicies allow the developer to insert hooks for when an > expression is appended to the buffer. This can be overloaded for > different types of expressions, letting concepts like Tainted strings > (e.g. your safe vs. unsafe strings) to be implemented. I added an > example to the README showing a simple example of this. Cool :) -- /Jacob Carlborg |
January 03, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dylan Knutson | On Thursday, 2 January 2014 at 08:36:24 UTC, Dylan Knutson wrote:
> The reason for this is that std.variant.Variant isn't CTFEable, because it uses memcpy in opAssign. I'd consider that a Phobos bug; perhaps there is a way to make std.variant CTFE compatible? That'd allow for a much wider (and more useful) range of templates to be evaluated at compile time.
I wish Variant worked at compile time myself. Did you file a bug/enhancement request? (I couldn't find one in bugzilla).
|
January 03, 2014 Re: Temple: Compile time, embedded D templates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicolas Sicard | On Friday, 3 January 2014 at 17:50:22 UTC, Nicolas Sicard wrote: > I wish Variant worked at compile time myself. Did you file a bug/enhancement request? (I couldn't find one in bugzilla). https://d.puremagic.com/issues/show_bug.cgi?id=11864 Doing some more tests, it seems like just about any template can be evaluated at compile time, if they don't set variables on the context (via var.name, or var("name")). I was surprised to find even filters work for CTFE'd templates! |
Copyright © 1999-2021 by the D Language Foundation