XF 2.2 Important places to note when you need to understand template extensions, and how they get used practically.


Well-known member
Hi, I've been trying to understand how this mechanism really works in the practical world since the beginning, It looks clear when you read @Kier 's examples, but when you dig into the real-world code, you might find lots of gray arias that you couldn't understand. This thing was a bit tricky to understand (for me), but eventually, it looks simpler than it used to be. And I'll summarize it up for you for better understanding, so you can make your amazing add-on and share it with the community :)

First, I'm gonna make you confused :sneaky: And it's good if you're already confused if you already have looked at thread_list_macros template because that's what we're gonna do now.
thread_list_macros is a macro template, and it has extensions like this.
    <xf:extension name="meta_cell">
        <div class="structItem-cell structItem-cell--meta" title="{{ phrase('first_message_reaction_score:')|for_attr }} {$thread.first_post_reaction_score|number}">
            <dl class="pairs pairs--justified">
                <dt>{{ phrase('replies') }}</dt>
                <dd>{{ $thread.discussion_type == 'redirect' ? '&ndash;' : $thread.reply_count|number_short }}</dd>
            <dl class="pairs pairs--justified structItem-minor">
                <dt>{{ phrase('views') }}</dt>
                <dd>{{ $thread.discussion_type == 'redirect' ? '&ndash;' : ($thread.view_count > $thread.reply_count ? $thread.view_count|number_short : number_short($thread.reply_count+1)) }}</dd>
<xf:extension name="statuses">
                    <xf:if is="property('reactionSummaryOnLists') == 'status' && $thread.first_post_reactions">
                        <li><xf:reactions summary="true" reactions="{$thread.first_post_reactions}" /></li>
                    <xf:extension name="before_status_state"></xf:extension>
                    <xf:if is="$thread.discussion_state == 'moderated'">
                            <i class="structItem-status structItem-status--moderated" aria-hidden="true" title="{{ phrase('awaiting_approval')|for_attr }}"></i>
                            <span class="u-srOnly">{{ phrase('awaiting_approval') }}</span>
                    <xf:if is="$thread.discussion_state == 'deleted'">

look at that <xf:extension name="before_status_state"></xf:extension> part.
By extending before_status_state you can add more status icons like this

instead of making a template modification?
Do you think, that's the purpose of this template extension?
Just creating a new template that extends this macro template and having the extension before_status_state in it is enough to add an icon?

No, No, And No. THAT'S SO WRONG! if that's what you think, you are on the wrong path.

Now I'm gonna help you to solve this puzzle. forget about the previous part.

And Let's take a look at the forum_view template.
forum_view is the main template that renders the content when you are on a public forum node page.
This is the template that uses the $templateOverrides variable which does the trickiest parts here, and it's very important to notice.

Look carefully, you don't see the name of this template (forum_view) under the developer footer when it comes to Question type nodes or another type node.
You only see forum_view_type_questionas opposed to forum_view

So this template becomes the main template when you're on a particular type node. in Pub\Controller\Forum\actionForum returns the view template as usual, but the template name is a dynamic variable ($viewTemplate) here. And this forum_view_type_question template extends the main forum_view template.

And look carefully again, in Pub\Controller\Forum\actionForum it also passes the tricky variable $templateOverrides that I already have mentioned before into the $viewParams, But $templateOverrides thing never get used in this forum_view_type_questiontemplate.

It gets used in the forum_view main template, which gets extended by this forum_view_type_question template, it doesn't have to be used in forum_view_type_question, because it inherits the usage of $templateOverrides variable by extending the main forum_view template.

Now let's come back to the thread_list_macros template, which I used to make you confused at the beginning. 😬

This is just a default macro template that gets used in the main forum_view template which is responsible for rendering thread list when you're not looking at a forum TYPE node, but just a default forum node.

What happens when you look at a forum question type node page is, this thread_list_macros template gets extended by the thread_list_question_macros template and logically will get called from the main forum_view instead of calling the default thread_list_macros template.
The responsible for this tricky part is this $templateOverrides. That part is a little bit invisible if you only look at the forum_view_type_question template because there is no sign of $templateOverrides in it, but it's in the forum_view which gets extended by forum_view_type_question so it runs like under the hood.

$templateOverride is nothing but key=>value pairs of template names, the Key comes as a name of the default template name, value is the template that extends that default template and it should get replaced to that default template name on the fly.
Here how it looks in the debugger:

The main template (forum_view) logically detects when you look at a question type node because forum_view_type_question is the one calling it, and parts in the forum_view template need to be changed dynamically when it comes to a question type node, so it has its data in $templateOverride variable, and it calls different macro templates instead of loading default macros,
in this case, it calls thread_list_question_macros template instead of default thread_list_macros template.

<xf:macro name="{{ $templateOverrides.quick_thread_macro ?: 'thread_list_macros::quick_thread' }}"
                        args="{$templateOverrides.quick_thread_macro_args}" />

Unfortunatly English is not my first language, but I hope this helps to clear up the gray aria in your mind about this template extensions.
I just wanna help the community, so you guys can build up great add-ons, and share them with us.
Good luck and happy coding. Cheers
Last edited:
Top Bottom