Dynamically add taxonomy to header

I want to dynamically inject a taxonomy into my page header, and use that when processing the page. More or less like the archive plugin does.

However, using onPageContentRaw or onPageProcessed appear to be too late. When adding the taxonomy then, it appears to be never processed (I checked this using {{dump(page.header.taxonomy)}} in the template.

The onBuildPagesInitialized event only runs once, and not per page.

So the question is: how can I manipulate a page’s header, so that I can still use the values when processing the page?

I’ve already read this old thread

but that does not provide a solution.

Hi @metbril, I did something very similar but with a blueprint and adding a function to a theme’s php file:

Hope the above might help.
Paul

It took some time to report back, but I have been able to get it working…

  1. Add the taxonomy to your site config (type in my case).
  2. Add the taxonomy to some pages.

Add an event hook to my theme (plugin is also possible):

    public function onPageProcessed(Event $event)
    {
        if ($this->isAdmin()) {
            $this->active = false;
            return;
        }

        // if taxonomy not set, then set default.
        $page = $event['page'];
        $header = $page->header();
        if ( !isset($header->taxonomy['type']) ) {
            $header->taxonomy['type'] = array('article');
        }
    }

Afterwards, I can create content filter with pages. For example, my homepage only shows pages with taxonomy of type article, note, photo or video:

---
title: Home
content:
    items:
        - 
            '@taxonomy.type': article
        - 
            '@taxonomy.type': note
        - 
            '@taxonomy.type': photo
        - 
            '@taxonomy.type': video
    filter:
        type: item
    limit: 20
    order:
        by: date
        dir: desc
    pagination: true
    url_taxonomy_filters: true
---

I have one B I G issue left…

This is working perfectly on the local MAMP setup. But when I apply the changes to my real website, The collection only returns items that have the type manually added. Any page that has the default type injected, is not included in the collection.

This is driving me insane. :crazy_face:

I have cleared all caches, compared system.yaml files, forced the caching method to be the same.

And I have tried changing the event from onPageProcessed to onPageContentRaw. This also does not make a difference.

So the big question is: why don’t the pages get included in the collection and how to fix this?

Perhaps @OleVik has some tips?

These are 3 example pages

All 3 pages do work locally with MAMP, but not with the webhoster

Collection 1 (Base, shows all items)

content:
    items:
        '@page.children': /blog
    filter:
        type: item
    order:
        by: date
        dir: desc
    limit: 5
    pagination: true

Collection 2 (does not work)

content:
    items:
        '@taxonomy.type': article
    filter:
        type: item
    order:
        by: date
        dir: desc
    limit: 5
    pagination: true

Collection 3 (does not work)

content:
    items:
        -
            '@taxonomy.type': article
    filter:
        type: item
    order:
        by: date
        dir: desc
    limit: 5
    pagination: true

I have added a {{dump(page.header.taxonomy)}} to the page.

  • Raw route to /blog: shows type taxonomy for all pages
  • Collection 1: shows type taxonomy for all pages
  • Collection 2/3: only shows type taxonmy for pages when manually added.

I did some more testing…

And I don’t know what changed, but it’s also not working locally.

So now this is the situation.

  • When accessing a collection through its route /blog (with collection @self.children), all item pages are shown and the header for each item page contains the injected taxonomy
  • When accessing a collection referring to the page ('@page.children': /blog), each item page is shown and contains the injected taxonomy
  • When accessing the taxonomy directly in the collection (examples 2 and 3 above), only the pages are included that have the taxonomy added manually.

For now it looks like the collection is built from the taxonomies in the physical file instead of basing it on the pages in cache/memory.

The only way to force the taxonomy is to do a $page->save() after injecting it. :frowning_face:

Well, I took a look at the archives plugin and that wrote the adjusted taxonomy back to the page object. Just that simple.

    public function onPageProcessed(Event $event)
    {
        if ($this->isAdmin()) {
            $this->active = false;
            return;
        }

        $page = $event['page'];
        $taxonomy = $page->taxonomy();
        if ( !isset($taxonomy['type']) ) {
            $taxonomy['type'] = array('article');
        }
        // set the modified taxonomy back on the page object
        $page->taxonomy($taxonomy);
    }

I think I solved my own problem. I will monitor for the coming days and report back.

1 Like

This solved my problem. The only dowside of using onPageProcessed is, that the event is triggered for every page update and processes all available pages. This will probably slow things down a little.

A side note is, that since the taxonomy is not actually saved in the page, you need to access the taxonomy in page templates through {{ page.taxonomy[0] }} instead of {{ page.header.taxonomy[0]}}.

The nice thing of this taxonomy now is, that I can build separate feeds/channels based on it, and also use the regular tagging feature.

For example, my home page blog.md has this frontmatter, which shows any item.mdpage with some specific post types:

---
content:
    items:
        -
            '@taxonomy.type': article
        -
            '@taxonomy.type': note
        -
            '@taxonomy.type': photo
    filter:
        type: item
    order:
        by: date
        dir: desc
    limit: 5
    pagination: true
---

The home page is available at https://example.com/ and also can be filtered by tag with https://example.com/tag:cat