Khanh Hoang - Kenn
Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.
Welcome to the 5th installment of an 8-part blog series we're calling "The Ultimate Guide to Drupal 8." Whether you're a site builder, module or theme developer, or simply an end-user of a Drupal website, Drupal 8 has tons in store for you! This blog series will attempt to enumerate the major changes in Drupal 8.
>> Hướng dẫn chính cho Drupal 8: Episode 1 - Authoring Experience Improvements
>> Hướng dẫn chính cho Drupal 8: Episode 2 - Mobile Improvements
>> Hướng dẫn chính cho Drupal 8: Episode 3 - Site Builder Improvements
>> Hướng dẫn chính cho Drupal 8: Episode 4 - Multilingual Improvements
Please note that since Drupal 8 is still under active development, some of the details below may change prior to its release. Still, since Drupal 8 is now feature-frozen, hopefully most info should remain relevant. Where applicable, Drupal 7 contrib equivalents of Drupal 8 features will be noted.
All of Drupal's output has been converted to use semantic HTML5 markup, as opposed to XHTML in Drupal 7. This means you'll find tags such as <nav>
, <header>
, <main>
, and <section>
in Drupal's default templates, as part of an overarching effort to clean up Drupal's default markup.
HTML5 also brings new form input types such as date
, tel
, and email
, which can provide targeted user interfaces on mobile devices (for example, only showing the number pad on phone numbers) to help streamline data entry. Drupal's Form API provides these additional types so you can easily create these new types of fields. The Drupal 7 equivalent can be found in the Elements module.
Additionally, you'll also find HTML5/CSS3 replacements for several things that previously needed custom workarounds, including resizing on text areas and first/last/odd/even classes, replaced by CSS3 pseudo selectors, and collapsible fieldsets largely replaced by the <details>
element.
While Drupal has shipped with jQuery since version 5, and jQuery UI since Drupal 7, Drupal 8 brings with it an expanded array of front-end libraries. For example, Modernizr (which makes it easy to detect if a browser supports touch, or HTML5/CSS3 features), Underscore.js (a lightweight JS helper library), and Backbone.js (a Model-View-Controller JavaScript framework). Together, these additional libraries allow for creating mobile-friendly, rich front-end applications in Drupal and they're used by several of the Authoring Experience and Mobile feature improvements to Drupal 8.
In a great boon for search-engine optimization, Drupal 8's RDFa module now outputs schema.org markup. This makes it much easier for search engines such as Google, Yahoo!, Bing, and Yandex to extract data about what's being presented on a given page in order to add meaning behind it, such as who the author of a given piece of content is.
Drupal 8 has expanded on Drupal 7's existing stellar accessibility record with even more improvements. Drupal 8 makes extensive use of WAI-ARIA attributes to provide meaning on rich front-end applications such as the in-place editor and responsive toolbar. On the back-end, Drupal 8 also provides a variety of new Accessibility tools for JavaScript, which allow module developers to easily create accessible applications. There is also an ongoing effort to provide automated testing for accessibility features via the Quail library.
This video, extracted from Dries's DrupalCon Prague Keynote, demonstrates how these new accessibility features appear to users of assistive technology.
Drupal 8 introduces Twig, which takes the place of the PHPTemplate-based theme system in Drupal 7 and below. Twig, like many similar popular templating engines from other projects, allows designers with HTML/CSS knowledge to modify markup without needing to be an expert in PHP. For example, instead of needing to understand the syntax differences between deeply-nested arrays vs. objects and when to use each, a simple {{ foo.bar }}
statement does the trick. Simple conditional and looping logic can be contained in {% ... %}
tags,
The following is an excerpt from page.html.twig (the equivalent of page.tpl.php in Drupal 7), showing off both some Twig features and some HTML5 tags and native ARIA support as well:
<?php <main role="main"> <a id="main-content"></a>{# link is in html.html.twig #} <div class="layout-content"> {{ page.highlighted }} {{ title_prefix }} {% if title %} <h1>{{ title }}</h1> {% endif %} {{ title_suffix }} {{ tabs }} {% if action_links %} <nav class="action-links">{{ action_links }}</nav> {% endif %} {{ page.content }} {{ feed_icons }} </div>{# /.layout-content #} {% if page.sidebar_first %} <aside class="layout-sidebar-first" role="complementary"> {{ page.sidebar_first }} </aside> {% endif %} {% if page.sidebar_second %} <aside class="layout-sidebar-second" role="complementary"> {{ page.sidebar_second }} </aside> {% endif %} </main> ?>
How do you provide those variables if you can no longer use PHP in templates directly? With THEME_preprocess_HOOK()
functions, same as you've always done (though they now go in a file called THEME.theme
instead of template.php
). Twig effectively *forces* a separation of presentation and "business" logic, which should make for far more maintainable and secure themes (and these will become even more secure once Make Twig auto-escape variables makes it in).
One other nice tidbit from Twig is if you turn on "debug" mode with a $settings['twig_debug'] = TRUE;
in your settings.php
file, helpful code comments will be displayed throughout Drupal's generated markup to inform you where to find the template for the markup you're trying to change, and which particular "theme suggestion" is being used to generate the markup. For example:
<?php <div class="content"> <!-- THEME DEBUG --> <!-- CALL: _theme('node') --> <!-- FILE NAME SUGGESTIONS: * node--1--full.html.twig * node--1.html.twig * node--article--full.html.twig * node--article.html.twig * node--full.html.twig x node.html.twig --> <!-- BEGIN OUTPUT from 'core/themes/bartik/templates/node.html.twig' --> <article class="node node--type-article node--promoted node--view-mode-full contextual-region clearfix quickedit-processed" data-history-node-id="1" data-quickedit-entity-id="node/1" role="article" about="/node/1" typeof="schema:Article" data-quickedit-entity-instance-id="0"> ... </article> <!-- END OUTPUT from 'core/themes/bartik/templates/node.html.twig' --> </div> ?>
It's a bit like having the fabulous Theme developer module baked into core!
Acquia's own llama-loving performance guru Wim Leers posited that the best way to make the Internet as a whole faster is to make the leading CMSes fast by default; meaning, enable their high-performance settings out of the box, rather than require users to be savvy enough to find them in all of their various locations. And in Drupal 8, that's exactly what we've done. You'll notice that Drupal 8 ships with features such as CSS and JS aggregation turned on out of the box for a much faster default installation. Huzzah!
What this means to you as a front-end developer though is that by default, Drupal is not immediately in a good place to start theming, unless you manually go around and start turning off those performance settings one by one (even hacking core's CSS directly will show absolutely no changes). Fortunately, Drupal 8 ships with a sites/example.settings.local.php
file, for exactly this purpose. It hard-codes the performance settings to off, so is extremely useful in a development environment. Simply copy it and rename it as sites/default/settings.local.php
and uncomment the following lines in sites/default/settings.php
:
<?php # if (file_exists(__DIR__ . '/settings.local.php')) { # include __DIR__ . '/settings.local.php'; # } ?>
And speaking of un-commenting lines, your new settings.local.php
file also contains some disabled-by-default settings about Twig specifically, e.g. to turn on debug mode and turn off caching there as well. Uncommenting these settings will definitely make your dev site slower, but will also make theming much easier, because you'll be able to see the results of your changes to Twig templates immediately, without having to clear the cache.
In other front-end performance-related news, while Drupal 8 will still ship with the latest versions of jQuery and jQuery UI, there's actually been a lot of movement away from using libraries like this for run-of-the-mill JavaScript, in order to keep front-end performance as quick as possible, especially important for mobile devices. The default install of Drupal 8 actually loads zero JavaScript for anonymous users!
So all around, while there is still more work to be done on further performance optimizations, once it ships, Drupal 8 should provide a much faster front-end experience for site visitors. Hooray!
Drupal 8 ships with several new UI elements that you can make use of in your own admin screens, including modal dialogs and drop buttons, which were part of the Chaos tool suite (ctools) module in Drupal 7 and below. Drupal 8 also introduces the concept of "button types" of "primary" (the default form action; in Seven theme styled as blue) and "danger" (styled as red links) to help users quickly make correct choices when confronted with multiple options on a form.
As mentioned in the Mobile Improvements article, Drupal 8 ships with numerous new responsive features, including responsive themes, toolbar, images, and tables.
To support these features, themes can now declare Breakpoints (the height, width, and resolution at which a design changes to meet shifting browsers and devices) which can be used by these various responsive features. (However, note that Move breakpoint settings to theme and module *.info.yml files is a patch actively being worked on that proposes changing the exact implementation.)
It's also looking like Drupal 8 will ship with support for the new <picture> element, which will start being supported in browsers this fall. This will make for a significant front-end performance improvement, particularly on mobile devices, as it allows delivering smaller images (typically the heaviest part of any page load) for smaller screens, saving data. Yeehaw!! (Thanks to Marc Drummond for this paragraph. :))
Also on the performance front... In the past, if you wanted to add CSS or JS to a particular page, you'd use the drupal_add_css()
and drupal_add_js()
functions, respectively. Not anymore! You now insert any JS/CSS assets in the #attached
property of a render array. For example:
seven.theme
function seven_form_node_form_alter(&$form, &$form_state) { ... $form['#attached'] = array( 'css' => array(drupal_get_path('module', 'node') . '/css/node.module.css'), ); ... }
While this will work okay for one-off assets that don't have any dependencies, the more common and recommended approach is to register one or more CSS/JS assets (along with their dependencies) as a library in your MODULE/THEME.libraries.yml
, and then add a reference to said library in the #attached
property. For example:
seven.libraries.yml
maintenance-page: version: VERSION js: js/mobile.install.js: {} css: theme: maintenance-page.css: {} dependencies: - system/maintenance install-page: version: VERSION js: js/mobile.install.js: {} css: theme: install-page.css: {} dependencies: - system/maintenance drupal.nav-tabs: version: VERSION js: js/nav-tabs.js: {} dependencies: - core/matchmedia - core/jquery - core/drupal - core/jquery.once - core/jquery.intrinsic
seven.theme
<?php function seven_preprocess_install_page(&$variables) { // ... $libraries = array( '#attached' => array( 'library' => array( 'seven/maintenance-page', 'seven/install-page', ), ), ); drupal_render($libraries); } ?>
While this isn't quite as convenient as a quick in-line call to drupal_add_FOO()
, it does mean that these assets are now cacheable for improved performance, and easily re-usable among different parts of the code base.
And finally, to end on a bit of a melancholy note, the last big improvement for front-end developers is that at last, in a move applauded by web designers everywhere, Drupal 8 core has officially dropped support for IE 6, 7 and 8, enabling the use of jQuery 2.0 and other code that assumes modern HTML5/CSS3 browser support. (And note that there's also talk of dropping support for Android 2.3 and below for the same reason.)
As a parting gift, html5shiv (an HTML5 "polyfill" for less capable browsers) is included in D8 core so at least IEs 8 and below don't completely crap out, and there's the IE8 project in contrib to allow those who absolutely must have IE8-compatible versions of core front-end features.
For the rest of us though, we're looking forward to snappier front-end code that doesn't have to worry about limitations in 5+ year old browsers. :) Hooray!
Because Drupal 8 is still under active development, and not yet in beta, some aspects of the APIs are not nailed down yet (and markup doesn't freeze until RC). Here are a few of the big remaining front-end efforts out there, which could use code and reviews:
<div>
s and whatnot) from Drupal's markup. This movement just got some fresh interest poured into it at DrupalCon Austin, resulting in a proposal to strip-down all of Drupal core's default markup to remove any extraneous cruft, and provide a base theme with helpful classes/wrappers for equivalence with the current status quo. Interesting times.