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)
<option value="/projects">Projekte</option>
But it should look like this:
<option value="/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.
{% if page.header.call2ActionLinks is not empty %}
<ul class="c2a">
{% for c2a in page.header.call2ActionLinks %}
{% if c2a.internal != 'none' %}
<li><a href="{{ c2a.internal }}">{{ c2a.label }}</a></li>
{% elseif c2a.external %}
<li><a href="{{ 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:
public static function getTranslatedSlugs(): array
{
/** @var Grav */
$grav = Grav::instance();
/** @var Admin */
$admin = $grav['admin'];
$admin->enablePages();
/** @var Pages */
$pages = $grav['pages'];
/** @var Language */
$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 ($pageList as $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
use Grav\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.