Skip to content

Commit 97429f4

Browse files
authored
Fix compose block inherit (#51)
1 parent 8cab2ea commit 97429f4

File tree

4 files changed

+34
-10
lines changed

4 files changed

+34
-10
lines changed

src/template_compiler_element.erl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ maybe_add_include(_Token, _Method, _IsCatinclude, Ws) ->
732732
Ws.
733733

734734

735-
compose({_, SrcPos, _}, Template, ArgsList, IsContextVars, Blocks, #cs{runtime=Runtime} = CState, Ws) ->
735+
compose({_, SrcPos, _}, Template, ArgsList, IsContextVars, Blocks, #cs{runtime=Runtime, module=Module} = CState, Ws) ->
736736
{Ws1, TemplateAst} = template_compiler_expr:compile(Template, CState, Ws),
737737
ArgsListAst = erl_syntax:list([ erl_syntax:tuple([A,B]) || {A,B} <- ArgsList ]),
738738
{_BlocksWs, BlocksAsts} = template_compiler:compile_blocks(Blocks, CState),
@@ -754,6 +754,7 @@ compose({_, SrcPos, _}, Template, ArgsList, IsContextVars, Blocks, #cs{runtime=R
754754
"_@is_context_vars,"
755755
"_@vars,"
756756
"_@block_list,",
757+
"_@module,",
757758
"_@block_fun,",
758759
"_@context)"
759760
],
@@ -766,6 +767,7 @@ compose({_, SrcPos, _}, Template, ArgsList, IsContextVars, Blocks, #cs{runtime=R
766767
{context, erl_syntax:variable(CState#cs.context_var)},
767768
{context_vars, erl_syntax:abstract(CState#cs.context_vars)},
768769
{block_list, BlockListAst},
770+
{module, erl_syntax:atom(Module)},
769771
{block_fun, BlockFunAst},
770772
{is_context_vars, erl_syntax:abstract(IsContextVars)}
771773
]),

src/template_compiler_runtime_internal.erl

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
block_call/6,
2727
block_inherit/7,
2828
include/9,
29-
compose/10,
29+
compose/11,
3030
call/4,
3131
print/1,
3232
unique/0
@@ -153,8 +153,17 @@ block_call(SrcPos, Block, Vars, BlockMap, Runtime, Context) ->
153153
After
154154
]
155155
end;
156-
{ok, [RenderFun|_]} when is_function(RenderFun) ->
157-
RenderFun(Block, Vars, BlockMap, Context);
156+
{ok, [{Module, RenderFun}|_]} when is_function(RenderFun) ->
157+
case Runtime:trace_block(SrcPos, Block, Module, Context) of
158+
ok ->
159+
RenderFun(Block, Vars, BlockMap, Context);
160+
{ok, Before, After} ->
161+
[
162+
Before,
163+
RenderFun(Block, Vars, BlockMap, Context),
164+
After
165+
]
166+
end;
158167
error ->
159168
% No such block, return empty data.
160169
<<>>
@@ -165,8 +174,13 @@ block_call(SrcPos, Block, Vars, BlockMap, Runtime, Context) ->
165174
block_inherit(SrcPos, Module, Block, Vars, BlockMap, Runtime, Context) ->
166175
case maps:find(Block, BlockMap) of
167176
{ok, Modules} ->
168-
case lists:dropwhile(fun(M) -> M =/= Module end, Modules) of
169-
[Module, Next|_] ->
177+
case lists:dropwhile(
178+
fun
179+
({M, _F}) -> M =/= Module;
180+
(M) -> M =/= Module
181+
end, Modules)
182+
of
183+
[ _Module, Next | _ ] when is_atom(Next) ->
170184
case Runtime:trace_block(SrcPos, Block, Next, Context) of
171185
ok ->
172186
Next:render_block(Block, Vars, BlockMap, Context);
@@ -177,7 +191,7 @@ block_inherit(SrcPos, Module, Block, Vars, BlockMap, Runtime, Context) ->
177191
After
178192
]
179193
end;
180-
_ ->
194+
[] ->
181195
<<>>
182196
end;
183197
error ->
@@ -258,7 +272,7 @@ include_1(SrcPos, Method, Template, Runtime, ContextVars, Vars, Context) ->
258272
end.
259273

260274
%% @doc Compose include of a template, with overruling blocks.
261-
-spec compose(SrcPos, Template, Args, Runtime, ContextVars, IsContextVars, Vars, BlockList, BlockFun, Context) -> Output when
275+
-spec compose(SrcPos, Template, Args, Runtime, ContextVars, IsContextVars, Vars, BlockList, BlockModule, BlockFun, Context) -> Output when
262276
SrcPos :: {File::binary(), Line::integer(), Col::integer()},
263277
Template :: template_compiler:template(),
264278
Args :: list({atom(),term()}),
@@ -267,10 +281,11 @@ include_1(SrcPos, Method, Template, Runtime, ContextVars, Vars, Context) ->
267281
IsContextVars :: boolean(),
268282
Vars :: map(),
269283
BlockList :: list( atom() ),
284+
BlockModule :: atom(),
270285
BlockFun :: function(), % (_@BlockName@, Vars, Blocks, Context) -> _@BlockAst
271286
Context :: term(),
272287
Output :: template_compiler:render_result().
273-
compose(SrcPos, Template, Args, Runtime, ContextVars, IsContextVars, Vars, BlockList, BlockFun, Context) ->
288+
compose(SrcPos, Template, Args, Runtime, ContextVars, IsContextVars, Vars, BlockList, BlockModule, BlockFun, Context) ->
274289
Vars1 = lists:foldl(
275290
fun
276291
({'$cat', [Cat|_] = E}, Acc) when is_atom(Cat); is_binary(Cat); is_list(Cat) ->
@@ -289,7 +304,7 @@ compose(SrcPos, Template, Args, Runtime, ContextVars, IsContextVars, Vars, Block
289304
true -> Runtime:set_context_vars(Args, Context);
290305
false -> Context
291306
end,
292-
BlockMap = lists:foldl(fun(Block, Acc) -> Acc#{ Block => [ BlockFun ] } end, #{}, BlockList),
307+
BlockMap = lists:foldl(fun(Block, Acc) -> Acc#{ Block => [ {BlockModule, BlockFun} ] } end, #{}, BlockList),
293308
{SrcFile, SrcLine, _SrcCol} = SrcPos,
294309
Options = [
295310
{runtime, Runtime},

test/template_compiler_include_SUITE.erl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ groups() ->
2323
,include_dynamic_test
2424
,include_args_test
2525
,compose_test
26+
,compose_inherit_test
2627
]}].
2728

2829
init_per_suite(Config) ->
@@ -78,6 +79,11 @@ compose_test(_Config) ->
7879
<<"AxB1yC">> = iolist_to_binary(Bin1),
7980
ok.
8081

82+
compose_inherit_test(_Config) ->
83+
{ok, Bin1} = template_compiler:render("compose2.tpl", #{}, [], undefined),
84+
<<"AxBXYC1yD">> = iolist_to_binary(Bin1),
85+
ok.
86+
8187
test_data_dir(Config) ->
8288
filename:join([
8389
filename:dirname(filename:dirname(?config(data_dir, Config))),

test/test-data/compose2.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A{% compose "compose_b.tpl" v=1 %}{% block a %}B{% inherit %}C{{ v }}{% endblock %}{% endcompose %}D

0 commit comments

Comments
 (0)