Template hooks from plugin

Hi,

I am using page-footer template hook from a plugin to add additional links in the footer.

class MLZThemesPlugin(IndicoPlugin):
       """MLZ Themes

    Provides event themes for MLZ.
    """
...
    def init(self):
        super(MLZThemesPlugin, self).init()
...
        self.connect(signals.plugin.template_hook, self._get_template_hooks)
        self.template_hook_map = {
                'page-footer':self._render_page_footer,
        }

....

    def _get_template_hooks(self, sender, **kwargs):
        """renderers should return a ``(is_markup, priority, value)`` tuple."""
        renderer = self.template_hook_map.get(sender)
        if renderer:
            return renderer()

    def _render_page_footer(self):
        return TemplateSnippet(
                '<div style="margin-left: 1em;margin-right: 1em; float: right;">'
                '<a href="https://mlz-garching.de/startseite/datenschutz.html">Datenschutz am MLZ</a>'
                '</div>'
                '<div style="margin-left: 1em;margin-right: 1em; float: right;">'
                '<a href="https://mlz-garching.de/startseite/impressum.html">Impressum</a>'
                '</div>'
                ,markup=True, priority=50)

The template does call the hook with ‘as_list=True’, but all attempts to return more than one item from the plugin failed .
I tried yielding more than one Snippet, makeing the content of the snippet a list or returning a list of Snippets.
Is it at all possible to return more than one item here?

Björn

I forgot to give one error-example ( for returning a list of snippets):

indico_1       |   File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/templates/footer.html", line 2, in top-level template code
indico_1       |     {% block footer -%}
indico_1       |   File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/templates/footer.html", line 29, in block 'footer'
indico_1       |     {% for item in template_hook('page-footer', as_list=true) %}
indico_1       |   File "/opt/indico/.venv/lib/python3.9/site-packages/indico/web/flask/templating.py", line 210, in call_template_hook
indico_1       |     if not (value := snippet.content):
indico_1       | AttributeError: 'list' object has no attribute 'content'

The problem is that you use the signal directly, but it should be use via self.template_hook(...) in plugins. Also, you do not need to wrap it in TemplateSnippet - this is just meant for more advanced usecases where you want to return multiple separate items with different markup/priority values.

And if you want to use multiple template hooks just call that method multiple times, with separate functions for each hook.

Thanks for pointing me in the right direction! It’s working now.