Subscribe to feed Planet Drupal - aggregated feeds in category Planet Drupal
Bijgewerkt: 1 uur 49 min geleden

OpenLucius: Drupal Module moment: WYSIWYG Filter

wo, 2016/03/16 - 11:15am

Every now and then you come across a module you wished you saw before. And I wonder why we did not discover this one earlier: WYSIWYG Filter. It even exists since Drupal 6.

WYSIWYG Filter is solving the following problem:

Lullabot: Get a decorator for your Drupal home

wo, 2016/03/16 - 8:01am
Design patterns

Software design patterns are general and reusable software design solutions to a defined problem. They were popularized in 1994 by the “Gang of Four” after their book Design Patterns: Elements of Reusable Object-Oriented Software.

These generic solutions are not snippets of code, ready to be dropped in your project, nor a library that can be imported and reused. Instead they are a templated solution to the common software challenges in your project. Design patterns can also be seen as best practises when encountering an identified problem.

With Drupal 8’s leap into modern PHP, design patterns are going to be more and more relevant to us. The change from (mostly) procedural code to (a vast majority of) object oriented code is going to take the Drupal community at large through a journey of adaptation to the new programming paradigm. Quoting the aforementioned Design Patterns: Elements of Reusable Object-Oriented Software:

[…] Yet experienced object-oriented designers do make good designs. Meanwhile new designers are overwhelmed by the options available and tend to fall back on non-object-oriented techniques they've used before. It takes a long time for novices to learn what good object-oriented design is all about. Experienced designers evidently know something inexperienced ones don't. What is it?

Even if you don’t know what they are, you have probably been using design patterns by appealing to common sense. When you learn what they are you’ll be thinking “Oh! So that thing that I have been doing for a while is called an adapter!”. Having a label and knowing the correct definition will help you communicate better.

The decorator

Although there are many design patterns you can learn, today I want to focus in one of my favorites: the decorator.

The decorator pattern allows you to do unobtrusive behavior inheritance. We can have many of the benefits of inheritance and polymorphism without creating a new branch in the class’ inheritance tree. That sounds like a mouth full of words, but this concept is especially interesting in the Drupal galaxy.

In Drupal, when you are writing your code, you cannot possibly know what other modules your code will run with. Imagine that you are developing a feature that enhances the entity.manager service, and you decide to swap core’s entity.manager service by your enhanced version. Now when Drupal uses the manager, it will execute your manager, which extends core’s manager and overrides some methods to add your improvements. The problem arises when there is another module that does the same thing. In that situation either you are replacing that module’s spiced entity manager or that module is replacing your improved alternative. There is no way to get both improvements at the same time.

This is the type of situations where the decorator pattern comes handy. You cannot have this new module inheriting from your manager, because you don’t know if all site builders want both modules enabled at the same time. Besides, there could be an unknown number of modules –even ones that are not written yet– that may create the conflict again and again.

Using the decorator

In order to create our decorator we’ll make use of the interface of the object we want to decorate. In this case it is EntityManagerInterface. The other key component is the object that we are decorating, let’s call it the subject. In this case our subject will be the existing object in the entity.manager service.

Take for instance a decorator that does some logging every time the getStorage() method is invoked, for debugging purposes. To create a decorator you need to create a pristine class that implements the interface, and receives the subject.

class DebuggableEntityManager implements EntityManagerInterface { protected $subject; public function __construct(EntityManagerInterface $subject) { $this->subject = $subject; } }

The key concept for a decorator is that we are going to delegate all method calls to the subject, except the ones we want to override.

class DebuggableEntityManager implements EntityManagerInterface { protected $subject; // ... public function getViewModeOptions($entity_type_id) { return $this->subject->getViewModeOptions($entity_type_id); } // … public function getStorage($entity_type) { // We want to add our custom code here and then call the “parent” method. $this->myDebugMethod($entity_type); // Now we use the subject to get the actual storage. return $this->subject->getStorage($entity_type); } }

As you have probably guessed, the subject can be the default entity manager, that other module’s spiced entity manager, etc. In general you’ll take whatever the entity.manager service holds. You can use any object that implements the EntityManagerInterface.

Another nice feature is that you can decorate an already decorated object. That allows you to have multiple decorators adding different features without changing the inheritance. You can now have a decorator that adds logging to every method the entity manager executes, on top of a decorator that adds extra definitions when calling getFieldDefinitions(), on top of …

I like the coffee making example in the decorator pattern entry in Wikipedia, even if it’s written in Java instead of PHP. It’s a simple example of the use of decorators and it reminds me of delicious coffee.

Benefits and downsides

One of the downsides of using the decorator pattern is that you can only act on public methods. Since you are –intentionally– not extending the class of the decorated object, you don’t have access to any private or protected properties and methods. There are a couple of situations similar to this one where the decorator pattern may not be the best match.

The business logic you want to override is contained in a protected method, and that method is reused in several places. In this case you would end up overriding all the public methods where that protected one is called.

You are overriding a public method that is executed in other public methods. In such scenario you would not want to delegate the execution to the subject, because in that delegation your overridden public method would be missed.

If you don’t find yourself in one of those situations, you’ll discover that the decorator has other additional benefits:

  • It favors the single responsibility principle.
  • It allows you to do the decoration during run-time, whereas subclassing can only be done in compile-time.
  • Since the decorator pattern is one of the commonly known design patterns, you will not have to thoroughly describe your implementation approach during the daily scrum. Instead you can be more precise and just say “I’m going to solve the problem using the decorator pattern. Tada!”.
Write better designs

Design patterns are a great way to solve many complex technical problems. They are a heavily tested and discussed topic with lots of examples and documentation in many programming languages. That does not imply that they are your new golden hammer, but a very solid source of inspiration.

In particular, the decorator pattern allows you to add features to an object at run-time while maintaining the object’s interface, thus making it compatible with the rest of the code without a single change.


Chapter Three: Accelerating Drupal 8 Through Adoption

di, 2016/03/15 - 11:54pm

Since making the decision to use Drupal 8 for all new projects Chapter Three has become even more active in the issue queues. We actively invest in Drupal 8 every day, funding Alex to work on it full time, as well as ensuring every employee and contractor has time to contribute.

Over the last several months...

We spearheaded a port of Doubleclick module to Drupal 8

We've worked on improving some of our debugging tools:

We've created some new modules for Drupal 8 inspired by our Drupal 8 projects


Agaric Collective: Web Components: What are they, and can we use them yet?

di, 2016/03/15 - 11:45pm

Talk about web components has been going for quite some time now: the term was coined in 2011. In this blog post, I will discuss the basics of what they are and what they do, and introduce the primary technological foundations for them. In future articles, I'll dig into the specifics and sample code - as they are currently supported or else poly-filled for today.

Web Components are a group of related standards promising to bring component-based extensibility to HTML documents. The great promise is that once you or someone else builds some component that provides a particular feature, it can easily be included and reused in other projects. For example, if you've created, say, a "treeview" component that displays data in a tree form, you can wrap up the definition of this in a component. Then, it would be possible for anyone to include the component easily wherever they might want to use a treeview. We'll ultimately get to defining our own components in a future article, but for now, let's look at a special sort of "built-in" web component.

Perhaps the most common HTML element that comes up when discussing web components is: the video tag. This is because the video tag offers a simple and very clear browser-native example of precisely what a web component looks like from the point of view of a consumer of a particular of a web component. If we were to include a video tag in a page, we don't end up with a naked auto-paying video display (by default). Instead, we end up with a nice little video player, complete with start/stop/seek and volume controls offered up by our browser:

[A video control as rendered by Chromium]

In our browser (which again, in this case is Chromium), we can select the developer tools option under the General section / Elements titled "Show user agent shadow DOM." Given this option is set, we are able to see how Chromium builds upon the video tag when it is rendered:

[Displays shadow root]

As you can see, beneath the video element comes one of the core pieces of the Web Components technologies: the shadow-root. Chromium has treated the video tag as a "shadow host" which is a containing element for a "shadow root", off of which hangs the implementation of the video element's controls. This shadow host/shadow root mechanism is the basis for encapsulation in web components: it separates the details of an element's implementation from the outside document. CSS styles and JavaScript inside the shadow root are scoped to that element. Inside of the shadow root, the implementation of the video tag is a sub-tree of elements which is not directly inline with the the document's top-level DOM. This means, for example, you can neither find nor directly address elements within the shadow root.

There are at least a few libraries that enable building web-components for current browsers, regardless of browser support for the standards-based web components support. The one I'll demonstrate quickly here is pulled directly from polymer's home page. I'm using this because it demonstrates what I believe is about as close to the implementation of the ideal for web components (from a consumer perspective) aside from having to use a polyfill for some browsers today:

<!-- Polyfill Web Components support for older browsers --> <script src=""></script> <!-- Import element --> <link rel="import" href=""> <!-- Use element --> <google-map latitude="37.790" longitude="-122.390"></google-map>

Again, the polyfill ensures that our browser will handle the subsequent tags. This library aims to support the core web components features in a way that is consistent with the core web-components as the standards evolve. The link tag is another standard web component feature, though Mozilla is not favoring supporting it further, that essentially imports an external definition which in this case is the definition of the tag. When all browsers support web components natively, things will hopefully be as simple as importing the reference to the component and then using it, as is done in the last statement above.

Hopefully this gives you a quick glimpse into how web components might make our web applications grow through a variety of new interface tools we can build on, extend, and easily utilize. In future articles, we'll look at examples of using the various building blocks of web components, and how the technology continues to evolve.


Dries Buytaert: A "MAP" for accelerating Drupal 8 adoption

di, 2016/03/15 - 10:02pm

Contributed modules in Drupal deliver the functionality and innovation proprietary content management solutions simply can't match. With every new version of Drupal comes the need to quickly move modules forward from the previous version. For users of Drupal, it's crucial to know they can depend on the availability of modules when considering a new Drupal 8 project or migrating from a previous version.

I'm pleased that many agencies and customers who use Drupal are donating time and attention to maintaining Drupal's module repository and ensuring their contributed modules are upgraded. I believe it's the responsibility of Drupal companies to give back to the community.

I'm proud that Acquia leads by example. It was with great pride that Acquia created a Drupal 8 Module Acceleration Program, or MAP. Led by Acquia's John Kennedy, MAP brings financial, technical and project management assistance to Drupal module maintainers. Acquia kicked off MAP in mid-October and to date we have helped complete production-ready versions of 34 modules. And it is not just any modules; we've been focused on those modules that provide critical pieces of functionality used by most Drupal sites.

When MAP was formed Acquia allocated $500,000 to fund non-Acquia maintainers in the community. In addition, we have so far invested more than 2,500 hours of our own developers' time to support the effort (the equivalent of three full-time developers).

What is impressive to me about MAP is both the focus on mission-critical modules that benefit a huge number of users, as well as the number of community members and agencies involved. John's team is leading a coalition of the best and brightest minds in the Drupal community to address the single biggest obstacle holding Drupal 8 adoption back.

Drupal 8 has already made a significant impact; in the 90 days following the release of Drupal 8.0.0, adoption has outpaced Drupal 7 by more than 200 percent. And as more modules get ported, I expect Drupal 8 adoption to accelerate even more.


DrupalEasy: Limiting Block-Level Styles in Drupal 8's CKEditor

di, 2016/03/15 - 9:46pm

By default, Drupal 8's "Basic HTML" text format WYSIWYG editor configuration allows content authors to utilize HTML heading elements "h2" through "h5". 

But what if you want to limit authors to a smaller set of block-level HTML elements? In previous versions of Drupal, this would require separate configuraiton of both the text format and the WYSIWYG editor. In Drupal 8, the solution is much simpler - simply limit the text format to use the block-level elements to be allowed (in this case, h4, h5, h6 - the "id" indicates that HTML "id" attributes may be specified on these elements as well):

The WYSIWYG editor automatically displays only those that are allowed by the updated text format!



ImageX Media: Storytelling in the Higher Education Recruitment Process

di, 2016/03/15 - 7:05pm

The decision to choose a university is likely one of the biggest financial and time commitments a person will make. It’s a big deal - often a life-changing experience. To persuade prospective students to take that leap of faith, higher-ed sites need to tell a story that is carefully architected to speak to their fears, hopes, and dreams. 


Acquia Developer Center Blog: Open-Sourcing Moonshot

di, 2016/03/15 - 6:25pm

Last week the entirety of Acquia Engineering, which spans the globe, was in Boston for Build Week.

It is a time for people to interact internally among their teams, and externally with other teams. It's an important part of our engineering culture, and it always ends with a Hackathon.

One of the projects in this year's Hackathon was focused on open sourcing a tool several teams have been using internally. The result: we are happy to announce Moonshot!

Tags: acquia drupal planet

DrupalCon News: Community Keynote Votes Are In

di, 2016/03/15 - 6:08pm

Thank you to everyone who participated in the Community Keynote voting. We had over 200 community members share their opinions on which issue that is facing the community right now should be shared on the mainstage.


Acquia Developer Center Blog: Drupal 8 Module of the Week: Paragraphs

di, 2016/03/15 - 5:38pm
Jeffrey A. "jam" McGuire

Each day, more Drupal modules are being migrated from Drupal 7 to Drupal 8 and new ones are being created for the Drupal community’s latest major release. In this series, the Acquia Developer Center is profiling some of the most prominent, useful modules available for Drupal 8. This week: Paragraphs.

Tags: acquia drupal planetparagraphsstructured contentauthoringwysiwyg

InternetDevels: Creating modal windows (pop-ups) in Drupal 8: full tutorial

di, 2016/03/15 - 3:02pm

Check out more tips about Drupal 8 by our experienced Drupal developers.

Read more

CiviCRM Blog: A 'Community Shares' extention for Civi

di, 2016/03/15 - 1:05pm

Hello everybody. I am assessing the feasibility of a CiviCRM integrated 'Community Shares' extension on behalf of my client, the Kindling Trust.

Community Shares are an investment mechanism available to Co-operative Societies in the UK - see if you want more info.

Kindling are a not for profit organisation based in Northern England, who have been using Civi for a number of years, and are planning on launching a community share offer in the future, in order to raise funds for a community owned farm, to develop sustainable food practices, and regional food security.

I anticipate that the new extension would build upon the existing CiviContribute and CiviMember components, and have attached an outline document describing how I would see it functioning.

We are interested in talking to members of the Civi partner ecosystem, who are interested in assisting us with developing the Extension, and providing estimates for the cost of development. We are currently at the stage of raising finances to undertake the work. Please email me here if you are interested.

AttachmentSize Outline document describing proposed extension76.27 KB CiviCRMCiviContributeCiviMemberDrupalExtensions

Code Enigma: Track all the things with Google Analytics

di, 2016/03/15 - 12:15pm
Track all the things with Google Analytics Language English Track all the things with Google Analytics

Custom dimensions and metrics allow to track almost anything you could need.

Tue, 2016-03-15 11:15By salva

Certainly, there's no need to introduce Google Analytics as an analytics tool for websites. However, not all of its features are equally known to site administrators, and it's very easy for organisations to get tempted to spend part of their budget into a custom tracking system that covers very specific aspects of their site.

The reality is, though, that Google Analytics can cover much more ground than it seems to, yet some of its features are sometimes overlooked and not really used. We've talked about custom event tracking in the past, and in this post I'd like to introduce another feature introduced not so long ago: custom dimensions and metrics.

Custom dimensions and metrics

At its core, Google Analytics (GA) tracks plenty of details about the visitors of a website. However, the information it tracks can't go beyond the details that can be extracted from the HTTP request or from the user's browser (user location, user browser, language of the user, etc). Anything that falls beyond this type of information belongs to the business domain, and as such, Google Analytics can't really track it without further details

For example, a site owner might want to know how many users like different types of food (vegetables, fish, meat, etc). That's simple enough to track on any site. But now imagine the owner wants to know how well a section of the site is doing with a particular audience (e.g: how popular the "Vegetables" section is among the users that like meat), in order to change their marketing approach, ads displayed on that section, etc, as they want to attract more people from a specific audience. The problem starts to unfold and become more complex now, because in order to surface that information, the site would need to track each visit to a page, but also store information about the specific details of the user that visited that page.

This kind of data belongs to the business domain, and it's exactly what custom dimensions and metrics allow site owners to track. In short, they make it possible to track user information alongside the standard details that Google stores for any page view. So, continuing with the example above, using this feature from GA we can easily track user-specific details, or other details about the contents, (e.g: the food shop that sponsors a specific page). With these details stored, GA allows to surface them when creating custom reports, in the same way we can use the default dimensions and metrics (like language, number of page views, number of sessions, etc).

The bare minimum thing to understand about this feature, is that using a custom metric, we can only track numeric values, whereas using a custom dimension, you can track any type of value (e.g: shop names). This is a basic description of custom dimensions and metrics, but you can find the complete documentation (with guidelines and examples of use case scenarios) in the help section of GA. Now, let's look at how easy it is to set this up in GA and integrate it in Drupal.

Setting up Custom Dimensions and Metrics in Analytics

This step couldn't be much simpler. All you have to do is going to the Administration tab of your GA account, choose the web property for which you want to track some custom data, and expand the Custom definitions section. From there, you can click to add either a custom dimension or a custom metric. For both of them, there are a few additional details to specify. Most of the time the default values will be good to go. For more complex data tracking, refer to the full documentation. The screenshot below shows how to access these pages from the Administration tab. Some more details can be found here.

Setting up Drupal

Once the GA part is sorted out, it's the time to start sending custom information from Drupal. Fortunately, the Google Analytics module already has support for this feature. From the settings page, located at admin/config/system/googleanalytics, you can access two separate fieldsets from which to specify the site or user data to send to Analytics, alongside the page view information. The great thing here, is that it leverages the use of tokens, so every available token in the system can be used here. What if you want to send some custom information that is not provided by an existing token? In such case, Token API comes to the rescue!

The picture below shows the configuration page for the Google Analytics module, with some custom dimensions added as tokens:


Note that I've stayed away of showing any code snippets. If you're not using the Google Analytics module, you can still send custom information to Google very easily, by manually adding the analytics.js file to your site, and with just a few lines of code. Since that's out of the scope of this article, I'll just link to this help page, which shows some examples of code snippets for different scenarios.

Show me the reports

So, we've configured our Analytics account, and configured Drupal to start sending those valuable bits of data that will allow us to engage with our audience in the most efficient way. Now we want to surface this data in some way (tables, anyone?). For that, we just need to go to the Customisation tab (back in the GA interface), and click on create custom report. You'll see there's a section for dimensions, and another one for metrics. Choose the ones to show in the table from your custom ones (or from the standard ones), and save:


After some time (give it at least one day!) the statistics should start to come through, and you'll be able to export, filter, reorder or perform any of the standard operations available in Google Analytics. The screenshot below shows some custom details captured from one of our sites and surfaced through the Analytics UI:


This article is a brief introduction to GA Custom Dimensions and Metrics, and to show how easy is to harness the power of this feature to create complex reports without having to go through a lot of development in your site. While GA is not limitless, it certainly allows for much more than what it's commonly known. Make sure you check it out before discarding it for a custom reports solution.


BlogGoogle Analytics Custom Events BlogBetter UX in your forms, the easy way BlogWYSIWYG flexibility with the Shortcode module PageWe build sites in Drupal

ActiveLAMP: Sandcamp 2016 Recap

di, 2016/03/15 - 3:00am

The San Diego Drupal Camp was great! You can’t beat the weather in San Diego, and as usual, these regional events are great for catching up with old friends that are still plugging away with the Drupal content management system. Checkout our highlight video: This year I had the pleasure of giving 3 sessions at the camp, and as promised, I want to share the slides and code for everything that I presented. Each deck is iframed in on this article, feel free to checkout my github page</a< if you want the speaker notes too.


Drupal core announcements: Update: PHP dependencies removed from git (8.1.x and 8.2.x branches)

di, 2016/03/15 - 1:17am

The Composer-managed vendor directory has been removed from the Drupal core git repository for the 8.1.x and 8.2.x branches. (This change was previously committed, but rolled back due to rate limits on Github affecting composer installation. Those limits have since been lifted, so we have recommitted the change.)

There will not be any changes for people downloading Drupal 8 from The packager will add dependencies to zip and tar packages.

If you're not using zip / tar files, e.g. when using a git clone, run composer install to get dependencies. See for instructions.

For background information, see the change record for this change and the related Drupal 8 core issue.


Jeff Geerling's Blog: Happy #PiDay 2016 - Celebrating with the Raspberry Pi

ma, 2016/03/14 - 10:53pm

I think today was my most Pi-full π day, ever! Let's see:

Early in the morning, I finished upgrading all the Ansible playbooks used by the Raspberry Pi Dramble so my cluster of five Raspberry Pis would run faster and better on the latest version of official Raspberry Pi OS, Raspbian Jessie.

Later, published an article I wrote about using Raspberry Pis placed throughout my house to help my kids sleep better:

Raspberry Pi project to regulate room temperature and sleep better by @geerlingguy

— Open Source Way (@opensourceway) March 14, 2016


FFW Agency: Managing CSS and JavaScript files in Drupal 8 with Libraries

ma, 2016/03/14 - 8:05pm
Managing CSS and JavaScript files in Drupal 8 with Libraries David Hernandez Mon, 03/14/2016 - 19:05

Drupal 8 revolutionizes the theming experience with many significant improvements to make theming easier, and give themers the flexibility and control they've never had before. One of those major improvements is to the library management system, which controls the attaching of CSS and JavaScript files.

In this post we will cover how to create and control libraries from a theme. This will include SMACSS categorization for CSS files, dependencies, how to conditionally attach libraries, manipulating libraries that come from anywhere in a site (core, modules, or base themes,) and targeting individual files for removal or replacement. All this without needing a single line of PHP.

Creating Libraries

The scripts and stylesheets properties used in previous versions of Drupal no longer exist. In Drupal 8 we manage all of these files using libraries defined in a .libraries.yml file, added to your theme.

Each library defined in this file includes a unique name, any number of CS or JS files, dependencies, and other information needed to define the properties of the library or assets.

Here is an example of a library file:

# In mythemename.libraries.yml

# Give your library a name.
  version: "1.0.x"
    # The SMACSS category.
      # The path to the css file.
      assets/css/base.css: {}
      assets/css/print.css: { media: print }
    assets/js/myglobal.js {}
    - core/jquery

# In the following example, we add a Google font (Lato).
    base: '//': { external: true }

The file is in YAML format, which Drupal 8 uses for all configuration files. It should be named using the name of your theme, just like your .info.yml file. Let’s take a look at each line to get a better understanding of all the properties.


# Give your library a name.

Each library is given a custom name. This name can be anything, but must be unique to the module or theme that supplies it. This should be easy to keep track of since the libraries that belong to the same module or theme are defined in the same file. The name does not have to be unique to the entire website, because libraries are referenced using both the library name and source. For example, mythemename/my-library-name, but we’ll get to that later when we start attaching and manipulating libraries.


version: "1.0.x"

The version is completely optional. It is only used for identification purposes, along with other properties like license, remote, and a few others that we won’t go into. You may want to add a version for a library you use with multiple projects to keep track of which version is used at any given time. It is also helpful when creating a library that uses CSS or JS from an external source. For example, if you copy code for a slideshow, you may want to add the source version here to keep track of it.


  # The SMACSS category.
    # The path to the css file.
    assets/css/base.css: {}
    assets/css/print.css: { media: print }

All CSS files are included below the css: line. In this case there are two CSS files, base.css and print.css. Each is listed below a category, base and theme, respectively. These are SMACSS categories, which Drupal 8 uses for all CSS file. See the documentation page on CSS file organizaton.


SMACSS is a method for organizing files and CSS rules. You don’t have to follow it in your theming, but you do need to understand how it works and what categories exist, because it used everywhere in Drupal 8 that you encounter CSS files. If you’ve never used SMACSS before, just know that there are five categories; base, layout, component, state, and theme.

When libraries are processed and stylesheets added to a page, they are added in the order of these categories. So a file in the base category will always come before a file in the theme category. The one caveat to this is all module libraries are grouped together and then all theme libraries, so regardless of category, a theme’s stylesheets will always come after the ones supplied by modules.

Back to our example...

Additional Properties

  assets/css/print.css: { media: print }

The line below the SMACSS category is where we add the CSS file. The path, relative to the root of the theme, is used to identify the file. Following the file are a pair of curly braces where additional properties can be set. In this case, the media property is set to print. The available values for media are screen, print, or all. If no value is set, all is used.


  assets/js/myglobal.js {}

Like CSS, we add JavaScript files below the js: line, with each file on a separate line. Unlike CSS, there is no SMACSS category to worry about. But, just like CSS, you can set additional properties inside the curly braces following the file name. For example, adding minified: true will tell Drupal this file has already been minified, so don’t try to minify it again when aggregating the files.

One thing to note is Drupal 8 adds all JavaScript files to the footer of a page. If you need to have your JavaScript loaded in the header, add header: true to the library.

  header: true
    assets/js/myglobal.js {}

If the header property is set to true, any dependencies defined in the library will also get loaded in the header.


  - core/jquery

The dependencies: line is where you add any libraries your library requires. This must be other libraries already defined by your theme, some module, or Drupal core. Notice that the library is referenced using its name, and where it came from. In this case, core. (core refers to a literal core.libraries.yml file. Libraries defined by core modules will use their names; block, node, field, views, system, etc.) This is how we avoid name conflicts.

External Files

      '//': { external: true }

In the second example, we see how to link to external stylesheets. Simply supply the external URL for retrieving the file, and set the external property to true.

Attaching Libraries

There are three basic ways for a theme to attach libraries; in the .info.yml file, directly in a template file, and in a preprocess function. Let's go over each of those methods.


To attach assets globally so they are added to every page of the website, add them in your theme’s .info.yml file.

  - core/normalize
  - mythemename/my-library-name


A great way to attach a library conditionally is to do so directly in a template file. Drupal 8 has a special function called attach_library() just for this purpose.

{# In a Twig template file. #}

{{ attach_library('mythemename/my-library-name') }}

The advantage here is in matching the same conditions of the template file. For example, if you use this method in your node.html.twig, the CSS and JS files will only get added when a node is rendered. If you do it in your node--content-type.html.twig the files will only get added when a node of that particular content type is rendered. You can imagine the flexibility when doing this in specific field or views templates.


Lastly, libraries can be attached in preprocess.

function mythemename_preprocess_page(&$variables) {
  $variables['#attached']['library'][] = 'mythemename/my-library-name';

Here you can add whatever logic needed to match the conditions you want before adding the library to the 'library' array.

Manipulating Libraries

Since all CSS and JS files in Drupal 8 are now in libraries, themes have complete control over those files, regardless of whether they are part of the theme or not. The two main ways to manipulate libraries are with libraries-extend and libraries-override.


Libraries-extend is a property used in your theme’s info file. It attaches your library to any existing library. The real power here is that the inclusion of your library will now match the library that was extended. If there is any special logic behind when and how that library is attached, your library goes along for the ride without you having to do anything to recreate that logic yourself.

# In

  # Classy's forums library is only included when the forums.html.twig
  # template is used. This will add my theme's 'forums' library at the same
  # time.
    - mythemename/forums

In the above example, a forums library is created as part of our example theme, and attached to Classy’s forums library. Any time Classy’s library gets attached, which is only when a forum is rendered, the example theme’s library also gets attached.


Libraries-override is an even more powerful property that can be used in your theme’s info file. It gives you complete control over any library, to manipulate in anyway you see fit.

Let’s take a look at some examples.

Remove a File

# In

  # The library name.
    # CSS files are always labeled as such. This format is required.
      # The SMACSS category is required.
        # The path to the file. It is not a path relative to your theme.
        assets/vendor/jquery.ui/themes/base/theme.css: false

You’ll notice the structure is exactly the same as when you define a library in your .libraries.yml file. You specify the library name, SMACSS category, and original path to the CSS file. The only difference being the library name must also include the source. In this case, core is prepended to the library name, because the jquery.ui library is defined by Drupal core.

On the line with the path to the CSS file, note that this path is the same as defined by the library. It is not a path relative to your theme, or the website root. It is exactly the same as defined by the jquery.ui library. The path is used as a key to identify the CSS file, so it has to match. If you don’t know what the path is, just find the .libraries.yml that defined the library, and copy it.

Lastly, in this example we’ve added false after the file. This tells Drupal to remove that CSS file any time the library is used. When we say, “no more PHP”, this is it. Gone are the days of preprocessing or alters, doing string searches, and unsetting array elements.

Replace a File

# In

        # Replace the System module's maintenance CSS file with a custom one.
        css/system.maintenance.css: css/maintenance.css

Here we have targeted one particular CSS file added by the System module, in a library called maintenance. Following the system.maintenance.css we supply the path to our own CSS file. This path is relative to the theme’s directory. And since we are supplying a file to an already existing library, this file does not have to be part of any other library defined by the theme.

When doing this yourself you’ll also notice that the new file gets placed in the exact same place the original file was linked in the head of a page. Whether the original file was first or seventh, the new file will be the same. This ensures the cascade of rules in all the stylesheets is not disturbed.

Replace and Remove Whole Libraries

# In

  # Replace Classy's messages library with a custom one.

  # Remove Classy's search results library completely.
  classy/search-results: false

In this example, we are doing two things. First, replace Classy’s  messages library with one from the example theme. This will prevent any of the files used in the Classy library from getting used, and replace them with the files in the example theme’s library. Note that your theme’s library does not have to match the original library. You can have more, or fewer, files, and call them whatever you want. This just substitutes your library for the original one.

Second, the false placed after Classy’s search-results library removes it completely. This is similar to how we removed an individual CSS file in the previous example, but in this case we remove the entire library.


As you can see, given the all-in approach Drupal 8 has taken with libraries, and the power of libraries-extend and libraries-override, themers now have total control!

Tagged with Comments

Jeff Geerling's Blog: Developing with VirtualBox and Vagrant on Windows

ma, 2016/03/14 - 8:02pm

I've been supporting Drupal VM (a local Drupal CMS development environment) for Windows, Mac, and Linux for the past couple years, and have been using Vagrant and virtual machines for almost all my development (mostly PHP, but also some Python and Node.js at the moment) for the past four years. One theme that comes up quite frequently when dealing with VMs, open source software stacks (especially Drupal/LAMP), and development, is how much extra effort there is to make things work well on Windows.

Problem: tool-builders use Linux or Mac OS X

The big problem, I see, is that almost all the tool-builders for OSS web software run either Mac OS X or a flavor of Linux, and many don't even have access to a Windows PC (outside of maybe an odd VM for testing sites in Internet Explorer or Edge, if they're a designer/front-end developer). My evidence is anecdotal, but go to any OSS conference/meetup and you'll likely see the same.


Acquia Developer Center Blog: Drupal How-To: Get Inline Images on Your Drupal Site.

ma, 2016/03/14 - 7:35pm

In this 3-part Drupal How-To series, I'm going to show you various options for configuring images on your site.

In Part 1, we looked at how to tweak the default image options. Here, in Part 2, we'll see ways to allow inline images. In Part 3, we'll see the latest options for responsive images.

Tags: acquia drupal planet

Evolving Web: Drupal 8 Theming Foundations: Using Stable vs. Classy as a Base Theme

ma, 2016/03/14 - 6:09pm
Drupal 8 Theming Foundations: Using Stable vs. Classy as a Base Theme Suzanne Kenned… Mon, 03/14/2016 - 13:09