building a custom theme in drupal 8
TRANSCRIPT
BUILDING A CUSTOMTHEME IN DRUPAL 8
BASED ON THE CLASSY BASE THEME
Presentation by Anne Tomasevich
INTRODUCTIONThis is the part where I talk about myself
Photo by Jessie Gladdek
savaslabs.com@Savas_Labs
AGENDAWhat's changing?
Let's make a theme
Twig basics and debugging
LET'S START FROM THE VERYBEGINNING
WHAT IS THEMING?
Themes allow you to change the look andfeel of your Drupal site.
- Someone who's good at being very general
WHAT'S CHANGING?...and how do I, a person who probably doesn't like change, cope with these changes...
WHAT'S NEW IN DRUPAL 8?Twig, a template engine by SensioLabs
Classy, a new base theme
template.php becomes [theme-name].theme. (Dear Drupalgods, can we please have theme.php?)
WHAT'S NEW IN DRUPAL 8?Responsive design elements are included by default
Breakpoints can be set and used across modules and themes
WHAT'S NEW IN DRUPAL 8?LOOK AT ALL THE PRETTY THINGS
WE GET TO USE NOW!!HTML5CSS3Modern jQuery librariesSMACSSBEMStandardized breakpoints
WHAT'S NEW IN DRUPAL 8?Support for IE8 and below is dropped meaning the use ofjQuery 2.0, HTML5, and CSS3 (including pseudo selectors) arenow supported
CSS:Far fewer IDs are used
CSS file structure now uses
Default class names follow the format
CSS and JS files are attached to pages differently
SMACSS
BEM
WHAT'S NEW IN DRUPAL 8?For a more comprehensive list, visit Drupal's change log.
WHY ALL THE CHANGES?ACCESSIBILITY TO NON-DRUPALERS
Fewer Drupal-specific conventions and more popular, well-documented frameworks (such as Twig), meaning non-Drupalers can jump in much more quickly.
D8 themers don’t need to know PHP to whip up a theme.*
* I mean kinda ¯\_(ツ)_/¯
WHY ALL THE CHANGES?SECURITY
Text is automatically escaped in Twig, meaning a lowerchance of XSS attacks.
Template files are more secure since they no longer containPHP code.
<?php db_query('DROP TABLE {users}'); ?>
Scary example courtesy of sqndr at d8.sqndr.com.
WHY ALL THE CHANGES?CURRENT FRAMEWORKS AND TOOLS
Separation of logic from appearance = more modular(reusable) code
More semantic CSS class names = leaner CSS and a morereadable DOM
A general trend towards more extendable, modular, well-organized, better-performing code
ANY DISADVANTAGES?1. Many contributed themes and modules don't having their 8.x
branches ready.
A fun note on the 8.x branch of a popular contrib theme:
This is a development branch. Please notethat this branch is probably severely broken.It is strongly recommended to wait beforeusing this branch or even creating issuesregarding it.
ANY DISADVANTAGES?2. Serious lack of documentation online
Of the documentation that DOES exist, much of it is:
Outdated, and marked as such.
Outdated, and NOT marked as such.
LET'S BUILD THIS THING
WHAT AM I TOTALLY GLOSSINGOVER?
template.php *.theme
Grid framework and CSS architecture
Probably a lot of other things
CREATE A THEME FOLDER
Drupal core now resides in its own folder. Contributed andcustom modules and themes are in the modules and themesfolders, respectively.
Don't forget to create a custom folder for your customtheme!
CREATE A .INFO.YML FILE# mappy.info.ymlname: Mappytype: themedescription: 'D8 Theme for a basic leaflet site.'core: 8.xbase theme: classylibraries: - mappy/global-styling - mappy/leafletregions: navbar: 'Top Navigation Bar' content: Content # required! sidebar: 'Sidebar' footer: 'Footer'
[theme-name].info becomes [theme-name].info.yml
DOT INFO DOT WHAT?YAML is a data serialization language.
Key-value pairs.
Check out on YAML syntaxbefore getting started.
And mind your whitespace!
Symfony's excellent writeup
CREATE A .INFO.YML FILE# mappy.info.ymlname: Mappytype: themedescription: 'D8 Theme for a basic leaflet site.'core: 8.xregions: navbar: 'Top Navigation Bar' content: Content # required! sidebar: 'Sidebar' footer: 'Footer'
This looks familiar, right?
CLASSY, A NEW BASE THEME# mappy.info.ymlbase theme: classy
In D8, default classes are stripped from Drupal core andmoved into the base theme Classy.
To avoid these default classes, simply don't base your themeon Classy.
But we want them because BEM is awesome! Check out thisawesome introduction.
LIBRARIES# mappy.info.ymllibraries: - mappy/global-styling - mappy/leaflet
In D8, assets can be added in a few different ways: globally,per-template, per-page, and more.
All libraries must be defined in your *.libraries.yml file.
CREATE A .LIBRARIES.YML FILE# mappy.libraries.ymlglobal-styling: css: theme: css/styles.css: {}
leaflet: css: theme: css/leaflet.css: {} js: js/leaflet.js: {} js/map.js: {} dependencies: - core/jquery
Note that jQuery is listed as a dependency of the Leaflet library.Since jQuery is no longer loaded automatically on every page, itmust be explicitly required.
ADDING ASSETS TO YOUR SITE# mappy.info.ymllibraries: - mappy/global-styling - mappy/leaflet
Since this is a small site and we need our libraries on everypage, we're adding them globally.
Visit for more information on methods for addingassets.
drupal.org
CREATE A .BREAKPOINTS.YMLFILE
# mappy.breakpoints.ymlmappy.mobile: label: mobile mediaQuery: '(min-width: 0px)' weight: 2 multipliers: - 1xmappy.narrow: label: narrow mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)' weight: 1 multipliers: - 1xmappy.wide: label: wide mediaQuery: 'all and (min-width: 851px)' weight: 0 multipliers:
Ours is stolen adapted from the Bartik theme.
BREAKPOINTSOnce you add a .breakpoints.yml file (and uninstall andreinstall your theme), the breakpoints you've set will beexposed in the admin UI.
These breakpoints can be used across various modules.
WITH THESE FILES SET UP, WENOW HAVE A WORKING CUSTOM
THEME!
TEMPLATE FILESIn our theme's current state, we're using Classy's defaulttemplate files.
If we want to override them, it's time to learn some Twig.
If one more person makes a "Gettin' Twiggy with it" joke...
INTRO TO TWIG is a template engine with syntax similar to Django, Jinja,
and Liquid.
It simplifies template creation with clean syntax and usefulbuilt-in filters, functions, and tags.
In a Drupal template file (now with the extention .html.twig),anything between curly braces is Twig.
Twig
TWIG DELIMITERS{{ These }} are for printing content, either explicitly or viafunctions
{% These %} are for executing statements
{# These #} are for comments
PRINTING VARIABLES ANDREGIONS
In D7 we render content like so:<?php print render($page['sidebar']); ?>
Printing variables in D8 is as easy as including them insidedouble curly braces:
{# In page--front.html.twig #}{# Print the sidebar region. #}
{{ page.sidebar }}
PRINTING VARIABLES WITHSPECIAL CHARACTERS
If a variable name contains special characters, use Twig'ssubscript syntax (which will look familiar to seasonedDrupalers).
{# In page--front.html.twig #}{# Print the page type. #}
{{ page['#type'] }}
This will come in handy more during debugging.
FILTERSTwig comes with many that variables are passedto via the pipe character.
built-in filters
Here's the date filter:{# Format the post date. #}
{{ post.published|date("Y-m-d") }}
DRUPAL-SPECIFIC FILTERSCheck them out here.
Remember our old friend t()?{# Run an ARIA label through t() #}
<nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
FUNCTIONSTwig also comes with various that can be used indouble curly braces.
functions
Here's the cycle function doing some very important work:{% set fruits = ['apple', 'orange', 'banana'] %}
{% for i in 0..10 %} {{ cycle(fruits, i) }}{% endfor %}
TAGSUsed for control flow and other fun things.
{# From Bartik's page.html.twig #}{# If there are tabs, output them. #}
{% if tabs %} <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}"> {{ tabs }} </nav> {% endif %}
In template files, we’ll use the if statement quite often.
GET PSYCHEDMake sure you check out the Twig coding standards!
TWIG DEBUGGINGTo enable debug mode and turn off caching, we need to do 3things:
1. Turn on Twig’s debug mode
2. Turn on Twig auto reload, meaning that Twig templates areautomatically recompiled when the source code is changed
3. Disable Drupal’s render cache
You do NOT need turn off Twig caching - turning on auto reloadis enough.
USE SETTINGS.LOCAL.PHP1. Copy sites/example.settings.local.php to sites/default and rename to settings.local.php. Fill outyour local database settings.
2. Uncomment the following at the bottom of sites/default/settings.php:
if (file_exists(__DIR__ . '/settings.local.php')) { include __DIR__ . '/settings.local.php';}
TURN ON DEBUG MODE ANDAUTO RELOAD
Check out settings.local.php// In settings.local.php
/** * Enable local development services. */$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';
This tells us to head over to development.services.yml.// In sites/development.services.ymlparameters: twig.config: debug: true auto-reload: true
TURN OFF DRUPAL'S RENDERCACHE
Just kidding, you already did.// In settings.local.php
/** * Disable the render cache (this includes the page cache). * * This setting disables the render cache by using the Null cache back-end * defined by the development.services.yml file above. * * Do not use this setting until after the site is installed. */$settings['cache']['bins']['render'] = 'cache.backend.null';
DEBUG AWAYNow you can:
View HTML comments in your browser’s code inspector withlots of helpful info:
Which theme hook is being implemented
Theme hook suggestions (i.e. how to override the currenttheme hook)
Which template file is being output.
Make changes to your source code and simply refresh thepage to see your changes rather than constantly rebuildingthe cache.
DUMP( )With Twig debugging turned on, we can use the Twig function dump().
{# In a template file #}{# Print out all variables on the page. #}
{{ dump() }}
{# Print the page's base path. #}
{{ dump(base_path) }}
EVEN BETTER: KINT( )Install the Devel and Devel Kint modules to use kint() in thesame way, but with a pretty, expandable array instead.
{# In a template file #}{# Print out all variables on the page. #}
{{ kint() }}
RESOURCES AND FURTHERREADING
A brilliant blog post about D8 theming (Savas)D8 theming guide (Sander)YAML formatting (Symfony)Intro to BEM (CSS Wizardry)Adding assets to pages (drupal.org)Twig documentation (Sensiolabs)Drupal-specific Twig filters (drupal.org)Twig coding standards (drupal.org)Twig debugging and devel (drupalize.me)
QUESTIONS?
@Savas_Labssavaslabs.com