Jul 24 2019
Jul 24
Computer screen with Drupal 9 written on it Thinking of joining FFW for a Drupal 9 training? Here's some of the topics we covered.
Apr 23 2019
Apr 23
DrupalCon Seattle Blog DrupalCon 2019 Seattle was a wonderful gathering of the Drupal community and sharing of thought leadership. At FFW, we were particularly excited for the event, as we were unveiling our brand evolution for the first time at the conference.
Jan 09 2019
Jan 09

Drupal 9 is coming. Even if it feels like you only just upgraded to Drupal 8, soon it’ll be time to make the switch to the next version. Fortunately, the shift from Drupal 8 to Drupal 9 should be relatively painless for most organizations. Here’s why.

A little background

Though tools were built in to make the upgrade from Drupal 6 or 7 to Drupal 8 run as smoothly as possible, it could still be a difficult or dramatic process. Drupal 8 marked a major shift for the Drupal world: it introduced major new dependencies, such as Symfony, and a host of new features in Core. The new structure of the software made it tricky to upgrade sites in the first place, which was complicated by the fact that it took a long time for a number of modules to be properly optimized and secured for the new version.

Drupal 9: A natural extension of Drupal 8

Fortunately, the large number of changes made to the Drupal platform in Drupal 8 have made it relatively simple to build, expand, and upgrade for the future. The new software has been designed specifically to make it simple to transition between Drupal 8 and Drupal 9, so that making the migration requires little more work than upgrading between minor version of Drupal 8.

In fact, as Dries Buytaert (the founder and project lead of Drupal) wrote recently in a blog on Drupal.org:

Instead of working on Drupal 9 in a separate codebase, we are building Drupal 9 in Drupal 8. This means that we are adding new functionality as backwards-compatible code and experimental features. Once the code becomes stable, we deprecate any old functionality.

Planning for Drupal 9

As more information is released about the new features and updates in Drupal 9, organizations should consider their digital roadmaps and how the new platform will affect them. And regardless of what your plans are feature-wise, your organization should begin planning to upgrade to Drupal 9 no later than summer of 2021. The reason for that is because the projected end-of-life for the Drupal 8 software is November of 2021, when Symfony 3 (Drupal 8’s largest major dependency) will no longer be supported by its own community.

In the meantime, the best thing your organization can do to prepare for the launch of Drupal 9 is to make sure that you keep your Drupal 8 site fully up to date.

For help planning out your Drupal roadmap, and to make sure that you’ll be ready for a smooth upgrade to Drupal 9 when it releases, contact FFW. We’re here to help you plan out your long-term Drupal strategy and make sure that your team can make the most of your site today, tomorrow, and after Drupal 9 is released.

Dec 14 2017
Dec 14

For anyone who's ever looked up a definition of a Drupal term and still wondered what it means, here are some practical explanations you can use to navigate the Drupal-verse. This is the latest in a series on Drupal-specific terminology.


Regions divide Drupal pages into different sections. Each section contains information that determines the positions of various elements. These elements can include menus, headers, footers, and sidebars. The elements in each Region are called Blocks. (For more information on Blocks, see Aliases, Blocks, and Content Types.)

A Drupal site's active theme keeps information on the number, name, and location of each Region. Different themes can have different Regions. Typically, administrative themes have fewer regions spaced in wide columns across a page. The themes that face a site's end-users often have more complex layouts, which means more Regions. (To learn more about Themes, see Article, Base Theme, Content.

Together, Blocks and Regions make up Drupal's core's primary layout functionality. This combination is a simple yet powerful solution that has been steadily expanded with each major version of Drupal. 

As a note: Drupal Regions can be overridden by contributed modules such as Panels. Regions can also be overridden by custom page templates that apply to specific URLs or URL alias patterns. While the use of Panels can increase overhead and complexity, it makes additional layouts and landing page capabilities available to site builders. Layouts made with Panels are saved in the site's database, which mitigates the risk of rolling custom code by editing a site's theme files.


A Drupal Revision is a saved version of a set of changes to a piece of Drupal content created with a Content Entity. Revisions apply to any piece of content on a site, including Articles, Basic Pages, and custom content types.

After a piece of content is created, any changes or updates made to the content are saved in new versions, or Revisions. Drupal does this rather than editing an existing published version. These versions are stored indefinitely each time a set of changes is saved, and can be found on a content item's administrative interface. Users can save revisions in unpublished draft form, to be published at a later date. Previous versions can also be republished, which allows content authors to revert content to an earlier state.

Drupal's core revision feature supports a powerful workflow functionality that can be custom-configured to align with an organization's processes for content approval. Revision functionality can also be extended with the contributed Diff module to highlight changes between various drafts.


Roles assign various permissions to a Drupal site's users. This includes the ability to edit and manage content and configure settings. Roles are typically grouped into sets of permissions that are determined by a user's expertise in the organization. A Role is a user-defined set of permissions that can be granted to groups of individuals. Typical Drupal user roles include Administrator (preconfigured), Content Creator, and Content Manager.

Anonymous and Authenticated are two special preconfigured user states that are accessed through the user administrative pages. Anonymous users are typically granted only the most basic permissions. By definition, Authenticated users are those that are known to the system. Authenticated users have an account and unique email address that associated with a cookie that resides locally in their browser.

When new functionality is added to Drupal, additional permissions are typically added to the system. These permissions can then be assigned to new or existing roles.

What Next?

If you've got questions about specific Drupal terms, let us know. Drop a request for a definition in the comments and we'll add it to our next ABCs of Drupal post. 

Aug 31 2017
Aug 31

The web has no shortage of digital trends that will pop up on your radar, and one whose momentum has increased over the last couple years is decoupling. In simple terms, the concept of decoupling means separating the frontend of your website from the backend. This means the components of a site that a visitor sees and interacts with (menus, page content, widgets) are built and displayed by software running in the web browser. The backend software, running on the server, accepts requests from the frontend for these different page components and returns them as essentially raw data.

With this full separation of concerns, each half of the website can focus on what it does best; the backend focusing on business logic and retrieval of data, the frontend focusing on display and user experience.

How Do We Achieve This?

This is where JavaScript frontend frameworks come into play. Popular ones include Angular, which we at FFW have used quite successfully on projects, or React, Ember, and many others too numerous to count. These frameworks enable a skilled developer to build a complex and highly interactive frontend without constant page refreshes that require the full attention of the backend.

To do this, it helps to have a powerful and flexible content management system, which doesn’t require lots of custom programming and reinvention of the wheel. This is where Drupal comes in. We’ve done this quite successfully with Drupal due to its robust and flexible API. Drupal 8 pushes this even further with its API first approach, and superior set of APIs.

Drupal 8 Services

Things like the built-in RESTful web services and superior content modeling tools do most of the work of building that backend system. Eventually the backend will communicate effortlessly with frontend systems and other applications and third-party service. This makes Drupal an effective content hub for distributing your content to any application that needs it.

Pros and Cons

When introducing anything new there are various factors to consider. A decoupled fronted can improve perceived performance and enhance interactivity. It can also do something very difficult with a fully baked content management system, where all rendering is handled by the backend. It enables developers and development teams to design and build a frontend almost completely independently from how the backend is developed. Your templating system, how CSS is built and managed, preferred methods for design components, all this can be treated like a separate project. Your designers and frontend developers don’t even have to have skills specific to the CMS you are using.

Life, of course, is never perfect. The main drawbacks become apparent when really thinking about how all this affects the way your site is built and managed. When using a CMS like Drupal, you start losing a lot of the key features that make it the tool it is. Can you use Drupal’s site building tools to, for example, change the order of fields displayed on a page? Things like that are now being hard-coded into the frontend. We also start losing some of the multilingual features, it plays less nice with metatags and other SEO features, and potentially increases the amount of work and skills needed to build your website. Those aren’t all unsolvable problems, but you’ll need to consider them when deciding where you are willing to devote the development time to building a decoupled site.

Two Approaches

If you understand the concept of separating your frontend and backend, you’ll start seeing two approaches while doing your research. “Headless” Drupal, which just means a fully decoupled frontend. The other is “progressive” decoupling. “What the heck is that?” you might say. Progressive decoupling blurs the line between what the frontend and backend are doing, rather than fully decoupling the two.

Progressive decoupling starts with a traditional website approach, with no decoupling, and the backend doing most of the work to produce the web page. Then, individual components that are deemed more interactive or take longer to produce are handled by the frontend. This approach plays a little more nicely with tools already present in your CMS, and is easier to implement on any existing website.

New Hotness Can Burn

Decoupling a website is a great way to solve some problems of the traditional website module. We certainly advocate it for projects suffering from those problems. But, as with all technology, make sure your use case has the need before forcing technology onto it. The decoupling approach can revolutionize your site visitor’s experience, but if forced to fit it can create new problems, increase development time, and inflate your costs.

A simple site, with few frontend performance problems, largely static content, and little need for things like user- or region-specific content, is not likely to need something like a decoupled frontend. My advice: Let your requirements always inform your solution. Technology is great at solving problems, but don’t let it create them by misapplying it to your project. If you want to talk about whether decoupled Drupal might be right for you, please contact us.

Jul 14 2017
Jul 14
Header eCommerce is one of the more mature areas of the internet - after all - selling things is what catapulted the web into prominence and it all happened in the shopping cart. But eCommerce is much more challenging now and to be competitive in today's market businesses need much more than a tool that takes their client's money. Businesses need to think in terms of Digital Experience Platforms or DXP's.
Nov 23 2016
Nov 23

At FFW, 90% of our staff spends all day, every day, working with code. We’re site builders and developers, and we’ve created a number of tools to help make our jobs easier. Today, we’re excited to share our Docksal development environment with you in the hopes that it will make your team’s life easier, too.

Docksal is an open-source tool created by FFW for defining and managing development environments. It brings together common development tools, minimizes time spent on configuration, and ensures the consistency of local development environments throughout a team’s continuous integration workflow.

Docksal automatically configures each project's environment to ensure team members are using the same tools, and versions, regardless of the individual requirements of each project. Most importantly, it makes the entire process easy. Docksal offers fully containerized environments with Docker, provides cross-platform support (MacOS, Windows, and Linux,) and has built-in tools that include:

  • drush
  • Drupal Console
  • WP-CLI
  • composer
  • PHP Code Sniffer
  • Apache Solr
  • Varnish
  • Memcache
  • Built-in testing support with Behat and Selenium.

Docksal will even automatically configure virtual hosts for you, so no more editing host files and server configurations.

How can Docksal help your organization?

Docksal has a threefold value proposition. It improves time-to-market and quality on development projects through:

  1. Bringing together common development tools on a unified platform
  2. Minimizing time spent configuring development environments
  3. Assuring quality by ensuring that local environments are consistent across a team’s continuous integration and development workflow.

Docksal makes it easy to bring new team members onto projects in no time flat: the software allows them to get set up and running easily and quickly. We built Docksal to streamline the process of adding team members to our projects: previously, they’d have to go find the code for the project, get it set up on their laptop, get it to work with everything on their laptop, perform a database dump, get the site running. We wanted to simplify this process.

Docksal reduces the work of several hours to several minutes. Our developers don’t have to waste time figuring out why the code isn’t working with the configurations they have on their computers, and our teammates who aren’t code-oriented don’t spend frustrating hours trying to simply access the project. With Docksal, anyone can get a specific Drupal environment set up and running on their machine in two minutes -- and everyone is running the same environment, which acts as an important check on quality and consistency.

Our suite of development tools

Docksal’s features may sound familiar to those of you who previously used our Drude tool. That’s because Docksal is Drude renamed and expanded. Docksal doesn’t just work with Drupal: it works with WordPress, stand-alone HTML files, or any other PHP project— because even though we all love Drupal, sometimes we have to work with other technologies, too.

In addition to Docksal, we’ve also created another development tool called CIBox. CIBox (Continuous Integration toolbox) is a development workflow tool that simplifies the process of checking changes to each project’s codebase. CIBox uses continuous integration -- the process of immediately testing new code when it’s contributed to a project -- to support a truly Agile development process.

CIBox allows developers to have an unlimited number of testing environments, deployment plans, and additional automations. It supports a continuous integration server dedicated to running site builds and tests, as well as a toolbox of scripts for Code Driven Development with Drupal, Wordpress, Symfony, Sylex support. It offers deployment plans and skeletons, and an improved QA workflow from most CI tools. Stay tuned for an upcoming blogpost that speaks to CI Box in more detail.

Try the software for yourself

Docksal and CIBox are both great tools for building projects and managing development environments. Both have saved us a lot of time and ensured that we have streamlined, quality-focused processes.. To get Docksal for yourself, visit docksal.io for downloads and more information, or to try CIBox, check here.  We hope that you give them a try — we think they’ll make your life better, too.

Aug 09 2016
Aug 09

It is amazing how often the content equation is underestimated or misunderstood whether building new properties or renewing existing sites.

The essence of any web project is the content or message to be conveyed. Understandably organizations will engage terrific creative agencies that will put tremendous effort into strategy and design. Unfortunately this often has the unintended effect of de-emphasizing existing content that may, or may not, need to be migrated to your new project. A thorough content audit early on in your planning process will help streamline your project and your budget.

Rarely is content brought over to a project wholesale without some important changes. This can be obvious like making PDF content more search engine friendly or less obvious like adding or changing metadata and reforming its underlying data structure. An audit will help determine if content migration should be included in your web development scope or handled as a separate component.

But unlike planning for strategy and design, resources are often scarce when it comes to content planning and conducting a content audit. It is likely the content planning process will be reduced to task level milestones and allocated to support staff or subject matter experts with little accommodation for the importance, difficulty or breadth of the requirements. This can lead to unforeseen and unwanted surprises during the development and user acceptance cycles of your project. 

Here are a few quick resources to get you started understanding the content planning process is Drupal.

A topic central strategy from a blog post that has only gotten more important: Understanding Content Planning: Why Taxonomy is Your New Best Friend

A great book from an accomplished Drupalist that will answer a lot of basic questions around content planning: The Drupal User's Guide by Emma Jane Hogbin Westby.

And a new series of articles about distributed content management by our very own Hank VanZile Director of Pre Sales Consulting starting with 'What is Distributed Content Management'

Jul 29 2016
Jul 29
Real Time Government Personalization We got a great response to our Real-Time Personalization Strategies for Government Websites session at Drupal GovCon last week. Download a copy of our slide deck and read more about personalization strategies.
Jul 21 2016
Jul 21

Extending in Twig is a method by which one template can inherit content from another template, while still being able to override parts of that content. This relationship is easy to imagine if you are familiar with Drupal’s default system of template inheritance.

A theme can have multiple page templates, many node templates, even more field templates, and a plethora of block and Views template. And it is common for those templates to largely be identical, save for a snippet of markup or some logic. The advantage in extending templates is reducing this duplication, thereby simplifying architecture and easing maintenance.

Let’s say, for example, you want to change the template for a specific block, adding a wrapper div around the main content area. This might be done by copying the standard block template and giving it a name specific to your block.

Classy’s block.html.twig template
  set classes = [
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    {{ content }}
  {% endblock %}

Copied to block--my-special-block.html.twig
  set classes = [
    'block-' ~ configuration.provider|clean_class,
    'block-' ~ plugin_id|clean_class,
<div{{ attributes.addClass(classes) }}>
  {{ title_prefix }}
  {% if label %}
    <h2{{ title_attributes }}>{{ label }}</h2>
  {% endif %}
  {{ title_suffix }}
  {% block content %}
    <div class=”content-wrapper”>{{ content }}</div>
  {% endblock %}

This accomplishes your goal. You have a template specific to this particular block, and a wrapper div just where you need it. Following the same method, and with a complex site, you can end up with lots of different block templates (or node templates, or field templates, or … you get the idea.)

But, now you have a different problem. The majority of the template is duplicated. All the CSS classes, the outer wrapper, the markup for the block title, etc. If any of that needs to be changed, like changing all block titles from H2s to H3s, you have to update every single one of those templates.

Even if this happens infrequently enough not to be considered time consuming, it is still prone to errors. You might make a mistake in one template, miss one that needs changing, or even change one that should not be changed.

This is where {% extends %} comes in

Extending templates allows you to reference the original template, and only override the parts that are unique to the child template.

In the block example, we can create a block--my-special-block.html.twig template with this content:

{% extends "block.html.twig" %}
{% block content %}
  <div class=”content-wrapper”>{{ parent() }}</div>
{% endblock %}

That’s it. That is the whole template. Twig uses the original block.html.twig template as the main template, and only uses what we override in the more specific block--my-special-block.html.twig template.

The parent() function simply returns all of the content within the {% block %} tags in the original template. This saves us from having to duplicate that content; keeping the template simple, and future proofing it. If any of that content changes in the original template, we don’t have to update the block--my-special-block.html.twig template.

In this example, the content in the original template is fairly simple, only printing the content variable, but imagine if there was a large amount of multiline html and Twig code wrapped in those block tags.

Twig blocks, not Drupal blocks!

This overriding is done by using Twig blocks. (Terminology is fun!) The Twig block is what you see identified by the {% block %} and {% endblock %} tags. The word "content" is the identifier for the block. You can have multiple blocks in a single template.

In the block--my-special-block.html.twig template file, we can do anything we want inside the block tags. Twig will replace the original templates “block” with the one in block--my-special-block.html.twig.

What else?

Well, you have access to pretty much everything in the main template, except the printed markup. So, for example, you can modify the variables it uses.

{% extends "block.html.twig" %}
{% set attributes = attributes.addClass(‘super-special’) %}

This template will add a CSS class called "super-special" to the attributes printed in the outer wrapper of the original block template. The alternative would be to copy the content of the entire block.html.twig template just to add this class to the ‘classes’ array at the top of the file.

You can also just set a variable that will be used by the original template.

{% extends "block.html.twig" %}
{% set foo = 'yellow' %}

Imagine a series of variant field or content type templates that set variables used by the original template for classes, determining structure, etc.

You can even add Twig logic.

{% extends "block.html.twig" %}
{% block content %}
  {% if foo %}
    <div class=”content-wrapper”>{{ parent() }}</div>
  {% else %}
    {{ parent() }}
  {% endif %}
{% endblock %}

Pretty much anything you still might want to do with Twig, inside or outside of the block tags, you can still do.

Things to note

Before you jump right in, and bang your head against a wall trying to figure out why something isn’t working, there a few things to know.

  • The {% extends %} line needs to be at the top of the file.
  • When overriding markup, you can only change what is within block tags in the original template. So add {% block %} tags around anything you might want to modify.
  • You cannot print additional things outside of the overriding block tags. You will have an extends line. You can set variables, add comments, add logic, and override blocks. You cannot put other pieces of markup in the template. Only markup that is inside a block.
  • If Drupal does not extend the correct template, based on what you expect from template inheritance, you may have to explicitly state the template you want.
    Example: {% extends "@classy/block/block.html.twig" %}

Additional Resources

Apr 21 2016
Apr 21

Drupal Console is the new CLI (Command Line Interface) for Drupal. This tool can help you to generate boilerplate code, as well as interact with, and debug Drupal 8. From the ground up, it is built to utilize the same modern PHP practices that have been adopted in Drupal 8.

Drupal Console takes advantage of the Symfony Console and other well-known third-party components like Twig, Guzzle, and Dependency Injection among others. By embracing those standard components, we’re fully participating in the PHP community, building bridges and encouraging the PHP community to join the Drupal project and allow us to reduce the isolation of Drupal.

Why is Drupal Console important?

Drupal is infamous for having a steep learning curve, complete with its own language of “Drupalisms”. While Drupal 8 simplifies and standardizes the development process, it is more technically advanced and complex than its predecessor. 

Managing the increasing complexity of Drupal 8 could be a daunting task for anyone. Drupal Console has been designed to help you manage that complexity, facilitating Drupal 8 adoption while making development and interaction more efficient and enjoyable. Drupal Console was created with one goal in mind: to allow individuals and teams to develop smarter and faster on Drupal 8. 

Drupal Console features

In this blog post, I will mention some of the most common features and commands of Drupal Console, to serve as a good introduction.

Install Drupal Console

[gist-embed data-gist-id="3c20c6acb6efd882e0295ff65db3d7d4" data-gist-file="install-drupal-console.sh" data-gist-hide-line-numbers="true" data-gist-show-loading="false"]

Copy configuration files

The init command copy application configuration files to the user home directory. Modifying this configuration files is how the behavior of the application can be modified. 

Drupal Console Init

Validate system requirements

The check command will verify the system requirements and throw error messages if any required extension is missing.

Drupal Console Check

Install Drupal 8

The easiest way to try Drupal 8 on your local machine is by executing the chain command and pass the option --file=~/.console/chain/quick-start.yml

The chain command helps you to automate command execution, allowing you to define an external YAML file containing the definition name, options, and arguments of several commands and execute that list based on the sequence defined in the file.

In this example, the chain command will download and install Drupal using SQLite, and finally, start the PHP's built- in server. Now you only need to open your browser and point it to

Drupal Console Chain Quickstart

Generate a module

The generate:module command helps you to:

  • Generate a new module, including a new directory named hello_world at modules/custom directory.
  • Creates a hello_world.info.yml file at modules/custom/hello_world directory.

Drupal Console Generate Module

Generate a service

The generate:service command helps you to: 

  • Generate a new service class and register it with the hello_world.services.yml file.

Drupal Console Generate Service

Generate a Controller

The generate:controller command helps you to:

  • Generate a new HelloController Class with a hello method at src/Controller directory.
  • Generate a route with a path to /hello/{name} at hello_world.routing.yml file.

Drupal Console Generate Controller

Generate a Configuration Form

The generate:form:config command helps you to:

  • Generate a SettingsForm.php class at src/Form directory,
  • Generate a route with path to /admin/config/hello_world/settings at hello_world.routing.yml
  • Register at the hello_world.links.menu.yml file the hello_world.settings_form route using system.admin_config_system as parent.

This command allows you to add a form structure to include form fields based on the field API. Also generates a buildForm and submitForm methods with the required code to store and retrieve form values from the configuration system.

NOTE: The parent route system.admin_config_system for the menu_link can be selected from the command interaction.

Drupal Console Generate Form Config

Debug Services

The container:debug command displays the currently registered services for an application. Drupal contains several services registered out-of-the-box plus the services added by custom and contributed modules, for that reason I will use peco a simplistic interactive filtering tool to make this debug easier.

Drupal container debug

Debug Routes

The router:debug command displays the currently registered routes for an application. Similar to debugging services. In this example, I will use peco to make this debugging task easier.

Drupal router debug

Create Data

The create:nodes command creates dummy nodes for your application.

Drupal Console Create Nodes

Drupal Console provides a YAML to execute using the chain command. This file contains instructions to execute create:users, create:vocabularies, create:terms and create:nodes command using one command.

[gist-embed data-gist-id="3c20c6acb6efd882e0295ff65db3d7d4" data-gist-file="drupal-chain-create-data.sh" data-gist-hide-line-numbers="true" data-gist-show-loading="false"]

Modify the Drupal Console language

The settings:set command helps to change the application configuration in this example using the arguments language es we can set Spanish as the application language. After switching the default language the interface is translated.

Drupal Console Chain Generate Controller es

All of the available commands

The list command can be used to show all of the available commands. A print screen was not included because the more that 130 commands make the image huge to show on this blog post. 

For the full list of commands, you can visit the documentation page at http://docs.drupalconsole.com/en/commands/available-commands.html

What makes Drupal Console unique

  • Has been built to utilize the same modern PHP practices adopted by Drupal 8.
  • Generates the code and files required by Drupal 8 modules and components.
  • Facilitate Drupal 8 adoption while making development and interaction more efficient and enjoyable. 
  • Allow individuals and teams to develop smarter and faster on Drupal 8.
  • Help developers to understand Drupal 8 with the "--learning" flag.
  • Fully multilingual and translatable, just like Drupal 8 itself.

Links and resources

Apr 21 2016
Apr 21

This is the third post in my series on Distributed Content Management.  In my first post I defined the term and used a few examples while doing so.  My second post, Great Examples of Distributed Content Management In Higher Education, expanded on the first example of a large university.  In today’s post we’ll explore the second example - a global pharmaceutical company - and once again discuss some great use cases for Distributed Content Management.


Setting The Scene

Pharmaceutical companies, more than companies in many other industries, must carefully consider all elements of their content lifecycle. Providing correct, approved content to both healthcare professionals and consumers is of utmost importance and, as such, web content in the pharmaceutical industry must undergo stringent regulatory review and control.  This requires consistent management across all digital properties and, for larger companies, that can be hundreds, or potentially even thousands, of websites and channels globally.


Use Case 1: Efficient Regulatory Review With Content Publishing Workflows

At first, the idea of Distributed Content Management may seem somewhat counterintuitive to how pharmaceutical companies work.  (In previous posts we’ve used it to explore empowering content creators and overcoming bottlenecks to content publishing - challenging concepts to tout for such a regulated industry.)  However, I’ve also opined that content approval and publishing workflows must be tailored to the specific use case.  

Consider a web publishing workflow that allows medical-legal reviews to take place within a Content Management System.  In some web systems this requires a multi-tiered platform wherein a “staging” version of the website - an exact copy of the real (“production”) website on which content changes have been staged - is made available for regulatory approval before the content is made available to the public.  While this is certainly more efficient than sharing offline documents, a deeper consideration of the technologies used can increase the efficiency and further control its risks.  

Some Content Management Systems, such as Drupal, allow content approval to take place on the production website, controlling the visibility and publishing of content through user authentication and roles instead of requiring  separate “staging” websites.  By mapping the appropriate roles to regulatory affairs, pharmaceutical companies using this approach can save costly and timely deployments of new content to the production site and free up the resources required to manage multiple copies of each website.


Use Case 2: Controlled, Single-Source Content Deployment

For some pharmaceutical content, decentralized content publishing may not be an appropriately-sized solution.  Some content is not only highly-regulated but also highly reused wherever products are marketed and is therefore best suited to be updated, approved, and disseminated from a central source.  Important Safety Information and Indications, for example, are types of content that a pharmaceutical company may choose to publish only through a centralized content repository.  

By establishing policies that all content editing must occur in the content repository, with individual websites disallowed from making changes locally, companies may avoid the need to have regulatory approval workflows on each of those sites and ensure that important information is updated in a timely and error-free way across numerous sites.  Content syndication is a fascinating opportunity for organizations considering Distributed Content Management and I’ll explore some of the available technologies, such as Acquia Content Hub, in later posts.


Use Case 3: Multichannel Brand Content

Single-source content syndication also provides an opportunity for pharmaceutical companies looking to promote their consumer products across multiple channels.  Let’s use e-commerce as an example.  Many companies choose to employ standalone, all-in-one e-commerce systems such as BigCommerce, Demandware and Magento rather than integrate e-commerce stores into each of their individual brand websites.  This makes a tremendous amount of sense: these systems can provide a number of compelling features such as gift cards, coupons, centralized inventory management, and opportunities for cross-selling other products among the company’s brands.  However, because these stores are independent of the main brand website, they too need to display content such as product descriptions, use and dosing information, ingredients, etc.  

By programmatically providing that content from a content repository to the e-commerce system, pharmaceutical companies can eliminate the risk of entering information directly into the store and potentially make use of the streamlined regulatory control processes they’ve already set up for the brand sites.


Use Case 4: Content Delivery To Validated Audiences

In addition to marketing content, pharmaceutical companies maintain large amounts of HCP content - information intended for healthcare professionals.  What content is available to these professionals, how they’ll access it, and how to validate the identity of a user seeking that information

is another key consideration for a pharma  company’s Distributed Content Management strategy.  A common approach is to segregate HCP content into regional “portals” - websites that require medical professionals to create accounts and login to see the information for their country or part of the world.  To overcome the challenge of validating these accounts, companies often integrate with an Identity Provider (IdP) such as DocCheck or Cegedim that specializes in maintaining national registries of healthcare professionals.  

However, having a number of disparate system integrations dependant on which country a website is intended to serve introduces both the overhead of managing multiple bundles of code - sometimes written in entirely different programming languages - and the opportunity for error in integrating the wrong code for the intended region.  Because of this, some global pharmaceutical companies may choose to build a more centralized approach to validation and registration using an integration platform such as Mulesoft Anypoint Platform to amalgamate the different Identity Provider code bundles and provide simultaneous access them all through a dedicated Identity Management system such as Janrain.


What’s Next?

We will continue exploring use cases for distributed content management for the next few posts before moving on to discussing some prerequisites for companies looking to implement Distributed Content Management.

Apr 13 2016
Apr 13
Content Management in Higher Education With a multitude of colleges, schools, and departments to account for, distributed content management is an important part of an effective digital strategy for higher education institutions. This post covers three common use cases for universities.
Mar 14 2016
Mar 14

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: '//fonts.googleapis.com/css?family=Lato': { 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 files. 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 is 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

      '//fonts.googleapis.com/css?family=Lato': { 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 mythemename.info.yml

  # 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 mythemename.info.yml

  # 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 mythemename.info.yml

        # 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 mythemename.info.yml

  # 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!

Feb 17 2016
Feb 17

After months of anticipation, Drupal 8 is finally here. Our offices are already buzzing with questions: who will benefit the most from D8? How can all departments utilize the many features of D8 to get the most out of this powerful new platform? And what new best practices can we follow to ensure our sites last?

If you’re currently running a site on Drupal 6 and asking yourself if you should upgrade to Drupal 8, the answer is clear. It’s time to upgrade your Drupal 6 website to a new Drupal 8 website, and here’s why:

Drupal 6 is nearing the end of its life

You may have already heard that on February 24th 2016, Drupal 6 will reach end of life and no longer be supported. What does this mean for you? 

Your organization could be vulnerable to security risks, bugs, and more. Moving forward, the Drupal community will no longer create new Drupal 6 modules, fix bugs in existing D6 modules, and write documentation around Drupal 6, and there will be no more commits on Drupal 6.x to the official tree. In the future, update status may stop working for Drupal 6 sites as well.

Good news: upgrading your Drupal 6 site to Drupal 8 is easy! Drupal 8 core provides a Migration path directly from Drupal 6 as an experimental feature, so sites can update directly to Drupal 8 using either a user interface or with Drush. See Executing an Upgrade from Drupal 6/7 to Drupal 8 for more details. The Migrate feature will be fully supported in a later minor release of Drupal 8.

Drupal 8 is secure

One of the most important effects this will have on organizations is that Drupal’s security team will no longer provide support or Security Advisories for Drupal 6. FFW (and the Drupal community as a whole) strongly encourages anyone with a Drupal 6 site to upgrade to Drupal 8 because of its many advantages and secure framework.

Drupal 8 is a mature and highly-secure CMS framework, with a global community of experts and peer review processes dedicated to maintaining security. Community members from all around the world guarantee Drupal 8 is strong enough to mitigate common vulnerabilities. Some of the largest organizations in the world trust Drupal for its stable and well-supported platform that will keep sensitive information (such as user profiles, documents, and other data) secure and private at all times. 

Drupal 8 has countless advantages

Our FFW Center for Excellence recommends upgrading from Drupal 6 to Drupal 8 because D8 offers a variety of new benefits that make the platform better than ever before. Drupal 8’s native web service integrations are mobile-driven (while Drupal itself serves as the data source), ensuring your stable D8 site looks great on any device. Drupal 8 also offers unmatched ‘future-proofing’, meaning your new Drupal 8 site is built to last. D8 is compatible with the most current versions of all major internet browsers and will remain compatible with future versions. But this is the best part: D8 is built with more widely-used coding practices than ever before, guaranteeing that the platform’s flexibility and scalability are accessible more developers and development teams than previous versions of Drupal.

By contrast, Drupal 6 is already incompatible with several prominent browsers. This shortcoming is due to outdated coding standards and markup that Drupal 6 supports. While Drupal 6 and 7 provide some core functionality with the standard installation, Drupal 8 is the first to offer unprecedented out-of-the-box capabilities that provide feature-rich websites without having to install, configure, and maintain numerous add-on modules to achieve the functionalities that matter most to your organization.

Still not convinced? Here are some more advantages to adopting Drupal 8:

Mobile-friendly, mobile-first 

All built-in themes in Drupal 8 are responsive, and administration pages are even designed for use on mobile devices. At last, data tables automatically scale according to screen size, eliminating the previous struggle for content editors working with Drupal 6, and even Drupal 7. This is a key feature for sites that report and distribute statistical data.

Easy in-place content editing

With the new editor functionality and bundled CKEditor WYSIWYG editor, Drupal 8 allows your to perform in-place content editing without ever having to load the full edit form.

More field types in core

Drupal 8 extends its signature content structuring system by including more field types in core and allowing fields to be attached to more types of content. You can also attach fields to forms to create custom contact forms.

We believe in Drupal 8

Did you know FFW launched our own website on Drupal 8? Our confidence in this new platform isn’t unprecedented; we have been involved in the development and refinement of D8 and supporting tools and modules throughout development. FFW is also currently in active development of several Drupal 8 projects with reputable clients, including a multilingual site for a publicly traded biomedical company and a new site for one of the largest open source organizations in the world.

One of our own Drupal 8 developers, Jesus Manuel Olivas, is the lead contributor to the Drupal Console project, a suite of tools that you run on a command line interface (CLI) to generate boilerplate code and interact with a Drupal 8 installation. 

We trust this platform, and we can’t wait to work with you to ensure your website is as stable, secure, and long-lasting as possible. Make sure to visit our events page to sign up for one of our free Drupal 8 trainings. Talk to us about how we can help you move from Drupal 6 to Drupal 8, and don’t hesitate to reach out with any additional questions about D8.

Feb 10 2016
Feb 10
New Training Format for 2016 FFW is proud to announce that we have changed the format of our training sessions. After an overwhelming positive response from our free trainings, we have decided to expand our training sessions and bring them straight to you, in person.
Jan 27 2016
Jan 27

As more and more organizations grow their digital presence into online empires, the demand for innovation and efficiency for managing content across a number of websites has never been greater. This ranges from global associations centrally managing content and website functionality for their many local chapters and corresponding digital properties to record labels that run hundreds of artist websites on a single platform. 

If you follow the world of websites and content management, you probably know how critical multi-sites have become for organizations that face these issues. You might also know that Drupal is widely regarded as the CMS that is used to deliver the most robust multi-sites in the world. This includes massive web platforms like of the City of Copenhagen, the National Audubon Society, and Warner Music Group. In many ways, multi-sites are much like a series of roads, leading users on a journey to find connected content that seems stretched across the Internet but actually exists on a unified platform. 

With a multi-site solution, web teams effectively have a network of sites that run on a single unified platform. Each site shares the same code but has a different database. This means that content, configuration, and appearance can be vastly different, yet the code behind it all is consistent and managed centrally. This presents some huge advantages and efficiencies when it comes to managing a portfolio of websites, both for developers and content editors. 

To discuss the wide variety of benefits multi-sites can provide organizations, I have put together a series of blog posts that will delve into the benefits of multi-sites, whether a multi-site solution is right for your organization, and whether a multi-site makes sense for everyone. 

Organizing Content across Different Sites

I’d like to begin our exploration of multi-sites by taking a look at the topic of content sharing with multi-site solutions. Content sharing has been an important topic as multi-site solutions continue to evolve. Different organizations have varying approaches to organizing their content across multiple sites. FFW has worked with some organizations that have what we would consider loose relationships between content across multiple sites. In such a case, each site was managed by a web team that had their own group of editors, which required every group to be responsible for creating and managing content on individual sites. 

However, there are some cases where editors want to use content across different sites. There are several options for how organizations can choose to share content across different sites. Among these options, organizations can choose between pulling individual articles from another website or subscribing to the feed and pulling all the content appearing in that particular feed to their site automatically. 

Content Sharing with Multi-site Solutions

The main goal of multi-site and content sharing solutions is to build a system that is easier for editors to use. This should be simple, where the only action editors need to do to pull the content from its original home and display it on a different site is to copy the URL of the article they want to pull in and paste it to the backend. Everything else is automated. On a technical level, each site provides a metatag with the URL from where the article is imported. That URL is a service call that provides the content is in JSON format, which is easy for the system to parse and run the import. We also use tagging so the content editor is able to specify what tags this content should fall into. Different sites have different sets of taxonomy, and what makes sense for one site might not work for another.

A similar approach has been taken for subscribing to the feed. Each website has pages that list content by terms. When editors want to subscribe to a page, all they have to do is copy the URL of the page, paste it to special form, and specify the tags all content should fall into. 

Models for Content Sharing

When sharing content across multiple sites, organizations can choose between sharing all content or select types of content. Systems can either pull content fully (all images, texts, fields etc.) or pull the teasers only. Visitors can be redirected to the site the content is being pulled from in order to read the full version via the teasers. The decision between these two options depends on what goals the organization wants to meet and is typically made by businesses on a case-by-case basis. Most importantly, organizations must determine how comfortable they feel with content displaying on other sites in its full version, meaning they will not receive visitors on other sites.  

Another interesting situation can occur when displaying teasers.  Let’s say that content X has been created on Site 1. Site 2 is interested in a feed where article X is displayed and subscribes to it. Site 3 pulls the feed from Site 2 where content X displayed. In this situation, it’s important to note that if visitors on site 3 click on content X teaser, they are redirected to Site 1 instead of site 2 since this is where the content was originally created. This is why we always keep the original references. 

When driving visitors of one site to another, it’s also important to ask site owners if they would like to keep the references to the site where content has been seen the first time. During one of our projects, FFW implemented a special block on a site that displayed information where visitors are coming from with the link to that site (page).  This way, we could drive visitors back to original site. 

The Benefits of Multi-site Content Sharing

As you can see, multi-site content sharing has a number of advantages that can be utilized by many corporations, from universities to commercial brands and associations. We’d love to hear from you about how you’ve used multi-site content sharing to grow your business. Feel free to discuss in the comments or reach out to us with any questions.

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web