Skip to content

Commit a41818c

Browse files
authored
Merge pull request #58 from gasche/template-inheritance
Hogan-style template inheritance
2 parents 5eafe34 + 9e4daeb commit a41818c

30 files changed

+992
-184
lines changed

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
### 3.2.0
22

3+
* Support for "template inheritance" (partials with parameters)
4+
`{{<foo}} {{$param1}}...{{/param1}} {{$param2}}...{{/param2}} {{/foo}`
5+
following the widely-implemented semi-official specification
6+
https://github.com/mustache/spec/pull/75
7+
(@gasche, 58)
38
* Partials are now supported in the `mustache` command-line tool (@gasche, #57)
49
They are interpreted as template inclusion: "{{>foo/bar}}" will include
510
"foo/bar.mustache", relative to the current working directory.

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,18 @@ let rendered =
3636
exit 2
3737
```
3838

39-
Spec compliance
40-
-----------
39+
Supported template language
40+
---------------------------
41+
42+
ocaml-mustache accepts the whole Mustache template language, except:
43+
- it does not support setting delimiter tags to something else than '{{' and '}}'.
44+
- it does not support lambdas inside the provided data
4145

42-
ocaml-mustache complies¹ to the latest [mustache specification](https://github.com/mustache/spec/tree/v1.1.3), and is automatically tested against it.
46+
It is automatically tested against the latest
47+
[mustache specification testsuite](https://github.com/mustache/spec/tree/v1.1.3).
4348

44-
¹: except for lambdas and set delimiters tags.
49+
ocaml-mustache also supports template inheritance / partials with parameters,
50+
tested against the [semi-official specification](https://github.com/mustache/spec/pull/75).
4551

4652
Todo/Wish List
4753
-----------

bin/mustache_cli.ml

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,19 @@ let manpage = Cmdliner.[
150150
(leftmost $(b,-I) option) has precedence, and the current working directory has precedence
151151
over include directories.";
152152

153+
`S "TEMPLATE INHERITANCE / PARTIALS WITH PARAMETERS";
154+
155+
`P "$(i,ocaml-mustache) supports a common extension to the original Mustache specification,
156+
called 'template inheritance' or 'parent partials', or here 'partials with parameters'.
157+
In addition to usual partials '{{>foo}}', which include a partial template, one can use
158+
the syntax '{{<bar}} {{\\$param1}}...{{/param1}} {{\\$param2}}...{{/param2}} {{/bar}}' to
159+
pass parameters to the included partial template. Inside this included template, parameters
160+
are used as '{{\\$param}}...{{/param}}', with the inner content being used by default
161+
if this parameter was not specified by the caller.";
162+
163+
`P "This is typically used to define page layouts that are wrapped 'around' the current template.
164+
See our EXAMPLES.";
165+
153166
`S Manpage.s_examples;
154167
`Pre {|
155168
## Simple usage.
@@ -172,7 +185,7 @@ Mustache is:
172185
- fun
173186

174187

175-
## Using a partial to include a subpage; see $(b,PARTIALS).
188+
## Including a subpage; see $(b,PARTIALS).
176189

177190
\$ cat page.mustache
178191
<html>
@@ -189,6 +202,47 @@ Mustache is:
189202
- simple
190203
- fun
191204
</body>
205+
</html>
206+
207+
208+
## Including a layount around a page; see $(b,PARTIALS WITH PARAMETERS).
209+
210+
\$ cat new-post.json
211+
{
212+
"title": "New Post",
213+
"authors": "Foo and Bar",
214+
"date": "today",
215+
"content": "Shiny new content."
216+
}
217+
218+
\$ cat post.mustache
219+
{{<post-layout}}
220+
{{\$page-title}}Post: {{title}}{{/page-title}}
221+
{{\$content}}
222+
<h1>{{title}}</h1>
223+
<p>{{content}}</p>
224+
{{/content}}
225+
{{/post-layout}}
226+
227+
\$ cat post-layout.mustache
228+
<html>
229+
<head>
230+
<title>{{\$page-title}}Default Title{{/page-title}}</title>
231+
</head>
232+
<body>
233+
{{\$content}}{{/content}}
234+
</body>
235+
</html>
236+
237+
\$ $(tname) new-post.json post.mustache
238+
<html>
239+
<head>
240+
<title>Post: New Post</title>
241+
</head>
242+
<body>
243+
<h1>New Post</h1>
244+
<p>Shiny new content.</p>
245+
</body>
192246
</html>|};
193247

194248
`S "CONFORMING TO";
@@ -200,6 +254,9 @@ Mustache is:
200254
`I ("Mustache specification testsuite",
201255
"https://github.com/mustache/spec");
202256

257+
`I ("Semi-official specification of PARTIALS WITH PARAMETERS",
258+
"https://github.com/mustache/spec/pull/75");
259+
203260
`S "REPORTING BUGS";
204261
`P "Report bugs on https://github.com/rgrinberg/ocaml-mustache/issues";
205262
]

bin/test/errors/parsing-errors.t

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Delimiter problems:
2828
$ PROBLEM=eof-before-section-end.mustache
2929
$ echo "{{#foo}} {{.}} {{/" > $PROBLEM
3030
$ mustache foo.json $PROBLEM
31-
File "eof-before-section-end.mustache", line 2, character 0: ident expected.
31+
File "eof-before-section-end.mustache", line 2, character 0: '}}' expected.
3232
[3]
3333
3434
$ PROBLEM=eof-before-inverted-section.mustache
@@ -84,7 +84,7 @@ Mismatch between section-start and section-end:
8484
$ echo "{{#foo}} {{.}} {{/bar}}" > $PROBLEM
8585
$ mustache foo.json $PROBLEM
8686
File "foo-bar.mustache", line 1, characters 0-23:
87-
Section mismatch: {{#foo}} is closed by {{/bar}}.
87+
Open/close tag mismatch: {{# foo }} is closed by {{/ bar }}.
8888
[3]
8989
9090
$ PROBLEM=foo-not-closed.mustache
@@ -97,9 +97,24 @@ Mismatch between section-start and section-end:
9797
$ echo "{{#bar}} {{#foo}} {{.}} {{/bar}} {{/foo}}" > $PROBLEM
9898
$ mustache foo.json $PROBLEM
9999
File "wrong-nesting.mustache", line 1, characters 9-32:
100-
Section mismatch: {{#foo}} is closed by {{/bar}}.
100+
Open/close tag mismatch: {{# foo }} is closed by {{/ bar }}.
101101
[3]
102102
103+
$ PROBLEM=wrong-nesting-variable.mustache
104+
$ echo '{{#bar}} {{$foo}} {{.}} {{/bar}} {{/foo}}' > $PROBLEM
105+
$ mustache foo.json $PROBLEM
106+
File "wrong-nesting-variable.mustache", line 1, characters 9-32:
107+
Open/close tag mismatch: {{$ foo }} is closed by {{/ bar }}.
108+
[3]
109+
110+
$ PROBLEM=wrong-nesting-partial.mustache
111+
$ echo "{{#foo}} {{<foo-bar}} {{/foo}} {{/foo-bar}}" > $PROBLEM
112+
$ mustache foo.json $PROBLEM
113+
File "wrong-nesting-partial.mustache", line 1, characters 9-30:
114+
Open/close tag mismatch: {{< foo-bar }} is closed by {{/ foo }}.
115+
[3]
116+
117+
103118
104119
Weird cases that may confuse our lexer or parser:
105120
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
{{$header}}{{/header}}
3+
<body>
4+
{{$content}}{{/content}}
5+
</body>
6+
</html>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<head>
2+
<title>{{$title}}Default title{{/title}}</title>
3+
</head>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{{<base}}
2+
{{$header}}
3+
{{<header}}
4+
{{$title}}My page title{{/title}}
5+
{{/header}}
6+
{{/header}}
7+
{{$content}}
8+
<h1>Hello world</h1>
9+
{{/content}}
10+
{{/base}}

bin/test/inheritance.t/run.t

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
$ echo "{}" > data.json
2+
3+
This test is the reference example from the template-inheritance specification:
4+
https://github.com/mustache/spec/pull/75
5+
6+
$ mustache data.json mypage.mustache
7+
<html>
8+
<head>
9+
<title>My page title</title>
10+
</head>
11+
<body>
12+
<h1>Hello world</h1>
13+
</body>
14+
</html>
15+
16+
17+
We also test the indentation of parameter blocks.
18+
19+
$ mustache data.json test-indent-more.mustache
20+
<p>
21+
The test below should be indented in the same way as this line.
22+
This text is not indented in the source,
23+
it should be indented naturally in the output.
24+
</p>
25+
26+
$ mustache data.json test-indent-less.mustache
27+
<p>
28+
The test below should be indented in the same way as this line.
29+
This text is very indented in the source,
30+
it should be indented naturally in the output.
31+
</p>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{{<test-indentation}}
2+
{{$indented-block}}
3+
This text is very indented in the source,
4+
it should be indented naturally in the output.
5+
{{/indented-block}}
6+
{{/test-indentation}}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{{<test-indentation}}
2+
{{$indented-block}}
3+
This text is not indented in the source,
4+
it should be indented naturally in the output.
5+
{{/indented-block}}
6+
{{/test-indentation}}

0 commit comments

Comments
 (0)