1:M relationship in Grav

Is there a convenient way to enforce a 1:M relationship? E.g. every flea lives on exactly one cat, although one cat may have many fleas.

The use case for me is a publisher’s catalogue of music, where each music item has one composer (though it might be ‘anon’). Ideally there would be a collection of composer pages, each giving a brief bio of the composer, and a collection of music-items. When creating a new music item, only existing composer-names could be used (this is to stop mis-spellings of names like Mussorgsky and to standardise names with variant spellings, like Handel/Händel/Haendel). Some CMS systems can enforce the restriction in the admin panel, by making it obligatory to fill the music-item’s composer field from a selection box or similar that is populated by listing the existing composer-names. Is there a way to do that in Grav? Alternatively, is it possible to program some kind of a consistency check?

Grav being a file-based CMS lets you create content as files. Obviously that type of editing flexibility means there is no way to enforce checks when adding content via a text editor.

However, if you use the admin plugin, you could create a required field for you page type via blueprints.

This field could be a select field and use @data-options to preset the list of options based on a static method call:

You can see an example of this. That static method could retrieve all pages in a certain taxonomy category (for example composer). This way you could create a set of pages of composers, and your field would be dynamic enough to update and add a new composer when you add one to the composer pages.

You get the idea :slight_smile:

Thanks! Yes, that would be dynamic enough for what I need. I’ll try to get acquainted with blueprints. Bit out of my comfort zone but I guess that’s how we progress.

PS I’m very impressed with the quality of support on Grav. You must work very hard.

Hello again. I have now got blueprints working, but I don’t know how to use data-options to preset the list of options.

I have a structure with authors and books. The file called authors lists the authors, and each author has a title, in the usual way:

title: 'Agatha Christie'

When I make a new book via the Admin panel I want to fill the author field by selecting from a dropdown list populated from the list of authors.

The blueprint for making a new book has a select field for the author:

  type: select
  label: Author
  default: Anon
  data-options@: ?????
	required: true

Please can you tell me what the data-options line should say? I tried '\authors::title' and other random guesses to no avail.


Someone will probably confirm but IIRC the correct syntax is @data-options instead of data-options@ (Maybe it’s an error in the docs or maybe it works!).
And for Grav to fetch the array with all the elements in each page, you have to call a public fonction present in a file on the folder: /system/src/Grav/common/page/
it can be Pages.php Collection.php Page.php etc…

Thanks @paulmassendari. Alas, that’s way beyond anything i understand. Pity: being able to populate a set of options is essential for what i want, and if Grav can’t do it in a way I understand I need to go back to Bolt or similar, which does it in a perfectly straightforward way. And we were were getting on so well ! A real shame.

(Or will the coming-soon paid-for Admin plugin supply that feature?)

It goes way beyond my php knowledge too, but I think it is still doable. If you take a look at the file Pages.php or at this page in the API: https://learn.getgrav.org/api/Grav/Common/Page/Pages.html
you will have a list of all the public functions available.
Then, if you want to use the function getTypes which display a list of all available page type, you just have to write :
@data-options: '\Grav\Common\Page\Pages::getTypes'
Your case is a bit more complex, as you have to call a function with parameters.
According to the doc, you can set the parameter for the function with this syntax:
@data-options: ['\Grav\Theme\ImaginaryClass::getMyDefault', 'default', false]

I’m also interested to know the correct way to do that, so let me know if you find something!

data-options@ is the preferred approach for Grav 1.1 going forward. It’s still compatible with @data-options (from Grav 1.1) but the change is to ensure you don’t need quotes around the string like you do when you prefix the string with @

I think in Grav 1.0 we didn’t support params, but 1.1 definitely does. Really we have improved forms so much in 1.1 that i forget what’s in 1.0 and what’s in 1.1!

Anyway, to use data-options@ you need to ensure the method is static and returns an array of ‘options’ as name/value pairs.

Thanks. I tried @data-options: '\Grav\Common\Page\Pages::getTypes' and I got a list of blueprints - nothing else, while data-options@ didn’t give me anything at all. What I’m looking for is a list of the title fields from the Authors folder. Can’t see at all how to get there. Thoughts welcome!