Skip to main content

Blog Post

Deep Dive Into Translating Paragraphs

by Dan Polant
May 24, 2017

At Drupalcon, Jay Callicott and I presented “Multilingual in Drupal 8: A soup to nuts guide featuring VisitTheUSA.com and Habitat.org”, which featured a step-by-step guide to setting up a Drupal 8 site for content, interface and config translation. We ended up getting a lot of questions (I took this as a good sign), especially about how translation worked with the Paragraphs module. Paragraphs as a content structure has indeed gotten very popular. To maintain its place as a top multilingual CMS solution, Drupal translation must work well with Paragraphs. So does it?

Mediacurrent has launched a number of sites that involve paragraph translation, including www.habitat.org and www.visittheusa.com. We recommend “full steam ahead” in terms of taking on multilingual projects in D8, including those with paragraphs. However, there are definitely some rough edges that may require workarounds.

Current paragraph translation model

Below is a diagram of how paragraph translation currently works.

Figure 1: Today’s Paragraph translation model
Today’s Paragraph translation model

This article goes on to explain more about this, including how to configure it.

The key thing to note is that the node only reference one set of paragraphs. These paragraphs are fully translatable though, so as long as you’re okay with your Spanish, English, etc versions containing the same translated paragraph entities, you’ll be fine. But is this a realistic expectation?

Problem: Untranslated paragraph bleed

In some projects, this constraint didn’t give us any trouble. However, we did encounter the following scenario:

  • Client was using TMS (e.g. Lingotek)
  • Client wanted to add a paragraph to a page with translations, and wrote the English version first.
  • They published the English version
  • It then showed up in all of the other translations, and the translated content wasn’t ready yet.

Figure 2: Untranslated paragraph bleed
Untranslated paragraph bleed

Solution: Paragraph-level language field

To fix this problem, we added an optional field to paragraphs to let editors pick a set of languages that each paragraph is allowed to display within. For example, to fix the problem as shown in Figure 2, we would set the value of our new “allowed languages” field to just “English,” at least until the Spanish translation was ready.

To add this new field, go to your paragraph type and add a new field. Pick “Language” as the type and set it to multivalue:

Figure 3: Custom language field configuration
Custom language field configuration

Then, go to your default translation (English in our case) for a node containing one of these paragraphs where you only want it to display in the English/default translation. Set the language value to “English.”

Figure 4: Setting paragraph allowed language
Figure 4: Setting paragraph allowed language

Now you need to write some custom code to implement the language restrictions. There are a lot of ways to do this. See below for an example that uses a theme preprocessor, assuming that you are attaching paragraphs to a node:

/**
 * Implements hook_preprocess_node().
 */
function mymodule_preprocess_node(&$variables) {
  $content = $variables['content'];
  // Loop over your paragraph reference field render element.
  foreach (Element::children($content['field_paragraphs']) as $field_name) {
    $element = &$content['field_paragraphs'][$field_name];
    $paragraph = $element['#paragraph'];
    // Don't show the paragraph if it has specified a language set and the
    // current node's language is not in that set.
    if ($paragraph->hasField('field_language') && $paragraph->field_language->value && !in_array($paragraph->field_language->value, $variables['langcode'])) {
      $element['#access'] = FALSE;
    }
  }
}

Other methods include altering the node template and looping over the paragraph field content there, or you could even make a new field formatter for paragraphs. The idea is the same: loop over the paragraph output, load the paragraph object, compare its language preferences to the current node language and remove the paragraph from the display if necessary.

I hope that this helps anyone stuck on this issue!

Headshot

Meet team member, Dan Polant

Dan is a skilled Drupal developer and problem solver who approaches coding as both an art and a science. He has been working with Drupal since 2010.  

Dan became interested in web technologies in 2008, when he created a custom content management platform for his funk band. Shortly after this, he began working with Wordpress, at which point he "saw the light" in terms of what was possible with well-adopted and well-documented open source frameworks. During his last semester at the University of Michigan School of Information graduate program, a professor gave him the opportunity to learn Drupal for a project for the National Science Foundation. This introduction paved the way for the career to which Dan has devoted himself ever since: solving problems for clients using Drupal and contributing code back to the Drupal community.

His deepest subject of expertise is e-commerce, having spent three years deeply immersed in building Drupal-Commerce-powered online stores and ordering systems for clients like Stanford Linear Accelerator Conferences, Children's Hospital of Philadelphia, Duck Commander and Casella Waste Management.

In his spare time, Dan enjoys playing guitar, writing music, running and of course entertaining his 18 month old son.


Learn more about Dan >

Related Insights