Drupal 8 multilingual tidbits 7: blocks and views

Up to date as of October 16th, 2015.

Once you have detailed language information on content, configuration, etc, which is now widely possible in Drupal 8 (see the tidbit on language assignment), you can use this data to pull out content for specific languages.

Everything is in blocks now

While not a multilingual change, it is hugely useful for multilingual use cases that everything is in blocks now. The page title, branding, breadcrumbs, menus, navigation tabs, and so on. This make it possible to customize page content much easier using the blocks controls, effectively giving site builders all the powers around page content.

Block visibility

Brand new in Drupal 8 are language visibility conditions for blocks provided by Language module. This combined with everything being a block allows you to swap out menus per language or localize the branding of the site.

This option is made available if you have more than one configured language on your website. While prior versions of Drupal provided visibility settings based on user roles, content types, paths, etc. this is now expanded to languages too. Here you can pick specific languages, even multiple of them (applying in an or relation).

For real advanced uses, Drupal allows you to configure a separate language negotiation method for content (on Administration » Configuration » Regional and Language » Languages » Detection and Selection). In this case the interface language of the page may be different from the content language. Block language visibility is compatible with this advanced scenario as well, allowing you to configure blocks as being "interface blocks" or "content blocks" in terms of which negotiated language will apply.

Multiple block instances

Drupal 8 also makes it possible to place the same block multiple times, which makes it possible to display it with different visibility conditions and at a different part of the page. For example, you can choose to move the contact form to the sidebar by creating a new block instance of the main page block that only applies to the /contact page and set the original main page block to not show up on the /contact page. Then you can place useful information with a map and physical address data in the main content region in a translatable block for example. The combination of these block tools with multilingual is a real powerhouse for creative site builders.

Many pages and blocks are views now

Another amazing thing in Drupal 8 is with the inclusion of Views, pages like the front page and even the content administration page became editable views. This allows you to customize what is displayed and how it is displayed and with the case of the content administration view even customize it for translation workflows or create a clone for translation workflows. And it is not just pages, several blocks also became views. The new comments, recent content, new users, etc. blocks are now views as well. This opens opportunities far and wide because Views has language filtering for content built-in (which is not new to Drupal 8), and it has rendering settings specific to language (greatly improved in Drupal 8).

Views language filtering

You can apply certain language filters or exclude specific languages here. There are also dynamic language possibilities based on the site default language or the language selected for the page. While language filtering is not new, what is exciting is the combination of almost universal language assignment as well as listings converted to Views on the frontend and backend.

This allows site builders to customize views for specific languages, apply dynamic language filtering to pages and possibly expose the language filter as needed. This also allows to easily add language specific filtering to admin interfaces combined with other features.

Views language rendering

While language filtering is acting in the views query building, you can also configure how the result is presented. When Language module is enabled and there is more than one language on the site, you can also configure the rendering language setting of views. This is configured from the bottom of the second column. The options include the language the view found the entity in (language of the view row), the original language of the entity regardless of what language views found, as well as the site default language or the current interface language (and content language if you have that configured too). Finally you can also just render in any specific language configured on the site.

In summary, Drupal 8 makes all things blocks on the page, which allows you to place multiple instances and assign page and language conditions, which makes for really powerful tools for page building. As for contents of the blocks themselves, use the built in Views module to do listings to pull data from entities with versatile language options as well. Drupal now provides a full set of tools for site builders to dynamically apply language based conditions to all parts of the website in detail.

Issues to work on

  • DONE! There are several issues to convert remaining special page items to blocks. Global menus at https://drupal.org/node/1869476, page elements (title, tabs, actions and messages) in https://drupal.org/node/507488, site elements (site name, slogan) in https://drupal.org/node/1053648.
  • DONE! You may have noticed that "Not applicable" and "Not specified" appear as options for block languages. This is silly. The interface or content language will never be one of these on a page. Picking these is useless. A specific issue for this is at https://www.drupal.org/node/2037979.
  • On the previous point, the same issue that I mentioned multiple times before about which languages apply to which things would solve it on a grander scale. See https://drupal.org/node/1314250
  • DONE! The Views language filter for the current negotiated language is misleadingly named as far as I see. It suggests the language is based off the user's preferred language, which may or may not be true. Discuss and solve at https://www.drupal.org/node/2037979

Comments

Globalbility's picture

Will it be possible to alter available languages lists to views language filter?
E.g.
A dynamic language list for the visitors fallback languages

Gábor Hojtsy's picture

Yes, you can still use hook_form_alter() to alter forms such as the views exposed filters on a specific view.

Ian Cawthorne's picture

On my Drupal 8 install, I don't have the two options in the "Content: Translation language" filter:

- Language selected for User interface text
- Language selected for Content

I have all the other, ie the languages, Select all, Not specified and Not applicable.

Do you know if there is something that should be set to for these options to be visible as filter options? (It sounds like "Language selected for Content" is the one I need!)

Gábor Hojtsy's picture

By default these two are the same, and in that case only one option is displayed. If you don't need a separate interface language from content language (which is typical) then there is no reason to have two separate options. You can configure the language negotiation setup to be different for languages from interface in the language detection and selection settings under Regional and language >> Languages.

Andrei Orekhov's picture

Hi Gábor,
The D8 multilingual support looks very impressive, so impressive in fact that I got hopelessly lost trying to figure out how to achieve a simple and natural functionality ;)
I am building a site in English as the default language and a number of "secondary" languages will be added for the users' convenience. As the content will be added continuously (in English initially) and then slowly translated by volunteers on the time available basis, at no point in time ALL content will be COMPLETELY translated into all supported languages. Nevertheless, it's important for all users regardless of their language chosen to see ALL nodes relevant to their query - if a node has a translation into their language they should see it in their language, if not - they should see it in the default language (English). I can't figure out how to set it up in Views. If I simply set "Translation language" = "Interface text language selected for page" and switch the site language to Russian, then I only get a handful of nodes I translated into Russian. If I remove the language filter, I see everything but all nodes that have a translation are listed twice. How can I configure the filter so that ALL nodes are listed, each node only once, translated if available and not translated if not?
Would really appreciare any insight.

Gábor Hojtsy's picture

You are not the only one :) See the question/answer below at http://hojtsy.hu/comment/21836#comment-21836

Víctor's picture

Hi Gábor, first of all thanks for your great work related on multilingual and for this pretty docs. I'm currently working on a multilingual Drupal 8 multisite and I need to translate some views. Translate config is pretty straightforward, but I don't know how to translate my views paths. I've tried this and it works for paths but doesn't work for breadcrumbs. I supose the problem occurs because the breadcrums are built based on paths and probably it doesn't attend to path alias. Is there a solution for this problem?

Andrei Orekhov's picture

Hi Gábor,
Could you please take a look at https://www.drupal.org/node/2831738 when you have a minute?
Either I am missing something obvious or there is something wrong with the links generation: in my understanding ALL links generated by a view with "Rendering Language" set to "Interface text language selected for page" should include the current UI language code in their URLs and lead to pages in the selected UI language regardless of whether the specific piece of content has a translation or not.
Would greatly appreciate your comment.

audrius's picture

I do have EXACTLY the same problem. Have you found any (not dirty) solution?

s427's picture

Is it possible to configure a view to display content in the current interface language, but if some content is not translated in the current language, display that content in the original language?

In other words, have the original language as a fallback if the translation doesn't exist?

I've tried all options present in "Rendering Language", but I can't seem to get that behavior.

Gábor Hojtsy's picture

That does not seem to be possible in core, however it would be relatively easy to write a views entity translation renderer plugin to offer that feature (and add it to core in a future release :) The base class for entity translation renderers is EntityTranslationRendererBase and none of the classes extending it seem to be using the entity repository to negotiate a language (and therefore apply fallback).

Andrei Orekhov's picture

Hi Permalink,
I have achieved what you seem to want the following way:
1. In your view filter criteria settings add "Default translation = TRUE". That will make sure the query will return all entities, translated or not, and every entity only one time. At this point it does not matter in what language you want to display the results.
2. In your view rendering language settings select "Interface text language selected for page". This way Drupal will return the translated page if it exists and the original page if there's no translation.
When you get to this stage you will realize there are two more problems which I do not know how to solve yet:
1. The sorting is according to the original language.
2. The views itself looks fine in your target language but when you click on a link in any untranslated row then you lose your selected interface language and fall back to original (default).

audrius's picture

Gabor, what is your advice for the least dirty way to get this:
View is listing nodes in some pre-defined view mode, but the links to the nodes are without language prefix or the code of language is displayed the same as the language of the node. The content itself is the same for all the languages, only some labels in the node are different.

What do I want is to get view mysite.com/en/myview listing if interface is currently selected in english with links:
www.mysite.com/en/node/1
www.mysite.com/en/node/2

What I want is if I switch interface to another language (french) mysite.com/fr/myview - then views links also automatically switch to that language:
www.mysite.com/fr/node/1
www.mysite.com/fr/node/2

But any of the combination of single/multilanguage nodes and views configurations do not work.
Is there a way to do this without manually building links with help of tokens and other not-so-clean ways?

Add new comment