T W I G ! – Drupal8 theming – DrupalCamp London 2014



T W I G ! – Drupal8 theming – DrupalCamp London 2014

1 0


slides-drupal8-twig-dclondon2014


On Github mortendk / slides-drupal8-twig-dclondon2014

T W I G !

Drupal8 theming

DrupalCamp London 2014

Offended ?

me:

@mortendk

Morten

Birch

heide-jørgensen

birch

bitch

Drupal since 4.7: 8 years

Frontend United !

King at Drupal Denmark

mothership

geek royale

Copenhagens Finest Themes (tm)

Fair warning

Im the definition of everything thats nasty, evil, despeckable & dark in this world im just quoting my ex

Send me

Recruiters:

2 Rules:

Dont ask me if i do database!

I will drink your booze

whats wrong with Drupal

So What is Actually wrong with Drupal Theming ?

From the frontend perspective ?

sorry devs you can moan later

2 things:

Rich Markup (tm)

<div class="foo bar baz whatever">
  <div class="foo bar baz whatever">
    <div class="foo bar baz whatever">

      <h1 class="pane-title">hello im drupal</h1>

      <div class="node node-type node-viewmode-argh">
        always add another div
      </div>

    </div>
  </div>
</div>
27 css files in drupal 7 stark
<style media="all">
  @import url("sites/modules/system/system.base.css?mz4mz0");
  @import url("sites/modules/system/system.menus.css?mz4mz0");
  @import url("sites/modules/system/system.messages.css?mz4mz0");
  @import url("sites/modules/system/system.theme.css?mz4mz0");</style>
<style media="all">
  @import url("sites/modules/contextual/contextual.css?mz4mz0");
</style>
<style media="all">
  @import url("sites/modules/aggregator/aggregator.css?mz4mz0");
  @import url("sites/modules/book/book.css?mz4mz0");
  @import url("sites/modules/comment/comment.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/date/date_api/date.css?mz4mz0");
  @import url("sites/modules/field/theme/field.css?mz4mz0");
  @import url("sites/modules/node/node.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/picture/picture_wysiwyg.css?mz4mz0");
  @import url("sites/modules/poll/poll.css?mz4mz0");
  @import url("sites/modules/search/search.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/search_krumo/search_krumo.css?mz4mz0");
  @import url("sites/modules/user/user.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/video_filter/video_filter.css?mz4mz0");
  @import url("sites/modules/forum/forum.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/views/css/views.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/admin_menu/admin_menu.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/admin_menu/admin_menu.uid1.css?mz4mz0");
</style>
<style media="all">
  @import url("sites/sites/all/modules/contrib/ctools/css/ctools.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/panels/css/panels.css?mz4mz0");
  @import url("sites/sites/all/modules/contrib/panels/plugins/layouts/twocol_stacked/twocol_stacked.css?mz4mz0");
  @import url("sites/sites/all/themes/mothership/mothership/templates/panels//mothership-html5page/mothership-html5page.admin.css?mz4mz0");
</style>
<style media="all">
  @import url("sites/themes/stark/layout.css?mz4mz0");
</style>

Drupals Frontend Problems

the markup

the css

W T F

Blame ?

lets point a finger

The "Developers"

The Themer

One markup to rule! em all

css overwriting

Nobody told us what to do!

Pretty please...

TWIG "initiative"

Was not an official thing

Guerilla TWIG

Anger driven development ;)

Amsterdam

San Francisco

PHP template dead to me!

TWIG

a little bit of french elegance

Lets make a plan

Frontend united amsterdam march 2012 badcamp 2012 Drupalcon Munich 2012 Drupalcon Portland 2013 frontend united london 2013

Dont do 100%

Build on usercases!

Dont Dumb it down

Themers are not that Dumb

the Frontend experience

  • Start from nothing
  • Provide tools
  • Visibility
  • consistency
  • dont dumb it down

New awesome [sjeit]

or 666 reasons why Drupal8 is better than Drupal7

HTML 5

HTML5

      <header role="banner">
        <nav>
          <a href="/">home</a> | <a href="/info">info</a>
        </nav>
      </header>
      <main>

        
        <div>
          ... 
        </div>    
      </main>
      <footer role="">
      </footer>

    

we DONT support

ie 6

ie 7

ie 8

(theres a module for that )

Pretty markup

<div id="badpractive">...</div>

37% less id *

counting at alpha9

* kinda

Drupal CSS

Drupal 7

      <body class="html facepalm whateverthefuck ">
    

Drupal8

      <body class="">
    

CSS Stucture

Build on SMACSS

CSS architecture (1887918)
    .notification {
        /* general styles for all notifications */
      }
      .notification--info {
        /* blue color adjustments */
      }
    

css filenames

Aproved

B.A.T. Namescheme

CSS file organization (nid: 1887922)

D8 File Structure

Drupal 8 core

/themes

provide visibility

themes now lives in "/themes"

or "sites/ *** /themes"

D8 File structure modules

modulename/templates/*.html.twig

wheres that template ?

DEBUG!

      $settings['twig_debug'] = TRUE;
    
settings.php

$settings['twig_debug'] = TRUE;

DEBUG!

Mothership (tm)

Mothership

Compiled

the twig templates are compiled

.scss -> .css

template.html.twig -> php

No more <?php print "php" ; ?>

No more DB

inside a theme...

Who does that ?

Bad Developers

No Themer wanna touch that shit

select * from table

 
      <article class="foo foo-whateverdrupal">
        <article class="foo foo-inner foo-whateverdrupal">
          ....
        </article>
      </article>
     

settings.php

      $settings['twig_debug'] = TRUE;
  
      $settings['twig_auto_reload'] = TRUE;
    

Twig Basic

its dead easy

comments & vars

    /*
    comment
    */
      <?php print $foo ; ?>
    
phptemplate
      {# comment #}

      {{ foo }}
    
twig

Variables

   /*
    so php template
    Now where is that value again
   */

 <?php print $foo['bar']['UND']->baz['what']->thefuck['seriously'] ?>
    
    
phptemplate
      {# hello twig can you find valdo ? #}

      {{ foo.bar.baz.done.with.this.shit }}
      
      {{ foo['bar'] }}

      {% functions %}
    
Twig

If / else

    <?php if($foo): ?>
      <?php print $var; ?>
    <?php endif; ?>
    
phptemplate
      {% if foo %}
        {{ var }}
      {% endif %}
    
twig

loops

      <h2>Team Awesome </h2>
      <ul>
        {% for user in users %}
            <li>{{ user.username}}</li>
        {% endfor %}
      </ul>
    
twig
      <h2>Team Awesome </h2>
      <ul>
        <li>cottset</li>        
        <li>joel</li>
        <li>jen</li>
        <li>mark carver</li>        
        <li>mortendk</li>
      </ul>
    
drupal8

loop stuff

  
    {{ loop.length }}    

    {{ loop.first }}

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

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

Set

      {% set foo %}
        count-{{ loop.index }}
      {% endset %}
      
      {{ foo }},  
    
twig
      count-1,count-2, count-3,
    
output

filter

     <p>
    {% filter upper %}
        uppercase for the win
    {% endfilter %}
    </p>
    
      <p>
        UPPERCASE FOR THE WIN
      </p>
    

|filter

      {{ foo|dostufftofoo }}
    
      {#  name = <a hred="foo">morten</a> #}
      {{ name|striptags|title }}
    
twig
      Morten  
    

Drupal8 Theme

Yggdrasil

theme structure

name: drupal7themename
      description = This is my epic D7 theme
      screenshot = screenshot.png
      engine = phptemplate
      core = 7.x
      php = 5.2

      regions[header] = Header
      regions[logo] = Logo
      regions[menu] = Menu
      regions[messages] = Messages
      regions[content] = Content
      regions[footer] = Footer

      stylesheets[all][] = css/style.css
      #FOAD fix
      stylesheets[all][] = donteverloadmeagain.css

drupal7.info

name: drupal8themename
      type: theme
      description: This is my epic D8 theme
      package: Core
      core: 8.x

      stylesheets:
        all:
          - css/layout.css
        print:
          - css/print.css
        stylesheets-remove:
          - system.theme.css
          - user.icons.css
          - stuffidontwant.css

      regions:
        header: Header
        logo: Logo
        menu: Menu
        messages: Messages
        content: Content
        footer: Footer

      # engine: phptemplate

drupal8.info

you phptemplate

# engine: phptemplate
themename.info

FOAD

its now build in

      stylesheets[all][] = css/style.css
      #FOAD fix
      ;stylesheets[all][] = donteverloadmeagain.css
      stylesheets[all][] = system.theme.css
      stylesheets[all][] = user.icons.css
      stylesheets[all][] = stuffidontwant.css
    
drupal 7
        stylesheets-remove:
          - system.theme.css
          - user.icons.css
          - stuffidontwant.css
    
drupal 8

Regions on Page

Drupal 7

<?php if ($page['footer']): ?>
  <footer role="contentinfo">
    <?php print render($page[footer]);  ?>
  </footer>
<?php endid ?>
<?php print render($page[region]); ?>

Drupal 8

{% if page.footer %}
  <footer role="contentinfo">
    {{ page.footer}}
  </footer>
{% endif %}
twig: {{ page.region }}

Blocks

    <div{{ attributes }}>
      {{ title_prefix }}
      {% if label %}
        <h2{{ title_attributes }}>{{ label }}</h2>
      {% endif %}
      {{ title_suffix }}

      <div{{ content_attributes }}>
        {{ content }}
      </div>
    </div>
        
block.twig
<nav class="{{ attributes.class }}" role="{{ attributes.role}}">
      {{ title_prefix }}
      {% if label %}
        <h2{{ title_attributes }}>{{ label }}</h2>
      {% endif %}
      {{ title_suffix }}
      {{ content }}
    </nav>
block--system-menu-block.html.twig

block.html.twig

theme hook suggestions

{{ whatever|replace }}

<div class="block blockmore blockmorecauseofdrupal">...</div>
      {{ attributes.class |replace( {'block': '' }) }}
block.html.
<nav class="{{ attributes.class }}" role="{{ attributes.role}}">
        {{ title_prefix }}
        {% if label %}
          <h2{{ title_attributes }}>{{ label }}</h2>
        {% endif %}
        {{ title_suffix }}

        {{ content }}
      </nav>
block--system-menu-block.html.twig
<nav class="l-foobar mainmenu" role="navigation">
        ... content ...
      </nav>
Done

Attribuets

Lets manipulate attributes

<body {{attribues}}>
page.html.html

{{attributes}}

<div {{attributes}}> ... </div>

    <article {{attributes}}=""> ... </article>
    
    <article class="{{attributes.class}}" {{attributes}}=""> 
      ...
    </article>
     
      <article class="{{ attributes.class }}" role="{{ attributes.role }}" {{="" attributes="" }}="">
      ....
      </article>
     

add .foo


      <article class="foo {{ attributes.class}}" {{attributes}}="">
        foo
      </article>

    
.twig
      <article class="foo field-foo" role="something">
        foo
      </article>
    
drupal

Terms

the designer is an idiot

the Markup

      
      <section class="tags">
        <span>3 tags:</span>
        
        <a href="#" class="odd">foo</a>, 
        <a href="#" class="even thedesignerisanidiot">bar</a>, 
        <a href="#" class="odd">baz</a>.

      </section>
    
the markup
      .thedesignerisanidiot{
        color: green;
        font-style:italic;
      }
      
    {# Start the loop #}
    {% for delta, item in items %}

      {# create a class var #}
      {% set class %}
        {# odd even #}  
        {{- cycle(["even", "odd"], delta) }} 
        {# count-x #}
        count-{{ loop.index -}}"
      {% endset %}

      <a href="#" class="{{class}}">{{item}}</a>, 
    
    {# end the loop #}
    {% endfor %}
    
field--field-tags.html.twig
       <a href="#" class="odd count-1">Odin</a>,
       <a href="#" class="even count-2">Thor</a>,
       <a href="#" class="odd count-3">Freya</a>,      
    
drupal8

tags vs tag

      {# first loop #}
      {% if loop.first %}
        {# set tags / tag #}
        <span>
        {% if loop.length > 1 %} 
          {{ loop.length }}
          tags:
          {% else %} 
          tag:
        {% endif %}
        <span>
      ...
    </span></span>
field--field-tags.html.twig
      <span>3 tags:</span>
    

add a class on 2 tag

      {% if loop.first %}
        ...
      {% elseif loop.index == 2 %}
      <a href="#" class="thedesignerisanidiot {{class}}">{{item}}</a>, 
      
      ...

    {# end the loop #}
    {% endfor %}
    
field--field-tags.html.twig
       <a href="#" class="odd count-1">Odin</a>
       <a href="#" class="thedesignerisanidiot even count-2">Thor</a>
       <a href="#" class="odd count-3">Freya</a>       
    
      {% if loop.first %}
        <span>
        {% if loop.length > 1 %}  
          {{ loop.length }}  tags:
        {% else %} 
        tag:
        {% endif %}
        <span>

        <a href="#" class="{{class}}">{{item}}</a>,
      {% elseif loop.index == 2 %}
        <a href="#" class="thedesignerisanidiot {{class}}">{{item}}</a>, 
      {% elseif loop.last %}
        <a href="#" class="{{class}}">{{item}}</a>.
      {% else %}
        <a href="#" class="{{class}}">{{item}}</a>,      
      {% endif %}   
    </span></span>
field--field-tags.html.twig
        3 tags:
       <a href="#" class="odd count-1">Odin</a>,
       <a href="#" class="thedesignerisanidiot even count-2">Thor</a>,
       <a href="#" class="odd count-3">Freya</a>.       
    

TWIG BLOCK

      {% block foobar %}
        {# i can be something else #}
      {% endblock %}
    
      {% block headerblock %}
        change me if im on the frontpage
      {% endblock %}
    
page.twig.html
      {% extends "themes/yggdrasil/templates/page.html.twig" %}
      {% block headerblock %}
        Im on the frontpage!
      {% endblock %}
    
page--front.html.twig

translate

    {{ 'last checked: @time ago'| t({'@time':time}) }}
    
      {% trans %}
        Hi im a swede and i speak funny
      {% endtrans %}
    

swedish

HERO's wanted

#dreammarkup

twig team

cottser, joel, jen lampton, mortendk, ruben, markcarver, fabianX. YOU!

#Drupaltwig weekly meeting

Thursdays at 1am CET

on IRC: #drupal-twig

Codesprint tomorrow

joels hitlist http://dev.drupaltwig.org/joelpittet/hitlist

https://drupal.org/node/2114563

merge html.html.twig with page.html.twig html.html.twig https://drupal.org/node/2090967

node.html.twig https://drupal.org/node/2004252

alpha release: https://drupal.org/node/3060/release

codesprints upcoming

Drupal Dev Days sZeged + midcamp chicago

#Drupaltwig

resourses

Questions?