Unique IDs for structured fields

I’m using Kirby as a headless CMS to provide content via its REST API and need unique IDs to be generated into the txt files. I already tried plugins like AutoID for Kirby3 but these don’t provide this feature for structured fields. Is there any other way to make this happen?

The feature for Structure Field IDs was removed from the last update of the AutoID plugin, but you could use the version before.

Other than that, you can create a hook that adds unique IDs to structure fields on save.

Thank you for your fast response. I already tried to use an older version of AutoID without success.

The idea of creating an own hook for that sounds promising and I’ll try that one.

This is an old one for Kirby 2: https://github.com/texnixe/kirby-structure-id

But might serve as starting point.

Happy to share the following hook that I’ve been using in a project where the client adds new project partners to a structure field and the hook assigns each entry with a slug as an ID field - maybe this helps as a starting point?

'page.update:after' => function ( $newPage, $oldPage ) {
	// limit this hook to pages of the blueprint "project"
	if ( $newPage->intendedTemplate() == "project" ) {
		// "partners" is the name of the structure field
		$partners = $newPage->partners()->yaml();
		// loop through all rows in the structure field
		foreach( $partners as &$item ) {
			// turn the title field into a slug to be used as autoid, if none exists
			if (!isset($item['autoid']) || !$item['autoid']) {
				$item['autoid'] = Str::slug( $item['title'] );
			}
		}
		// save the entire "partners" structure back to the file, now with autoids
		$newPage->save([
			'partners' => Data::encode( $partners, "yaml" ),
		]);
	}
}
2 Likes

hi @enjoi. i am the dev responsive for autoid plugin. i dropped support recently when i did a major overhaul of the sourcecode. personally i was no longer convinced that using structures as fake pages is a good idea. but your usecase might diver. please describe your usecase so i can understand better.

i am not sure how you codes escapes an endless update loop on the $newPage. you have no such check in pace. maybe kirby does something magical. maybe @texnixe knows.
otherwise it would be a good idea to only save the page if an autoid has actually been added. at least that is what i did up to v1.4.1.

@bnomei Why do you think this can end in an endless loop? Since the hook does not update the page, nothing should happen.

it calls $newPage->save() on any project. which when saved gets an update hook thus a loop, right? or does calling save() with no changes actually not perform a save and trigger hooks?

No, save() doesn’t trigger an update hook for all I can see.

ah save() is not update() i was stuck in k2 ways it seems. thanks for explaining.

Indeed - and, almost more important: my code is lacking a check that ensures that an ID does not already exists (it simply renders a slug from the title, but that same slug could already exist). It was a quick hack and works ok in the specific context it is used, but definitely something that should be there.

Re your other question about use cases: in my project, the structure is not used as fake pages, but I needed the ID for each row in order to reliably access them from some other page. Say, I have three project pages, each with three partners in a structure “partners”. On the front page of the website, I have an element where four partners of the company can be featured. I want the admin to be able to choose these from the pool of nine partners set up in the projects - therefore the rows in those structures had to have unique IDs.

1 Like

i added support for structures again but be sure to test well there might be some hidden bugs left.

2 Likes