SlideShare ist ein Scribd-Unternehmen logo
1 von 35
Downloaden Sie, um offline zu lesen
Drupal 8: ThemingDrupal 8: Theming
Theming basics & TWIG for Drupal 8 modulesTheming basics & TWIG for Drupal 8 modules
Drupal Meetup StuttgartDrupal Meetup Stuttgart
07/02/2015
1. Introduction:1. Introduction:
Template EnginesTemplate Engines
Once upon a time, in a D7 module...Once upon a time, in a D7 module...
function mymodule_block_content() {
$output = '';
$users = mymodule_get_some_users();
$output = '<ul class="list" style="margin-top:10px">';
foreach ($users as $user) {
$output .= '<li class="item"><em>' . $user->name . '</em></li>';
}
$output .= '</ul>';
return $output
}
Markup and styling mixed with business logic
Hardly to be overwritten
We can do this a little bit better:We can do this a little bit better:
function mymodule_block_content() {
$users = mymodule_get_some_users();
$output = theme('mymodule_block', $users);
return $output
}
function mymodule_theme() {
return array(
'mymodule_block' => array(
'variables' => array('users' => NULL),
),
);
}
function theme_mymodule_block($variables) {
$users = $variables['users'];
$output = '<ul class="list" style="margin-top:10px">';
foreach ($users as $user) {
$output .= '<li class="item"><em>' . $user->name . '</em></li>';
}
$output .= '</ul>';
return $output
}
Can be overwritten, in template.php
(mytheme_mymodule_block)
We can do this much more better:We can do this much more better:
function mymodule_block_content() {
$users = mymodule_get_some_users();
$output = theme('mymodule_block', $users);
return $output
}
function mymodule_theme() {
return array(
'mymodule_block' => array(
'variables' => array('users' => NULL),
'template' => 'mymodule_block'
),
);
}
and in mymodule_block.tpl.php:
<ul class="list" style="margin-top:10px">
<?php foreach ($users as $user) : ?>
<li class="item"><em><?php print $user->name; ?></em></li>
<?php endforeach; ?>
</ul>
Template file can be copied and overwritten
And maybe use CSS, not markup or inline styles...
Voilá, a Template Engine!Voilá, a Template Engine!
(aka Theme Engine)
Drupal 4.7 / 5 / 6 / 7: PHPTemplate
Drupal 8: TWIG
Variables
What's wrong with PHPTemplate?What's wrong with PHPTemplate?
Drupal proprietary stuff
Requires PHP knowledge
Hard to read
Potentially insecure, e.g. printing malicous strings
Empowers business logic, e.g. DB queries
One typo can take your site offline
Sooo old-style
So Drupal 8 goesSo Drupal 8 goes
PHPTemplatePHPTemplate SmartySmarty PHPTALPHPTAL TWIGTWIG
2. Building a Drupal 82. Building a Drupal 8
ThemeTheme
Create a theme folder structureCreate a theme folder structure
- config
- schema
- mytheme.schema
- css
- base.css
- layout.css
- images
- js
- special.js
- libraries
- flexslider
- templates
- node.html.twig
- page.html.twig
logo.svg
screenshot.png
mytheme.breakpoints.yml
mytheme.info.yml
mytheme.libraries.yml
mytheme.theme
/themes/custom/mytheme/
Tell Drupal about your themeTell Drupal about your theme
name: 'My theme'
type: theme
description: 'Just a sample theme for Drupal 8.'
package: Custom
core: 8.x
libraries:
- mytheme/global
stylesheets-remove:
- core/assets/vendor/normalize-css/normalize.css
regions:
header: Header
content: Content
sidebar_first: 'Sidebar first'
footer: Footer
/themes/custom/mytheme/mytheme.info.yml
Tell Drupal about css/js libraries in your themeTell Drupal about css/js libraries in your theme
# This one is specified in mytheme.info.yml and loaded on all pages
global:
version: VERSION
css:
theme:
css/base.css {}
css/layout.css: {}
# Those are needed in some special places and loaded via #attached['library']
special:
version: VERSION
css:
theme:
css/special.css: {}
js:
js/special.js: {}
flexslider:
version: '2.5.0'
css:
theme:
libraries/flexslider/flexslider.css: {}
js:
libraries/flexslider/jquery.flexslider.js: {}
dependencies:
- core/jquery
/themes/custom/mytheme/mytheme.libraries.yml
Add preprocessing stuff, if neededAdd preprocessing stuff, if needed
<?php
/**
* Implements hook_element_info_alter().
*/
function mytheme_element_info_alter(&$type) {
// We require Modernizr for button styling.
if (isset($type['button'])) {
$type['button']['#attached']['library'][] = 'core/modernizr';
}
}
/themes/custom/mytheme/mytheme.theme
Formerly known as template.php!
Specify breakpoints, if neededSpecify breakpoints, if needed
mytheme.mobile:
label: mobile
mediaQuery: ''
weight: 2
multipliers:
- 1x
mytheme.narrow:
label: narrow
mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)'
weight: 1
multipliers:
- 1x
mytheme.wide:
label: wide
mediaQuery: 'all and (min-width: 851px)'
weight: 0
multipliers:
- 1x
/themes/custom/mytheme/mytheme.breakpoints.yml
Add the remaining stuff...Add the remaining stuff...
Templates
Scripts
Stylesheets
Images
Logo
Screenshot
...
3. Theming basics for3. Theming basics for
modulesmodules
Good News!Good News!
Not so many changesNot so many changes
Main difference: no more theme() functions!
Registering templatesRegistering templates
(no more theme functions!)
function mymodule_theme($existing, $type, $theme, $path) {
return array(
'mymodule_something' => array(
'variables' => array('something' => NULL, 'otherthing' => NULL),
),
);
}
hook_theme(), in your module file
Create a templateCreate a template
(*.html.twig, not *.tpl.php)
{% if something %}
<p>
{{ something }}
{{ otherthing }}
</p>
{% endif %}
mymodule-something.html.twig, in your module's template
folder (/modules/custom/mymodule/templates)
Use this somewhereUse this somewhere
(using render array, not theme())
...
$output = array(
'#theme' => 'mymodule_something',
'#something' => 'Something',
'#otherthing' => 'Otherthing',
);
...
Somewhere in your code (controller, plugin, ...)
Alter some stuffAlter some stuff
(mainly provided by other modules)
/**
* Implements hook_preprocess_HOOK().
*/
function yourmodule_preprocess_mymodule_something(&$variables) {
...
}
In your module file or theme
4. TWIG Basics:4. TWIG Basics:
SyntaxSyntax
Print / Output:
{{ some content }}{{ some content }}
Comments:
{# this is a comment #}{# this is a comment #}
Execute statements:
{% expression %}{% expression %}
5. TWIG Basics:5. TWIG Basics:
VariablesVariables
Accessing variablesAccessing variables
Simple variables (strings, numbers, booleans):
{{ foo }}
Complex variables (arrays / objects):
Objects & arrays:
{{ foo.bar }}
Alternative:
{{ attribute(foo, 'bar') }}
Only arrays:
{{ foo['bar'] }}
Example from views module:
{% if attributes -%}
<div{{ attributes }}>
{% endif %}
{% if title %}
<h3>{{ title }}</h3>
{% endif %}
<{{ list.type }}{{ list.attributes }}>
{% for row in rows %}
<li{{ row.attributes }}>{{ row.content }}</li>
{% endfor %}
</{{ list.type }}>
{% if attributes -%}
</div>
{% endif %}
Assigning values to variablesAssigning values to variables
{% set foo = 'bar' %}
{% set foo, bar = 'foo', 'bar' %}
{% set foo = [1, 2] %}
{% set foo = {'foo': 'bar'} %}
{% set foo = 'foo' ~ 'bar' %}
{% set foo %}
<div id="pagination">
...
</div>
{% endset %}
More examples:
http://twig.sensiolabs.org/doc/tags/set.html
6. TWIG Basics:6. TWIG Basics:
Control structuresControl structures
{% if ordered_list %}
<ol>
{% else %}
<ul>
{% endif %}
IF ... THEN ... ELSE ... ENDIF
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
FOR ... ENDFOR
{% include '@mytheme/parts/footer.html.twig' %}
INCLUDE -> fetch another template file
{% block footer %}
© Copyright 2015 drubb
{% endblock %}
BLOCK -> section that can be repeated, or overwritten by other template files
7. TWIG Basics:7. TWIG Basics:
Filters & FunctionsFilters & Functions
{{ title|upper|trim('.') }}
{% filter upper %}
This text becomes uppercase
{% endfilter %}
More examples: abs, first, last, length, lower, reverse, round,...)
http://twig.sensiolabs.org/doc/filters/index.html
General Twig filters
Drupal specific filters
Translate:
<a href="{{ url('<front>') }}" title="{{ 'Home'|t }}" rel="home" class="site-logo"></a>
Without:
{{ content|without('links') }}
Safe join:
{{ items|safe_join(", ") }}
More examples:
https://www.drupal.org/node/2357633
Filter: simple transformations on output
{{ max(1, 3, 2) }}
{{ random(['apple', 'orange', 'citrus']) }}
More examples:
http://twig.sensiolabs.org/doc/functions/index.html
General Twig functions
Drupal specific functions
Url:
<a href="{{ url('<front>') }}" title="{{ 'Home'|t }}" rel="home" class="site-logo"></a>
Path:
{{ path('entity.node.canonical', {'node': node->id()}) }}
More examples:
https://www.drupal.org/node/2486991
Function: takes arguments to compute output
8. TWIG Basics:8. TWIG Basics:
InheritanceInheritance
<header>
...
</header>
<article>
...
</article>
<footer>
{% block footer %}
<h4>This is the footer coming from Template 1!</h4>
{% endblock%}
</footer>
Second template (special.html.twig)
First template (default.html.twig)
{% extends "default.html.twig" %}
{% block footer %}
{{ parent() }}
<h5>But there's a second line now!</h5>
{% endblock%}
9. TWIG Basics:9. TWIG Basics:
ExampleExample
{#
/**
* @file
* Theme override to display a block.
*
* Available variables:
* - ...
*
* @see template_preprocess_block()
*/
#}
{%
set classes = [
'block',
'block-' ~ configuration.provider|clean_class,
]
%}
<div{{ attributes.addClass(classes) }}>
{{ title_prefix }}
{% if label %}
<h2{{ title_attributes }}>{{ label }}</h2>
{% endif %}
{{ title_suffix }}
{% block content %}
{{ content }}
{% endblock %}
</div>
block.html.twig
Thank You!Thank You!
http://slides.com/drubb
http://slideshare.net/drubb

Más contenido relacionado

Was ist angesagt?

Drupal 8 Sample Module
Drupal 8 Sample ModuleDrupal 8 Sample Module
Drupal 8 Sample Moduledrubb
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Formsdrubb
 
Drupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsDrupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsLuís Carneiro
 
Drupal Module Development
Drupal Module DevelopmentDrupal Module Development
Drupal Module Developmentipsitamishra
 
Creating Custom Drupal Modules
Creating Custom Drupal ModulesCreating Custom Drupal Modules
Creating Custom Drupal Modulestanoshimi
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5Jason Austin
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress WebsitesKyle Cearley
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentTammy Hart
 
XUL - Mozilla Application Framework
XUL - Mozilla Application FrameworkXUL - Mozilla Application Framework
XUL - Mozilla Application FrameworkUldis Bojars
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comtutorialsruby
 
Presentation drupalaton august 2013
Presentation drupalaton august 2013Presentation drupalaton august 2013
Presentation drupalaton august 2013Bram Goffings
 

Was ist angesagt? (17)

Drupal 8 Sample Module
Drupal 8 Sample ModuleDrupal 8 Sample Module
Drupal 8 Sample Module
 
Drupal 8: Forms
Drupal 8: FormsDrupal 8: Forms
Drupal 8: Forms
 
Design to Theme @ CMSExpo
Design to Theme @ CMSExpoDesign to Theme @ CMSExpo
Design to Theme @ CMSExpo
 
Drupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First StepsDrupal Camp Porto - Developing with Drupal: First Steps
Drupal Camp Porto - Developing with Drupal: First Steps
 
RuHL
RuHLRuHL
RuHL
 
Drupal Front End PHP
Drupal Front End PHPDrupal Front End PHP
Drupal Front End PHP
 
Oop's in php
Oop's in php Oop's in php
Oop's in php
 
Drupal Module Development
Drupal Module DevelopmentDrupal Module Development
Drupal Module Development
 
Creating Custom Drupal Modules
Creating Custom Drupal ModulesCreating Custom Drupal Modules
Creating Custom Drupal Modules
 
Object Oriented PHP5
Object Oriented PHP5Object Oriented PHP5
Object Oriented PHP5
 
Drupal 8 Hooks
Drupal 8 HooksDrupal 8 Hooks
Drupal 8 Hooks
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress Websites
 
Laying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme developmentLaying the proper foundation for plugin and theme development
Laying the proper foundation for plugin and theme development
 
Php go vrooom!
Php go vrooom!Php go vrooom!
Php go vrooom!
 
XUL - Mozilla Application Framework
XUL - Mozilla Application FrameworkXUL - Mozilla Application Framework
XUL - Mozilla Application Framework
 
oop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.comoop_in_php_tutorial_for_killerphp.com
oop_in_php_tutorial_for_killerphp.com
 
Presentation drupalaton august 2013
Presentation drupalaton august 2013Presentation drupalaton august 2013
Presentation drupalaton august 2013
 

Andere mochten auch

Drupal 8: TWIG Template Engine
Drupal 8:  TWIG Template EngineDrupal 8:  TWIG Template Engine
Drupal 8: TWIG Template Enginedrubb
 
Making Sense of Twig
Making Sense of TwigMaking Sense of Twig
Making Sense of TwigBrandon Kelly
 
Blocks & layouts szeged
Blocks & layouts szegedBlocks & layouts szeged
Blocks & layouts szegeddasjo
 
Twig for Drupal @ Frontendunited Amsterdam 2012
Twig for Drupal @ Frontendunited Amsterdam 2012Twig for Drupal @ Frontendunited Amsterdam 2012
Twig for Drupal @ Frontendunited Amsterdam 2012Rene Bakx
 
Things Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & DrupalThings Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & Drupallucenerevolution
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Michael Miles
 
Single Page Applications in Drupal
Single Page Applications in DrupalSingle Page Applications in Drupal
Single Page Applications in DrupalChris Tankersley
 
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015Dropsolid
 
Multilingual Improvements for Drupal 8
Multilingual Improvements for Drupal 8Multilingual Improvements for Drupal 8
Multilingual Improvements for Drupal 8Acquia
 
Entities, Bundles, and Fields: You need to understand this!
Entities, Bundles, and Fields: You need to understand this!Entities, Bundles, and Fields: You need to understand this!
Entities, Bundles, and Fields: You need to understand this!tedbow
 
Drupal 101: Tips and Tricks for Troubleshooting Drupal
Drupal 101: Tips and Tricks for Troubleshooting DrupalDrupal 101: Tips and Tricks for Troubleshooting Drupal
Drupal 101: Tips and Tricks for Troubleshooting DrupalAcquia
 
Intro to Apache Solr for Drupal
Intro to Apache Solr for DrupalIntro to Apache Solr for Drupal
Intro to Apache Solr for DrupalChris Caple
 
Everything You Need to Know About the Top Changes in Drupal 8
Everything You Need to Know About the Top Changes in Drupal 8Everything You Need to Know About the Top Changes in Drupal 8
Everything You Need to Know About the Top Changes in Drupal 8Acquia
 
Drupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + DockerDrupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + DockerRoald Umandal
 
Successes and Challenges When Managing Large Scale Drupal Projects
Successes and Challenges When Managing Large Scale Drupal ProjectsSuccesses and Challenges When Managing Large Scale Drupal Projects
Successes and Challenges When Managing Large Scale Drupal ProjectsAcquia
 
Speedrun: Build a Website with Panels, Media, and More in 45 Minutes
Speedrun: Build a Website with Panels, Media, and More in 45 MinutesSpeedrun: Build a Website with Panels, Media, and More in 45 Minutes
Speedrun: Build a Website with Panels, Media, and More in 45 MinutesAcquia
 
Webform and Drupal 8
Webform and Drupal 8Webform and Drupal 8
Webform and Drupal 8Philip Norton
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Brian Ward
 
Drupal 8 Quick Start: An Overview of Lightning
Drupal 8 Quick Start: An Overview of LightningDrupal 8 Quick Start: An Overview of Lightning
Drupal 8 Quick Start: An Overview of LightningAcquia
 

Andere mochten auch (20)

Drupal 8: TWIG Template Engine
Drupal 8:  TWIG Template EngineDrupal 8:  TWIG Template Engine
Drupal 8: TWIG Template Engine
 
Making Sense of Twig
Making Sense of TwigMaking Sense of Twig
Making Sense of Twig
 
Blocks & layouts szeged
Blocks & layouts szegedBlocks & layouts szeged
Blocks & layouts szeged
 
Twig for Drupal @ Frontendunited Amsterdam 2012
Twig for Drupal @ Frontendunited Amsterdam 2012Twig for Drupal @ Frontendunited Amsterdam 2012
Twig for Drupal @ Frontendunited Amsterdam 2012
 
Things Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & DrupalThings Made Easy: One Click CMS Integration with Solr & Drupal
Things Made Easy: One Click CMS Integration with Solr & Drupal
 
Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8Demystifying AJAX Callback Commands in Drupal 8
Demystifying AJAX Callback Commands in Drupal 8
 
Single Page Applications in Drupal
Single Page Applications in DrupalSingle Page Applications in Drupal
Single Page Applications in Drupal
 
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
State of Search, Solr and Facets in Drupal 8 - Drupalcamp Belgium 2015
 
Multilingual Improvements for Drupal 8
Multilingual Improvements for Drupal 8Multilingual Improvements for Drupal 8
Multilingual Improvements for Drupal 8
 
Designing with Drupal 8
Designing with Drupal 8Designing with Drupal 8
Designing with Drupal 8
 
Entities, Bundles, and Fields: You need to understand this!
Entities, Bundles, and Fields: You need to understand this!Entities, Bundles, and Fields: You need to understand this!
Entities, Bundles, and Fields: You need to understand this!
 
Drupal 101: Tips and Tricks for Troubleshooting Drupal
Drupal 101: Tips and Tricks for Troubleshooting DrupalDrupal 101: Tips and Tricks for Troubleshooting Drupal
Drupal 101: Tips and Tricks for Troubleshooting Drupal
 
Intro to Apache Solr for Drupal
Intro to Apache Solr for DrupalIntro to Apache Solr for Drupal
Intro to Apache Solr for Drupal
 
Everything You Need to Know About the Top Changes in Drupal 8
Everything You Need to Know About the Top Changes in Drupal 8Everything You Need to Know About the Top Changes in Drupal 8
Everything You Need to Know About the Top Changes in Drupal 8
 
Drupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + DockerDrupal 8 + Elasticsearch + Docker
Drupal 8 + Elasticsearch + Docker
 
Successes and Challenges When Managing Large Scale Drupal Projects
Successes and Challenges When Managing Large Scale Drupal ProjectsSuccesses and Challenges When Managing Large Scale Drupal Projects
Successes and Challenges When Managing Large Scale Drupal Projects
 
Speedrun: Build a Website with Panels, Media, and More in 45 Minutes
Speedrun: Build a Website with Panels, Media, and More in 45 MinutesSpeedrun: Build a Website with Panels, Media, and More in 45 Minutes
Speedrun: Build a Website with Panels, Media, and More in 45 Minutes
 
Webform and Drupal 8
Webform and Drupal 8Webform and Drupal 8
Webform and Drupal 8
 
Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8Using VueJS in front of Drupal 8
Using VueJS in front of Drupal 8
 
Drupal 8 Quick Start: An Overview of Lightning
Drupal 8 Quick Start: An Overview of LightningDrupal 8 Quick Start: An Overview of Lightning
Drupal 8 Quick Start: An Overview of Lightning
 

Ähnlich wie Drupal 8: Theming

Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Siva Epari
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practicesmanugoel2003
 
D7 theming what's new - London
D7 theming what's new - LondonD7 theming what's new - London
D7 theming what's new - LondonMarek Sotak
 
Drupal 8 Theme System: The Backend of Frontend
Drupal 8 Theme System: The Backend of FrontendDrupal 8 Theme System: The Backend of Frontend
Drupal 8 Theme System: The Backend of FrontendAcquia
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesShabir Ahmad
 
Drupal 8 版型開發變革
Drupal 8 版型開發變革Drupal 8 版型開發變革
Drupal 8 版型開發變革Chris Wu
 
Introduction And Basics of Modules in Drupal 7
Introduction And Basics of Modules in Drupal 7 Introduction And Basics of Modules in Drupal 7
Introduction And Basics of Modules in Drupal 7 Dhinakaran Mani
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindValentine Matsveiko
 
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...LEDC 2016
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8Allie Jones
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes ramakesavan
 
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008Mir Nazim
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Ted Kulp
 
The Flexibility of Drupal 8 | DCNLights 2017
The Flexibility of Drupal 8 | DCNLights 2017The Flexibility of Drupal 8 | DCNLights 2017
The Flexibility of Drupal 8 | DCNLights 2017Michael Miles
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Maurizio Pelizzone
 

Ähnlich wie Drupal 8: Theming (20)

Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010Drupal Module Development - OSI Days 2010
Drupal Module Development - OSI Days 2010
 
Drupal Best Practices
Drupal Best PracticesDrupal Best Practices
Drupal Best Practices
 
Drupal theming
Drupal themingDrupal theming
Drupal theming
 
D7 theming what's new - London
D7 theming what's new - LondonD7 theming what's new - London
D7 theming what's new - London
 
Drupal 8 Theme System: The Backend of Frontend
Drupal 8 Theme System: The Backend of FrontendDrupal 8 Theme System: The Backend of Frontend
Drupal 8 Theme System: The Backend of Frontend
 
Drupal 8 - Core and API Changes
Drupal 8 - Core and API ChangesDrupal 8 - Core and API Changes
Drupal 8 - Core and API Changes
 
Django design-patterns
Django design-patternsDjango design-patterns
Django design-patterns
 
Drupal 8 版型開發變革
Drupal 8 版型開發變革Drupal 8 版型開發變革
Drupal 8 版型開發變革
 
Introduction And Basics of Modules in Drupal 7
Introduction And Basics of Modules in Drupal 7 Introduction And Basics of Modules in Drupal 7
Introduction And Basics of Modules in Drupal 7
 
Migrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mindMigrate yourself. code -> module -> mind
Migrate yourself. code -> module -> mind
 
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
Валентин Мацвейко та Владислав Мойсеєнко — D8: Migrate Yourself: code->module...
 
Debugging in drupal 8
Debugging in drupal 8Debugging in drupal 8
Debugging in drupal 8
 
Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes Drupal 7 Theming - Behind the scenes
Drupal 7 Theming - Behind the scenes
 
PHP MVC
PHP MVCPHP MVC
PHP MVC
 
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
Best Practices For Drupal Developers By Mir Nazim @ Drupal Camp India 2008
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 
The Flexibility of Drupal 8 | DCNLights 2017
The Flexibility of Drupal 8 | DCNLights 2017The Flexibility of Drupal 8 | DCNLights 2017
The Flexibility of Drupal 8 | DCNLights 2017
 
Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress Use Symfony2 components inside WordPress
Use Symfony2 components inside WordPress
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 

Mehr von drubb

Barrierefreie Webseiten
Barrierefreie WebseitenBarrierefreie Webseiten
Barrierefreie Webseitendrubb
 
Drupal 9 Entity Bundle Classes
Drupal 9 Entity Bundle ClassesDrupal 9 Entity Bundle Classes
Drupal 9 Entity Bundle Classesdrubb
 
Drupal 8 Dependency Injection Using Traits
Drupal 8 Dependency Injection Using TraitsDrupal 8 Dependency Injection Using Traits
Drupal 8 Dependency Injection Using Traitsdrubb
 
Closing the Drupal Hosting Gap - A Review of Wodby
Closing the Drupal Hosting Gap - A Review of WodbyClosing the Drupal Hosting Gap - A Review of Wodby
Closing the Drupal Hosting Gap - A Review of Wodbydrubb
 
Composer & Drupal
Composer & DrupalComposer & Drupal
Composer & Drupaldrubb
 
Headless Drupal
Headless DrupalHeadless Drupal
Headless Drupaldrubb
 
Spamschutzverfahren für Drupal
Spamschutzverfahren für DrupalSpamschutzverfahren für Drupal
Spamschutzverfahren für Drupaldrubb
 
Drupal 8: Neuerungen im Überblick
Drupal 8:  Neuerungen im ÜberblickDrupal 8:  Neuerungen im Überblick
Drupal 8: Neuerungen im Überblickdrubb
 
Drupal Entities
Drupal EntitiesDrupal Entities
Drupal Entitiesdrubb
 

Mehr von drubb (9)

Barrierefreie Webseiten
Barrierefreie WebseitenBarrierefreie Webseiten
Barrierefreie Webseiten
 
Drupal 9 Entity Bundle Classes
Drupal 9 Entity Bundle ClassesDrupal 9 Entity Bundle Classes
Drupal 9 Entity Bundle Classes
 
Drupal 8 Dependency Injection Using Traits
Drupal 8 Dependency Injection Using TraitsDrupal 8 Dependency Injection Using Traits
Drupal 8 Dependency Injection Using Traits
 
Closing the Drupal Hosting Gap - A Review of Wodby
Closing the Drupal Hosting Gap - A Review of WodbyClosing the Drupal Hosting Gap - A Review of Wodby
Closing the Drupal Hosting Gap - A Review of Wodby
 
Composer & Drupal
Composer & DrupalComposer & Drupal
Composer & Drupal
 
Headless Drupal
Headless DrupalHeadless Drupal
Headless Drupal
 
Spamschutzverfahren für Drupal
Spamschutzverfahren für DrupalSpamschutzverfahren für Drupal
Spamschutzverfahren für Drupal
 
Drupal 8: Neuerungen im Überblick
Drupal 8:  Neuerungen im ÜberblickDrupal 8:  Neuerungen im Überblick
Drupal 8: Neuerungen im Überblick
 
Drupal Entities
Drupal EntitiesDrupal Entities
Drupal Entities
 

Drupal 8: Theming

  • 1. Drupal 8: ThemingDrupal 8: Theming Theming basics & TWIG for Drupal 8 modulesTheming basics & TWIG for Drupal 8 modules Drupal Meetup StuttgartDrupal Meetup Stuttgart 07/02/2015
  • 3. Once upon a time, in a D7 module...Once upon a time, in a D7 module... function mymodule_block_content() { $output = ''; $users = mymodule_get_some_users(); $output = '<ul class="list" style="margin-top:10px">'; foreach ($users as $user) { $output .= '<li class="item"><em>' . $user->name . '</em></li>'; } $output .= '</ul>'; return $output } Markup and styling mixed with business logic Hardly to be overwritten
  • 4. We can do this a little bit better:We can do this a little bit better: function mymodule_block_content() { $users = mymodule_get_some_users(); $output = theme('mymodule_block', $users); return $output } function mymodule_theme() { return array( 'mymodule_block' => array( 'variables' => array('users' => NULL), ), ); } function theme_mymodule_block($variables) { $users = $variables['users']; $output = '<ul class="list" style="margin-top:10px">'; foreach ($users as $user) { $output .= '<li class="item"><em>' . $user->name . '</em></li>'; } $output .= '</ul>'; return $output } Can be overwritten, in template.php (mytheme_mymodule_block)
  • 5. We can do this much more better:We can do this much more better: function mymodule_block_content() { $users = mymodule_get_some_users(); $output = theme('mymodule_block', $users); return $output } function mymodule_theme() { return array( 'mymodule_block' => array( 'variables' => array('users' => NULL), 'template' => 'mymodule_block' ), ); } and in mymodule_block.tpl.php: <ul class="list" style="margin-top:10px"> <?php foreach ($users as $user) : ?> <li class="item"><em><?php print $user->name; ?></em></li> <?php endforeach; ?> </ul> Template file can be copied and overwritten And maybe use CSS, not markup or inline styles...
  • 6. Voilá, a Template Engine!Voilá, a Template Engine! (aka Theme Engine) Drupal 4.7 / 5 / 6 / 7: PHPTemplate Drupal 8: TWIG Variables
  • 7. What's wrong with PHPTemplate?What's wrong with PHPTemplate? Drupal proprietary stuff Requires PHP knowledge Hard to read Potentially insecure, e.g. printing malicous strings Empowers business logic, e.g. DB queries One typo can take your site offline Sooo old-style So Drupal 8 goesSo Drupal 8 goes PHPTemplatePHPTemplate SmartySmarty PHPTALPHPTAL TWIGTWIG
  • 8. 2. Building a Drupal 82. Building a Drupal 8 ThemeTheme
  • 9. Create a theme folder structureCreate a theme folder structure - config - schema - mytheme.schema - css - base.css - layout.css - images - js - special.js - libraries - flexslider - templates - node.html.twig - page.html.twig logo.svg screenshot.png mytheme.breakpoints.yml mytheme.info.yml mytheme.libraries.yml mytheme.theme /themes/custom/mytheme/
  • 10. Tell Drupal about your themeTell Drupal about your theme name: 'My theme' type: theme description: 'Just a sample theme for Drupal 8.' package: Custom core: 8.x libraries: - mytheme/global stylesheets-remove: - core/assets/vendor/normalize-css/normalize.css regions: header: Header content: Content sidebar_first: 'Sidebar first' footer: Footer /themes/custom/mytheme/mytheme.info.yml
  • 11. Tell Drupal about css/js libraries in your themeTell Drupal about css/js libraries in your theme # This one is specified in mytheme.info.yml and loaded on all pages global: version: VERSION css: theme: css/base.css {} css/layout.css: {} # Those are needed in some special places and loaded via #attached['library'] special: version: VERSION css: theme: css/special.css: {} js: js/special.js: {} flexslider: version: '2.5.0' css: theme: libraries/flexslider/flexslider.css: {} js: libraries/flexslider/jquery.flexslider.js: {} dependencies: - core/jquery /themes/custom/mytheme/mytheme.libraries.yml
  • 12. Add preprocessing stuff, if neededAdd preprocessing stuff, if needed <?php /** * Implements hook_element_info_alter(). */ function mytheme_element_info_alter(&$type) { // We require Modernizr for button styling. if (isset($type['button'])) { $type['button']['#attached']['library'][] = 'core/modernizr'; } } /themes/custom/mytheme/mytheme.theme Formerly known as template.php!
  • 13. Specify breakpoints, if neededSpecify breakpoints, if needed mytheme.mobile: label: mobile mediaQuery: '' weight: 2 multipliers: - 1x mytheme.narrow: label: narrow mediaQuery: 'all and (min-width: 560px) and (max-width: 850px)' weight: 1 multipliers: - 1x mytheme.wide: label: wide mediaQuery: 'all and (min-width: 851px)' weight: 0 multipliers: - 1x /themes/custom/mytheme/mytheme.breakpoints.yml
  • 14. Add the remaining stuff...Add the remaining stuff... Templates Scripts Stylesheets Images Logo Screenshot ...
  • 15. 3. Theming basics for3. Theming basics for modulesmodules
  • 16. Good News!Good News! Not so many changesNot so many changes Main difference: no more theme() functions!
  • 17. Registering templatesRegistering templates (no more theme functions!) function mymodule_theme($existing, $type, $theme, $path) { return array( 'mymodule_something' => array( 'variables' => array('something' => NULL, 'otherthing' => NULL), ), ); } hook_theme(), in your module file
  • 18. Create a templateCreate a template (*.html.twig, not *.tpl.php) {% if something %} <p> {{ something }} {{ otherthing }} </p> {% endif %} mymodule-something.html.twig, in your module's template folder (/modules/custom/mymodule/templates)
  • 19. Use this somewhereUse this somewhere (using render array, not theme()) ... $output = array( '#theme' => 'mymodule_something', '#something' => 'Something', '#otherthing' => 'Otherthing', ); ... Somewhere in your code (controller, plugin, ...)
  • 20. Alter some stuffAlter some stuff (mainly provided by other modules) /** * Implements hook_preprocess_HOOK(). */ function yourmodule_preprocess_mymodule_something(&$variables) { ... } In your module file or theme
  • 21. 4. TWIG Basics:4. TWIG Basics: SyntaxSyntax
  • 22. Print / Output: {{ some content }}{{ some content }} Comments: {# this is a comment #}{# this is a comment #} Execute statements: {% expression %}{% expression %}
  • 23. 5. TWIG Basics:5. TWIG Basics: VariablesVariables
  • 24. Accessing variablesAccessing variables Simple variables (strings, numbers, booleans): {{ foo }} Complex variables (arrays / objects): Objects & arrays: {{ foo.bar }} Alternative: {{ attribute(foo, 'bar') }} Only arrays: {{ foo['bar'] }} Example from views module: {% if attributes -%} <div{{ attributes }}> {% endif %} {% if title %} <h3>{{ title }}</h3> {% endif %} <{{ list.type }}{{ list.attributes }}> {% for row in rows %} <li{{ row.attributes }}>{{ row.content }}</li> {% endfor %} </{{ list.type }}> {% if attributes -%} </div> {% endif %}
  • 25. Assigning values to variablesAssigning values to variables {% set foo = 'bar' %} {% set foo, bar = 'foo', 'bar' %} {% set foo = [1, 2] %} {% set foo = {'foo': 'bar'} %} {% set foo = 'foo' ~ 'bar' %} {% set foo %} <div id="pagination"> ... </div> {% endset %} More examples: http://twig.sensiolabs.org/doc/tags/set.html
  • 26. 6. TWIG Basics:6. TWIG Basics: Control structuresControl structures
  • 27. {% if ordered_list %} <ol> {% else %} <ul> {% endif %} IF ... THEN ... ELSE ... ENDIF {% for item in items %} <li>{{ item }}</li> {% endfor %} FOR ... ENDFOR {% include '@mytheme/parts/footer.html.twig' %} INCLUDE -> fetch another template file {% block footer %} © Copyright 2015 drubb {% endblock %} BLOCK -> section that can be repeated, or overwritten by other template files
  • 28. 7. TWIG Basics:7. TWIG Basics: Filters & FunctionsFilters & Functions
  • 29. {{ title|upper|trim('.') }} {% filter upper %} This text becomes uppercase {% endfilter %} More examples: abs, first, last, length, lower, reverse, round,...) http://twig.sensiolabs.org/doc/filters/index.html General Twig filters Drupal specific filters Translate: <a href="{{ url('<front>') }}" title="{{ 'Home'|t }}" rel="home" class="site-logo"></a> Without: {{ content|without('links') }} Safe join: {{ items|safe_join(", ") }} More examples: https://www.drupal.org/node/2357633 Filter: simple transformations on output
  • 30. {{ max(1, 3, 2) }} {{ random(['apple', 'orange', 'citrus']) }} More examples: http://twig.sensiolabs.org/doc/functions/index.html General Twig functions Drupal specific functions Url: <a href="{{ url('<front>') }}" title="{{ 'Home'|t }}" rel="home" class="site-logo"></a> Path: {{ path('entity.node.canonical', {'node': node->id()}) }} More examples: https://www.drupal.org/node/2486991 Function: takes arguments to compute output
  • 31. 8. TWIG Basics:8. TWIG Basics: InheritanceInheritance
  • 32. <header> ... </header> <article> ... </article> <footer> {% block footer %} <h4>This is the footer coming from Template 1!</h4> {% endblock%} </footer> Second template (special.html.twig) First template (default.html.twig) {% extends "default.html.twig" %} {% block footer %} {{ parent() }} <h5>But there's a second line now!</h5> {% endblock%}
  • 33. 9. TWIG Basics:9. TWIG Basics: ExampleExample
  • 34. {# /** * @file * Theme override to display a block. * * Available variables: * - ... * * @see template_preprocess_block() */ #} {% set classes = [ 'block', 'block-' ~ configuration.provider|clean_class, ] %} <div{{ attributes.addClass(classes) }}> {{ title_prefix }} {% if label %} <h2{{ title_attributes }}>{{ label }}</h2> {% endif %} {{ title_suffix }} {% block content %} {{ content }} {% endblock %} </div> block.html.twig