Development News

Vasily Yaremchuk: I have switched my Drupal 8 site to a static HTML site with Tome

Main Drupal Feed - Fri, 05/10/2019 - 19:00
I have switched my Drupal 8 site to a static HTML site with Tome

Many years ago I made my personal page on Drupal 7, as soon as Drupal 8 was released I have upgraded to this version. My personal site is just a page with my contacts and my blog. 

In truth, I do not always have enough time to write posts to my blog, as well as keep the core and modules up to date. Some times between the huge projects I have a frame to share my experience and to make some support tasks and improvements. 

So more than 99% of its life my personal site works as a simple static HTML site.

Does it make sense to use Drupal as a backend? 

Let's imagine the site is static at any time except the time when I want to edit it...

And it's possible with Tome. It's Drupal 8 module. You can get more information on the official site

Let me show you my personal site It's a static HTML site. I don't have the permanent version of this site either hosted somewhere or locally. But I have a private repository of my Drupal site with configurations and content in flat files. 

Tome module allows exporting configurations in .yml files and content in .json files as well as install Drupal with those files without operating with the DataBase dump.

I have decided to put some changes on the site. I need to get the site locally, log in Drupal admin, make changes and generate a new version of my static site. That's it.  

Cloning the site:

$ git clone

It's my private repository, that I have forked from

Coming to the folder:

$ cd personal

If you've taken a look at you could find that there is no core folder there. You have to run 

$ composer install 

to get all necessary dependencies. 

Install the site with drush:

$ drush tome:install

Run a local server with drush:

$ drush runserver

Make some changes in the admin area. A new password to login in admin provided after the previous action.

If all changes were done, we can stop the server and generate a static site:

$ drush tome:static --uri=

Attention! Don't forget to set the basic URL of your production site, otherwise, you can get incorrect links that point to your local environment in some places of the static site.

Now you have a new static version of the site and you can deploy it on your hosting.

Don't forget to update the repository with those changes:

$ git status

You can see that one file with content is changed. Let me commit those changes:

$ git add .

$ git commit -m "content changes"

$ git push

Finally, you can delete the local Drupal 8 site:

$ cd ..

$ rm -R personal

Vasyl Yaremchuk 05/10/2019

WPTavern: Tips for Replying to A Call for Papers or A Call for Speakers

Wordpress Planet - Fri, 05/10/2019 - 18:32

The following is a guest post written by Jennifer Bourn. With 21 years experience as a graphic designer, 15 years experience as a web designer, 14 years as a creative agency owner, and 11 years as a blogger, Jennifer Bourn has worked with hundreds of service-based businesses to build brands and establish profitable online platforms. She also co-organizes the Sacramento WordPress Meetup and WordCamp Sacramento.

After being the lead organizer for WordCamp Sacramento for two years, speaker wrangler for two years, managing the program for a year, and speaking at several WordCamps and non-WordPress related conferences myself, I have seen a lot of amazing and a lot of awful speaker submissions. Some speaker submissions have been from people I know personally — people I want to choose and say yes to — but ultimately couldn’t because their submission was subpar.

It’s incredibly tough to both apply to speak and select speakers from applications.

With that in mind, I shared a Twitter thread yesterday with tips for replying to a Call for Papers or a Call for Speakers that will help you get your next talk submission accepted and it is summarized for your convenience below:

If your title is confusing, weird, unclear, too cutesy, or it feels like you put no effort into it, that will work against you. Organizers want talks attendees will be interested in and excited for. It must be easy to understand what the talk is about based on the title alone.

If your talk description is all about you, is only one sentence long, is sarcastic/unprofessional, isn’t aligned with the event focus/theme, or it’s totally self-serving, you should rethink things. Your talk isn’t about you, it’s about helping attendees expand their knowledge and move the needle and helping organizers host a successful event.

It is never ever a good idea to disparage or put down a person, job, tool, piece of software, or anyone/anything to make your point or make your topic interesting. If the only way you can communicate your point is through negativity, reconsider the topic. Being controversial may have been a draw in years past, but now it’s a risk most organizers aren’t willing to take.

Consider that someone else (or several people) may submit a talk on the exact same subject. Your title and description need to convince organizers why your submission should be picked over the other person’s submission.

Consider that if you submit multiple talks, none of them may be selected if your titles aren’t interesting and your descriptions are not descriptive. It must be clear what the talk is about and what the takeaways are, and how this talk will benefit the attendees.

Always think about how you can make the organizers’ or event planners’ jobs easier and follow instructions. For example, if they ask for bios in third-person, provide your bio in third-person. If they ask for full name, provide your full name.

Spell the name of the conference, software, industry, etc. correctly in your speaker application. Want to speak at a WordPress event? Double check that you’ve capitalized the P and proofread your submission.

Look at the topics requested by the event organizers. Submit talks on those topics and your chances of being selected will be higher because they are telling you what they want. Lists of preferred topics are usually included because that is what their local community has specifically requested.

Don’t submit the same talk you’ve submitted 10 times to other events. Put in some effort. Look at the event theme and submit something that relates to it or customize the talk title/description to include the theme.

Look at the past event schedules, agenda, or programs. Look at the types of talks they accept. For example, if a WordCamp has only had 2-3 business related talks in the past four years, it might be a sign they aren’t looking for business talks and want talks focused more on using WordPress.

Look at the topics the event has already covered in previous years. Then find the gap and find something they haven’t already heard or done.

Steer clear of the marketing hype. Avoid topics related to killing it, hustling, crushing, and dominating. Don’t refer to yourself as a guru or a thought leader (that’s only cool when other people say it about you). Avoid negativity, sarcasm, and assumptions about the audience.

If organizers ask how or why you’re qualified to talk on the topic being submitted:

  • It’s okay to be new/just learning — fresh voices are awesome.
  • Don’t just copy and paste your bio into the field. They already have your bio and that’s not what they meant or what they want.

Never assume the people reviewing your application are experts on your talk topic or have the same technical background you do.

Avoid submitting a talk that is all about one piece of software — i.e. one plugin — especially if the software is premium and requires an investment. An entire session dedicated to a paid plugin 1) excludes those who have not purchased it or cannot purchase it and 2) will apply to few attendees. Instead, consider a compare/contrast presentation that covers both free and paid options or a talk that introduces attendees to multiple options.

It’s okay to submit opinion pieces as talks, but be careful to NOT position your opinion or approach as the only one or the right one, when there are other options. Often there isn’t one right way (unless it’s technical and there is one right way).

If the submission form asks what skill level audience your talk is the best fit — Beginner, Intermediate, or Advanced — don’t pick them all. That isn’t helpful. The same is true if they ask who your talk is aimed at — designers, developers, or users, etc.

Organizers for events like WordCamps need to satisfy a diverse audience. The attendee makeup often ranges from those who make a living with WordPress all the way to newbies who just learned what WordPress is a few days ago, so talks at and for every skill level are needed and valued. Don’t skip applying because you think your talk isn’t advanced enough.

If there is a ‘notes to the organizer’ field in the talk submission form, communicate that you’re open to suggestions or making tweaks to the talk focus to ensure it’s a great fit for their audience. Often a talk being reviewed is close to what they want, but it needs a small tweak to be selected.

If something funky happened when you hit submit, don’t be afraid to submit your talk again. Organizers would rather have duplicate submissions than miss your submission. Also, it’s okay to reach out to confirm your submission was received.

Don’t skip applying to speak because you don’t think you know enough yet or don’t have enough experience yet. Everyone has value to contribute and fresh perspectives are always appreciated. Plus, there are people who just discovered or figured out the thing you want to talk about exists — I guarantee you can help them.

Behind the scenes organizers work hard to create a diverse lineup of speakers that provides representation for everyone in the community. Organizers can ask, beg, plead, and do loads of outreach, but ultimately, they are limited by who is willing to apply and/or who is willing to accept an invite to speak. So please say yes and apply.

When organizers make the offer to help you brainstorm talk ideas, craft a talk title/description, and even create your slide deck or watch your practice, say yes. Take them up on the offer. Asking for help doesn’t make you any less awesome. There are a lot of people who are incredibly talented and smart with great value to share but find it difficult to put what they know into a talk format. If that’s you, you’re not alone and there are people who want to help.

Interested in trying your hand at speaking for the first time?

Every event has limited space. When securing rooms for multi-track events and planning the schedule, organizers need to be able to split attendees across the different rooms/tracks. This means they need competing talks in each track that will be a draw and attract attendees. No one wants one full room and one empty room. No one.

If you don’t get selected, don’t get down on yourself. Often the selection choice has nothing to do with you and is simply a matter of many submissions on the same topic(s), needing to balance topics across disciplines to serve the range of attendees or skill sets, and looking for more diverse representation in the speaker lineup.

If the event is local to you, always apply. Many times event/conference organizers want to fill the speaking spots (or at least half of them) with local people from their community or region and you’ll have a leg up on the out-of-towners. Similarly, if there is a meetup group in the area tied to the event/conference, go to the meetup and get to know the organizers and other attendees.

New to a subject/topic? Just learning it? No problem! Consider submitting a talk reviewing your experience as a new user. Share surprises and obstacles encountered, lessons learned, and suggestions for improvement. This can be hugely valuable for advanced users who tend to what new users deal with and it can provide a different perspective and voice.

Want to learn a topic better? There’s no better way than to teach others about it. Submit the talk, do the work to learn it, and teach everything you’ve learned so far. For example, if you want to build a membership site, submit a talk on how to choose a membership plugin, document your research in finding the right plugin, and share what plugins you reviewed, what criteria you used for evaluation, what you discovered (pros/cons), and which you ended up choosing.

Never underestimate the power of awareness. Consider pitching a talk that presents options to expand attendees awareness of what is available or possible and gives them a starting place to research things on their own.

WPTavern: Storefront 2.5.0 Introduces a Custom, Block-Based Homepage

Wordpress Planet - Fri, 05/10/2019 - 15:59

Storefront, WooCommerce’s free flagship theme, has just released version 2.5.0 with updates that make it easier to setup and customize the homepage.

In 2017, WooCommerce 2.2 introduced starter content to help users set up the homepage template, menus, widgets, and add some demo products. This content has been updated to incorporate the WooCommerce blocks that were rolled into the plugin’s 3.6 release. It also adds support for the new cover block, which enables users to place headings, paragraphs, and buttons inside the block.

These changes essentially create a custom, editable homepage with all the flexibility of blocks, giving users more control than the previous custom homepage template approach. The old homepage (template-homepage.php) has now been retired.

Storefront is active on more than 200,000 stores. Many of these sites already have their homepages set, but the new block-based homepage makes it easier to set up a new store or make changes to existing homepage designs without having to use custom code or a plugin.

Version 2.5 is a minor release but still requires testing before updating, as some users have already reported a few discrepancies with how the “full width” template is displayed. Previewing the update in a staging environment will ensure there are no surprises on update. New Drupal Media Library interface: managing media with joy

Main Drupal Feed - Fri, 05/10/2019 - 15:50

The blend of usability and attractiveness exists — this is Media Library in Drupal 8.7 core. That’s what comes to mind when we see Drupal Media Library’s updated UI. Managing media on websites will now be easier and more enjoyable than before!

Drupal Media Library allows you to:

Roy Scholten: No one-offs

Main Drupal Feed - Fri, 05/10/2019 - 14:05
Sub title

Things seen here are configured there.


An elaboration on underlying considerations that make simple suggestions as this one not so simple after all.

An important consideration when deciding whether to “add something to core” is that generally speaking, core doesn’t do one-offs. The underlying principle is not “make it do X” but “make it possible to make it do X (and X2, X3,…)

Linking from a create context to a configuration context

In this particular case we have a proposal to link to the screen where you can add new content types from the page that lists available content types to create content with. Or, in url speak: on /node/add, put a link to /admin/structure/types. Or once more: on the screen that lists existing content types that you can create content with, add a link to the screen that lets you define new content types.

Notice the distinction between “create content of type X” and “define a new type of content Y”. The first is a content creation task, the second is a content definition task (in Drupal jargon usually captured under “site building”). This distinction then should clarify why a link to define a new content type should not use the “blue + button” pattern on a screen that is in service of a content creation task.

Back to the “no one-offs” principle. Where and how can we add a link of this kind? To answer that question we should look for possible patterns. Is there a more generalised definition for the type of problem that this single link to elsewhere wants to solve?

The example is: put a link to the content type definition area on the screen that lists already available types to create content with. Restated more generally: link to that area of the Drupal admin where the things on this screen are configured.

Connecting the dots is important

You know those links at the bottom of product pages in an online store: “people who bought this item also bought X, Y and Z”. In our case it’s more like “Things seen here are configured there.

I noticed a sort of similar pattern in the Android OS settings pages, where the screen ends with suggestions of related topics to the ones already shown. It’s a way to provide meaningful next places to go if the current page didn’t offer what you were looking for (and is of course a symptom of how many settings there are in the first place).

“Things seen here are defined there.

If we can find more examples of where this would be meaningful and helpful then we might have a good case for introducing a new user interface pattern. See image for some initial examples.

Tags Drupal drupalplanet blog: Tomorrow is WordPress Translation Day 4

Wordpress Planet - Fri, 05/10/2019 - 09:17

The fourth edition of WordPress translation day is coming up on Saturday 11 May 2019: tomorrow! Get ready for a 24-hour, global marathon dedicated to localizing the WordPress platform and ecosystem. This event takes place both online and in physical locations across the world, so you can join no matter where you are!

The WordPress Polyglots Team has a mission to translate and make available the software’s features into as many languages as possible. As WordPress powers more than 33% of websites, people from across the world use it in their daily life. That means there is a lot that needs translating, and into many different languages.

On 11 May 2019, from 00:00 UTC until 23:59 UTC, WordPress Translation Day aims to celebrate the thousands of volunteers who contribute to translation and internalization. The event is also an opportunity for encouraging more people to get involved and help increase the availability of themes and plugins in different languages.

“At the time of the last event in 2017, WordPress was being translated into 178 languages, we have now reached the 200 mark!” What happens on WordPress Translation Day?

There are a number of local meetings all over the world, as well as online talks by people from the WordPress community. More than 700 people from around the world took part in past WordPress Translation Days, and everyone welcome to join in this time around!

Everyone is welcome to join the event to help translate and localize WordPress, no matter their level of experience. A lot is happening on the day, so join in and you will learn how to through online sessions!

What can you expect?
  • Live online training: Tutorials in different languages focused on translation and localization, or l10n, of WordPress. These are streamed in multiple languages
  • Localization sessions: General instruction and specifics for particular areas and languages. These sessions are streamed in multiple languages.
  • Internalization sessions: Tutorials about optimizing the code to ease localization processes, also called internationalization or i18n. These sessions are streamed in English.
  • Local events: Polyglot contributors will gather around the world for socializing, discussing, and translating together.
  • Remote events: Translation teams that cannot gather physically, will connect remotely. They will be available for training, mentoring, and supporting new contributors. They will also engage in “translating marathons”, in which existing teams translate as many strings as they can!

A number of experienced WordPress translators and internationalization experts are part of the line-up for the livestream, joined by some first time contributors.

Whether you have or haven’t contributed to the Polyglots before, you can join in for WordPress Translation Day. Learn more about both local and online events and stay updated through the website and social media.

Morpht: Drupal 8 Configuration - Part 1: The Configuration API

Main Drupal Feed - Fri, 05/10/2019 - 02:18

We live in an age of Drupal complexity. In the early days of Drupal, many developers would have a single Drupal instance/environment (aka copy) that was their production site, where they would test out new modules and develop new functionality. Developing on the live website however sometimes met with disastrous consequences when things went wrong! Over time, technology on the web grew, and nowadays it's fairly standard to have a Drupal project running on multiple environments to allow site development to be run in parallel to a live website without causing disruptions. New functionality is developed first in isolated private copies of the website, put into a testing environment where it is approved by clients, and eventually merged into the live production site.

While multiple environments allow for site development without causing disruptions on the live production website, it introduces a new problem; how to ensure consistency between site copies so that they are all working with the correct code.

This series of articles will explore the Configuration API, how it enables functionality to be migrated between multiple environments (sites), and ways of using the Configuration API with contributed modules to effectively manage the configuration of a project. This series will consist of the following posts:

  • Part 1: The Configuration API
  • Part 2: How the API works (coming soon)
  • Part 3: Using the API (coming soon)
  • Part 4: Extending the API with contributed modules (coming soon)
  • Part 5: Module developers and the API (coming soon)

Before we get started, let's review some terminology. A Drupal project is the overall combination of the core codebase and all of the environments that are used for development of the project. An environment is a copy/clone of the website that is accessible at a unique domain name (URL). When most users on the web think of a website, they think of the environment accessed at a single URL, like or These URLs are the entry to the live production environments for these websites. However, in addition to the production environment, large projects will have additional environments, where code is developed and tested before being deployed to the production environment. The combination of these environments make up the project. Drupal 8 is built to enable developers to migrate functionality for a project between environments, using the Configuration API.

Components of a Drupal environment

What makes up an environment of a Drupal project? In other words, when making a 'copy' of a Drupal site, what are the elements that need to be migrated/copied to create that copy? A Drupal environment consists of the following elements:

  1. Codebase: At the core of any Drupal system is codebase that makes up the 'engine' that runs Drupal. The codebase of any Drupal site consists of Drupal core, modules (both contributed and custom), and themes (again, both contributed and custom). The codebase is a series of files, and these files provide the functionality of a Drupal site.
  2. Configuration: Configuration is the collection of settings that define how the project will implement the functionality provided by the codebase. The codebase provides the abstract functionality to create things like content types, fields and taxonomies. Developers configure a Drupal site through the admin interface, to create the actual content types, fields, and taxonomies used in the project, that will allow end-users to do things like create pages or make comments. As developers build out the functionality of the project through the admin interface, the settings they choose are saved as the configuration for that environment. Configuration is environment-specific, and the Configuration API provides a means of migrating configuration between environments.
  3. Content: Content is the data on a site that is specific to the given environment. Content may be created by end-users, or by content admins. While content, like configuration, sometimes needs to be migrated between environments, content should be considered environment-specific. The Migrate API provides a means of migrating content between environments.
  4. Uploaded files: Most Drupal projects will have files uploaded as content. These are not part of the codebase that provides the functionality of the system, rather they are files that are to be provided to end users. Examples are images, audio/video files and PDFs.
  5. Third party technologies: Drupal 8 is a hub framework, built to integrate with 3rd party libraries, APIs, softwares, and other technologies. For example, a project may use a 3rd party CSS/JS framework, or swap out the default database caching backend to a Redis caching backend, which provides significant performance improvements. While these third party technologies are not part of Drupal, often the technologies will be required in each environment for the project to run.

The above five elements together make up a Drupal environment. The environment is a fully-functioning Drupal copy (instance), with its own configuration and content. Each environment will have its own domain (URL) at which the environment can be accessed.

Types of environments

Typical projects these days will have a minimum of three environments:

  1. Production environment: The main live environment that end users will use.
  2. Staging environments: One or more environments on which site owners can test new functionality or bug fixes before they are deployed to the production environment.
  3. Development environments, where new functionality can be developed in isolation. Development environments may be publicly accessible, or may only exist on a developers computer, not accessible to the outside internet.
Content and configuration - both stored in the database

A major issue that existed with all versions of Drupal core up to and including Drupal 7, was that content and configuration were both stored in the database, and there was no way to separate them. This made it difficult to manage configuration changes, such as adding a field to a content type, between multiple environments. There was no way to export the configuration for that single field, so to ensure consistency full databases were migrated. The problem is that database migrations are an all-or-nothing venture; when migrating from one environment to another, the entire database of the source environment overwrote the entire database on the target environment, meaning all content and configuration was overridden on the target environment.

This opens up a problem though. Imagine this scenario:

  1. A developer copies the production database to their local computer.
  2. Someone creates new content on the production environment, that becomes part of the database.
  3. The developer adds a new field on their local environment.
  4. The developer migrates their local database to the production environment, overwriting all configuration and content on the production environment.

With the above scenario, the new field created on the developer's local environment is now on the production environment, however the content created in step 2 is overwritten and lost. As such, the above process is untenable. Databases cannot be migrated 'up' (to production) after a site has gone live. They can only be migrated 'down' (from production).

To overcome this problem, a common way to make changes to configuration before Drupal 8 was to make configuration changes on the production environment, then copy the production environment's database down to the other environments. For example, if a developer was writing code that depended on a new field, rather than create the field on their local development environment, they would create the field on the production environment, then copy the production environment database down to their local development environment. Now the field exists on both the production environment as well as their development environment. This solution works, but is akin to killing a mosquito with a sledgehammer - it's overkill. The developer did not need the whole database, only the configuration for that single field. And any changes they had already made in their own environment, such as content for testing, is now wiped out with data from the production environment.

While this process worked (and still does continue to work for many projects), it was not ideal. It led to issues where database migrations had to be coordinated with clients and other developers to ensure that it was safe to wipe out content or configuration someone else may still be working with.

The Configuration API

The Drupal 8 Configuration API was created to overcome the above issue, so that developers could migrate configuration - such as Field API fields, content types, and taxonomies - between environments, without having to overwrite the entire database. It decoupled configuration from content. To understand how it makes things better, let's again review the components of a Drupal site, and the storage mechanisms behind them:

  • Codebase (files)
  • Configuration (database)
  • Content (database)
  • Uploaded files (files)

With the Configuration API, configuration can be exported into files, and these files can be migrated between environments and imported into the new environment. This means that we can now migrate individual items of configuration without having to overwrite the entire database. The Configuration API decouples configuration from content. In the next parts of this series, we will explore how the API work

Note 1: the Drupal 7 Features module essentially does the same thing, and though the methodology is different, many of the concepts in the following articles will be relevant to that module as well.

Note 2: the Drupal 8 Migrate API was developed in parallel to the Configuration API, allowing for content also to be migrated, again without overwriting the entire database.


In this article, we looked at an overview of the Configuration API to understand what it is, and why it was created. After reading this article, you should have an understanding of what a Drupal environment is, and what it consists of. You should understand that in Drupal 8, configuration is stored in the database, but can be exported to files, which can then be used to migrate content between environments. In Part 2 - How the API works, we will take a closer, more technical look at how the API works, and in Part 3 - Using the API, we will discuss how to use the API, and some contributed modules that extend its functionality.

WPTavern: Advanced Custom Fields 5.8.0 Introduces ACF Blocks: A PHP Framework for Creating Gutenberg Blocks

Wordpress Planet - Thu, 05/09/2019 - 18:14

After six months in development, Advanced Custom Fields 5.8.0 was released yesterday with a new PHP-based framework for developing custom Gutenberg block types. ACF Blocks was announced in October 2018, to the great relief of many developers who didn’t know how they were going to keep pace with learning the JavaScript required to use WordPress’ Block API.

ACF’s creator, Elliot Condon, was one of the more vocal critics of Gutenberg leading up to its inclusion in WordPress 5.0. Developers were concerned about whether or not their custom metaboxes generated by ACF would still be compatible. The ACF team worked to ensure the plugin was integrated into the Gutenberg UI as much as possible and surprised users by announcing an acf_register_block() function that would allow developers to use PHP to create custom blocks.

The new ACF Blocks add-on is built on top of Advanced Custom Fields Pro and does not require any JavaScript knowledge. It integrates with custom fields so developers can create custom solutions. ACF blocks are rendered using a PHP template file or a callback function that allows full control of the output HTML and live previews while editing the blocks. They also maintain native compatibility with WordPress core, meaning that all Gutenberg features like “alignment” and “re-usable blocks” work as expected.

Early feedback indicates that ACF Blocks has made custom Gutenberg development more approachable for developers who are not as well-versed in React, significantly speeding up the creation of custom blocks.

ACF Pro 5.8 for #WordPress makes Gutenberg block development a breeze! Here's a staff block I made in less than 30 mins. @wp_acf #ACFBlocks #wordpressdeveloper #Gutenberg #reactjs #webdevelopment #webdeveloper

— Sam (@sam_kent_) May 9, 2019

This is one example of how the WordPress product ecosystem continues to evolve to support developers in the transition to a more JavaScript-powered WordPress.

ACF Blocks also launched with a suite of nine ready-to-use bocks available as a plugin from the new website. These include commonly-requested functionality for client sites, such as testimonial, team, multi-button, star-rating, pricing list, and click-to-tweet, with more on the way.

DrupalCon News: Reflections from DrupalCon Seattle’s Grant & Scholarship Recipients

Main Drupal Feed - Thu, 05/09/2019 - 16:56

What an event this last DrupalCon was! Thanks to all who joined us in April for DrupalCon Seattle 2019.

In planning this event, more funds than ever before — 30 percent more, to be exact — were allocated for grants and scholarships. This tied in with the overall aim of having a cross-section of attendees, all of whom play a part in contributing and advancing the Drupal Project. Funding for grants and scholarships is from the support of our conference partners, as well as conference registrations.

Sven Decabooter: How to make a Drupal 8 local task title dynamic

Main Drupal Feed - Thu, 05/09/2019 - 15:00
How to make a Drupal 8 local task title dynamic

When defining local tasks (= tabs) in your Drupal 8 modules, you can specify a title for the tab via the 'title' property in your [MODULENAME].links.task.yml file.

However, in some cases you might want to make the task title dynamic, e.g. depending on the context of the entity where the tab is displayed.
This can be achieved by overriding the \Drupal\Core\Menu\LocalTaskDefault class with your own class for that tab.

Here is an example that uses a callback function to dynamically set the title, both for the route and the local task:


  1. Add the dynamic logic to your controller File: my_module/src/Controller/DynamicTabController.php <?php namespace Drupal\my_module\Controller; use Drupal\Core\Controller\ControllerBase; use Drupal\node\NodeInterface; /** * Controller for our dynamic tab. */ class DynamicTabController extends ControllerBase { /** * Route title callback. * * @param \Drupal\node\NodeInterface $node * The node entity. * * @return string * The title. */ public function getDynamicTabTitle(NodeInterface $node) { return $this->t('Dynamic tab for @type', ['@type' => $node->bundle()]); } }
  2. Use the dynamic title callback for your route File: my_module/my_module.routing.yml entity.node.dynamic_tab: path: '/node/{node}/dynamic_tab' defaults: _entity_form: 'node.dynamic_tab' _title_callback: '\Drupal\my_module\Controller\DynamicTabController::getDynamicTabTitle' requirements: _entity_access: 'node.view'
  3. Add your custom LocalTask plugin File: my_module/src/Plugin/Menu/LocalTask/DynamicTabLocalTask.php <?php namespace Drupal\my_module\Plugin\Menu\LocalTask; use Drupal\Core\Menu\LocalTaskDefault; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\node\NodeInterface; use Drupal\my_module\Controller\DynamicTabController; use Symfony\Component\HttpFoundation\Request; /** * Local task plugin to render dynamic tab title dynamically. */ class DynamicTabLocalTask extends LocalTaskDefault { use StringTranslationTrait; /** * {@inheritdoc} */ public function getTitle(Request $request = NULL) { $node = $request->attributes->get('node'); if ($node instanceof NodeInterface) { $controller = new DynamicTabController(); return $controller->getDynamicTabTitle($node); } return $this->t('Default'); } }
  4. Set your custom class for your local task File: my_module/my_module.links.task.yml entity.node.dynamic_tab: route_name: entity.node.dynamic_tab base_route: title: 'Default' class: '\Drupal\my_module\Plugin\Menu\LocalTask\DynamicTabLocalTask'

Now the dynamic title will be used to render your tab name, and the tab page title.

Sven Decabooter Thu, 05/09/2019 - 17:00

Specbee: Drupal 8.7 Features (What’s New and Why Should You Care)

Main Drupal Feed - Thu, 05/09/2019 - 13:50
How do you stay ahead of your competition? Easy - Be relevant. Address your audience’s pain points. Repeat. With the adoption of the continuous innovation model, Drupal is doing that and more. Drupal 8.7 was released on May 1st following the 6 months release cycle for Drupal 8. We saw huge improvements in Drupal 8.6 which was a big release. With 8.7, it just got better - With more stable modules ready to be used on productions and other interesting out-of-the-box features.

ThinkShout: Recognizing Insecure Drupal Code

Main Drupal Feed - Thu, 05/09/2019 - 12:00

Within the Drupal community, it seems like many developers are interested in ensuring their modules and themes are secure, but don’t really know what insecure code looks like. I’ve personally found a lot of resources that tell you about security best practices, but don’t dive deeper into common missteps and their consequences.

Drupal 8 is the most modern and secure release of Drupal yet, which leads developers to expect that all Drupal 8 APIs are perfectly safe to use. While it’s great that Drupal has earned that reputation, there are still plenty of ways to leave your site vulnerable.

In this blog I’ll go through examples of insecure code that I’ve seen doing security research and review into Drupal 8, which will hopefully make it easier for you to know what to look for when reviewing your own code.

So you want to render HTML…

Outputting HTML is Drupal’s bread and butter, but if you’re rendering user input you may be vulnerable to cross site scripting, otherwise known as XSS.

XSS occurs when a malicious user identifies an exploit that allows user input to be executed as Javascript. Then, typically, an attacker leads someone without higher privileges (an administrator) to trigger the exploit. At that point, an attacker can do anything the administrator can do - add more administrator accounts, delete content, download sensitive data, and potentially use a chained exploit to execute server-side code.

Twig has your back

With Drupal 8’s implementation of Twig, all variables rendered normally (within curly braces) are automatically filtered. The attributes object, which is often used in Twig, is also generally safe. For example, trying to add a malicious attribute with code like:

<b {{ attributes.addClass('"onmouseover="alert(1)"') }}>Hello</b>

Will render safely as:

<b class="&quot;onload=&quot;alert&quot;">Hello</b> Unquoted attributes

Twig isn’t inherently immune to XSS. If you don’t wrap attributes in double quotes, for instance, user input could render a malicious attribute. For example, if you have a template like:

<b class={{ configurable_class }}>Hello</b>

And pass in a class configured by a user:

$variables['configurable_class'] = 'foo onclick=alert(bar)';

The final, unsafe HTML will be:

<b class=foo onclick=alert(bar)>Hello</b>

This is because variables have HTML special characters escaped, but aren’t aware of the context they’re rendered in. onclick=alert(bar) on its own is completely safe, but when inside an opening HTML tag can trigger XSS.

The raw filter

One of the filters that comes with Twig, raw, marks a value as being safe and does not escape it. That means that if you ever see something like:

{{ variable | raw }}

In your templates, that could lead to an XSS vulnerability. There are very few use cases for raw, so if you can avoid using it completely you should.

Misusing render arrays

Render and form arrays in Drupal can also be misused to allow XSS. For example, you may know that HTML like this executes arbitrary Javascript on click:

<a href="javascript:alert()">Click me!</a>

And if you’re using url or link objects or render elements, this will be rendered as:

<a href="alert()">Click me!</a>

Which is safe. However, if you’re not using the url or link APIs, Drupal doesn’t have the context to know that the “href” attribute could be unsafe, and will render it without escaping. For example, this code:

$build = ['#type' => 'html_tag', '#tag' => 'a', 'Hello']; $build['#attributes']['href'] = $user_input;

When provided this user input:

$user_input = 'javascript:alert("foo")';

Will render:

<a href="javascript:alert(\"foo\")">Hello</a>

Like the Twig attribute issue, this is a result of Drupal not being aware that untrusted data is being passed to potentially dangerous APIs. Here are some more examples of render arrays that allow XSS:

$build['#markup'] = $user_input; $build['#allowed_tags'] = ['script']; $build['#children'] = $user_input; $build['#markup'] = t($user_input); $build = ['#type' => 'inline_template', '#template' => $user_input]; Not filtering in Javascript

While the examples so far have been about backend code, XSS is commonly triggered from Javascript. Take this example, where the value of an input is passed to jQuery’s html function to display an error:

var value = $('input.title').val(); $('.error').html('<p>Invalid title "' + value + '"</p>');

Since the html function assumes the data you pass is safe, this could trigger XSS. A better way of approaching this is to use the text function, which escapes special characters:

var value = $('input.title').val(); $('.error').text('Invalid title "' + value + '"');

The most Drupal-y way to accomplish this would be to use the Drupal.t function, which accepts placeholders that are automatically escaped, and translates text:

var value = $('input.title').val(); $('.error').html(Drupal.t('<p>Invalid title "@title"</p>', {'@title': value}); Sniffing out XSS problems

In general, a good way to spot XSS is to question complexity wherever you see it. Look into your biggest forms and controllers and see if there’s anything odd using user input, and if so make an effort to exploit it. Also, if there’s any opportunity to use Twig instead of concatenating HTML in the backend, use Twig!

So you want to query the database…

Drupal comes with a database abstraction layer that saves you from writing SQL by hand, which has done a lot to prevent a type of vulnerability called SQL injection, otherwise known as SQLi.

SQLi occurs when a malicious user identifies an SQL query that can be unsafely modified by user input, allowing them to add arbitrary statements or additional queries onto an existing query. SQLi can allow attackers to read arbitrary sensitive data, insert arbitrary data, or even wipe existing data if they are able to.

Use the abstractions

The best advice when querying the database is to use Drupal’s database API wherever possible. Drupal has great documentation on how to properly use this API here:

The API is normally safe to use, but can be used unsafely in ways that aren’t clear to all Drupal developers.

Not using placeholders

There are cases where you need to write a query by-hand, which is fine unless that query uses user input, in which case you need to use placeholders. For example, this code has user input ($name) in the query string:

\Drupal::database() ->query("DELETE FROM people WHERE name = \"$name\"") ->execute();

If $name is set to a malicious value, like:

$name = 'myname" OR "" = "';

The final query ends up being:

DELETE FROM people WHERE name = "myname" OR "" = ""

Which in this example would delete everyone from the people table. The proper way to do this would be to use placeholders in your query string, and pass the user input as an argument:

\Drupal::database() ->query('DELETE FROM people WHERE name = :name', [ ':name' => $name, ]) ->execute(); Not escaping LIKE

Typically when using the database API, using the condition method and passing user input as the value is safe. However, if you are using the LIKE condition, you need to escape user input that may contain the wildcard character (%). For example, this code has user input ($name) in a LIKE condition:

$result = \Drupal::database() ->delete('people') ->condition('name', '%_' . $name, 'LIKE') ->execute();

If $name is set to a malicious value, like:

$name = '%';

The final query ends up being:

DELETE FROM people WHERE name LIKE "%_%"

Which would delete every row in the people table where the name included an underscore. The proper way to do this is to escape the user input using the escapeLike method, like so:

$database = \Drupal::database(); $result = $database ->delete('people') ->condition('name', '%_' . $database->escapeLike($name), 'LIKE') ->execute(); Trusting user operators

Passing user input as a condition value is generally safe, but passing it to other parts of the API like table names, column names, or condition operators is dangerous. For example, this code has user input ($operator) as a condition operator:

$result = \Drupal::database() ->select('people') ->condition('name', $name, $operator) ->execute();

If $operator is set to a malicious value, like:


The final query ends up being:


Which would query all session IDs from the sessions table, allowing user sessions to be hijacked.

To address this, compare the user input to a list of known valid SQL operators before using it in the query.

General SQL tips

If you use the database API in a typical, non-complex way, you’ll probably be fine. Just remember to use placeholders, escape user input when used in a LIKE statement or as an operator, and try to never write queries by hand.

So you want to write some code…

Beyond Drupal specific APIs, a lot of your code is just plain PHP, which comes with its own set of security issues. One last kind of exploit I’ll briefly cover is remote code execute, otherwise known as RCE.

RCE occurs when a malicious user identifies an exploit that allows user input to be executed as server-side code, most commonly by your runtime language (PHP) or the shell. RCE allows an attacker to do anything your web user can do, which could be everything from reading sensitive data, setting up a persistent backdoor, or using the compromised server to reach more servers on your network.

PHP, historically, has allowed for RCE in a lot of different ways, so there’s no golden rule to follow. Instead, watch out for some of the RCE classics:

Using user input to execute shell commands:

`magick convert $user_input output.png`; shell_exec("magick convert $user_input output.png");

You could use the escapeshellarg function here to escape user input, but that isn’t foolproof as options (--foo=bar) are just wrapped in quotes, which in some command line applications is treated as a valid option. Validating the user input against a small set of allowed characters may be the best bet here, in addition to using escapeshellarg.

Using eval to execute dynamic PHP expressions:


This allows arbitrary PHP to be executed and should not be used.

Using unserialize on data that could be entered by the user:


This allows for object injection, a vulnerability that can lead to RCE, and should be avoided if possible. Consider storing complex data as JSON instead, which is safe to use.

Without a deep experience in how RCE exploits are performed it’s hard to spot vulnerabilities, but you should review any code that has dynamic shell commands, eval, or unserialize with a high level of scrutiny.

A parting thought

Information like this can be daunting, but the best way to apply it to your work is to research common vulnerabilities, try a few exploits out, and make security a part of your company’s culture as well as code. Once you start thinking about security it’s hard to get it out of your head - does your company properly use encryption? Is two factor authentication enforced? How’s your office’s physical security? Being aware of these issues can lead to improvements that extend far beyond your custom code.

WPTavern: WPWeekly Episode 351 – Results of the Gutenberg Accessibility Audit

Wordpress Planet - Thu, 05/09/2019 - 00:52

In this episode, John James Jacoby and I are joined by Rachel Cherry, Freelance software engineer, consultant, and director of WPCampus and Brian DeConinck, a front-end designer and developer with the OIT Design and Web Services team, part of the Office of Information Technology at NC State University.

We learn how Tenon was chosen as the vendor to perform the audit and what conditions needed to be met. We then dissected the results of the Gutenberg Accessibility Audit conducted by Tenon. We discuss the state of Gutenberg’s accessibility, recommendations for those in Higher Education environments, and where Gutenberg development might go from here.



WPWeekly Meta:

Next Episode: Wednesday, May 15th 3:00 P.M. Eastern

Subscribe to WordPress Weekly via Itunes

Subscribe to WordPress Weekly via RSS

Subscribe to WordPress Weekly via Stitcher Radio

Subscribe to WordPress Weekly via Google Play

Listen To Episode #351:

WPTavern: WordPress Professionals: Take the Future of WordPress Careers Survey

Wordpress Planet - Wed, 05/08/2019 - 23:24

Nevena Tomovic, a Business Developer at Human Made, is researching the most important skills for pursuing a career in WordPress. She is conducting a survey for professionals that is open to anyone working in a WordPress-related capacity, including writers, developers, marketers, UI & UX designers, illustrators, community drivers, evangelists, project managers, and creatives.

The survey takes less than five minutes to complete and the results will be shared at WordCamp Europe in Berlin and on Tomovoic will be giving a presentation titled “Renaissance jobs in WordPress: Skills you need to survive the 21st-century career,” where she will elaborate on global trends related to the job landscape. She will also be speaking about how employers and managers can attract new talent through WordPress education.

In a recent post on her blog, Tomovic elaborated on the concept of “Renaissance jobs,” positions that use titles merging multiple skills into one role:

Renaissance jobs, also otherwise known as hybrid roles are a mishmash of more than one skill, a combination of expertise in more than one domain. You might have come across roles such as experience architect, user experience consultant, or even customer wrangler, all of these typically involve technical knowledge, excellent communication and management skills. All of these roles are a completely foreign concept for most of our parents. The 21st century has brought with it remote work, chief growth officers, and a globalized workforce among other things.

Tomovic’s survey data will identify what skills are most important in the WordPress job market right now. The survey does not collect any personal data and the raw data will be deleted after the results are published.

If you want to check out Tomovic’s talk in person, make sure to purchase a ticket to WordCamp Europe. The final batch of tickets has gone on sale and there are only 133 general admission tickets remaining.

Freelock : Assessment of May 8 Drupal Security update SA-CORE-2019-007

Main Drupal Feed - Wed, 05/08/2019 - 20:12
Assessment of May 8 Drupal Security update SA-CORE-2019-007 John Locke Wed, 05/08/2019 - 14:12

New versions of Drupal core dropped today, to fix a file handling issue.

After assessing the patches, statements, and risks associated with this update, we have decided this is an important update to apply, but not urgent for most of the sites we manage.

Exploitation of the flaw takes two things:

Drupal Drupal Planet Security

WPTavern: New Membership Block Coming to Jetpack, Site Health and Debug Info Added to Version 7.3

Wordpress Planet - Wed, 05/08/2019 - 17:57

Jetpack 7.3 was released yesterday with changes that improve the “out of the box” experience. The plugin now enables fewer features on setup so users can have more control over what they activate on their sites.

The new version also integrates with WordPress 5.2’s new Site Health checks. It includes a status check and moves Jetpack’s legacy debug data to a section in the new “Site Health Info” tab. The initial status check isn’t very descriptive regarding critical errors, but these error messages can be improved in future iterations so users know how to get to a page with more information.

New Membership Block Now Available for Jetpack Beta Testers

Jetpack is getting ready to introduce a new Membership block that will essentially function like a recurring donation button using Stripe as the payment gateway.

Users will be able to set the currency, price, product name, and renewal interval directly within the block.

This release adds the new block behind the JETPACK_BETA_BLOCKS constant for users who are beta testing new blocks. Feedback from testers will be addressed in future pull requests. The PR merged into Jetpack 7.3 includes the following technical additions for the new Membership block:

  • Introduce endpoints that communicate with WP.COM
  • Whitelist certain options, CPTs and meta to store / sync data
  • Introduce Gutenberg block that uses these endpoints and provides UI to connect to Stripe, create and choose a product
  • Introduce a frontend of a block with the sole purpose of displaying a checkout window from in an iframe

In its current form, the use of the term “Membership” for the block might be a bit misleading for some users, depending on their expectations. Site owners usually expect more granular management of members, multiple membership tiers, customizable emails, various renewal options, content access, and more for managing memberships.

Unless Jetpack intends to make this the gateway to more robust membership capabilities, then “Recurring donation/payment button” might be a more accurate name for the block. However, it wouldn’t be surprising to see a more full-featured Membership module turn up as a SaaS product from, as opposed to everything getting packed into the plugin.

No release date has been announced for the membership block as it is still under active development and in the very early stages of beta testing.

Check out the full changelog to see all the enhancements and bug fixes in Jetpack 7.3. Drupal 6 core security update for SA-CORE-2019-007

Main Drupal Feed - Wed, 05/08/2019 - 17:31

As you may know, Drupal 6 has reached End-of-Life (EOL) which means the Drupal Security Team is no longer doing Security Advisories or working on security patches for Drupal 6 core or contrib modules - but the Drupal 6 LTS vendors are and we're one of them!

Today, there is a Moderately Critical security release for Drupal core to fix a vulnerability in the protections added in SA-CORE-2019-003. You can learn more in the security advisory:

Drupal core - Moderately Critical - Third-party Libraries - SA-CORE-2019-007

Here you can download the Drupal 6 patch to fix, or a full release ZIP or TAR.GZ.

If you have a Drupal 6 site, we recommend you update immediately! We have already deployed the patch for all of our Drupal 6 Long-Term Support clients. :-)

If you'd like all your Drupal 6 modules to receive security updates and have the fixes deployed the same day they're released, please check out our D6LTS plans.

Note: if you use the myDropWizard module (totally free!), you'll be alerted to these and any future security updates, and will be able to use drush to install them (even though they won't necessarily have a release on

WPTavern: WordPress 5.2 “Jaco” Released, Includes Fatal PHP Error Protection and A Recovery Mode

Wordpress Planet - Wed, 05/08/2019 - 17:16

WordPress 5.2 “Jaco” named after bassist Jaco Pastorius, is now available for download. Normally, I’d start listing new features but I’m going to do something a little different this time.

Let’s begin by recognizing the 327 people who contributed to this release with 109 of those being first time contributors. It was led by Matt Mullenweg, Josepha Haden Chomphosy, and Gary Pendergast. Included in the list is Alex (Viper007Bond) Mills who passed away from Leukemia earlier this year.

Screenshot taken by Brandon Kraft

Mills still has a few uncommitted patches in Trac so it’s possible he’ll end up on the list of contributors in future releases.

Minimum PHP Version Required to Run WordPress 5.2 Is Now 5.6.20

WordPress 5.2 bumps up the minimum PHP version required to 5.6.20. If you’re using an older version, you’ll need to update PHP before upgrading to WordPress 5.2. Updating PHP to version 7.3 or above is recommended.

Additional Improvements to Site Health Check

In WordPress 5.1, Site Health Check features were added to inform users of outdated PHP versions. WordPress 5.2 builds on this foundation by adding two new pages that help debug common configuration issues. Users can find the Site Health section in the WordPress backend by browsing to Tools > Site Health.

Site Health Check Test Results

Browsing to the Site Health page triggers a series of tests. When the tests are performed, errors and recommended improvements are displayed on the results page. There’s also a an Information tab that displays every detail about the configuration of your site.

Site Health Check Detailed Information

Theme and Plugin authors can add their own tests and modify or remove existing ones with filters.

Fatal Error Protection

Instead of seeing the dreaded “white screen of death,” WordPress 5.2 includes fatal PHP error protection. When a fatal error is detected, a user-facing error message is displayed and an email is sent to the administrator’s email address.

The email includes a link to a new feature called “recovery mode.” While in recovery mode, plugins and themes that are causing fatal errors are put into a paused state to ensure administrators can work around the errors and access the backend normally.

In addition to being informed about which themes or plugins are causing fatal errors, administrators have at least three options to fix the issue.

  • Administrators can deactivate the theme or plugin to maintain a working version of the site.
  • Administrators can fix the problem if they have the technical capabilities, and afterwards reactivate the theme or plugin.
  • Administrators can file a support request with the developer, pointing out the error.

Administrators can exit recovery mode by pressing a button in the admin bar. A few examples on how developers can utilize this feature can be found here.

WordPress 5.2 also includes accessibility improvements, thirteen new dashboard icons, plugin compatibility checks, and an variety of changes to the block editor. In addition, the Privacy Policy page includes four new helpers that make customizing and designing the page easier.

To learn more about the features in WordPress 5.2 and how to extend or work with them, check out the WordPress 5.2 Field Guide.

Security advisories: Drupal core - Moderately critical - Third-party libraries - SA-CORE-2019-007

Main Drupal Feed - Wed, 05/08/2019 - 16:56
Project: Drupal coreDate: 2019-May-08Security risk: Moderately critical 14∕25 AC:Complex/A:Admin/CI:All/II:All/E:Theoretical/TD:UncommonVulnerability: Third-party librariesDescription: 

This security release fixes third-party dependencies included in or required by Drupal core. As described in TYPO3-PSA-2019-007: By-passing protection of Phar Stream Wrapper Interceptor:

In order to intercept file invocations like file_exists or stat on compromised Phar archives the base name has to be determined and checked before allowing to be handled by PHP Phar stream handling. [...]

The current implementation is vulnerable to path traversal leading to scenarios where the Phar archive to be assessed is not the actual (compromised) file.


Install the latest version:

Versions of Drupal 8 prior to 8.6.x are end-of-life and do not receive security coverage.

Also see the Drupal core project page.

Reported By: Fixed By: 

TEN7 Blog's Drupal Posts: Episode 059: 2019 Twin Cities Drupal Camp

Main Drupal Feed - Wed, 05/08/2019 - 13:35

Chris Weber and Dan Moriarty, volunteer organizers for the 2019 Twin Cities Drupal Camp are today's podcast guests. We'll be talking about the changes to this year's TCDrupal Camp and fond memories of previous camps. 

TCDrupal Camp is a three-day conference for open source enthusiasts, designers, hackers, geeks, developers, UI experts, IT managers and anyone else that wants to find out more about Drupal. It’s a great place to learn, code, network and have fun with your fellow Drupalistas.