I would be great if there was a way to set Advanced -> Route Overrides -> Default Route to match the Content -> Title automatically, even when updated. Is there any way to achieve this?
In short:
When you add ‘title’ and ‘slug’ variables to the frontmatter of the English version of page ‘branchen’ and ‘transportsysteme’, these variables will override the default German url and menu values.
For example default.en.md in folder for ‘Branchen’:
@metbril, that means that I have to write a complete plugin to achieve that, right?
@pamtbaau, my problem is that I want to automate that the page title will always be the custom slug so that our content guys won’t have to enter it twice. I already “skipped” the /de/ as it’s the default language.
I know no other solution than the one mentioned by @metbril.
If I understand your needs correctly this time… then the following might be doing what you are after.
You might need some more regex to replace invalid chars like for example 's.
Creating framework of plugin:
$ bin/plugin devtools newplugin
And replace most of old code and add the following:
public function onPluginsInitialized()
{
// Don't proceed if we are in the admin plugin
if (!$this->isAdmin()) {
return;
}
// Enable the main event we are interested in
$this->enable([
'onAdminSave' => ['onAdminSave', 0]
]);
}
public function onAdminSave(Event $e)
{
$page = $e['object'];
$slug = strtolower(preg_replace('/ /', '-', $page->title()));
$header = $page->header();
$header->slug = $slug;
$page->header($header);
}
@pamtbaau, thank you! That’s nearly the same code I’m currently working on
As you said I will have to add more replacements. Is there any way to use the native replacement function and patterns that grav uses to generate urls or folder names?
In Admin/Pages I tried to add a new page with name “Qqq’s Www”:
In the modal popup, while typing the page’s name, the folder name gets a transformed value “qqqs-www”.
Seems to me this is done using Javascript.
A folder is created named /pages/05.qqqs-www
In Admin/Pages I tried to rename the foldername in tab Advanced to “Qqq’s Www”:
The backend throws an error on save with message that value is incorrect.
The error is thrown in method BlueprintSchema::validate() which will validate the page’s header against rules.
No correction occurs.
Considering the above, I’m not sure if you can reuse any transformation code when the user changes the Title.
@pamtbaau, thanks for checking this out. I wrote my own rule to transform umlauts like “ä” to “ae” and to remove all non-alphanumeric chars. Maybe I will also add a transformation for all other special characters to their closest equivalent, like “ø” to “o”.
In onPluginsInitialized() I had to add a line that checks if the page I’m on is a content page and not somewhere in a plugin or in the configs. I don’t know if this is the best practice but it just checks if the uri path contains “pages”:
The extra check in onPluginsInitialized() sounds like a good idea… I think you should also check if Uri::paths() returns 3 elements. When creating a folder, Uri::paths() only returns 2 elements.
NB. Maybe it’s a good idea to mark the thread as solved, so others know you have found a solution.
I will mark it as solved once it’s solved I just found another issue: When I hit save on a modular and it creates a slug it is no longer modular because the template switches to a page template Now I have to figure out how to detect the template
It happens even with my plugin deactivated. When I set a slug for a module in the advanced tab and hit save, the module becomes a page and under page templates only page templates are listed (automatically chooses the first in alphabetic order). When I uncheck the slug and hit save it gets reverted to a module but also choosing the first template alphabetic order.
@Paddi This could well be an ‘undocumented feature’ of Grav…
It is however a bit silly to change the slug of a child of a modular, because the child-page is never displayed on its own and hence doesn’t need a slug to set the url. I guess…
Some tests:
If I set a translated slug for the main Module page, all goes well. Page gets a translated url.
If I set a translated slug for a child page, things go wrong as you have noticed.
If I only translate the title of a child page, the menu gets translated and the subpage urls becomes translated into ‘translated_url#tanslated_title’.
Note: Spaces are replaced by ‘_’ instead of ‘-’
The following extra check in ‘onAdminSave()’, might help to prevent setting slug for children:
// Do not set slug if page is child of modular eg. 'modular/features'
if (strpos($page->template(), '/') > 0) {
return;
}
I think this is why this bug is happening because slugs are not intended to be used on modules.
$page->template() was what I was looking for, thank you. I changed it a bit so it is checking if “modular” is in the String and if false, the code will be executed.
Now everything is working, at least I think so Maybe I will have some more “surprises” while using this plugin. I think this feature should be implemented in Grav itself. Without this workaround it’s just a matter of time until one of our content creators forget to set the slug for english content and then we have a german url for an english page…