Drupal 8 Theming – Lauri Eskola – What's new?



Drupal 8 Theming – Lauri Eskola – What's new?

0 0


twig-minicamp-turku-14


On Github lauriii / twig-minicamp-turku-14

Drupal 8 Theming

22.10.2014 Lauri Eskola

Me:

Lauri Eskola

@lauriii

Twitter:

@laurii1

What's new?

HTML5

HTML5

              
      <header role="banner">
        <h1>Dries FTW!</h1>
        <nav>
          <a href="/">home</a> | <a href="/info">info</a>
        </nav>
      </header>
      <main>
        <aside>
          ...
        </aside>
        <div>
          ... 
        </div>    
      </main>
      <footer role="">
      </footer>
              
            

So Drupal 8 WON'T support

ie 6

ie 7

ie 8

Drupal CSS

Drupal 7

              
      <body class="html drupal7 is-awesome wtf not-logged-in no-sidebars page-node page-node- page-node-274 node-type-page">
              
            

Drupal 8

              
      <body>
              
            

CSS build on SMACSS and BEM

More from #1887918

CSS

              
      .field {
        margin: 6px 9px;
      }
      .field.field--name {
        color: pink; 
      }
              
            

HTML

              
      <div class="field field--name" />
              
            

Seven CSS file structure

Drupal 8 File structure

No more

sites/all/where/the/f*ck/is/my/themes

Templates in template folder!

AND!

Templates are auto-loaded with hook_theme implementation key!

Completely new theme layer!

Drupal 7 theme layer - WTF?

Drupal 8 theme layer - FTW!

Twig

Basics in under 5 minutes

This is Twig, no Drupal!

Comments & Vars

PHP:

              
      <?php

      // My test variable
      print $variable;
              
            

Twig:

              
      {# My test variable #}
      {{ variable }}
              
            

Set variables

              
      {% set variable = 'result' %}
              
            
            
      {%
        set array = [
          'foo',
          'bar',
        ]
      %}
              
            

Arrays

PHP:

              
      <?php

      // WTF?!
      print $foo['im']['und']->boss['long']['ass']['shit'] ?>
              
            

Twig:

              
      {{ foo.im.boss.long.ass.mofo }}
              
            

Loops

              
      <h2>Team Awesome</h2>
      <ul>
        {% for user in users %}
          <li>{{ user.username}}</li>
        {% endfor %}
      </ul>
              
            
              
        <h2>Team Awesome</h2>
        <ul>
          <li>cottser</li>        
          <li>joel</li>
          <li>david</li>
          <li>mark carver</li>        
          <li>mortendk</li>
        </ul>
              
            

Loops

              
      <h2>Team Awesome</h2>
      <ul>
        {% for user in users %}
          <li>{{ user.username}}</li>
        {% else %}
          <li>no results found</li>
        {% endfor %}
      </ul>
              
            

Loop stuff

              
      {{ loop.length }}    

      {{ loop.first }}

      {{ loop.last }}
     
      {{ loop.index }}

      {% if loop.first %}
        ...  
      {% elseif loop.index == 2 %}
        ...
      {% elseif loop.last %}
          ...
      {% endif %}
              
            

Filter

              
      <p>
        {% filter upper %}
          uppercase for the win
        {% endfilter %}
      </p>
              
            

|Filter

              
      {% set name = 'Lauri' %}
      <span>           
        {{ name|length }}
      </span>
              
            

Returns:

              
      <span>
        5
      </span>
              
            
  • |abs
  • |batch
  • |capitalize
  • |covert_encoding
  • |date
  • |date_modify
  • |default
  • |escape
  • |first
  • |format
  • |join
  • |json_encode
  • |keys
  • |last
  • |length
  • |lower
  • |nl2br
  • |number_format
  • |merge
  • |upper
  • |raw
  • |replace
  • |reverse
  • |round
  • |slice
  • |sort
  • |split
  • |striptags
  • |title
  • |trim
  • |url_encode

Twig blocks

page.html.twig
              
      {% block headerblock %}
        <h2>This block needs more kittens!</h2>
      {% endblock %}
              
            
page--front.html.twig
              
      {% extends "page.html.twig" %}
      {% block headerblock %}
        {{ parent() }}
        <h4>Kitten!</h4>
      {% endblock %}
              
            

Will return:

Other pages than front page:

Will return:

Front page:

More stuff?

Twig documentation: http://twig.sensiolabs.org/

You no like it?

Solution!

              
      # engine: phptemplate
              
            
themename.info

Drupal specific Twig functionalities

This is Drupal!

Filters

              
      {% set class_name = 'lauri/druid' %}

      {%
        set contributors = [
          'rteijeiro',
          'joelpittet',
          'Cottser',
          'lauriii',
          'Dries',
        ]
      %}

      {{ class_name|clean_class }}
      {{ contributors|without('lauriii') }},
              
            

Returns

              
      lauri-druid
      rteijeiro,joelpittet,Cottser,Dries,
          

HTML Attributes

Not ready yet, more info #2325517

Preprocess:

              
      <?php
        function template_preprocess_username(&$variables) {
          $variables['attributes'] = new Attribute();
        }
      ?>
              
            

Template:

              
      <div{{ attributes.setAttribute('id', 'kitten').setAttribute('I-Love', 'Dries') }}>

      <div{{ attributes.removeAttribute('id') }}>
              
            

Add/Remove class

More information #2325067

              
      <div{{ attributes.addClass('field-item-' ~ name|clean_class) }}>
              
            
OR
              
      <div{{ attributes.removeClass('GTFO', 'i-hate--you') }}>
              
            

Translate

              
      {{ 'Author: @username'| t({'@username':username}) }}
              
            

Or:

              
      {% trans %}
        Author {{ username }}
      {% endtrans %}
              
            

Twig debug

No more guessing!

services.yml
              
     debug: true
              
            
It works and it's awesome!

Will return:

              
    <!-- THEME DEBUG -->
    <!-- CALL: _theme('page') -->
    <!-- FILE NAME SUGGESTIONS:
       * page--front.html.twig
       * page--node.html.twig
       x page.html.twig
    -->
    <!-- BEGIN OUTPUT from 'core/themes/bartik/templates/page.html.twig' -->
              
            

Want this to D7?

Do it! #2307505

Autoescape

Context-Aware Auto-Escaping

Basic idea: everytime variable goes to template run appropriate escaping function!

Different Escape functions

              
      <?php

      Drupal\Component\Utility\SafeMarkup::isSafe();
      Drupal\Component\Utility\SafeMarkup::escape();
      Drupal\Component\Utility\SafeMarkup::checkAdminXss();

              
            

How it works?

              
    <?php

    public static function escape($string) {
      return static::isSafe($string) ? $string : String::checkPlain($string);
    }
                
              
            

Consensus banana

Steps:

  • Phase 1. Move all the classes to templates ✓ done!
  • Phase 2. Classy <- we are here!

Phase 1:

Move classes from preprocess to templates

node.html.twig

              
  {%
    set classes = [
      'node',
      'node--type-' ~ node.bundle|clean_class,
      node.isPromoted() ? 'node--promoted',
      node.isSticky() ? 'node--sticky',
      not node.isPublished() ? 'node--unpublished',
      view_mode ? 'node--view-mode-' ~ view_mode|clean_class,
      'clearfix',
    ]
  %}
  <article{{ attributes.addClass(classes) }}>
   {{ content }}
  </article>

              
            

Phase 2:

New theme: Classy

What will this change?

Move all the class logic to Classy - so no classes from core (even automated tests uses now Classy)

Simplify core markup even more! (removing all unnecessary divs & other elements)

Creating new theme?

Remember to extend Classy!

Bonus!

No more hardcoded logo..

... or menu!

Want to help?

RC1 means markup freeze...

... so there's plenty of time still!

Next sprints at KWD 21.11.