Content file translations and page hooks

Good afternoon

I am automatically translating page content via kirby-machine-translation since provides a nice method for that: $page->machineTranslate($targetLang, $sourceLang, $force). So for example

$page->machineTranslate("en", "de", true);

create an auto-translated article.de.txt content file for my article.en.txt which is great.

As far as my tests show, the hooks I can define in config.php such as page.create:after or page.update:after do not fire and there are no page.translate:after hooks.

What I would like to do are two things after the translation has taken place:

  1. Generate a language specific slug
  2. Update a page specific image which has language specific text on it

Obviously I could change the plugin source code to add these two things but that is not a clean solution.

I also tried to update the slug manually while translating the content:

                foreach($languages as $targetLanguage){
                    $newPage->machineTranslate($targetLanguage, $languages->default(), true);
                    $newPage->translation($targetLanguage)->update(['slug' => $newPage->createdOn()->toDate('%Y-%m-%d').'-'.$newPage->title()->slug()]);
                }

But that does not work either. The changeSlug() method is not available for Kirby\Content\ContentTranslation objects and $contenttranslation->slug() | Kirby CMS (getkirby.com) only returns the slug, not update it.

Any ideas how to fix this?

Thanks
Andreas

You need to use changeSlug() with the lang code as param, see $page->changeSlug() | Kirby CMS

A contenttranslation object cannot be updated, anyway.

I don’t know what this maschineTranslate() method does, but note that objects are immutable in Kirby. So you need to store the result of that method in a variable, before calling changeSlug()

Thanks @texnixe , I solved the issue with this code, in case anyone needs it for future reference:

                // Let's get all currently set up language codes
                $languages = kirby()->languages();

                foreach($languages as $targetLanguage){
                    // First, let's translate the page to the target language
                    $translatedPage = $newPage->machineTranslate($targetLanguage, $languages->default(), true);
                    // Then, lets get the content of the page in the target language ...
                    $pageForSlug = page($newPage->uuid())->content($targetLanguage);
                    // So we can then update the slug to a localized one
                    $translatedPage->changeSlug($pageForSlug->createdOn()->toDate('%Y-%m-%d').'-'.$pageForSlug->title()->slug(), $targetLanguage);
                }

This not only automatically translate the page into all currently setup languages in kirby using the above linked plugin (via DeepL), it also localizes the slug :+1:

@tobiasfabian FYI in case that is a feature you might want to think about including in your plugin? Auto slug translation that is :slight_smile:

Andreas

Getting the page object if you already have it is unnecessary.

Either use $newPage->content($targetLanguage) or $translatedPage->content($targetLanguage)

Oh, and not really an issue, but the variable name is rather confusing, because what page($newPage->uuid())->content($targetLanguage) returns is not a Page object, but a content object.

1 Like

Very true, thank you! Also, it turns out that by adding the date to the slug manually, there is a chance that I might reach the limit of the slug length so I added a Str::short just to make sure:

                // Let's get all currently set up language codes
                $languages = kirby()->languages();

                foreach($languages as $targetLanguage){
                    // First, let's translate the page to the target language
                    $translatedPage = $newPage->machineTranslate($targetLanguage, $languages->default(), true);
                    // Then, lets get the content of the page in the target language ...
                    $pageContentForSlug = $newPage->content($targetLanguage);
                    // So we can then update the slug to a localized one
                    $translatedPage->changeSlug(Str::short($pageContentForSlug->createdOn()->toDate('%Y-%m-%d').'-'.$pageContentForSlug->title()->slug(), 120,''), $targetLanguage);
                }

@texnixe I have one more question if I might: is there a way to get the page object in a specific language/translation (not just the content)

Thanks
Andreas

No, because the page object contains everything (content, translations, files…).

What are you after?

Understood, thanks.

I have a method which generates an open graph image dynamically when the title of a page changes. Now with the translation tool I am using to translate the content, this does not work because the hooks are not called.

But I solved the problem by simply calling the method after translation for each language and adding a targetLanguage parameter to my method and grabbing the content in the target language there instead of using the fields methods, but thanks for asking :+1: