Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Multilingual Sites in Craft 3

Multilingual Sites in Craft 3

The challenges of multilingual sites in general, and how to implement them using Craft CMS version 3

Zoltan Varady

September 27, 2018

Other Decks in Programming


  1. Who will do the translation? Internally, by the content team

    By the developers Outsourced to a translation agency via an API? Automated translation
  2. Translation workflow Do you need to publish all languages at

    once? Proofreading / approval Translation management tools

  3. To borrow from Drupal Content translation (entries, categories, etc) Interface

    translation (static messages, Craft::t, twig’s | t filter) Configuration translation (settings, email templates…)
  4. Belgian Site Group Swiss Site Group Schwiizerdütch de-CH Swiss French

    fr-CH Swiss Italian it-CH Flemish nl-BE Belgian French fr-BE Belgian German de-BE
  5. Not So Fancy Fancy Shoes en-GB Shirts en-GB Pants en-GB

    Shoes en-GB Shirts en-GB Pants en-GB
  6. Multi-valued fields Matrix Categories, tags Related entries Assets but not

    Tables (use Matrix or Super Table instead if you need it)
  7. pizza dough tomatoes mozzarella ham pineapple pizzatészta paradicsom mozzarella kolbász

    pizza dough tomatoes mozzarella pizzatészta paradicsom mozzarella
  8. Localization is more than words 05/06/2018 vs 06/05/2018 vs 2018.

    06. 05. 2,100.99 vs 2 100,99 $100 vs 100 EUR GMT UTC DST CET PST 1 hour, 2 hours vs نابْح ُ ص باح ْ صَأ بِحاص
  9. Yii 2 + INTL = FTW {{ 'Hello {name}!' |

    t({ name: 'Zoltan' }) }} => Hello Zoltan {{ 'Hello {0}!' | t([‘Zoltan’]) }} => Hello Zoltan {{ 'Total: {amt,number}' | t({amt: 2510.99}) }} => 2,510.99 {{ 'You are the {n,spellout,%spellout-ordinal} in line' | t({n: 47}) }} => You are the forty-seventh in line {{ 'Eres {n,ordinal,%digits-ordinal-feminine}' | t({n: 1}) }} => Eres 1.ª
  10. {{ '{d,date,short}' | t({d: date().timestamp}) }} => 9/18/18 {{ 'Today

    is {d,date,long}' | t({d: date().timestamp}) }} => September 18, 2018 {{ 'Today is {d,date,yyyy-MM-dd}' | t({d: date().timestamp}) }} => 2018-09-18 {{ 'Last updated: {0, duration,%with-words} ago' | t([15024]) }} => Last updated: 4 hours, 10 minutes, 24 seconds ago
  11. {{ 'You {likeCount,plural, offset: 1 =0{did not like this} =1{liked

    this} one{and one other person liked this} other{and # others liked this} } ' | t ({likeCount: 2}) }} => You and one other person liked this
  12. Configuration translation No standardized way of storing or displaying translations

    Plugins need to take care of it themselves Drupal does it via a configuration schema
  13. Site aliases general.php 'aliases' => [ '@webHu' => getenv('HU_BASE_URL'), '@webEn'

    => getenv('EN_BASE_URL'), '@assetBaseUrl' => getenv('ASSET_BASE_URL'), '@assetBasePath' => getenv('ASSET_BASE_PATH'), ], .env HU_BASE_URL="https://designhet.hu/2018/" EN_BASE_URL="https://designweek.hu/2018/" ASSET_BASE_URL="https://designhet.hu/2018/" ASSET_BASE_PATH=“/home/asdf/2018/“ <ul class="language"> <li><a href="{{ alias('@webHu') }}">Magyar</a></li> <li><a href="{{ alias('@webEn') }}">English</a></li> </ul> <script src="{{ alias('@assetBaseUrl') }}/js/jquery-3.3.1.min.js"></script>
  14. Routes return [ 'hirek' => ['template' => 'news/index'], 'esemenyek' =>

    ['template' => 'events/index'], ]; Section settings config/routes.php Route settings
  15. Per-site templates “create a new sub-folder in your templates folder,

    named after your site's handle, and place the templates in there”
  16. Per-site configuration not directly possible - general.php is loaded early

    in the bootstrap process Craft has no idea about the current site or language at the time workarounds: use environment vars, seperate index.php entry points, or arrays keyed by site handle
  17. currentSite currentSite.name => English currentSite.handle => default currentSite.language => en-GB

    currentSite.baseUrl => @web/ {{ alias(currentSite.baseUrl) }} => https://designhet.hu/
  18. Twig craft.app.sites => all sites currentSite.group.sites => sites in current

    group entry.getSupportedSites => sites that entry is active for
  19. Names Zoltan Várady Várady Zoltán Várady Zoltánné Pablo Diego José

    Francisco de Paula Juan Nepomuceno María de los Remedios Cipriano de laSantísima Trinidad Ruiz y Picasso validation and sorting can be challenging https://www.w3.org/International/questions/qa-personal-names
  20. Challenges in Craft Configuration translation Structure entries always propagate Collaborative

    translation of core and plugins transifex, localize.drupal.org
  21. Summary consider your audience what needs to be translated translation

    is not just words; see culture, colors, images… who are the translators, what is the workflow once you have this, use the tips given to map it onto a Craft site