Multilanguage fields within a builder

Hello,

How to define different page titles per each language available, but within a builder? this does not seem to work:

pages:
  build:
    - title:
        en: Galleries
        es: Galerías
      template: galleries
      num: 1

Thank you

This is not possible and doesn’t even make sense, because the subpages are only created in the default language, anyway.

I may not be understanding this well.

I’ve seen several posts in the forum which seem to be declaring multiple languages right in the bp file for tittles and field labels. This one for example.:

title:
  en: Project page
  fr: Page de projet
fields:
  title:
    label:
      en: Title
      fr: Titre
    type:  text
  text:
    label:
      en: Text
      fr: Texte
    type:  textarea

Is this still supported? is it documented?

When you say the subpages are only created in the default language, are you refering to the text files?

If I switch language in the panel, the pages are there, and I can change their title manually.

In my case it would make a lot of sense to be able to do it automatically.

My builder builds en ‘edition’ of an event. This edition has a lot of subpages, and their titles are used to fill mostly menus and headers in the frontend.

When user switches language in the frontend, all menus and headers should switch language too. If the titles for the secondary language are empty, the primary language titles will be used, and so the wrong language.

What is nice of the autobuilder is not having to go and create each subpage manuall every time one needs to create an edition. But having to go and edit every subpage’s title in the secondary language manually is similarly annoying

I am understanding this correctly and there is no way for the builder to give title to pages in a secondary language? Is doing this manually after creating an edition the only possible way ? (other than creating a hook or similar)

Thank you

Using language variations for labels etc. in a blueprint is a completely different story then a title field in a text file. These blueprint settings refer to the form labels, help texts etc. in the Panel.

And as I said, the text file is only created in the default language, so to actually store a value for the non default language, you would have to go to that page and hit save.

Because of that, it is indeed impossible. Theoretically, you could use a hook to create the other language versions of those subpages with their respective titles, but unfortunately, there is this issue that currently renders this option useless . Maybe create a custom page builder field or use a hook to create the subpages instead of the builder option.

Ok, I understand now.

I think that IF it makes sense to be able to specify the title in the default language, then it makes sense to be able to specify the title in the secondary language aswell.

Otherwise a page per page manual translate of title is needed. I would say this goes against the usefulness of the builder ?

Unless I am missing something, I’ll create a suggestion or feature request for this.

I’ll check my options now, thanks for the suggestions.

Thank you.

To a certain extend, yes, depending on the use case of these subpages.

There is another option to make up for this deficiency: language variables. Define the language specific translations for the title field in a language variable and use those in your templates. This is particularly useful if these subpages are only containers with no content of their own. Then you might as well make the title readonly or set translate to false in the blueprints for those subpages.

This is actually what I’d do especially if these title field values do not have to be editable.

1 Like

Using the language variable in my case is going to be dirty. I’d need to make a case based function with every subpage title that cannot be translated and hijack my snippets with it.

Additionally the panel admin would be seeing untranslated titles only on those subpages for reasons unknown to her/him.

If the subpage builder can’t do it, a hook should be used Ithink, if I cannot then I will write a hook based builder just this once, which leaves my templates alone and will show the right translated subpage titles to the admin.

Thanks

@texnixe, I am thinking of a workaround.

In my case the page ‘edition-item’, which contains the builder to create all its subpages, is created ‘manually’ in the panel. And so I understand the panel.page.create hook IS triggered

The issue you mentioned ONLY affects the subpages created by the builder itself, which then do NOT trigger the hook. Am I correct?

If I get this right, couldn’t I use $page->index() under the ‘edition-item’ panel.page.create hook, to loop all its (builder created) subpages and use update() to give them titles in the secondary language ?

I think the question would be: is the ‘edition-item’ panel.page.create hook triggered BEFORE or AFTER the builder finished creating the subpages?

Evenmore, in my case, three of these subpages do have another builder in them! ( that is why I was talking about index() and not children() ), so the second question would be: is the hook triggered BEFORE or AFTER the builder within the children created by the first builder finished creating the sub-subpages ?

This is starting to look like a riddle.

Thank you very much for your help.

Yes, exactly, the issue is with the subpages created by the builder; the normal panel.page.create hook works as it should.

That’s exactly the problem, the event is triggered before the subpage builder does its work, see /panel/app/src/panel/collections/children.php, lines #79ff.

1 Like

I am attempting the hook based builder, but I have a question:

Can I pass ‘num’ to $pages->create() in the data array or any other way, in a similar manner to how I pass ‘num’ to the builder?

edit/

Ah no, the file you gave me has the answer:

  if(isset($build['num'])) $subpage->sort($build['num']);

Thanks

Ok, so building a page builder based on hooks, I am experiencing something very similar to the described issue with the subpage builder that led me to do this in the first place.

This is simplified version of my hook, with three items in $missing array (there are more):

kirby()->hook('panel.page.create', function($page) {

	if( $page->intendedTemplate() == 'edition-item' ):

		$missing = array 
		(
			array
			(
				'title_en' => 'Galleries',
				'title_es' => 'Galerías',
				'uid' => 'galleries',
				'template' => 'galleries',
				'num' => '1',
			),
			array
			(
				'title_en' => 'Other Exhibitors',
				'title_es' => 'Otros Expositores',
				'uid' => 'other-exhibitors',
				'template' => 'other-exhibitors',
				'num' => '2',
			),
			array
			(
				'title_en' => 'Press',
				'title_es' => 'Prensa',
				'uid' => 'press',
				'template' => 'press',
				'num' => '3',
			),
		);

		foreach( $missing as $m ):

			$subpage = $page->children()->create( $m['uid'], $m['template'], array(
				'title' => $m['title_en'],
			));

			if( isset($m['num']) ):
				$subpage->sort($m['num']);
			endif;

			$subpage->update(array(
				'title' => $m['title_es'],
			), 'es');

		endforeach;
	
	endif;
});

This works very well.

Now I want to also create subpages for those three pages. So I write another hook, be it as an elseif to this one or separated. I’ll do it separated to simplify:

kirby()->hook('panel.page.create', function($page) {

	if( $page->intendedTemplate() == 'WHICHSUBPAGE' ):

		$missing = array 
		(
			array
			(
				'title_en' => 'Press Releases',
				'title_es' => 'Comunicados de Prensa',
				'uid' => 'press-releases',
				'template' => 'press-releases',
				'num' => '1',
			),
			array
			(
				'title_en' => 'Press Images',
				'title_es' => 'Imágenes de Prensa',
				'uid' => 'press-images',
				'template' => 'press-images',
				'num' => '2',
			),
			array
			(
				'title_en' => 'Press Accreditation',
				'title_es' => 'Acreditación de Prensa',
				'uid' => 'press-accreditation',
				'template' => 'press-accreditation',
			),
		);

		foreach( $missing as $m):

			$subpage = $page->children()->create($m['uid'], $m['template'], array(
				'title' => $m['title_en'],
			));

			if( isset($m['num']) ):
				$subpage->sort($m['num']);
			endif;

			$subpage->update(array(
				'title' => $m['title_es'],
			), 'es');

		endforeach;

	endif;
	
});

…if where I wrote WHICHSUBPAGE I write ‘galleries’ it works, if I write ‘other-exhibitors’ or ‘press’ it does NOT.

If I move ‘press’ or ‘other-exhibitors’ to the first position of the array in the first hook, then THAT page fires the second hook, and so I can create subpages on it, the other two don’t

So It is as if ONLY the first page created in the first hook fires the panel.page.create hook ? and not the other two ?

Is this expected? related to the mentioned issue?

Thank you

I have no answer, but actually, why use a second hook at all. Create the subpages and then create the children of the subpages within the first hook.

I tried that aswell, but did not seem to work neither. Maybe I made a mistake.

Could you drop a tip on how would you introduce that code there ?

I do think that what I describe here looks a lot like the issue you linked. It is as if only a first create() fires the panel.page.create hook, and the rest are blocked. Can this be added to the open issue or help in its resolution ?

Thank you @texnixe

I’ll try to do some tests tomorrow, it’s too late tonight to think clearly.

Yes, please. Thank you.

In example, if in the first hook foreach loop, after the $subpage->update , I add something like this it does NOT work:

	    if( $m['uid'] == 'press' ):

			$missing2 = array 
			(
				array
				(
					'title_en' => 'Press Releases',
					'title_es' => 'Comunicados de Prensa',
					'uid' => 'press-releases',
					'template' => 'press-releases',
					'num' => '1',
				),
				array
				(
					'title_en' => 'Press Images',
					'title_es' => 'Imágenes de Prensa',
					'uid' => 'press-images',
					'template' => 'press-images',
					'num' => '2',
				),
				array
				(
					'title_en' => 'Press Accreditation',
					'title_es' => 'Acreditación de Prensa',
					'uid' => 'press-accreditation',
					'template' => 'press-accreditation',
				),
			);

			foreach( $missing2 as $m2):

				$subpage2 = $subpage->children()->create($m2['uid'], $m2['template'], array(
					'title' => $m2['title_en'],
				));

				if( isset($m2['num']) ):
					$subpage2->sort($m2['num']);
				endif;

				$subpage2->update(array(
					'title' => $m2['title_es'],
				), 'es');

			endforeach;

		endif;

It does not work neither if I use:

if( $subpage->uid() == 'press' ): 

Instead of $m[‘uid’]

I am not so good at php yet, so I may be doing someting simple wrong, maybe I can’t call the variable $subpage within the second, nested, foreach?

Any help would be appreciated.

Thank you

I tested this and it is a question of the order, this works for me:

kirby()->hook('panel.page.create', function($page) {

	if( $page->intendedTemplate() == 'edition-item' ):

		$missing = array
		(
			array
			(
				'title_en' => 'Galleries',
				'title_es' => 'Galerías',
				'uid' => 'galleries',
				'template' => 'galleries',
				'num' => '1',
			),
			array
			(
				'title_en' => 'Other Exhibitors',
				'title_es' => 'Otros Expositores',
				'uid' => 'other-exhibitors',
				'template' => 'other-exhibitors',
				'num' => '2',
			),
			array
			(
				'title_en' => 'Press',
				'title_es' => 'Prensa',
				'uid' => 'press',
				'template' => 'press',
				'num' => '3',
			),
		);
    $missing2 = array
			(
				array
				(
					'title_en' => 'Press Releases',
					'title_es' => 'Comunicados de Prensa',
					'uid' => 'press-releases',
					'template' => 'press-releases',
					'num' => '1',
				),
				array
				(
					'title_en' => 'Press Images',
					'title_es' => 'Imágenes de Prensa',
					'uid' => 'press-images',
					'template' => 'press-images',
					'num' => '2',
				),
				array
				(
					'title_en' => 'Press Accreditation',
					'title_es' => 'Acreditación de Prensa',
					'uid' => 'press-accreditation',
					'template' => 'press-accreditation',
				),
			);
		foreach( $missing as $m ):

			$subpage = $page->children()->create( $m['uid'], $m['template'], array(
				'title' => $m['title_en'],
			));
      if($subpage->intendedTemplate() == 'press') {
        foreach($missing2 as $m2) {
          $subpage2 = $subpage->children()->create($m2['uid'], $m2['template'], array(
					  'title' => $m2['title_en'],
				  ));
          if( isset($m2['num']) ):
					  $subpage2->sort($m2['num']);
				  endif;

				$subpage2->update(array(
					'title' => $m2['title_es'],
				), 'es');
        }

      }
			if( isset($m['num']) ):
				$subpage->sort($m['num']);
			endif;


			$subpage->update(array(
				'title' => $m['title_es'],
			), 'es');


		endforeach;

	endif;
});
1 Like

This works for me too.

So basically you do it BEFORE the sorting and updating ?

Any idea why that is ?

Thank you, this workaround is complete!