Hi there
I’m trying to update a structure field after updating the site. It’s used for multilingual tags inside each project. Since I need slugs to get the filtering done, I planned to generate slugs inside a structure field with type: hidden
and use it as a value inside my project-blueprint. The Site throws an error, that the form couldn’t be saved. Does anybody has hints on how to solve that?
Here is my code:
'hooks' => [
'site.update:after' => function ($newSite,$oldSite) {
$tags = $newSite->tags()->yaml();
foreach($tags as $tag) {
$tag["slugde"] = Str::slug($tag["de"]);
$tag["slugen"] = Str::slug($tag["en"]);
}
$newSite->update([
'tags' => Data::encode($tags, "yaml")
], 'de');
},
]
texnixe
September 11, 2019, 11:54am
2
When and where exactly is the error thrown? When you try to save the page and before the hook is called? Does the hook do anything despite the error?
Could you provide the blueprint or at least the relevant parts for testing?
hey @texnixe
thanks for looking into it! The error shows up when I throw an error after iterating through the structure field with
throw new Exception(Data::encode($tags, "yaml"));
I think it shows up before the hook tries to update the page, because afterwards everything reloads on my local environment.
My site-blueprint looks like this:
title:
en: Site
de: Startseite
tabs:
dashboard:
# ...
settings:
label:
en: Language settings
de: Sprach-Einstellungen
columns:
- width: 2/4
sections:
projectsTags:
type: fields
fields:
tags:
label: Tags
type: structure
translate: false
fields:
de:
label:
en: German
de: Deutsch
type: text
width: 1/2
required: true
slugde:
type: text
width: 1/2
type: hidden
en:
label:
en: English
de: Englisch
type: text
width: 1/2
required: true
slugen:
type: text
width: 1/2
type: hidden
# ...
texnixe
September 11, 2019, 12:54pm
4
German is your default language, isn’t it?
The problem with your code is that you want to modify $tag
in your loop, so you have to change it like this:
'hooks' => [
'site.update:after' => function ($newSite,$oldSite) {
$tags = $newSite->tags()->yaml();
foreach($tags as &$tag) { // note the `&` in front of `$tag`
$tag["slugde"] = Str::slug($tag["de"]);
$tag["slugen"] = Str::slug($tag["en"]);
}
$newSite->update([
'tags' => Data::encode($tags, "yaml")
], 'de');
},
],
Apart from that, everything should work. Why are you throwing the exception?
What’s the purpose of creating these slugs?
Amazing, thanks for your support!
Yes, that’s why I update just the German language. The structure-field is set to translate: false
, so that there is only an option to create the tags in the default language. The idea is a kind of taxnomy area, where you see the translations next to each other.
Just to understand what’s going on. Is there a better method?
The possibility to add tags inside the sites taxonomy field. Later on, the user can choose the tags with following setup inside my project-blueprint:
currentLang:
type: hidden
tags:
type: hidden
tagsde:
label: Tags
type: multiselect
accept: options
options: query
query:
fetch: site.tags.toStructure
text: "{{ structureItem.de }}"
value: "{{ structureItem.slugde }}"
when:
currentLang: de
tagsen:
label: Tags
type: multiselect
accept: options
options: query
query:
fetch: site.tags.toStructure
text: "{{ structureItem.en }}"
value: "{{ structureItem.slugen }}"
when:
currentLang: en
And following hooks inside my config:
return [
'hooks' => [
'site.update:after' => function ($newSite,$oldSite) {
$tags = $newSite->tags()->yaml();
foreach($tags as &$tag) {
$tag["slugde"] = Str::slug($tag["de"]);
$tag["slugen"] = Str::slug($tag["en"]);
}
$newSite->update([
'tags' => Data::encode($tags, "yaml")
], 'de');
},
'page.update:after' => function ($newPage,$oldPage) {
if ($oldPage->intendedTemplate()->name() === 'project') {
foreach (kirby()->languages() as $language) {
$code = $language->code();
$newPage->update([
'currentLang' => $code,
'tagsen' => $code === 'en' ? $newPage->tagsen() : $newPage->content('en')->tagsen(),
'tagsde' => $code === 'de' ? $newPage->tagsde() : $newPage->content('de')->tagsde(),
'tags' => $code === 'en' ? $newPage->tagsen() : $newPage->tagsde(),
], $code);
}
}
},
'page.create:after' => function ($page) {
if ($page->intendedTemplate()->name() === 'project') {
foreach (kirby()->languages() as $language) {
$page->update([
'currentLang' => $code
], $code);
}
}
}
]
];
Is it overblown? And one question to understand it better: What is the exact meaning of the ampersand, something php specific? (I’m more a Designer than a coder, still getting into php and kirby step by step)
texnixe
September 11, 2019, 3:09pm
6
It means that you are passing the variable by reference, allows you to modify your variable: PHP: Passing by Reference - Manual