XF 2.2 Adding a new variable to post_macros


Well-known member
I need to generate a new dropdown menu item in post_macros. This dropdown is generated on the fly based on some XF options. It would be very easy to generate this dropdown right in the template without going down into a template render listener.

Problem is, I don't want to regenerate this dropdown HTML each time post_macro is invoked. So I had the bright idea to save the variable once, in thread_view, and then post_macros would be able to access it. But it's not working. What am I doing wrong? Shouldn't this work?

In template thread_view:
<xf:if is="{{ $xf.visitor.isMemberOf($xf.options.td_posts_repository_groups) }}">
    <xf:set var="$posts_repo_dropdown" value="TESTING" />

In template posts_macro:
<xf:if is="{{ $xf.visitor.isMemberOf($xf.options.td_posts_repository_groups) }}">
                <a class="actionBar-action menuTrigger"
                    title="Submit to Posts Repository"
                    aria-haspopup="true">Posts Repository</a>

                <div class="menu" data-menu="menu" aria-hidden="true">
                    <div class="menu-content">
                        <h3 class="menu-header">Submit to Posts Repository</h3>
                        {{ $posts_repo_dropdown }}
                        <a class="menu-linkRow" role="button" tabindex="0" data-menu-closer="on" data-xf-init="copy-to-clipboard" data-copy-text="{$bookmark.content_link}">{{ phrase('copy_link') }}</a>
                        <a href="{$bookmark.edit_link}" class="menu-linkRow" data-xf-click="overlay">{{ phrase('edit') }}</a>
                        <a href="{$bookmark.delete_link}" class="menu-linkRow" data-xf-click="overlay">{{ phrase('delete') }}</a>
                <xf:set var="$hasActionBarMenu" value="{{ true }}" />

I know the $posts_repo_dropdown is getting set successfully, because I can echo it in thread_view and it shows up fine. I thought vars defined in parent templates were passed to child templates automatically?
I thought vars defined in parent templates were passed to child templates automatically?
They are - but macros are not child templates.

Included (Child Template)
<xf:include template="some_template" />

<xf:macro template="macro_template" name="macro_name" arg-var1="..."  />

You have to explicitly pass variables to macros, they can't magically access variables from the template they are being called from.
Gotcha thanks. So that being the case, what's the best way to get my var into the macro without generating it for every post?
I'd probably have to see what you are generating, but my hunch is that it isn't worth trying such optimization - at the end you will have the HTML for earch post anyway.

Unless there are expensive things happening (callbacks, etc.), there most likely won't be any performance benefit storing the content in a variable, passing it to the macro, using it there and returning the HTML back to thread_view - probably not even measurable.

If you still want to to go variable route you've got several options
  • Set it as a page param (somewhat hacky though)
  • Change to macro signature and pass it
It's literally just pulling some data from an option (plain text) and turning that into an array with explode then looping through it to make the drop-down.

Maybe you're right and this isn't the place to spend my optimization time.
Top Bottom