Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

Themes & Styling

Dynamically add taxonomy to header

Solved by Robert View solution

Started by Robert 7 years ago · 7 replies · 975 views
7 years ago

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

/forum/archive/header-injection-t7221

but that does not provide a solution.

7 years ago

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):

PHP
    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:

YAML
---
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
---
7 years ago

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?

last edited 01/27/19 by Robert
7 years ago

These are 3 example pages

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

Collection 1 (Base, shows all items)

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

Collection 2 (does not work)

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

Collection 3 (does not work)

YAML
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.
7 years ago

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:

last edited 01/27/19 by Robert
7 years ago Solution

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

PHP
    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.

https://github.com/getgrav/grav-plugin-archives/blob/13b0953b0e1270120d1a87cb61f28730959a4b51/archives.php#L71

👍 1
last edited 02/06/19 by Robert
7 years ago

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:

MARKDOWN
---
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

Suggested topics

Topic Participants Replies Views Activity
Themes & Styling · by Pedro M, 2 months ago
4 197 2 months ago
Themes & Styling · by Ian, 2 months ago
3 92 2 months ago
Themes & Styling · by Norbert, 2 years ago
11 454 3 months ago
Themes & Styling · by Lukáš Findeis, 3 months ago
0 47 3 months ago
Themes & Styling · by Sebadamus, 4 months ago
5 127 3 months ago