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



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

0 0


drupal8-twig-stockholm-2014

slides for drupalcamp stockholm 2014

On Github mortendk / drupal8-twig-stockholm-2014

T W I G !

Drupal8 theming

DrupalCamp Stockholm 2014

me:

@mortendk

Morten

Birch

heide-jørgensen

birch

bitch

Drupal since 4.7: 8 years

Frontend United !

King Drupal Denmark

Theme: Mothership

Drupal Association Board member

geek royale

Copenhagens Finest Themes (tm)

"As a themer I want to implement an awesome design into Drupal I will accept this story when in not loosing my sanity inside a php array"

So What is Actually wrong with Drupal Theming ?

From the frontend perspective ?

sorry devs you can moan later

2 things:

Divitis

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>

css overload

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>

css overload

5 classes for each field

<div class="field field-something field-even_more another-field-cause-im-drupal"> 
    wait im just a piece of data
</div>

    

Drupals Frontend Problems:

1. the markup

2 .the css

why

Blame ?

The "Developers"

The Themer

One markup to rule! em all

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
  • Dont solve all problems
  • 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>

    

Drupal8 DONT support

ie 6

ie 7

ie 8

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

Approved

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!

Drupal7 Mothership (tm)

Mothership

Compiled

the twig templates are compiled

.scss -> .css

(yes its the same thingie that compiling thing)

SQL in a theme ?

Who does that ?

Bad Developers

No Themer wanna touch that shit

SELECT * FROM users

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

gonna be an the UI

      $settings['twig_debug'] = TRUE;
      $settings['twig_auto_reload'] = TRUE;
    
node: 1969278

Branding & logo

HARD coded

Branding & logo

is now a block

Also in Drupal8

* Backbone * modernizr *

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

github.com/mortendk/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

if 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

{{attributes}}

    <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

and they wanna support ie "something"

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

html.html.twig + page.html.twig

drupal.org/node/2090967

translate

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

Höidy hoeeeydi

HERO's wanted

Frontend Heros

No more fucking whining!

Drupaltwig.org

twig team

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

YOU

#Drupaltwig weekly meeting

Thursdays at 1am CET

on IRC: #drupal-twig

Codesprint tomorrow

11:00

Field.twig

codesprints upcoming

Drupal Dev Day's sZeged 24-30 march

Midcamp Chicago 24-30 march

#Drupaltwig

drupaltwig.org

resourses

TWIG documentation: twig.sensiolabs.org/doc/templates.html drupaltwig.org Slides: http://mortendk.github.io/drupal8-twig-stockholm-2014

Questions?

@mortendk

#drupaltwig

drupaltwig.org