Jan 07 2020
Jan 07

You’ve just freshly installed Drupal 8 on your computer and you are really looking forward to
getting your website up and running fast. You want all those amazing features you have heard
about of Drupal 8. So, what do you do next? Pick your Drupal 8 modules! Coz modules are the
building blocks of any great Drupal mansion.

Of course, it isn’t as simple as it sounds. Drupal 8 is powered by its ever-growing open-source
community who work hard to develop thousands of modules that can enhance and extend the
functionality of a Drupal website. Choosing out of thousands of Drupal 8 modules can be a

Luckily for you, many significant contributed modules from Drupal 7 have made their way to
Drupal 8 core. Which means, you will only need to enable these modules once Drupal 8 is
installed. Let’s dive into a short list of top Drupal 8 modules you must have to build great digital
experiences. Following that, we’ll talk about how to pick your Drupal 8 modules.

Admin Toolbar Module

The Drupal Admin Toolbar module is extremely useful for better navigation for site admins and
site builders. The default Toolbar isn’t very user friendly. This module aims to extend the
functionality of the toolbar by offering drop-down menus that allow easy access to various
admin pages. It also offers a submodule to extend its functionality called Admin Toolbar Extra
Tools. This submodule adds more helpful links to the admin menu to perform tasks like flush
cache, run cron and more.

Paragraphs Module

The Drupal 8 Paragraphs Module gives a lot of power in the hands of content authors and
editors. It allows them to create flexible and structured content easily. You can now add various
paragraphs field types like images, text blocks, quotes, slideshows, videos and so much more.
Using the familiar node edit form, you can add/play around with as many paragraph items and
place them wherever you want to. It also offers widgets (still in experimental) which will allow drag and drop functionality, duplicating paragraphs and many other features that can elevate
user experience while working with the Paragraphs module.

Webform Module

This is one Drupal 8 module that is always on my recommended-modules-list. It is so versatile
and such an essential Drupal module that it is hard to ignore. Almost every website needs a
form. A contact form or a survey form or a feedback form – there is no running away from
them. The Drupal 8 Webform Module is a rich form builder that is easily customizable and
extendable. It allows to collect form data, send it to third-party applications or send emails to
admins or users. You can also export this data to spreadsheets for further analysis. There’s so
much more that the Webform module offers which cannot be summed up here.

Display Suite

The Drupal Display Suite module is a very easy-to-use and handy tool to build page layouts. It
offers a slick drag and drop interface to arrange content. There are a list of predefined layouts
and templates to choose from. Custom layouts and templates can also be created and added in
the theme. Custom view modes and custom fields can also be defined.

Devel Module

The Drupal Devel module is a very handy tool for developers and site admins. It is widely used
in testing purposes because of its ability to generate a lot of content for nodes, comments,
users and various content types and entities. Also, it allows developers debug any problems
with node access. Page footers can be added for all pages with the help of its submodule called
Webprofiler. Webprofiler also gives the site admins an insight to some analytics about the
caching abilities, database queries, resource utilization and much more.

Drupal GraphQL Module

GraphQL is a modern querying language that replaces old-timers like REST to communicate with
APIs. It is faster and yields only the results you are looking for – minus all the unwanted
baggage that comes along with a REST API call. The Drupal GraphQL module enables your
Drupal website to create GraphQL schemas and expose Drupal entities with GraphQL client

Pathauto Module

Having a well-structured URL does not only improve the user experience, it is very vital for
search engine optimization too. The Drupal Pathauto module is definitely a must-have module
in every Drupal project. It helps in automatically generating SEO friendly and well-structured
URLs. Site admins can also change the pattern system by changing the tokens it uses.

Google Analytics

The Drupal Google Analytics module adds Google analytics tracking system to your website.
Using this Drupal module, all features of Google analytics can be accessed and integrated with
your website. It allows for domain tracking, users tracking, monitoring tracked links, monitoring
downloaded files, site search, Adsense support and much more.

Things to Remember while choosing your Drupal 8 modules

Be it personalization modules, social media integration modules, marketing automation
modules or any other module, you can always find more than one for each functionality. Here’s
what you should keep in mind before making a choice:


Before you download a module, you should know if it is going to be compatible with your
version of Drupal. You just cannot install a version 7 module into your Drupal 8 installation
without cross checking if it is supported. To find out what version of the module has been
released in Drupal.org, you can go to the module’s project page and scroll right to the end
where you will see the download link and find the release versions specified. If it isn’t specified,
go to http://drupal.org/project/Modules/name and filter by Core compatibility.

They’re free but they consume space

You must keep in mind that although the contributed Drupal modules are free of cost, they are
not feather light. Unused modules can unnecessarily consume a lot of space and resources
which can make your Drupal website heavier and slower. So, before you download a module,
analyze if you really need it or if any other core module can perform the same functionality for
your website. Also, feel free to abandon those hardly used and inactive modules to make your
website feel healthier and light.

Actively Maintained Modules

It is very important to choose modules that are actively maintained, updated and published by
the developers. Because, if you run into any security vulnerabilities or any other issues, you
know that you can get a quicker response from the developer/contributor. Also, you will be
sure that an updated new version is on its way soon.


Using popular modules means you can trust the module to do the job and be secure with less
issues. In the module’s project page on drupal.org, you can see the number of downloads and
how many websites are currently using that particular module.

Look out for issues

On the right side of the Drupal module’s project page, you can find the number of issues and
bugs (open and closed) associated with that module. On clicking on the link, you will be able to

see a detailed report of all bugs and issues. Looking at this can give you an idea if the module
can really help you with your functionality or not. The ‘Last Updated’ date can also give you an
idea of how active the developers are in solving issues and how responsive they are.

Jan 07 2020
Jan 07

We’ve already discussed in our previous blog, how Progressive Web Apps (PWAs) are trending and making web apps load faster, ensuring exceptional user experience.

For one of our clients, we implemented this solution to create a budget planner and currency calculator for a giant travel retail outlet and helped boost the sales just after 3 months of its deployment. 

Let’s dig deeper into the technical details and understand the nitty-gritty of creating PWA using React on a Drupal 8 website. 

Why Opt For This Approach

With the increasing popularity of ReactJS, JavaScript libraries and frameworks prove to be useful in building complex applications by seamlessly getting embedded on a Drupal site, thus combining the robustness of an API-first CMS with slick and quick React frontend to collectively give way to amazing digital experiences along with future-proof builds. 

To create PWA on a Drupal site, one can use Service Workers, Web App Manifest and HTTPS. However, opting this approach will not unnecessarily increase the load of the application and will reduce the entire application load time. Possessing knowledge of React in addition to Drupal is the only requisite here to implement the approach.

How To Create PWA With React on Drupal 

Step 1: Create React Environment

In our last blog on React, we learned how to set up Setup React App From Square One Without Using Create-React-App  Once the environment is set up, we shall move forward to creating a React app.

Step 2: Create React Application

Before looking into the process of creating a React application, let’s get a hold of the below terms:

  • Components - It's the building block of any react app. Basically, there are two types of components.
    • Functional
    • Class (From 16+ react version, this component is deprecated. Only functional components are used.)
  • Props - Arguments passed in react components to send data to components. 
  • States - Behaves like a data store to components. It’s mostly to update components when user performs some operation like clicking buttons, typing some text etc.

Now, let's write our first code block of React by using ES6 classes to create a React component called App.


class App extends React.Component {


Now we'll add the render() method to render DOM nodes.


class App extends React.Component {

  render() {

      return (





In return, we’ll insert a simple HTML element. 


class App extends React.Component {

  render() {

    return <h1>Hello world!</h1>



Finally, we're going to use the React DOM render() method to render the App class we created into the root div in our HTML.


ReactDOM.render(<App />, document.getElementById('root'))

Here is the full code for our index.html:


<!DOCTYPE html>



    <meta charset="utf-8" />


    <title>Hello React!</title>


    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>

    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

    <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>




    <div id="root"></div>


    <script type="text/babel">

      class App extends React.Component {

        render() {

          return <h1>Hello world!</h1>



      ReactDOM.render(<App />, document.getElementById('root'))




Now if you view your index.html in the browser, you'll see the h1 tag we created rendered to the DOM.

hello world screenshot

Hello World screenshot

Step 3: Visualizing the React component in Storybook

Storybook is a user interface development environment and playground for UI components. 

Visualizing the React component in Storybook

The tool allows testing the components independently and interactively in an isolated development environment. Story file code looks like:

Story file code

After running `npm run storybook` command, storybook will open on localhost server as shown in the attached screenshot.

storybook screenshot


Step 4: Creating Custom Block API in Drupal 8 and Embedding React application 

On running npm run build command on React application, it creates this react minified JS file:



The minified js file searches for the markup in the /drupal_root/module/custom/react_block/src/Plugin/Block/ReactApp.php file

and on finding the div ID, it renders itself at that point.

file getting rendered

And this is how the React block renders itself on our Drupal 8 website and makes the website a PWA.

Srijan can help you leverage the power of React with API-first Drupal to create robust content workflows and hence lead to joyful editorial experiences for your business to evolve. Get in touch with our experts or leave your queries in the comment section below and let’s get the conversation started.

Jan 07 2020
Jan 07

We’ve already discussed in our blog how decoupling Drupal helps you achieve greater flexibility, to deliver data anywhere and everywhere to the user at a lightning fast speed, ensuring exceptional web experience.

Let’s dig deeper into the technical details of how progressively decoupled apps can be created using React on a Drupal 8 website.

Why Opt For This Approach

With the increasing popularity of ReactJS, JavaScript libraries and frameworks prove to be useful in building complex applications by seamlessly getting embedded on a Drupal site, thus combining the robustness of an API-first CMS with slick and quick React frontend to collectively give way to amazing digital experiences along with future-proof builds. 

How To Create Progressively Decoupled App With React on Drupal

Step 1: Create React Environment

In our last blog on React, we learned how to set up Setup React App From Square One Without Using Create-React-App  Once the environment is set up, we shall move forward to creating a React app.

Step 2: Create React Application

Before looking into the process of creating a React application, let’s get a hold of the below terms:

  • Components - It's the building block of any react app. Basically, there are two types of components:  Functional and Class (From 16+ react version, this component is deprecated. Only functional components are used.)
  • Props - Arguments passed in react components to send data to components. 
  • States - Behaves like a data store to components. It’s mostly to update components when user performs some operation like clicking buttons, typing some text etc.

Now, let's write our first code block of React by using ES6 classes to create a React component called App.

class App extends React.Component {

Now we'll add the render() method to render DOM nodes.


class App extends React.Component {
render() {
return (

In return, we’ll insert a simple HTML element. 

class App extends React.Component {
render() {
return <h1>Hello world!</h1>

Finally, we're going to use the React DOM render() method to render the App class we created into the root div in our HTML.

ReactDOM.render(<App />, document.getElementById('root'))

Here is the full code for our index.html:

<!DOCTYPE html>
<meta charset="utf-8" />

<title>Hello React!</title>

<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/[email protected]/babel.js"></script>

<div id="root"></div>

<script type="text/babel">
class App extends React.Component {
render() {
return <h1>Hello world!</h1>

ReactDOM.render(<App />, document.getElementById('root'))

Now if you view your index.html in the browser, you'll see the H1 tag we created rendered to the DOM.

hello world screenshot

Hello World screenshot

Step 3: Visualizing the React component in Storybook

Storybook is a user interface development environment and playground for UI components. 

Visualizing the React component in Storybook

The tool allows testing the components independently and interactively in an isolated development environment. Story file code looks like:

Story file code

After running `npm run storybook` command, storybook will open on localhost server as shown in the attached screenshot.

storybook screenshot

Step 4: Creating Custom Block API in Drupal 8 and Embedding React application 

On running npm run build command on React application, it creates this react minified JS file:



The minified js file searches for the markup in the /drupal_root/module/custom/react_block/src/Plugin/Block/ReactApp.php file

and on finding the div ID, it renders itself at that point.

file getting rendered

And this is how the React block renders itself on our Drupal 8 website and makes the website a progressively decoupled app..

For one of our clients, we implemented this solution to create a budget planner and currency calculator for a giant travel retail outlet and helped boost the sales just after 3 months of its deployment. 

Srijan can help you leverage the power of React with API-first Drupal to create robust content workflows and hence lead to joyful editorial experiences for your business to evolve. Get in touch with our experts or leave your queries in the comment section below and let’s get the conversation started.

Jan 06 2020
Jan 06

In my last blog, I talked a bunch about some of the basics of our development efforts around Acquia ContentHub 2.x. There's a lot more I'd like to discuss about that module and the efforts our team has put into it, but one of the comments I got on twitter specifically asked about the Drush commands we packaged with 2.x, how they're used, and what you can do with them, so in an effort to both continue discussing the good work of the team, and the capabilities of the product, I'm going to dedicate this blog to that topic.

A Word about Data Models

I could certainly just document how to use the commands, but as with anything, I think understanding the theory involved is helpful, both for greater understanding of the product itself, as well as principles of good Drupal development. In the previous blog, we talked about the 5 basic steps of data flow, but I didn't get into the specifics much. So I want to talk first and foremost about how ContentHub finds and serializes data to be syndicated (since this will apply directly to one of our drush commands).

ContentHub 2.x relies heavily on a new contrib module called depcalc. Depcalc's got a rather simple API that allows a DependentEntityWrapper instance (a super lightweight pointer to load a particular entity) to be parsed for other dependencies. This API then recursively calls itself, finding all dependencies of all entities it encounters along the way, until it runs out of stuff to look at. Now, many data models are going to be processed pretty quickly, but there are lots of other data models which process slowly. Deeply nested dependency trees will take some time to calculate. I've seen trees of 1200-1400 take 6-8 minutes to process, but I've also seen trees of 300-400 process in just a few seconds. I've also seen data models that didn't come back with results after over 30 minutes of processing. The difference is HOW they're structured, so it's really critically important to understand your data model. If you don't you might not get the results you want or expect. ContentHub has a number of APIs dedicated to helping to streamline this functionality and I intend on discussing them at length in other blogs posts, but for the sake of this blog, it is just important that we establish a baseline understanding. Different data models have different processing characteristics. YMMV.

Calculating Dependencies

In order to understand the characteristics of your data model, you need to understand the basics of how depcalc is going to find dependencies for your entity(ies). First, when an entity is handed to depcalc, it dispatches a dependency calculation event with the DependentEntityWrapper. Event subscribers tend to focus on one classification of dependency, so for instance, one might check to see if the entity is a content entity with entity reference fields, and then dig through all those reference fields finding subsequent entities for processing. Another subscriber might execute if the entity is a config entity and process through Drupal core's config dependencies. Yet another subscriber might look exclusively at text areas finding the input filter that was used to process the data in the field. A handful of these sorts of events exist within depcalc specifically, and since it's an event subscriber pattern, if you have a custom relationship that won't be calculated through our existing subscribers, you can always add your own. As I previously mentioned, all entities found this way are recursively calculated until we find no new entities. We don't attempt to deal with simple configuration, and non-entity data is yet to be used in our syndication pattern.

Identifying Problematic Data Models

Now that you understand the basics of HOW we calculate dependencies, it's up to you to look at your own data models and make determinations about their compatibility with the process we're about to attempt. There are a few obvious guidelines to follow however.

  1. If an entity of a particular bundle has references to other entities of that same bundle, it's possible you will end up having a dependency tree that includes ALL entities of that bundle.
    One of our early clients asked us why they were getting ALL news articles when they exported any one news article. We looked at the data model and noticed that they had "previous article/next article" entity reference fields, and suddenly, this was a very easy question to answer. Similarly, I've had customers with less clear cut relationships between entities of "like" bundle. Organizations related to other organization, and this can lead to situations where calculation on one organization node might happen rather quickly while others simply seem to never finish. In future blogs we'll talk about how to handle these situations, but you need to identify up front if you have them.
  2. Paragraphs
    We support paragraphs, but if you've used it for page layout, it can be a real bear to calculate depending on how deeply nested it is and how many paragraphs are used on an average page. Also, we don't move twig templates around, so the receiving site likely won't have the templates to interpret the incoming paragraph data and it will be displayed oddly.
  3. Lots of entity references
    If you have a single entity bundle with many entity references, this can also be indicative of problematic data modeling, and can make it difficult to predict how long entities of a given bundle might take to process.
  4. Custom Field Types
    This isn't really "problematic" so much as you should be aware that ContentHub is going to make a "best guess" at field types it doesn't understand. If you have custom field types, or even contrib field types we've not yet written support for, some of your data may be incorrect or missing. If you find this to be true for any contrib field, feel free to file a ticket and we can look at what it would take to get it supported.

Ultimately, there's no harm in trying, but you might be surprised by how many entities are actually related to each other in these circumstances. In a future blog I'll detail how we break down these entities and make them processable even when they might be problematic. Also, keep in mind that if an entity you want to syndicate references an entity with the characteristics we've described above, all the same problems can apply.

Exporting Via Drush to Flat File

With all my caveats out of the way, let's get to the meat of this blog and talk about using Drush to export our data. We're going to use a file in the local file system to store our data for output. In order to do this though we'll actually need to files. ContentHub's Drush export command works on the idea of a manifest file to define the specific entities we want to see exported, so we must first create the manifest file. The file can be named anything you like, so you could actually have a series of manifests for different use cases. The manifest can have 1 entity, or however many you need. Start small and work your way up to whatever you might need. In the normal operation of ContentHub with Acquia's service, we seldom need to move many top level entities at once. While a lot of care was taken to make the import and export processes as lean as possible, Drupal core still has static caching of entities baked deeply into entity storage, which can exhaust memory if you have lots of entities loaded over the course of a single bootstrap.

The manifest file should be in yaml format. We support referencing entities in "type:id" or "type:uuid" formats. Your manifest could look as simple as this:

  - "node:1"

A more complicated manifest file might look thus:

  - "node:1"
  - "node:91644a22-8ec8-413e-91fb-b928dba88fd7"
  - "node:315a0239-57d2-4dcb-89bd-f9a76851b74c"

Our first example exports node 1 and its dependencies. Our second example exports node 1, and the two other nodes by their uuids, along with all the dependencies across all 3 entities. If all of these nodes were of the same type, the supporting config/content entities common to them all would only have one entry in the resulting exported output, so this can be a fairly efficient way to group entities together by top level bundle. Also, since we can export config entities, a manifest file can also reference config entities. If you wanted to export a view or some other entity with these 3 nodes, you could absolutely do that, you just need to use the Drupal entity type id, and the id or uuid of the entity you want to export.

Let's assume our manifest file is named "manifest.yml". We can execute our drush command from inside the Drupal directory like so:

drush ach-elc manifest.yml

Once the dependency calculation and serialization processes are complete, this will output what we call "CDF" directly into your terminal. CDF is a custom json data format we use for communicating about our entities. In future blogs, I'll break down CDF into its various components so that it's easy to understand and dissect. If you want to capture this CDF to file, we can do so with typical CLI notation:

drush ach-elc manifest.yml > manifest.json

A Quick Word About File Handling

CDF Doesn't attempt to make the binary representation of files portable. There are obvious reasons for and against doing this, but currently ContentHub depends on sites and their files being publicly accessible. We currently only support the public file scheme (though we want to support S3 and Private files in the long term). If the site you performed your export on is not accessible to the site you will import into, then your files will be missing once the import is complete.

Importing Data from CDF File

Assuming we have successfully exported CDF data to a local file, we can attempt an import. Let's discuss the basic requirements of the receiving site:

  1. Code base must be the same
    All the same modules must be available within the code base. They don't have to be enabled or configured (ContentHub will do that), but they do have to be present.
  2. A blank canvas is always best
    While not a strict requirement, a blank canvas in terms of content and configuration is always going to demo best. I'd suggest using the "Minimal" installation profile for your first attempt. Keep in mind, ContentHub attempts to unify your configuration settings, so if both the Originator (we call these sites Publishers) and the Receiver (we call these sites Subscribers) have the same entity bundles, ContentHub is going to bring the receiver's configuration inline with the originator. That's fine most of the time, but if your setup is more complicated and includes any sort of configuration conflicts, we'll need to solve those separately. While this CAN be done, you probably don't want to attempt it for your first try using ContentHub, which is why I'm suggesting the Minimal profile.

With those guidelines in place, we are now ready to attempt an import. Be sure to point the drush command at the json file you created, NOT our original yml file.

drush ach-ilc manifest.json

This should result in terminal output that tells you how many items were imported. Something like:

Imported 73 from manifest.json.


Congrats! You've just successfully moved content and configuration from one Drupal site to another via Acquia ContentHub! As I've mentioned before, ContentHub is actually backed by a service for doing this at scale, but the benefits of having a drush command for debugging and testing purposes is really invaluable. It works at a small scale, and makes it possible to trial ContentHub's features. We actually do this programmatically in our test coverage a lot to prove that ContentHub is working as expected, and covers the various use cases we want to see.

In future blog posts I'm going to dissect CDF and show what it's doing, and how it does it. I'll also be posting about manipulating your data models, controlling what field data is and isn't syndicated and calculated, and probably a general discussion of the different events ContentHub & Depcalc dispatch, what they're used for, and how they can customize and streamline your data flows. As always, I'm super interested in any feedback people have, and would love to hear about your experience.

Jan 06 2020
Jan 06

At BADCamp, you'll get a chance to learn from the best, see old friends, make new connections, and walk away refreshed, inspired—and a little bit smarter, too.

Join us for four days of talks, training classes, summits, contributions, and socials with some of the brightest minds from all over the planet!

Sign up for the newsletter today! Scroll down to the bottom of the Home Page to sign up.

Jan 06 2020
Jan 06

"There's an app for that."

We hear this often because it's true. In today's hyper-connected world, offering mobile apps for your business or services have become an expectation. According to Statista, the total number of mobile apps on Apple and Google's app stores are 1.8M and 2.47M respectively. It's now the norm to build apps that support both platforms. But native apps have always been an issue for businesses due to the costly development cycle. Then comes cross-platform technology, which enables developers to build and maintain a single code base for applications that can be published across multiple platforms.   

At Evolving Web, we specialize in web development using Drupal and recently extended our offerings to include mobile solutions. We developed mobile applications using React Native that could be seamlessly integrated to Drupal 8 using modules such as JSON:API or SimpleOAuth, and also implemented third party services such as Firebase or Amplify to enhance the mobile experience with features like push notification or real-time data synchronization.   

We have been actively researching and experimenting with cross-platform technologies and have learned that while they can save a lot of development time and costs, they also present new challenges.

Here's a quick overview of the pros and cons of cross-platform technology:


  • Write once, run anywhere: developers don't need to write Swift for iOS or Java/Kotlin for Android. The whole business logic remains in one single piece of code.
  • Easy code management: a single code base is easier to maintain.
  • Shorter development cycle: write once, deploy to both stores. 


  • Unoptimized app performance: the need to support multiple platforms can diminish performance. 
  • Not-so-native feel: Balancing platform-specific experiences can be difficult due to differences in user experiences for iOS and Android.

In this article, we'll explore our experiences with React Native and Flutter, two mobile application frameworks that will continue to dominate in 2020.

The Top Two Mobile Frameworks

In 2019, React Native took the lead of being the most used cross-platform mobile framework, followed by Flutter, Cordova, Ionic and Xamarin. Flutter has also been a rising star in the last year.  

React Native

Created by Facebook in 2015, React Native is undoubtedly the most adored cross-platform mobile development framework with 83.4k stars on Github so far. The framework allows you to build applications using Javascript or Typescript, and brought in the concept of the bridge that helps you generate and manipulate native mobile UI components from a background Javascript thread. Unlike other frameworks such as PhoneGap, Cordova, and Ionic—which rely on webview to render UI components—React Native allows us to create and manipulate real UIView instances like we would have done with native mobile development.  

Moreover, you can also write modules in native languages such as Objective C, Swift or Java, which allows you to interact with OS APIs if you want to build more sophisticated applications. This opens up more possibilities regarding what you can build with React Native.   

Facebook and Instagram are two top-of-the-chart applications built in React Native, not to mention other names such as Tesla and Bloomberg. In May 2019, Microsoft announced a new performance oriented open source project for React Native developers who want to target Windows, another example of how much the framework is extending their capabilities. 


  • Convenience: benefit from time and cost efficiencies. 
  • Faster refresh: get near-instant feedback for changes on React components.
  • It's a sibling with ReactJS so the web components are reusable. 
  • Awesome performance: thanks to its technical capabilities and big, supportive community.


  • Not completely intuitive: you may need expertise from native developers for platform-specific modules.   

With a vibrant developer community and increasing recognition from tech businesses, React Native will thrive and continue to evolve in 2020.

Apps Built With React Native

Apps built by React Native - Facebook, Tesla, Bloomberg

  • Facebook
  • Tesla
  • Bloomberg  


Flutter is a modern development kit from Google used to build mobile apps for Android, iOS and Google Fuchsia—an operating system that can run on embedded systems in smartphones, tablets, and personal computers.

Google announced Flutter's first stable release in 2018. Despite being quite young on the market, Flutter has quickly gathered a large community and is the fastest-growing skill among software engineers. One of the reasons Flutter has risen so quickly is because of its performance. With the UI refreshing at 60fps—mostly using GPU—each and every pixel on the screen is painted on SkiaCanvas, allowing developers to create sophisticated, smooth and highly customizable UIs.   

In order to build apps with Flutter, developers need to use Dart, a programming language also developed by Google. There are many fantastic features of Dart that make it crucial to Flutter's success, one of which is that Dart is one of the few languages that does compiling in both AOT and JIT. Just-in-time (JIT) compilers run during the execution of the program, compiling on the fly, which provides much faster development cycles as developers see updates right away, though it has slow startup times. On the other hand, ahead-of-time (AOT) compiles high-level programming languages into native machine code so that the resulting file can execute natively and really fast. Flutter's use of Dart benefits from the hot reload thanks to the JIT compiler and the quick execution and startup times due to the AOT compiler.   


  • Hot reload: you can see the results of your changes almost instantly.
  • Speed: fast execution and startup times.
  • High-performing native experience: the UI refreshes up to 60 fps animations.
  • Direct access to native code: you can import libraries and use native APIs.
  • Fantastic testing and performance profiling support. 


  • Relatively young: not as much support as other frameworks. 
  • Less features: less available plug-ins.  

Apps Built With Flutter

Flutter Apps - Google Ads, Alibaba, Top Goals

  • Google Ads
  • Alibaba 
  • Top Goals


If you're a developer with a JS background, React Native's big community will speed up the learning process and is a quick way to familiarize yourself with mobile development.   

If you don't mind learning a new language and want to experiment with a new technology that's performance focused, Flutter is the way to go.  

In 2020, we will continue to bring more beyond-Drupal solutions to our clients and can't wait to maximize the capabilities of React Native and Flutter for future projects. Tune in for future blog articles where we teach you how to integrate these solutions with Drupal!

If you want to learn more about Evolving Web and our culture, feel free to visit our careers page

Jan 06 2020
Jan 06

When Layout Builder was introduced into Drupal 8 Core, it gave Site Builders a tremendous amount of flexibility previously reserved for Front End Developers (or Themers).  While it represents a major leap for Drupal, there are still some shortcomings in the module, and that's where some great additional contributed modules are really helping.

In this blog post, we will highlight three of the best modules currently available.  (Note: more are being added all the time!). For a complete list of contributed modules for Layout Builder, visit https://www.drupal.org/docs/8/core/modules/layout-builder/additional-modules.

Layout Builder Styles

layout builder styles edit configThis module allows site builders to select from a list of styles to apply to layout builder blocks and layout builder sections.  Created by Brian Osborne (bkosborne) a Senior Web Developer from Princeton University, this module makes it incredibly simple to apply previously defined CSS styles to both sections and blocks (you'll need those styles in a stylesheet in your theme or use a module like Asset Injector).

A "style" is just a representation of one or more CSS classes that will be applied. Additionally for blocks, a block template suggestion is added for the selected style.

A simple user interface is provided for managing the styles available. Since a style is a configuration entity, it can be exported and imported just like any other configuration data on your site.

Please note that this module requires Drupal 8.7.0 at a minimum.  The full documentation is here at https://www.drupal.org/docs/8/modules/layout-builder-styles.  At the time of this writing, the module is still in beta; however, we've used it a number of times without issue.

Layout Builder Library

This module was created by Lee Rowlands (larowlan), a Senior Drupal Developer for PreviousNext (Tim Plunkett is a co-maintainer).

With this module, Site builders can create and deploy pre-defined layouts for each entity-type and bundle combination.  Content editors can then select from existing layouts.

Also, Site admins can prevent content-editors from creating their own bespoke layouts, but give them the ability to customize layouts on a per-content-item basis.

layout library

This module is also in Beta at the time of this writing; however, it is recommended by the project's maintainer, and we've had no issues with it.

Layout Builder Restrictions

layout builder restrictionsOut of the box, the Layout Builder "Manage Display" interface shows all blocks (including all entity-specific fields), and all layouts that are registered in the system. This module provides an interface for suppressing blocks and/or layouts. Sites can allow all options from a certain provider, or restrict all options by provider, or specify individual allowed blocks & layouts.

Created by Mark Fullmer (mark_fullmer) from the University of Texas.  

This module is very helpful in restricting what a content editor sees when they click add section or block.  

Restricting the layouts a content editor can choose, can prevent any "over-creativity" from creeping into your site.  By restricting blocks, the entire interface becomes less confusing.  The reasoning here is why should we display blocks (or anything) that we would never want to be added to a node?

This module is in version 2.4 as of this writing, and is recommended by the project's maintainer.  Mark has also committed to ensuring compatibility with Drupal 9.

Final Thoughts

Layout Builder is a game-changer for Drupal Site Builders.  These three additional modules really help make it easier to use!

Newcomers to Layout Builder in Drupal 8 should check out our 30-minute video class at https://www.ostraining.com/class/drupal-8-layout-builder/

About the author

Rod holds two masters degrees and has been training people how to do "things" for over 25 years. Originally from Australia, he grew up in Canada and now resides just outside Cincinnati, Ohio.
Jan 06 2020
Jan 06

It is known that page load time is one of the important aspects of search engine result position. Site speed is what stands between the website and the potential user.

Caching therefore plays an essential role in optimizing websites to deliver high-performance. Not only does it help support faster load times than otherwise possible, but it also helps in reducing latency. The information can be stockpiled at every level right from the original server to intermediate proxies to the browser.

Drupal encompasses numerous tools for caching content that can work for your site exceptionally and it’s important to know what they are and what they do. This blog will elucidate the caching mechanism in Drupal 8.

Drupal 8 Caching Modules

By default, Drupal 8 comes with 2 modules for implementing caching-

  • Internal Page Caching:
The Internal Page Caching module when enabled, stores the complete page information even if the user visiting the site hasn’t logged in. Future anonymous visitors will then observe that the same content is loaded extremely fast since the page wasn’t put together from scratch. This module is useful for websites with a lot of unregistered users
  • Internal Dynamic Page Cache:

The Internal Dynamic Page Cache module is designed to cache small sections of each page for all users whether they are logged in or not. Whenever the page content is requested by the same or different user, the module can pull in those individual parts to speed up the building of the page on the fly.

Understanding Caching At Different Layers

Caching in Drupal takes place at three separate levels: application, component, and page. Given below is the detailed description of each-

  • Application-level Caching

Application-level caching is in-built in Drupal. However, you won’t see it in action until you scrutinize Drupal’s internal code. It is active by default and won’t even show older, cached pages.

The application-level caching in Drupal ensures that the cached pages are separately stored from the site content (which goes into the database). You can’t set this up, except for guiding Drupal where to save cached pages explicitly. 

Drupal stores its external and internal data structures efficiently to enhance repeated users’ access when performing application-level caching. This isn’t the information that a site visitor sees in itself but forms a critical factor in constructing any page. The only level of refinements that can be made at this level is improving where this cached information is stored, like using Memcached instead of the database.

  • Component-level Caching

Component-level caching works on front-end components such as blocks, panels, and views. For example, you might own a website having dynamic content but a single block remains constant. In fact, you may have the same block widely scattered across dozens of pages. Caching it can deliver improved performances significantly.

Though component-level caching is generally disabled by default, however, you can make it active with some simple configuration changes. You can initiate with identifying blocks, panels, and views on your site that remains the same across to later cache them strenuously. You will notice a strong speedup for authenticated users.

  • Page-level Caching

As the name suggests, this page-level caching caches, stores, and delivers the entire page to the user. One of the most effective types of caching,  it shoes static HTML pages to users to improve site performance almost immeasurably.

Page-level caching gives you enough space to customize where you can use any number of caching servers, including Varnish, or CDNs like CloudFlare to deliver cached pages from servers close to the users’ location. 

CDNs help you in bringing your site closer to your users. However, it only works for anonymous users by default. Fortunately, this drives huge traffic to any website.

A typical Drupal application comprises of all the layers mentioned above. However, to better understand the flow and learn how to debug a caching issue, a flowchart is given to illustrate how content is cached at different layers-

Flowchart of how caching works in Drupal 8Learn more about caching from here-

[embedded content]

Cacheability Metadata in Drupal 8. What is it?

Cacheability metadata is used to describe the thing which is rendered with respect to its dynamism. Сaching properties could be applied to any object and one can easily change the default cache settings of these three properties-

  1. Cache Tags  
  2. Cache Contexts  
  3. Cache Max-Age
  • Cache Tags: 

Tags are used to nullify cache entries when something on the site undergoes modification. (nullifying or invalidating means that the cache entry won’t get used, and will be reconstructed the next time that piece of content is rendered). Drupal comprises multiple cache tags to explicate all sorts of different scenarios from individual nodes and blocks, to site configuration settings, and menus. 

For example, the cache tag ‘node:5’ gets invalidated any time the Drupal content node with ID 5 gets modified.

So, whenever content gets cached which depends on something related to node 5,  the cache entry keeps track of that tag; then, saving the node causes that cache entry to get invalidated. This implies that any time you save something in Drupal, a relevant tag gets invalidated.

The tag for the same will look like this-

Syntax : “node:5” 

node_list: List cache tags for node entities

  • Cache Contexts: 

Contexts are quite different from tags. Cache contexts are stored alongside cache entries and are designed to let content vary depending on what circumstances or situation it is showcased in.

For instance, you have a site with users of several different roles, and one block on the site is meant to show content differently depending on what roles the user seeing it has. This can’t be implemented through cache tags alone. However, it won’t be a good idea to leave the block completely uncached, instead, it can have the “user permissions” context applied to it. This way, the block can be cached multiple times- specifically one time for each combination of roles that the users see the block have. This way, an administrator can see something different from an editor who will see something different from a user who has both roles.

Commands shown in for caching tags

  • Cache Max-age:

Cache max-age is the last step to handle cache invalidation. You have to simply set the time on how long the content should be cached for. This can vary from 0 seconds (to not cache content at all) to as long as you want. 

Presuming that all of the tags and contexts being used are working as intended, this can be put to indefinite (default state in Drupal) since those can cover most scenarios where cached content might need to be created.

Given this, there is still no mechanism that notifies your Drupal site about the change in content, and therefore, no-cache tags can be invalidated and no context is helpful (as the content doesn’t vary by the situations in which it is displayed).

However, if you set a max-age of 3600 on the page, then it will cache its content for up to one hour before automatically invalidating, at which point the next person who views the page would get a brand-new updated version (fresh with new content from the remote service) which would then get cached for another hour. This way, you can leverage all the benefits of caching without causing your site to stop updating itself with content from the remote service. 

Summing Up-

Caching lets you retrieve data instantly without having to request it from the source. Given that, it makes up a significant part of website speed optimization. If you want to ease surfing experience for your users on the site, then enable the cache for the same. Drupal 8 has enhanced its caching capabilities considerably.

Jan 06 2020
Jan 06

The templating engine of Drupal 8 has seen a massive turnaround. Unlike Drupal 7, there’s Twig in Drupal 8 instead of PHPTemplate. Twig is basically a templating language for PHP i.e a tool used to output variables inside HTML. Fabien Potencier, the creator of the Symfony framework, gave life to Twig. Contrary to Drupal 7, you cannot call the regular PHP functions in your templates in Drupal 8. he way forward, in Drupal 8, is to create filters and functions.

Icon resembling human wearing blue shirt standing in front of a white board explaining Twig Extension in Symfony and Drupal

Twig extension gives more flexibility to process nearly anything inside the twig. Twig can be extended in many ways such as tags, filters, operators, global variables, and functions.

One of the major plus points of creating a twig extension in Drupal 8 is in the view.

Drupal 8 views can often be more challenging in the case where you want to perform operations on the value or need to process the content in the field. When you need to write code often, try to reuse it rather than writing it from scratch every time.

You must use a filter when you want to transform the data you want to display. Imagine you have a title that you always want to be capitalized. For example, twig has the capitalize filter that allows you to transform any text into its equivalent in uppercase.

I came across Twig Extension during one of my E-commerce projects where I had to print dynamic currency name. Drupal Commerce allows only 3 characters long currency code and they have also implemented their own Twig Extension to convert Price object into equivalent price format. So to handle this case where I have to show currency name with more number of characters, I had implemented my own Twig Extension. Similarly, there are several other cases where these Twig Extension can be very handful.

Let’s see an example where we will create a filter that will allow us to count the number of words in the article. The process of creating filters and functions is exactly the same as normal Twig. Also, you can use word count to display the reading time of the article or any other use case as per the requirement.

The main difference between regular Twig and Drupal 8 Twig is that, in Drupal 8, you must create a service definition of the class you are creating and the class must also belong to a namespace, otherwise it will not be registered as a Twig filter in the Drupal environment.

This example assumes you have a module called:


This will be the basic definition of the inn service.

    class: Drupal\twig_word_count_extension\TwigExtension\TwigWordCountExtension
      - { name: twig.extension }

The key tags are also absolutely necessary and that is what Drupal tells you what this class is supposed to do (that is, register it as an extension of Twig).

And now the source code that should be placed in the path defined in the class service definition key.


namespace Drupal\twig_word_count_extension\TwigExtension;

use Twig_Extension;
use Twig_SimpleFilter;

class TwigWordCountExtension extends \Twig_Extension  {
   * This is the same name we used on the services.yml file
  public function getName() {
    return 'twig_word_count_extension.twig_extension';

  // Basic definition of the filter. You can have multiple filters of course.
  public function getFilters() {
    return [
      new Twig_SimpleFilter('word_count', [$this, 'wordCountFilter']),
  // The actual implementation of the filter.
  public function wordCountFilter($context) {
    if(is_string($context)) {
      $context = str_word_count($context);
    return $context;

Clear your caches and now, if everything goes according to plan, you can use the filter in your templates.

{{ "shuffle me!" | word_count }} {# Return 2. #}

Note: If these twig extensions don’t have other service dependencies (i.e. if you don't inject services in them), the performance is not affected. However, if these extensions have lots of complex dependencies, for example, say those making database connections or perform heavy operations, the performance loss can be significant.

To avail help from our experts for your Drupal projects, you can check out our suite of services. You can also talk to us at [email protected].

Jan 03 2020
Jan 03

For years, Drupal site builders have endured a less than great experience with any media they wanted to use.  It was difficult to manage and reuse images; let alone video, audio, and other media.  A number of excellent contributed modules tried to bridge that gap in Drupal 7; however Drupal 8 committed to having a media manager in core.  

As of December 2019, that wait is over with the Media module now officially out of "experimental" and fully integrated into Drupal core.

Probably the most exciting change for site builders in Drupal 8 is that almost everything is an entity, and media is no exception.  That introduces one big issue for images - an image style is not so ealily added to your image as it was in Drupal 7.  Learn how to create and apply image styles for media following this tutorial.  It's not difficult, but it does require some planning, because it's now a four-step process.

Step One:  Set up Image Styles

Go to Configuration > Media > Image styles and define styles as needed. For this article, we will use "Gallery", but the steps can be repeated for additional styles as needed.  For simplicity and consistency, it's not a bad idea to use the image style names in the next step as well.

image styles

Step Two: Set up Media View Modes

Go to Structure > Display modes > View modes and navigate to the “Media” section. Add media view modes.

While it's not necessary to name the view modes the same as the image styles, it can help keep everything better organized, especially when there are many more styles than are being covered in this tutorial.

media styles

Step Three: Manage Media Display

Once you’ve created all your media view modes, go to Structure > Media types > Image > Manage Display and enable "Gallery".  Continue to enable all custom displays created in Step One.

custom display settings

Now that these are enabled, go to the "Gallery" display, find the image field and make sure its format is “Image.” Click the gear icon and set the image style.
Repeat this step for remaining displays.

manage display media

Step 4: Manage Entity Display

Now we'll see it in action.  I’m going to review how to setup fields in a content type, but this process can be used on any entity that allows for fields to be defined.

Go to the Manage Display tab of your content type, “Article” in my case. For the Default display, set the “Rendered entity” View Mode to “Gallery.” Now every article node when displayed with this mode will use that style to render the image field.

manage display content

Repeat this step for any other entity displays that have been created, and that's it.

Be sure to watch this video from our class on the Drupal 8 Media Module.

[embedded content]

See the full class here: https://www.ostraining.com/class/learn-drupal-8-media-module/

About the author

Rod holds two masters degrees and has been training people how to do "things" for over 25 years. Originally from Australia, he grew up in Canada and now resides just outside Cincinnati, Ohio.
Jan 03 2020
Jan 03

If you look up the word ‘terraform’ in the Oxford English Dictionary, the meaning that you find may make you reminisce about some of the science fiction movies or TV series you have watched or heard of. And you may start wondering if something like ‘terraforming’ is actually possible. Transformation of another planet to make it Earth-like, which is what terraform means, would seem like a glorious idea. As there’s always a ‘but’ associated with any brilliant thought that we have, this terraforming of Mars or any other planet is not possible with the current technologies, says NASA.

Terraform process of a planet shown through an open sky filled with white curves to resemble shooting stars

Anyway, on Earth, terraforming is possible. (Although this is in no way referring to the tackling of climate change, it would be nice to see some strong measures being taken). Earth, our home, is witnessing a wave of digitisation all around in this 21st century. Amongst different digital innovations that are happening, one of the open-source tools, which is incidentally, and rightfully, named Terraform, is here to metamorphose the web arena. And Drupal web application infrastructure can reap the benefits of Terraform to a great extent.

Infrastructure As Code with Terraform

Logo of Terraform with Capital T formed by violet parallelograms and Hashi Terraform written below it

To better understand Terraform, let’s start with an example where you are hosting a Drupal site on AWS. Managing the infrastructure here is a crucial aspect. You will be required to create an Amazon Elastic Compute Cloud (EC2) instance with your Drupal code to serve traffic. But that’s not all. There are more things to be taken care of. You are required to look after the identity and access management (IAM), subnets, auto-scaling groups, virtual private cloud, security groups, target groups, load balancers, Elastic load balancing and many more. Infrastructure as Code (IaC) is your solution to manage infrastructure resources effectively.

IaC automates the provisioning of infrastructure and allows your digital firm to build, deploy and scale cloud applications rapidly, cost-effectively and with minimum risks. It utilises top-of-the-line descriptive coding language for automating the process of provisioning of IT infrastructure. This reduces the need for developers to manually provision and manage servers, operating systems, database connections, storage and several other infrastructure elements. To apply IaC, leveraging Terraform is your best bet.

What is Terraform anyway? It’s a configuration orchestration tool that can work with private cloud, public cloud or on-premise system and has the provision for secure and convenient design, governance and improvement for infrastructure as code. As a cross-platform, extensible tool, Terraform codifies APIs into declarative configuration files. These can, then, be shared amongst team members, treated as code, edited, analysed and versioned.

“Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently.” - Terraform.io

Terraform enables you to define infrastructure in config/code and lets you rebuild/change and track alterations to infrastructure easily. Terraform’s speed and operations are impeccable. Its plan command ensures that you make alterations to the infrastructure predictably and safely. That is, you will know what Terraform will do before you make any changes which leaves zero possibilities of any sort of surprises later on. By building a graph of all your resources and parallelizing the building and modification of any non-dependent resources, it gives insights into dependencies in the infrastructure. And, intricate changesets can be applied to the infrastructure with the help of minimal human interaction. Being open-source, it also has a lively community for you to easily engage with them and start using it.

Table with rows and columns showing comparisons between Terraform, Ansible, Chef, Puppet and SaltStackComparison of Terraform with similar tools | Source: IBM

IBM states that, in general, Ansible, Puppet, SaltStack and Chef are considered to be the configuration management tools where the software is installed and managed on existing server instances. Terraform, on the other hand, is considered to be an orchestrator which provides server instances itself thereby leaving the job of configuring those servers to other tools.

Bar graph with horizontal, blue coloured bars to show statistics on market share of Terraform, Ansible, Chef, Puppet, and Salt

Even though Ansible leads the adoption charts, it’s the Terraform that has witnessed a surge in users in recent times. According to a 2019 State of the Cloud survey, conducted by RightScale, Terraform displayed the strongest growth. It expanded from 20% in 2018 to 31% in 2019.

Implementing serverless architecture with Terraform and Drupal

A session at Decoupled Days 2019 showed how Terraform can be used in the Drupal web application infrastructure. It demonstrated how to architect a serverless solution for serving the frontend with data that is fetched via an API from Drupal. The serverless frontend application was hosted with multiple cloud providers available via a CDN (Content Delivery Network). Such an application could be provisioned several times in multiple regions of more than one cloud providers with the help of Terraform. Writing wrapper scripts for Terraform streamlined the process of deploying infrastructure.

Drupal’s multisite capabilities, where multiple separate websites from a single codebase could be run, made the hosting requirements for the backend simple. The Frontend part wasn’t easy as it required to run multiple instances to emulate the number of web properties. All the websites were built on a common stack and the infrastructure resources could be easily shared where needed.

Drupal’s multisite capabilities, where multiple separate websites from a single codebase could be run, made the hosting requirements for the backend simple.

In this decoupled Drupal setup, the infrastructure for static web assets (comprising HTML, CSS, JavaScript, fonts and others) required Amazon S3 or similar storage and a CDN distribution with origin set to the S3 bucket. The frontend code was done using Angular.

With the presence of different environments and the need for an endpoint to access the API, hardcoding the URL during the build time was necessary. IP whitelist was used for Drupal server for high-level security. All the content was retrieved from a proxy. The proxy could be placed behind a CDN thereby improving performance and availability.

With several websites and environments, infrastructure automation was needed. Terraform made it all possible. It enabled the process of writing similar scripts for AWS and Aliyun, for instance. Terraform modules were run once to prepare the environment and create IDs of all the resources. The IDs were set in a configuration file which was accessible to all the Jenkins runs. This made sure that the front end code could be deployed from the CI (Continuous Integration) builds. Terraform also helped in administering the state of all the infrastructure.


System administrators and DevOps engineers strive to do more with less. Defining infrastructure in code and automating its deployment brings about operational efficacy and lower administrative overhead. Terraform is all set to be your go-to toolset for infrastructure automation. And, it can be a great asset in Drupal web application infrastructure.

Using Terraform can be fun. For starters, you can take Terraform for a spin and simply play with it to better understand its efficiency for your digital business.

Offering fantastic digital experience has always been the objective of OpenSense Labs. Talk to our experts at [email protected] and understand more about Terraform’s capability in transforming the landscape of your web application infrastructure.

Jan 03 2020
Jan 03

Ok, the problem is clear:

  • Your composer based Drupal site put code base to the /web folder
  • You are using a shared hosting which maps your primary domain to /public_html, and you can't change that

Now your users will have to browse your site as http://example.com/web . And it is not cool.

So how to serve your site from the subfolder /public_html/web but removing the /web suffix so it becomes transparent to users?

Here are the steps, as I learned from this thread on Drupal.org

1. Open your settings.php file and add the following code:

if ( isset($GLOBALS['request']) && '/web/index.php' === $GLOBALS['request']->server->get('SCRIPT_NAME') ) {
    $GLOBALS['request']->server->set('SCRIPT_NAME', '/index.php');

2. Create a .htaccess file on the /public_html folder with:

<IfModule mod_rewrite.c>
RewriteEngine on
# Redirect to the subdirectory because that's where Drupal is installed
RewriteRule (.*) web/$1 [L]

3. Update .htaccess under /public_html/web folder

Uncomment the line RewriteBase and set it to:

RewriteBase /web

4. Clear the cache and run update.php

Your site should work by browsing http://example.com now (without the /web suffix). Your menu items may still have the /web part, but it will be gone after some hard refresh.

5. (Bonus) If you want to redirect http/https and wwww/non-www:

On the .htaccess file under /public_html/web, please add those lines between the <IfModule mod_rewrite.c> tag:

This is to redirect non-https + www to https + non-www:

  RewriteCond %{HTTPS} off [OR]
  RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
  RewriteRule (.*) https://example.com/$1 [L,R=301]

And this is to redirect non-https + non-www to https + www"

  RewriteCond %{HTTPS} off [OR]
  RewriteCond %{HTTP_HOST} !^www\. [NC]
  RewriteCond %{HTTP_HOST} ^(.*)$  [NC]
  RewriteRule (.*) https://www.%1/$1 [R=301,L]

You can see those examples on Htaccess guide.

Jan 02 2020
Jan 02

So my blog's been offline for a while now. I think there was a security issue sometime around 8.2.2 because I just upgraded the public version of the site from 8.2.1 directly to 8.8.1. I actually did an upgrade to 8.8.0 alpha-something that I used to bootstrap the upgrade to 8.8.1, but public-facing the site made a pretty big jump. Some of this is due to laziness on my part, but a pretty significant portion of my disappearance has been due to a new (to this blog) position within Acquia. I've been at Acquia for nearly 6 years now (in April of 2020), and for almost the last 2 years, I've been helping Acquia re-develop the ContentHub product.

ContentHub is a really interesting problem space. I tend to get sucked into these very nuanced, support-everything-imaginable situations with Drupal module and core development, and ContentHub is no different in that respect. Ultimately, it's intended to be a syndication engine, taking content from one site and materializing it on another. However, the nuance of doing this between Drupal sites is quite detailed. In order to solve this, we approach content syndication in a 5 step process, with 2 steps happening on the originator, 2 steps happening on the receiver, and 1 step happening within our service.

  1. Dependency Calculation (Originator)
    Any given piece of data within Drupal might depend on dozens of other pieces of data. The common "article node" that Drupal 8's standard profile ships with depends on around 40 other entities at the very least. These include the node type, field storage and config, author, tags, image(s) and any supporting entity bundle/field/view mode/form mode data each of those entities requires. Even simple entities are quite complicated in terms of what data they require in order to operate. We can't really "depend" on any of these things existing on the receiving end of our syndication pipeline, so we have to package it all up and send it en mass and let the receiver figure out the details.

  2. Data Serialization (Originator)
    Ideally, this is a "solved" problem in Drupal 8. The 8.x-1.x version of ContentHub tried to use the serialization engine that ships with Drupal core in order to do much of this work, but this approached tended to come up short when dealing with multilingual data. This may have been a flaw exclusive to ContentHub 8.x-1.x, but ultimately, when looking at this problem space, it seemed easier to have each field declare how it was to be serialized, deal with all language level data on a per field basis, and have a fallback mechanism for unrecognized field types for "best guess" solutions.

  3. Communication (Originator->Service->Receiver)
    Once we've found all our dependencies and serialized them, we send that data to an Acquia specific service whose job it is to filter data by customer-defined criteria, and send the appropriate data to any receiving sites the customer might have on a per-filter basis.

  4. Data Collection (Receiver)
    Since only filtered data is sent to a receiver, it may not actually get all the data required to install a given piece of content, it just gets the content itself. Each piece of data is constructed with a reference to all its dependencies so that a complete list of requirements can be built before attempting to import anything.

  5. Data Import/Site Configuration/Dependency Handling (Receiver)
    Ok, this is a bunch of stuff to have all in one step, but when you have a giant list of completely different types of data with different module & configuration dependencies, you have to be flexible. In this step we start by identifying all the required modules for an entire import. Once that's complete, we check to see if those modules exist on our receiver and bail out if they don't. If they DO exist, we enable them and start parsing through the incoming data. This is tricky too though because we can't create a new node without first creating the node type and adding all the fields to it. If one of those fields references taxonomy terms from a particular vocabulary, we have to make sure that vocabulary exists... etc, etc. To this end, we loop our data set progressively creating the dependencies based upon what we have locally available and what's required to support our incoming data. Eventually, we'll process the entire incoming data stream finishing with the original entity that was requested for syndication.

Having outlined this basic flow, I want to contrast this with Migrate for a moment. Both Drupal 8 & 7 migrations happen on a per-entity-type basis. All the incoming node types are created before any nodes will be created. All the users will be created before nodes. All the terms, etc before most nodes (based on what dependencies any migration might have). This is really sensible since we tend to use Migrate for an entire site's worth of data at a time. ContentHub doesn't have this luxury since as little as 1 item might go to a site for syndication, or as much as many thousands. Whatever the case, ContentHub has to be capable of identifying how to handle any incoming entity type, creating that entity type, and moving on to some other based upon how the dependencies are stacked in a given Drupal setup.

This approach is really powerful because it ends up acting very similarly to the Features module. Since ContentHub can syndicate any sort of entity (so long as it supports uuid... don't get me started) it can package up things like content types, views, etc and send them to another site, complete with automated module dependency calculation. The team's common demo example has been installing Umami as an originator of content, and then using Standard or Minimal as a receiver, and then watching all the Umami configurations and content stream in to fill out a blank site. Acquia's demo team has actually been using it for setting up demo content in a limited capacity, and I'd love to help push that further by figuring out how to use our data format to uninstall data from a site (by reverse dependency encumbered-ness).

Ultimately, I'm really pleased with the efforts of the last almost 2 years of time. I think ContentHub 2.x is a really cool tool that a lot of people could use to varying degrees to do different compelling things. We included a couple of drush commands with it so that people could play with it without subscribing to our service. They can import/export data from manifest files, and are really useful for demoing the product and also doing development in a completely controlled manner. If you get a chance to play with ContentHub 2.x I'd be very interested to hear from you, or if you want to ask questions, please let me know!

Jan 02 2020
Jan 02

Major League Hacking’s Local Hack Day - Build is a global day-long hack day, which brings ideas to life with a worldwide community.

The Local Hack Day Build was scheduled from the 1st-7th December 2019 in different cities across the globe. A 12 hours hackathon known as BUILD was carried at more than 200+ locations during this period. Facebook and MLH were the event sponsors! 

QED42’s Pune office hosted approximately 65+ bright and curious minds for the Local Hack Day - Build on the 7th December 2019! This included a considerable amount of college graduates.

MLH Local Hack Day 2019

I had the opportunity to engage with Facebook Developer Circle Pune. To my surprise, students possessed knowledge about technologies like Docker, Git, and presented innovative ideas. Within a span of 12 hours, groups had created both desktop and mobile applications, which was commendable.

Let me walk you through the Local Hack Day at QED42. 

| Introduction

We kickstarted the event started with the MLH Local Hack Day introduction by Sangeeta Gupta (Facebook Developer Circle Pune Lead). Post this, Sayak Sarkar conducted a brief session on Git and Github. 

MLH Local Hack Day 2019

Some groups came up with innovative ideas, while others received ideas from the organizers. And finally, the event began! 

| Event Kick-Off

Groups of curious and innovative minds started working on their prototypes. In the middle of the prototype creation process, the organizers had arranged scrumptious lunch for everybody. Post lunch the groups resumed work on their respective prototypes.

MLH Local Hack Day 2019

| Interaction with FDC, Hyderabad

We also had the opportunity to interact with our sister community Facebook Developer Circle from Hyderabad. They were also hosting the MLH Hack Day!  Sharing updates and stories with them was an absolute pleasure. We played a fun game between Pune and Hyderabad folks, where each team has to mention a programming language name until other team runs out of known language names.

MLH Local hack day Facebook Developer Circle Hyderabad

Among several innovative ideas and demos, here are a few of my favourites:

  1. An application that enables children with down syndrome identify wet and dry waste by looking at the images. The app guides and communicates via text to speech functionality, whether or not the choice made by the individual is right. This helps improve the performance of special children. Link: https://github.com/Amarn7/Learn

       Team Members:

  • Amar Nagargoje
  • Atharva Barve
  • Tejas Bhadane
  • Nirav Madariya
  1. An Online Judge System which also is one of the world's first Self Learning Ladder - based judge system, along with developing their own indigenous IDE. To make this project more of a Capstone Project, the team developed a Web interface and an Android App interface too. Link: https://github.com/pratikdaigavane/Son-Of-Anton

       Team Members: 

  • Ayush Shah
  • Kunal Raut
  • Prathamesh Shiralkar
  • Pratik Daigavane
  • Saarth Deshpande
  • Tejas Joshi
  • Utkarsh Atre
  1. Built an internet bot to buy and sell digital gold on Paytm Gold at the best possible buying and selling prices. Enabling users to earn money without doing anything. Link: https://github.com/PranshuTople/GoldDigger

       Team Members: 

  • Pranshu Tople
  • Pallavi Saha
  • Shubham Nandi
  • Rishabh Agarwal
  1. Women Safety App where the map will be segregated on the basis of the danger zones in the city based on the threat level. The areas will be colour-coded as grey, yellow, and red. The mobile will be connected with the GPS for live tracking if a person goes into the threat zone a prompt will be sent to the emergency contacts. If the person stays too long in the danger zone without any activity, the alert will be sent to the police department. Areas are segregated by the threat level determined by crowdsourcing the information about any particular area. Link: https://github.com/Knightfire1998/DotDashDot3.git

       Team Members:

  • Reshikesh Umakant Dhanrale
  • Akshit Abhay Keoliya
  • Shweta Singh
  1. Learning to use Azure Cloud Cognitive services and GitHub integration. Mood Detector - Captures your face and detects the mood like Happy or Sad. Link: https://github.com/AJV009/mooddetector/Hacker name: Alphons Jaimon

  2. Millions of saplings are planted every year, and millions die too. Because they are not taken care of. This is a humble attempt to track all such saplings around a volunteer's vicinity keeping the external factors like weather into account. Link: https://github.com/Devendrabhat/angry-buddha

       Team Members:

  • Aniruddha Kibey
  • Devendra Bhat
  • Shagun Kaushik
  • Shreyas Kalmegh

You may also read about the other projects here: https://github.com/devcpune/solid-doodle/

MLH Local Hack Day 2019

Here are a few more highlights from the Local Hack day: 

  1. FDC Pune members launched the official Facebook Developer Circle: Pune organisation on GitHub and made the first solid-doodle repo. Currently, it has 102 commits and 23 contributors in the repo. Link: https://github.com/devcpune/solid-doodle/

  2. We discussed the DevC Training courses and how they can prove to be extremely beneficial for the community.

MLH Local Hack Day 2019

At the end of the local hack day, we collected the participant’s feedback in a rather innovative way! Participants drew emoji’s on colourful sticky notes to express their feedback about the event. 

MLH Local Hack Day 2019

We had a wonderful time collaborating with participants from different domains. Hacking, brainstorming, and innovating collectively at the Local Hack Day - Build! 

Jan 02 2020
Jan 02

A magnificent year has gone by! 2019 saw Drupal evolving by leaps and bounds. As the year comes to an end, here is a look at some of the significant moments from the Drupal world that happened during this time.

2019 written in orange amidst a black backdrop

18 years old: Drupal is no longer a kid!

It was on 15th January 2001 when the world saw Drupal burst onto the scene. Drupal 1.0.0 was released on this date. Since then, with the support from thousands of open source enthusiasts and contributors, it is today one of the market leaders in the CMS segment. Drupal turned 18 in 2019 and Drupal Community revelled in its success with much mirth.

Screengrab of a Drupal 2019 tweet with a name and image on top left and text below itDrupal Community members were surely excited

New Drupal releases

As per Drupal’s 6-month release cycle, the Drupal fraternity witnessed two new Drupal versions being released in 2019 - Drupal 8.7.0 and Drupal 8.8.0.

Drupal 8.7 was one step closer to a better future. It came packed with much-needed features, particularly the stable JSON:API core module and the stable Layout Builder module. With JSON:API support being included as a core feature, displaying your Drupal content in decoupled websites, mobile applications and others would be a downhill task.

[embedded content]

After being introduced as an experimental module in Drupal 8.5, the announcement of a stable and production-ready version of the Layout Builder module in Drupal 8.7 was huge news. Its provision for state-of-the-art content management solution with features like drag and drop management for content blocks and the quicker process of creating layout templates for content is a massive improvement.

[embedded content]

Drupal 8.8, that released on 4 December 2019, is the last normal feature release of Drupal 8. It came with a stable version of the Media Library module that was previously added as a beta experimental module in the core. Media Library streamlines the reuse of images, documents, videos and other assets across the website.

[embedded content]

Claro, a new experimental administration theme, was also introduced in Drupal 8.8. Its intuitive features like touch-friendly administration pages and more accessible colour combination and contrasts will definitely enthral website handlers.

[embedded content]

Drupal 8.8 also introduced a new experimental Help Topics module for further enhancement of in-Drupal help.

The Composer Initiative yielded great results as Drupal 8.8 became the first release that included native Composer support.

From the vantage point of businesses

With Drupal 9 set to be released in June 2020, the Drupal business leaders, as stated by Drupal Business Survey 2019, were eagerly looking forward to it. The survey revealed that the thought leaders from the Drupal circle had a lot of anticipations from Drupal 9.

Pie chart with different variations of blue colour in different regions to show Drupal Business Survey 2019(a)Pie chart with different blue coloured separations to show Drupal Business Survey 2019(b)

Source: Drupal.org

Majorly, these were the key results from the survey that showed what Drupal business leaders are excited about:

  • Streamlined upgrade path from Drupal 8 to Drupal 9
  • Ease of update. No large jumps on functionality changes when moving from one version to another
  • Better interface and improved user experience for developers as well as administrators, content editors and end-users.
  • The possibility of Drupal development becoming more simpler and a go-to option for not only the enterprises but also small and mid-size projects.
  • Drupal getting more powerful as an API-first CMS.

The survey did show that there are apprehensions about the migration from Drupal 7 to Drupal 8 or even from Drupal 7 to Drupal 9. It is perceived as a business-critical decision and the one that may be very intricate.

A clear picture: Drupal 9 upgrade

Infographics consisting of blue strip at centre and arrows on the left to show Drupal 2019 releases and future release pipeline

By the end of 2018 and in the entire 2019, Drupal Community began to see the clarity with the state of Drupal 7, Drupal 8 and Drupal 9. In DrupalCon Seattle 2019, the Driesnote presentation clarified that Drupal 7 will be fully supported by the community till November 2021 in addition to receiving security patches. From thereon, until at least November 2024, vendor support will continue.

It further stated that the Drupal 7 to Drupal 8 upgrade can be an uphill task for large sites in particular but nevertheless, once done, its advantages outranks the challenges.

Driesnote presentation in DrupalCon Amsterdam 2019 showed that the progress on Drupal 8’s Automated Updates Initiative has been spectacular last year.

[embedded content]

Symfony 3, which Drupal 8 is highly dependent upon, has an End-Of-Life date towards the end of 2021. That means Drupal 8 will be End-Of-Life by November 2021. Essentially, by the time Drupal 8 reaches End-Of-Life, every Drupal site should have upgraded to Drupal 9. Driesnote in DrupalCon Amsterdam also stated that the upgrade from Drupal 8 to Drupal 9 will be extremely easy. Consistently checking for and removing the use of deprecated code would make the migration from Drupal 8 to Drupal 9 a very simple one.

Rather than working on Drupal 9 in a separate codebase, it is being built in Drupal 8. Therefore, the new features and functionalities are being added as backwards-compatible code and experimental features. As the code attains stability, old functionalities will be deprecated.

Drupal project pipeline

Drupal adoption rate saw a palpable growth last year.

Graphical representation showing different lines forming regions to specify usage statistics of Drupal


Table with rows and columns showing usage statistics of DrupalSource: Drupal.org

When it comes to the experience that the business leaders had selling Drupal projects, according to Drupal Business Survey 2019, it has been fantastic. While the Drupal project pipeline has grown or remained at the same level, the average deal size has proliferated. Future of the Drupal project line is predicted to remain steady.

Pie chart with different blue coloured regions showing Drupal 2019 project pipelineSource: Drupal.org

When asked about the type of projects that the respondents completed in 2018 and the industries in which they implemented Drupal projects for providing ambitious digital experience, ‘Education’ turned out to be the most popular industry. Industries like ‘Travel and Tourism’, ‘Sports’, ‘Telecommunications’, and ‘Logistics and Support’ also witnessed an increase in the implementation of Drupal projects.


On examining Drupal.org’s contribution data in a 2018-2019 report, it was found that the number of contributors and contributions have increased to a great extent. There was an 8% rise in the number of Drupal.org projects that received contributions when compared to 2017-2018 period. More than half of the contributions were done on contributed modules. Interestingly, the big jump in non-product credits was discernible. This includes activities like organising different Drupal conferences, promoting Drupal, and community working groups.

Bar graph consisting of green and blue horizontal bars to represent Drupal contributionSource: Dries Buytaert's Blog

There was a noticeable increase in the number of contributions that the Drupal.org’s credit system received. The top 30 contributors (the top 0.4%) accounted for 19% of credits. (Our very own Drupal architect Gaurav Kapoor was amongst them.)

It was also found that most of the contributions were sponsored. Even though sponsored contributions remained on the higher side when compared to volunteer contributions, the latter is significant to Drupal’s growth and success as an open-source CMS.

Bar graph with green and blue horizontal bars to show Drupal contributionSource: Dries Buytaert's Blog

Drupal Business Survey 2019 shows that 111 out of 118 businesses contributed to Drupal. The survey delineated that the businesses have been contributing in multiple ways that ensure good health of Drupal. Whether it’s the contribution to modules, themes and distributions, or improvement of Drupal’s documentation, or sponsoring and organising events, businesses have been helping Drupal grow in their own ways. Some of the businesses, unable to contribute, cited lack of time and resources as the reason.

Bar graph comprising of blue horizontal bars to show statistics on Drupal contributionDifferent ways to contribute to Drupal | Source: Drupal.org

Decoupled approach

Since the time when Dries Buytaert, founder and project lead of Drupal, talked about RESTful Drupal and later about the future of Decoupled Drupal, this approach has evolved into something more exciting and attained new heights.

The two ways of decoupling Drupal include progressive decoupling and fully decoupling. But, as 2018 neared its end and 2019 began to unfurl, the fully decoupled approach branched into two methods. It was due to ever-increasing convolutions of JavaScript development that, in addition to existing fully decoupled application, it also took the form of a fully decoupled static site. The popularity of JAMstack and its reputation of rendering high performance, top-notch security and fewer complexities during the development gave wings to approach of building fully decoupled static sites.

Most importantly, API-first Initiative made great progress and strengthened Drupal’s capabilities as headless or decoupled solution. Not only has Drupal core started offering out-of-the-box JSON:API implementation with JSON:API module landing in core since the launch of Drupal 8.7, but several new improvements to JSON:API support in the contributed space were seen. (For instance, an interactive query builder called JSON:API Explorer.)

[embedded content]

Diversity and inclusion

Although Drupal’s contributors were found to have become more diverse in Drupal.org’s contribution data studied between 2018-2019, more effort needs to be put in to fill the gaps.

For instance, in this report, some interesting facts emerged when gender diversity and geographical diversity of Drupal.org contributors were studied. Even though the contributions made by persons who do not identify as male increased by one percent in 2018-2019 period, the gender imbalance in Drupal is still a worry. Non-male contributors accounted for only 8%.

Three bar graphs consisting of vertical bars of blue and green colours showing statistics on Drupal diversity and inclusionSource: Dries Buytaert's Blog

When it comes to geographical diversity, Europe and North America continued to dominate the contributions space. While the United States topped among the countries, India remained the second-largest contributor. Overall, the contributions from Asia were on the decline (particularly India in spite of it being the second-largest contributor).

Drupal Community understands the need to foster diversity and inclusion. Several efforts have been taken in 2019 to show its strong will to diversify its community and be more inclusive.

Drupal Association, like in 2018, changed its logo to show its support for LGBTQ+ community for the whole month of June (Pride Month).

Drupal logo, resembling a droplet, in Rainbow colour on left and 'Drupal Association' written on left

Listening to a more diverse group of people can be an inspiration to new contributors from all gender identities, races, religious groups, geographies, ethnicities and more. There were significant efforts made to help more people from underrepresented groups speak at Drupal conferences and workshops. For instance, Drupal Diversity and Inclusion group hosted a speaker diversity training workshop in September.

In their resolve to diversify the leadership group, Drupal Association decided to elevate a diverse group of leaders. The nominations for community elected board position were open for all.

Climate change

It was also the year when a teenager took the world by storm. An unlikely teenager somehow got the world’s attention. Greta Thunberg inspired millions of people to join the global climate strike in September which turned out to be the largest climate demonstration in human history.

On top of green background, 'Digital climate strike' written on left and a text supporting it on right

Drupal.org, along with thousands of websites across the globe, posted a banner message declaring that it has opted for a global digital climate strike.

End thoughts

2019 proved to be remarkable for Drupal. It reached new avenues. It kept getting bigger. It realised where it lacked and showed strong resolve to improve.

Drupal 8 isn’t done yet. It’s gonna be here for a while and will continue to offer enriching digital experiences all over the world. But, eventually, Drupal 9 will take over. It’s going to be released in a few months from now and Drupal Community is very excited to welcome it. A lot of interesting things are lined up for Drupal in 2020 and it will be amazing to see them all happening.

Happy New Year to all the Drupalists! Grow Drupal, grow with Drupal.

Jan 02 2020
Jan 02

Recent travel to Rwanda has brought me to build a POC (Proof-of-Concept) with a familiar stack, only in a very different structure.

To better understand why the POC was built that way, I should give you the backstory.

The Backstory

In 2016, I was invited to present about Drupal & Elm in DrupalCamp Tokyo. I always like to bring this fact up in any kind of conversation - but this time there’s even a reason beyond my usual bragging rights: The flight is terribly long from Israel to Tokyo. Twenty-four hours door-to-door kind of long.

As it so happened, a short time before my flight, Adam, Gizra US Director had virtually dropped a PDF on my table. I was preparing myself for yet another long RFP (Request for proposal) with an impossible spec, and an even less possible timeline. I was surprised to see that was not the case. That PDF was forty-something pages, with a wireframe per page and some notes, showing the flow of a rather interesting app.

Wireframe from the spec

Three years later I still refer to those pages as the best spec we’ve ever received. The people behind those wireframes were Dr. Wendy Leonard and her Ihangane team. They were planning an electronic medical record for an HIV prevention program in Rwanda.

I was really impressed. Sure, the wireframes were rougher than usual, but they did exactly what they were supposed to. The team was smart enough to not rush into development and in fact, they even printed out the spec pages, went to the field, sat with nurses, and let them click on the screens. The printed screens. They clicked on paper!

Anyway, did I ever mention I was invited to Tokyo in 2016?

That long 24 hours flight. I’ve finished my book (“Ancillary Justice”), watched a movie (“Wreck-It Ralph”, as for some reason I love watching cartoons on planes), and there were still many hours before my arrival. So I took my laptop out, spun up a Drupal backend and an Elm frontend - and the first POC for Ihangane’s app called “E-Heza” was born in the sky.

The Good Ol’ Days

And so began the development. A decoupled architecture, where we had a RESTful server in the backend and Elm in the front. Like any project we had: different challenges, deadlines, deadlines we missed, scope creep, managing the project, managing the client, managing expectations, delivering, hot fixing, being proud of what we’ve accomplished, having a technical debt. Rinse and repeat.

While we were developing, the Ihangane team was hard at work implementing our work in the field. In fact, they were able to get it going in a dozen health centers in Rwanda. And while it worked for the most part, there was one challenge we knew was lurking, and waiting - Offline.

Have you ever worked with non profits, or NGOs, and they tell you they have a need for a site, and some of its users are in developing countries where infrastructure isn’t always good, internet is slow, and so we must take care of a light theme and shave every single byte possible, but then in the design they insist on hero banners with huge images, and every possible JS transition?

Well, we have. But that was not such a case. This time it was for real - all health centers had internet, but it was not rare for them to have the connections dropped for days on end. And so, we decided it was time to implement a proper offline support. The reason I say “proper” Is that we actually had offline support from the get go, but it was a very crude one. Only after the nurses checked all the patients, and a “session” was done, did the nurses manually start a sync process. But that wasn’t very nice, and we decided to go with “opportunistic syncing” - where data was pushed and pulled whenever an internet connection was available.

Offline & Service Workers

I’m going to side step, and go technical here: Getting offline support was admittedly a bit easier than I had feared. It is surely the most complicated part of the system, but we were able to keep it confined to the edges of the front-end application.

Elm, in all its greatness, already taught us to think about interacting with JS the same way we would with a remote server. So, instead of having Elm contact directly the remote server, we’ve placed a service worker as a middleware.

That meant that Elm keeps using HTTP requests, the same way it always did, but now we intercept those requests, and the service worker decides - are we online, then call the server and sync the data; Or are we offline, and we should use the data from IndexDB. To make the wiring of the offline part to Elm even less disruptive, we’ve structured our responses from the service worker to be similar to the ones we used to get from the server. In other words, the change was minimal, and it looks beautiful.

But still, as one can imagine, adding this layer brings a new set of challenges. Our app isn’t a news reader, where the worst case scenario is you cannot read your news. No, our app is all around creating new content, and the worst-case scenario for us is losing patient data.

The Rwanda Visit

Back to the main narrative. I was invited to attend a workshop that Ihangane had organized in Rwanda (you know, like that one time I was invited to Tokyo in 2016). It was a two-day workshop where different stakeholders came, and had discussions not only around Ihangane’s solutions but also in general - how to improve the health care in Rwanda.

Some parts were boring - the usual amount of suits talking about things they don’t necessarily know much about. But there was one topic that I found especially interesting: The Government of Rwanda is spearheading a “Health Cloud” effort. This project is a huge undertaking. To give just one example of the many challenges involved - currently in Rwanda when a baby is born, they don’t always get a national ID. In other words, there’s no unique identifier for every person - so the challenges are somewhat larger than just which best methods to use to create this platform.

But what really caught my attention, is how dedicated they were to make sure no vendor locking will happen under their supervising eye. I really appreciated it. I can only imagine how many private, for-profit organizations are trying to get their foot in the door in those emerging markets. I’m not saying all for-profit organizations are evil, I’m just not naive.

Rural Rwanda

I love saying “Rural Rwanda.” With my Israeli accent, it’s a real tongue twister for me. I also loved having a one day visit in the outskirts of Kigali, visiting nurses in Muhondo health center and see our system in action.

Spent a whole day in rural Rwanda, watching - in action - an @elmlang web-app with a #Drupal backend we've built for @ihanganeproject.

No marketing landing pages, no sale funnels, no targeted ads. Just a web-app that helps provide a better health care to mothers and their babies pic.twitter.com/PnLqV0vpSQ

— Amitai Burstein (@amitaibu) November 14, 2019

Make sure your speakers are on. That’s what I call true “stress testing” - when you have a room with about a hundred mothers and their (cute, yet screaming) babies, every extra second the app takes, is another second people are waiting.

What a great day it was for us - watching with our own eyes, seeing the good parts of the app, finding a couple of bugs, but mainly spotting workflows that could be improved, and benefit the team operating it, as well as the patients. When you see these women that have walked for hours with their babies on their backs to reach the health center, “try to refresh the page” or “let’s wait a couple minutes for the system to fully sync” is becoming less acceptable. I was very proud to see how we were able to be part of a thing that really does good to much less fortunate people.

Letting it All Sink In

  • We have mothers with HIV or high risk for HIV.
  • We have their babies, that need to be examined, and be checked for different signs of malnutrition.
  • We have no internet connection in some areas.
  • We need to support Android devices, as the measurements taken in the field are being registered in those devices.
  • We have this “Health Cloud” idea, that we want to help think about. We don’t want to follow a typical enterprise kind of thinking, but rather use our own more radical one.

At the same time of my visit to Rwanda I have started my affair with Plain text accounting with hledger. I think this quote sums it up nicely:

Accounting data is valuable; we want to know that it will be accessible for ever - even without software. We want to know when it changes, and revision-control it. We want to search and manipulate it efficiently.

It took my brain about a month to switch the word “Accounting” with “Medical”, as in:

Medical data is valuable; we want to know that it will be accessible for ever …

Then another thing happened. Did I ever tell you about my invitation to DrupalCamp Tokyo in 2016? Well, while I was in Rwanda I was invited to DrupalCamp Tokyo 2019.

Once again I was in a plane, finished my book (“The Sudden Appearance of Hope”), watched a movie (“Aladdin”, because cartoons are for kids!), and still had many hours ahead of me. Up in the sky, and for the sake of a good story I’d like to believe it was in the exact same spot the first POC was conceived, a new one started to form.

Same Ingredients, Different Mix

What if we didn’t have a DB, and stored medical records in plain text, the same as we’ve been doing with our accounting data?

What if Git, faithful and efficient Git, was taking care of syncing and working offline?

What if we’ve used Termux - to have a terminal on Android devices, and thus open the door to running a server locally on each device?

I felt those questions required me to answer them. The result is in this repo and the most important part about it, is the data. All the information we have is stored in YAML files. For example, here’s how we define the information of a mother, and the relation to her children:

id: 000f8e43-d638-49fa-8c9a-3429bb819f21
first_name: Aurelia
last_name: Sherlyn
    - ad1bce42-69c7-4d55-82e1-129fb4b91e87
    - b16df0be-ad66-4901-b7a1-2aa720c9968e
    - 0c9a59e4-dd51-40d6-8978-157fc9b65909

That’s it really. Thank you for reading, bye bye.

No, seriously, there’s some more on how we have some software to help view and manipulate the data (which is what you are probably interested in), but I think that having the data in a human readable format (as opposed to be inside DB tables) is the biggest thing in this POC.

Think about how you build a feature in a traditional website:

  1. The client has a feature idea.
  2. You sketch out some wireframes, the client approves them, and they will be out of the loop until section (6).
  3. You do a technical design.
  4. You add a table in your DB.
  5. You write some front end code.
  6. You deploy to TEST - and there the client sees the outcome for the first time.

But with plain text medical records, the “client” can write for themselves how the result of measurements should look. Any kind of conversation would be around that piece of data. Even if there’s no software on top of it, you know what the measurements are just by reading it.

version: 1
group_meeting: 2020-01-30-morning
# We have a single config file in the root, that has the measurements' units.
height: 125
weight: 12
# Mid-Upper Arm Circumference, known as MUAC.
muac: 30

For me, that’s the biggest win. In fact, maybe that’s the “no vendor lock-in” solution for Health Cloud, we can start building on top!

The Disposable Software

I wanted to build the local server in Haskell, but it seemed that to get it running on Termux it was more complicated than a simple pkg install php. So I decided to go with Symfony, and it was indeed a good decision. Setting everything up worked nicely, with a lot of copy & paste from the docs that are great. I’d say that only the Normalizer package (the equivalent of encoders/ decoders in Elm and Haskell) wasn’t fun to work with. Maybe because I’m so used to the guarantees of Elm and Haskell, working with a non-typed language felt less reliable.

Since PHP has its own web server, all we have to do is spin up the web server, and then use the browser to connect to that local server. The server is not meant for production, but in our case we have only a single client, so it actually works great. We can view data, we can add or change data, and we can even upload images directly from the device.

Adding measurements via Browser

Looking at the Git diff, we’d see the commit that resulted with submitting the form.

version: 1
group_meeting: 2020-01-30-morning
- height: 125
+ height: 130
weight: 12

I also wanted to show how the fact that we have the app in PHP doesn’t mean we are tightly coupled with it. We only care about the data, and that one is language agnostic. So I came up with a tiny Haskell utility, that you can give it a path to the data in another folder, and it will create 100 fake mothers and children, so we could test the app with more data.

Furthermore, since we’ve changed the structure of the stack, and we no longer need to think about a server as an entry point to get or manipulate data, the next thing I did was to create a console command to show a listing of mothers participating in a single group meeting. Below we can see the fake date we’ve created with the Haskell utility.

A list of mothers shown in the terminal

Final Thoughts

I think the biggest accomplishment here is stepping outside of the usual stack structure, and recognizing the unique situation that we are facing. This structure isn’t going to be right for a majority of the cases, but I’d argue that there are a good portion of problems that could be sovled with such a stack. Obviously it’s not a panacea, and it brings different problems; on the other hand, I find it solves some existing ones quite nicely.

In terms of syncing and access control - that’s baked deep inside Git, not to mention that having it as distributed, version controlled, and (sorry for the buzzword) “blockchain”-ed has many merits. In terms of security of running a local PHP server - since it’s running locally, and it’s not open to the outside world, it’s nothing more than a nicer interface to editing files. But obviously, by using Symfony and applying best practices - we make sure we write secure code.

I don’t know what’s next for this POC, as it’s not only for me to decide. But I do hope we’d get a chance to move forward some more with it, to reach a point where we can test it out in the field. If one day a nurse in a tiny room with many crying babies will tell me it improves her day to day work - that would be well worth it.

Jan 01 2020
Jan 01

The Problem

Replacing files uploaded to your Drupal site can be very frustrating. In most cases, when an editor wants to replace a document, they want to keep the exact same filename and filepath and just overwrite the contents of the file. This is important in cases where the file is linked to elsewhere throughout the website or on other websites outside of the editors control. If you use the media module to manage documents on your site, you'll quickly discover that it's not possible to upload a replacement file for a document and keep the same filename.

Why is this? The core file field allows you to remove and upload a replacement file. But when you upload a replacement file with the same filename, Drupal appends a number to the end of it, like _0, _1, etc. This is because the old file is not actually removed from the filesystem immediately. Drupal will mark it as a temporary file and it will be removed during a cron run sometime in the future (* see exception to this below). Drupal won't overwrite that file with the new one, so it appends a number to the end to make it unique. Drupal also does this to support revisions properly. If the file field is attached to an entity that has revisions enabled, then Drupal keeps that old file around because previous revisions may require it.

* Actually, as of Drupal 8.4, old unused files are never deleted unless you have a specific config override set that enables this cleanup.

Existing Contrib Solutions

There is a 4 year old Drupal core issue where the community has tried to resolve this problem. Probably the most popular solution has been to use the Media Entity Download module. It works by creating a special route for each media entity that will directly return the file associated with that entity as a download. So if you had a document media entity with ID 59, editors can create links to /media/59/download and Drupal will serve the file directly from that path. This solves the problem because it hides the actual file system path from visitors. It doesn't matter what that path is or how many numbers Drupal has appended to the end of replacement files, the visitor never sees it and you'll never have broken links.

The main problem I have with Media Entity Download is that it gets Drupal involved in serving up the files which are normally not handled by Drupal at all. After all, the files are just sitting there in the public filesystem. The web server (apache, nginx) typically serves them to visitors and leaves Drupal out of it. With this module, every time a file is requested, Drupal is bootstrapped and a PHP process is tied up until the download completes to the visitor. This is a bit scary if you get a large surge of traffic with many users requesting large downloads.

The New Solution

I just completed work on the Media Entity File Replace module to provide another solution to this problem. This module is intended for site builders that are using the Media module to manage documents on their site. It works by adding a replacement file widget to the media edit form for media types that use a file source (Image, Document, etc). You can control which specific media types it's enabled for by visiting the form display configuration and showing/hiding it. When replacement files are selected and the form is saved, the file is first uploaded to temporary storage and then copied over the existing file. The filepath and filename are kept in tact. Just the contents of the file and the metadata describing the file are updated - which is what editors want most of the time.

Edit form for a document media entity showing the &quot;replace file&quot; form widget

Note that the module still supports the previous behavior of NOT overwriting the original file. Editors just need to uncheck the "Keep original filename" checkbox and the replacement file will be uploaded and the media entity updated to reference it.

This module should fill a functionality gap in document management in Drupal - I hope others find it useful!

Dec 31 2019
Dec 31

In 2018, The Open Source Initiative celebrated its 20th Anniversary, a milestone and a huge success for the global non-profit dedicated to raising awareness and adoption of open source software. Since its inception, the open source movement has gained tremendous momentum in corporate computing. In the recent years, open source has entered the government sphere as well.

One such popular open-source platform is Drupal. Developed by Dries Buytaert in 2001, Drupal became a sensation when it was used to build a network for the Democratic primary campaign of Howard Dean in 2003. Since then, Drupal has come a long way and now more than 100 countries use Drupal for their government websites.

Steve Nichols, CTO of Georgia Technology Authority, which runs more than 65 state government websites, recently talked about how shifting to a Drupal platform helped him manage the government websites in a better way. Earlier, these government websites were running on two different versions of proprietary software - Vignette 6 and Vignette 7. But as the functionalities increased, it became very cumbersome and expensive. Soon they started looking out for other options, and all the evident choices pointed to open source CMS, and the most obvious and the strongest among all the contenders was Drupal.

When they dug a little deeper, they found out that many key federal government sites were being powered by Drupal, and that is when they decided upon to narrow down on the Drupal CMS.

So why exactly do these government websites opt for a Drupal CMS among the plethora of options? Why is the most obvious choice Drupal? Let us know a bit more about what makes Drupal so special!

Drupal's Market Share

In the present world, with more than 150 federal government sites running on Drupal platform, it is kind of obvious that the Drupal CMS has an enormous market share when it comes to the government websites and the public sector in general.

Nasa Website build with drupal cms

The list contains big guns like NASA, Department of Health, Department of Education, Transportation, Defense and Homeland Security. When Drupal platform is being preferred by some of these big government sites, it is not surprising to see that many other private and media companies are inclining towards Drupal CMS for their own websites.

Drupal's Adaptability Features

A few years back, the energy department's website, energy.gov got into a lot of trouble. The website faced low traffic, high bounce rate, and to make it worse, the entire website was built on the basis of an internal office structure which made it quite impossible to navigate. It needed immediate attention, and that is when the organization decided to migrate their website to Drupal.

One of the greatest strengths of the Drupal CMS is its ability to integrate with any other solutions and services. Even a proprietary CMS such as Sharepoint, is likely to coexist with Drupal and other open source platforms. The modular system that a Drupal CMS works on, allows it to adjust easily based on the type of deployments.


While the typical stereotypes about open-source platforms is that they are quite vulnerable to threats, Drupal has a track-record of being one of the most secure open-source CMS. Well-equipped to handle cyberthreats, the Drupal community does a great job to work together and ensure that they eliminate any threats before they affect the users.

Drupal consists of several security modules, making it one of the most reliable platforms amongst several others. Some of these modules include, Login Security, Password Policy, Captcha, Security Kit etc.

Multisites - An Easy Task

Governments tend to have multiple websites, in multiple languages in order to handle various sections of their administration. Irrespective of whether the government has just a couple of websites or few hundreds, the task of building each one of them individually and maintaining them is going to be a tough job.

Drupal CMS makes it easier with its multisite feature, allowing the developers to copy the site's code base and create as many new websites as required. Thus, by leveraging the features and functionalities of an already existing website, the need to build every single site from scratch, is eliminated.

Additionally, Drupal also offers out of the box Content and Entity Translator modules which help content authors to translate pages, individual fields, elements and more. Thus, multiple sites in multiple languages is an easy feat with Drupal CMS.

Say Hello To DeGov

DeGov is the first of its kind Drupal 8 open source distribution that focuses on the needs of government organizations only! DeGov offers a comprehensive set of customized functionalities which are commonly used only for those applications that are necessary for government websites.

With the ability to release federal and state portals, internet sites for ministries, authorities, municipalities and more, DeGov distribution allows web pages and group-specific portals to be created easily, without any hassle.
Learn more about DeGov here.

Dec 31 2019
Dec 31

As APIGEE end of support for Drupal 7 in May 2020 is combined with Drupal 7 end of life in Nov 2021, developer portal are not left with many choices - migrate to Drupal 8 or continue with Apigee’s integrated portals. 

For a custom Drupal 7 developer portal, migrating to Drupal 8 comes as a natural choice. In this blog we will understand why it is so important and what should be on your checklist while migrating to Drupal 8.

Benefits of Migrating Your Developer Portal to Drupal 8 

With continued effort of the Drupal community for its long-term sustainability and more effortless adoption, complete re-architecturing of Drupal 8 has made it different from the previous migrations. There are many ways why Drupal 7 can put your developer portal at risk

Drupal 8 with its performance-enhancing features and modules can turn your developer portal into a speedy and high performing one. Let’s look at what makes Drupal 8 the best version to be on:

  • Drupal 8’s adoption of Symfony framework has made it all the more better. Symfony’s robust, flexible and high-performance framework allows for easy scalability of a website.
  • BigPipe Caching lets you segregate your page into different sections which gets rendered as they become available, enhancing website’s performance and speed.

Source: specbee

  • Drupal 8 is PHP7 ready, which is twice as fast as PHP 5.6. It is capable of enhancing the performance of your developer portal to about 110%, with reduced memory usage.
  • Talking about Drupal 8 themes, they are responsive, making your developer portal look great on almost any device. 
  • Drupal 8 is equipped with CKEditor, which lets you preview your entered content quickly as well as an in-place editor that lets you edit blocks, content, menus, etc. right on the same page.
  • SEO will not be a concern anymore. Drupal 8’s built-in powerful SEO modules, like SEO Checklist, PathAuto, Redirect, and MetaTag can help boost your developer portal’s SEO. 
  • Not to forget about Drupal 8’s out-of-the-box multilingual support, which can help boost language-based views of your developer portal.

Planning Your Migration - Your To Do Checklist

It is important to follow the best approach for the migration process. Having spent too much time on building the right content for your developer portal, you would not want to drop your stats without a proper plan. Content migration becomes a significant decision for your business. 

When you think of developer portal migration to Drupal 8, you need to look into enhancements to the front-end features such as smartDocs API reference documentation, theme editor enhancements, default portal theme and content enhancements, quick start and how developer accounts are managed using the developer identity service.

To ease the process of migration, maximum time should be spent on planning. If properly administered, this will further bring down the number of hours spent on the actual migration. Though content migration is a tedious task, however, strategizing it well in advance will make the developers smoothly execute the process.

One would need one of these two steps to migrate their developer portal to Drupal 8:


  1. For minimal custom implementations on Drupal 7 portal, have Apigee Developer Portal Kickstart ready to migrate Drupal 7’s configuration and content.
  2. Follow custom migration approach for heavy customizations of Drupal 7 portal. For this, Apigee Edge module can help in connecting Drupal 8 Portal to Apigee and use Drupal 8 Migration API to migrate the Drupal 7 implementations to Drupal 8 Portal.


Now, let’s take a look at the pointers to consider before migration:


  • Take Backup

It is always a good practice to take a backup of your entire website before starting with the migration process. This can be done with the help of Backup and Migrate module to create a database dump to save all your Drupal database tables into a single file download, to be later used for restoring at a later stage. 

Enabling Backup and Migrate Module

  1. Navigate to Administer > Modules
  2. Select Backup and Migrate in the Other block
  3. Scroll to the bottom of the page and click Save Configuration

Configuring Backup and Migrate Module

  1. Navigate to Administer > Configuration > System > Backup and Migrate
  2. Download a backup of the default (Drupal) database by clicking Backup now. 

It is recommended to download a backup prior to updating or installing modules.

Backup to Server

Create a private directory to store backups on the server by following the below 3 steps:

  1. Navigate to Administer > Configuration > Media > File System
  2. In the Private file system path field enter sites/default/files/private
  3. Click Save configuration


  • Quick Roundup of Functionality and Content Check

Having a quick yet thorough check of the website for the entire set of features and functionalities of your developer portal will give you an idea of moving on from irrelevant ones. Do check if you want to drop off with any content or content types post analyzing them. This is the time when the need for new content types arises.

Like content types, it is important to figure out which of these fields should be migrated. You should check which of the fields are important in your existing site and which of them are no longer relevant for the new site. Examine the number of users logging in, reviews, ratings, views and other taxonomy terms too.

In this way, you get a chance to completely revamp the architecture of your website.

  • Move Content Securely

Migrating web content is an integral business decision where you must take precautions to avoid any security breach or data theft. Ensuring your database and development infrastructure is up-to-date with the latest upgrade, wiping out all your data including user accounts from database infrastructure and not sending database dump via unsafe channels are few things which need to be kept in mind.

  • Prepare a Backup Plan for Theme Mismatch

Up until Drupal 7, PHPTemplate has been the default Drupal Theme engine. But Drupal 8 uses Twigs (part of Symfony2 framework) to render pages in a highly flexible and secure way. It won’t allow your existing (D7) theme to port directly to D8. Note that no single module can move your existing theme to Drupal 8.

Upon migrating the developer portal, custom CSS styles will be overwritten. So the new default theme needs to be applied along with custom CSS styles manually post migration.

  • Search Modules upon Migration

Drupal 7 core modules and many contributed modules are now available in Drupal 8 core. While most of them are automatically upgraded, a few modules will need manual upgrade as they are not mapped to the same Drupal 8 module or are now segregated into different modules. 

Due to Drupal 8’s revamped architecture, if you’re unable to find a particular contributed module in Drupal 8, you can:

  • Simply archive the module’s data, or
  • Find a similar community module sharing common functionality, or
  • Hire a developer and get a custom module built with the required functionality

However, when it comes to custom modules, you need to port them in Drupal 8. You can hire Drupal developers who can help you with porting the modules.


All you need to do the following things before migrating the developer portal to Drupal 8: 


  1. Prepare the Migration script for Drupal 8 considering the number of developers on Drupal 7 portal, capturing all the custom field data attached to a user entity. Do a parity check on Drupal 7 portal users with the new Drupal 8 portal and list all the extra fields needed to be created on the new portal. Migration script should execute avoiding the API call to Apigee to update a developer.
  2. Sync Developer apps and developer API products with Drupal 8 via Apigee Contributed module. If there are any custom attributes attached to app or API products as dependent, this should be processed via custom migration script.
  3. Migrate Open API spec’s documentation content on developer portal to Drupal 8 Portal via Drupal 8’s Apigee Catalog module or DevPortal Module. Migration script should write the documentation pages to new Drupal 8 portal, based on the option chosen to present doc’s on Drupal 8 Portal.
  4. Migrate any other monetization related configuration (triggering get or post data to Apigee) to Drupal 8 via custom migration script. 
  5. Implement customization done on contributed Apigee Devconnect module newly on Drupal 8 Portal and the data related to this implementation should be processed via migration script.

Wrapping it up

Migrating your developer portal to the latest version is a difficult decision to make. However, it proves to be a brilliant decision once you get a secure, accessible, modern, and responsive website, which suits your needs and stays compatible with updates for years.

For a successful migration that keeps in mind all these steps, you'll need to work with experienced developers. Our team of experts can help you in migrating your developer portal to Drupal 8 to future proof your digital presence, solve your queries around API security and provide a range of services around API designed with a strategy tailored to your success. Contact us today.

Dec 26 2019
Dec 26
Drupal Commerce 2.16: cart expiration, exact promotion time & more!

E-commerce opportunities are endless nowadays. More and more business owners decide to hire e-commerce developers and skim the cream off online sales. Today, we will describe the new opportunities offered by Drupal Commerce 2.16.

Read more
Dec 26 2019
Dec 26

Drupal 8 has lot of inbuilt functionality within it, one of the main important features is Configuration Synchronization. It will help us to migrate full setup properly on site deployment. But the main problem is that, According to the Drupal 8 CMI documentation,

The Configuration Manager module in Drupal 8 provides a user interface for importing and exporting configuration changes between a Drupal installation in different environments, such as Development, Staging and Production, so you can make and verify your changes with a comfortable distance from your live environment.

The same idea appears in this article,

Perhaps the most important concept to understand is that the configuration system is designed to optimize the process of moving configuration between instances of the same site. It is not intended to allow exporting the configuration from one site to another. In order to move configuration data, the site and import files must have matching values for UUID in the system.site configuration item. In other words, additional environments should initially be set up as clones of the site. We did not, for instance, hope to facilitate exporting configuration from whitehouse.gov and importing it into harvard.edu.

So Still we hardly depends on the Features module, But we can use the CMI (Configuration management Interface between two different sites with simple hacking solution.

The CMI works with based on the site UUID, If the sites have different UUID then, it won’t work, So changing destination site’s UUID with Source site’s UUID would solve the problem.

Just follow the below steps to use CMI between two different sites,

1. Export Configuration from your source site (Site A)

2. Extract the file, Open the system.site.yml file and get the Source site (Site A) UUID

3. Run the drush command in your destination site (Site B)

drush config-set "system.site" uuid "Your Source Site UUID here"

4. After that, try as usual Import Process in destination site (Site B)

It will accept the Site A configuration in Site B. So we can migrate all datas into our another site.

FYI : I am not sure, It is a effective / Proper way to do it.. If there is any problem with this method please mentioned in the comment.

Dec 26 2019
Dec 26

In such a time, i want to place blocks in sidebar region with the dynamic weight. It means the blocks should render in different position for each page request. I have searched and tried lots of method but unfortunately i can’t find proper method to do that. So i have decided to do that with some hacky way.

Drupal 8 is providing a hook to alter the region template_preprocess_region, it would prepares values to the theme_region. I have planned to use the hook to alter the block's position to be rendered in the region.

Adding the following codes in THEMENAME.theme file would solve the problems,

function themename_preprocess_region(&$variables) {
  if ($variables['region'] == 'sidebar_second') {
    $variables['elements'] = shuffle_assoc($variables['elements']);
    $content = '';
    foreach ($variables['elements'] as $key => $value) {
      if (is_array($variables['elements'][$key])) {
        $content .= \Drupal::service ('renderer')->render($value);
    $variables['content'] = array(
      '#markup' => $content,

function shuffle_assoc($list) {
  if (!is_array($list)) {
    return $list;

  $keys = array_keys($list);
  $random = array();
  foreach ($keys as $key) {
    $random[$key] = $list[$key];
  return $random;

It is working well in my site but i know it is the hacky way, not sure about the proper way to do that. If anyone of you know about this kindly share it in the comments :)

Dec 26 2019
Dec 26

Twig can be extended in many ways; you can add extra tags, filters, tests, operators, global variables, and functions. You can even extend the parser itself with node visitors. In this blog,

I am going to show you how to create new custom twig filters in drupal. For example we are going to create a filter to remove numbers from string, will explain with hello_world module.

Create hello_world folder in modules/custom/ folder with the following files,

1. hello_world.info.yml // It would contains normal module .info.yml file values, Check here for more details

2. hello_world.services.yml // It would contain following lines,

    arguments: ['@renderer']
    class: Drupal\hello_world\TwigExtension\RemoveNumbers
      - { name: twig.extension }

3. src/TwigExtension/RemoveNumbers.php It would contain followings in that,

namespace Drupal\hello_world\TwigExtension;

class RemoveNumbers extends \Twig_Extension {    

   * Generates a list of all Twig filters that this extension defines.
  public function getFilters() {
    return [
      new \Twig_SimpleFilter('removenum', array($this, 'removeNumbers')),

   * Gets a unique identifier for this Twig extension.
  public function getName() {
    return 'hello_world.twig_extension';

   * Replaces all numbers from the string.
  public static function removeNumbers($string) {
    return preg_replace('#[0-9]*#', '', $string);


Enable the hello_world module and clear the cache, then you could use the “ removenum “ filters in your twig file,

{{ twig-value-with-numbers | removenum }}

It would remove the all numbers from the string, enjoy with your custom filters !

Download the hello_world module here

Dec 26 2019
Dec 26

One of the most favourite and  valuable features in drupal is multisite configuration, Drupal 8 provide simple way to create multisite it reduced lots of works. The following steps shows to configure multisite in drupal 8,

  • Should have more than one domain and databases, I am going to use the domain (www.domain1.com, www.domain2.com) and databases (domain1, domain2).
  • Create two folders in drupal-8/sites/ folder with domain1, domain2 name, the folder path would be like this drupal-8/sites/domain1/ and drupal-8/sites/domain2/
  • Create files/ folder in both the folder (drupal-8/sites/domain1/files)
  • Copy the default.settings.php file and paste it into the both folder then rename it as settings.php ( drupal-8/sites/domain1/settings.php, drupal-8/sites/domain1/settings.php)
  • Edit the settings.php file for domain1 to adding the database,
$databases['default']['default'] = array (
  'database' => 'domain1', // Change value to domain1 for www.domain.com and domain2 for www.domain2.com.
  'username' => 'root',
  'password' => 'root',
  'prefix' => '',
  'host' => 'localhost',
  'port' => '3306',
  'namespace' => 'Drupal\\Core\\Database\\Driver\\mysql',
  'driver' => 'mysql',
  • Copy the drupal-8/sites/example.sites.php file and paste in on the same location then change the file name to sites.php (drupal-8/sites/sites.php)
  • Add the following line in the bottom of the drupal-8/sites/sites.php file
$sites = array(
 'domain1' => 'domain1.com', // Folder name => Domain name.
 'domain2' => 'domain2.com',

Thats all, both domain would works well with the different db with a single instance.

Dec 26 2019
Dec 26

I needed a way to check the currect user has permission to view the currect/particular page, Searched lot finally got the exact way, going to show the tricks to you in this blog.

Drupal has an api called " drupal_valid_path " , Normally it used to test the url is valid or not. but the trick is that, It also check the user has permission to view the currect/particular page.

It will return TRUE If path is valid and user has permission to view the page, otherwise it will return FALSE,

For example,

$path = current_path();
if (drupal_valid_path($path)) {
  // Your code here.
Dec 26 2019
Dec 26

Most of the times developers don't like the GUI, It makes feel lazy. Drupal has a tool (Drush) to do some management work from command line.

And also the installing the drupal site makes very lazy while doing with browser, The Drush has an option to install the full site with a single command.

The Following command will install the drupal in standard method,

drush site-install standard --account-name=admin --account-pass=[useruser_pass] --db-url=mysql://[db_user]:[db_pass]@localhost/[db_name]
Dec 24 2019
Dec 24

Remember how 2015 was filled with anticipation in the run up to the release of Drupal 8? Well, 2020 is all set to be a repeat of that - the same rush, excitement, innovative work will be happening around Drupal 9. But that’s not the only thing to look forward to for Drupalers in 2020.

From charting new growth paths, to ensuring an enhanced experience and easier adoption of Drupal for beginners, to creating closer integration with other technology frameworks - 2020 has a lot in store for Drupal. And here are the ones we are most excited about.

Drupal 9

Well that’s an obvious one and will definitely be at the top of the list everyone in the Drupal community. 

Drupal 9 is all set to release on 3 June 2020. The big deal with Drupal 9 is that it shouldn’t be a big deal. And that thinking is exactly what is new.

That’s because Drupal 9 is not being built on a new core, but rather within Drupal 8. Here’s how:

  • New features and functionalities will be added to D8 as backward-compatible code. These will start being available to D8 users as experimental features, that can be used and modified. All this while, older D8 features will work without a hitch.
  • Once these new features are stable, their older counterparts will be deprecated. 
  • And finally, 3rd party dependencies, like those with Symfony and Twig, will be updated to offer support for their latest versions.

This collection of new stable features and updated 3rd party dependencies will be what forms Drupal 9.

Drupal-9 - Drupal in 2020We’ve already covered what to expect with Drupal 9 and how to prepare for it and ensure a smooth upgrade experience.

So let’s move on to the other interesting developments slated for 2020.

Drupal 9 Product Tracks

The launch of Drupal 9 is also significant because this is the first time the community has a strategic roadmap for how we want Drupal 9 to grow. Dries’ State of Drupal address in Drupal Amsterdam outlined the four product tracks envisioned for D9:

  • Reduce the cost and effort involved in managing a Drupal 9 website. So the focus will be on introducing new features and functionalities that simplify website support, maintenance and updates - configuration management, automated updates and more.
  • Enhance the beginners’ experience with Drupal by making it simpler to install and get it running out of the box. The first two initiatives in this track are two new themes - Olivero for the frontend and Claro for admins.
  • Work towards ensuring an Open Web that’s accessible, secure, inclusive and interoperable. In the next decade, the Drupal community will collectively ensure that their work - project, websites, solutions - consistently meet these standards
  • Prepare Drupal to be one of the best structured data and content repositories, ready to work seamlessly with a range of devices and delivery channels

2020 will see these product tracks being actively discussed within the community and work starting on several new initiatives.

Drupal 8.8

Drupal 8.8 was released on 4 December 2019 and sites on Drupal 8 can look forward to harnessing great new features and functionalities in 2020. Some of the key upgrades are:

  • Media Library being marked as stable, so content writers and editors can add media content right from the WYSIWYG editor
  • Official support for Composer out-of-the-box, meaning Drupal is simple and easy to install and update with Composer taking care of updating all third-party dependencies
  • The Automatic Update module is available in early alpha stage and has a set of very convenient features. It allows you to configure your site to display PSA messages for required updates or mail them directly to the site admins. You can check if your site is ready for update, with all requisite file permissions, and update your site with just a click, if all prerequisites are in place.
  • The JSON:API Explorer which is an interactive query builder to explore your JSON:API server, strengthening Drupal’s positioning as an effective decoupled solution.

Decoupled Drupal

Yes, Decoupled Drupal has been talked about for quite a few years now, but 2020 and the following decade will be when it becomes extremely commonplace. This will be primarily due to the growth of a complete ecosystem of features and solutions that make it easier to pull off decoupled Drupal solutions. 

While the API-first initiative and the project around building a reusable component library are key to great decoupled Drupal implementations, there are also third-party frameworks and solutions launched in 2019 that will drive decoupled Drupal in 2020:

  • Acquia Content Cloud: A platform that allows content creators to write, edit, and review content independent of the channel where it will be published. The content created here can be pushed to multiple different channels simultaneously or at different times, and will be automatically formatted to best fit the channel. 
  • GatsbyJS: A React-based site generator that offers the perfect JAMstack for a headless Drupal architecture. GatsbyJS drives greater site performance and smooth user experience. It offers a full plugin library to allow almost any kind of content to be pulled in for site creation, via GraphQL. The not-so-steep learning curve and growing community of developers means GatsbyJS will see higher adoption as enterprises try to get more done with Drupal. 

Growing the Drupal Community

This decade is going to be special for us as well as Srijan puts in concerted efforts to grow the Drupal community in India and Asia at large. As a part of this, we plan to:

  • Commit greater number of resources to contributing to Drupal, working across a diverse range on ongoing initiatives and Drupal 9.
  • Drive the Drupal India Association to bring structure and increased participation of different firms and developers in the Indian Drupal community.

Much like the last decade, 2020 and beyond will be marked by exciting new developments in Drupal. But unlike before, these developments will not just be around core Drupal, but rather focussed on how Drupal will interact and operate with other technology solutions and frameworks to solve key enterprise challenges. 

What are you most excited about Drupal's future in 2020?

And if you are wondering how Drupal can help you solve a particular challenge at your organization, just drop us a line and our Drupal experts will be in touch.

Dec 23 2019
Dec 23

Multilingual websites have clear business benefits. Customers who order website creation or improvement want the highest level of their user-friendliness.

Among the vital elements of an easy-to-use multilingual site is a language switcher. Let’s discuss what this switcher is, see beautiful examples of it, and review how it works in Drupal 8 — the best CMS for multilingual websites.

What is the language switcher?

A multi-language switcher is a UI element allowing users to view content in their preferred tongue. Switchers are included in the website’s header, footer, navigation, near the content posts, and more.

They can be in the form of buttons, dropdown menus, lists, flags, etc. The form doesn’t matter — it just needs to be obvious and convenient for users to switch between the versions.

Best Examples of Language Switch Designs


Germany’s version of the famous e-commerce platform offers a handy dropdown with radio buttons. The languages presented on amazon.de are German, Dutch, Polish, Turkish, and Czech.

Language switcher on the amazon.de website


Very user-friendly in its simplicity, the multilingual switcher on the Nokia Corporation’s website offers links to the appropriate versions. Their list is really impressive and contains 26 languages.

Language switcher on the Nokia website


The Drupal 8 website for the Croatian National Tourist Board has a very stylish switcher. Fifteen languages to a person’s choice are presented as country flags with labels. The flags are filled with color when the user hovers over them.

Language switcher on the croatia.hr site

Language switcher in Drupal 8

Since Drupal 8 is multilingual out-of-the-box, it also has a built-in language switcher. It is included in the whole package of its impressive multilingual features (almost a hundred languages supported, interface translations ready, easy setup, RTL, and more).

The switcher can be added anywhere on your website and allows flexible configuration as to the languages included, custom label (e.g. “Choose your language”), etc. These are pretty basic things, the rest is up to developers who can create the switcher’s perfect look and functionality.

How to add a language switcher in Drupal 8

Adding a switcher only becomes available after you enable the multilingual functionality. So we will run through these preparatory steps very briefly — although there are many other interesting options to configure.

1) Enabling the multilingual modules

We need to enable the multilingual modules in Drupal 8 core:

  • Configuration Translation
  • Content Translation
  • Interface Translation
  • Language
Enabling the multilingual modules in Drupal 8

2) Adding a language

Then in the Configuration section, we will see the “Regional and language” subsection. We click on “Languages” to add new ones to the site. It will offer a dropdown of almost a hundred languages as well as the “custom language” option.

Adding a language to a Drupal 8 siteAdding a language to a Drupal 8 site

3) Creating a language selector for editors

The language selector is a kind of language switcher but for content editors. To get it, we need to choose which content types and their particular fields will be translatable in “Regional and language” — “Content language and translation.”

Making content translatable in Drupal 8

This will let editors select the language to write in and use the “Translate” tab.

Option to choose language during content creation on a multilingual Drupal 8 siteOption to translate content on a multilingual Drupal 8 site

4) Creating a language switcher for users

Finally, we can get a content switcher for website users so they can switch between the content versions. Drupal provides a “Language switcher” block. Like all other blocks, it is found in Structure — Block layout.

We need to click on the region in which we want to place the switcher. Then we find the language switcher block on the list of available blocks, click “Place block” again, and save blocks.

Finding the language switcher block in multilingual Drupal 8

While placing the block (or at any time) we can choose a custom title for it (for example, “Select language”) or choose to display no title at all. We can also select the languages to show in the switcher, which by default will mean all.

Configuring language switcher on a multilingual Drupal 8 site

We put in the “Sidebar first” region:

Basic language switcher in sidebar first region of a Drupal 8 site

Or maybe we could move it to the header by clicking on the pencil near the block and opening the configuration settings:

Basic language switcher in header of a Drupal 8 site

This and many other options are provided by Drupal out-of-the-box. But, of course, your language switcher will look much more stylish after our developers apply their CSS, JavaScript, and other front-end skills.

Video about creating a language switcher to a Drupal 8 site

We have created a brief video with the above described process. Enjoy!

[embedded content]

Create a language switcher or a multilingual site!

You can always entrust our Drupal support experts with:

  • creating a language switcher for your site according to your vision
  • building you a feature-rich multilingual site from scratch in any industry

Let’s do it — your multilingual audience is waiting!

Dec 23 2019
Dec 23

From time to time conversations come up among developers, and other fellow travelers, about being self-taught vs getting formal training. Over time I’ve come to realize that the further and further you get into your career, the less the distinction means anything; eventually we are all mostly self-taught.

I’ve written before about the value of my liberal arts education and I stand by my assertion that what I learned in that setting was, and is, valuable to my life and work. But just because something was useful to life does not mean it was the only way to acquire the skills. It’s a good way for many people, but far from the only way.

For anyone in a technical field, and most professional fields really, to succeed over time you need to learn new tools, skills, and techniques. The tools I knew when I graduated college are all largely outmoded or significantly upgraded, and I’ve had to learn a variety of technologies that didn’t exist in 2001.

Within the Drupal community lots of people talk about being self-taught, sometimes with pride sometimes with embarrassment, but in truth very few people were formally trained on the platform. Lots of very successful developers in the Drupal community (and beyond) have degrees in fields like religion and art history, not computer science, and have taught themselves how to do awesome things. In fact, I’ll argue that just about every Drupaler taught themselves most of what they know about Drupal. How they did that can vary widely, but we are a community with few formal training programs and lots of people who stumbled into Drupal trying to solve a non-technical problem. Even advanced workshops at conferences dig deep into one small area and expect you to generalize that knowledge to your projects, which I count as self-teaching. For example, I had a friend ask the other day about how to control the PDO connection settings in Drupal 7 — which I didn’t know how to do, but knew they were similar to Drupal 8 — so I sent him my Drupal 8 instructions and he figured it out how from there. He’s now taught himself how to do what he needed for that project and in the process generalized the approach for whatever he may need next time.

So then it is important for all of us to find, and hopefully share, techniques for self-teaching — even for those who have some kind of formal training. Here are my suggestions for people who are starting out and haven’t yet found the pattern that works for them:

  1. Assume you first solution is wrong. Most of us have, or will, stumble our way through a project where we don’t really know what we’re doing without a lot of support. We usually learn a great deal in the process, and launching those projects can feel pretty good cause you’ve succeeded at something hard. It is easy to get into the habit of assuming the solutions from that project were correct because they worked. In truth those projects are really rough around the edges, and just because we got it to work does not mean the solution was good. Assuming the first solution is good enough forever is how you become an expert beginner which then takes a lot of effort to undo. Once you have a working solution, step back and see if you can think of a better one, or see if you now can guess better search terms to see if someone else wrote up a different solution to the same problem. Admit your work could be better and try to improve it.
  2. Learn a few more programming languages. Most people who are self-taught from the start, and even some who have a BA/BS in Computer Science, only know 2 or 3 programming languages (PHP, JS, and CSS+HTML are often the only languages new people learn at first). One of the courses I took by chance in college forced me to learn 8 in 16 weeks. It was grueling, miserable, and darned useful. I can still learn a new language in just a couple weeks and rarely do I hit a language construct I don’t recognize. You don’t need to go that far. When I first started out a mentor told me you should learn a new language every year, and for several I did. Some of those, not the languages I learned in college, are the ones I use most day-to-day. All told I’ve spent time writing code in more than twenty different languages. That many isn’t terribly useful but the more languages you learn, the more you learn to understand the elements of your primary language.
  3. Learn basic algorithms and to measure complexity. The kind of thinking that goes into formal algorithms will help you be a better developer overall; badly thought through processes is the place I tend to see the largest gaps between developers with and without formal training. Any college-level CS program will put you through an algorithms course that teaches a variety of specific algorithms and force you to understand their structures. If you didn’t go through one of those programs, this is probably the course that will help you the most. On the one hand most of us rarely rewrite these algorithms as on modern platforms some library or another will provide a better version than we are likely to craft for our project. But learning what they are, when they are used, and how to understand their performance is useful for any project that involves lots of data or processing. MIT has a version of their algorithms course from 2011 online, or find one through another provider. Even if you just watch the lectures (really watching, not just vaguely have them on while cooking and cleaning), you can learn a great deal of useful information. I learned a lot watching those lectures as it refreshed and updated my understanding of the topics.
  4. Find and learn from mentors. Notice I used a plural there; you should try to find a few people willing to help you learn your profession, and more generally help you learn to advance in your field. Most of us benefit from learning from the experiences of multiple people, and who we need to learn from changes over time. I had the great experience of having a few wonderful mentors when I was first starting out, and much of the advice they gave me still serves me well. Some of it contradicted, and resolving those contradictions forced me to learn to do things my own way and find my own solutions.
  5. Learn other platforms. This is both a protection against future shifts in the market, and also a way to see how things work from outside your current professional bubble. Drupal developers can learn a lot from writing a WordPress plugin, or better yet an add-on for a platform in another language (think about Plone, Gatsby, or Hugo). Or try to learn to work with a platform like Salesforce or AWS. Other platforms have different communities, different learning styles, and different patterns. Like understanding additional languages, different platforms help you broaden your understanding and provide insights you can bring back to your main work.
  6. Learn to give and take criticism. Part of learning is getting feedback on your work, and part of being on a team is sharing feedback with others. If you took art or music classes in high school or college you probably learned some of the basic lessons you need here, but if you didn’t, consider taking one now at your local community college or art center. The arts are wonderful for getting experience with criticism. For all art is often open to interpretation, it also requires specific skills. If you play off-key, it sounds wrong. If your sculpture collapses under its own weight, the project failed. If your picture’s subject is out of focus, you need to re-shoot it. Sure there are brilliant artists who can violate all the rules, but if you have never experienced an art critique you are not one of those artists. The experience of getting direct, blunt, and honest feedback will help you understand its value and how to give that feedback yourself.
  7. Share what you think you know. We learn a great deal with we teach others. Both because it forces us to refine our thinking and understanding so we can explain it, and because learners ask questions we cannot answer off the top of our heads. This can be user group or conference presentations, internal trainings for your team, mentoring junior developers, writing a blog, or anything else that gets your from learning to teaching. It’s okay if you’re not 100% right, that’s part of how we learn. A few years ago I was doing a joint project with a junior developer who asked me a lot of questions, and pushed hard when she thought I was making mistakes. When she asked why I was selecting a solution or setting a pattern, she was never satisfied with “because that’s the best way to do it.” She wanted me to explain why that was the best way. If I couldn’t walk her through it right away, I went back and hunted for reference material to explain it or if that failed I tested her counter ideas against my plans to see if I was missing something. While I was usually right, not always and we did make changes based on her feedback. More importantly it forced me to show my work in fine detail which was a good exercise for me and gave her insights to help her do better work.
  8. Find your own patterns. At the start I said this list was for people who didn’t have their own patterns yet. In the long-run of your career you need to figure out what you need to know to get to where you want to go next. Eventually you will need to find a pattern that works for you and the life you are living. No one can tell you what that is, nor how to learn it all yourself. Experiment with learning styles, areas of work, roles, and types of projects as much as you are able until you feel your way to the right solutions for you.
Dec 23 2019
Dec 23

Making multilingual sites is hard. I’ve been using Drupal since version 5 and I can say a few things about the evolution of Drupal multilingual capabilities:

  • First, Drupal 8 is – in my opinion – the first version of Drupal where someone could say that multilingual works, pretty much out of the box.
  • Second, the documentation about how to deal with different scenarios is quite good.
  • And third, from a user experience perspective, translating the user interface of a site is really hard.

In this post we will talk about the third point and what we did to manage that complexity.

Our Current Scenario

We are building a really complex site, and the main challenges we faced regarding multilingual are:

  • The site is a multisite architecture, one database using Organic Groups.
  • Each group represents a country, and each country needs its site in one or more languages.
  • We have several variations of the same language depending on the region this language is spoken in.
  • We don’t want to let content editors translate the site directly from the UI.
  • We don’t speak all the languages the site is in.

The last item is quite relevant, when you don’t speak a language, you cannot even be sure if the string you are copying into a textbox says what it should.

The First Attempt

We started with a translation matrix to store all the translations. A simple Google drive spreadsheet to track each string translation in each language.

Each column uses the language code as a header.

Using a tool to convert Spreadsheets into po files we get each translation file fr.po, es.po, pt.po.

We used wichert/po-xls to achieve this with good results.

Not So Fast

This initial, somewhat naive, approach had a few problems.

  • Drupal string translations are case sensitive. This means that if you made a typo and wrote Photo instead of photo the translation will fail.
  • Some strings are the result of a calculation. For example. Downloads: 3 is actually managed by Drupal as Downloads: @count.

But the more complex item is that Drupal 8 has two ways to translate strings. The first one is inherited from Drupal 7. The one that makes use of the well known t function for example t('Contact us.').

The other one is a new way that allows site builders to translate configuration entities.

The two scenarios that allow translation of a Drupal site.

Translating Configuration Entities is Really Hard

To translate configuration entities, you need to identify which configuration needs translation, and find the exact part relevant to you. For complex configuration entities like views, this could be quite hard to understand.

Even for an experienced site admin this can be hard to understand.

Another problem that we had to solve was the vast amount of configuration alternatives you have when dealing with a medium-size Drupal site.

Each category has a lot of items to translate.

It was clear to us that in order to translate all those items we needed to find another way.

More problems… Identifying Which Strings to Translate is Hard

One thing to consider when dealing with Drupal translations is that it’s not easy to identify if a string is displayed somewhere in the frontend or if it is only a backend string.

Translating the entire codebase may not be a viable option if you want to keep a short list of translations reviewed by a group of people. In our case, it was important to make sure that translations are accurate, and that translators do not feel overwhelmed.

We don’t have a great solution to this problem yet. One of the strategies we used was to search for all the strings in twig templates and custom modules code using a grep search.

egrep -hro "[\>, ]t\('.*'\)" . | cut -c 5-   # Get strings inside ->t(...) and t(...)
egrep -hro "{{ '.*'\|\t" .                   # Get twig strings '....'|t
egrep -hro " trans .*" .                     # Get twig strings inside trans

However, as we figured out later by reading the documentation, twig strings cannot be used as a source for translations. Internally, Drupal maps those strings back to the regular use of t('strings').

This means that strings like:

{% trans %}Copyright {{ year }}{% endtrans %}

Are actually converted to

t('Copyright @year')

And that last string is the one you should use as source of the translation.

At the end, we cleaned up the spreadsheet list using visual inspect, and so far it has been working fine.

How We Solved the Problems?

To recap the problems we had:

  • We did not want to translate all the available strings.
  • We did not know all the languages, therefore copy and pasting was a risk.
  • Translators were expecting to have a reduced number of strings to translate.
  • Configuration translations are quite complex to track.

As we mentioned before using the xls-to-po tool, we were able to obtain the PO files to translate one part of the strings that we needed to translate.

We also used drush_language to automate the process.

drush language-import --langcode=fr path/to/po_files/fr.po

This little snippet iterates over all of the po files in the po_files directory and imports the language using the drush command mentioned above.

The xls spreadsheet has in the first column the Message Id, and the language codes of the system

By using conditional cell colors, we can quickly identify which translations are pending.

Solving the Configuration Translation Problem

The second part of our problem was a bit more tricky to fix.

We used a custom script to get all the config entity strings that were relevant to us.

Here is a simplified version of the script.

$prefix = 'views.view.custom_view';
$key = 'display.default.display_options.exposed_form.options.reset_button_label';

$configFactory = \Drupal::service('config.factory');
$list = $configFactory->listAll($prefix);

$rows = [];

foreach ($list as $config_name) {
  $columns = [];
  // Add the unique identifier for this field.
  $columns[] = $config_name . ':' . $key;

  // Get the untranslated value from the config.
  $base_config = $configFactory->getEditable($name);
  $columns[] = $base_config->get($key);

  $rows[] = $columns;

If you wonder how to get the $prefix and $key, they are obtained by inspecting the name of the field we want to translate in the Configuration Translation UI.

You need to inspect the HTML of the page, see the name attribute.

We print the result of the script to obtain a new CSV file that looks like this

The first column is a unique id that combines the prefix and the key.

Then, we copy and paste this CSV file as a new tab in the general translation matrix, and complete the header with the rest of the languages translations.

Finally we use a spreadsheet formula to find the translation we want for the languages we are interested in.


This will search for a match in the Strings matrix, and provide a translation.

Spreadsheet magic.

Final step: Importing the Configuration Strings Translation Back to Drupal

Once we have all the translations we need. We export the CSV file again and use this other script (simplified version) to do the inverse process:

use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Encoder\CsvEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;

$filename = 'path/to/config_translations.csv';

$serializer = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]);
$configFactory = \Drupal::service('config.factory');
$languageManager = \Drupal::service('language_manager');

$serializer->encode($data, 'csv');
$data = $serializer->decode(file_get_contents($filename), 'csv');

foreach ($data as $row) {
  $name_key = array_values($row)[0];
  list($name, $key) = explode(':', $name_key);

  // The languages we care start after the second column.
  $languages = array_filter(array_slice($row, 2));

  foreach ($languages as $langcode => $translation) {
    $config_translation = $languageManager
                            ->getLanguageConfigOverride($langcode, $name);
    $saved_config = $config_translation->get();
    $config_translation->set($key, $translation);

Some Other Interesting Problems We Had

Before finishing the article, we would like to share something interesting regarding translations with contexts. As you may know, context allows you to have variations of the same translation depending on, well… context.

In our case, we needed context to display different variations of a French translation. In particular, this is the string in English that we needed to translate to French:

Our organization in {Group Name}

In France, this translates into Notre organisation en France. But if you want to say the same for Canada, due to French grammatical rules you need to say Notre organisation au Canada (note the change en for au).

We decided to create a context variation for this particular string using context with twig templating.

{% trans with {'context': group_iso2_code} %}
Our organization in { group_name }
{% endtrans %}

This worked ok-ish, until we realized that this affected all the other languages. So we need to specify the same translation for each group even if the language was not French

This is not what we want...

After some research we found the translation_fallback module but unfortunately it was a Drupal 7 solution.

Long story short, we ended up with this solution.

{% if group_uses_language_context %}
  {% trans with {'context': country_iso2_code} %}
    Our organization in { group_name }
  {% endtrans %}
{% else %}
  {% trans %}Our organization in { group_name }{% endtrans %}
{% endif %}

Which basically provides two versions of the same string. But if the group needs some special treatment, we have the change to override it. Lucky for us, xls-to-po has support for strings with context. This is how we structured the translations for strings that require context:

CA, in this case, is the ISO code for Canada


For us, this is still a work in progress. We will have to manage around 20 or more languages at some point in the project. By that point, having everything in a single spreadsheet may not be maintainable anymore. There are other tools that could help us to organize source strings. But so far a shared Google Sheet worked.

We still use configuration management to sync the strings in production. The snippets provided in this post are run against a backup database so we can translate all the entities with more confidence. Once we ran the script we use drush config:export to save all the translations to the filesystem.

Dec 22 2019
Dec 22

One of OSTraining’s members wants to have a carousel slider in her site. She wants the carousel to show 3 image slides and some text below them, and the carousel to move only one position at a time when you click the “Next” button. 

This is possible to achieve, thanks to the Drupal Slick module which has several options and settings to customize this interaction with a couple of clicks. 

Keep reading in order to learn how to use this module!

191216 slick

Step #1. Install the Module

  • In order to build the carousel, we have to install two modules and their corresponding third-party libraries.

    • Open the Terminal application of your system 
    • Type: composer require drupal/slick 

191216 slick 000 

 Now, it is time to add the JS library for the slick module. You can use the file manager of your operating system or the terminal for the next operation: 

  • Type the following commands in order:

mkdir libraries 

This creates a directory called libraries in the root folder of your Drupal installation.

cd libraries

To access the directory.

wget https://github.com/kenwheeler/slick/archive/1.8.0.tar.gz

This command downloads the slick library from its GitHub repository in a compressed tar.gz file.

tar xzvf 1.8.0.tar.gz

To uncompress the tar.gz file.

191216 slick 001

mv slick-1.8.0/ slick

To change the name of the uncompressed folder.

cd ..

To go back to the root folder.

composer require “drupal/blazy:1.0-rc4”

This will download the specific version of Blazy, required for Slick to work properly, since the stable version of Slick works only with version 1.0 of Blazy.

191216 slick 003

mv blazy-master/ blazy

To change the name of the uncompressed folder.

rm *.zip && rm *.tar.gz

To delete both compressed files. 

191216 slick 004

You should at the end have the following folder structure:

191216 slick 005

The files slick.min.js and blazy.min.js are inside the slick and blazy folders respectively. 

cd ..

To go back to the root folder.

composer require drupal/slick_views

This will download the Slick Views module, which integrates Drupal Views with Slick.

  • Click Extend.
  • Enable the following modules:
    • Blazy
    • Blazy UI
    • Slick
    • Slick UI
    • Slick Views
  • Click Install.

191216 slick 007

We are now set and can proceed with configuring the Slick Optionset.

Step #2. The Slick Optionset

  • Click Configuration > Slick.

191216 slick 008

The first configuration screen shows the list of available Slick optionsets. Imagine optionsets as cassettes or CDs, which you can exchange in your player to get the right song (in this case the right carousel). The bottom half of the screen shows all different skins, that can be applied to the carousel. This functionality will be covered in a future tutorial. The UI tab has two options regarding the style of these skins.

  • Click Add slick optionset.

191216 slick 009

You will be presented with a lot of options, most of them are self-explanatory. Let’s take a look at some of them.

  • Give the optionset a proper label.
  • Replace the Previous and Next arrows text with the symbols “<” (less than) and “>” (greater than), so that the code reads like this:

<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0"> < </button>

  • Increase the number of Slides to show to 3.
  • Increase the speed to 900ms (making the slide effect slower).
  • Change the CSS override to swing.
  • Click Save.

191216 slick 010

Step #3. - Create the Carousel View

  • Click Structure > Views > Add view.
  • Enter a proper name for the view.
  • Show Content of type Article.
  • Select Create a block.
  • Choose Slick Carousel of fields.
  • Set the number of Items per block to 0.
  • Click Save and edit.

191216 slick 011

  • Click Add in the Fields section.
  • Enter Body in the search box.
  • Check the Body option.
  • Enter Image in the search box.
  • Check the Image option.
  • Click Add and configure fields. 

191216 slick 015

  • Change the Formatter option to Trimmed.
  • Set the number of characters to 150 as the Trimmed limit.
  • Click Apply and continue.

191216 slick 013

  • Change the Image style to Medium.
  • Link the image to the Content.
  • Click Apply.

191216 slick 014

  • Rearrange the fields in this order: 
    • Image
    • Title
    • Body
  • Click the Slick Carousel Settings.
  • Check Vanilla Slick.
  • Select the optionset you created before.
  • Click Apply.

191216 slick 015

  • Save the view

Step #4. - Place the Block

  • Click Structure > Block layout.
  • Scroll down to the Content section.
  • Click Place block.
  • Search for the view you have just created. 
  • Click Place block.

191216 slick 016

  • Drag the block behind the Main page content block.
  • Scroll down and click Save blocks.

Now you can take a look at one of your articles and test the carousel. Congratulations!

The rest is CSS styling. To improve the layout, for example with CSS Grid, take a look at this article.

Thanks for reading!

About the author

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

Although web accessibility begins on a foundation built by content strategists, designers, and engineers, the buck does not stop there (or at site launch). Content marketers play a huge role in maintaining web accessibility standards as they publish new content over time.

“Web accessibility means that people with disabilities can perceive, understand, navigate, and interact with the Web, and that they can contribute to the Web.” - W3

Why Accessibility Standards are Important to Marketers

Web accessibility standards are often thought to assist audiences who are affected by common disabilities like low vision/blindness, deafness, or limited dexterity. In addition to these audiences, web accessibility also benefits those with a temporary or situational disability. This could include someone who is nursing an injury, someone who is working from a coffee shop with slow wifi, or someone who is in a public space and doesn’t want to become a nuisance to others by playing audio out loud.

Accessibility relies on empathy and understanding of a wide range of user experiences. People perceive your content through different senses depending on their own needs and preferences. If someone isn’t physically seeing the blog post you wrote or can’t hear the audio of the podcast you published, that doesn’t mean you as a marketer don’t care about providing that information to that audience, it just means you need to adapt in the way you are delivering that information to that audience.

10 Tips for Publishing Accessible Content

These tips have been curated and compiled from a handful of different resources including the WCAG standards set forth by W3C, and our team of accessibility gurus at Palantir. All of the informing resources are linked in a handy list at the end of this post. 

1. Consider the type of content and provide meaningful text alternatives.

Text alternatives should help your audience understand the content and context of each image, video, or audio file. It also makes that information accessible to technology that cannot see or hear your content, like search engines (which translates to better SEO).

Icons to show image, audio, video

Types of text alternatives you can provide:

  • Images - Provide alternative text.
  • Audio - Provide transcripts.
  • Video - Provide captions and video descriptions in action.

This tip affects those situational use cases mentioned above as well. Think about the last time you sent out an email newsletter. If someone has images turned off on their email to preserve cellular data, you want to make sure your email still makes sense. Providing a text alternative means your reader still has all of the context they need to understand your email, even without that image.

2. Write proper alt text.

Alternative text or alt text is a brief text description that can be attributed to the HTML tag for an image on a web page. Alt text enables users who cannot see the images on a page to better understand your content. Screen readers and other assistive technology can’t interpret the meaning of an image without alt text.

With the addition of required alternative text, Drupal 8 has made it easier to build accessibility into your publishing workflow. However, content creators still need to be able to write effective alt text. Below I’ve listed a handful of things to consider when writing alt text for your content.

  • Be as descriptive and accurate as possible. Provide context. Especially if your image is serving a specific function, people who don’t see the image should have the same understanding as if they had.
  • If you’re sharing a chart or other data visualization, include that data in the alt text so people have all of the important information.
  • Avoid using “image of,” “picture of,” or something similar. It’s already assumed that the alt text is referencing an image, and you are losing precious character space (most screen readers cut off alt text at around 125 characters). The caveat to this is if you are describing a work of art, like a painting or illustration.
  • No spammy keyword stuffing. Alt text does help with SEO, but that’s not it’s primary purpose, so don’t abuse it. Find that happy medium between including all of the vital information and also including maybe one or two of those keywords you’re trying to target.
Illustration of red car with flames shooting out of the back, flying over line of cars on sunny roadway.Example of good alt text: “Red car in the sky.”
Example of better alt text: “Illustration of red car with flames shooting out of the back, flying over line of cars on sunny roadway.”

3. Establish a hierarchy.

Upside down pyramid split into three sections labeled high importance, medium importance, low importance

Accessibility is more than just making everything on a page available as text. It also affects the way you structure your content, and how you guide your users through a page. When drafting content, put the most important information first. Group similar content, and clearly separate different topics with headings. You want to make sure your ideas are organized in a logical way to improve scannability and encourage better understanding amongst your readers.

4. Use headings, lists, sections, and other structural elements to support your content hierarchy.

Users should be able to quickly assess what information is on a page and how it is organized. Using headings, subheadings and other structural elements helps establish hierarchy and makes web pages easily understandable by both the human eye and a screen reader. Also, when possible, opt for using lists over tables. Tables are ultimately more difficult for screen reader users to navigate.

If you’re curious to see how structured your content is, scan the URL using WAVE, an accessibility tool that allows you to see an outline of the structural elements on any web page. Using WAVE can help you better visualize how someone who is using assistive technologies might be viewing your page.

5. Write a descriptive title for every page.

This one is pretty straight forward. Users should be able to quickly assess the purpose of each page. Screen readers announce the page title when they load a web page, so writing a descriptive title helps those users make more informed page selections.

Page titles impact:

  • Users with low vision who need to be able to easily distinguish between pages
  • Users with cognitive disabilities, limited short-term memory, and reading disabilities.

6. Be intentional with your link text.

Write link text that makes each link’s purpose clear to the user. Links should provide info on where you will end up or what will happen if you click on that link. If someone is using a screen reader to tab through 3 links on a page that all read “click here,” that doesn’t really help them figure out what each link’s purpose is and ultimately decide which link they should click on.

Additional tips:

  • Any contextual information should directly precede links.
  • Don’t use urls as link text; they aren’t informative.
  • Avoid writing long paragraphs with multiple links. If you have multiple links to share on one topic, it’s better to write a short piece of text followed by a list of bulleted links.

EX: Use "Learn more about our new Federated Search application" not "Learn more".

7. Avoid using images of text in place of actual text.

The exact guideline set forth by W3 here is “Make it easier for users to see and hear content including separating foreground from background.” 

There are many reasons why this is a good practice that reach beyond accessibility implications. Using actual text helps with SEO, allows for on-page search ability for users, and creates the ability to highlight for copy/pasting. There are some exceptions that can be made if the image is essential to include (like a logo). Providing alt text also may be a solution for certain use cases.

8. Avoid idioms, jargon, abbreviations, and other nonliteral words.

The guideline set forth by W3 is to “make text content readable and understandable.” Accessibility aside, this is important for us marketers In the Drupal-world, because it’s really easy to include a plethora of jargon that your client audience might not be familiar with. So be accessible AND client-friendly, and if you have to use jargon or abbreviations, make sure you provide a definition of the word, link to the definition, or include an explanation of any abbreviations on first reference.

Think about it this way: if you are writing in terms people aren’t familiar with, how will they know to search for them? Plain language = better SEO.

9. Create clear content for your audience’s reading level.

For most Americans, the average reading level is a lower secondary education level. Even if you are marketing to a group of savvy individuals who are capable of understanding pretty complicated material, the truth is, most people are pressed for time and might become stressed if they have to read super complicated marketing materials. This is also important to keep in mind for people with cognitive disabilities, or reading disabilities, like dyslexia.

I know what you’re thinking, “but I am selling a complicated service.” If you need to include technical or complicated material to get your point across, then provide supplemental content such as an infographic or illustration, or a bulleted list of key points.

There are a number of tools online that you can use to determine the readability of your content, and WebAIM has a really great resource for guidelines on writing clearly.

10. Clearly label form input elements.

If you are in content marketing, chances are you have built a form or two in your time. No matter whether you’re creating those in Drupal or an external tool like Hubspot, you want to make sure you are labeling form fields clearly so that the user can understand how to complete the form. For example, expected data formats (such as day, month, year) are helpful. Also, required fields should be clearly marked. This is important for accessibility, but also then you as a marketer end up with better data.

Helpful Resources

Here are a few guides I've found useful in the quest to publish accessible content:

Accessibility Tools

Dec 19 2019
Dec 19

Holiday gift: Automatic Updates

As of today, the Automatic Updates contributed module for Drupal 7 and Drupal 8 has had its first stable release! This represents the completion of Phase 1 of the Automatic Updates Initiative, and the culmination of more than 18 months of work.


Please note: this phase 1 work provides automatic update coverage for many scenarios, but not for every Drupal use case.

With this phase 1 release you can:

  • See Drupal PSAs that the security team determines are highly critical directly in your administrative interface.
  • Run readiness checks to determine if your site is eligible for automatic updates (is the filesystem writable, no custom edits to updated files, etc).
  • Automatically update Drupal 7 and Drupal 8 sites
    • Current limitations
      • Updates Drupal core, but not contributed projects
      • Right now, can update only if the sites are not built or maintained with Composer 
      • Database updates are supported in Drupal 8, but not supported in Drupal 7 (if there are DB updates, an automatic update in D7 will be rolled back)

The Automatic Updates module will not be an official solution until the second phase is complete and the feature becomes part of Drupal Core. However, we believe that even as a contributed module Automatic Updates provides a significant improvement in maintenance and cost of ownership for a broad base of existing Drupal 7 and 8 sites, particularly those managed by small, independent site owners.


The second phase of this initiative will focus on solving the remaining requirements and getting automatic updates ready for inclusion in Drupal core. The outstanding requirements include:

  • Support for Composer-built sites
  • Support for contributed modules and themes
  • Support for a more robust roll-back process
  • More robust support for database updates

We are currently seeking sponsors for the second phase of this initiative, so please reach out to us at the Drupal Association if you'd like to support this work!

Many thanks!

Thank you to these individuals:

And to these organizations:

Dec 19 2019
Dec 19

by Elliot Christenson on December 19, 2019 - 12:04am

In November 2021, Drupal 7 will be End-of-Life (EOL). To continue getting security updates, you'll need to get Extended Support (D7ES). But if you sign up before EOL, you'll get automatic security updates until then AND a better price when EOL comes.

In case you haven't heard, the Drupal project is discontinuing "official support" for Drupal 7!

Drupal 7 will continue to be supported a bit longer than in the past - until November 2021, but you'll need to update to Drupal 8 (or more likely 9) eventually!

Or do you? What if the expense or timeframe won't work for your organization.

We've previously mentioned our intention to offer Drupal 7 Extended Support, but what we'd like to clarify now is an important piece: the PRICE.

Our Drupal 6 pricing costs a bit more than our current Drupal 7 pricing. We want to offer special pricing for our existing clients. For as little as $99 per month, they can keep your Drupal 7 website running for years to come!

We'd like to offer that same deal to anyone else that wants to join us before the coming wave of 2020 and 2021. We aren't sure how long this special pricing will last, so please contact us now to begin discussing how we can help!

A great way to get started is with our FREE SITE AUDIT.

Contact Us for a FREE Site Audit and to Learn More About D7ES!

If you buy Drupal 7 Maintenance and Support now, you'll get to keep that price when the change to Drupal 7 Extended Support happens in 2021!

Dec 19 2019
Dec 19

Forums or message boards are an implementation of an early way of communicating, generating content and interacting through the internet, by creating threaded discussion boards, called bulletin boards. Despite the fact of being one of the most traditional ways to exchange information over the web, forums are still a very effective way to build a community around your website or web application. 

Drupal 8 offers by default the Forum module in Core. This module allows you to implement a basic forum on your Drupal site or web application. 

Keep reading, in order to learn how to use this module! 

Step #1. Enable the Module

  • Click Extend
  • Scroll down until you find the forum module, or use the search box to filter it out
  • Enable the module
  • Click Install

 191126 drupal forum  

No further modules are required.

 Step #2. - The Forum Settings

The Forum module has created a new content type called Forums.

  • Click Structure > Forums 

191126 drupal forum 001

The concepts to configure the module are the following: 

  • Topics are Drupal nodes posted into a forum. The comments to these nodes are the threaded replies to the forum topic.
  • Topics have to be always inside a forum. It is not possible to place a topic inside a container. 
  • Forums can contain unlimited forums and can even contain other forums, called child forums.
  • Containers are created to hold (wrap) a group of forums. It is possible to wrap a container around many forums, the same way a forum can hold one or multiple containers holding at the same time multiple forums.

As you can see, with the right planning, it is possible to create complex nested structures to categorize the content of users. 

  • Click Edit to configure the General discussion forum
  • Scroll down and click Delete

191126 drupal forum 002

  • Click Add container

 191126 drupal forum 003

If your site was about pets, then it is very probable that you would have a section for dogs and a section for cats, for example. To organize the forum content, it makes sense to create a global container for each one of these pets. 

  • Enter the required information
  • Click Save

191126 drupal forum 004

  • Click Add forum
  • Create as many forums as needed, according to your own categorization

These forums will be placed at the first level of the container

 191126 drupal forum 005 

Besides these forums on the first container level, we are going to create additional child forums, to preserve the information structure and be able to do comparisons between them later on.

191126 drupal forum 006

The final structure should look like the image below.

191126 drupal forum 007

Step #3. - Adding Topics to the Forum

  • Click on the root link, that is the link of the main container (in this case Dogs)

The system will send you to a page with the following URL pattern:


Notice that the column Topics on the table shows no results. That is because we have not added a topic to any of the forums. 

  • Click on the Food link below the parent forum Herding group

191126 drupal forum 008

  • Click Add new forum topic

191126 drupal forum 009

Check that you are placing the topic in the right place. 

  • Click Save

191126 drupal forum 010 

Each one of the comments to this new node will increase the count on the forums table.

191126 drupal forum 011

191126 drupal forum 012

If you click on the forum link, you will see a table with all the topic details of that particular forum. 

191126 drupal forum 013

I hope you liked this tutorial. Thanks for reading!

About the author

Jorge lived in Ecuador and Germany. Now he is back to his homeland Colombia. He spends his time translating from English and German to Spanish. He enjoys playing with Drupal and other Open Source Content Management Systems and technologies.
Dec 18 2019
Dec 18
Project: Drupal coreVersion: 8.8.x-dev8.7.x-dev7.x-devDate: 2019-December-18Security risk: Critical 17∕25 AC:Basic/A:User/CI:All/II:All/E:Proof/TD:UncommonVulnerability: Multiple vulnerabilitiesDescription: 

The Drupal project uses the third-party library Archive_Tar, which has released a security improvement that is needed to protect some Drupal configurations.

Multiple vulnerabilities are possible if Drupal is configured to allow .tar, .tar.gz, .bz2 or .tlz file uploads and processes them.

The latest versions of Drupal update Archive_Tar to 1.4.9 to mitigate the file processing vulnerabilities.

Edited to clarify the nature of the upstream release.


Install the latest version:

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

Additional information

All advisories released today:

Updating to the latest Drupal core release will apply the fixes for all the above advisories.

(Note that this SA is the only one in the list that applies to Drupal 7.x)

Reported By: Fixed By: 
Dec 18 2019
Dec 18
Project: Drupal coreVersion: 8.8.x-dev8.7.x-devDate: 2019-December-18Security risk: Moderately critical 10∕25 AC:Basic/A:User/CI:Some/II:None/E:Theoretical/TD:DefaultVulnerability: Access bypassDescription: 

The Media Library module has a security vulnerability whereby it doesn't sufficiently restrict access to media items in certain configurations.

  • If you are using Drupal 8.7.x, you should upgrade to Drupal 8.7.11.
  • If you are using Drupal 8.8.x, you should upgrade to Drupal 8.8.1.

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

Alternatively, you may mitigate this vulnerability by unchecking the "Enable advanced UI" checkbox on /admin/config/media/media-library. (This mitigation is not available in 8.7.x.)

Additional information

All advisories released today:

Updating to the latest Drupal core release will apply the fixes for all the above advisories.

Reported By: Fixed By: 
Dec 18 2019
Dec 18
Project: Drupal coreVersion: 8.8.x-dev8.7.x-devDate: 2019-December-18Security risk: Moderately critical 14∕25 AC:Basic/A:Admin/CI:Some/II:All/E:Theoretical/TD:DefaultVulnerability: Multiple vulnerabilitiesDescription: 

Drupal 8 core's file_save_upload() function does not strip the leading and trailing dot ('.') from filenames, like Drupal 7 did.

Users with the ability to upload files with any extension in conjunction with contributed modules may be able to use this to upload system files such as .htaccess in order to bypass protections afforded by Drupal's default .htaccess file.

After this fix, file_save_upload() now trims leading and trailing dots from filenames.


Install the latest version:

  • If you use Drupal core 8.7.x: 8.7.11
  • If you use Drupal core 8.8.x: 8.8.1

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

Additional information

All advisories released today:

Updating to the latest Drupal core release will apply the fixes for all the above advisories.

Reported By: Fixed By: 
Dec 18 2019
Dec 18
Project: Drupal coreVersion: 8.8.x-dev8.7.x-devDate: 2019-December-18Security risk: Moderately critical 12∕25 AC:None/A:None/CI:None/II:None/E:Theoretical/TD:AllVulnerability: Denial of ServiceDescription: 

A visit to install.php can cause cached data to become corrupted. This could cause a site to be impaired until caches are rebuilt.


Install the latest version:

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

To mitigate this issue in any version of Drupal 8, you can also block access to install.php if it's not required.

Additional information

All advisories released today:

Updating to the latest Drupal core release will apply the fixes for all the above advisories.

Reported By: Fixed By: 


About Drupal Sun

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

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

See the blog post at Evolving Web

Evolving Web