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!
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?
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.