Nov 24 2017
Nov 24

Drupal 8 represents some major changes to the way we work with themes. There is now Twig, asset libraries, component based CSS, to name a few of the changes. If you are used to working with themes in Drupal 7, all these changes can be overwhelming. But it is well worth the effort - building themes in Drupal 8 is a much improved experience.

Over the course of the coming weeks and months, I’ll be sharing tutorials specifically on Drupal 8 theming to help you get over the learning curve. In this first post, I’m exploring some of the key changes in Drupal 8.

Theme location

You can store your theme in three different locations in your code base in Drupal 8:

  • themes
  • sites/all/themes
  • sites/(site name)/themes

If you are running a multi-site, you’d create your theme in sites/(site name)/themes , with (site name) being the name of the site. Otherwise, the recommended approach is to put your theme in the themes folder.

Compared to Drupal 7

In Drupal 7, the themes folder was reserved for core themes. As such, custom and contributed themes should not be stored there. In Drupal 8, core themes have been moved to the /core folder.

This is where you keep meta-data and settings for the theme. The name of this file should match the name of the theme. This is the only required file in a theme in Drupal 8 and a theme cannot exist without this file.

Here is an example of a simple .info.yml file:

name: Responsive Skeleton
type: theme
description: 'Responsive, mobile friendly base theme based on Skeleton'
package: Core
core: 8.x
  - responsive_skeleton/global-styling
  header: Header
  highlighted: Highlighted
  help:  Help
  content: Content
  sidebar_first: 'Left sidebar'
  sidebar_second: 'Right sidebar'
  footer: Footer

If you’d like to learn more about YAML files, check out my introduction to YAML in Drupal 8.

Compared to Drupal 7

In Drupal 7, this file would be called A lot of the information would be the same but it would be in the INI format rather than YAML. If you have done any Drupal 7 development, the information will look familiar to the above snippet. One of the key differences between Drupal 7 and 8 is that the key value pair are separated with an equals sign (“=“) in the INI format used in Drupal 7, and colon (“:”) in the YAML format used in Drupal 8. There needs to be a space after the colon.


This is a PHP file used for additional logic (that should not be in template files) and preprocessing variables for templates.

Compared to Drupal 7

In Drupal 7, this file would be called template.php. A lot of the hooks, such as hook_preprocess, are the same (and some have been removed). The change of name from template.php to THEMENAME.theme brings it inline with the naming of module files (MODULENAME.module).


Templates provide the HTML structure for the site. Drupal 8 uses the Twig theme engine.

Example template files:

  • block.html.twig
  • comment.html.twig
  • node.html.twig
  • page.html.twig

Example twig file (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{{ content_attributes.addClass('content') }}>
      {{ content }}
  {% endblock %}

Compared to Drupal 7

The default theme engine in Drupal 7 is PHPTemplate. The templates in Drupal 7 included PHP code. There is no PHP code in the Twig templates in Drupal 8. Twig brings many advantages over PHPTemplate including enhanced security and inheritance.


This folder contains your theme’s CSS files. In Drupal 8 there is a recommended best practice for how you architect your CSS files that should be followed, which is based on SMACSS and BEM. This helps to create CSS that is reusable (components that can be reused multiple times), maintainable and scalable.

Here is an example for a really simple theme:

|- base/
|—- elements.css
|- components/
|—- block.css
|—- breadcrumb.css
|—- buttons.css
|—- header.css
|—- node.css
|—- table.css
|—- views.css
|— colors.css
|- layout.css
|- print.css

The files in the components are small self-contained chunks.

In order for your Drupal site to use the CSS files, they should be listed in THEMENAME.libraries.yml (see below).


This file contains a list of CSS and JS libraries to use in your theme.

Here is an example of adding CSS files in a theme’s .libraries.yml file:

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

You can also load CSS files only when needed, rather than for every page in the site. In the following example, node.css is loaded on node pages only.

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

      css/node.css: {}


Used to define responsive breakpoints for your theme.

Wrapping up

Moving from PHPTemplate to Twig, INI format to YAML, new CSS architecture and managing CSS and Javascript as library assets are some of the main changes in theming in Drupal 8. These changes have improved security and inheritance and made theming more elegant. I’ll be sharing a lot more about each of these in the coming weeks and months! If you’d like to be first to get them, jump on my newsletter list.

Nov 24 2017
Nov 24

We have sat down with our Commercial director, Iztok Smolic and ask him a couple questions. Enjoy the interview. 


When did you start working at AGILEDROP and what were your initial responsibilities?

I am one of the co-founders of AGILEDROP, so I am with the company from its beginning. In the early days, all of us wore many hats. In my case, 60% of the time I was working on the development and the other 60% I was communicating with new clients and wrote proposals (yes, I did some overtime). As we grew I was able to focus on the thing I was best at, that was advising to clients and being creative and innovative in marketing.

What are your responsibilities as the Commercial director?

As the commercial director, I am responsible for sales and marketing. Sales at AGILEDROP means understanding what the agency is looking for and advise them on the solution. Marketing is how we make sure to stay on top of the mind with potential clients. I believe we can help any digital agency experiencing resource challenges; we just need the opportunity to prove ourselves. 


Iztok Smolič

What are your daily tasks?

My daily tasks depend on my projects. Sometimes I am managing a team of developers who are upgrading one of our websites, some other day I am involved with organizing an event in our office. I am communicating with agency owners and managers on a daily base. I make sure that I reach out to at least one existing or potential partner to learn what are they struggling with that day.

How does your typical work week look like?

Every Monday morning we start with a sync meeting, after that, I sit down with our MD, Marko, to talk about strategy. After that, it's a mixture of meetings, emails, and reading on new exciting topics that can help my customers. To be honest, I am not great at scheduling my time, and this is something I am continually trying to improve.

Who do you work with?

Most of the time I work with the management team to sync around schedules and development team to get an understanding how can we best help our clients. Because of that, I am in contact with everyone in the organization, which is cool. 

What is that you do that adds value to our services?

Having 11 years of Drupal experiences help me better understand challenges our clients face. I can make decisions faster with more confidence. I believe agency owners value my technical skills from the past as well as my ability to understand their business struggles.

If you have any other questions for Iztok, get in touch, he will be more than happy to answer them. 

Nov 23 2017
Nov 23

As seen in the recent Uber hack, storing secrets such as API tokens in your project repository can leave your organisation vulnerable to data breaches and extortion. This tutorial demonstrates a simple and effective way to mitigate this kind of threat by leveraging Key module to store API tokens in remote key storage.

Even tech giants like Uber are bitten by poor secret management in their applications. The snippet below describes how storing AWS keys in their repository resulted in a data breach, affecting 57 million customers and drivers.

Here’s how the hack went down: Two attackers accessed a private GitHub coding site used by Uber software engineers and then used login credentials they obtained there to access data stored on an Amazon Web Services account that handled computing tasks for the company. From there, the hackers discovered an archive of rider and driver information. Later, they emailed Uber asking for money, according to the company.

Uber could have avoided this breach by storing their API keys in a secret management system. In this tutorial, I'll show you how to do exactly this using the Key module in conjunction with the Lockr key management service.

This guide leverages a brand-new feature of Key module (as of 8.x-1.5) which allows overriding any configuration value with a secret. In this instance we will set up the MailChimp module using the this secure config override capability.

Service Set-Up

Before proceeding with the Drupal config, you will need a few accounts:

  • Mailchimp offer a "Forever Free" plan.
  • Lockr offer your first key and 1,500 requests for free.

These third-party services provide us with a simple example. Other services are available.


There are a few modules you'll need to add to your codebase.

composer require \
  "drupal/key:^1.5" \
  "drupal/lockr" \


  1. Go to /admin/modules  and enable the MailChimp, Lockr and Key modules.
  2. Go to /admin/config/system/lockr
  3. Use this form to generate a TLS certificate that Lockr uses to authenticate your site. Fill out the form and submit.
    Lockr Create Auth Certificate
  4. Enter the email address you used for your Lockr account and click Sign up.
  5. You should be now be re-prompted to log in - enter the email address and password for your Lockr account.
  6. In another tab, log into the MailChimp dashboard
    1. Go to the API settings page -
    2. Click Create A Key
    3. Note down this API key so we can configure in Drupal in the next step.
      MailChimp API Dashboard
  7. In your Drupal tab, go to /admin/config/system/keys and click Add Key
  8. Create a new Key entity for your MailChimp token. The important values here are:
    1. Key provider - ensure you select Lockr
    2. Value - paste the API token you obtained from the MailChimp dashboard.
      Key Create MailChimp Token
  9. Now we need to set up the configuration overrides. Go to /admin/config/development/configuration/key-overrides and click Add Override
  10. Fill out this form, the important values here are:
    1. Configuration type: Simple configuration
    2. Configuration name: mailchimp.settings
    3. Configuration item: api_key
    4. Key: The name of the key you created in the previous step.
      Key Override Create

... and it is that simple.


The purpose of this exercise is to ensure the API token for our external services are not saved in Drupal's database or code repository - so lets see what those look like now.

MailChimp Config Export - Before

If you configured MailChimp in the standard way, you'd see a config export similar to this. As you can see, the api_key value is in plaintext - anyone with access to your codebase would have full access to your MailChimp account.

api_key: 03ca2522dd6b117e92410745cd73e58c-us1
cron: false
batch_limit: 100
api_classname: Mailchimp\Mailchimp
test_mode: false

MailChimp Config Export - After

With the key overrides feature enabled, the api_key value in this file is now null.

api_key: null 
cron: false
batch_limit: 100
api_classname: Mailchimp\Mailchimp
test_mode: false

There are a few other relevant config export files - lets take a look at those.

Key Entity Export

This export is responsible for telling Drupal where Key module stored the API token. If you look at the key_provider and key_provider_settings values, you'll see that it is pointing to a value stored in Lockr. Still no API token in sight!

   - lockr
   - mailchimp
id: mailchimp_token
label: 'MailChimp Token'
description: 'API token used to authenticate to MailChimp email marketing platform.'
key_provider: lockr
 encoded: aes-128-ctr-sha256$nHlAw2BcTCHVTGQ01kDe9psWgItkrZ55qY4xV36BbGo=$+xgMdEzk6lsDy21h9j….
key_input: text_field

Key Override Export

The final config export is where the Key entity is mapped to override MailChimp's configuration item. 

status: true
   - key.key.mailchimp_token
   - mailchimp.settings
id: mailchimp_api_token
label: 'MailChimp API Token'
config_type: system.simple
config_name: mailchimp.settings
config_item: api_key
key_id: mailchimp_token


Hopefully this tutorial shows you how accessible these security-hardening techniques have become. 

With this solution implemented, an attacker can not take control of your MailChimp account simply by gaining access to your repository or a database dump. Also remember that this exact technique can be applied to any module which uses the Configuration API to store API tokens.

Why? Here are a few examples of ways popular Drupal modules could harm your organisation if their configs were exposed (tell me about your own worst-case scenarios in the comments!).

  • s3fs - An attacker could leak or delete all of the data stored in your bucket. They could also ramp up your AWS bill by storing or transferring terabytes of data.
  • SMTP - An attacker could use your own SMTP server against you to send customers phishing emails from a legitimate email address. They could also leak any emails the compromised account has access to.

What other Drupal modules could be made more securing in this way? Post your ideas in the comments!

Go forth, and build secure Drupal projects!

Photo of Nick Santamaria

Posted by Nick Santamaria
Systems Operations Developer

Dated 24 November 2017

Add new comment

Nov 23 2017
Nov 23

Is your commerce site ready for the big time? We're talking about Black Fridays, product launches, back-to-school weeks, and any other time you are going to get exponentially more traffic than you would normally get. A lot of people just assume their site/server/staff can handle such increased volume, but unless you've tested it by running 10 or 20 or 50 times the traffic through it, you really don't know.

The problem is that scaling doesn't work in a linear way. Let's say you're currently using 10 percent of your server's capacity. Simple math would indicate that you could handle 10 times as much traffic and be at 100% of capacity, so you should be fine.

But it doesn't necessarily work that way in the real world. It could be that there is some sort of hidden flaw that flares up when that volume of traffic comes through: maybe you hit some sort of race condition, or a caching system starts to cycle too fast, or you get a database bottleneck and everything gets backed up behind it. It could be some little glitch that's easily fixed and everything goes back to normal—but if you fix it halfway through the biggest sales day of the year, it's too late.

So how can you get ready?

1. Do performance testing.

Your goal should be to mimic live as much as possible. You don't just want to run the test on your local server. You want to spin up a similar environment, or maybe spin something up at 1/10th of the scale and hit it hard with lots of capacity. Or do it through Amazon and only run it for an hour or something to save on cost.

Once you have your environment, you have to try to simulate actual traffic. You don't want to just hit the home page repeatedly, because that's not how your customers interact with your site. They go through the checkout, and click around on product pages, and search, and log in to their account. They do a whole bunch of random stuff, and you have to try to mimic that. You can't do it perfectly, but you want to hit all the parts of your site and throw a bit of randomness in there to try to get as close to the real experience as possible.

In a perfect world, you would have gone through a similar event like Black Friday already and learned from it. But maybe you're a first-timer. Or maybe you're launching a big new product unlike anything you've had before, and it's backed by a TV spot, and you're expecting a massive volume of sales to follow. So test your site and be sure.

2. Prepare for stock issues.

Stock problems can obviously be much worse in a high-volume situation. On a slow day, if an order goes through when you are out of stock, maybe you could just call that person and say oops, sorry, but it's going to take a couple days to fill that order.

But if you have a huge burst of traffic, you might sell 20 items when you only have two in stock. And you can't even get 18 on your next order, and it's going to take six weeks to get that many, and now you have a real problem.

So if that happens, what do you do? How are you handling out-of-stock issues? Do you have messaging to say this is going to be delayed? Are you going to shift customers to alternate recommended products? These are all things you need to consider.

3. Set staffing levels appropriately.

You don't want to be in a situation where your website can handle the traffic, but your human workers cannot. In a physical store, everyone knows they need to up the number of sales staff to deal with a huge crush of shoppers. But when it comes to the website, sometimes people forget that someone still needs to put 10 times as many items in boxes, and deal with 10 times as many email complaints, and talk to 10 times as many customers via live chat.

How does your current process scale? How fast does it take you to do an order? Maybe you need to think about automated shipping, or standardized box sizes, or any one of a number of other things that will make your staff's lives easier during high-volume times.


As you can see, there are quite a few things that you can do to make sure your opperating smoothly during those peak sales days throughout the year. Some of these things you can do yourself. Some of them you might need some technical support. If support is what you need, or you'd like to discuss this further, contact us. We've been through it all before and can share our experience.

Contact us!

Nov 23 2017
Nov 23

As mentioned in my previous post, I’ll be sharing the videos of the various talks by Amazees at Drupal Camp Cape Town 2017, over the upcoming weeks. 

First up we have Head of Global Maintenance at Amazee Labs, Bryan Gruneberg, who spoke about "Maintainability and Longevity - Keeping customers and developers happy". Maintaining strong, robust sites that evolve with the client’s needs is of utmost importance to us and was a topic that received a lot of interest from Camp attendees. 

Enjoy the Video!

[embedded content]

Nov 23 2017
Nov 23

Everyone who codes in Drupal will sooner or later encounter the need to define tighter control of access to content. The standard mechanisms of roles and permissions are very flexible, but they may be insufficient in complex projects. When access to nodes starts to depend on, for example, fields assigned to a given user, then you have to take advantage of more advanced solutions. In Drupal 7 and 8 we can use a hook – hook_node_access() or a so-called grants mechanism.

Permission control using hook_node_access()

In cases where advanced permission control is needed, hook_node_access() is the most popular choice. There are some slight differences between Drupal 7 and 8, but the way it works is more or less the same. It takes three arguments: $node, $op and $account.
With every attempt to access a given node, Drupal will call mymodule_node_access() in all modules and check whether a given user $account has all the necessary permissions to run $op in a $node. The hook should return one of the following responses:

AccessResult::allowed() (lub NODE_ACCESS_ALLOW in version 7)
AccessResult::forbidden() (lub NODE_ACCESS_DENY in version 7)
AccessResult::neutral() (lub NODE_ACCESS_IGNORE in version 7)

Simple, yet effective, isn’t it? This is what it looks like in practice (D8):

use Drupal\Core\Access\AccessResult;
use Drupal\node\NodeInterface;
use Drupal\Core\Session\AccountInterface;

function mymodule_node_access(NodeInterface $node, $op, AccountInterface $account) {
  $type = $node->getType();
  if ($type == 'foo' && $operation == 'view') {
    if(strstr($account->getEmail(), '')) {
        return AccessResult::allowed();
    else {
      return  AccessResult::forbidden();
  return AccessResult::neutral();

It would seem like access control using hook_node_access() would be enough for even the most advanced needs, but as they say, there’s no rose without thorns. Checking a long list of nodes one by one will surely negatively impact efficiency. In particular, the Views and Menu modules cannot afford to use that hook too often. Due to optimisation reasons, the developers of Drupal limited the calling of hook_node_access() only to nodes displayed in the “Full” mode. In all other cases, you have to rely on standard roles and permission system or use less resource-heavy Access Grants.

Access Grants

Even though it’s very easy to understand the principle of operation of hook_node_access(), Access Grants is a far more complex subject. Some bloggers try to present it using a metaphor for doors, locks and keys. Personally, I think that stretches the truth a little bit too much. That’s why I’m going to go with a comparison to a secret military base.
Attention! What does a military base have in common with Drupal? Well, for instance, both of them have restricted areas where you can get only if you have proper authorisations and permissions. What is more important, in both cases the users and visitors are given passes that clearly define the scope of what they can see or do upon entry.
In standard permission system used by Drupal, we have a single guard, who checks the role of a user on their pass. The role defines all the actions that the user can do (e.g. reading a Type A node, reading and writing to a B type node...) 
In mymodule_node_access(), there are multiple guards, one for each module. Each one of them identifies the user and determines if they will be given access based on selected criteria. Every guard has full access to user data, as well as to the protected area (node) – their decision is based on all of these factors.
What is the role of the aforementioned Access Grants? They divide authorisation process into two separate parts, which are served by two separate hooks. The way they are used in Drupal 7 and 8 is almost identical.

1) hook_node_access_records()

The first hook is activated when the node is saved. It has one argument – $node. The role of a hook is to determine the list of the so-called grants – passes that have to be showed when access to the node is attempted. 

function mymodule_node_access_records(\Drupal\node\NodeInterface $node) {
  return $grants[] = [
    'realm' => 'realm1',
    'gid' => 12345,
    'grant_view' => 1,
    'grant_update' => 1,
    'grant_delete' => 1,
    'priority' => 0,

Every grant has its own realm. The user, who attempts to access a given node has to have at least one grant (pass) in every defined realm. For example, if Drupal builds the following list of grants based on all the hooks it finds:

$grants[] = 
[ 'realm' => 'realm1', 'gid' => 123, … ],
[ 'realm' => 'realm1', 'gid' => 456, … ],
[ 'realm' => 'realm2', 'gid' => 789, … ]

The user needs to have at least one realm1 pass and one realm2 pass in order to access the node.
Complicated? I’ll try to present it using my military analogy. Let’s assume that our secret base has several departments (we’ll use them to convey the concept of realms). Every department has its own guard at the entrance to every restricted area. A user who wants to access a given area needs to go to each guard and shows that he has an appropriate pass (that is, a grant). If the guard determines that user’s pass complies with the requirements of his department, he allows the user to pass further. If the user doesn’t have a pass, they won’t be able to access the area and he won’t be checked by other guards.
Why is this approach faster? It’s because the guard doesn’t have to know the details of authorisation (or have access to the node at all), he only needs to compare the passes.

What is a realm?

A realm (or as I called it in my military metaphor – a department) can be any string, usually, the name of a module is used. Such an approach makes the grants system somehow cleaner and more understandable – the user needs to have one grant (pass) for each module that defines its own node access rules using hook_node_access_records(). You can use this convention if you don’t consider it to be overly simplified. 

All or nothing

Using authorisation mechanisms, sometimes the need arises to use two extreme scenarios: access for all or only for the administrator. In the first case, all that is needed is to return an empty list of grants in a hook. This will mean that in a given realm, the users don't need any passes. In the second case, one has to define a grant that won’t be given to any user whatsoever.

2) hook_node_grants()

Who grants the grants (passes) to the users? The answer is – again – a hook. In this case, it’s hook_node_grants(), which is executed at each attempt to access a given node. It uses two arguments – user account $account and the operation – $op. Using these two arguments, it determines the list of grants identified using realm (key) and identifier (value).

use Drupal\Core\Session\AccountInterface;

function mymodule_node_grants(AccountInterface $account, $op) {
  if ($op == 'view') {
    $grants['realm1'] = array(123);

Notice, that the above hook doesn’t have access to $node. This is why the grants mechanism is much quicker, as it doesn’t require the node to be loaded each time it needs to be accessed. Thanks to that grants defined by you can be taken into consideration during building views and generating menus.

Permission reset

When you start working with the grants mechanism, you can stumble upon several unexpected problems. When your authorisation doesn’t work properly, you should first and foremost try and rebuild the node_access table in Drupal’s database. You can do it using node_access_rebuild() function or by going to /admin/reports/status/rebuild (you can find this link in the Status Report in your administration panel).
If your grants won’t work as intended after a rebuild, give the node_access table a good read and check if to contains a row with nid=0, gid=0, realm=all. This entry is added by default during Drupal installation and it turns off the entire grants system. This row doesn’t indicate any error – without that entry, the access to content on the entire website would be available to the administrator only.

Types of operations

Most probably you noticed that I omitted the types of operations on a node in my description of grants. You can decide what types of operations (view/update/delete) will be available to each user in both hooks presented above (just check the examples!) You have to remember one thing: if a number of grants will be available for a given realm, the one with the highest access level will be always selected.


At the end of this article, I want to remind you that all the permission mechanisms in Drupal work in parallel. You can, therefore, mix all the authorisations and access control methods together. It’s also worth noting that there’s an ongoing discussion at to turn the grants system into something that’s easier to understand and more in line with an object-oriented approach. However, we wouldn’t expect any revolutionary changes anytime soon.
Dismissed! :-)

Nov 23 2017
Nov 23

Developers often come across a situation where they are required to reduce database load by caching DB objects in RAM. Here Memcache improves Drupal application performance by moving standard caches out of the database and by caching the results of other expensive database operations. 

Note that Drupal doesn’t support Memcache by default, and for this, we need to install it on the server. Let’s see how to install Memcache on the server and configure it with Drupal 8 to reduce the load on the database with every page load.

Let’s see how to install Memcache on server

Open the terminal on your local machine and run the following codes:

Step 1: sudo apt-get update

Step 2: sudo apt install memcached

Step 3: sudo apt install php-memcached

Step 4: Make sure Memcache daemon is working fine by running the following command: 

“ps aux | grep memcached”

Step 5: Also, check whether the Memcached extension is properly configured in PHP7 by creating info.php page.

nano /var/www/html/memcache/info.php

And enter the below code 


Step 6: Now restart both Memcached and php7-fpm services 

service memcached restart
service php7.0-fpm restart

Step 7: Go to any web browser and access info.php as 

http://localhost/memcache/info.php”, and search for “Memcache” you will see the screen similar to the one mentioned below.

Memcache server

After installation of Memcache in your server, download Memcache module and Memcache Storage module. Now go to “” and enable the two modules.

Memcache Enabled

Configuring Memcache with Drupal 8:

Open your site settings.php and paste the below code. Here we are using Memcache storage for Drupal 8 as it provides an integration of D8 and Memcached PECL.

// Set’s default cache storage as Memcache and excludes database connection for cache
$settings['cache']['default'] = 'cache.backend.memcache_storage';
// Set’s Memcache key prefix for your site and useful in working sites with same memcache as backend.
$settings['memcache_storage']['key_prefix'] = '';
// Set’s Memcache storage server’s.
$settings['memcache_storage']['memcached_servers'] =  ['' => 'default'];

To debug Memcache include below code following above code in settings.php

// Enables to display total hits and misses
$settings['memcache_storage']['debug'] = TRUE;
Memcache debug

Note: Before uninstalling Memcache and Memcache storage, comment/delete Memcache settings code from your settings.php file.

That’s it! If you are planning to configure Memcache with Drupal, you need to look out for three things: which cache bins will be offloaded with Memcache; website traffic and volume of content; and the amount of RAM allocated to Memcache. 

Now you know how to configure Memcache with Drupal 8 to reduce database load. Go ahead and try it on your own website. In case you need any help in installing and configuring Memcache with Drupal 8, do leave a comment below and I will get back to you ASAP!


Nov 23 2017
Nov 23

When you think of training, perhaps you remember an event that you were sent to where you had to learn something boring for your job. The word training does not usually make people smile and jump for joy, that is unless you are talking about Drupal training. These gatherings spread the Drupal knowledge and increase diversity in the community of Drupal developers.

Join us for the next Drupal Global Training Day with our online full day session on getting started with Drupal on November 29th. It will be held online from 9 AM to 4 PM EST.

Sign up now.

A link to the live workshop on Zoom will be provided when you sign up!

The Drupal Association coordinates four dates each year as Global Training Days, designed to offer free and low-cost training events to new-to-Drupal developers and to create more Drupal talent around the world. The community is growing exponentially as more people learn how fun and easy it is to get involved and be productive. Volunteer trainers host these global events in person and online. In 2016, a Global Training Days Working Group was established to run this program. There is a Global Training Days group on that lists trainings around the world.

Mauricio Dinarte will be leading the training online on November 29th. As an introduction to Drupal a person needs to learn certain things that are specific to Drupal and some are not that intuitive. It is important to cover the very basics in terminology and process. An introductory class can include many things, but this list is what Mauricio covers during the day long event:

  • Drupal installation requirements and process
  • Nodes
  • Content types
  • Fields
  • Blocks
  • Theme regions
  • Views
  • User and permissions
  • Menus
  • Taxonomy

The outcome of the day of training is that everyone walks away understanding the main moving parts of Drupal and a bit about what they do. Of course you will not become a developer overnight, but you will have enough information to build a simple site and then explore more of Drupal on your own.

You can follow up with many online tutorials and by joining the Drupal group in your area and attending the meetings. At meetings you will connect with other people at different levels of skill and you will be helped and helpful at the same time! If there is no Drupal group in your area, I suggest you start one. It can start as easily as posting online that you will be at a specific location doing Drupal at a certain time of day - you will be surprised at who may show up. If no one shows up the first time, try again or try a different location. One of the best things about Drupal is the community and how large and connected we are. If you start a group, people will usually help it grow.

Bringing new people to Drupal is not only good for increasing the size of the member base, it also brings diversity and reaches people that may never have had an opportunity or access to a free training. Drupal trainings are usually held at a university in or near a city which attracts people from different backgrounds and cultures. We can also reach people that are not in a city or near a school by sharing online.

Have you ever thought about volunteering at a Global Training Days event? We have a blog about organizing your own Global Training Days workshop that can get you started. This is a great way to get to know the people in the community better, up your skills and perhaps share something you have learned. I learned much about programming by assisting developers at sprints and trainings. This is where the real fun begins. Learning does not have to be stressful, and in the Drupal community people are friendly and welcoming. No question is stupid and even those with no experience have valuable skills. Developers love people without prior experience because they make the perfect testing candidates for UI and UX. The down side is that Drupal is so captivating that you will probably not remain a newbie for very long, so enjoy it while it lasts.

One of the true highlights of Global Training Days is seeing all the people around the world gain valuable skills and share knowledge. We hope you can join us.

Nov 23 2017
Nov 23

Last week I switch from years of using Chrome to Firefox 57 because of all the hype about it being fast, and that I'd been suffering from Chrome using up to 10GB of ram. The big issue I hit though was I didn't have Dreditor and there seemed to be no way to install it. I decided to go on using Firefox without Dreditor, and loading Chrome every time I needed to do an in depth patch review.

Then yesterday I saw the latest Commit Strip cartoon, where in a reply @williambl suggested Chrome Store Foxified for converting Chrome plugins to Firefox. First thing I thought was to try the Dreditor Chrome plugin, and it worked.

This morning Berdir suggested "maybe someone will release that thing as a public extension". So I went digging on and found I could download the XPI file Chrome Store Foxified created during the conversion.

So here it is:
Download Dreditor for Firefox now!
MD5SUM: 2b7455e057ac6a84bd01423b0984c21d

Nov 23 2017
Nov 23

GraphQL is becoming more popular every day. Now that we have a beta release of the GraphQL module (mainly sponsored and developed by Amazee Labs) it's easy to turn Drupal into a first-class GraphQL server. In this second post of the series, we'll describe they way Drupal fields are represented in GraphQL and look at a few examples.

Last week we talked about the new structure of the GraphQL package. We have also looked at the tools bundled with the module - the explorer and the voyager - and we've explored how to fetch a username. Now let's use GraphiQL to assemble queries that are a bit more complex.

The Naming

GraphQL naming conventions are slightly different than Drupal's.

  • Fields and properties are in camelCase. This means that field_image in Drupal becomes fieldImage in GraphQL and the revision_log property becomes revisionLog.
  • Entity types and bundles use camelCase with the first letter capitalized so taxonomy_term becomes TaxonomyTerm and the tags vocabulary becomes TaxonomyTermTags. As we can see bundles are prefixed with the entity type name.

The structures

While fields and properties both translate to the same GraphQL structure called Field, entity types and bundles, despite sharing the naming convention, don't. The former is implemented as GraphQL Interfaces and the latter are GraphQL Types (implementing these Interfaces). As an example: 

This query contains fields from 3 different GraphQL structures that build upon one another.

  • entityId and entityCreated come from the Entity Interface. These fields are available for all entity objects. nodeById query returns a Node Interface which extends Entity Interface.
  • title and status are defined in the Node Interface and are available for all nodes, regardless of their content type.
  • fieldSubtitle is a field (field_subtitle in Drupal) that has been added to the Article content type. It's not a part of neither Node nor Entity Interfaces, it is only available in the NodeArticle Type. nodebyId can return any node, not just Article, so we need to wrap the fieldSubtitle in a GraphQL Fragment.

If we paste the query into GraphiQL (/graphql/explorer) we'll get a result similar to this one:

The Fragments

GraphQL Fragments, as the name implies, are just pieces of a query. They mostly serve two purposes:

  1. Executing part of a query conditionally - only when the result is of a specified type. In the example above fieldSubtitle will be evaluated only when the node with id 1 is an Article. If it turns out to be a Basic Page, the fragment will be omitted and the response will just be one field shorter without raising any exceptions.
  2. Reusability. A fragment can be given a name and be used more than once.

There are two fragments in this query. The first one starting on line 3 is an inline fragment. We need it because fieldCategory and fieldTags are only attached to Articles and nodeById can return any node.

The other one, defined on line 18, is a named fragment thanks to which we don't need to repeat the sub-queries for fieldCategory and fieldTags.

This is how the result could look like. Node 1 is an Article, it has 2 tags in one category term.

The Aliases

There might be situations when we want to use the same field more than once in a single query, to fetch node 1 and 2 simultaneously for instance. We can do that thanks to GraphQL Aliases

Here we're calling nodeById twice, each time with different arguments and aliases. The former will appear under nodeOne key in the result and the latter will be available under nodeTwo. We've also transformed the inline fragment holding the article fields into a named fragment and used it in both queries to reduce unnecessary repetition.

That's it for this post. In the next one, we'll see how to retrieve the values of Drupal fields and properties.

Nov 23 2017
Nov 23

Drupal has become one of the most popular CMS around the world. Since it is written in PHP, very popular web programming language, it is also attractive to developers. It has nearly forty thousand modules and more than two thousand different themes, so it's no wonder that developers and designers like to work with it. It is suitable for all types of websites, from those advanced and heavier portals for communities to lighter, simpler personal web pages. Most importantly, it's great for ambitious websites (link to blog post about this).

What are other benefits we recognize?

It is open source software.

That means that anyone can download, use, work on, and share it with others. It’s built on principles like collaboration, globalism, and innovation. Since core software, modules and a large number of themes are open sourced; web development cost can be reduced significantly.

It is SEO friendly.

SEO is number one when it comes to online marketing strategies. In order to achieve great website rang with keywords people search to discover your products online, Drupal has the excellent flexibility of display content. And one more thing we see as very important, Drupal has the ability to give pages aliases, so times, when URL was like “” are over, better version of it is “”. Search engines prefer the second version, and readers do as well.  

It is mobile-ready.

Smart devices are becoming increasingly widespread, and web pages, made on Drupal's platform, can be viewed the same on smart devices as on desktop computers. This additional feature is a great advantage for businesses, because it allows them to spend less on optimizing mobile pages, and the traffic is automatically increased as the number of customers who prefer smart devices is increasing every day.

Drupal conference

The community.

Drupal has a highly active community which participates in every aspect of Drupal developing and is responsible for Drupal being the most successful software on the market.  Is one of the largest open source communities, and we all support each other, and we are doing everything to make Drupal the best.


Because Drupal is an open source system, the questions arise whether it is safe. In a closed-source system that is licensed, the code is closed to the eyes of the public, so it's impossible to figure out how many bugs are waiting for us in this system. As an open source system, Drupal is open for everyone, so bugs are found faster and defective, so security should not be the reason for not picking Drupal for your website, straight opposite.

There are much more benefits of Drupal; we chose 5 of the most significant of them. We cannot escape the truth that Drupal is getting more and more powerful every day. With all those people behind it, providing a free open source solution for everybody, we are not surprised. If u have any more questions about Drupal, reach out to us, we are more than happy to answer them.

Nov 22 2017
Nov 22

Ready to level up your skills before the New Year? You're in luck! Promet Training has confirmed Drupal 7 and Drupal 8 courses for developers, project managers and content editors coming up. Each month, Promet Training offers classes in AustinLas VegasWashington, D.C., Chicago & Live Online. Visit for the full course schedule and sign up today.

This four-day course provides a comprehensive understanding of Drupal 8 Site Building and Front End development. The procedures throughout the week are introduced step-by-step and then reinforced with practice and challenges. You'll build multiple sites and themes to meet the needs of a client and reflect on your own experience to take the procedures you learn back into your own work and any new situations you encounter.

November 27-30 / Washington, D.C. (Confirmed Course)

This five-day course provides a comprehensive understanding of Drupal 8 for developers responsible for full stack development. The procedures throughout the week are introduced step-by-step and then reinforced with practice and challenges. You'll build multiple sites, a custom theme and a few custom modules to meet the needs of a client and reflect on your own experience to take the procedures you learn back into your own work and any new situations you encounter.

This course allows developers to walk through the process of building multiple custom modules and provides techniques and best practices for developing custom functionality to extend the capabilities of Drupal.

Quickly get developers running full speed ahead in Drupal 8, and convey a full understanding of how Drupal sites are constructed and how the system works. 

December 11-15 / Las Vegas, NV

December 18-22 / Live Online (Confirmed Course)

This 4 day class provides a broad introduction to the essential skills necessary for editing content, building websites, managing the theme layout and working with the extremely popular Panels module.

December 11-14 / Austin, TX

Nov 22 2017
Nov 22
Drupal 8 - Smart Cropping of Media with Image Widget Crop

Sometimes, in your Drupal site, you may need to crop images with a predefined aspect ratio but with different size values within a certain range. This is where the Image Widget Crop module is your tool for the job.

It can be used in a great variety of Drupal sites. From image galleries to educational sites with illustrations.

In this tutorial, you’ll be using the contrib Image Widget Crop module in conjunction with the new media features for images available in Drupal core.  

Step #1. Create and Configure the Media Entity

To make the most of the Drupal core media features:

  • Install the Media Entity Image module
  • Go to Structure > Media bundles
  • Click Add media bundle

Click Add Media Bundle

  • Give your Media bundle a title and a description
  • Choose Image in the Type provider dropdown
  • Uncheck the Published checkbox
  • Click Save media bundle

Click Save Media Bundle

Next, you will add an image field to the Media bundle you’ve just created.

  • On the dropdown on the right click Manage fields
  • Click Add field 

Click Add Field

Manage Fields

  • Choose the Image field type
  • Give it a label
  • Click Save and continue

Click Save and Continue

  • Leave the defaults and click Save field settings
  • Click Save settings once again 

Click Save settings

You have created a Media bundle with an image field attached to it. Now you have to reference this Media bundle within a Content type through a Reference field. Let’s do just that! 

Step #2. Reference the Media Bundle within the Article Content Type

  • Click Structure > Content types > Article > Manage fields
  • Delete the default image field of the Article Content type 

Notice: I’m working in a sandbox installation with dummy content. Please, don’t delete anything if you have actual content in your Article Content type.

Click Delete

  • Click Add field
  • Give your new field a proper name
  • Choose Other in the Reference subsection
  • Click Save and Continue

Click Save and Continue

  • In the Type of item to reference choose Media
  • Click Save field settings

Click Save field settings

  • Select the Media bundle you created in Step #1 
  • Click Save settings

Click Save settings

Good job! You have referenced the Media bundle you created in Step #1.

Step #3. The Image Widget Crop Module

Next, you will add images to your Media bundle and enable the crop functionality of the Image Widget Crop module.

  • Download and enable the Image Widget Crop module
  • Go to Configuration > Media > Crop types in to create the Crop type you’re going to use
  • Click Add crop type

Click Add crop type

  • Give your Crop type a proper name. For example, Image_Widget_Crop
  • The Aspect Ratio refers to the relation between the width and the height of the image. I’m going to choose 16:9 for this exampĺe. It is common for wide screens. Other common aspect ratios are 1:1 (square) or 4:3 (like old TVs)

Aspect ratio

Aspect ratio

  • The SOFT LIMIT dictates the size at which a warning will be displayed if I carry on reducing the size of the image 
  • The HARD LIMIT dictates the smallest size an image will be cropped to
  • I’m choosing 640x360 for the SOFT LIMIT and 400x225 for the HARD LIMIT in this example
  • Click Save crop type

Click Save crop type

  • Click Configuration > Media > Image styles
  • Edit the Crop thumbnail style
  • Delete the default Scale effect
  • Select Manual crop
  • Click Add

Select Manual crop and click the Add button

  • For the Crop type choose Image_Widget_Crop (or whatever you called your crop type)
  • Click Add effect 

Click Add effect

Step #4. Add a Crop Type to your Media Bundle

  • Go to Structure > Media bundles > Images to crop > Manage form display
  • On the widget column of your image asset select Image_Widget_Crop
  • Click the cogwheel on the right
  • For the Preview image style select Crop thumbnail
  • Select your Crop type
  • Click Update
  • Click Save

Click Save

  • Click Manage display
  • Disable the Thumbnail
  • Hide the Media asset label
  • Click on the cogwheel on the right and select the proper image style
  • Click Update
  • Click Save 

Step #5. Create your Media Asset

  • Click Content > Media > Add a new media
  • Select an image from your computer, preferably a big one
  • Click on the down arrow to open your cropping widget
  • Resize the cropping area, and play with it a little bit
  • Notice that you get the SOFT LIMIT warning and it doesn’t go away. Even when you’ve reached the HARD LIMIT.

Copping applied

  •  Click Save once you’re satisfied with your cropping selection

Click Save

Step #6. Create your Content

  • Go to Content > Create Content > Article
  • Give it a body
  • Reference the media asset you’ve just created 
  • Click Save.

You’ll see your article with the cropped media asset 

Congratulations! You just learned how to use the Image Widget Crop Drupal contrib module. Along the way, you have also taken a quick look at Drupal 8 core media capabilities.

Please leave us your comments and questions below. Thanks for reading!

About the author

Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.
Nov 22 2017
Nov 22

This blog has been re-posted with permission from Dries Buytaert's blog. Please leave your comments on the original post.

Over the past weeks I have shared an update on the Media Initiative and an update on the Layout Initiative. Today I wanted to give an update on the Workflow Initiative.

Creating great software doesn't happen overnight; it requires a desire for excellence and a disciplined approach. Like the Media and Layout Initiatives, the Workflow Initiative has taken such an approach. The disciplined and steady progress these initiative are making is something to be excited about.

8.4: The march towards stability

As you might recall from my last Workflow Initiative update, we added the Content Moderation module to Drupal 8.2 as an experimental module, and we added the Workflows module in Drupal 8.3 as well. The Workflows module allows for the creation of different publishing workflows with various states (e.g. draft, needs legal review, needs copy-editing, etc) and the Content Moderation module exposes these workflows to content authors.

As of Drupal 8.4, the Workflows module has been marked stable. Additionally, the Content Moderation module is marked beta in Drupal 8.4, and is down to two final blockers before marking stable. If you want to help with that, check out the Content Moderation module roadmap.

8.4: Making more entity types revisionable

To advance Drupal's workflow capabilities, more of Drupal's entity types needed to be made "revisionable". When content is revisionable, it becomes easier to move it through different workflow states or to stage content. Making more entity types revisionable is a necessary foundation for better content moderation, workflow and staging capabilities. But it was also hard work and took various people over a year of iterations — we worked on this throughout the Drupal 8.3 and Drupal 8.4 development cycle.

When working through this, we discovered various adjacent bugs (e.g. bugs related to content revisions and translations) that had to be worked through as well. As a plus, this has led to a more stable and reliable Drupal, even for those who don't use any of the workflow modules. This is a testament to our desire for excellence and disciplined approach.

8.5+: Looking forward to workspaces

While these foundational improvements in Drupal 8.3 and Drupal 8.4 are absolutely necessary to enable better content moderation and content staging functionality, they don't have much to show for in terms of user experience changes. Now a lot of this work is behind us, the Workflow Initiative changed its focus to stabilizing the Content Moderation module, but is also aiming to bring the Workspace module into Drupal core as an experimental module.

The Workspace module allows the creation of multiple environments, such as "Staging" or "Production", and allows moving collections of content between them. For example, the "Production" workspace is what visitors see when they visit your site. Then you might have a protected "Staging" workspace where content editors prepare new content before it's pushed to the Production workspace.

While workflows for individual content items are powerful, many sites want to publish multiple content items at once as a group. This includes new pages, updated pages, but also changes to blocks and menu items — hence our focus on making things like block content and menu items revisionable. 'Workspaces' group all these individual elements (pages, blocks and menus) into a logical package, so they can be prepared, previewed and published as a group. This is one of the most requested features and will be a valuable differentiator for Drupal. It looks pretty slick too:

Drupal 8 Outside In Content Creation Prototype

An outside-in design that shows how content creators could work in different workspaces. When you're building out a new section on your site, you want to preview your entire site, and publish all the changes at once. Designed by Jozef Toth at Pfizer.

I'm impressed with the work the Workflow team has accomplished during the Drupal 8.4 cycle: the Workflow module became stable, the Content Moderation module improved by leaps and bounds, and the under-the-hood work has prepared us for content staging via Workspaces. In the process, we've also fixed some long-standing technical debt in the revisions and translations systems, laying the foundation for future improvements.

Special thanks to Angie Byron for contributions to this blog post and to Dick Olsson, Tim Millwood and Jozef Toth for their feedback during the writing process.

Nov 22 2017
Nov 22

Drupal 8 has a great AJAX form API which includes some tools to create modal dialogs using the jQuery modal library. The Examples module even demonstrates how to create a custom form and display it in a modal window. But what if what you want to do is display an already created form in a modal? How do we do that? Let's see how to do it with an example. Let's display the node add form in a modal window.

The first thing that we need to do is create a link which will trigger the modal when the user clicks it. The only special things that this link needs to have are a few attributes that will let Drupal know to display the contents of the link in a dialog:

<a href=""
    Create Node

Drupal also needs to include the JavaScript libraries which will read these attributes and make them work, so let's add the following libraries to your module's dependencies (in your equivalent to this example's modal_form_example.libraries.yml file).


If you are unsure about how to add libraries on Drupal 8 you can consult the documentation to either add it in a theme or add it in a custom module. At the end of the post I will provide a repository with the code where I added the libraries in a block.

And that's it! If you click the link, the form will be displayed in a modal dialog! Drupal will automatically detect that you are sending an AJAX request and will display just the form so you won't need to worry about removing the rest of the blocks or hiding undesired markup.

The last thing missing, is what will happen if the user creates a node? By default, the node will redirect the user to another page but if we want to just close the modal dialog and leave the user on the same page we need to tell the form to do that. For this we are going to alter the form and add an AJAX command letting Drupal know that we want to close the dialog as soon as the node is created. In the .module file of a custom module we will add this code:

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\CloseModalDialogCommand;
use Drupal\Core\Ajax\RedirectCommand;

 * Implements hook_form_alter().
function modal_form_example_form_node_article_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $form['actions']['submit']['#submit'][] = '_modal_form_example_ajax_submit';
  $form['actions']['submit']['#attributes']['class'][] = 'use-ajax-submit';

 * Close the Modal and redirect the user to the homepage.
 * @param array $form
 *   The form that will be altered.
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 *   FormState Object.
function _modal_form_example_ajax_submit(array $form, FormStateInterface &$form_state) {
  $response = new AjaxResponse();
  $response->addCommand(new CloseModalDialogCommand());

The first function adds an extra submit function (which will be executed after Drupal finishes processing the node) and the second function adds the command to close the Dialog when the node has been created.

We can do this with practically any form in Drupal and you can add extra commands to do more complex things. Here are two resources:

Nov 22 2017
Nov 22

Over the past weeks I have shared an update on the Media Initiative and an update on the Layout Initiative. Today I wanted to give an update on the Workflow Initiative.

Creating great software doesn't happen overnight; it requires a desire for excellence and a disciplined approach. Like the Media and Layout Initiatives, the Workflow Initiative has taken such an approach. The disciplined and steady progress these initiative are making is something to be excited about.

8.4: The march towards stability

As you might recall from my last Workflow Initiative update, we added the Content Moderation module to Drupal 8.2 as an experimental module, and we added the Workflows module in Drupal 8.3 as well. The Workflows module allows for the creation of different publishing workflows with various states (e.g. draft, needs legal review, needs copy-editing, etc) and the Content Moderation module exposes these workflows to content authors.

As of Drupal 8.4, the Workflows module has been marked stable. Additionally, the Content Moderation module is marked beta in Drupal 8.4, and is down to two final blockers before marking stable. If you want to help with that, check out the Content Moderation module roadmap.

8.4: Making more entity types revisionable

To advance Drupal's workflow capabilities, more of Drupal's entity types needed to be made "revisionable". When content is revisionable, it becomes easier to move it through different workflow states or to stage content. Making more entity types revisionable is a necessary foundation for better content moderation, workflow and staging capabilities. But it was also hard work and took various people over a year of iterations — we worked on this throughout the Drupal 8.3 and Drupal 8.4 development cycle.

When working through this, we discovered various adjacent bugs (e.g. bugs related to content revisions and translations) that had to be worked through as well. As a plus, this has led to a more stable and reliable Drupal, even for those who don't use any of the workflow modules. This is a testament to our desire for excellence and disciplined approach.

8.5+: Looking forward to workspaces

While these foundational improvements in Drupal 8.3 and Drupal 8.4 are absolutely necessary to enable better content moderation and content staging functionality, they don't have much to show for in terms of user experience changes. Now a lot of this work is behind us, the Workflow Initiative changed its focus to stabilizing the Content Moderation module, but is also aiming to bring the Workspace module into Drupal core as an experimental module.

The Workspace module allows the creation of multiple environments, such as "Staging" or "Production", and allows moving collections of content between them. For example, the "Production" workspace is what visitors see when they visit your site. Then you might have a protected "Staging" workspace where content editors prepare new content before it's pushed to the Production workspace.

While workflows for individual content items are powerful, many sites want to publish multiple content items at once as a group. This includes new pages, updated pages, but also changes to blocks and menu items — hence our focus on making things like block content and menu items revisionable. 'Workspaces' group all these individual elements (pages, blocks and menus) into a logical package, so they can be prepared, previewed and published as a group. This is one of the most requested features and will be a valuable differentiator for Drupal. It looks pretty slick too:

Drupal workspaces prototypeAn outside-in design that shows how content creators could work in different workspaces. When you're building out a new section on your site, you want to preview your entire site, and publish all the changes at once. Designed by Jozef Toth at Pfizer.

I'm impressed with the work the Workflow team has accomplished during the Drupal 8.4 cycle: the Workflow module became stable, the Content Moderation module improved by leaps and bounds, and the under-the-hood work has prepared us for content staging via Workspaces. In the process, we've also fixed some long-standing technical debt in the revisions and translations systems, laying the foundation for future improvements.

Special thanks to Angie Byron for contributions to this blog post and to Dick Olsson, Tim Millwood and Jozef Toth for their feedback during the writing process.

Nov 22 2017
Nov 22

Our very first official Drupal 8 product release is our SooperThemes Drupal Portfolio Module! While working on a full release of all our themes and modules we saw an oppurtunity to re-invent our portfolio solution and wrote a new module from scratch, ensuring compatibility and ease of maintenance across Drupal 7 and Drupal 8 ecosystems. We're telling you that our new portfolio module is better, faster, sexier, and easier to use than any portfolio module you're used before, on Drupal or elsewhere.

Creating Professional Portfolio Views Has Never Been Easier

You only have mere seconds to impress people with your website. SooperThemes Portfolio offers 65 design settings and unlimited control over animation, color, and content to help you get it right the first time.

Leverage query building, ordering, and contextualization that made Views and Drupal big. Whether you're displaying nodes, files, or custom entities SooperThemes Portfolio will handle it.

65 Settings, 14 Caption Designs, Advanced Motion Design... And Still Easy To Use

As you've come to expect of SooperThemes' products customisability is something we pay attention to. Without being overbearing we provide settings that allow you to match your portfolio, showcase, or e-commerce grid to you site's branding and content. We implemented color pickers that support transparency, example caption designs, and individual motion design options for loading the image grid, filtering, and hovering items. 

Get the details on our portfolio module landing page:
Portfolio Drupal Module

Upgrading Your Drupal 7 Site From Glazed Portfolio/MD Portfolio

First of all, if Glazed Portfolio is working fine for you, you don't have to upgrade. While the new module provides more features and easier customisability this doesn't mean it's worth your time to configure new views with SooperThemes Portfolio  if you're going to end up with the same design that was already working fine for you.

However, if your portfolio views are up for a make-over, or if some of the little bugs and limitations in the old module are bothering you this is the time to upgrade! Since both modules are based on the same grid system the views settings will be familiar. 

Upgrading is very simple:

1. Install new module

2. Create new view or edit example view. Customize to your liking

3. Reference the new view in your menu links and drag and drop pages

4. Uninstall glazed portfolio/MD Portfolio

Where are Drupal 8 Glazed Builder and Glazed Theme at?

Releasing SooperThemes Portfolio is just one of the stepping stones on the way to a full Drupal 8 release for our flagship products. The only 2 remaining stepping stones are finalization of our Entity Browser/Media integration in Glazed Builder and the migration of our theme demos to the Drupal 8 ecosystem. The release itself will take some work in terms of updating our provisioning software and content/documentation on Expect new updates in December!

Nov 22 2017
Nov 22

Why do we need to override Config Entity Types?

  1. By default, Vocabulary list displays all the vocabularies. In case we want to restrict certain roles from viewing certain vocabularies. Overriding that Class(VocabularyListBuilder) function would be the solution to display specific/no/all vocabularies.
  2. Let's assume we need to specify vocabulary-path for each vocabulary apart from name, title, description, vid etc. In this case we would need to override the default Vocabulary Form of taxonomy_vocabulary config entity type.
  3. Suppose we want to custom access check for views on the basis of role/user/views operation or whatever, we would need to override ViewsAccessControllerhandler of view configEntityType and write our own logic.
  4. Another use case can be, if we want to display all the image fields which use image style being deleted, on confirm text message, we again need to override ImageStyleFlushForm class and redefine getconfirmText function.

In short, to customise and meet our dynamic requirements which may not be supported by config entity type definition as a part of @ConfigEntityType annotations in core or contributed modules, we need to override existing config entity types and write some custom code :).

How can we override Config Entity Types?

Entity types use object based annotation unlike array based annotation which is commonly used. Also, Unlike Content Entity Types where every thing is a field, NOTHING is a field for Configuration Entity type.

Every Drupal config entity type is defined as a particular ConfigEntityType Annotation. Entity controller is completely different from the Controller of MVC pattern. To avoid this confusion in terminology Entity Controllers are termed as handlers, each form related to a particular entity type say taxonomy_vocabulary is declared inside handlers with form key. 

In this article, will take an example of adding custom form elements to config entity type forms to explain this.

In case we need to add a custom element to any of these forms, we need to follow these 2 steps:

I) Set a new handler class specific to that form.

  1. Implement hook_entity_type_alter(array &$entity_types).
  2. Set new handler class as : 
     ['{form_type}' => 'Drupal\my_module\MyModuleForm',

    where, id = configEntityType id,  form_type eg: default, reset, delete etc is whichever form we want to override and MyModuleForm is the Class name of new form we'll define in Step II.
    Here is the sample code of overriding default form of taxonomy vocabulary.

     ['default' => 'Drupal\my_module\VocabularyForm',
     'reset' => 'Drupal\taxonomy\Form\VocabularyResetForm',
     'delete' => 'Drupal\taxonomy\Form\VocabularyDeleteForm'

II) Define the class set in Step I.

  1. Extend the actual class of the form we want to add new form elements to. 
    use Drupal\taxonomy\VocabularyForm as VocabularyFormBuilderBase;
    {this is optional, we need to do this to keep the new class name same as base class i.e VocabularyForm}.
    class MyModuleForm extends VocabularyFormBuilderBase 
    OR simply, 
    class MyModuleForm extends VocabularyForm

    This override is important because we need to inherit functions and form elements defined in the parent class i.e VocabularyForm and also add additional feature i.e form element without disturbing the core code. This is purely OOPs concept of inheritance.

  2. We need to override the form function by 
    1. Inheriting the parent elements by parent::form(....) and
    2. Defining the new custom elements as the basic example below:
      $form['third_party_settings']['qed42_textfield'] = array(
       '#type' => 'textfield',
       '#title' => t('QED42 Custom Form Element'),
       '#default_value' => $vocabulary->getThirdPartySetting('my_module', 'qed42_textfield', 'Qed42 textfield default value')

      Config Entities have by default "getThirdPartySetting()" function { Config entities inherit this function if these extend ConfigEntityBase class which implements ConfigEntityInterface interface which in turn extends ThirdPartySettingsInterface interface}. This thirdParty function allows to set and retrieve a value particularly for a module.

    3. Similarly, we can inherit the save function to save the value of newly added form element with Third Party Settings  as : 
      If the form is set as Tree we need to set value as
      $vocabulary->setThirdPartySetting('my_module', 'qed42_textfield', $form_state->getValue('third_party_settings')['qed42_textfield']);
      else :
      $vocabulary->setThirdPartySetting('my_module', 'qed42_textfield', $form_state->getValue('qed42_textfield'));
      and of course inherit the parent save function. 
    4. We can implement the same logic for extending definition of any existing method  AND can also define new functions inside our new Form.

Any Configuration Entity Type (Date format etc) can be overridden similarly, this can be extended to list_builder, access etc.  Apart from overriding, we can also add new flavours of entity controller using the above steps.

Nov 21 2017
Nov 21

Need a way to mix fields from referenced entities with regular fields from managed display?

Then the Display Suite Chained Fields module might be for you.

So how do you go about using the module?

Step 1: Enable a display suite layout for the view mode

To use the chained fields functionality, you must enable a display suite layout for the view mode. Select a layout other than none and hit Save.

Screenshot showing how to go about enabling a layout Enabling a layout

Step 2: Enable the entity reference fields you wish to chain

To keep the manage display list from being cluttered, you must manually enable the entity reference fields you wish to show chained fields from. For example, to show the author's picture, you might enable the 'Authored by' entity reference field, which points to the author. After you've enabled the required fields, press Save.

Screenshot showing enabling the fields for chaining Enabling fields for chaining

Step 3: Configure the chained fields as required

Finally, just configure the chained fields as normal.

Screenshot showing chained fields available for configuration Configuring chained fields

That's it - let me know your thoughts in the comments or the the issue queue.

Photo of Lee Rowlands

Posted by Lee Rowlands
Senior Drupal Developer

Dated 22 November 2017

Add new comment

Nov 21 2017
Nov 21

Whether you are a Drupal newcomer or a seasoned Drupal developer, you're bound to run into one, some, or all of the issues outlined below. Some are obvious, some not so obvious, but we'll show you how to troubleshoot them all regardless.

Some of these issues took a while to troubleshoot, so if you use Drupal as much as we do, make sure you bookmark this page for easy reference in the future. There is nothing worse than spending hours on a problem that can be solved within minutes with the right information (we've all been there).

  1. If you’re working on a Drupal 8 site and you get the message "The provided host name is not valid for this server," you’re not alone. This is a result of a feature added to Drupal 8 to protect against HTTP Host Header attacks.

    • To fix, set the $settings['trusted_host_patterns'] variable in your settings file.
    • If you are running from one hostname, like, you’d set it like so: $settings['trusted_host_patterns'] = array( '^www\.mysite\.com$', );
    • For more information, check out this stackExchange post.
  2. Configuration management in Drupal 8 is great! But you might run into one thing thing that bugs you - for example, if you override a configuration value within settings.php there is no indication in the UI that the values were actually overridden. This is a complete 180 from Drupal 7, which displayed overridden values within the UI. Right now, there is no official solution to this problem, unfortunately, but here are two things you can do:

  3. Kint is a great and detailed new debugging tool in Drupal 8, but it very often runs out of memory when you’re debugging within a Twig template, which defeats the purpose of using it.

    • The first option is to just output one variable if that’s all you need to see, like so - but be aware that even just one variable can be a giant object, so try to be as direct as possible:

    {{ kint(content.field_name['#items'].getValue()) }}

    • The next option is to limit the number of output levels. You can do so in a number of ways:

      • In settings.php:
      require_once DRUPAL_ROOT . '/modules/contrib/devel/kint/kint/Kint.class.php';
      Kint::$maxLevels = 3;
      • Create a /modules/contrib/devel/kint/kint/config.php file and add / modify the line $_kintSettings['maxLevels'] = 3;
      • In a preprocess function, add the following:
      Kint::$maxLevels = 3;
    • When Kint loads the object you’re debugging onto the page, don’t click the plus sign! That expands the whole tree. Click the block instead, and click what you need from there.

H/T Stackexchange

  1. Many developers rely on Drush to do a variety of tasks, such as drush uli to log in to sites. If the site uri isn’t specified correctly, you’ll get a url of http://default instead of the correct url. Setting the $base_url of the site in settings.php doesn’t affect Drush. There are two options.

    • When you run a Drush command that requires the uri, such as drush uli, specify the uri, like so: drush uli
    • Set the uri in drushrc.php. If you don’t have this file already, you can simply create it in sites/default and put the following:
    * @file
    * Provides drush configuration to
    $options['uri'] = '';
  2. Generally, when you’re developing, you don’t want your CSS and JS cached, so that you can debug it. An easy way to make sure caching is turned off is to put these lines in your settings file:

     * Disable CSS and JS aggregation.
    $config['system.performance']['css']['preprocess'] = FALSE;
    $config['system.performance']['js']['preprocess'] = FALSE;
  3. MAMP is a fantastic local development tool, but it can sometimes be tricky to set up with Drupal and Drush. Are you getting an error similar to this when using Drush, but the site works fine?

    exception 'PDOException' with message 'SQLSTATE[HY000] [2002] No such file or directory' in core/lib/Drupal/Core/Database/Driver/mysql/Connection.php:146

    There’s an easy fix. Add the following to your database credentials within your settings.*.php file:

    'host' => '',
    'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock',

    H/T to Modules Unravelled for this fix!

  4. A lot can go wrong if your files and directories are not properly secured. The extended documentation can be found here.

    • sites/default/files: This directory should have the permissions rwxrwx--- or 770
    • You can use the File Permissions module to correctly set up your file permissions, especially if you are seeing errors about your sites/default/files and sites/default/private directories being incorrectly set up.
  5. You’re setting up a new Drupal installation, or doing something new in an existing one, and boom, a white screen. What do you do? There are a handful of options for debugging. Here are a few to get you started:

    • Check your error logs! Look at your Drupal, PHP, and Apache logs.
    • Make sure you have error reporting on. Follow these directions to turn it on and in many cases, get the errors printed on the WSOD:
    • Here’s a debugging tactic to tell you which module may be hanging up your site and causing the issue:
    • Increase your PHP memory limit !

Did we miss anything?

Have a troublesome common bug? Reach out to us on twitter @ChromaticHQ!

Here are the first 15 Drupal problems we published in 2013 - you may still find some of these useful, though some may be out of date.

  1. Users with 'edit page content' access cannot edit simple pages. Chances are the nodes that the users are trying to edit have an input format that they're not permitted to use. Try this:
    • Check the input format for the body field. If its "Full HTML" or "PHP Code" for example, and that user role cannot create content of that input type, they won't even see an edit tab for that node. Either change the input format to one they can access, or grant access to that input format at: admin/settings/filters
    • Double check that their role has permission to edit that particular node type at admin/user/permissions
  2. My client cannot see content he/she has created after logging out. This is likely a caching issue. They can see the content when they are logged in because some caching instances are based on user roles. Check the following:
    • Clear cached data at admin/settings/performance.
    • Clear your browser's cache.
    • Adjust the "Minimum Cache lifetime" setting also under admin/settings/performance.
  3. Images within posts are disappearing after publishing the node. This is likely related to the "Input Format" (again). If the node is using the default settings, "Filtered HTML," input format tags such as img, object, script, etc. will be stripped out. Try the following:
    • Grant the role in question access to the "Full HTML" input format.
    • Create a custom Input Format that includes the tags you want.
  4. My theme (CSS/template) changes aren’t showing up.
    • Is CSS caching turned on? If so, turn it off while your theme is still under development. You can do so at admin/settings/performance.
    • If that still doesn't work, try clearing your browser's cache
    • If you're using Drupal 6, you may also need to clear out the theme registry if you have added new theme functions or new templates. While you're at admin/settings/performance, you can hit the "Clear cached data" button. Check out a full write-up about the new theme registry.
  5. I’ve lost all my anonymous user content! (comments).
    • When was the last time you imported/exported your database? This issue seems to happen when MySQL creates the user's table from a batch file (or database transfer via Navicat) – the user id from the table is auto-incremented and the required ‘0’ value is replaced. Try the following:
    • Manually reset the uid value for the anonymous visitors in the users table. More info found at
  6. I'm getting the dreaded white screen of death! There are many possible causes for this: PHP error reporting settings, memory exhaustion, etc. Try the following:
  7. My web pages take forever to load. What’s the deal? Obviously, there could be many factors at play with this one. Try using the caching capabilities of Drupal. Caching can drastically improve the load times. Especially compressing CSS and JavaScript files - this will help reduce the number of header requests.
  8. It’s a pain to try and develop a theme starting with Garland. Isn’t there a better way to theme from scratch? Yes, there is. Install the Zen theme starter kit. Zen makes it easy to theme from scratch, and best of all, Zen is a standards-compliant theme.
  9. My blog gets hit with a ton of spam, what can I do? 1 word: Mollom; install the Mollom spam module, configure it, and you’ll forget that spam ever existed. Mollom has a free and a paid version - the free will be sufficient for most sites and it even includes some impressive statistics reporting.
  10. How can I figure out which theme function (or template file) I need to override in different places? Install the Devel module. The Devel module was created specifically for Drupal developers. It will streamline your Drupal development process by showing you which functions/templates were used to render parts of the page.
  11. My layout looks “broken” all of a sudden, what happened? This may be a CSS issue, it may be a caching issue, or it may be something else. Try emptying the cache (admin/settings/performance) or try rebuilding the theme registry. Side note: you can easily empty Drupal's cache and rebuild the theme registry using the menu provided by the Devel module mentioned above.
  12. CSS images disappear when caching CSS caching is turned on. There are a number of potential causes for this:
    • Check the permissions to the files and CSS folders at (sites/default and sites/default/files/css respectively) - the server needs read and write access.
    • Is your CSS file importing another with @import? This could be breaking things. Try embedding the imported CSS directly.
    • Are you using relative or absolute paths? There seems to be an issue with this as well.
    • Do you have any funny characters in your URL? While working on a local version of one our sites, we had parenthesis in a directory name; this was breaking the link.
  13. My custom URL alias keeps being overridden! If you have the Pathauto module installed, it might be overriding your custom URL. To fix this, uncheck “Automatic URL Alias” under the URL alias fieldset – this will allow you to use your custom URL in conjunction with the Pathauto module. Also, there is a patch that apparently fixes this issue - though we have yet to test this.
  14. Users cannot view/edit custom CCK field(s). Do you have the “Content Permissions” helper module enabled that comes packaged with CCK? If so, check the field permissions for that user role. By default, only users with administer CCK privileges can edit/view each field.
  15. A specific Drupal user isn’t able to perform a necessary task (such as editing a specific content type). Double check the permissions for the user’s Role(s); they probably don’t have sufficient privileges to carry out the task.
Nov 21 2017
Nov 21

Firewise USA™'s paper application process existed for 15 years but, in 2016, the Firewise team decided to bring the process online. They chose to build this process on top of Drupal 8.

Since moving to Drupal, the Wildfire Division of the National Fire Protection Association has streamlined their processes - enabling them to more efficiently deliver on their program’s goal: teaching individuals how to adapt to living with wildfires and take community action to prevent loss of property.

Join us, Acquia, and our client Aron to discuss the challenges and rewards of bringing a paper process online as a Drupal 8 web app. Topics we’ll discuss:

  • Leveraging an agile philosophy to respond quickly to change, collaborate across disciplines and stakeholder groups and get to a working product in as little time as possible.
  • Balancing effective deliverables with shared understanding to produce working software that meets the organization’s needs.
  • Organizational hurdles to overcome when adding structure and bringing an established paper application process online.

[embedded content]

Nov 21 2017
Nov 21



A point of sales system is already in production in Drupal 7; people are using it and seem to like it. And now, we've ported it to Commerce 2 for Drupal 8. Check out this week's High5 to learn more!

What does this mean?

In Drupal 8, the POS is much more built in, and you can easily do things like change out widgets. So if you update your orders and you add a new field, the field will show up there. If you add a specific widget that controls how that field displays, you can pick from a list of available options and it will work in the POS.

How is this different?

In Drupal 7, the POS was very stand alone—it was all custom-built forms and custom-built options. You actually configured it outside of Commerce itself. It used some of the underlying parts of Commerce, but from a user perspective it was almost as if it was a separate module.

For Drupal 8, that's not the case. It has the same level of functionality, but it's integrated much more so you can use a lot of the Commerce infrastructure. For instance: Drupal 7 had the concept of locations (as in store locations), but Drupal 8 has the concept of stores built right in, so we just use that. There's lots of stuff that goes along with stores: you can attach addresses and extra billing information and so on, and the POS can take full advantage of that in Drupal 8.

Are there any new features?

We have quite a bit more reporting (such as KPI reports for tacking metrics for sales people, for instance.) We also have a new "quick add" section that lets you easily add common products without having to look them up by SKU—it's quite robust and fits nicely into the user interface.

When will all this be ready?

We're only at Alpha 1 right now. Alpha 2 should be coming soon. The module should be fully ready to go in the near future. You can download it's current state and follow progress here.

The bottom line

POS is finally ready for Drupal 8. You can start using it, and we're going to continue releasing new features at least once a month for the foreseeable future.

Nov 21 2017
Nov 21

Hello Drupalers! Here is another #Tips&Trick to make your placeholder translatable. Recently, I have an opportunity to fix one of the issues in Drupal 8 instance where the website was not multilingual hence unable to handle internationalization. After fixing the issue, the contact form now supports more than 25 languages. Let me explain you, what exactly was the issue over here? And how did we overcome this issue?

Issue: Here, Drupal Contact Form Placeholder was not translatable from User Interface Translation.

As we all know anything passes through t() function is always translatable. The issue is generally found in Drupal 8, not sure whether it occurs in Drupal 7 or not. To check the same in Drupal 7, you need to use contributed locale module and check whether web form placeholder gets transformed or not when we do the translation. Remember, Placeholder does pass through t() function.

Notably, all text that passes through t() are visible in User Interface Translation. However, there is no such option to create the translation of a custom text. There many of us have difficulties in translating the text.

See the screenshot below for an example:

Core Drupal Translation UI

Workaround: To add Custom placeholder through your module in the form field.

Form Manage field placeholder setting

Don’t add it through field setting, leave it blank. We will add it through a custom module or custom Twig File. Here, Placeholder text should pass through t().

Adding Placeholder through custom module in the form

Scenario 1: To add custom placeholder to your form.

 * Implements hook_form_form_id_alter().

function custom_form_contact_message_feedback_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
          $form['field_name']['widget']['0']['value']['#placeholder'] = t('custom placeholder needs to be translate’);

Way to add through custom Twig file in your form

Scenario 2: To add custom string to your template file or twig.

<div class="sample-text">
          {{ 'custom placeholder needs to be translate'|t }}

Once we have added our custom placeholder to custom module or twig, it should start displaying in User Interface Translation. And from there we can add translation for our choice of language. See the screenshot below for an example of ‘Filter Translatable Strings’.

Filtering Translation

Once it is visible on User Interface Translation, add text for your respective language and save the translation. Here I am adding text for the Hungarian language.

Custom Placeholder started displaying in Translation UI

Below is the sample for contact form after applying the solution.

Contact form Sample

The above step is one of the workarounds to translate custom text in Drupal 8 using custom code and Core User Interface Translation. Possibly, you can import .po file of respective languages by exploring & importing the same file with updated msgid & msgstr.  Let me know if you come up with a better solution for the above-mentioned issue.

Valuebound, we are fully on the Drupal 8 bandwagon - from an internal, client site development to consulting services. Our development team has been working with Drupal 8 as a group for over a year. Are you interested in learning more about how Drupal can help your business grow? Contact Us.


Nov 21 2017
Nov 21

The unmatched capabilities to interact with other systems is listed among Drupal 8’s best improvements (along with the Views and BigPipe in core, easier migrations, handier configuration management, excellent web accessibility, and much more). And there are various ways to provide great performance in this interaction. One of them is the new and fresh module called Subrequests. We will briefly get acquainted with the Subrequests’ principle of work and features for speed enhancement today.

Drupal 8 and third-party integration

Let’s first take a glance at your Drupal 8 site’s ability to share its data to any external systems you need. These can be native mobile applications on Android or iOs, super dynamic JavaScript apps (based on Angular, React, Node, Ember, Backbone, etc.), or any other third-party systems.

Among other things, this let you use the trending “headless”, or “decoupled” approach, when Drupal serves as a back-end and outputs its data to some front-end system for the sake of exceptional speed, interactivity, real-time features, and more.

The key thing here is to present Drupal’s HTML data in the formats needed by these applications (JSON, XML, or HAL+JSON). Just like good interpreters help people who speak different languages, there are high-class “synchronous interpreters” between Drupal and third-party apps.

These great assistants transform the data into the required formats. The Drupal core now has a “team” of these built-in. These are web services: Serialization, HAL, RESTful Web services, and HTTP Basic Authentication.

In addition, there also are great contributed modules, one of which we will present right now.

Subrequests module and its performance-improving mission

How to help the “synchronous translation” work exceptionally fast? Here is where the Subrequests module comes in.

The Subrequests module groups any sets of requests together, with absolutely no limitations. Thanks to this aggregation, all JSON API requests are sent in just one. The absence of round-trips for fetching Drupal’s data greatly improves performance. Drupal bootstrap is only needed once.

The single request contains all the information that the app needs from Drupal. It’s kept in a JSON document called “blueprint.” The blueprint lists multiple subrequest objects.

The Subrequests module allows for very handy options like sending parallel requests, sending requests that depend on the response to previous request, and more.

Installing the Subrequests Drupal 8 module

This module did not exist in Drupal 7. Subrequests are a true novelty of Drupal 8, with its 8.x-2.0-beta3 released just a month ago.

For efficient work, the module needs some external PHP libraries. So to install the Subrequests module with all these libraries, you could use this Composer command:

composer require drupal/subrequests:^2.0

More technical details along with the code samples can be found in the article of the module’s maintainers, Lullabot, and on the module’s page.


To get the best of the Subrequests Drupal 8 module, create custom solutions for your website’s great performance and handy integration, or migrate to Drupal 8, contact InternetDevels developers. Get more news from our newsletter and on our social media pages!

Nov 21 2017
Nov 21

We recently Open Sourced our temporary environment builder, M8s. In this blog post we will be demoing everything you need to get started!

by Nick Schuch / 21 November 2017


In this video we will introduce you to M8s and the problem which it is solving.

[embedded content]

Provisioning a M8s cluster

Now that you are acquainted with the M8s project, it's time to get a cluster provisioned!

In this video we will setup a Google Kubernetes Engine cluster and deploy the M8s API components.

[embedded content]

Setting up CircleCI

Now that our M8s cluster is up and running, it's time to setup our pipeline to run a build.

In this video we will be configuring CircleCI to run the M8s CLI.

[embedded content]

Pushing a topic branch

It's time to put it all together!

In this video we will be pushing a topic branch to demonstrate how M8s interacts with a Pipeline.

[embedded content]


You made it to the finale! In this video we will be checking out the build environment and how a developer can access the Mailhog and Solr containers.

[embedded content]


To learn more about the M8s project you can go and checkout:

We welcome any and all feedback via Twitter and our Github Project issues page.


m8s, Kubernetes, Drupal Development Photo of Nick Schuch

Posted by Nick Schuch
Sys Ops Lead

Dated 21 November 2017

Add new comment

Your name

Comment (required) About text formats

Restricted HTML

  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h2> <h3> <h4> <h5> <h6>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
Nov 21 2017
Nov 21

Nowadays, a lot of knowledge is available on the Internet, we can get answers to almost all our questions and easily ease our curiosity and give us new ideas. Drupal community is also very active in this field, there are many blogs that are worth your time, so we present them to you.

Dries Buytaert blog 

Dries Buytaert is the “father” of Drupal, therefore he is the greatest source of everything related to Drupal. On his personal blog, you can read about Drupal community, news and his personal thoughts about developments world. 

The Drupal Association  

The Drupal Association encourages Drupal community and its growth. They participate in several segments of Drupal, such as promotion, financing, education, etc. The main areas in which they work are, DrupalCon, and Drupal Jobs. On their blog, they represent news and novelties from Drupal and Drupal Association.

Lullabot Articles

Lullabot provides their insights about Drupal development. They publish tutorials and present new version of Drupal and modules. We also like to listen to the podcast show called “Behind the screens”, where they have interviews with different people involved in Drupal.  


The Palantir blog shares ideas and their experience in Drupal development, why they love Drupal and what benefits they see in it. We also like to listen to their podcasts On the air with Palantir. 

Acquia blog

Acquia has a leading cloud platform for whole digital experiences in Drupal. Their blog provides insights of the firm, their contribution to the community, events, and ideas about creating the future.


PreviousNext Blog

Blog of this Australian firm enables us to see first hand, how to build agile websites. They also share their presentations from Drupal conferences. 

Nuvole Blog

Nuvole, a firm specializing in online communications through open-source tools, writes mostly about code driven development, Drupal conferences and new versions of Drupal. 

Amazee Labs

Amazee Labs is a Swiss firm working in global environment, providing the whole digital experience. They write about their way of working, projects, conferences and personal experience related to Drupal. We also like to read their blog posts on Medium, those blog posts are from system company Amazee I/0. 


They are partners in supporting their clients’ digital transformation. Over the blog, you can learn about e-commerce, their projects, and client’s story. They also provide great technical tutorials and CMS market insights.

New target

They work on many different platforms, Drupal included. From their blog, you can get the wider perspective of different platforms, web design and online marketing. 

Those are blogs that we like to read, if you have any other favorite blog, let us know on twitter

Nov 20 2017
Nov 20
Posted by lizzjoy on 20 November 2017

This month, our membership campaign celebrates the ways we, together, build community on the home of the Drupal project. Hear from the Drupal Association team how and why offers you tools to make more connections, to increase your potential for a fulfilling professional career, and to enable your contributor journey in Drupal.

You can do a lot on and its sub sites. Check out the campaign page. We hope you are inspired to learn more about what offers and if you aren't yet a Drupal Association member, join today!

Top sections of campaign landing pageSections below the fold on landing page

Want to help our campaign?

We need your help so we meet our two goals: sign up 50 new members and raise $1500. We've made a page of resources for you to share.

Thank you for building community with us!

Nov 20 2017
Nov 20

The objective of the JavaScript Framework Initiative is to modernize Drupal core's JavaScript, to make Drupal core backend improvements that enable us to build UIs with JavaScript, and to explore where Drupal can benefit from using a JavaScript framework.

We have weekly meetings on Mondays at 18:30 UTC in #javascript in Drupal Slack. Anyone is welcome to join!

Notes from the November 20 meeting:

  1. @drpal's update on the past week's work
  2. Using as a way to generate React forms without requiring developers to learn React. Possible replacement for Form API. Is this something that seems viable / a good idea?
    • The way they use JSON schema is valuable; not necessarily the implementation.
      Related core issue:
    • Explore separate react-ui and react-json-schema. tim.plunkett has code locally for the schema piece and will post a patch.
  3. Initiative communication
  4. What's the next UI after dblog?
  5. What are the next steps around the React DBLog prototype + component ui library, json schema forms?
    • Take Tim’s work and try to generate form components from Drupal data
    • Do we want to actually add a new dblog to core or is it solely for an experiment?
Nov 20 2017
Nov 20

This past weekend, I was honored to be able to present a session at 2017's New England Drupal Camp (NEDCamp) about Drupal 8's Migrate API. Redfin has implemented many Drupal 8 migrations to date both from CSV data sources and legacy Drupal sites (Drupal 6 and 7). As a result, we want to share with you what we've learned in hopes of saving you the time often spent in the trials and errors of data migration.

My Master's degree is in Technology Education, so I understand that people learn things differently. Some people are auditory or visual learners while others like to read. To that end, I wanted to summarize our session here. If you are an audio or visual learner, please check out these resources:

Otherwise, let's peek at the concepts...

The overall process is:

  1. Scaffold out a module (.info.yml file). You can use Drupal Console for this.
  2. Write YAML files to define your migrations.
  3. Set up any global configuration if needed (your legacy database connection credentials in settings.php, a folder for your CSV files, etc).
  4. Extend/alter/write any custom plugins or code to support those migrations.

While you can use the Drupal Migrate UI to do this, I recommend building your Drupal 8 site the way you want (maybe taking advantage of newer paradigms like paragraphs, for example), and then worry about your migrations. There are four main modules that come in to play when not using the UI. Two are in core--migrate, and migrate_drupal. "migrate" lets you get anything into Drupal 8, while "migrate_drupal" extends and supports that to enhance your experience when migrating IN from a Drupal 6 or 7 (or 8!) site.

Two modules in the contrib space help you above and beyond what is provided in core. Migrate Tools provides Drush command integration for managing your migrations, while Migrate Plus provides loads of enhancements for migrating your data (additional plugins, etc). It's important to make sure you're using the right version of the module for your version of Drupal, by the way--but that's easy since you're using Composer, right?

Write Some Migrations

The Migrate API follows a traditional software design pattern called Extract, Transform, Load. To avoid some confusion with the concept of "Load" (in this case meaning loading data INTO your Drupal database), there's some different terminology used in Migrate:

  • Extract == Source
  • Transform == Process
  • Load == Destination

One thing that Migrate Plus provides is the concept of a "Migration Group." This allows multiple migrations to share some configuration across all of them. For example, if all migrations are coming from the same MySQL database (say, a Drupal 6 database), then that shared configuration can go into the migration group configuration once rather than into each individual migration.

There's some global configuration that goes into each individual migration, for example its "id" key (the unique ID of this migration), and its "label" (friendly name in the UI / Drush).

One thing you can specify also are "dependencies" - for example to a module. You can also enforce "migration_dependencies," which means that before THIS migration is run, THAT one needs to run. This is a great way to ensure references (like entity references, or taxonomy terms) are migrated into the site before anything that uses them.

Each migration then should specify three unique sections--source, process, and destination (sound familiar?).


The source section specifies which plugin to use. These plugins are usually found in the module involved. For example, if you want to migrate data in from Drupal 7 nodes, take a look in core/modules/node/src/Plugin/migrate/source for the implementation / plugin id to use. Often, though, you'll actually find yourself writing a new Class in your own module which extends this one.

Each different source plugin might have some additional configuration that goes along with it. For example, with "plugin: d7_node" you might also specify "node_type: page" to migrate in only basic pages from your Drupal 7 site. You might also specify "key" here to say which database key from the $databases array in settings to use (if that wasn't specified globally in your migration group!).

The purpose of all source plugins is to provide a Row object (core/modules/migrate/src/Row.php) that is uniform and can be consumed by the next part of the process.

If you do write your own migration plugin, two methods I find myself frequently overriding are query() (so I can add conditions to the typical source query, for example - like only grabbing the last year's worth of blog posts), and prepareRow(). The method prepareRow() is your hook-like opportunity to manipulate the Row object that's about to be transformed and loaded into the database. You can add additionally-queried information, or translate certain values into others, or anything you need in prepareRow(). The only thing to beware of is every Row becomes a destination entity, so if you're doing something like joining on taxonomy terms, you're better to do that in prepareRow and add a new property to it with setSourceProperty() rather than, say, LEFT JOINing it on in the query.

Destination (yes, I skipped Process)

The destination plugins work largely the same way. You simply specify what entity (usually) you're migrating into. For example, you might have destination: 'entity:node' and any additional configuration related to that destination. One example for entity:node is to add default_bundle: page here so that you don't need to set bundle: 'page' in your process section (which we're about to get to). Similarly, if migrating files, you can specify source_base_path: '' to automatically download images from that path when importing!

Like source plugins, destination plugins have additional configuration here that is tied to the plugin.

There are so many things that are entities in Drupal 8, the possibilities are vast here - you can migrate nodes, users, comments, files, sure. But you can also migrate configuration, form display, entity view modules, anything in contrib, or your own legacy code! Migrate Plus also provides a "Table" destination so you can migrate directly into MySQL tables inside of Drupal (note that this is generally not best practice if you're migrating into entities--you're better off using the entity:whatever plugin so you take full advantage of the entity API).


This is where all the real magic happens, in my opinion. To keep this blog post short (is it too late for that?), I won't go too deep into all the process plugins available, but I will talk about a few special cases and then encourage you to check out the documentation for yourself.

The "get" plugin is the most basic of all. It simply means "take the value off the Row object for property x, and map it to value y." In your real migration's yml file it would look like destVal: sourceVal - which simply means "take what's in $row->sourceVal and put it in the destination's "destVal" property.

The "migration_lookup" plugin goes one simple step further than get and translates the incoming ID to the new ID value on the new site. For example, if you have a migration that migrates person nodes and the nid was 65 for John Smith on the Drupal 6 site, but is 907 on the new Drupal 8 site, a reference to that person (say on the "authors" field of your "Research" content type) would also need to be translated. This plugin transforms the incoming 65 to the correct 907 by referencing a migration that has already been run (remember the migration_dependencies key?).

Multiple plugins can even be chained together to form a "pipeline" of transformations that can happen in order. For example, if your old database only had usernames as "Chris Wells" and "Patrick Corbett," but you wanted to make usernames, you could run that through the machine_name plugin to change it to "chris_wells" instead. But, what if there was already a "chris_wells" user? Well, you can then run the new value through dedupe_entity to append an "1" or "2" etc until it's unique. You can create fairly complex pipelines here in the yml file without having to touch any PHP code.

Sometimes a field in Drupal has a "nested value," like the body or link fields. The body field has a "value" and a "format" on it. To map these, you use a slash (/) to separate the field and the sub-field, like 'body/value': description and 'body/format': format -- just be sure and use those "ticks" (apostrophes, single-quotes, whatever you call them) around these types of keys.

Feel free to check out all the core process plugins, and even ones provided by contrib, like: get, migration_lookup, machine_name, dedupe_entity, default_value, concat, explode, flatten, static_map, substr, skip_on_empty, skip_row_if_not_set, menu_link_parent, callback, entity_generate, and entity_lookup!

There's one more special one, formerly known as "iterator" and now called "sub_process." This lets you create multi-step a pipeline against an array of structured data arrays. Make sure to pay some special attention to that one.

Put it all together

So by now you've created your shiny new Drupal 8 site just how you want and you've written a module (.info.yml file, really). You've placed all these migrations in it. You can place them in config/install and they will be read in as configuration. You can then edit them as needed using drush config-edit or similar in Drupal Console. You could also uninstall and reinstall your module each time you alter the yml files.

Alternatively, you can also place them in /migrations (off your module root) and instead they will be loaded as plugins instead of configuration. This way is likely preferred since you can just flush the plugin cache when you make changes to the YML file.

Once you also have your source set up (database, CSV files, XML, whatever), you can start to run your migrations with Drush!

The most commonly-used Drush commands for migrating (in my world) are:

  • migrate-status - where are things at?
  • migrate-import - run a migration (single or whole group)
  • migrate-rollback - "un-run" a migration
  • migrate-reset-status - used to reset a migration to "Idle" state if the PHP code you're writing bombs out or you press Ctrl-C in frustration.

Others I don't use as frequently are:

  • migrate-stop - stops a running migration and resets it to idle (I usually press Ctrl-C and then do a drush mrs (migrate-reset-status))
  • migrate-fields-source - list all the available properties on Row to import (I usually just inspect this in the debugger in prepareRow())
  • migrate-messages - display messages captured during migration (PHP warnings, etc) (I usually just look at the database table where these are stored instead of printing them in terminal)


So there you have it. Migration in a nutshell! Please do feel free to leave comments and questions below or reach out to us at Redfin if you need help migrating data into your shiny new Drupal 8 site.

Nov 20 2017
Nov 20

DrupalCamp Atlanta was such a great experience -- I can't decide if it was a great end to a good year or the beginning of even a better year. My last blog post was about organizing and presenting the Webform training materials, which was in preparation for my three-hour Webform training at DrupalCamp Atlanta. Suffice it to say, it was an enlightening experience. Not to mention I learned a few things...

First off, I am in awe of all the people in the Drupal community that are 'professional trainers'. The ability to understand and explain something as complex as Drupal is no easy task. The 14 attendees at my Webform training had various skill levels. Because my leg did not nervously shake at all during my three hours at the podium, I can finally say my comfort level with public speaking is increasing. I also came away with some invaluable, practical information. Prior to attending DrupalCampAtlanta, I had completely underestimated how hard it is to coordinate people to do hands-on exercises, like installing and building a webform. After the first hour of the training, I took a break and decided that the hands-on exercises were going to be impossible to accomplish in the remaining two hours, and that the training should instead focus on walking through all the material while answering any questions. I haven’t given up hope on being able to do hands-on exercises, however, I do need to rethink my approach. Fortunately, I was able to attend other sessions, watch some 'profession trainers' in action, and learn a few things.

Michael Anello (ultimike) at DrupalEasy is a 'professional trainer'. He knows how to talk Drupal to people that don't yet "grok" Drupal. I attended Mike's Drupal 8 Configuration System Basics presentation and it was a perfect example of how to do a K.I.S.S. (Keep It Simple Stupid) presentation. My understanding of Drupal's Configuration System is pretty solid yet, Mike managed to convey the most important aspect to working with Drupal's Configuration System, which is that the development team needs to define a clear agreed-upon process for exporting, importing and updating a Drupal site's configuration. Knowledge is one thing; being able to relate that knowledge is the real stuff.

Over one of many 'Drupal' beers, I told Mike that I want to sit in on his training so that I could learn from a 'master'. I’m specifically intrigued by his Drupal Career Online for individuals; It's a 12-week, instructor-led online course that goes deep and broad into the technology, community engagement, and hands-on exercises to give you a rock-solid foundation for a successful Drupal career.

Mike's helping Drupal newbies become Drupal rockstars. He’s helping to grow the Drupal community by inspiring and helping individual developers to join our community. "He is helping the little guy in our community."

I am 6'3" and still feel like the little guy in the Drupal Community. This was especially true during the Keynote Contrib Panel discussion that I was part of with Ryan Szrama and Damien McKenna. Ryan and Damien are both passionate Drupal contributors, who as part of their jobs get paid to contribute to Drupal. Ryan is the CEO of CommerceGuys, Damien is the community lead for MediaCurrent. And then there is me; the guy who created the Webform module for Drupal 8. I admire both Ryan's and Damien's role in the Drupal community and when you watch the video, you can see me hunched over, listening and deciding, nodding and shaking my head in accordance with what points I agree with or see differently. Please understand, I don't disagree with anything talked about in our panel discussion; I just have a disparate perspective which I can sum up and explain as "don't forget the little guy."

During the panel discussion, Ryan and Damien talked about their contributions to Drupal as part of their current employment. However, all three of us started out in the Drupal community as individuals making contributions to Drupal after hours. Drupal's community is changing and many aspects of Drupal is being built and maintained by paid contributors working for companies and organizations. You should read Who sponsors Drupal development? (2016-2017 edition) to get a better understanding of the Drupal community. Yes, I was surprised that I was the number 1 individual contributor in the Drupal community and one of the few people who is not making "paid contributions" to the Drupal community.

Right now, I have the time available and experience to be able to make a sizeable contribution to Drupal. Early on my Drupal career, Dries Buytaert (the guy who started Drupal) discussed how the Drupal community is a "do-ocracy"; where individuals and groups of people decide what needs to be done and then they just do it. As an individual, as well as in many ways a little guy in the Drupal community, I decided to do ‘something,’ which became the Webform module for Drupal 8. It’s something that has, in turn, become something that I’m passionate about, that I’m eager to see grow and change. And not just personally - it’s a passion that extends to the Drupal community and everyone involved.

I feel that the Drupal community might be forgetting about the little guy, which we can't afford to do. Little guys (aka individuals) have started and built out most of Drupal key modules and themes. Most Open Source projects started out with an individual writing and sharing their code and dreams. Dries, who is ironically very tall, started Drupal as a little guy. He was a college kid in a dorm room, and now he is the project lead to the largest Open Source community and CTO of Acquia.

Drupal is a major project with a massive community built by individuals, including myself. Our community definitely needs corporate sponsorship to support events and major initiatives. At the same time, we need to remember that our community is built one developer at a time. Maintaining the proper balance between individuals and organizations within the Drupal community is an ongoing challenge. Since I am a "little guy', I am interested in seeing more individual developers become part of the Drupal community.

As a follow up to Promoting paid services within the Drupal community and What "About" the Webform module and the Drupal Community? I have decided to start encouraging individual developers to join the Drupal Association with a simple banner in the Webform module's UX that says…

The Drupal Association brings value to Drupal and to you. Join today

The Drupal Association brings value to Drupal and to you. Join today

My hope is that individual developers (aka little guys) will join the Drupal Association and the Drupal community.

I strongly feel that Drupal Association is the backbone of the Drupal Community. As the Drupal Association grows, it needs to remember and help the little guy. Who knows? Maybe even provide scholarships to Michael Anello's Drupal Career Online for individuals.

For now, I am going to embrace my "little guy" status in the Drupal community and just keep plugging away at the Webform module for Drupal 8.

Well, that and focus on keeping my leg from shaking whenever I speak in public.

In closing, I want to encourage you to join the Drupal Association as an individual while reviewing and/or writing a patch for the Drupal community.

Every little bit helps.

Photo by: Utzu Logigan (

Almost done…

We just sent you an email. Please click the link in the email to confirm your subscription!

OKSubscriptions powered by Strikingly

Nov 20 2017
Nov 20

The Drupal Association is excited to expand its team with two new staff members who are filing the roles Conference Director and Community Liaison. Please join me in welcoming Brooke Candelaria and Rachel Lawson. Both are going to add great value to the Drupal Association team as well as to the Drupal community.

Conference Director

We are excited for Brooke Candelaria, our new Conference Director, to join the team. She will infuse DrupalCon with ideas that draw on her extensive technology event experience in open source - Python specifically. In addition to taking over DrupalCon North America planning, Brooke will be a great partner in finding the best way to deliver DrupalCon globally. In addition to Brooke’s expertise, she brings enthusiastic energy to everything she does whether that is planning events or volunteering for the Houston Livestock Show and Rodeo. Brooke resides in Houston, Texas, USA.

Community Liaison

The team is equally excited that Rachel Lawson has agreed to join the team as our new Community Liaison where she will engage with the Drupal community to build a better relationship and understanding between the Drupal Association and the community. Rachel is well suited for this position given her background as a Drupal developer as well as her communications experience in the pharmaceutical industry. Even more impressive is that Rachel has been in the Drupal community for over 11 years and played many important roles such as Community Working Group member, Sprint Lead and mentor, DrupalCon and camp presenter, and more. Rachel has demonstrated time and again that she is a great communicator and has a natural talent to rally people behind a common goal. While you will see Rachel mostly online, she will still be touring Drupal events on her motorbike. Rachel resides in Norfolk, UK.

Nov 20 2017
Nov 20

In my recent talk at DrupalSouth Auckland 2017 I took a hard look at the hyperbole of Drupal supposedly powering over a million websites. Where does Drupal really sit in relation to other CMS platforms, both open source and proprietary? What trends are emerging that will impact Drupal's market share? The talk looked outside the Drupal bubble and took a high level view of its market potential and approaches independent firms can take to capitalise on Drupal's strengths and buffer against its potential weaknesses.

But, Drupal powers over a million websites!

One of the key statistics that Drupalers hold onto is that it's powered over a million websites since mid 2014 when Drupal 7 was in ascendance. However, since Drupal 8 was released in late 2015, Drupal's overall use has stalled at around 1.2m websites, as seen circled in red on the Drupal Core usage statistics graph below.

Drupal install graph

The main reason for this stall in growth was that Drupal 8 was a major architectural re-write that wasn't essential or even affordable for many Drupal 7 sites to migrate to. For clients considering major new projects, many held off on committing to Drupal 8 until there were more successful case studies in the wild and didn't commission new Drupal 7 sites given that version was nearing a decade old. Anecdotally, 2016 was a tough year for many Drupal firms as they grappled with this pause in adoption.

Of course, Drupal 8 is now a well-proven platform and is experiencing steady uptake as circled in green on the usage graph above. This uptake corresponds with a down tick in Drupal 7 usage, but also indicates a softening of total Drupal usage. If we extrapolate these trend lines in a linear fashion, then we can see that Drupal 8 might surpass Drupal 7 usage around 2023.

Drupal usage extrapolation

Of course, technology adoption doesn't move in a straight line! Disruptive technologies emerge that rapidly change the playing field in a way that often can't be envisaged. The example that springs to mind is Nokia's market share was still growing when the iPhone 4 was released in 2010. By the time the iPhone 4s was released in 2011, Nokia's sales volumes had almost halved, leading to Microsoft's catastrophic purchase of the handset division in 2013 and subsequent re-sale for 5% of the purchase value in 2016. Oops!

Builtwith stats

Despite this downward trend in overall Drupal usage, we can take comfort that its use on larger scale sites is growing, powering 5.7% of the Top 10,000 websites according to However, its market share of the Top 100,000 (4.3%) and Top Million (3%) websites is waning, indicating that other CMS are gaining ground with smaller sites. It's also worth noting that Builtwith only counts ~680,000 Drupal websites, indicating that the other ~500,000 is detecting are likely to be development and staging sites.

So, where are these other sites moving to when they're choosing a new CMS? 

Wordpress usage

Looking at the stats from W3Techs, it's clear to see that Wordpress accounts for almost all of the CMS growth, now sitting at around 30% of total market share.

Wordpress has been able to achieve this dominance by being a fantastic CMS for novice developers and smaller web agencies to build clients' websites with. This is reinforced by Wordpress having an exceptional editor experience and a hugely popular SAAS platform at

Drupal's place in the CMS market

The challenge Wordpress poses to other open-source CMS platforms, like Joomla, Typo3 and Plone, all with under 1% market share and falling, is their development communities are likely to look direct their efforts to other platforms. Drupal is able to hedge against this threat by having a large and highly engaged community around Drupal 8, but it's now abundantly clear that Drupal can't compete as a platform for building smaller brochure-ware style sites that Wordpress and SAAS CMS like Squarespace are dominating. We're also seeing SAAS platforms like Nationbuilder eat significantly into Drupal's previously strong share of the non-profit sector.

With all the hype around Headless or Decoupled CMS, Drupal 8 is well positioned to play a role as the backend for React or Angular Javascript front-ends. Competitors in this space are SAAS platforms like Contentful and Directus, with proprietary platforms like Kentico pivoting as a native cloud CMS service designed to power decoupled front-ends.

We often talk of Drupal as a CMS Framework, where it competes against frameworks like Ruby on Rails, .NET and Django to build rich web based applications. Drupal 8 is still well placed to serve this sector if the web applications are also relying on large scale content and user management features.

Which brings us to the Enterprise CMS sector, where Drupal competes head to head with proprietary platforms like Adobe Experience Manager, Sitecore and legacy products from Opentext, IBM and Oracle. The good news is that Drupal holds its own in this sector and has gained very strong market share with Government, Higher Education, Media and "Challenger" Enterprise clients.

This "Comfort zone" for Drupal usage is characterised by clients building large scale platforms with huge volumes of content and users, high scalability and integration with myriad third party products. Operationally, these clients often have well established internal web teams and varying degrees of self reliance. They're often using Agile delivery methods and place high value on speed to market and the cost savings associated with open-source software.

Where Drupal is gaining a competitive edge since the release of Drupal 8 is against the large proprietary platforms like Adobe Experience Manager and Sitecore. These companies market a platform of complementary products in a unified stack to their clients through long standing partnerships with major global digital agencies and system integrators. It's no surprise then that Acquia markets their own platform in a similar way to this sector where Drupal serves as the CMS component, complemented by subscription-based tools for content personalisation, customer segmentation and cloud based managed hosting. Acquia have actively courted global digital media agencies with this offering through global partnerships to give Drupal a toe hold in this sector.

Garnter Magic Quadrant CMS

This has meant Acquia has made significant headway into larger Enterprise clients through efforts like being recognised as a "Leader" in the Gartner Magic Quadrant for CMS, lending Drupal itself some profile and legitimacy as a result. This has driven Enterprise CIOs, CTOs and CMOs to push their vendors to offer Drupal services, who have looked to smaller Drupal firms to provide expertise where required. This is beneficial to independent Drupal services firms in the short term, but the large digital agencies will quickly internalise these skills if they see a long term market for Drupal with their global clients.

As one of those independent Drupal firms, PreviousNext have staked a bet that not all Enterprise customers will want to move to a monolithic platform where all components are provided by a single vendor's products. We're seeing sophisticated customers wanting to use Drupal 8 as the unifying hub for a range of best-of-breed SAAS platforms and cloud services. 

Drupal 8 hub

This approach means that Enterprise customers can take advantage of the latest, greatest SAAS platforms whilst retaining control and consistency of their core CMS. It also allows for a high degree of flexibility to rapidly adapt to market changes. 

What does this all mean for Drupal 8?

The outcome of our research and analysis has led to a few key conclusions about what the future looks like for Drupal 8:

  • Drupal's overall market share will steadily fall as smaller sites move to SAAS CMS and self-managed Wordpress installs.
  • The "comfort zone" of Government, Media, Higher Education and "Challenger" Enterprise clients will grow as many of these clients upgrade or switch to Drupal 8 from Drupal 7 or proprietary platforms.
  • Drupal will gain traction in the larger Enterprise as the global digital agencies and system integrators adopt Drupal 8 as a direct alternative to proprietary CMS products. 
  • Independent Drupal services firms have a good opportunity to capitalise on these trends through partnerships with larger global agencies and specialisation in technologies that complement Drupal 8 as a CMS.
  • A culture of code contribution needs to grow within the larger clients and agencies moving to Drupal to ensure the burden of maintaining Drupal's development isn't shouldered by smaller independent firms and individual developers. 

Despite the fact that we've probably already passed "Peak Drupal", we're firm believers that Drupal 8 is the right tool for large scale clients and that community has the cohesion to adapt to these existential challenges!

Add new comment

Nov 18 2017
Nov 18

We will cover here two options to get started with Docker for Drupal: the Docker Community Edition, then a more straightforward way with Docksal.

Let's have a look at the underlying stack by starting with the bare minimum Docker setup to have a Drupal 8 site running before switching to Docksal.


Install Docker

Get Docker CE for MacOSX, it will run the Docker daemon.

Docker MacOSX

Then check if everything went right.

docker version

docker version

Get Drupal 8.x with PostgreSQL

Create a drupal-docker directory and put it this stack.yml file taken from the official Drupal repository on Docker hub.

cd in this directory then

docker swarm init
docker-compose -f stack.yml up

You can then list the running containers

docker ps

Docker Drupal ps

Install Drupal

Open http://localhost:8080 in your browser

Complete the database credentials with what is defined in the stack.yml file:

  • Database type: PostgreSQL
  • Database name: postgres
  • Database username: postgres
  • Database password: example
  • Under advanced options, replace localhost by postgres

Docker Drupal Postgresql install

Basic Docker commands

List Docker stacks

docker stack ls

Remove a stack

docker stack rm <stack name>

Get a container IP

# get the container id with ps
docker ps
# then inspect the container
docker inspect <container ID>

SSH into a container

docker exec -it <container id e.g. apache> bash

List all containers, even the ones that are not running

docker ps --all

Other Docker basic commands

We will not go on with Docker here, just check the documentation on for a more complete setup with PHPStorm.



[embedded content]

Docksal uses Docker to create fully containerized environments. It also uses Virtual Box to support MacOS and Windows. Its main feature is the inclusion of a command-line tool, called fin, that simplifies the management of all components.

Docksal comes preloaded with common Drupal development tools like Drush and Drupal Console, as well as php tools like Composer, PHP Code Sniffer, and php-cli. It also comes with node, npm, ruby, bundler, and python.

Install Docksal

# Get or update Virtualbox then install Docksal
curl -fsSL | sh
# Create and start the VM
fin vm start

The default directory for your Docksal projects will be ~/Projects

If you are using MacOSX High Sierra, there is a bug with NFS.

Docksal High Sierra

Here is how to fix this, this documentation also explains how to switch back to Virtualbox. If you have followed the first installation of Docker CE, just add DOCKER_NATIVE=1 to ~/.docksal/docksal.env, make sure that the Docker daemon is running (start Docker CE) then

fin reset system

If you do not apply this fix, it will cause the following issue while installing Drupal on the next step.

Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by <em class="placeholder">standard</em> have unmet dependencies

Create a Drupal 8 project

Note that you will have the choice to create a Drupal 7, Drupal 8, Wordpress, Magento or static project.

fin project create

This command will clone the sample Drupal 8 project so it is equivalent to

cd ~/Projects
git clone
fin init

Docksal create project

Open http://drupal8.docksal in your browser after the setup.

Running docker ps will show the containers behind this setup.

docker ps Docksal

fin commands, to be runned in your project directory

List project services

fin status

Recreate project services and containers

fin restart

Stop project services and remove their containers

fin rm

Other fin commands


Nov 17 2017
Nov 17

Even when salt, shells or stones were used instead of money, the most successful sellers were those relying on marketing and analytics! After, it was always important to find ways to persuade people to buy goods, as well as to figure out which goods were most in demand. Today, with modern online stores and platforms such as Drupal that are great for e-commerce, the importance of marketing and analytics remains the same. But the tools for them have become far more advanced! In today’s article, we’ll cover some special Drupal modules of this kind.

Nice marketing & analytics Drupal modules for e-commerce sites

You could bring your online store’s usability sky-high, provide perfect display on mobile phones, and make it impeccable from shopping cart to checkout (as shown by the examples of famous e-commerce websites). But even this is not enough.

It’s the marketing and analytics tools that will be the missing piece in the puzzle of your e-commerce website’s success!

Let’s see at least some of them right now. You will find modules both for online stores built on Ubercart and on Drupal Commerce.

Ubercart Early Bird Discount

Encourage your customers to be early birds that catch good discounts! Here is a module for the Drupal store on Ubercart that lets you easily create discounts with a particular end date, as well as set discount amounts in currency or by percent.

Commerce Wishlist

With the help of this handy tool, you can get a Wishlist on your Drupal Commerce store. It provides an “Add to Wishlist” button for products, builds a customizable list of “wishes,” lets users quickly move products from their Wishlist to their cart, etc.

Ubercart Recommender

We recommend you consider this module for Ubercart that allows you to give purchase recommendations to your customers. There are two types of recommendations: those based on the user’s purchasing history and on what other shoppers “also chose.” It works with the Views and is highly customizable.

Commerce Recommender

Here is a similar module for Drupal Commerce. It also gives recommendations on the basis of purchases. If a user has no purchases, nothing will be displayed in the first type of recommendations. To fix this, you could also consider using the Browsing History Recommender module, which uses viewing history instead of the purchasing history.

Commerce Google Analytics

The Commerce Google Analytics module lets you send your order data to Google Analytics. Using Rules, you can determine when to send this data. GA Push integration is one of its additional useful features.

Who Bought What|Ubercart

Get some priceless information to use in your marketing campaigns by discovering “Who bought what.” This special tool will give it to you as a handy list containing all the shoppers’ name, purchase amount, and all other attributes.

Commerce MailChimp

Here is a handy way to track the statistics on your MailChimp e-mail marketing campaigns. The Commerce MailChimp module that offers integration with the popular MailChimp’s eCommerce360 tool.

Commerce Campaign Monitor

Here is a module that smoothly connects your Drupal Commerce website to Campaign Monitor and lets your customers subscribe to your mailing list after the checkout.


You can effortlessly send triggered marketing emails to your customers about abandoned cart and more via the Mailjet. In addition, it lets you track the sales generated by each of your newsletters.

MailUp Newsletter Module

This is a tool that provides the integration between your Drupal online store and the MailUp email marketing platform. Its great features include multiple newsletter subscriptions, extra subscriptions options, automatic data transfer and synchronization between Drupal and MailUp, and much more.

Commerce Reporting

An advanced reporting system included in one module is at your disposal. It gives you table-based and filterable reports about sales, customers, products, payment methods, and more. You can manage all reports in the same handy dashboard, export them as CSV files, etc.

Commerce Conversion Tracking

You can easily track conversions in your online store with Google Analytics, Clicky, or other system of your choice, if you use the Commerce Conversion Tracking module.


These are just a couple of cool marketing and analytics Drupal modules in e-commerce. In addition, custom ones can also be created, which will work exactly how you wish. For creating custom modules or building a Drupal online store from scratch, you are welcome to contact our developers. Enjoy the age of e-commerce with its modern tools!

Nov 17 2017
Nov 17

Ever since the release of Drupal 8, the most popular keyword search in the framework is “Headless Drupal” also referred as Decoupled Drupal. Headless Drupal is something where you use Drupal to store data that can be accessed in multiple applications (via REST APIs). The front end frameworks like Ionic interacts with Drupal using HTTP requests.

Check out how to use this feature of Drupal and Ionic framework to build a hybrid mobile application.

What is Ionic?

In simple terms, Ionic is an open source framework that is built atop Apache Cordova to develop hybrid mobile apps. Hybrid apps are not developed specifically for a platform that means you can manage a single codebase for different platforms. Let’s build a simple movie listing page.


Installing Ionic:

  • To install Ionic you need to install  Apache Cordova, nodejs, npm in your system. Run the following codes.

sudo apt-get install nodejs
sudo apt-get install npm
sudo npm install -g cordova
sudo npm install -g ionic

Drupal Set up :

Enable the following modules for rest API

Modules required

  • Enable CORS (Cross Origin Resource Sharing) for accessing the data between applications. Change the CORS config as per the origins of services.yml file:
  • A content type of the movie :
    content type
  • A rest export view with a list of movies:

Rest View

Step 1 - Create an Ionic menu-based app using the below command:

ionic start <appname> sidemenu

You can choose tabs/blank instead of side menu for your app.

Step 2 - Run the app. Navigate to the app folder.

Ionic serve / ionic serve --lab (This allows you to view your app in both ios and Android platforms)

This opens the app in your desktop browser.

Step 3 - Create a page:

ionic generate page movie-list

Step 4 - Navigate to app folder. Edit the movie-list.ts from App Folder > src > pages > movie-list. This is where the view will be requested for data.

Step 5 - Now display the view data in the app.

The movies variable declared in movie-list.ts can be accessed in the movie-list.html. Below ion-header (similar to head in HTML), add ion-content (similar to body in HTML).

The sanitizer.bypassSecurityTrustHtml is used to save the html tags exposed from views.

Step 6 - To add the page to the menu, edit the app.component.ts file from App Folder > src > app.

Import your page at the top and add the page in pages variable.

Step 7 - Now check your app in the browser. You will be able to see the movie list page on the menu. You may see the output similar to the below screenshot. :


You can apply the CSS for the ratings in app.scss file. The CSS applied here would be applied globally. If you want to apply styles to the specific page, you can create a .scss file in your page folder.

You may need to import some app components like HTTP, Headers for HTTP calls if facing any errors.

Login functionality can also be implemented as follows:

Login form in login.html would be

The form can be validated in login.ts.

The authenticated actions in Drupal like adding content can be done by passing the CSRF token stored in the local storage into headers.

You can also refer Ionic website to check out more details about deploying the app

In this way, you can use the Ionic framework to build the hybrid mobile apps and use the decoupling feature of Drupal to store the data. Try Ionic and see how it enhances digital experience. If you have any suggestions or queries please comment down let me try to answer.

 Below given is a presentation on "Building mobile app using Ionic framework."


Nov 16 2017
Nov 16

We're super excited for you to have 4 smoking hot new designs as well as some awesome improvements to our Drupal 7 products! Our updates our available for download immediately!

4 Hot New Theme Designs

With our Drupal 8 development nearing completion we're making sure all our designs are looking their best and are ready for prime-time. SooperThemes is all about empowering users with top notch design and we produced 4 smoking hot new demos for Photography, (Drupal) Agency, App, and Marketing Agency websites.

Gradient Design Tool For Stunning Section Backgrounds

Design stunning, layered backgrounds for your sections without photoshop! All the beautiful multi-colored sections in our new App demo were made with Glazed Builder. Our gradient tool supports color transparency which means you can create stunning gradients and then blend them with patterns or photography to create mesmerizing designs. If it's your job to create engaging landing pages your job is now easier with Glazed Builder. 

We Listened: New Button To Add Sections Anywhere In Your Page

When landing pages get very long dragging new sections from the top of the page can become tedious. You complained and we listened! A popular request was to make the main Glazed Builder controls float and follow along with you when scrolling down the page. However, this solution can cause conflicts with other controls, and can become confusing when using nested Glazed Container. Instead we designed a new solution that is both clear and effective:  

Save Precious Time With Single Click Inline Editing

Glazed Builder is all about getting things done fast and with ease. Previously inline editing required 1 click to initialize the editor and a second click to place the cursor where you want to start typing. From now on the first click is not needed any more and you can click and type directly, saving you precious milliseconds and providing a more intuitive editing experience! 

Using External Images in Glazed Builder

Thanks to the fully featured media library integration managing images in Glazed Builder was already a great experience. However, we have now exposed the image url on all image widgets in Glazed Builder so that you can directly reference external images, without needing to import them to your media library. 

Vertical Centering Option On Sections

Sections already had a full width option and a full height option. We added a vertical centering option. Vertical centering was already possible using padding but since full height sections with centered text are now a popular design pattern we decided to add this option that makes a good companion to the already existing settings for full width and 100% height.

CMS Portfolio Module Revamped And New Module To Be Announced Tomorrow

For the production of our Photography demo we launched many new capabilities in our portfolio modules. The Glazed CMS Portfolio module previous offered just 2 displaying images: stacked images and thumbnails that link to a lightbox. We needed this component to be more flexible so that we can customize image display for different use cases. The result is a fusion between field formatters, views, and our portfolio images field. You can now use views to format the image field in portfolio pages. Furthermore, you can select any field formatter and view on a per-node basis as well. Our photography demo has a complete dropdown menu showcasing different variations (It's the Gallery Pages dropdown).

On top of that, we have dropped the MD Portfolio module from our products and wrote a new module from scratch for both Drupal 7 and 8. This new module is called SooperThemes Portfolio and will be the topic of another blog post tomorrow! If you're looking to update your website and it uses our portfolio modules it's recommended to wait for tomorrow's blog post.

As always, see our changelogs in the documentation section for a more complete list of changes and feel welcome to give us feedback in the comments! For bug reports please use our support forum.

Nov 16 2017
Nov 16

The best open-source booking system builder is now available for the world-class Drupal 8 CMS.

In between other projects, we've been investing in the future of open source booking applications. The bat library is a production tested, rock solid base for solving all kinds of availability management problems. Now, it's a first class citizen in drupal 8. With drupal 8’s API first capabilities, there's never been a better platform for quickly prototyping and building open booking applications. How about a community bike sharing application with a react front end? With drupal 8, your content backend is already built, and you can focus on the interface your users will see. Or perhaps you need a tour booking platform for multiple vendors, with the huge added capabilities of drupal commerce.

What's the best part? Your platform is completely open source, without any vendor lock-in or monthly service fees. As the authors and maintainers of bat, we're here for you - support is provided on stack overflow and the issue queue, and if you're looking for custom development services or an enterprise support SLA, just get in touch!

Finally, we'd be remiss not to give a shout out to one of our resident coding geniuses, Nicolò Caruso. He has put in a huge effort to get this built and ready to release to the community. 

In summary, we're super stoked about the combined possibilities of drupal 8 and bat. We're looking forward to hearing your comments and feedback!

Get in touch to learn more or discuss your project Try it outRead the Docs

Nov 16 2017
Nov 16

In this edition of 3 Takeaways, Joe Flores, Sr Drupal Developer, answers the question, "what happens during website launch?" From quality assurance to setting the domain name, this video clears things up. 


[embedded content]


Hi everybody. My name is Joe Flores, I’m one of the senior developers here at Elevated Third and I’m here to talk to you about your website launch.

Website launch is the culmination of the entire design and dev process and there is a lot riding on the success of this part of the project. There are so many things that can go wrong during launch and here’s what we do to make sure things go as smooth as possible.

Takeaway #1: How launch is different from development

We’re not actually creating code. We are assuming the content of the website is finished and that there will be no major structural changes. This is to ensure that there are no conflicts between the dev server and live. At this point, we are assuming that content changes will only happen on the live website.

Takeaway #2: Configuration and testing

During the launch process your website will be moving on to a new server with more memory and storage space that we configure for security and speed. So we do things like changing admin password, enabling caching, disabling development workflow modules, and configuring marketing automation rules. We do all of this to make sure no one sees an unfinished product. So then, we perform one final QA to make sure everything is running.

Takeaway #3: The actual launch

We spend on average 2 days doing all this stuff to make sure launch is the easiest part of the process. By this point, we caught all big errors and ensured the site is secure. So all this part involves is setting the domain name. We did all the front loading to make sure the launch is smooth and this process only takes a couple of hours.

And that is your 3 takeaways for website launch.

Nov 16 2017
Nov 16

As one of North America’s premier users of Drupal we have worked together with Okanagan College to develop a new Drupal Web Developer Certificate that will be offered weekday evenings beginning January 8, 2018.

We are so anxious to find coding talent that we are putting our own money on the line in hopes of addressing our HR recruitment challenges.

“We need great candidates for interesting and exciting CMS work in Kelowna and are looking forward to hiring graduates from this program,” says Shae Inglis, CEO of Acro Media. “In fact, Acro Media is going beyond just supporting the OC program. We are also sponsoring a contest to provide a $4,000 tuition award to a talented student who submits the best code sample before Dec. 15 for the January intake of the course. Contest details are available at

“The Drupal Web Developer Certificate will give students the knowledge, practice and experience to find great jobs and careers in the Okanagan. This exciting Okanagan College and industry partnership has resulted in a program that will provide companies with highly qualified and work-ready graduates,” explains Dennis Silvestrone, Okanagan College’s Director of Continuing Studies and Corporate Training.

Taught by industry experts, this 240-hour Certificate will be offered at the Okanagan Innovation Centre in downtown Kelowna Mondays through Thursdays from 4:30 p.m. to 9:30 p.m. Students applying for the Drupal Web Developer Certificate are financial aid and student loan eligible.

For more information visit or call 1-888-638-0058 to learn more about qualifying for this Certificate.

Nov 16 2017
Nov 16

Building commerce websites always means building integrations. Every time we work on project that is aimed at selling something (products, subscriptions, paid access, etc.), we have to choose a payment provider that will take care of our transactions.

Almost every payment provider out there gives us the ability to test their services using some sort of testing or sandbox environment. This is a nice chance to fully test the checkout funnel and avoid stressful situations when deploying the application to a live environment.

While setting up commerce checkout flow locally, you’ll probably run into one (or all) of the following hiccups:

  • Issues with setting up a payments provider account,
  • No ability to parse incoming webhooks,
  • Problems with redirecting your customers back to the website.

The reason is simple: you’re hidden behind your NAT/firewall, so there is no way to reach your website from any remote server. As a workaround, you could probably create a manual payment method (for example bank transfer) and use this to browse all steps of your checkout flow. But you'll have to admit: this won't solve your main problem. Alternatively, you could clone your project to a remote environment, but is this always necessary? There has to be a better way to save time and keep working locally whilst keeping the full ability to test and debug remote services. Let’s have a closer look at how to wrap it all together with Drupal 8, Commerce 2 and a small tool called ngrok. In this example, I will be using the Mollie payments platform - scroll down to find out more! (Additional info about how to use Mollie and Drupal together in this post)

Download and set up ngrok

Ngrok is a very simple command line tool that allows you to expose a local web server to the internet. It takes only a few moments to set it up and its variety of configuration options is quite impressive (see the corresponding documentation).

Create ngrok account and download library files

Three easy steps:

  1. Simply visit and create a new account:
  2. Download and unpack the ngrok binary:
  3. Install your authtoken. Your personal account comes with its own token, which is available for reference via this link:

When you get your token, locate the ngrok file and run the following command:

# ./ngrok {command} {param_is_a_token_conaining_lot_of_strange_chars_like_3Adacx$$321!}

./ngrok authtoken 5RpgRe8UA4qFWXtZoZb5P_3KeqMMsh6BjYMtWnJpgJt

Tune up your virtual host

Tune up the configuration of virtual host with the website you want to test by adding the server alias. For example, your apache2 vhost, with URL http://ngork.local, should have a * alias, so you conf file should start like this:

<VirtualHost *:80>

  ServerName ngrok.local
  ServerAlias *.ngrok.local *

Run ngrok

The very basic usage to start a simple HTTP tunnel goes like this:

# ./ngrok {command} {local_hostname}:{port}

./ngrok http ngrok.local:80
  • http command says start an HTTP tunnel
  • local_hostname argument says forward tunnel to this hostname
  • and port argument says listen on that port

After running the command, you will see ngrok up and running:

Testing Drupal Commerce 2 and Mollie payments with ngrok - preview of started session

That should do the trick for now: you should be able to visit your page at URL provided by ngrok. The unfortunate thing about a free account is that every time you start a new tunnel, it creates a new URL. You can visit the ngrok web interface at to check the status, incoming requests, connections, headers and much more.

Set up Commerce 2 / Drupal 8

Our test project needs a basic setup, with the following commerce 2.x modules turned on:

  • Commerce Checkout
  • Commerce Order
  • Commerce Payment
  • Commerce Price
  • Commerce Product
  • Commerce Store
  • Commerce Cart - not really required, but helpful to easily jump through the UI
  • Mollie Payment

Configure basics - set up you default store, product type etc. at the end your checkout flow will contain following panes:

Testing Drupal 8 - Commerce 2 Checkout UI example screenshot

Set up a Mollie payment account

Log in to the Mollie dashboard and jump to the Website profiles page, where you can create a profile or edit an existing one. Under contact information, provide the URL that is generated by your running ngrok process. Mollie will use it to send you all the webhooks:

Testing Drupal Commerce 2 and Mollie payments - preview of Mollie dashboard profiles pane

Next, expand the Live end Test API keys pane to find the credentials that you need to configure the payment method in commerce. Install the Mollie Payment module and navigate to the Payment UI ( /admin/commerce/config/payment-gateways). Next, fill out the new payment method form with all the required details:

Testing Drupal 8 - Commerce 2 Payment UI example screenshot

Test it...

That’s it! You can start with testing your payments, add any product to your cart and run through the checkout. After reviewing your order, you will automatically get redirected to the payment page, select any method and submit your transaction. For payment providers where you can define a full return URL and not only the domain - which is not the case with Mollie -, you can add XDEBUG_SESSION_START={YOUR-IDEKEY}, and start a debug session, as if you were working  on a regular local environment.

Testing Drupal Commerce 2 and Mollie payments - preview of Mollie payment selection screen

With ngrok up and running and your Mollie profile properly configured, you will get back to your local website. In the following few minutes, your local project should be receiving a bunch of webhooks. Whilst you wait for them coming in, you can preview your transactions in the Dashboard.

Key takeaways

Ngrok is definitely a great time-saver. It provides a lot of useful features and helps to resolve a variety of problems that you’ll often encounter during local development. In this article, I just demonstrated one example of its usage. It’s good to keep in mind that ngrok allows you to do much more:

  • Demoing - with ngrok running on your machine, you can share your local project with your teammates and clients
  • Insecure/mixed content check - with ngrok you can access your project via https:// which allows you to check insecure content warnings (no SSL needed!)   
  • Analysis - using the dashboard that is located at http://localhost:4040, you can inspect all requests/responses
  • Secure connection - you can secure your tunnel with a password  
  • Receiving webhooks - finally, you’re able to receive all webhooks and respond to them
  • Developing headless Drupal applications - while working locally you can expose your endpoints to your teammates ( check our article about Drupal 8 and React )

Drupal 8 is a really powerful and API-ready framework. It works very well together with lots of external services. Considering this, in addition to the never-ending technological progress, this flexible situation forces us to leave our self-created comfort zone and “I only use one tool” mentality. There are plenty of options to learn more about and use external tools, APIs and services. This provides a lot of flexibility, but, on the other hand, also requires some adaptation, has a learning curve and requires focus at every single stage of product development.

As developers - who don’t like mistakes, especially when payment integrations and real money are involved - we can’t afford to miss a beat here. Checkout funnels are leads that convert into real sales. They provide crucial business value to our clients and have to be extremely reliable; every payment needs to come through successfully. Testing your payment services through ngrok will allow you to stay in close control of your project, reduce stress and track down any issues before you spin up your application. It doesn’t take much time to set up, but the payoff is tremendous.

As always, you can discover more Drupal secrets on our blog. Automatic quarterly updates? Subscribe to our newsletter!


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