@@ -19,7 +19,7 @@ void ForStatement::Render(OutStream& os, RenderContext& values)
1919void ForStatement::RenderLoop (const InternalValue& loopVal, OutStream& os, RenderContext& values)
2020{
2121 auto & context = values.EnterScope ();
22-
22+
2323 InternalValueMap loopVar;
2424 context[" loop" ] = MapAdapter::CreateAdapter (&loopVar);
2525 if (m_isRecursive)
@@ -31,23 +31,23 @@ void ForStatement::RenderLoop(const InternalValue& loopVal, OutStream& os, Rende
3131 {
3232 return ;
3333 }
34-
34+
3535 auto var = parsedParams[" var" ];
3636 if (!var)
3737 {
3838 return ;
3939 }
40-
40+
4141 RenderLoop (var->Evaluate (context), stream, context);
42- });
42+ });
4343 }
4444
4545 bool isConverted = false ;
4646 auto loopItems = ConvertToList (loopVal, InternalValue (), isConverted);
4747 if (!isConverted)
4848 {
4949 values.ExitScope ();
50- return ;
50+ return ;
5151 }
5252
5353 if (m_ifExpr)
@@ -159,6 +159,7 @@ void SetStatement::Render(OutStream&, RenderContext& values)
159159class BlocksRenderer : public RendererBase
160160{
161161public:
162+ virtual bool HasBlock (const std::string& blockName) = 0;
162163 virtual void RenderBlock (const std::string& blockName, OutStream& os, RenderContext& values) = 0;
163164};
164165
@@ -170,17 +171,39 @@ void ParentBlockStatement::Render(OutStream& os, RenderContext& values)
170171 if (!found)
171172 return ;
172173
173- auto parentTplPtr = boost::get<RendererBase*>(&parentTplVal->second );
174- if (parentTplPtr == nullptr )
174+ bool isConverted = false ;
175+ auto parentTplsList = ConvertToList (parentTplVal->second , isConverted);
176+ if (!isConverted)
177+ return ;
178+
179+ BlocksRenderer* blockRenderer = nullptr ; // static_cast<BlocksRenderer*>(*parentTplPtr);
180+ for (auto & tplVal : parentTplsList)
181+ {
182+ auto ptr = boost::get<RendererBase*>(&tplVal);
183+ if (!ptr)
184+ continue ;
185+
186+ auto parentTplPtr = static_cast <BlocksRenderer*>(*ptr);
187+
188+ if (parentTplPtr->HasBlock (m_name))
189+ {
190+ blockRenderer = parentTplPtr;
191+ break ;
192+ }
193+ }
194+
195+ if (!blockRenderer)
175196 return ;
176197
177- BlocksRenderer* blockRenderer = static_cast <BlocksRenderer*>(*parentTplPtr);
178198
179199 auto & scope = innerContext.EnterScope ();
180200 scope[" $$__super_block" ] = static_cast <RendererBase*>(this );
181201 scope[" super" ] = Callable ([this ](const CallParams&, OutStream& stream, RenderContext& context) {
182202 m_mainBody->Render (stream, context);
183203 });
204+ if (!m_isScoped)
205+ scope[" $$__parent_template" ] = parentTplsList;
206+
184207 blockRenderer->RenderBlock (m_name, os, innerContext);
185208 innerContext.ExitScope ();
186209
@@ -210,7 +233,21 @@ class ParentTemplateRenderer : public BlocksRenderer
210233 void Render (OutStream& os, RenderContext& values) override
211234 {
212235 auto & scope = values.GetCurrentScope ();
213- scope[" $$__parent_template" ] = static_cast <RendererBase*>(this );
236+ InternalValueList parentTemplates;
237+ parentTemplates.push_back (InternalValue (static_cast <RendererBase*>(this )));
238+ bool isFound = false ;
239+ auto p = values.FindValue (" $$__parent_template" , isFound);
240+ if (isFound)
241+ {
242+ bool isConverted = false ;
243+ auto prevTplsList = ConvertToList (p->second , isConverted);
244+ if (isConverted)
245+ {
246+ for (auto & tpl : prevTplsList)
247+ parentTemplates.push_back (tpl);
248+ }
249+ }
250+ scope[" $$__parent_template" ] = ListAdapter::CreateAdapter (std::move (parentTemplates));
214251 m_template->GetRenderer ()->Render (os, values);
215252 }
216253
@@ -223,6 +260,11 @@ class ParentTemplateRenderer : public BlocksRenderer
223260 p->second ->Render (os, values);
224261 }
225262
263+ bool HasBlock (const std::string &blockName) override
264+ {
265+ return m_blocks->count (blockName) != 0 ;
266+ }
267+
226268private:
227269 std::shared_ptr<TemplateImpl<CharT>> m_template;
228270 ExtendsStatement::BlocksCollection* m_blocks;
0 commit comments