Planet Drupal

Subscribe to Planet Drupal feed - aggregated feeds in category Planet Drupal
Updated: 12 min 25 sec ago

Dries Buytaert: State of Drupal presentation (February 2016)

Thu, 24/03/2016 - 14:14

I was excited to travel to India a few months ago for DrupalCon, an area where we have a really big opportunity for the growth of Drupal. In keeping with tradition, here are the slides and video from my keynote presentation. You can watch the recording of my keynote (starting at 20:15) or download a copy of my slides (PDF, 158 MB).

The main areas of focus for the talk included Drupal's rapid growth and progress in India, key technology trends driving the future of the web, and how Drupal is responding to these trends. As a call-to-action, I encouraged Drupalists in India to form grassroots communities locally, to become a part of the larger Drupal community conversation, and to port modules from Drupal 7 to Drupal 8 to accelerate its adoption.

Have a look and as always, feel free to leave your thoughts in the comments!

Categories: Elsewhere

Deeson: 9 reasons Group for Drupal 8 is awesome

Thu, 24/03/2016 - 12:27
1. It’s already available

With a very stable release out the door, we’ve been getting a number of positive reviews from early adopters. Don’t hesitate, download the alpha release now!

2. The UX is great

You don’t need to visit a dozen pages to configure your site’s group functionality. Once you’ve enabled the module, all you need to look for is the Group section right next to the People section.

3. It’s fresh

The biggest competitor for Group is Organic Groups (OG), a module that has been around for a while now. Group, on the other hand, was written from scratch for Drupal 7 and then re-written from scratch for Drupal 8. This allowed us to leverage the latest available tools to their full extent.

4. A different data model

People have grown so accustomed to the way OG works, that they have come to accept it. But the OG approach is not necessarily the right one. Try out Group and you’ll discover a whole new way of doing things. (Spoiler alert: We have dedicated Group entities.)

5. It’s easy to develop for...

Enabling your module’s content entities to become part of a Group has never been more easy. Group D8 uses the plugin system, allowing you to extend its functionality by writing a module with less than 10 lines of code.

6. … but even easier to build sites with

Because Group uses a lot of the basic features available in Drupal 8, we get a lot back from Drupal core. Full Views support? Check! Exportability? Check!

7. It ships with a node integration

Need your groups to have private content? We’ve got you covered! Group D8 ships with the Group Node module, allowing you to add nodes to a Group and share access to the the group members only.

8. It has a clear and concise roadmap

There is very little left to do before we can move from alpha to beta. After that, it’s only a short sprint before we can tag a release candidate. Check out the roadmap for yourself.

9. It’s very well received

So what are you waiting for? Check out the module right now! It’s already been featured on the Modules Unraveled podcast, was the subject of a talk at DrupalCamp London and is getting praise from nearly anyone who’s come into contact with it.

Categories: Elsewhere

KnackForge: Disable Drupal 8 cache during development

Thu, 24/03/2016 - 08:36
Disable Drupal 8 cache during development

We know Drupal 8 has a heavy caching mechanism, so we need to clear cache for changes made in twig file or some other file to reflect in the site. Basically, a themer or developer won't love the caching system on the development stage. So it is better to disable cache on the development stage rather than clearing cache for every change being made.

And here are the steps to disable cache and save your valuable time:

  • Copy and rename the sites/example.settings.local.php file as sites/default/settings.local.php

    rajamohamed Thu, 03/24/2016 - 13:06
Categories: Elsewhere

KnackForge: Formatting the way the date/time is displayed in Drupal 8

Thu, 24/03/2016 - 07:33
Formatting the way the date/time is displayed in Drupal 8

You can create a new date/time format by navigating to Admin -> Configuration -> Regional and Language -> Date and Time format and click on 'Add Format'. Once you’ve created date format, you can control the way date is displayed on the node using preprocess function.

In theme_name.theme file, add the following lines. This would override the way date is displayed in node.

Thu, 03/24/2016 - 12:03
Categories: Elsewhere

KnackForge: Drupal 8 block caching

Thu, 24/03/2016 - 06:30
Drupal 8 block caching

The approach to custom block caching is different in Drupal 8 from Drupal 7. In Drupal 8, all renderable arrays are cacheable, even those returned by custom block.


  • Some expensive-to-calculate data depends on the active theme: different results for different themes. Then you'd vary by the theme cache context.

    rajamohamed Thu, 03/24/2016 - 11:00
Categories: Elsewhere

Pantheon Blog: The Trouble with Two Autoloaders

Wed, 23/03/2016 - 20:35
An autoloader is a bit of PHP code designed to load class files as they are needed. This is a language feature of PHP; when an autoloader is registered, PHP will call it any time a reference to an unknown (un-loaded) class is made. Composer makes it even more convenient to use an autoloader, as it will generate one automatically from the information provided in a project’s various composer.json files when the project is installed and updated.
Categories: Elsewhere

Mustardseed Media Drupal Video Tutorials: Awesome Hero Images (and hook_block_view_alter uglyness)

Wed, 23/03/2016 - 18:34
Awesome Hero Images and hook_block_view_alter uglyness Video of Awesome Hero Images and hook_block_view_alter uglyness Hero Images have been a big trend in web design for...

Drupal tutorial videos from Mustardseed Media Inc.
Categories: Elsewhere

SitePoint PHP Drupal: Theming Views in Drupal 8 – Custom Style Plugins

Wed, 23/03/2016 - 17:00

Views is in Drupal 8 core. We all know that by now. Twig is the new templating engine in Drupal 8. This we also know. But do we know how to interact programmatically with the first in order to theme a View using the second? Aside from overriding View templates like with any other subsystem, we have available a more powerful alternative in the form of Views plugins (Display, Style, Row and Field).

In this article, we are going to look at how we can create a custom Style plugin for Views in Drupal 8. We will use the Bootstrap tab markup as a goal and implement a tabbed output for our View results. In the View configuration, the Style settings will allow us to specify which field will be used as the tab navigation copy, leaving the rest of the fields shown in the respective tab panes. Basically, each View result will represent a tab - so this example is not suited for Views which have more than a few results. The main goal is to illustrate how we can create our own Views Style plugins in Drupal 8.

We will not cover the details on how you can use Bootstrap in your project. However, you can check out the documentation page on assets or even this article on how to make sure anonymous users can benefit from jQuery being loaded on the page. And if you want to see the code we write ahead of time, you can find it in this repository within the Demo module.

What Is the Style Plugin?

The Views Style plugin is the one responsible for rendering the listing. Notable examples of core Style plugins are Unformatted List, HTML List, Table or Grid. They are used by the Display plugin and they in turn use Row plugins that represent one item in the listing.

In Drupal 8, all Views plugin types are built using the new Plugin system and share some common functionality (they always extend from the same Views PluginBase).

Let’s now create our own such Style plugin that can be used by most Display types (Page, Block, etc) and which uses the Field row plugin.

The Bootstrap Tabs Style Plugin

The first step is to create our plugin class located in the Plugin/views/style folder of our module:

namespace Drupal\demo\Plugin\views\style; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\style\StylePluginBase; /** * A Views style that renders markup for Bootstrap tabs. * * @ingroup views_style_plugins * * @ViewsStyle( * id = "bootstrap_tabs", * title = @Translation("Bootstrap Tabs"), * help = @Translation("Uses the Bootstrap Tabs component."), * theme = "demo_bootstrap_tabs", * display_types = {"normal"} * ) */ class BootstrapTabs extends StylePluginBase { /** * Does this Style plugin allow Row plugins? * * @var bool */ protected $usesRowPlugin = TRUE; /** * Does the Style plugin support grouping of rows? * * @var bool */ protected $usesGrouping = FALSE; /** * {@inheritdoc} */ protected function defineOptions() { $options = parent::defineOptions(); $options['tab_nav_field'] = array('default' => ''); return $options; } /** * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $options = $this->displayHandler->getFieldLabels(TRUE); $form['tab_nav_field'] = array( '#title' => $this->t('The tab navigation field'), '#description' => $this->t('Select the field that will be used as the tab navigation. The rest of the fields will show up in the tab content.'), '#type' => 'select', '#default_value' => $this->options['tab_nav_field'], '#options' => $options, ); } }

Continue reading %Theming Views in Drupal 8 – Custom Style Plugins%

Categories: Elsewhere

Acquia Developer Center Blog: How to Organize a Drupal Meetup: 3 Lessons Learned from Experience

Wed, 23/03/2016 - 15:50

As the organizer of the Washington, DC Drupal meetup for three years, I've had the benefit of finding out what works and what doesn’t when setting up a meetup. Although I recently had to step away from my organizing duties due to other commitments, I'd like to provide a retrospective on what I've learned from organizing meetups. My goal is to help those who want to set up a meetup in their area for the first time, and to help provide ideas for those who are already running a meetup.

Tags: acquia drupal planet
Categories: Elsewhere

DrupalEasy: Drupal 6 to Drupal 8(.0.x) Custom Content Migration

Wed, 23/03/2016 - 14:36

Note: This blog post is based on Drupal 8.0.x. While the concepts will remain the same in 8.1.x, the code examples will no longer be valid because migrations will become plugins in 8.1.x.

Even if you're only casually acquainted with Drupal 8, you probably know that the core upgrade path to Drupal 8 has been completely rewritten from the ground-up, using many of the concepts of the Migrate and Drupal-to-Drupal migration modules. Using the Migrate upgrade module, it is possible to migrate much of a Drupal 6 (or Drupal 7) site to Drupal 8 with a minimum of fuss ( is a prime example of this). "Migrate upgrade" is similar to previous Drupal core upgrade paths - there are no options to pick-and-choose what is to be migrated - it's all-or-nothing. This blog post provides an example of how to migrate content from only a single, simple content type in a Drupal 6 site to a Drupal 8 site, without writing any PHP code at all.

Setting the table

First, some background information on how the Drupal 8 Migrate module is architected. The Migrate module revolves around three main concepts:

  • Source plugins - these are plugins that know how to get the particular data to be migrated in. Drupal's core "Migrate" module only contains base-level source plugins, often extended by other modules. Most Drupal core modules provide their own source plugins that know how to query Drupal 6 and Drupal 7 databases for data they're responsible for. For example, the Drupal 8 core "Node" module, contains source plugins for Drupal 6 and Drupal 7 nodes, node revisions, node types, etc… Additionally, contributed and custom modules can provide additional source plugins for other CMSes (WordPress, Joomla, etc…), database types (Oracle, MSSQL, etc…), and data formats (CSV, XML, JSON, etc.)
  • Process plugins - these are plugins designed to receive data from source plugins, then massage it into the proper form for the destination on a per-field basis. Multiple process plugins can be applied to a single piece of data. Drupal core provides various useful process plugins, but custom and contributed modules can easily implement their own.
  • Destination plugins - these are plugins that know how to receive data from the process plugins and create the appropriate Drupal 8 "thing". The Drupal 8 core "Migrate" module contains general-purpose destination plugins for configuration and content entities, while individual modules can extend that support where their data requires specialized processing. .

Together, the Source -> Process -> Destination structure is often called the "pipeline".

It is important to understand that for basic Drupal 6 to Drupal 8 migrations (like this example), all of the code is already present - all the developer needs to do it to configure the migration. It is much like preparing a meal where you already have a kitchen full of tools and food - the chef only needs to assemble what is already there.

The configuration of the migration for this example will take place completely in a custom .yml file that will live inside of a custom module. In the end, the custom module will be quite simple - just a .info.yml file for the module itself, and a single .yml file assembling the migration.

Reviewing the recipe

For this example, the source Drupal 6 site is a large site, with more than 10 different content types, thousands of nodes, and many associated vocabularies, users, profiles, views, and everything else that goes along with an average Drupal site that has been around for 5+ years. The client has decided to rewrite the entire site in Drupal 8, rebuilding virtually the entire site from the ground-up - but they wanted to migrate a few thousand nodes from two particular content types. This example will demonstrate how to write a custom migration for the simpler of the two content types.

The "external article" content type to be migrated contains several fields, but only a few of consequence:

  • Title - the node's title
  • Publication source - a single line, unformatted text field
  • Location - a single line, unformatted text field
  • External link - a field of type "link"

Some additional notes:

  • The "Body" field is unused, and does not need to be migrated.
  • The existing data in the "Author" field is unimportant, and can be populated with UID=1 on the Drupal 8 site.
  • The node will be migrated from type "ext_article" to "article".

Several factors make this a particularly straight-forward migration:

  • There are no reference fields at all (not even the author!)
  • All of the field types to be migrated are included with Drupal 8 core.
  • The Drupal 6 source plugin for nodes allows a "type" parameter, which is super-handy for only migrated nodes of a certain type from the source site.
Rolling up our sleeves

With all of this knowledge, it's time to write our custom migration. First, create a custom module with only an .info.yml file (Drupal Console's generate:module command can do this in a flash.) List the Migrate Drupal (migrate_drupal) module as a dependency.

Next, create a new "migrate.migration.external_articles.yml" file in /config/install/. Copy/paste the contents of Drupal core's /core/modules/node/migration_templates/d6_node.yml file into it. This "migration template" is what all node migrations are based on when running the Drupal core upgrade path. So, it's a great place to start for our custom migration.

There's a few customizations that need to be made in order to meet our requirements:

  • Change the "id" and "label" of the migration to something unique for the project.
  • For the "source" plugin, the "d6_node" migration is fine - this source knows how to query a Drupal 6 database for nodes. But, by itself, it will query the database for nodes, regardless of their type. Luckily, the "d6_node" plugin takes an (optional) "node_type" parameter. So, we add "ext_article" as the "node_type".
  • We can remove the "nid" and "vid" field mappings in the "process" section. The Drupal core upgrade path preserves source entity ids, but as long as we're careful with reference fields (in our case, we have none), we can remove the field mappings and let Drupal 8 assign new node and version ids for incoming nodes. Note that we're not migrating previous node revisions, only the current revision.
  • Change the "type" field mapping from a straight mapping to a static value using the "default_value" process plugin. This is what allows us to change the type of the incoming nodes from "ext_article" to just "article".
  • Similarly, change the "uid" field mapping from a straight mapping to a static_value of "1", which assigns the author of all incoming nodes to the UID=1 user on the Drupal 8 site.
  • Since we don't have any "body" field data to migrate, we can remove all the "body" field mappings.
  • Add a mapping for the "Publication source". On the Drupal 6 site, this field's machine name is "field_source", on the Drupal 8 site, the field's machine name is field_publication_source. Since it is a simple text field, we can use a direct mapping.
  • Add a direct mapping for "field_location". This one is even easier than the previous because the field name is the same on both the source and destination site.
  • Add a mapping for the source "External link" field. On the Drupal 6 site, the machine name is "field_externallinktarget", while on the Drupal 8 site, it has been changed to "field_external_link". Because this is a field of type "link", we must use the "d6_cck_link" process plugin (provided by the Drupal 8 core "Link" module). This process plugin knows how to take Drupal 6 link field data and massage it into the proper form for Drupal 8 link field data.
  • Finally, we can remove all the migration dependencies, as none of them are necessary for this simple migration.

The resulting file is:

Note that .yml files are super-sensitive to indentation. Each indentation must be two spaces (no tab characters).

Serving the meal

To run the migration, first enable the custom module. The act of enabling the module and Drupal core's reading in of the migration configuration could trigger an error if the configuration isn't formatted properly. For example, if you misspelled the "d6_node" source plugin as "db_node", you'll see the following error:

[Error] The "db_node" plugin does not exist.

If the module installs properly, then Drupal Console's "migrate:debug" command can be run to confirm that the migration configuration exists.

Finally, using Drupal Console, the migration can be run using the following command:

drupal migrate:execute all --db-type=mysql --db-host= --db-port=33067 --db-name=legacy_d6db --db-user=drupaluser --no-interaction


  • "all" - runs all defined migrations as listed by "migrate:debug". Alternatively, the "id" of a single migration may be used.
  • The various "db-*" arguments refer to the Drupal 6 source database.
  • "--no interaction" stops the "migrate:execute" command from prompting for any additional (optional) arguments.

Once the migration is complete, navigate over to your Drupal 8 site, confirm that all the content has been migrated properly, then uninstall the custom module as well as the other migrate-related modules.

Note that the Migrate module doesn't properly dispose of its tables (yet) when it is uninstalled, so you may have to manually remove the "migrate_map" and "migrate_message" tables from your destination database.

Odds and ends
  • One of the trickier aspects about writing custom migrations is updating the migration configuration on an installed module. There are several options:
    • The Configuration development module provides a config-devel-import-one (cdi1) drush command that will read a configuration file directly into the active store. For example: drush cdi1 modules/custom/mymodule/config/install/migrate.migration.external_articles.yml
    • Drush core provides a config-edit command that allows a developer to directly edit an active configuration.
    • Finally, if you're a bit old-school, you can uninstall the module, then use the "drush php" command to run Drupal::configFactory()->getEditable('migrate.migration.external_articles)->delete();, then reinstall the module.
  • The Migrate Tools module provides Drush commands similar to the Drupal 7 Migrate module, including "migrate-status", and "migrate-rollback".
  • Sometimes, while developing a custom migration, if things on the destination get really "dirty", I've found that starting with a fresh DB helps immensely (be sure to remove those "migrate_" tables as well!)

Thanks to Mike Ryan and Jeffrey Phillips for reviewing this post prior to publication.

Categories: Elsewhere

Drupal Association News: 2016 Drupal Association at-large election winner announced

Wed, 23/03/2016 - 13:00

Everyone on the staff and Board of the Drupal Association would like to congratulate our newest board member:

Shyamala Rajaram.

In addition to congratulating Shyamala, please join me in thanking the 22 other candidates who put themselves out there in service of Drupal and volunteered for election. It's brave and generous to nominate yourself for this work, and we should all be very grateful that our community has so many people willing to contribute this way.

This was the fifth election we've held for at-large board seats at the Drupal Association. This year, we had two specific goals for the elections:

  • More candidate diversity - We had four female candidates this year, representing 17% of the field. This was a big improvement over last year, when there was one female candidate. We also had 23 candidates, from 12 different countries—including South American and Asian countries. 
  • Increase voter turnout - This year, 2,126 of you voted in our election. Our pool of eligible voters was 135,747, so that means our voter turnout was 1.56%. This is still low, but a vast improvement over the last election, which saw a .89% turnout. 

Our next steps will be to reach out to the candidates for their evaluation of the elections experience. We also want to hear from you. Please tell us about your experience with the elections process in the comments below so that we can include them in our planning for the 2017 elections.

And finally, you may recall that after some public conversation last year we also changed our self-nomination process in 2016 to ask candidates to opt-in for sharing their election voting data. We use IRV voting and are glad to share that data with you. We've redacted the names of candidates who did not opt-in to share their voting data, though vote counts are still represented.



Voting Results

Counting votes using Instant Runoff Voting. There were 23 candidates competing for 1 seats. The number of voters was 2,126 and there were 2,126 valid votes.

The bar charts below show the vote counts for each candidate in each round. Place the mouse over a bar to see the number of votes.

  • Yellow — Votes carried over from the previous round.
  • Green — Votes received in this round.
  • Red — Votes transferred away in this round.

A candidate's votes in a round is the sum of the yellow and green bars. Since the green and red bars represent votes being transferred, the sum of the green and red bars is the same.

The exhausted bar represents votes where the voter did not indicate a next preference and thus there were no candidates to transfer the vote to. The threshold bar (where shown) indicates the number of votes that ensures that a candidate will win a seat.

Round 1



Count of first choices.

Round 2

(prev) (next)


Count after eliminating tolabs and transferring votes.

Round 3

(prev) (next)


Count after eliminating shehrevar and transferring votes.

Round 4

(prev) (next)


Count after eliminating Kenndillard and transferring votes.

Round 5

(prev) (next)


Count after eliminating krylov and transferring votes.

Round 6

(prev) (next)


Count after eliminating knibals and transferring votes.

Round 7

(prev) (next)


Count after eliminating Redacted and transferring votes.

Round 8

(prev) (next)


Count after eliminating tomgrandy and transferring votes.

Round 9

(prev) (next)


Count after eliminating Redacted and transferring votes.

Round 10

(prev) (next)


Count after eliminating Gemdev and transferring votes.

Round 11

(prev) (next)


Count after eliminating TheJustinRhodes and transferring votes.

Round 12

(prev) (next)


Count after eliminating voidberg and transferring votes.

Round 13

(prev) (next)


Count after eliminating drupalviking and transferring votes.

Round 14

(prev) (next)


Count after eliminating Redacted and transferring votes.

Round 15

(prev) (next)


Count after eliminating jpamental and transferring votes.

Round 16

(prev) (next)


Count after eliminating davidhernandez and transferring votes.

Round 17

(prev) (next)


Count after eliminating johnkennedy and transferring votes.

Round 18

(prev) (next)


Count after eliminating rachit_gupta and transferring votes.

Round 19

(prev) (next)


Count after eliminating svettes and transferring votes.

Round 20

(prev) (next)


Count after eliminating danigrrl and transferring votes.

Round 21

(prev) (next)


Count after eliminating MatthewS and transferring votes.

Round 22



Count after eliminating -enzo- and transferring votes. Candidate Shyamala is elected.


Winner is Shyamala.

Flickr photo: Clyde Robinson

Categories: Elsewhere blog: Communicating better on

Wed, 23/03/2016 - 12:48

Last year, Drupal Association staff—in collaboration with Forum One—developed the content strategy for One of the problems that surfaced early-on during that project was the problem of communicating with the community. Rolling out the new Sections on is part of how we are starting to address that.

Sharing important communications with the community as a whole was, and still is, a challenge, mainly due to how hard it can be to find clear, “official” communication channels on specific topics. Because has grown organically, an important announcement could be posted to a number of different places: to forums, to the homepage, to a group on, to the issue queue, or to the Drupal Association blog on

A community member might know about the existence of some of the channels, but not the others. For them, it is not clear which channel(s) to watch to make sure they don't miss important things. And when you are the one sharing important information, it is really hard to know if your message actually reached the people who needed to see it.

Many hours, a bunch of post-its, and quite a few Google docs were spent figuring out a better structure. Here are the communication channels we plan to create and consolidate.

Communication channels

We grouped all the various ways to send a message into groups based on the purpose.

Primary communication channels

These channels are the main source of all the news and announcements. They will include original content written specifically for these channels. The content will be published frequently, following an editorial calendar schedule in each channel.

  • ‘Official’ source of news on: Drupal (the software), (the website) and the Drupal Association.
  • Located in a dedicated News & Events section.
  • Curated content - mainly press releases, official announcements.
  • Comments are not enabled on this content.
  • Blogs on a limited number of topics - aligned with top level Sections of the site. E.g. About section includes Drupal blog, section includes ' blog', Community section - 'Community blog', etc.
  • More frequent and less official updates and announcements.
  • Discussions happen here via comments.
  • Managed by maintainers of respective Sections.
Secondary communication channels

These channels will be used to support communication happening via primary channels. They also will include original content, but communication might be less frequent, aimed to support only the most important announcements.

DrupalCon sessions
  • In-person communication with the community.
  • Opportunity to get direct feedback.
  • Opportunity to communicate via live presentation.
  • Video recordings available on
  • An opportunity to do an extended presentation on the topic with slides and questions from the audience.
  • Video recordings available on
Tertiary Communication Channels

These channels will be used to retranslate messages from the primary and secondary channels to a larger audience or different audience segments. They will provide the ability for the community to follow and consume information from primary and secondary channels in different ways. No original content will be written for these channels. homepage
  • Highlight important information for Newcomers, Learners and Skilled users.
  • News and Blog posts can be promoted.
Planet Drupal
  • Provides ability to consume information from primary channels via RSS.
  • All primary channels will have feeds added to Planet.
  • There is no need to promote something to the homepage to get it on Planet anymore.
  • Provides ability to consume information from primary channels via email.
  • These are various newsletters sent by the Drupal Association staff.
Social media
  • Provides ability to consume information from primary channels via preferred social media.
Direct communication channels Mailing lists

In some cases for community members with specific roles or duties, we use mailing lists for private two-way communication. E.g. mailing lists for working groups, infrastructure team, webmasters and other users with advanced access on the site.

Which existing channels will be replaced?

This restructure of the communication channels means that some of the existing ones might be replaced by new and better alternatives, including:

  • Announcement-only groups (e.g. core, governance) will eventually be migrated into blogs for appropriate sections on
  • News and announcements forum will be eventually replaced by a combination of topical blogs
  • blog will eventually be replaced by a blog in Drupal Association section on
  • homepage will eventually be replaced by the landing page for groups area on
The First Steps

It will take some time to put all these channels, tools and processes in place. But the first steps have already been taken, and we're working to bring the idea to life.


We've decided to tackle primary communication channels first. The first primary channel we are implementing is the blog. Most of the top-level sections will have a topical blog inside of them. Typically, those blogs will be curated and only section maintainers will be able to publish posts in them. The following blogs already exist: blog

As with the Sections, we wanted to try the concept out on a less visited area. So we created the Blog first. It is a main source of announcements and updates our team will share from now on instead of the blog or forums. In fact, this post you are reading now is in that blog already.

Drupal blog

The Drupal blog is a part of 'About' section. It is a main source of important news and announcements about Drupal project. The editorial calendar for the blog is managed by the Drupal Association. And posts are typically written by staff or members of the Drupal Core committers team.

Keep up-to-date with blogs

At the moment, to follow new posts you can subscribe to an RSS feed for each blog. The ability to subscribe to new posts via email, or have them show up in your tracker, will be added soon.

All of the posts from both and Drupal blogs appear on Planet Drupal automatically, and the most important ones will also be promoted to the homepage for additional visibility.

The posts are typically also announced on Twitter (@drupal_org and @drupal respectively). And you can follow comments on individual posts to take part in discussions.

We are excited to take this first step towards improving community communications on Watch this space for more news and updates.

Categories: Elsewhere

Pixelite: Writing PHPunit tests for your custom modules in Drupal 8

Wed, 23/03/2016 - 12:00

I have been doing a bit of Drupal 8 development as of recent, and am loving the new changes, and entities everywhere. I am passionate about automated testing, and when I saw that integrating PHPunit into your custom modules is now even easier, I set out to see how this all worked.

Why is PHPunit important

There are are number of reasons why PHPunit is a great idea

  • it forces you to write testable code in the first place, this means small classes, with methods that do a single thing
  • it runs in only a few seconds, there is also no need to have a working Drupal install
  • integrates with PHPStorm, allowing you run your tests from within the IDE
Step 1, set up your phpunit.xml.dist file

There is a file that comes included with Drupal 8 core, but by default it will not scan any sub-directories under /modules (e.g. like the very common /modules/custom). I stumbled across this question on stackoverflow. So you have a couple of options from here:

Option 1 - Create and use your own phpunit.xml.dist file

You can simply copy (and modify) Drupal 8 core’s phpunit.xml.dist file into git repo somewhere (perhaps outside the webroot), and use this file for all your custom module tests.

Option 2 - Patch Drupal 8 core

Another option (which is the option I took) was to apply a simple patch to Drupal core. There is an open issue on to look at scanning all sub-directories for test files. At the time of writing it was uncertain whether this patch would be accepted by the community.

Step 2, write your tests

There are some general conventions you should use when writing your PHPunit tests:

  • the suffix of the filename should be Test.php, e.g. MonthRangeTest.php
  • the files should all reside in either the directory /MY_MODULE/tests/src/Unit/ or a sub directory of that

More information on the requirements can be found on the documentation.


Data providers are pretty much the best thing to happen to automated testing. Instead of testing a single scenario, you can instead test a whole range of permutations in order to find those bugs. You start by declaring an annotation @dataProvider for your test method:

<?php /** * @covers ::getMonthRange * @dataProvider monthRangeDataProvider */ public function testGetMonthRange($expected_start, $expected_end, $month_offset, $now) { // ... more code }

You then declare a method monthRangeDataProvider that returns an array of test cases (which are also arrays). The items in the data provider method are passed one at a time to the testing method, in the same order they are declared (so you can map them to friendly names).

<?php /** * Data provider for testGetMonthRange(). * * @return array * Nested arrays of values to check: * - $expected_start * - $expected_end * - $month_offset * - $now */ public function monthRangeDataProvider() { return [ // Feb 29 @ noon. [1454284800, 1456790399, 0, 1456747200], // ... more tests follow ]; }

More information can be found in the phpunit documentation for data providers.

Testing for expected exceptions

Just as important as testing valid inputs, you should also test invalid inputs as well. This is easily achieved with @expectedException annotations above your test method:

<?php /** * Tests that an end date that is before the start date produces an exception. * * @expectedException Exception * @expectedExceptionMessage Start date must be before end date */ public function testGetWorkingDaysInRangeException() { // ... more code in here } Step 3, enhance your test class with PHPunit metadata

You can annotate both the test class and the methods to provide additional information and metadata about your tests:


This is mainly used for PHPunit’s automated code coverage report, but I find it also very helpful for developers to up front state what method that are testing.


This is used at a class level, and saves you having to write rather lengthy @covers statement for all your testing methods, if they all test the same class.


If a certain test makes no sense to run unless a previous test passed, then you can add in a ‘depends’ annotation above the test method in question. You can depend on multiple other tests too. Note, that this does not change the execution order of the tests, they are still executed top to bottom.

@group or @author

You can think of adding a ‘group’ to a PHPunit class the same as tagging in. It is free tagging in that sense, and you can tag a single class with many tags. This should allow you to categorise your tests. @author is an alias of group, the idea being you can run all tests written by a particular developer.

More information can be found in the PHPunit documentation on annotations.

Step 4, run your test suite

This section assumes you have opted to use Drupal core’s phpunit.xml.dist file (modify the paths as appropriate if you are using a file in another location).

List groups (or tags)

cd core/ ../vendor/bin/phpunit --list-groups

Run all tests that are tags with a particular group (or tag)

cd core/ ../vendor/bin/phpunit --group tamdash

Example CLI output

$ ../vendor/bin/phpunit --group tamdash PHPUnit 4.8.11 by Sebastian Bergmann and contributors. ........... Time: 5.01 seconds, Memory: 144.25Mb OK (11 tests, 18 assertions)

If you are using PHPStorm, spend a few minutes and set this up too.

Example output

So now there is no need to flip back to your terminal if you just want to quickly run a group of tests.


PHPunit is a great way to be able to run quick tests on isolated parts of your code. Tests often take less than 10 seconds to run, so developer feedback is near instant. It also forces your developers to write better more testible code from the get go. This can only be a good thing. Personally I am very excited to see PHPunit join Drupal 8, and cannot wait to see what people do with it.


There seems to be quite healthy debate on whether contrib or custom modules should ship with their own phpunit.xml.dist file or whether Drupal core’s file should cover both. I am keen to hear anyone’s thoughts on this. Also let me know if you have any contrib modules in the wild shipping their own phpunit.xml.dist files, and how you found that process.

Categories: Elsewhere

Modules Unraveled: 158 Using the Group module as an Alternative to Organic Groups in Drupal 7 and 8 with Kristiaan Van den Eynde - Modules Unraveled Podcast

Wed, 23/03/2016 - 06:00
Published: Wed, 03/23/16Download this episodeGroup Module
  • What is the Group module?
    • A really awesome tool to basically create subsites within one site, private content, manage groups of people or all that combined.
  • Why did you create it instead of just using OG?
    • OG DX experience...
  • There are versions for D7 and D8. Which are you more focused on?
    • D8
  • How is the Group module different from Organic Groups?
    • Good question! The key difference is how the modules decide to structure their data, how that affects the user flow and how the configuration model is built.
  • What is the underlying architecture? OG uses entityreferences heavily. How does Group work?
    • Dedicated Group Entity
  • What’s the status? Is it usable now? (D7 and D8)
    • Available for Drupal 7 and 8, with the 8 version being a large improvement over D7. There’s a few minor things I need to add to the D8 version, but it looks and works great already!
  • Is there much difference between the Drupal 7 and 8 version?
    • Yes and no: the key concept remains the same, but the UX and data model was improved even further. I would really recommend going forward with D8 from now on if you have the chance.
Use Cases
  • Why should I use Group instead of OG?
    • UX, UX, UX
    • data structure
    • DX
    • But most of all: dedicated functionality, it will all make sense!
  • Users that get something special that you can’t do with Roles
  • Groups of people
  • Groups of content
  • There are so many!!!
Questions from Twitter
  • Michelle Lauer @bymiche
    How many subgroups can you nest? How are permissions inherited?
  • Michelle Lauer @bymiche
    Can you easily categorize roles within a group?
  • Michelle Lauer @bymiche
    If you have many roles and want to expose them to "managers" - for UX purposes, roles in categories would be easier to look at
  • Erich Beyrent @ebeyrent
    Sounds like a great UX, what about DX - is there a well-defined API as well?
  • Damien McKenna @DamienMcKenna
    Any plans to port some OG modules, e.g. og_menu or og_menu_single?
  • Damien McKenna @DamienMcKenna
    Would it be possible to create og_forum's functionality out of the box or will it require custom work?
  • Damien McKenna @DamienMcKenna
    Are the join forms configurable/fieldable?
  • Ted Bowman @tedbow
    Interested in this. Can you add fields to a membership?
  • Erich Beyrent @ebeyrent
    What doesn't Groups do? Are there features that you feel need to be added before 1.0 release?
Episode Links: Kristiaan on drupal.orgKristiaan on TwitterThe Group ModuleDrupal 8 Entity Relationship DiagramsConfiguration inspector for Drupal 8Tags: GroupOrganic Groupsplanet-drupal
Categories: Elsewhere

Daniel Pocock: GSoC 2016 opportunities for Voice, Video and Chat Communication

Wed, 23/03/2016 - 04:55

I've advertised a GSoC project under Debian for improving voice, video and chat communication with free software.

Replacing Skype, Viber and WhatsApp is a big task, however, it is quite achievable by breaking it down into small chunks of work. I've been cataloguing many of the key improvements needed to make Free RTC products work together. Many of these chunks are within the scope of a GSoC project.

If you can refer any students, if you would like to help as a mentor or if you are a student, please come and introduce yourself on the FreeRTC mailing list. If additional mentors volunteer, there is a good chance we can have more than one student funded to work on this topic.

The deadline is Friday, 25 March 2016

The student application deadline is 25 March 2016 19:00 UTC. This is a hard deadline for students. Mentors can still join after the deadline, during the phase where student applications are evaluated.

The Google site can be very busy in the hours before the deadline so it is recommended to try and complete the application at least 8 hours before the final deadline.

Action items for students:

  • Register yourself on the Google Site and submit an application. You can submit applications to multiple organizations. For example, if you wish to focus on the DruCall module for Drupal, you can apply to both Debian and Drupal.
  • Join the FreeRTC mailing list and send a message introducing yourself. Tell us which topics you are interested in, which programming languages your are most confident with and which organizations you applied to through the Google site.
  • Create an application wiki page on the Debian wiki. You are permitted to edit the page after the 25 March deadline, so if you are applying at the last minute, just create a basic list of things you will work on and expand it over the following 2-3 days
Introducing yourself and making a strong application

When completing the application form for Google, the wiki page and writing the email to introduce yourself, consider including the following details:

  • Link to any public profile you have on sites like Github or bug trackers
  • Tell us about your programming language skills, list the top three programming languages you are comfortable with and tell us how many years you have used each
  • other skills you have or courses you have completed
  • any talks you have given at conferences
  • any papers you have had published
  • any conferences you have attended or would like to attend
  • where you are located and where you study, including timezone
  • any work experience you already have
  • any courses, exams or employment commitments you have between 22 May and 24 August
  • anybody from your local free software community or university who may be willing to help as an additional mentor
Further reading

Please also see my other project idea, for ham radio / SDR projects and my blog Want to be selected for Google Summer of Code 2016?.

If you are not selected in 2016

We try to make contact with all students who apply and give some feedback, in particular, we will try to let you know what to do to increase your chances of selection in the next year, 2017. Applying for GSoC and being interviewed by mentors is a great way to practice for applying for other internships and jobs.

Categories: Elsewhere

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

Tue, 22/03/2016 - 18:31

Each day, more Drupal 7 modules are being migrated to Drupal 8 and new ones are being created for the Drupal community’s latest major release. In this series, the Acquia Developer Center is profiling some of the most prominent, useful modules, projects, and tools available for Drupal 8. This week, a handy-dandy usability module called Linkit.

Tags: acquia drupal planetusabilitydrupal 8D8Linkitautocomplete
Categories: Elsewhere

Mediacurrent: Easy Ways to Make Your Website More Accessible

Tue, 22/03/2016 - 17:56

I recently had the opportunity to give a beginners talk about website accessibility at MidCamp 2016 where I covered some easy ways to promote accessibility in terms of structure, color and contrast, fonts, links, and media. It was a wonderful experience for me and I was grateful for the audience who had some nice feedback and interesting questions. Here are the highlights of the presentation, plus the audio recording and links to related resources.  

Categories: Elsewhere

Jeff Geerling's Blog: Use Drupal 8 Cache Tags with Varnish and Purge

Tue, 22/03/2016 - 17:52

Over the past few months, I've been reading about BigPipe, Cache Tags, Dynamic Page Cache, and all the other amazing-sounding new features for performance in Drupal 8. I'm working on a blog post that more comprehensively compares and contrasts Drupal 8's performance with Drupal 7, but that's a topic for another day. In this post, I'll focus on cache tags in Drupal 8, and particularly their use with Varnish to make cached content expiration much easier than it ever was in Drupal 7.

Categories: Elsewhere

Disruptive Library Technology Jester: Modify Islandora objects on-the-fly using Devel “Execute PHP Code”

Tue, 22/03/2016 - 16:45

Alan Stanley taught me this trick at an Islandora Camp a few years ago, and when trying to remember it this morning I messed up one critical piece. So I’ll post it here so I have something to refer back to when I need to do this again.

The Drupal Devel module includes a menu item for executing arbitrary PHP code on the server. (This is, of course, something you want to set permissions on very tightly because it can seriously wreck havoc on your day if someone uses it to do bad things.) Navigate to /devel/php on your Islandora website (with the Devel module enabled), and you’ll get a nice, big ≶textarea> and an “Execute” button:

Execute arbitrary PHP using Drupal Devel module.

In this case, I’m generating the TECHMD datastream using the FITS module and displaying the results of the function call on the HTML page using the Devel module’s dpm() function:

include drupal_get_path('module', 'islandora_fits') . '/includes/'; $object= islandora_object_load('demo:6'); $results = islandora_fits_create_techmd($object, False, array('source_dsid' => 'OBJ')); dpm($results);

Works like a charm!

Categories: Elsewhere