Home / Ultimate Guide to Drupal 8: Episode 5 - Front-End Developer Improvements

Ultimate Guide to Drupal 8: Episode 5 - Front-End Developer Improvements

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.

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.

HTML5

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.

Three iPhones showing a date, phone, and email field, respectively.

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.

New front-end libraries and helpers

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.

Native Schema.org output

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.

Side-by-side comparison of a Drupal node with what is extracted from schema.org tools

Even more improved Accessibility

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.

New theme system: Twig

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!

"Fast by default"

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!

New UI elements

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.

Showing off button types + drop button pattern
Modal dialog showing an admin screen

Theme Responsively

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. :))

New method of selectively adding JS/CSS to the page

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.

R.I.P. IE 6, 7, and 8

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!

A Wanted poster with IE in it and some bullet holes. :)

And more?

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:

  • While not complete yet (hint: here's a great way to learn Twig! ;)), there is an ongoing effort to Convert all core theme functions to Twig templates so that theming works the same way no matter what's output on the page, except in *very* rare cases where theme functions are still needed for performance. This should make theming much more approachable, because it would negate the requirement for designers to learn PHP to make trivial markup alterations in almost all cases.
  • Convert page elements (title, tabs, actions, messages) into blocks and Move menu_block module functionality into core would get rid of those "oh-so-special" one-off variables in favor of consistent placement/theming (as well as caching) of page elements everywhere as blocks.
  • The Dream Markup movement arose to try and strip all of the nasty cruft (extra <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.
  • Also out of DrupalCon Austin, the Headless Drupal group formed out of a desire to make it easier to use completely custom front-ends in e.g. Angular JS on top of Drupal.

That's a wrap!

Join us next time, when we'll talk about all the new back-end developer features coming to Drupal 8!

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

Filtered HTML

  • Use [acphone_sales], [acphone_sales_text], [acphone_support], [acphone_international], [acphone_devcloud], [acphone_extra1] and [acphone_extra2] as placeholders for Acquia phone numbers. Add class "acquia-phones-link" to wrapper element to make number a link.
  • To post pieces of code, surround them with <code>...</code> tags. For PHP code, you can use <?php ... ?>, which will also colour it based on syntax.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <h4> <h5> <h2> <img>
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.