In my theme I have a blueprint for a custom page template (let’s call it custom.html.twig) that includes an additional field with a page selection. In the returned <select> list the option labels show the translated page titles, but the value attributes – which will be stored in the page’s frontmatter – always contain the slug for the default language.
Is there a way to show the translated slugs?
Example: an option in the select list of a page in the secondary language German looks something like this (ignoring the fancy select lists here)
HTML
<optionvalue="/projects">Projekte</option>
But it should look like this:
HTML
<optionvalue="/de/projekte">Projekte</option>
In the blueprint (mytheme/blueprints/custom.yaml) I’ve tried both type: pages as well as type: select with data-options@. The result is the same in both cases:
hi, @clivebeckett, you can set the var in the page template
(as i understand you define var in the theme blueprints.yaml file, if so)
an example for a pages form field could be {% set internalLinkVariant1 = page.find(theme_var('internalLinkVariant1')) %}
and then do what you need, like this <a href="{{ internalLinkVariant1.url|e }}">{{ internalLinkVariant1.title|e }}</a>
Thank you! But this is not about the theme blueprints.yaml, but about the blueprint for a page template as stored in mytheme/blueprints/. I tried to clarify that in an edit for the post, sorry if it was a bit unclear before.
so use header_var('internalLinkVariant1'), fallback to theme_var, or page.header.internalLinkVariant1 instead. Just test it )
{% set internalLinkVariant1 = page.find(header_var('internalLinkVariant1')) %}
or {% set internalLinkVariant1 = page.find(page.header.internalLinkVariant1)) %}
the declaration for custom var in page blueprint must start with header. that why i thought it is theme blueprint
Thank you! If I’m not overlooking anything, this is still not what I’m searching for. I had tried to strip everything down wanting to avoid unnecessary information. Apparently I did not manage to explain properly with this 🙂 – Let’s have another go:
custom.yaml
still only a small section
my internal link is part of a field type:list which is why I forgot to add “header” after I dropped the original dot
the alternative implementation of the page selector is commented out – the result in the form is the same
The problem is not in the Twig template (see below) – although it’s possible that it can be solved in the template. The problem is, that the form as defined in custom.yaml shows translated page titles – but not the translated slugs in the value attribute of the select list. So if I am in the form of a German page and select the page “Projekte” which has the slug “/de/projekte”, the form shows “/projects” as value instead – and this is what will be saved in the frontmatter/header section of the page’s markdown.
custom.html.twig
I do have access to the header data and it works – but on the German website it links to the English (default) page – because of the above mentioned default slug in the form.
HTML
{% if page.header.call2ActionLinks is not empty %}
<ulclass="c2a"> {% for c2a in page.header.call2ActionLinks %}
{% if c2a.internal != 'none' %}
<li><ahref="{{ c2a.internal }}">{{ c2a.label }}</a></li> {% elseif c2a.external %}
<li><ahref="{{ c2a.external }}"target="_blank">{{ c2a.label }}</a></li> {% endif %}
{% endfor %}
</ul>{% endif %}
This works – with some changes. I wanted the default level marker (—-—-▸ Page Title) back in the list which was missing. Here’s my updated version for documentation. For easier readability it contains the original lines of code in comments:
PHP
publicstaticfunctiongetTranslatedSlugs():array{/**@varGrav*/$grav=Grav::instance();/**@varAdmin*/$admin=$grav['admin'];$admin->enablePages();/**@varPages*/$pages=$grav['pages'];/**@varLanguage*/$language=$grav['language'];$activeLanguage=$language->getActive();$isDefaultLanguage=$language->getDefault()===$activeLanguage;$showDefaultLanguageInUrl=$grav['config']->get('system.languages.include_default_lang',false);// making sure $pages->getList() returns the level marker and hides modules// $pageList = $pages->getList(null, 0, true, false, true, true, true, false);$pageList=$pages->getList(null,0,true,false,false,false,false,false);$translatedPages=[];foreach($pageListas$key=>$value){$page=$pages->find($key);// this replacement is just a matter of personal taste// $slug = $page->route();// if (!$isDefaultLanguage || ($isDefaultLanguage && $showDefaultLanguageInUrl)) {// $slug = "/{$activeLanguage}{$slug}";// }$slug=(!$isDefaultLanguage||($isDefaultLanguage&&$showDefaultLanguageInUrl))?'/'.$activeLanguage.$page->route():$page->route();// $value of $pageList now contains the level marker// $translatedPages[$slug] = $page->title();$translatedPages[$slug]=$value;}return$translatedPages;}
Also make sure to include
PHP
useGrav\Common\Grav;
in your Plugin Class definition. This was not in the plugin skeleton created by devtools and it took me a while to figure out how to include it.