Grav: 1:M relationships and searching collections by custom header field

Created on 10 Jun 2018  路  2Comments  路  Source: getgrav/grav

I am trying to create a 1:M relationship ("An release belongs to 1 artist, and an artist can have M releases") in Grav by using a custom field (uuid) defined via a blueprint, like so:

Release:

# blueprints/release.yaml
title: Release Entry
extends@: default

form:
  fields:
    tabs:
      type: tabs
      active: 1

      fields:
        advanced:
          fields:
            overrides:
              fields:
                header.uuid:
                  type: text
                  label: 'Unique ID - do not modify'
                  data-default@: '\Grav\Theme\Upitup::uuid'
                  readonly: true
        content:
          fields:
            header.artist:
              type: select
              label: Select artist
              data-options@: '\Grav\Theme\Upitup::getArtists'

Artist:

#blueprints/artist.yaml
title: Artist Entry
extends@: default

form:
  fields:
    tabs:
      type: tabs
      active: 1

      fields:
        advanced:
          fields:
            overrides:
              fields:
                header.uuid:
                  type: text
                  label: 'Unique ID - do not modify'
                  data-default@: '\Grav\Theme\Upitup::uuid'
                  readonly: true

My theme functions are defined as follows:

class Upitup extends Theme
{

    public static function uuid()
    {
        return uniqid(null, true);
    }

    public static function getArtists() 
    {
        $page = Grav::instance()['page'];
        $collection = $page->evaluate(['@page.children' => '/artists']);

        $options = [];
        foreach ($collection as $artist) {
            $options[$artist->header()->uuid] = $artist->title();
        };

        return $options;
    }

My goal is to show the Artist of a a specific Release. All I could figure out so far is to get all Pages of type "Artist" and checking one by one for the specific uuid I"m looking for, which is obviously suboptimal. Like so:


{% set artists = page.evaluate([{'@page':'/artists'}]) %}
{% for artist in artists %}
    {% if artist.header.uuid == page.header.artist %}
       Release by {{ artist.title }}
    {% endif %}
{% endfor %}

I read the manual twice but I couldn't figure out what's the best way to achieve this simple scenario.
Is there a recommended way in Grav to filter collections by a custom value?

Many thanks!

question

Most helpful comment

Right now you need to do something like this -- create a collection of pages and find the one(s) you want to display. You can probably use some caching, but this isn't something that's supported out of the box (look into how taxonomies work for example).

What you described is something I'm working on when I have some spare time and some of the base classes are already in Grav 1.4 and there are multiple improvements in Grav 1.5 to start supporting customizable pages/objects with relations between them. My goal is to have all of this fully integrated with Grav 2.0.

All 2 comments

Right now you need to do something like this -- create a collection of pages and find the one(s) you want to display. You can probably use some caching, but this isn't something that's supported out of the box (look into how taxonomies work for example).

What you described is something I'm working on when I have some spare time and some of the base classes are already in Grav 1.4 and there are multiple improvements in Grav 1.5 to start supporting customizable pages/objects with relations between them. My goal is to have all of this fully integrated with Grav 2.0.

Thanks @mahagr and looking forward to seeing relationship support in Grav 2.

One last question: would it be a terrible idea to use _creatively_ taxonomy tags to automatically store primary IDs (e.g. in my example above a creation-time uuid) upon creation of pages (Artists and Releases in my case) to be used later on for taxonomy filtering?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fabrizioT picture fabrizioT  路  26Comments

glasswork picture glasswork  路  28Comments

ursbraem picture ursbraem  路  29Comments

giansi picture giansi  路  17Comments

joville picture joville  路  23Comments