<?xml version="1.0" encoding="utf-8"?>
<!-- generator="Kirby" -->
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">

  <channel>
    <title>Tag: drupal &#183; Blog &#183; Liip</title>
    <link>https://www.liip.ch/de/blog/tags/drupal</link>
    <generator>Kirby</generator>
    <lastBuildDate>Mon, 29 Oct 2018 00:00:00 +0100</lastBuildDate>
    <atom:link href="https://www.liip.ch" rel="self" type="application/rss+xml" />

        <description>Liip Blog Artikel mit dem Tag &#8220;drupal&#8221;</description>
    
        <language>de</language>
    
        <item>
      <title>Drupal Europe 2018</title>
      <link>https://www.liip.ch/de/blog/drupal-europe-2018</link>
      <guid>https://www.liip.ch/de/blog/drupal-europe-2018</guid>
      <pubDate>Mon, 29 Oct 2018 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>In 2017, Drupal Association decided not to host a DrupalCon Europe 2018 due to <a href="https://www.drupal.org/association/blog/drupalcon-europe-solving-the-financial-problem">waning attendance and financial losses</a>. They took some time to make the European event more sustainable. After this, the Drupal community decided to organise a Drupal Europe event in Darmstadt, Germany in 2018. My colleagues and I joined the biggest European Drupal event in October and here is my summary of few talks I really enjoyed!</p>
<h2>Driesnote</h2>
<p>By <a href="https://twitter.com/Dries">Dries Buytaert</a><br />
Track: Drupal + Technology<br />
<a href="https://www.youtube.com/watch?v=iXB0sNreSlM">Recording</a> and  <a href="https://dri.es/files/state-of-drupal-september-2018.pdf">slides</a></p>
<p>This year, Dries Buytaert focuses on improvements made for Drupal users such as content creators, evaluators and developers. </p>
<p>Compared to last year, Drupal 8 contributions increased by 10% and stable modules released by 46%. Moreover, a steady progress is noticeable. Especially in many core initiatives like <a href="https://www.drupal.org/blog/drupal-8-6-0">the last version of Drupal 8</a> which is shipped with features and improvements created from 4 core initiatives.</p>
<p>Content creators are the key-decision makers in the selection of a CMS now. Their expectations have changed: they need flexibility but also simpler tools to edit contents. The layout_builder core module gives some solutions by enabling to edit a content inline and drag-and-dropping elements in different sections. The management of medias has been improved too and there is a possibility to prepare different “states” of contents using workspaces module. But the progress doesn’t stop here. The next step is to modernize the administrative UI with a refresh of the Seven administration theme based on <a href="https://www.liip.ch/Go to React">React</a>. Using this modern framework makes it familiar to Javascript (JS) developers and is building a bridge with the JS community.</p>
<p>Drupal took a big step forward for evaluators as it provides a demo profile called “<a href="https://www.drupal.org/docs/8/umami-drupal-8-demonstration-installation-profile">Umami</a>” now. Evaluators have a clear understanding of what kind of websites can be produced by Drupal and how it works by navigating through the demo website.<br />
The online documentation on drupal.org has also been reorganized with a clear separation of Drupal 7 and Drupal 8. It provides some getting-started guides too. Finally, <a href="https://www.drupal.org/docs/official_docs/en/_evaluator_guide.html">a quick-install link</a> is available to have a website  running within 3 clicks and 1 minute 27 seconds!</p>
<p>Developers experience has been improved as well: minor releases are now supported for 12 months instead of the former 4 weeks. Teams will have more time to plan their updates efficiently. Moreover, Gitlab will be adopted within the next months to manage the code contributions. This modern collaborative tool will encourage more people to participate to projects.</p>
<p>Regarding the support of the current Drupal versions, Dries shares that Symfony 3, the base component of Drupal 8 will be end-of-life by 2021. To keep the CMS secure, it implies to be end-of-life by November 2021 and Drupal 9 should be released in 2020. The upgrade from Drupal 8 to Drupal 9 should be smooth as long as you stay current with the minor releases and don’t use modules with deprecated APIs.<br />
The support of Drupal 7 has been extended to November 2021 as the migration path from Drupal 7 to Drupal 8 is not stable with multilingualism yet.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/228360/slide-driesnote-drupal-progress.jpg" alt="This is a slide from Driesnote presentation showing a mountain with many tooltips: &quot;Drupal 8 will be end-of-life by November 2021&quot;, &quot;Drupal 7 will be supported until November 2021&quot;, &quot;Drupal 9 will be released in 2020&quot;, &quot;Drupal 8 became a better tool for developers&quot;, &quot;You now have up to 12 months to upgrade your sites&quot;, &quot;Drupal 8 became much easier to evaluate&quot;, &quot;We've begun to coordinate the marketing of Drupal&quot;, &quot;Drupal 8 became easier to use for content creators&quot;, &quot;Drupal.org is moving to GitLab very soon&quot;."><figcaption>Slide from Driesnote showing current state of Drupal.</figcaption></figure>
<p>Last but not least, <a href="https://events.drupal.org/amsterdam2019">DrupalCon is coming back next year and will be held in Amsterdam</a>!</p>
<h2>JavaScript modernisation initiative</h2>
<p>By <a href="https://twitter.com/chumillas">Cristina Chumillas</a>, <a href="https://twitter.com/laurii1">Lauri Eskola</a>, <a href="https://twitter.com/alwaysworking">Matthew Grill</a>, <a href="https://twitter.com/da_wehner">Daniel Wehner</a> and <a href="https://twitter.com/justafish">Sally Young</a><br />
Track: Drupal + Technology<br />
<a href="https://youtu.be/KrbmsOjWFPw">Recording</a> and <a href="https://www.drupaleurope.org/sites/default/files/slides/2018-09/Drupal%20Europe%202018_%20Admin%20UI%20%26%20JavaScript%20Modernisation%20Initiative.pdf">slides</a> </p>
<p>After a lot of discussions on which JS framework will be used to build the new Drupal administrative experience, <a href="https://reactjs.org/">React</a> was finally chosen for its popularity.</p>
<p>The initiative members wanted to focus on the content editing experience. This affects a big group of Drupal users. The goal was to simplify and modernize the current interface. Furthermore, embracing practices that are familiar to JS developers so they can easier join the Drupal community.<br />
On one hand, a UX team ran some user tests. Those showed that users like the flexibility they have with Drupal interface but dislike its complexity usually. A comparative study was ran to know what has been used in other tools or CMSs too. On the other hand, the User Interface (UI) team worked on the redesign of the administrative interface and built a design system based on components. The refreshment of the Seven administration theme is ongoing.<br />
Another group worked on prototyping the User Experience (UX) and  User  Interface (UI) changes with React. For instance, if an editor quits a page without saving they's last changes, a popup appears to restore the last changes. This is possible due to contents stored to the state of the application. </p>
<p>You can see a demo of the new administrative UI in the video (go to 20 minutes 48 seconds):</p>
<figure class="embed-responsive embed-responsive--16/9"><iframe src="//youtube.com/embed/KrbmsOjWFPw" frameborder="0" webkitallowfullscreen="true" mozallowfullscreen="true" allowfullscreen="true"></iframe><figcaption>Demo of the new administrative UI in Drupal 8</figcaption></figure>
<p>If you are interested, you can <a href="https://github.com/jsdrupal/drupal-admin-ui-demo">install the demo</a> and of course <a href="https://www.drupal.org/about/strategic-initiatives/admin-ui-js">join the initiative</a>!</p>
<h2>Drupal Diversity &amp; Inclusion: Building a stronger community</h2>
<p>By <a href="https://twitter.com/sparklingrobots">Tara King</a> and <a href="https://twitter.com/ekl1773">Elli Ludwigson</a><br />
Track: Drupal Community<br />
<a href="https://youtu.be/Z3dBfYQAacs">Recording</a></p>
<p>Diversity in gender, race, ethnicity, immigration status, disability, religion etc. helps a lot. Proven it makes a team more creative, collaborative and effective.</p>
<p>Tara King and Elli Ludwigson who are part of the <a href="https://www.drupal.org/drupal-diversity-inclusion-contribution-team">Drupal Diversity and Inclusion team</a> presented how Drupal is building a stronger and smarter community. The initial need was to make Drupal a safer place for all. Especially for the less visible ones at community events such as women, minorities and people with disabilities.<br />
The group addressed several issues, such as racism, sexism, homophobia, language barriers etc. with different efforts and initiatives. For example, diversity is highlighted and supported in Drupal events: pronoun stickers are distributed, <a href="https://twitter.com/search?q=%23wearedrupal&amp;src=typd">#WeAreDrupal</a> hashtag is used on Twitter and social events are organized for underrepresented people as well. Moreover, the group has released <a href="https://www.drupaldiversity.com/resources">an online resource library</a>, which collects articles about diversity. All of this is ongoing and new initiatives were created. Helping people finding jobs or attracting more diverse people as recruiters are only two to name.</p>
<figure><a href="https://www.flickr.com/photos/68158920@N08/43944786484/in/pool-drupaleurope/"><img src="https://liip.rokka.io/www_inarticle/a68315/diversity-and-inclusion-flyer-at-drupal-europe.jpg" alt='Flyer put on a table with the text "Make eye Contact. Invite someone to join the conversation. Consider new perspectives. Call out exclusionary behavior. Be an ally at Drupal events."'></a><figcaption>Diversity and Inclusion flyer, photo by Paul Johnson, license CC BY-NC 2.0</figcaption></figure>
<figure><a href="https://www.flickr.com/photos/gaborhojtsy/30863579608/in/pool-drupaleurope"><img src="https://liip.rokka.io/www_inarticle/15c4ed/all-gender-restrooms-sign-at-drupal-europe.jpg" alt='Sign mentionning "All-gender restrooms" at Drupal Europe venue.'></a><figcaption>All-gender restrooms sign, photo by Gábor Hojtsy, license CC BY-SA 2.0</figcaption></figure>
<p>If you are interested in the subject and would like to be involved, there are weekly meetings in #diversity-inclusion <a href="http://drupalslack.herokuapp.com/">Drupal Slack</a> channel. You can join the <a href="https://www.drupal.org/drupal-diversity-inclusion-contribution-team">contrib team</a> or work on the <a href="https://www.drupal.org/project/issues/ddi_contrib">issue queue</a> too.</p>
<h2>Willy Wonka and the Secure Container Factory</h2>
<p>By <a href="https://twitter.com/skwashd">Dave Hall</a><br />
Track: DevOps + Infrastructure<br />
<a href="https://youtu.be/bPdMZ92n7ls">Recording</a></p>
<p><a href="https://www.docker.com/">Docker</a> is a tool that is designed to create, deploy and run applications easily by using containers. It is also about “running random code downloaded from the internet and running it as root”. This quote points out how it is important to maintain secure containers. David Hall illustrates this with practical advice and images from the “Willy Wonka and the chocolate factory” movie. Here is a little recap:</p>
<ul>
<li>Have a light image: big images will slow down deployments and also increase the attack surface. Install an Alpine distribution rather than a Debian which is about 20 times lighter;</li>
<li>Check downloaded sources very carefully: for instance, you can use wget command and validate checksum for a file. Plus you can scan your images to check vulnerabilities using tools like <a href="https://github.com/aquasecurity/microscanner">Microscanner</a> or <a href="https://github.com/arminc/clair-scanner">Clair</a>;</li>
<li>Use continuous development workflows: build a plan to maintain your Docker images, using a good Continous Integration / Continous Delivery (CI/CD) system and document it;</li>
<li>Specify a user in your dockerfile: running root on a container is the same as running root on the host. You need to reduce the actions of a potential attacker;</li>
<li>Measure your uptime in hours/days: it is important to rebuild and redeploy often to potentially avoid having a compromised system for a long time.</li>
</ul>
<p>Now you are able to incorporate these advice into your dockerfiles in order to build a safer factory than Willy Wonka’s.</p>
<h2>Decoupled Drupal: Implications, risks and changes from a business perspective</h2>
<p>By <a href="https://twitter.com/Schnitzel">Michael Schmid</a><br />
Track: Agency + Business<br />
<a href="https://youtu.be/DFKJbNTZyGw">Recording</a></p>
<p>Before 2016, Michael Schmid and his team worked on fully Drupal projects. Ever since they are working on progressive and fully decoupled projects.<br />
A fully decoupled website means that frontend is not handled with Drupal but with a JS framework such as <a href="https://reactjs.org/">React</a>. This framework is “talking” to Drupal via an API such as <a href="https://graphql.org/">GraphQL</a>. It also means, that all interactions from Drupal are gone: views with filters, webforms, comments etc. If a module provides frontend, it is not useable anymore and needs to be somehow re-implemented.<br />
When it comes to progressive decoupled websites, frontend stack is still built with Drupal. But some parts are implemented with a JS framework. You can have data provided by APIs or injected from Drupal too. The advantage is that you can benefit from Drupal components and don’t need to re-implement everything. A downside of it are conflicts with CSS styling and build systems handled on both sides. Therefore you need to have a clear understanding of what does what.</p>
<p>To be able to run such projects successfully, it is important to train every developer in new technologies: JS has evolved and parts of the logic can be built with it. We can say that backenders can do frontend now. In terms of hiring it means, you can hire full stack developers but also JS engineers. Attracting more developers as they love working with JS frameworks such as React on a global level.</p>
<p>Projects are investments which continue over time and expect failures at the beginning. These kinds of projects are more complex than regular Drupal ones, they can fail or go over budget. Learn from your mistakes and share them with your team in retrospectives. It is also very important to celebrate successes!<br />
Clients request decoupled projects to have a faster and cooler experience for users. They need to understand that this is an investment that will pay off in the future.</p>
<p>Finally, fully decoupled Drupal is a trend for big projects and other CMSs are already using decoupled out of the box. Drupal needs to focus on a better editor experience and a better API. There might also be projects that require simple backend edition instead of Drupal.</p>
<h2>Hackers automate but the Drupal Community still downloads updates on drupal.org or: Why we need to talk about Auto Updates</h2>
<p>By <a href="https://twitter.com/noljoh">Joe Noll</a> and <a href="https://twitter.com/hernanibf">Hernani Borges de Freitas</a><br />
Track: Drupal + Technology<br />
<a href="https://youtu.be/elgVgXxPRTg">Recording</a> and <a href="https://www.slideshare.net/hernanibf/drupal-europe-2018-hackers-automate-but-the-drupal-community-still-downloads-modules-from-drupalorg">slides</a> </p>
<p>In 2017, 59% of Drupal users were still downloading modules from drupal.org. In other words, more than half of the users didn’t have any automatisation processes to install modules. Knowing that <a href="https://www.drupal.org/security">critical security updates were released in the past months</a> and it is only a matter of hours until a website gets potentially hacked, it comes crucial to have a process to automate these updates.<br />
The update can be quite complex and may take time: installing the update, reviewing the changes, deploying on a test environment, testing either automatically or manually and deploying on production. However this process can be simplify with automation in place.</p>
<p>There is a core initiative to support small-to-medium sites owners that usually are not taking care of security updates. The idea is a process to download the code and update sources in the Drupal directory.<br />
For more complex websites, automating the composer workflow with a CI pipeline is recommended. Everytime a security update is released, the developer pushes it manually in the pipeline. The CI system builds an installation containing the security fix within a new branch. This will be deployed automatically to a non-productive environment where tests can be done and build approved. Changes can be merged and deployed on production afterwards.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/8774e8/update-strategy-drupal-europe.jpg" alt="A schema showing the update strategy through all steps from a CI pipeline"><figcaption>Update strategy slide by Joe Noll and Hernani Borges de Freitas</figcaption></figure>
<p>To go further, the <a href="https://www.drupal.org/project/update_runner">update_runner</a> module focuses on automatizing the first part by detecting an update and firing up a push for an update job.</p>
<h2>Conclusion</h2>
<figure><a href="https://www.flickr.com/photos/amazeelabs/42861616520/in/photostream/"><img src="https://liip.rokka.io/www_inarticle/33a4fb/swiss-drupal-community.jpg" alt="Swiss Drupal community members cheering at a restaurant"></a><figcaption>Meeting the Swiss Drupal community, photo by Josef Dabernig, license CC BY-NC-SA 2.0</figcaption></figure>
<p>We are back with fresh ideas, things we are curious to try and learnings from great talks! We joined social events in the evenings too. Therefore we exchanged with other drupalists, in particular with the Swiss Drupal community! This week went so fast. Thank you <a href="https://www.drupaleurope.org/team">Drupal Europe organizers</a> for making this event possible!</p>
<p><em>Header image credits: <a href="https://www.flickr.com/photos/amazeelabs/43723875575">Official Group Photo Drupal Europe Darmstadt 2018</a>  by Josef Dabernig, license CC BY-NC-SA 2.0.</em></p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/fee029/drupal-europe-photo-group.jpg" length="1109915" type="image/jpeg" />
          </item>
        <item>
      <title>Drupal 8 &#8211; Multilanguage Improvements</title>
      <link>https://www.liip.ch/de/blog/drupal-8-multilanguage-improvements</link>
      <guid>https://www.liip.ch/de/blog/drupal-8-multilanguage-improvements</guid>
      <pubDate>Wed, 12 Apr 2017 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>As a Swiss-based Drupal 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 Drupal to make this an easy task (usually). We mainly used node translations in Drupal 7 for maximum flexibility. We used to separate languages from each other using the various i18n modules, language specific menus, blocks, URL-patterns, terms and so on.</p>
<p>With Drupal 8, things changed.</p>
<p>I struggled a little doing multilingual sites in Drupal 8 the same way I was used to in Drupal 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.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/c98a72751151c90efcbb09843a1e11b8bf6b536d/maxresdefault-1024x575.jpg" alt="Drupal 8 multilanguage"></figure>
<p><em>Image: drupal8multilingual.org</em></p>
<h2>Drupal 8 <del>issues</del> multilanguage challenges</h2>
<h3>Challenge 1: Node add / edit menu handling</h3>
<p>The main challenge I had using Drupal 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 Drupal 8.</p>
<h3>Challenge 2: Untranslated Nodes show up in Menu</h3>
<p>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. <a href="http://hojtsy.hu/blog/2015-nov-18/drupal-8-multilingual-tidbits-20-combination-use-cases-content-and-menus">here</a> and <a href="https://www.drupal.org/node/2466553">here</a>). 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.</p>
<h3>Challenge 3: Language Switcher shows all languages – always.</h3>
<p>Somewhat confusing is the Language Switcher. In Drupal 7, a language link was not available or strikethrough if there was no translation available. In Drupal 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 drupalish 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</p>
<p>An example to illustrate the above-written challenges.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/5329af720a3db73e995bc721779f81764ecae8a5/welcome-to-drupal-8-3-0-drupal-8-3-01-1.jpg" alt="multilanguage issues with Drupal 8"></figure>
<p><em>English Front-Page with mixed navigation items.</em></p>
<p>The screen above shows an installation with 2 languages (English and German). The <strong>English Page</strong> is a basic page which has a translation. English is selected. If you choose <strong>Deutsch</strong> on the language switcher, the <strong>English Page</strong> becomes <strong>Deutsche Seite</strong> (see image below) and shows the German content. So far so good. But the second menu item you see with the title <strong>Über uns (nur Deutsch)</strong> 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.</p>
<p><em>German only Page – Language Switcher visible. </em></p>
<p>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.</p>
<h2>How to <del>fix</del> improve this?</h2>
<p>Luckily, the Drupal 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.</p>
<p>To sum up again: <em>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.</em></p>
<p>Since there is no patch and still some ongoing discussions on <a href="https://www.drupal.org">drupal.org</a> you need to implement it on your own. Implement the following two modules.</p>
<h3>Hide untranslated menu items</h3>
<p>Code from <a href="https://www.drupal.org/node/2466553#comment-11991690">drupal.org/node/2466553#comment-11991690</a>. Credits go to michaelkoehne.</p>
<pre><code class="language-php">&lt;?php

use Drupal\Core\Menu\MenuLinkInterface;
use Drupal\menu_link_content\Plugin\Menu\MenuLinkContent;
use Drupal\Core\Language\LanguageInterface;

/**
 * Implements hook_preprocess_menu().
 */
function MYMODULE_preprocess_menu(&amp;$variables) {
  if ($variables['menu_name'] == 'main') {
    $language = Drupal::languageManager()
      -&gt;getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
      -&gt;getId();
    foreach ($variables['items'] as $key =&gt; $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-&gt;getTranslationLanguages();

    // Remove links which are not translated to the current language.
    if (!array_key_exists($language, $languages)) {
      return FALSE;
    }
    else {
      if (count($item['below']) &gt; 0) {
        foreach ($item['below'] as $subkey =&gt; $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-&gt;getPluginId(), 2);
    $uuid = $menu_link[1];
    $entity = \Drupal::service('entity.repository')
      -&gt;loadEntityByUuid('menu_link_content', $uuid);
  }
  return $entity;
}</code></pre>
<h3>Hide untranslated languages in language switcher</h3>
<p>Code from <a href="https://www.drupal.org/node/2791231#comment-12004615">drupal.org/node/2791231#comment-12004615</a> (slightly adapted. Links get a class, not removed by default). Credits to Leon Kessler.</p>
<pre><code class="language-php">&lt;?php

/**
 * @file
 * Hide language switcher links for untranslated languages on an entity.
 */
use Drupal\Core\Entity\ContentEntityInterface;

/**
 * Implements hook_language_switch_links_alter().
 */
function MYOTHERMODULE_language_switch_links_alter(array &amp;$links, $type, $path) {
  if ($entity = MYOTHERMODULE_get_page_entity()) {
    $new_links = array();
    foreach ($links as $lang_code =&gt; $link) {
      try {
        if ($entity-&gt;getTranslation($lang_code)-&gt;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) &lt; 2) {
      $links = array();
    }
  }
}

/**
 * Retrieve the current page entity.
 *
 * @return Drupal\Core\Entity\ContentEntityInterface
 *   The retrieved entity, or FALSE if none found.
 */
function MYOTHERMODULE_get_page_entity() {
  $params = \Drupal::routeMatch()-&gt;getParameters()-&gt;all();
  $entity = reset($params);
  if ($entity instanceof ContentEntityInterface) {
    return $entity;
  }
  return FALSE;
}</code></pre>
<p>Please note: The code above is from Drupal.org and therefore thanks to the original authors linked above.</p>
<p>Enable those two modules and you're all set!</p>
<p>I did not encounter any issues yet using those two modules. If ever something changes in the way Drupal handles those cases, you just need to switch off the modules and everything should be back to normal. So nothing to lose right?</p>
<p>There are other attempts to this by altering the menu block. One of them is <a href="https://www.drupal.org/project/menu_block_current_language">Menu Block Current Language</a> 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).</p>
<p>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.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/f9211b40340b5371365ffb6e71bec9904823864b/maxresdefault.jpg" length="69997" type="image/jpeg" />
          </item>
        <item>
      <title>Advanced Drupal 8 Configuration Management (CMI) Workflows</title>
      <link>https://www.liip.ch/de/blog/advanced-drupal-8-cmi-workflows</link>
      <guid>https://www.liip.ch/de/blog/advanced-drupal-8-cmi-workflows</guid>
      <pubDate>Fri, 07 Apr 2017 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>After implementing some larger enterprise Drupal 8 websites, I would like to share some insights, how to solve common issues in the deployment workflow with Drupal 8 CMI.</p>
<h2>Introduction to Drupal CMI</h2>
<p>First of all, you need to understand, how the configuration management in Drupal 8 works. CMI allows you to export all configurations and its dependencies from the database into yml text files. To make sure, you never end up in an inconsistent state, CMI always exports everything. By default, you cannot exclude certain configurations.</p>
<h3>Example:</h3>
<p>If you change some configuration on the live database, these configurations will be reverted in the next deployment when you use</p>
<pre><code>drush config-import</code></pre>
<p>This is helpful and will make sure, you have the same configuration on all your systems.</p>
<h2>How can I have different configurations on local / stage / live environments?</h2>
<p>Sometimes, you want to have different configurations on your environments. For example, we have installed a “devel” module only on our local environment but we want to have it disabled on the live environment.</p>
<p>This can be achieved by using <a href="https://www.drupal.org/project/config_split">the configuration split module</a>.</p>
<h3>What does Configuration Split?</h3>
<p>This module slightly modifies the CMI by implementing a <a href="https://www.drupal.org/project/config_filter">Config Filter</a>. Importing and exporting works the same way as before, except some configuration is read from and written to different directories. Importing configuration still removes configuration not present in the files. Thus, the robustness and predictability of the configuration management remains. And the best thing is: You still can use the same drush commands if you have at <strong>least Drush 8.1.10 installed</strong> .</p>
<h3>Configuration Split Example / Installation Guide</h3>
<p>Install config_split using composer. You need need at least “ <a href="https://www.drupal.org/project/config_split/releases/8.x-1.0-beta4">8.x-1.0-beta4</a>” and <strong> &gt;</strong> drush 8.1.10 for this guide.</p>
<pre><code>composer require drupal/config_split "^1.0"</code></pre>
<p>Enable config_split and navigate to “admin/config/development/configuration/config-split”</p>
<pre><code>drush en config_split -y</code></pre>
<p>Optional: Installing the <a href="https://www.drupal.org/project/chosen">chosen module</a> will make the selection of blacklists / greylists way more easier. You can enable chosen only on admin pages.</p>
<pre><code>composer require drupal/chosen "^1.0"</code></pre>
<p>I recommend you to create an “environments” subfolder in your config folder. Inside this folder you will have a separate directory for every environment:</p>
<figure><img src="https://liip.rokka.io/www_inarticle/9c0892d2d0f29225ff661d1fd126efe86eb98821/folder.jpg" alt="Drupal 8 Configuration Management Folders"></figure>
<p>Now you can configure your environments:</p>
<figure><img src="https://liip.rokka.io/www_inarticle/b227da8edbc1f2a2285e57135989adc7f2ade4c0/sonfig-split-overview.jpg" alt="Config Split in Drupal 8 Configuration Management"></figure>
<p>The most important thing is, that you <strong>set every environment to “Inactive”.</strong> We will later activate them according to the environment via settings.php</p>
<figure><img src="https://liip.rokka.io/www_inarticle/ba0deaae35cf9943916748361f205d59ab66bf53/inactive.jpg" alt="Config Split settings with the Drupal 8 Configuration Management"></figure>
<p>Here is my example where I enable the devel module on local:</p>
<figure><img src="https://liip.rokka.io/www_inarticle/ca408abae031f7fb47eeae005387914febb71661/devel.jpg" alt="Dev Environment Example"></figure>
<h4>Activate the environments via settings.php</h4>
<p>This is the most important part of the whole setup up. Normally, we never commit the settings.php into git. But we have a [environment]-settings.php in git for every environment:</p>
<pre><code>settings.php (not in git)

variables-dev.php (in git and included in the settings.php of dev)
variables-live.php (in git and included in the settings.php of live)
settings.local.php (in git and included locally)</code></pre>
<p>You need to add the following line to the variables-[environment].php. Please change the <strong>variable name</strong> according to your environment <strong> machine name</strong> :</p>
<pre><code>// This enables the config_split module
$config['config_split.config_split.dev']['status'] = TRUE;</code></pre>
<p>If you have done everything correctly and cleared the cache you will see  <strong>“active (overriden)”</strong> in the config_split overview next to the current environment.</p>
<p>Now you can continue using</p>
<pre><code>drush config-import -y
drush config-export -y</code></pre>
<p>and config_split will do the magic.</p>
<h2>How can I exclude certain Config Files and prevent them to be overridden / deleted on my live environment?</h2>
<p>The most prominent candidates for this workflow are <strong>webforms</strong> and <strong>contact forms</strong> . In Drupal 7, webforms are nodes and you were able to give your CMS administrator the opportunity to create their own forms.</p>
<p>In Drupal 8 webforms are <strong>config entities</strong> , which means that they will be deleted while deploying if the yml files are not in git.</p>
<p>After testing a lot of different modules / drush scripts, I finally came up with an easy to use workflow to solve this issue and give CMS administrators the possibility to create webforms without git knowledge:</p>
<h3>Set up an “Excluded” environment</h3>
<p>First of all, we need an “excluded” environment. I created a subfolder in my config-folder and added a .htaccess file to protect the content. You can copy the .htaccess from an existing environment, if you are lazy. Don't forget to deploy this folder to your live system before you do the next steps.</p>
<figure><img src="https://liip.rokka.io/www_inarticle/45a33184b847dff36284b9214265f1a2f98fe018/excluded.jpg" alt="Folders"></figure>
<figure><img src="https://liip.rokka.io/www_inarticle/cf587f0a75dc0022b0ea79ebe635f6622e3de82f/excluded-list.jpg" alt="Excluded"></figure>
<p>Now you can exclude some config files to be excluded / grey-listed on your live environment:</p>
<pre><code>webform.webform.*
contact.form.*</code></pre>
<figure><img src="https://liip.rokka.io/www_inarticle/1b56c2fe044d55da0205588b7a3654a822f2e373/greylisted.jpg" alt="Greylist Webform in Config Split"></figure>
<p>Set the excluded environment to <strong> “Inactive”</strong> . We will later enable it on the live / dev environment via settings.php.</p>
<h3>Enable “excluded” environment and adapt deployment workflow</h3>
<p>We enable the “excluded” environment on the live system via variables-live.php (see above):</p>
<pre><code>// This will allow module config per environment and exclude webforms from being overridden
$config['config_split.config_split.excluded']['status'] = TRUE;</code></pre>
<p>In your deployment workflow / script you need to add the following line before you do a drush config-import:</p>
<pre><code>#execute some drush commands
echo "-----------------------------------------------------------"
echo "Exporting excluded config"
drush @live config-split-export -y excluded

echo "-----------------------------------------------------------"
echo "Importing configuration"
drush @live config-import -y</code></pre>
<p>The drush command “ <strong>drush @live config-split-export -y excluded</strong> ” will export all webforms and contact forms created by your CMS administrators into the folder “excluded”. The “drush config-import” command will therefore not delete them and your administrators can happily create their custom forms.</p>
<h3>Benefit of disable “excluded” on local environment</h3>
<p>We usually disable the “excluded” environment on our local environment. This allows us to create complex webforms on our local machine for our clients and deploy them as usual. In the end you can have a mix of customer created webforms and your own webforms which is quite helpful.</p>
<h2>Final note</h2>
<p>The CMI is a great tool and I would like to thank the maintainers of the <a href="https://www.drupal.org/project/config_split">config_split module</a> for their great extension. This is a huge step forward making Drupal 8 a real Enterprise CMS Tool.</p>
<p>If you have any questions, don't hesitate to post a comment.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/283d9942e75d52c1ca4ceb29373d3cd6cc0ba2eb/drupal-blogposts.jpg" length="57057" type="image/png" />
          </item>
        <item>
      <title>The DrupalDay 2017 in Rome</title>
      <link>https://www.liip.ch/de/blog/drupalday-2017-rome</link>
      <guid>https://www.liip.ch/de/blog/drupalday-2017-rome</guid>
      <pubDate>Thu, 09 Mar 2017 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>This year was the 6th edition of the <a href="http://roma2017.drupalday.it/">DrupalDay Italy</a>, the main event to attend for Italian-speaking drupalists.</p>
<p>Previous editions took place in other main Italian cities like Milan, Bologna and Naples.</p>
<p>This time Rome had the privilege to host such a challenging event, ideally located in the Sapienza University Campus.</p>
<p>The non-profit event, was <strong>free of charge</strong> .</p>
<h2>A 2-days event</h2>
<p>Like most development-related events these days, the event spanned over 2 days, March, 3rd and 4th.</p>
<p>The first day was the conference day, with more than 20 talks split in 3 different “tracks” or, better, rooms.</p>
<p>In fact, there was no clear separation of scopes and the same room hosted Biz and Tech talks, probably (but this is just my guess) in an attempt to mix different interests and invite people to get out of their confort zone.</p>
<p>The second day was mainly aimed at developers of all levels with the “Drupal School” track providing courses ranging from site-building to theming.</p>
<p>The “Drupal Hackaton” track was dedicated to developers willing to contribute (in several ways) to the Drupal Core, community modules or documentation.</p>
<h2>The best and the worst</h2>
<p>As expected, I've found the quality of the talks a bit fluctuating.</p>
<p>Among the most interesting ones, I would definitely mention Luca Lusso's “ <strong>Devel – D8 release party</strong> ” and Adriano Cori's talks about <a href="https://www.drupal.org/project/http_client_manager">HTTP Client Manager</a> module.</p>
<p>I was also positively surprised (and enjoyed a lot) the presentation about “ <strong>Venice and Drupal</strong> ” by Paolo Cometti and Francesco Trabacchin where I discovered that the City of Venice has an in-house web development agency using Drupal for the main public websites and services.</p>
<p>On the other hand, I didn't like Edoardo Garcia's Keynote “Saving the world one Open Source project at a time”.</p>
<p>It seemed to me mostly an excuse to advertise his candidature as <a href="https://assoc.drupal.org/election/18/candidates">Director of the Drupal Association</a>,</p>
<p>I had the privilege to talk about “ <a href="https://speakerdeck.com/ralf57/decoupled-frontend-with-drupal-8-e-openui-5">Decoupled frontend with Drupal 8 and OpenUI 5</a>“.</p>
<p>The audience, initially surprised by the unusual Drupal-SAP (the company behind OpenUI) association, showed a real interest and curiosity.</p>
<p>After the presentation, I had chance to go into the details and discuss my ideas with a few other people.</p>
<p>I also received some critics, which I really appreciated and will definitely make me improve as a presenter.</p>
<h2>Next one?</h2>
<p>In the end, I really enjoyed the conference, both the contents and the ambiance, and will definitely join next year.</p>]]></description>
          </item>
        <item>
      <title>How to get involved in Drupal projects</title>
      <link>https://www.liip.ch/de/blog/get-involved-drupal-projects</link>
      <guid>https://www.liip.ch/de/blog/get-involved-drupal-projects</guid>
      <pubDate>Tue, 10 Jan 2017 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Drupal is an open source project and really depends on its community to move forward. It is all about getting to know the <abbr title="Content Management System">CMS</abbr>, spreading the knowledge and contribute to projects.</p>
<p>I will give you some ways to get involved, even if you are not a developer there is a task for you!</p>
<figure><img src="https://liip.rokka.io/www_inarticle/1b085808edffcc4d2aa4a0e4523ed23ae97492ab/drupalcon-dublin-2016-mentors-1024x371.jpg" alt="A group of Drupal mentors at DrupalCon 2016 in Dublin"></figure>
<p>Drupal Mentors – DrupalCon Dublin 2016 by <a href="https://www.flickr.com/photos/comprock/">Michael Cannon</a> is licenced under <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC BY-SA 2.0</a></p>
<h2>Participating in user support</h2>
<p>Sharing your knowledge with others is very important to the community: it is a nice thing to do and you might also learn some things by doing so. Whatever your skill level, you can give back to the community with online support. There are many places where you can give support starting with the <a href="https://www.drupal.org/forum/18">Support Forums</a>. You can also go to <a href="http://drupal.stackexchange.com">Drupal Answers</a> which is more active than the forums or subscribe to the Support Mailing list. If you prefer real-time chat, you can also join #drupal-support channel on IRC or the <a href="https://www.drupal.org/node/2798167">Slack channels</a>.</p>
<h2>Helping out on documentation</h2>
<p>Community members can write, review and improve different sorts of documentation for the project: <a href="http://drupal.org/documentation">community documentation</a> on drupal.org, <a href="http://api.drupal.org/">programming API reference</a>, help pages inside the core software, documentation embedded in contributed modules and themes etc.</p>
<p>Contributing is a good way to learn more about Drupal and share your knowledge with others. Beginners are particularly encouraged to participate as they are more likely to know where documentation is lacking.</p>
<p>If you are interested, check out the <a href="https://www.drupal.org/contributor-tasks#anyone">new contributor tasks for anyone</a> and <a href="https://www.drupal.org/contributor-tasks#writers">writers</a>.</p>
<h2>Translating Drupal interface in your own language</h2>
<p>The default language for the administration interface is English but there are about <a href="https://localize.drupal.org/translate/drupal8">100 available languages for translations</a>. There is always a need for translations as many of these translation sets are incomplete or can be improved for core and contributed modules.</p>
<p>All translations are now managed by the translation server. If you are willing to help, all you have to do is logging into drupal.org and join a language team. There is even <a href="https://drupalize.me/videos/translation-drupal">a video to learn how the translation system works</a> and a <a href="https://www.drupal.org/node/302194">documentation</a>.</p>
<p>You can also help to translate documentation into your language. Most language-specific communities have their own documentation so you should get in touch with them directly. To learn more, see <a href="https://www.drupal.org/node/17229">the dedicated page</a>.</p>
<h2>Improving design and usability</h2>
<p>The idea is to improve the usability especially in Drupal 8 regarding the administration interface. The focus is mainly on content creation and site building. The community has done many research to understand the problems that users run into and how the new improvements performs. The purpose is also to educate developers and engage designers in order to grow the UX-team. You can visit the Drupal 8 <a href="https://www.drupal.org/community-initiatives/drupal-core/usability">UX page</a> for more details and join the <a href="https://groups.drupal.org/usability">usability group</a>.</p>
<h2>Writing a blog post about Drupal</h2>
<p>Writing a blog post about Drupal is a good way to share your knowledge and expertise. There are many subjects to explore, technical or not: talking about <a href="https://blog.liip.ch/archive/2016/11/30/fairly-complex-drupal-commerce-site-freitag-ch.html">a former project you developed</a> or writing a <a href="https://blog.liip.ch/archive/2016/06/20/lets-debug-drupal-8.html">tutorial</a>, telling about <a href="https://blog.liip.ch/archive/2016/07/07/quick-look-current-state-drupal-8-ecosystem.html">the state of a version</a> or sharing about <a href="https://blog.liip.ch/archive/2016/06/27/personal-report-about-drupal-developer-days-milano-2016.html">an event you attended</a>… And if you are lucky enough your post can be published on the <a href="http://www.theweeklydrop.com">Weekly Drop</a>, the official Drupal newsletter!</p>
<p>Don't forget to reference your blog post on <a href="https://www.drupal.org/drupalorg/docs/content/planet-drupal">Planet Drupal</a>, this platform is an aggregated list of feeds from around the web which shares relevant Drupal-related knowledge and information.</p>
<p>You can also find <a href="https://blog.liip.ch/archive/category/products/drupal">our Drupal related blog posts</a> on the Liip blog.</p>
<h2>Testing core and modules</h2>
<p>Testing Drupal projects is necessary to make the platform stable and there are many things to test! If you have a technical background, you can help <a href="https://www.drupal.org/patch/review">to review patches</a> or <a href="https://www.drupal.org/docs/7/testing">to write unit tests</a>.</p>
<p>For non-technical people, you can provide some feedback about usability of the administration interface that will help to improve the user experience. Follow the <a href="https://www.drupal.org/node/1237450">process</a> to give a proper feedback.</p>
<h2>Contributing to development</h2>
<p>There are many ways to contribute code in core and “contrib” projects such as modules or themes.</p>
<p>You can first help to improve existing projects by submitted patches. This would be the natural thing to do when you work with a module and you notice a bug or a missing feature: search in the corresponding issue queue if the problem have been noticed before. If not, post a message explaining the issue and add a snippet of code if you found a potential fix. Then you can <a href="https://www.drupal.org/node/707484">create a patch and submit it</a> into the issue queue.</p>
<p>You can also contribute to new projects by creating your very own module or theme or create a sandbox for more experimental projects.</p>
<h2>Attending events</h2>
<p>The Drupal association organizes many events all around the world to promote the <abbr title="Content Management System">CMS</abbr> and gather the community.</p>
<p>One of the biggest events are the Drupalcons. A Drupalcon gathers thousands of people and lasts about one week including 3 full days of conferences. These conferences cover many topics: site building, user experience, security, content authoring etc. You can also join sprints to contribute to Drupal projects and social events to meet the members of the community. Check out our report about <a href="https://blog.liip.ch/archive/2015/10/14/drupalcon-barcelona-2015.html">DrupalCon Barcelona 2015</a>!</p>
<p>“Drupal Dev Days” conferences occur once a year and gather developers to discuss and present topics technically relevant to the community. You can join sprints, intensive coding sessions and technical conferences.</p>
<p>You can also join DrupalCamps to meet your local community. These events last one or two days and focus on sharing knowledge amongst the community. You can attend conferences and sprints.</p>
<p>There are also many Drupal meetups which are free events happening in many cities in the world. Presentations and discussions finish around nice drinks and appetizers.</p>
<h2>Sponsoring events</h2>
<p>The community holds conventions and meetups in many countries and being a sponsor will not only help Drupal development but it will also enable you to be noticeable within the community. There are different levels of sponsorings that will offer from mentions on social media to advertising online and at the exhibition space of the event. All you have to do is getting in touch with the event organizers. By the way, Liip will sponsor the <a href="https://drupalmountaincamp.ch">Drupal Mountain Camp</a> in Davos this year!</p>
<h2>Offering a donation</h2>
<p>You can <a href="https://assoc.drupal.org/donate">give donations to the Drupal association through the website</a> in order to support drupal.org infrastructure and maintenance, worldwide events such as Drupalcons. The donations are either in Euros or Dollars.</p>
<p>You can also become a member of the <a href="https://assoc.drupal.org/home">Drupal Association</a> for the same purpose, as an individual member or an organization member. The minimal fees are 15 Euros. Find more information about <a href="https://assoc.drupal.org/membership">membership on drupal.org</a>.</p>
<h2>Conclusion</h2>
<p>Drupal projects are constantly improving thanks to passionate volunteers who work on many subjects: development, documentation, marketing, events organization, supports… There is for sure a task that will suit you and it only takes small time commitment to make changes.</p>
<p>So join the great Drupal community and <a href="https://www.drupal.org/getting-involved-guide">start getting involved</a>!</p>]]></description>
          </item>
        <item>
      <title>Drupal 8 Migrate Multilingual Content using Migrate API</title>
      <link>https://www.liip.ch/de/blog/drupal-8-multilingual-content</link>
      <guid>https://www.liip.ch/de/blog/drupal-8-multilingual-content</guid>
      <pubDate>Thu, 05 Jan 2017 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>As a follow-up to my <a href="https://blog.liip.ch/archive/2016/05/04/using-the-new-drupal-8-migration-api-module.html">previous blog post about the usage of Migrate API in Drupal 8</a>, I would like to give an example, how to import multilingual content and translations in Drupal 8.</p>
<h2>Prepare and enable translation for your content type</h2>
<p>Before you can start, you need to install the “Language” and “Content Translation” Module. Then head over to “admin/config/regional/content-language” and enable Entity Translation for the node type or the taxonomy you want to be able to translate.</p>
<p>As a starting point for setting up the migrate module, I recommend you my blog post mentioned above. To import data from a CSV file, you also need to install the <a href="https://www.drupal.org/project/migrate_source_csv">migrate_source_csv</a> module.</p>
<h2>Prerequisites for migrating multilingual entities</h2>
<p>Before you start, please check the requirements. You need at least Drupal 8.2 to import multilingual content. We need the destination option “translations”, which was added in a patch in Drupal 8.2. See the corresponding <a href="https://www.drupal.org/node/2225775">drupal.org issue</a> here.</p>
<h2>Example: Import multilingual taxonomy terms</h2>
<p>Let's do a simple example with taxonomy terms. First, create a vocabulary called “Event Types” (machine name: event_type).</p>
<p>Here is a simplified dataset:</p>
<table><thead><tr><th>Id</th>
<th>Name</th>
<th>Name_en</th>
</tr></thead><tbody><tr><td>1</td>
<td>Kurs</td>
<td>Course</td>
</tr><tr><td>2</td>
<td>Turnier</td>
<td>Tournament</td>
</tr></tbody></table>
<p>You may save this a csv file.</p>
<pre><code>Id;Name;Name_en
1;Kurs;Course
2;Turnier;Tournament</code></pre>
<h3>The recipe to import multilingual content</h3>
<p>As you can see in the example data,  it contains the base language (“German”) and also the translations (“English”) in the same file.</p>
<p><strong>But here comes a word of warning:</strong> </p>
<p>Don't try to import the term and its translation in one migration run. I am aware, that there are some workarounds with post import events, but these are hacks and you will run into troubles later.</p>
<p>The correct way of importing multilingual content, is to</p>
<ol>
<li>create a migration for the base language and import the terms / nodes. This will create the entities and its fields.</li>
<li>Then, with an additional dependent migration for each translated language, you can then add the translations for the fields you want.</li>
</ol>
<p>In short: You need a base migration and a migration for every language. Let's try this out.</p>
<h3>Taxonomy term base language config file</h3>
<p>In my example, the base language is “German”. Therefore, we first create a migration configuration file for the base language:</p>
<p>This is a basic example in migrating a taxonomy term in my base language ‘de'.</p>
<p>Put the file into <code>&lt;yourmodule&gt;/config/install/migrate.migration.event_type.yml</code> and import the configuration using the <a href="https://blog.liip.ch/archive/2016/05/04/using-the-new-drupal-8-migration-api-module.html">drush commands explained in my previous blog post about Migration API</a>.</p>
<pre><code class="language-yaml">id: event_type
label: Event Types
source:
  plugin: csv
  # Full path to the file. Is overriden in my plugin
  path: public://csv/data.csv
  # The number of rows at the beginning which are not data.
  header_row_count: 1
  # These are the field names from the source file representing the key
  # uniquely identifying each node - they will be stored in the migration
  # map table as columns sourceid1, sourceid2, and sourceid3.
  keys:
    - Id
ids:
  id:
    type: string
destination:
  plugin: entity:taxonomy_term
process:
  vid:
   plugin: default_value
   default_value: event_type
  name:
    source: Name
    language: 'de'
  langcode:
    plugin: default_value
    default_value: 'de'

#Absolutely necessary if you don't want an error
migration_dependencies: {}</code></pre>
<h3>Taxonomy term translation migration configuration file:</h3>
<p>This is the example file for the English translation of the name field of the term.</p>
<p>Put the file into <code>&lt;yourmodule&gt;/config/install/migrate.migration.event_type_en.yml</code> and import the configuration using the <a href="https://blog.liip.ch/archive/2016/05/04/using-the-new-drupal-8-migration-api-module.html">drush commands explained in my previous blog post about Migration API</a>.</p>
<pre><code class="language-yaml">id: event_type_en
label: Event Types english
source:
  plugin: csv
  # Full path to the file. Is overriden in my plugin
  path: public://csv/data.csv
  # The number of rows at the beginning which are not data.
  header_row_count: 1
  keys:
    - Id
ids:
  id:
    type: string
destination:
  plugin: entity:taxonomy_term
  translations: true
process:
  vid:
    plugin: default_value
    default_value: event_type
  tid:
    plugin: migration
    source: id
    migration: event_type
  name:
    source: Name_en
    language: 'en'
  langcode:
     plugin: default_value
     default_value: 'en'

#Absolutely necessary if you don't want an error
migration_dependencies:
  required:
    - event_type</code></pre>
<h2>Explanation and sum up of the learnings</h2>
<p>The key in the migrate configuration to import multilingual content are the following lines:</p>
<pre><code class="language-yaml">destination:
  plugin: entity:taxonomy_term
  translations: true</code></pre>
<p>These configuration lines instruct the migrate module, that a translation should be created.</p>
<pre><code class="language-yaml">tid:
  plugin: migration
  source: id
  migration: event_type</code></pre>
<p>This is the real secret. Using the <a href="https://www.drupal.org/docs/8/api/migrate-api/migrate-process/process-plugin-migration">process plugin migration</a>,  we maintain the relationship between the node and its translation.The wiring via the tid field make sure, that Migrate API will not create a new term with a new term id. Instead, the existing term will be loaded and the translation of the migrated field will be added. And thats exactly what we need!</p>
<p>Now go ahead and try to create a working example based on my explanation. Happy Drupal migrations!</p>]]></description>
          </item>
        <item>
      <title>A fairly complex Drupal Commerce site: freitag.ch</title>
      <link>https://www.liip.ch/de/blog/fairly-complex-drupal-commerce-site-freitag-ch</link>
      <guid>https://www.liip.ch/de/blog/fairly-complex-drupal-commerce-site-freitag-ch</guid>
      <pubDate>Wed, 30 Nov 2016 00:00:00 +0100</pubDate>
      <description><![CDATA[<figure><img src="https://liip.rokka.io/www_inarticle/089a5e215d9fc9464e23516b20dfe8f4a9afb44f/f-square-152x152.jpg" alt="Freitag logo"></figure>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/995cdfb591c8f36f1e94c9608fb683529aa708cd/f-square-512x512.jpg" length="812" type="image/png" />
          </item>
        <item>
      <title>Living style guide meets Drupal 8</title>
      <link>https://www.liip.ch/de/blog/living-style-guides-drupal-8</link>
      <guid>https://www.liip.ch/de/blog/living-style-guides-drupal-8</guid>
      <pubDate>Tue, 25 Oct 2016 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Times are constantly changing, and so is Liip. There is a particular term that caught our attention – living style guides. It might not be the latest or the coolest fad in web development, but tools that make Drupal 8 compatible with living style guides are fairly recent. That's why we decided to take a look at what's out there in order to introduce style guide driven development to our repertoire.</p>
<h2>What is a living style guide?</h2>
<p>A style guide in web development is a document that define the concept and look of your product. The exact contents of a style guide can however greatly vary depending on the company, project and development team. The general idea is that it should be a clear guideline for both the development team and the client.</p>
<p>What makes a style guide “living” is that the style guide is synchronous with the actual codebase. So basically you will have two “websites” that share the same CSS and the same elements. This ensures that the documentation stays up to date.</p>
<h2>What is style guide driven development?</h2>
<p>Style guide driven development is a workflow that decouples the frontend and the backend of the project. Basically you do all the UX and design work on the style guide, which contains every element and block that will be used for the final product, allowing you to ignore the current state of the backend development. A workflow that implements the style guide based approach might look something like this:</p>
<figure><img src="https://liip.rokka.io/www_inarticle/befdcd51b9e9059de4d5ae4707e090bf642859e1/bazinga-cycle-1024.jpg" alt="Style guide driven workflow utilizing living style guides"></figure>
<h3>I. Ideation</h3>
<p>First you gather the requirements and set the foundation for your project. Defining the basic feel of your product, including typograph, colors, and the elements that will make up your product.</p>
<h3>II. Atomization</h3>
<p>In a second step, you take all the elements that you have defined, and take them apart into smaller pieces. You repeat this step several times until you end up with a collection of patterns and small components. I would also like to invite you to read Marc Drummond's  <a href="https://www.marcdrummond.com/posts/2016/09/26/why-base-drupal-theme-system-around-components">blog post about component-based theme systems</a>.</p>
<h3>III. Implementation</h3>
<p>This is the part when you start implementing the style guide itself. This is also a great opportunity to test your design in different browsers, to play around with elements, and test their re-usability.</p>
<h3>IV. Integration</h3>
<p>In this phase all you have to do is to integrate the components and patterns from the style guide in our product. This sounds easy, but you might notice some issues that you didn't consider before. That's also one of the good points of this workflow – you can always go back to the first step to re-evaluate the situation, and either create new elements or even adjust existing ones.</p>
<h2>Implementing living style guides in Drupal 8</h2>
<p>After we have realized the advantages that living style guides could bring to our team, we decided <figure><img src="https://liip.rokka.io/www_inarticle/2f99fae58ff8d3c4a1e9a913bb5a2cd346b4698c/drupal-300x300.jpg" alt="Drupal logo Liip green"></figure>to first make an evaluation phase. Everyone from our team had the opportunity to present a possible solution, regardless of their role and experience. We did however agree on the following guidelines to make the evaluation smoother:</p>
<ul>
<li>The style guide has to be integrated into a Drupal 8 Theme.</li>
<li>The taskrunner has to be Gulp.js / Node.js.</li>
<li>As a CSS preprocessor we went with SASS.</li>
<li>Lastly we agreed on using the Zurb Foundation CSS Framework.</li>
</ul>
<p>Out of the several technologies that we evaluated, there were two that we considered mature enough for building our next project on either of them: kss-node and Pattern Lab.</p>
<h3>kss-node</h3>
<p>The first one is <a href="https://github.com/kss-node/kss-node">kss-node</a>, a kss based Drupal 8 solution by none other than <a href="https://www.drupal.org/u/johnalbin">John Albin</a>, creator of the Zen theme.  Albins kss-node, as the name already suggests, is based on Knyle Style Sheets, which generates style guides based on the comments and rules in your stylesheets. Setting it up is pretty straightforward, which might be a deciding factor based on the technical background of your team. You also have a lot of freedom in tweaking the generated style guides. This means you will have an easier time presenting the style guides to your customers. The only drawback I see going this way is that KSS gives you a more or less set way to structurize your stylesheets. Other than that, it's a handy tool that serves it's purpose.</p>
<h3>Pattern Lab</h3>
<p>The second is <a href="http://patternlab.io/">Pattern Lab</a>, a static site generator for PHP and Node. Pattern Lab places much more focus splitting up components. You basically have five different levels:</p>
<ul>
<li>Atoms, the smallest component that can exist. Just like in chemistry! Text areas, buttons and icons would fall into this category.</li>
<li>Molecules, several atoms that make up a single component when placed together.  A good example would be a search text field and its search button.</li>
<li>Organisms are compound elements too big to be molecules, but not big enough to be templates. For example a blog comment with all the details and a reply button.</li>
<li>Templates are the biggest building blocks that cover a section or even a whole page of the website. This would be a blog post with a title, breadcrumbs and a comment section.</li>
<li>Pages, templates filled with actual content.</li>
</ul>
<p>Getting Pattern Lab to work with Drupal 8 isn't an easy task. For this reason I recommend using the <a href="https://github.com/aleksip/shila-drupal-theme">Shila theme</a> by <a href="https://github.com/aleksip">Aleksi Peebles</a>. This theme comes with a starterkit which does a large chunk of the tedious work for you. It also comes with some nice extras like switching between breakpoints in the style guide itself. This is a handy feature if you plan running automated tests with Selenium. You will probably want to spice the theme up a bit if you decide to use it in a real project though.</p>
<h3>Final thoughts</h3>
<p>The mentioned solutions are very similar, yet somehow different. Pattern Lab takes more fine-tuning, and you will have to put in some effort to take advantage of all the features it offers. On the other hand, kss-node also offers you flexibility, but looks clean and professional even out of the box. Me as a developer lean towards Pattern Lab, but I have to agree that kss-node seems to be more attractive for people less versed in technical stuff, including clients.</p>
<p>In any case we look forward to give style guide driven development a real try. Do you have any experience with living style guides or style guide driven development? Share it below in the comment section!</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/befdcd51b9e9059de4d5ae4707e090bf642859e1/bazinga-cycle-1024.jpg" length="54064" type="image/png" />
          </item>
        <item>
      <title>Drupal SearchAPI and result grouping</title>
      <link>https://www.liip.ch/de/blog/drupal-searchapi-result-grouping</link>
      <guid>https://www.liip.ch/de/blog/drupal-searchapi-result-grouping</guid>
      <pubDate>Mon, 24 Oct 2016 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>In this blog post I will present how, in a recent e-Commerce project built on top of Drupal7 (the former version of the Drupal CMS), we make Drupal7, SearchAPI and Commerce play together to efficiently retrieve grouped results from Solr in SearchAPI, with no indexed data duplication.</p>
<p>We used the <a href="https://www.drupal.org/project/search_api">SearchAPI</a> and the <a href="https://www.drupal.org/project/facetapi">FacetAPI</a> modules to build a search index for products, so far so good: available products and product-variations can be searched and filtered also by using a set of pre-defined facets. In a subsequent request, a new need arose from our project owner: provide a list of products where the results should include, in addition to the product details, a picture of one of the available product variations, while keep the ability to apply facets on products for the listing. Furthermore, the product variation picture displayed in the list must also match the filter applied by the user: this with the aim of not confusing users, and to provide a better user experience.</p>
<p>An example use case here is simple: allow users to get the list of available products and be able to filter them by the color/size/etc field of the available product variations, while displaying a picture of the available variations, and not a sample picture.</p>
<p>For the sake of simplicity and consistency with <a href="https://www.drupal.org/project/commerce">Drupal's Commerce</a> module terminology, I will use the term “Product” to refer to any product-variation, while the term “Model” will be used to refer to a product.</p>
<h2>Solr Result Grouping</h2>
<p>We decided to use <a href="http://lucene.apache.org/solr/">Solr</a> (the well-known, fast and efficient search engine built on top of the Apache Lucene library) as the backend of the eCommerce platform: the reason lies not only in its full-text search features, but also in the possibility to build a fast retrieval system for the huge number of products we were expecting to be available online.</p>
<p>To solve the request about the display of product models, facets and available products, I intended to use the feature offered by Solr called <a href="https://cwiki.apache.org/confluence/display/solr/Result+Grouping">Result-Grouping</a> as it seemed to be suitable for our case: Solr is able to return just a subset of results by grouping them given an “single value” field (previously indexed, of course). The Facets can then be configured to be computed from: the grouped set of results, the ungrouped items or just from the first result of each group.</p>
<p>Such handy feature of Solr can be used in combination with the SearchAPI module by installing the <a href="https://www.drupal.org/project/search_api_grouping">SearchAPI Grouping</a> module. The module allows to return results grouped by a single-valued field, while keeping the building process of the facets on all the results matched by the query, this behavior is configurable.</p>
<p>That allowed us to:</p>
<ul>
<li>group the available products by the referenced model and return just one model;</li>
<li>compute the attribute's facets on the entire collection of available products;</li>
<li>reuse the data in the product index for multiple views based on different grouping settings.</li>
</ul>
<h2>Result Grouping in SearchAPI</h2>
<p>Due to some limitations of the SearchAPI module and its query building components, such plan was not doable with the current configuration as it would require us to create a copy of the product index just to apply the specific Result Grouping feature for each view.</p>
<p>The reason is that the features implemented by the SearchAPI Grouping are implemented on top of the “ <a href="https://www.drupal.org/node/1254452">Alterations and Processors</a>” functions of SearchAPI. Those are a set of specific functions that can be configured and invoked both at indexing-time and at querying-time by the SearchAPI module. In particular <em>Alterations</em> allows to programmatically alter the contents sent to the underlying index, while the <em>Processors</em> code is executed when a search query is built, executed and the results returned.</p>
<p>Those functions can be defined and configured only per-index.</p>
<p>As visible in the following picture, the SearchAPI Grouping module configuration could be done solely in the Index configuration, but not per-query.</p>
<figure><a href="https://www.liip.ch/content/4-blog/20161024-drupal-searchapi-result-grouping/SearchAPI_processor_settings.png"><img src="https://liip.rokka.io/www_inarticle/663d0523052de6eafe7f91da70a21268f5f6718a/searchapi-processor-settings-300x280.jpg" alt="SearchAPI: processor settings"></a></figure>
<p>Image 1: SearchAPI configuration for the Grouping Processor.</p>
<p>As the SearchAPI Grouping module is implemented as a SearchAPI Processor (as it needs to be able to alter the query sent to Solr and to handle the returned results), it would force us to create a new index for each different configuration of the result grouping.</p>
<p>Such limitation requires to introduce a lot of (useless) data duplication in the index, with a consequent decrease of performance when products are saved and later indexed in multiple indexes.</p>
<p>In particular, the duplication is more evident as the changes performed by the Processor are merely an alteration of:</p>
<ol>
<li>the query sent to Solr;</li>
<li>the handling of the raw data returned by Solr.</li>
</ol>
<p>This shows that there would be no need to index multiple times the same data.</p>
<p>Since the the possibility to define per-query processor sounded really promising and such feature could be used extensively in the same project, a new module has been implemented and published on Drupal.org: the <a href="https://www.drupal.org/project/search_api_extended_processors">SearchAPI Extended Processors</a> module. (thanks to SearchAPI's maintainer, <a href="https://www.drupal.org/u/drunken-monkey">DrunkenMonkey</a>, for the help and review :) ).</p>
<h2>The Drupal SearchAPI Extended Processor</h2>
<p>The new module allows to extend the standard SearchAPI behavior for Processors and lets admins configure the execution of SearchAPI Processors per query and not only per-index.</p>
<p>By using the new module, any index can now be used with multiple and different Processors configurations, no new indexes are needed, thus avoiding data duplication.</p>
<p>The new configuration is exposed, as visible in the following picture, while editing a SearchAPI view under “Advanced &gt; Query options”.</p>
<p>The SearchAPI processors can be altered and re-defined for the given view, a checkbox allows to completely override the current index setting rather than providing additional processors.</p>
<figure><a href="https://www.liip.ch/content/4-blog/20161024-drupal-searchapi-result-grouping/SearchAPI_view_extended_processor_settings.png"><img src="https://liip.rokka.io/www_inarticle/49035888583138fd0866e31eb73c51154ac10a51/searchapi-view-extended-processor-settings-300x213.jpg" alt="Drupal SearchAPI: view's extended processor settings"></a></figure>
<p>Image 2: View's “Query options” with the SearchAPI Extended Processors module.</p>
<p>Conclusion: the new SearchAPI Extended Processors module has now been used for a few months in a complex eCommerce project at Liip and allowed us to easily implement new search features without the need to create multiple and separated indexes.</p>
<p>We are able to index Products data in one single (and compact) Solr index, and use it with different grouping strategies to build both product listings, model listings and model-category navigation pages without duplicating any data.</p>
<p>Since all those listings leverages the Solr <a href="https://cwiki.apache.org/confluence/display/solr/Common+Query+Parameters#CommonQueryParameters-Thefq(FilterQuery">cwiki.apache.org/confluence/display/solr/Common+Query+Parameters#CommonQueryParameters-Thefq(FilterQuery</a>Parameter text: FilterQuery query parameter) to filter the correct set of products to be displayed, Solr can make use of its internal set of caches and specifically the <a href="https://cwiki.apache.org/confluence/display/solr/Query+Settings+in+SolrConfig#QuerySettingsinSolrConfig-filterCache">filterCache</a> to speed up subsequent searches and facets. This aspect, in addition to the usage of only one index, allows caches to be shared among multiple listings, and that would not be possible if separate indexes were used.</p>
<p>For further information, questions or curiosity drop me a line, I will be happy to help you configuring Drupal SearchAPI and Solr for your needs.</p>]]></description>
                  <enclosure url="http://liip.rokka.io/www_card_2/30eba90bb413ef702e64fbb0e6858c1e8106f877/searchapi-processor-settings.jpg" length="90531" type="image/png" />
          </item>
        <item>
      <title>Drupal Cross-Squad Knowledge Sharing</title>
      <link>https://www.liip.ch/de/blog/drupal-cross-squad-knowledge-sharing</link>
      <guid>https://www.liip.ch/de/blog/drupal-cross-squad-knowledge-sharing</guid>
      <pubDate>Fri, 14 Oct 2016 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>We do lots of Drupal projects @ Liip, mainly in the Zürich and Fribourg offices. Since Liip is organized in individual and independent squads, we do not have lots of touchpoints or projects which we do cross-office wise. But all the squads doing Drupal have one thing in common: A big interest in Drupal and the strong will to do projects successfully.</p>
<p>If I talk about a “squads doing Drupal”, then don't think of Developers only, but also of Project Owners, UXers, Business Developers, Designers, Analytics Specialists and so on. With such squads in Zürich and Fribourg, things are done differently. Different sitebuilding, different workflows, different opinions and finally also different projects. This is on the one hand very interesting but on the other hand… weird. Being in the same company, doing the same kind of work but not the same way while not using the same toolbox and processes.</p>
<h2>Inter-office knowledge transfer</h2>
<p>To give freedom to the different Drupal squads but also profit from the huge knowledge in both offices, we started to have quarterly Hackdays. During these Hackdays, we spend a whole day exchanging and discussing a wide variety of topics. Last Monday, October 10, we had another Drupal Hackday in our new office in Berne:</p>
<p>To have something to talk about (or not waste time), we usually gather possible topics beforehand and vote for them. As an example, this time the following topics were on our list:</p>
<ul>
<li>Product owners: <a href="https://journal.liip.ch/de/2016/06/wellen-modell/">The wave model</a> or how we do Jira in Fribourg</li>
<li>Front-End: Possibilities in Drupal 8, Scalable CSS for Drupal, Styleguide vs. Drupal, Motion design, Browsersync and gulp for Drupal</li>
<li>Site Building: To Display Suite or not?</li>
<li>Composer / Drupal Console / Drush / Git and CMI</li>
<li>Commerce: State of the thing …</li>
<li>BizDev: Streamline offering process</li>
<li>Development: Caching (BigPipe, Redis, Varnish etc.)</li>
<li><a href="https://blog.liip.ch/archive/2016/07/11/an-opensource-drupal-theme-for-the-swiss-confederation.html">Bundrupal</a>: Fixing current issues, working on content types, creating ckeditor styles etc.</li>
<li>Migrate in Drupal 8: Insights in Migrate 8 with JSON</li>
</ul>
<p>For sure we could not cover everything in one day. But the next Drupal Hackday is just around the corner. But for this time, the “Pain Points” were quickly addressed. Let's look a bit deeper in my two favourite sessions:</p>
<h3>Drupal 8: Share experiences and practices from a bigger project</h3>
<p>The main focus was (once again) on Drupal 8 and how to use the “New kids on the Block” like <a href="https://getcomposer.org/">Composer</a>, <a href="https://drupalconsole.com/">Drupal Console</a>, <a href="https://www.drupal.org/docs/8/configuration-management">Configuration Management</a> and all the other nice things finally available on the Drupal-Island. Furthermore, the experiences and thoughts from a bigger project are worth sharing, as they bring all of us forward. Since the squad in Fribourg did not do a lot of Drupal 8 projects yet, we could profit a lot from the Zürich developers. Uncertainties in terms of setup and workflow could be resolved and the people in Fribourg are (even more) eager to adapt this and maybe also improve on our future stack. The reason why we in Fribourg hesitated adopting those new tools was that we have a very well developed toolbox we use for earlier versions of Drupal. Quite a shift for us, but anyway worth to get our hands dirty with the new fancy stuff available in Drupal 8.</p>
<h3>Business Development: Streamline estimations</h3>
<p>In another session, the Fribourg squad could share their way of estimating Drupal projects. Since we had some differences in the past, we wanted to make sure we all estimate projects with the same parameters and the same understanding for an estimate. What's included and what's not? What base numbers and options do we have and so on. This session involved almost every role from the squad and was discussed very openly. We could find a way and defined actions to improve right away and to adapt and improve fastly if needed (depending on the needs in each office). A test-estimation round using this tool led us on a fictional project to almost exactly the same number. Surprise for everybody but also a success for the tool. Differences in estimations can be spotted and addressed easily. Together, we found a way to make project estimations easier and if needed even comparable across our offices.</p>
<h3>And many more …</h3>
<p>So on one side a very heavy developer session (with lots of buzzwords, code and console), on the other side also a “hot” discussion amongst almost all roles with a fair amount of knowledge transfer from Fribourg to Zürich and vice versa.</p>
<p>Besides that, we also talked a lot to each other between the Sessions. Projects, tools, modules, issues and so on. Backends where shown, ideas spread and solutions given. Other Sessions involved Front-End presentations and discussions about living Styleguides. Other people played around with the Drupal 8 Rest API possibilities or tried new possible base themes (like <a href="https://www.drupal.org/project/zen">Zen</a> for example).</p>
<h2>Sharing is caring and how we improved</h2>
<p>When I started at Liip 3 years back, we did not have a lot of communication between the squads doing Drupal. People in Fribourg for sure knew the people doing Drupal in Zürich. There was for sure some communication. But a real “Knowledge transfer” or something similar did not exist at this time.</p>
<p>The situation already improved by switching to Slack instead of mailing lists and Skype. The Slack channel we use to exchange in our Drupal-Guild makes collaboration and knowledge sharing easy and eased the inter-office discussion about problems. The Hackdays in addition are a very good possibility to visit other offices and to see each other in person. My impression is, that everybody really enjoys these days and many people are very passionate about Drupal and to show what has been done or can be done to improve even more.</p>
<p>The existence of those independent Drupal squads is from my point of view very valuable. Every squad can do their way of working and with the Drupal Hackday in place, we exchange our experiences like different companies would do. I think this is no disadvantage at all and helps us to adapt the good ideas and practices for each squad in whatever office individually.</p>
<p>I'm very much looking forward to the next Drupal Hackdays. Even if the Drupal Hackdays are mainly an “Internal” thing, we also welcome customers and other people interested in Drupal. So if you want to join a Hackday or if you're curious if Drupal is the right tool for you, drop us a line and we will show you how we do Drupal @ Liip!</p>]]></description>
          </item>
    
  </channel>
</rss>
