Skip to content

Commit 471e700

Browse files
committed
have partials interpreted as template inclusion in mustache_cli
(Before this PR, any use of partials will fail in the command-line tool.) Partial names are turned into filenames by adding ".mustache" and then resolveas paths relative to the current working directory (from which the tool is invoked, not the directory where the template file is located). For example, `{{>foo/bar}}` would include "foo/bar.mustache". This behavior is used by other command-line mustache processors, typically the Ruby implementation (`gem install mustache`), so it is somewhat-standard for a default behavior of partials. Note: the Ruby implementation also supports {{> ../foo/bar}}, which is not accepted by our current lexer (partial names must use dots in a way that would be valid for other tags). The lexer could be relaxed to allow those, but this can come as a later change.
1 parent 7d7cf77 commit 471e700

File tree

8 files changed

+48
-27
lines changed

8 files changed

+48
-27
lines changed

CHANGES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
### 3.2.0
22

3-
* Improve error messages (@gasche, #47 and #51)
3+
* Partials are now supported in the `mustache` command-line tool (@gasche, #57)
4+
They are interpreted as template inclusion: "{{>foo/bar}}" will include
5+
"foo/bar.mustache", relative to the current working directory.
6+
* Improve error messages (@gasche, #47, #51, #56)
47
Note: the exceptions raised by Mustache have changed, this breaks
58
compatibility for users that would catch and deconstruct existing
69
exceptions.

bin/mustache_cli.ml

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,6 @@ module Mustache = struct
33
include With_locations
44
end
55

6-
let apply_mustache ~json_data ~template_filename ~template_data =
7-
let env = Ezjsonm.from_string json_data
8-
and tmpl =
9-
let lexbuf = Lexing.from_string template_data in
10-
let () =
11-
let open Lexing in
12-
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = template_filename };
13-
in
14-
try Mustache.parse_lx lexbuf
15-
with Mustache.Template_parse_error err ->
16-
Format.eprintf "Template parse error:@\n%a@."
17-
Mustache.pp_template_parse_error err;
18-
exit 3
19-
in
20-
try Mustache.render tmpl env |> print_endline
21-
with Mustache.Render_error err ->
22-
Format.eprintf "Template render error:@\n%a@."
23-
Mustache.pp_render_error err;
24-
exit 2
25-
266
let load_file f =
277
let ic = open_in f in
288
let n = in_channel_length ic in
@@ -31,11 +11,34 @@ let load_file f =
3111
close_in ic;
3212
(Bytes.to_string s)
3313

34-
let run json_filename template_filename =
35-
let json_data = load_file json_filename
36-
and template_data = load_file template_filename
14+
let load_template template_filename =
15+
let template_data = load_file template_filename in
16+
let lexbuf = Lexing.from_string template_data in
17+
let () =
18+
let open Lexing in
19+
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = template_filename };
3720
in
38-
apply_mustache ~json_data ~template_filename ~template_data
21+
try Mustache.parse_lx lexbuf
22+
with Mustache.Template_parse_error err ->
23+
Format.eprintf "Template parse error:@\n%a@."
24+
Mustache.pp_template_parse_error err;
25+
exit 3
26+
27+
let load_json json_filename =
28+
Ezjsonm.from_string (load_file json_filename)
29+
30+
let run json_filename template_filename =
31+
let env = load_json json_filename in
32+
let tmpl = load_template template_filename in
33+
let partials name =
34+
let path = Printf.sprintf "%s.mustache" name in
35+
if not (Sys.file_exists path) then None
36+
else Some (load_template path) in
37+
try Mustache.render ~partials tmpl env |> print_endline
38+
with Mustache.Render_error err ->
39+
Format.eprintf "Template render error:@\n%a@."
40+
Mustache.pp_render_error err;
41+
exit 2
3942

4043
let usage () =
4144
print_endline "Usage: mustache-cli json_filename template_filename"

bin/test/dune

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(cram
2+
(deps %{bin:mustache}))

bin/test/errors/sys-errors.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
$ touch foo.json
2-
$ touch foo.mustache
1+
$ echo "{}" > foo.json
2+
$ echo "" > foo.mustache
33

44
Nonexistent json file:
55
$ mustache nonexistent.json foo.mustache

bin/test/partials.t/bar.mustache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{foo}} {{bar}} !

bin/test/partials.t/data.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"foo": "Foo",
3+
"data": { "bar": "Bar" }
4+
}

bin/test/partials.t/foo.mustache

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{{#data}}
2+
Inside the include is "{{>bar}}"
3+
{{/data}}

bin/test/partials.t/run.t

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Simple test:
2+
3+
$ mustache data.json foo.mustache
4+
Inside the include is "Foo Bar !"
5+

0 commit comments

Comments
 (0)