Jump to page: 1 2
Thread overview
Temple: Compile time, embedded D templates
Dec 31, 2013
Dylan Knutson
Dec 31, 2013
Jacob Carlborg
Jan 01, 2014
Dylan Knutson
Jan 01, 2014
Dylan Knutson
Jan 01, 2014
Jacob Carlborg
Jan 01, 2014
Jacob Carlborg
Jan 01, 2014
Jacob Carlborg
Jan 02, 2014
Dylan Knutson
Jan 02, 2014
Dylan Knutson
Jan 02, 2014
yazd
Jan 02, 2014
Dylan Knutson
Jan 03, 2014
Nicolas Sicard
Jan 03, 2014
Dylan Knutson
Jan 02, 2014
Jacob Carlborg
Jan 02, 2014
Dylan Knutson
Jan 03, 2014
Dylan Knutson
Jan 03, 2014
Jacob Carlborg
December 31, 2013
Hello,

A few months ago I had posted a project of mine, templ-d. It was an experiment in writing a template engine for embedding D code in arbitrary text files, a-la Vibe.d's Diet templates, but without the requirement of generating HTML.

So, I've revamped templ-d, and written Temple in its place. It supports all the neat stuff that a template engine should, including (but not limited to!)

 - Nested templates (`render` templates within templates)
 - Layouts that can `yield` to partials
 - Compile time generation of the template functions, for zero overhead rendering
 - Writes to an OutputStream (a type of OutputRange), making it compatible with Vibe.d
 - Easy to work with template contexts, for passing runtime variables to templates.

The syntax is based off of eRuby, the templating engine for Ruby on Rails, so it should be very recognizable to the RoR devs here, and very intuitive to use for those who haven't used eRuby before.

There's a much more in depth rundown, as well as a plethora of examples, in the README on the project's page, here:

https://github.com/dymk/temple

dub package: http://code.dlang.org/packages/temple

Thanks, and please let me know what you think!
December 31, 2013
On 2013-12-31 07:05, Dylan Knutson wrote:
> Hello,
>
> A few months ago I had posted a project of mine, templ-d. It was an
> experiment in writing a template engine for embedding D code in
> arbitrary text files, a-la Vibe.d's Diet templates, but without the
> requirement of generating HTML.
>
> So, I've revamped templ-d, and written Temple in its place. It supports
> all the neat stuff that a template engine should, including (but not
> limited to!)

Looks quite nice.

Since you support setting variables in a context using opDispatch, why no support opDispatch to get the variables as well? Something like this:

Hello, <%= var.name %>

And to convert to a specific type:

% if(var.should_bort!bool) {

-- 
/Jacob Carlborg
January 01, 2014
On Tuesday, 31 December 2013 at 13:10:53 UTC, Jacob Carlborg wrote:
> On 2013-12-31 07:05, Dylan Knutson wrote:
>> Hello,
>>
>> A few months ago I had posted a project of mine, templ-d. It was an
>> experiment in writing a template engine for embedding D code in
>> arbitrary text files, a-la Vibe.d's Diet templates, but without the
>> requirement of generating HTML.
>>
>> So, I've revamped templ-d, and written Temple in its place. It supports
>> all the neat stuff that a template engine should, including (but not
>> limited to!)
>
> Looks quite nice.
>
> Since you support setting variables in a context using opDispatch, why no support opDispatch to get the variables as well? Something like this:
>
> Hello, <%= var.name %>
>
> And to convert to a specific type:
>
> % if(var.should_bort!bool) {


Ah yeah, I quite like that. I tried to implement the `var.should_bort!bool` syntax, but I can't pass an additional type parameter to opDispatch, other than the string of the method it's dispatching to. Is there a way to do that? Something like this:

struct Params
{
private:
	Variant[string] vars;

public:
	T opDispatch(string op, T)() @property
	{
		return vars[op].get!T;
	}
}
January 01, 2014
Added a goodie: Nestable capture blocks (like pseudo-templates inside your templates)

This template:
```
		<% auto outer = capture(() { %>
			Outer, first
			<% auto inner = capture(() { %>
				Inner, first
			<% }); %>
			Outer, second

			<%= inner %>
		<% }); %>

		<%= outer %>
```

Evaluates to this:
```
		Outer, first
		Outer, second
			Inner, first
```

a-la Rail's capture helper. It was slightly strange to implement, and means tighter coupling between the template function and a template context, but I think at this point that's alright, given the two are yin and yang anyways.

Right now they don't lazily evaluate; would it be desirable for them to do so?
January 01, 2014
On 2014-01-01 04:24, Dylan Knutson wrote:

> Ah yeah, I quite like that. I tried to implement the
> `var.should_bort!bool` syntax, but I can't pass an additional type
> parameter to opDispatch, other than the string of the method it's
> dispatching to. Is there a way to do that? Something like this:
>
> struct Params
> {
> private:
>      Variant[string] vars;
>
> public:
>      T opDispatch(string op, T)() @property
>      {
>          return vars[op].get!T;
>      }
> }

I was pretty sure that was possible, but apparently it doesn't compile.

-- 
/Jacob Carlborg
January 01, 2014
On 2014-01-01 12:53, Jacob Carlborg wrote:

> I was pretty sure that was possible, but apparently it doesn't compile.

Reported as: https://d.puremagic.com/issues/show_bug.cgi?id=11855

-- 
/Jacob Carlborg
January 01, 2014
On 2013-12-31 07:05, Dylan Knutson wrote:
> Hello,
>
> A few months ago I had posted a project of mine, templ-d. It was an
> experiment in writing a template engine for embedding D code in
> arbitrary text files, a-la Vibe.d's Diet templates, but without the
> requirement of generating HTML.
>
> So, I've revamped templ-d, and written Temple in its place. It supports
> all the neat stuff that a template engine should, including (but not
> limited to!)

Does it support any kind of helpers, like Rails do?

-- 
/Jacob Carlborg
January 02, 2014
On Wednesday, 1 January 2014 at 13:04:27 UTC, Jacob Carlborg wrote:
> On 2013-12-31 07:05, Dylan Knutson wrote:
>> Hello,
>>
>> A few months ago I had posted a project of mine, templ-d. It was an
>> experiment in writing a template engine for embedding D code in
>> arbitrary text files, a-la Vibe.d's Diet templates, but without the
>> requirement of generating HTML.
>>
>> So, I've revamped templ-d, and written Temple in its place. It supports
>> all the neat stuff that a template engine should, including (but not
>> limited to!)
>
> Does it support any kind of helpers, like Rails do?

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:

```d
<%
import std.string;
struct FormHelper
{
	string model_name;

	auto field_for(string field_name, string type="text")
	{
		if(model_name != "")
		{
			field_name = "%s[%s]".format(model_name, field_name);
		}

		return `<input type="%s" name="%s" />`.format(type, field_name);
	}

	auto submit(string value = "Submit")
	{
		return `<input type="button" value="%s" />`.format(value);
	}
}

auto form_for(
	string action,
	string name,
	void delegate(FormHelper) block)
{
	auto form_body = capture(block, FormHelper(name));
	return `
		<form action="%s" method="POST">
			%s
		</form>`.format(action, form_body);
}
%>

<%= form_for("/shorten", "", (f) { %>
	Shorten a URL:
	<%= f.field_for("url") %>
	<%= f.submit("Shorten URL") %>
<% }); %>

<%= form_for("/person", "person", (f) { %>
	Name: <%= f.field_for("name") %>
	Age: <%= f.field_for("age") %>
	DOB: <%= f.field_for("date_of_birth", "date") %>
	<%= f.submit %>
<% }); %>
```

Renders:
```
<form action="/shorten" method="POST">
	Shorten a URL:
	<input type="text" name="url" />
	<input type="button" value="Shorten URL" />
</form>

<form action="/person" method="POST">
	Name: <input type="text" name="person[name]" />
	Age: <input type="text" name="person[age]" />
	DOB: <input type="date" name="person[date_of_birth]" />
	<input type="button" value="Submit" />
</form>
```

This change is present in the latest release of Temple
January 02, 2014
I've made a post on Reddit, if anyone that found the library nifty would like to upvote:

http://www.reddit.com/r/programming/comments/1u71sr/temple_compile_time_embedded_templating_engine/
January 02, 2014
On Thursday, 2 January 2014 at 01:12:24 UTC, Dylan Knutson wrote:
> On Wednesday, 1 January 2014 at 13:04:27 UTC, Jacob Carlborg wrote:
>> On 2013-12-31 07:05, Dylan Knutson wrote:
>>> Hello,
>>>
>>> A few months ago I had posted a project of mine, templ-d. It was an
>>> experiment in writing a template engine for embedding D code in
>>> arbitrary text files, a-la Vibe.d's Diet templates, but without the
>>> requirement of generating HTML.
>>>
>>> So, I've revamped templ-d, and written Temple in its place. It supports
>>> all the neat stuff that a template engine should, including (but not
>>> limited to!)
>>
>> Does it support any kind of helpers, like Rails do?
>
> 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:
>
> ```d
> <%
> import std.string;
> struct FormHelper
> {
> 	string model_name;
>
> 	auto field_for(string field_name, string type="text")
> 	{
> 		if(model_name != "")
> 		{
> 			field_name = "%s[%s]".format(model_name, field_name);
> 		}
>
> 		return `<input type="%s" name="%s" />`.format(type, field_name);
> 	}
>
> 	auto submit(string value = "Submit")
> 	{
> 		return `<input type="button" value="%s" />`.format(value);
> 	}
> }
>
> auto form_for(
> 	string action,
> 	string name,
> 	void delegate(FormHelper) block)
> {
> 	auto form_body = capture(block, FormHelper(name));
> 	return `
> 		<form action="%s" method="POST">
> 			%s
> 		</form>`.format(action, form_body);
> }
> %>
>
> <%= form_for("/shorten", "", (f) { %>
> 	Shorten a URL:
> 	<%= f.field_for("url") %>
> 	<%= f.submit("Shorten URL") %>
> <% }); %>
>
> <%= form_for("/person", "person", (f) { %>
> 	Name: <%= f.field_for("name") %>
> 	Age: <%= f.field_for("age") %>
> 	DOB: <%= f.field_for("date_of_birth", "date") %>
> 	<%= f.submit %>
> <% }); %>
> ```
>
> Renders:
> ```
> <form action="/shorten" method="POST">
> 	Shorten a URL:
> 	<input type="text" name="url" />
> 	<input type="button" value="Shorten URL" />
> </form>
>
> <form action="/person" method="POST">
> 	Name: <input type="text" name="person[name]" />
> 	Age: <input type="text" name="person[age]" />
> 	DOB: <input type="date" name="person[date_of_birth]" />
> 	<input type="button" value="Submit" />
> </form>
> ```
>
> This change is present in the latest release of Temple

How much of this is done at compile-time? 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? Or is it completely dependant on an optimizing compiler to do this work?
« First   ‹ Prev
1 2