XF 2.2 Understand macro extension

Earl

Well-known member
In XenForo core templates:
post_question_macros template has <xf:macro name="answer" extends="post_macros::post">
What does it mean?
According to this post:
When calling a macro, we now generally prefer <xf:macro name="template_name::macro_name"> over <xf:macro template="template_name" name="macro_name"> although both options are supported.
"post" is supposed to be the macro name, But it also has name=" " attribute and extends="post_macros::post" both parts at the same time, but no template=" " attribute being used.

This one is a bit confusing,

Looks like it means the macro name is answer and it's a child macro that extending another macro named post in the post_macros template.

Is that correct?

If that's the case, this answer macro is in this post_question_macros never get referred from anywhere.
(I used the template search with name="answer" and I got nothing but only the post_question_macros, which mean it doesn't get called from anywhere)

And we can extend that child macro too because it also has extensions named main_cell, extra_classes, etc. In that case, we have to call that child of that child macro post_macros::answer Right?

could anyone please explain this a little bit further?
Thanks in advance.
 
Last edited:
Solution
Looks like it means the macro name is answer and it's a child macro that extending another macro named post in the post_macros template.

Is that correct?
Yes, that's correct.

If that's the case, this answer macro is in this post_question_macros never get referred from anywhere.
(I used the template search with name="answer" and I got nothing but only the post_question_macros, which mean it doesn't get called from anywhere)
It might not be called in templates, but it is used. In this case, the name of the macro is defined in code by the thread type handler (similar to how we define the template that's specific to a thread type).

And we can extend that child macro too...
Looks like it means the macro name is answer and it's a child macro that extending another macro named post in the post_macros template.

Is that correct?
Yes, that's correct.

If that's the case, this answer macro is in this post_question_macros never get referred from anywhere.
(I used the template search with name="answer" and I got nothing but only the post_question_macros, which mean it doesn't get called from anywhere)
It might not be called in templates, but it is used. In this case, the name of the macro is defined in code by the thread type handler (similar to how we define the template that's specific to a thread type).

And we can extend that child macro too because it also has extensions named main_cell, extra_classes, etc. In that case, we have to call that child of that child macro post_macros::answer Right?
Yes, you can extend an extended macro, though you'd have to call it in your code then. The extension system (templates and macros) are generally for a specific purpose. They aren't replacements for template modifications where an add-on wants to add functionality to an existing system. They make more sense as things in the core that end up being extendable systems.
 
Solution
They aren't replacements for template modifications where an add-on wants to add functionality to an existing system
I see an extension named before_status_watch in this section of thread_list_macros template
HTML:
                    <xf:extension name="status_sticky">
                        <xf:if is="$thread.sticky">
                            <li>
                                <i class="structItem-status structItem-status--sticky" aria-hidden="true" title="{{ phrase('sticky')|for_attr }}"></i>
                                <span class="u-srOnly">{{ phrase('sticky') }}</span>
                            </li>
                        </xf:if>
                    </xf:extension>

                    <xf:extension name="before_status_watch"></xf:extension>
                    <xf:if is="{$showWatched} AND {$xf.visitor.user_id}">
                        <xf:if is="{$thread.Watch.{$xf.visitor.user_id}}">
                            <li>
                                <i class="structItem-status structItem-status--watched" aria-hidden="true" title="{{ phrase('thread_watched')|for_attr }}"></i>
                                <span class="u-srOnly">{{ phrase('thread_watched') }}</span>
                            </li>
                            <xf:elseif is="!$forum AND {$thread.Forum.Watch.{$xf.visitor.user_id}}" />
                            <li>
                                <i class="structItem-status structItem-status--watched" aria-hidden="true" title="{{ phrase('forum_watched')|for_attr }}"></i>
                                <span class="u-srOnly">{{ phrase('forum_watched') }}</span>
                            </li>
                        </xf:if>
                    </xf:if>
<xf:extension name="before_status_watch"></xf:extension>

Does that mean, just having a new template like this:
HTML:
<xf:extends template="thread_list_macros" />
<xf:extension name="before_status_watch">
    <xf:extensionparent />
    <li>
        <i class="structItem-status structItem-status--community-mod" aria-hidden="true" title="{{ phrase('community_moderated')|for_attr }}"></i>
        <span class="u-srOnly">{{ phrase('community_moderated') }}</span>
    </li>

</xf:extension>

is it not enough to add new content to before_status_watch?

I created that template, but I don't see it's working.

Anybody wanna tell me why?
 
Last edited:
Top Bottom