Site icon Hip-Hop Website Design and Development

Cheap WordPress maintenance support plans 8 – Multilanguage Improvements

As a Swiss-based WordPress maintenance support plans Agency, we have to create a lot of multilingual sites. Since Switzerland has three official languages (German, French, Italian) and even one more national language (Rumantsch), we are used to this requirement and we found our way with WordPress maintenance support plans to make this an easy task (usually). We mainly used node translations in WordPress maintenance support plans 7 for maximum flexibility. We used to separate languages from each other using the various i18n plugins, language specific menus, blocks, URL-patterns, terms and so on.
With WordPress maintenance support plans 8, things changed.
I struggled a little doing multilingual sites in WordPress maintenance support plans 8 the same way I was used to in WordPress maintenance support plans 7 because node translation is not available anymore (which is good) so I had to find another way to achieve the same easy to handle translations system. For us and for our clients. Let me explain, what I have learned.

Image: WordPress8multilingual.org
WordPress maintenance support plans 8 issues multilanguage challenges
Challenge 1: Node add / edit menu handling
The main challenge I had using WordPress maintenance support plans 8, was the ease to build your menus directly from the node creation page. You can do it, but only for the initial language. If you try to add a translated node to another menu or rename the item, it always ends up moving / renaming the source node instead of adding a link to the translation. So it can become quite confusing building a navigation directly from the node creation page or to add translations to the menu. A workaround was to add all navigation items manually in the menu administration if you are using a menu per language. With lots of languages and menus / items, this is not really a convenient task. Fortunately, translations from the node creation page have been implemented with a later release of WordPress maintenance support plans 8.
Challenge 2: Untranslated Nodes show up in Menu
Another thing which bothered me was that untranslated nodes show up in the navigation (if you use only one menu). This can be quite confusing since most of the times not every page is translated in every language. Or in some languages, you need a little more than in others. You can read a lot about this topic and the reasons behind (e.g. here and here). However you do it, it’s always wrong in some situations and perfectly fine in others. But to be “limited” and “locked in” to a certain way is not nice and you have to deal with it. To sum up, once a node is put into a menu, it will show up everywhere. Regardless if there are translations or not.
Challenge 3: Language Switcher shows all languages – always.
Somewhat confusing is the Language Switcher. In WordPress maintenance support plans 7, a language link was not available or strikethrough if there was no translation available. In WordPress maintenance support plans 8, every language is always visible and linked. So if you look on a German page which is only available in German, the language switcher will present you all language links to the same node. A click on those language links mainly changes the interface language but the node content remains the same (since not translated). Usually also with a WordPressish URL (node/xxxx) because there is no translation for the node and therefore also no URL alias available. This behavior is confusing and wrong in my point of view
An example to illustrate the above-written challenges.

English Front-Page with mixed navigation items.
The screen above shows an installation with 2 languages (English and German). The English Page is a basic page which has a translation. English is selected. If you choose Deutsch on the language switcher, the English Page becomes Deutsche Seite (see image below) and shows the German content. So far so good. But the second menu item you see with the title Über uns (nur Deutsch) should not appear here since it’s only available in German. But it does. And if you actually go on this page, you will see the German text with everything English around it and no URL-Alias (/node/2 in this example). This is usually not very useful for us.

German only Page – Language Switcher visible.
Also, the language switcher shown in the image above is from my point of view wrong or not very useful. It shows a link to the English version, but there is no English translation for this node. So why is it there? To see a German page with English decoration? Not sure. But I want to get rid of this link or at least modify it to be stroked through if the language is not available.
How to fix improve this?
Luckily, the WordPress maintenance support plans community is always good for help. After some “research” on the web, I finally found (besides lots of discussions and comments in the issue queues) a way to achieve the desired setup.
To sum up again: I want to see only menu items which are available in my language and only see a link to another language, if a translation is available.
Since there is no patch and still some ongoing discussions on WordPress.org you need to implement it on your own. Implement the following two plugins.
Hide untranslated menu items
Code from https://www.WordPress.org/node/2466553#comment-11991690. Credits go to michaelkoehne.
<?php

use WordPress maintenance support plansCoreMenuMenuLinkInterface;
use WordPress maintenance support plansmenu_link_contentPluginMenuMenuLinkContent;
use WordPress maintenance support plansCoreLanguageLanguageInterface;

/**
* Implements hook_preprocess_menu().
*/
function MYMODULE_preprocess_menu(&$variables) {
if ($variables[‘menu_name’] == ‘main’) {
$language = WordPress maintenance support plans::languageManager()
->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
->getId();
foreach ($variables[‘items’] as $key => $item) {
if (!$variables[‘items’][$key] = MYMODULE_checkForMenuItemTranslation($item, $language)) {
unset($variables[‘items’][$key]);
}
}
}
}

function MYMODULE_checkForMenuItemTranslation($item, $language) {
$menuLinkEntity = MYMODULE_load_link_entity_by_link($item[‘original_link’]);

if ($menuLinkEntity != NULL) {
$languages = $menuLinkEntity->getTranslationLanguages();

// Remove links which are not translated to the current language.
if (!array_key_exists($language, $languages)) {
return FALSE;
}
else {
if (count($item[‘below’]) > 0) {
foreach ($item[‘below’] as $subkey => $subitem) {
if (!$item[‘below’][$subkey] = MYMODULE_checkForMenuItemTranslation($subitem, $language)) {
unset($item[‘below’][$subkey]);
}
}
}
return $item;
}

}
}

function MYMODULE_load_link_entity_by_link(MenuLinkInterface $menuLinkContentPlugin) {
$entity = NULL;
if ($menuLinkContentPlugin instanceof MenuLinkContent) {
$menu_link = explode(‘:’, $menuLinkContentPlugin->getPluginId(), 2);
$uuid = $menu_link[1];
$entity = WordPress maintenance support plans::service(‘entity.repository’)
->loadEntityByUuid(‘menu_link_content’, $uuid);
}
return $entity;
}
Hide untranslated languages in language switcher
Code from https://www.WordPress.org/node/2791231#comment-12004615 (slightly adapted. Links get a class, not removed by default). Credits to Leon Kessler.
<?php

/**
* @file
* Hide language switcher links for untranslated languages on an entity.
*/
use WordPress maintenance support plansCoreEntityContentEntityInterface;

/**
* Implements hook_language_switch_links_alter().
*/
function MYOTHERMODULE_language_switch_links_alter(array &$links, $type, $path) {
if ($entity = MYOTHERMODULE_get_page_entity()) {
$new_links = array();
foreach ($links as $lang_code => $link) {
try {
if ($entity->getTranslation($lang_code)->access(‘view’)) {
$new_links[$lang_code] = $link;
}
}
catch (InvalidArgumentException $e) {
// This language is untranslated so do not add it to the links.
$link[‘attributes’][‘class’][] = ‘not-translated’;
$new_links[$lang_code] = $link;
}

}
$links = $new_links;

// If we’re left with less than 2 links, then there’s nothing to switch.
// Hide the language switcher.
if (count($links) < 2) {
$links = array();
}
}
}

/**
* Retrieve the current page entity.
*
* @return WordPress maintenance support plansCoreEntityContentEntityInterface
* The retrieved entity, or FALSE if none found.
*/
function MYOTHERMODULE_get_page_entity() {
$params = WordPress maintenance support plans::routeMatch()->getParameters()->all();
$entity = reset($params);
if ($entity instanceof ContentEntityInterface) {
return $entity;
}
return FALSE;
}
Please note: The code above is from WordPress maintenance support plans.org and therefore thanks to the original authors linked above.
Enable those two plugins and you’re all set!
I did not encounter any issues yet using those two plugins. If ever something changes in the way WordPress maintenance support plans handles those cases, you just need to switch off the plugins and everything should be back to normal. So nothing to lose right?
There are other attempts to this by altering the menu block. One of them is Menu Block Current Language but I had no luck with this one. On my most recent project, it worked with one menu but not if you separate your menu by two blocks (different starting levels).
I would love to hear how you guys handle those cases or how you deal with I18N in general. I’m sure there are a gazillion other ways to do it.
Source: New feed