Alternatives to '@slugify-title'

Hello

I created a blueprint to ease adding news on my website. Basically only the title is required on creation, and it is always a date (with format YYYY/MM/DD).

I would like the folder of the page to be automatically named with the format ‘YYYY-MM-DD’. I tried the following:

folder:
  type: hidden
  default: '@slugify-title'

But it simply creates a folder using the ‘YYYYMMDD’ format.

Is it possible to use a different functions than ‘@slugify-title’? Ideally being able to use a regex would be nice, but something that would replace ‘/’ with ‘-’ would be ok too.

@mathmax Currently, ‘@slugify-title’ is internally translated into a call to method \Grav\Plugin\Admin\Utils::slug($str), where $str is the value of the title of the page.

Among others, the method ‘slug()’ does the following:

$str = preg_replace('/[-\s]+/', '-', $str);
$str = preg_replace('/[^a-z0-9-]/i', '', $str);

This means that ‘-’ will not be removed from a title with value ‘YYYY-MM-DD’ and a folder will be created exactly as the title.

Would it be possible for you, or your users, to enter ‘YYYY-MM-DD’ as title instead of ‘YYYY/MM/DD’?

Thank you for your reply.

Actually I was first trying to input ‘YYYY-MM-DD’ but the hyphens got deleted in the folder name. I use Grav 1.5.1.

Anyway, I now need to input the title with ‘/’ instead of ‘-’, so I was wondering if there are tokens other than ‘@slugify-title’ or methods to allow setting the folder name is a more generic way. Maybe it is also possible to override some php methods and add more flexibility here?

If this is not possible I will simply use ‘@slugify-title’ and manage with the folder names it produces…

I have created a new blueprint as shown in Add a custom page creation modal.

When I create a post using ‘Add Post’ and enter ‘2018-09-18’ as ‘Post Title’ in the modal form, then save the page, a folder is created with the name ‘2018-09-18’ containing the new page.

I checked again and confirmed that the hyphens are removed in the folder name.
By adding some debug output I can see that they are being removed by this line of the slug function:

$str = transliterator_transliterate('Any-Latin; NFD; [:Nonspacing Mark:] Remove; NFC; [:Punctuation:] Remove;', $str);

Well, there might be some difference depending on the environment I guess. I am testing on my local installation, on Windows.

My original question was more about alternatives to ‘@slugify-title’ or if it is possible to override some methods to make custom replacements.

Maybe the following sample might give you some thoughts to handle your use case.

Created the same blueprint as above (kept the @slugify-title) and created a plugin with the following code:

public function onAdminSave($event)
{
   $page = $event['object'];
   $title = $page->title();
   $folder = preg_replace('/([0-9]{4})([\/-]?)([0-9]{2})\2([0-9]{2})/', '$1-$3-$4', $title);
   $page->folder($folder);
}

The event ‘onAdminSaved’ is fired when a page is saved. The assigned method ‘onAdminSave($event)’ , takes the original title and transforms it into a foldername with ‘-’ as separator.

Notes:

  • You will probably want to embed the script in some test to be sure you are handling only the right pages…
  • Maybe you have to play with the regex (it tests for none, ‘/’, or ‘-’ as seperator between the date parts.
  • If I’m not mistaken, slashes in the foldername will split the foldername into subfolders. That might not be what you want. Or maybe you do…

Thank you! That looks like a good solution. I will test it after I get back home.

I was wondering if Grav has a rewrite mechanism like some other CMS have. For example, in Magento it is possible rewrite any core class by inheriting it (usually from a plugin). Generally most of the code is left untouched and just a specific method is overriden. Magento then uses dependency injection to always instantiate the rewriten class even if the instance’s creation is requested from the core code.

Example here

This makes it possible to customize very specific cases and is often more efficient than handling events. When catching a general event (assuming it exists for the customization we intend to do), we need to apply a bunch of conditions to restrict the cases, let the default behavior occur completely and then reprocess our custom behavior on the top of it…

@pamtbaau Your solution worked. Thank you!

I was hopping to override AdminController::taskContinue() but that doesn’t seem possible… so I will go with events.