Srijan Technologies: A closer look at Acquia AgilOne

Planet Drupal - Fri, 2020/04/24 - 4:51am

CDPs are meant to integrate customers’ data beyond digital and physical technology warehouses to provide valuable insights into the data and help enterprises in delivering substantial engagement at every touch-point.


Jeff Geerling's Blog: Presenting on Drupal Dev Environments and Migrations at CMS Philly on May 1st

Planet Drupal - Fri, 2020/04/24 - 3:55am

Friend and former colleague Chris Urban and I will be presenting the results of the 2020 Drupal Local Development Survey at CMS Philly—which is now a virtual event—on May 1st. You can find more information about the session here: 2020 Developer Tool Survey Results. I'll also be posting the survey results on this blog soon after.

Chris also coaxed me into talking about my ongoing Drupal 7 to 8 migration saga in a separate session, so if you've missed the first 13 live stream episodes, check out the session How I'm migrating from Drupal 7 to Drupal 8 to get caught up—then subscribe to my YouTube channel to see how it all ends 🤪.

It remains to be seen whether Chris and I will be wearing Hawaiian shirts during the session:


Drupal Association blog: #DrupalCares Fundraising Update & Program Enhancements

Planet Drupal - Thu, 2020/04/23 - 11:10pm

Carrie Lacina, the Drupal Association’s Director of Fund Development, provides an update on fundraising efforts and program enhancements.

Hello! I’m Carrie Lacina, I’ve been at the Drupal Association for over 5 years in various Fund Development roles. I worked in the digital media and advertising space for 12 years before making the jump to the nonprofit open source world. At the Drupal Association, I enjoy engaging with a global community of organizations using or connecting with Drupal, partnering to solve their business needs while supporting the financial sustainability of the Drupal Association. 

You may have read recent #DrupalCares updates from my teammates including Frequently asked questions, answered by Angie Sabin and Sustaining the DA through the COVID-19 crisis by Tim Lehnen. Today I’d like to build on their updates by providing information on new or enhanced fundraising program elements along with a general update on our progress. 

But first, I’d like to say THANK YOU! I am overwhelmed by the outpouring of activity from individuals and organizations offering financial support for the Drupal Association.  You have proven what I’ve known all along: Drupal is strong and together we thrive.

Why support the Drupal Association? 

You probably know that Drupal will be fine and that open source projects, including Drupal, survive and even thrive during economic downturns. But the Drupal Association may not. Why does that matter? I appreciate how Matt Westgate framed it in the latest Lullabot Podcast:

Drupal the software will survive, that's the ‘engine.’ We will always have that and will continue to work on it. The Drupal Association is the ‘car,’ the vehicle to which we put the engine in, to make things move, with doors that open to include and invite other people into the project."

-Matt Westage, CEO, Lullabot

From an organizational perspective, open source contribution is essential to any business that relies on the project. The Drupal Association provides the tools to drive that success, but we need financial support to execute on our mission. By participating in Drupal Association programs, you directly support the Drupal Project, serve the global community and support its velocity and growth. Your support allows us to:

  • Maintain and expand how individuals and organizations can contribute and achieve recognition
  • Keep Drupal secure with advisories, documentation and releases
  • Drive initiatives for diversity, equity, and inclusion
  • Help the community follow the same path by bringing people together in person and online to collaborate and celebrate their Drupal successes
#DrupalCares Fundraising Update 

We launched the #DrupalCares campaign in early April. It’s incredible how quickly the community rallied to make a huge impact on our financial outlook:

  • 26 DrupalCon Minneapolis sponsors have pledged to keep their marketing dollars intact with the Drupal Association in 2020
  • 28 organizations have joined or upgraded their Drupal Association Supporting Partner program
  • More than 800 members have joined or upgraded their individual memberships
  • We’ve raised $228,000 in donations and matching challenges from Dries and Vanessa Buyteart and the Drupal business community, with a full week left to go.

We’ve made so much progress, and we're only $24,000 away from reaching our #DrupalCares Match Challenge!  Please consider donating today to help us reach our goal.  Any individual donations, increased memberships, or new memberships through the end of April will receive a 3:1 matching contribution to the #DrupalCares program, up to $100,000, for a total match potential of $300,000.

Drupal Association Program Updates and Enhancements

In addition to the $500,000 gap we are facing from the loss of DrupalCon Minneapolis net revenue, we anticipate a drop in our non-conference related revenue during an economic downturn. The Drupal Association has been working diligently to diversify funding while weaving in program changes and enhancements that continue to provide value and make it easier for organizations and individuals to invest in our mission.

Individual Memberships

Thank you to the new and renewing Drupal Association individual members!  We’ve had an outpouring of support through this program and have heard your suggestions for how we can improve our membership options.  Our team recently rolled out improvements to make it easier than ever to support Drupal as an Individual Member.  In the last few weeks we have:

  • Implemented monthly recurring payment option for memberships, since it’s often easier to give smaller monthly amounts rather than a lump annual sum
  • Enabled early renewals for recurring members who want to make an impact sooner
  • Added new tiers for individuals who have the capacity and desire to give more
  • Provided marketplace credit to organizations for each member of staff who has a membership

Please stay tuned for even more feature improvements, like:

  • Creating a mechanism to allow organizations to purchase memberships on behalf of their staff
  • Updating payment tools to support more currency types
  • Offering lower tiers for regions of the world that can’t easily support the current levels of member pricing

Supporting Partner Program

The Drupal Association Supporting Partner program offers organizations a way to financially support our mission which includes Thank you to our supporting partners, technology supporters, and hosting supporters - your continued support and generosity is crucial to the Drupal ecosystem.

Often seen as an infrastructure investment for organizations that make significant cost-savings by using a CMS with no licensing fees, the Supporting Partner Program has evolved over the years to offer even more benefits. From thought leadership, accreditation, networking opportunities, talent support and industry visibility - there’s something to meet every organization’s needs.

In an effort to grow participation from all types of organizations, we’ve launched two new Supporting Partner tiers. The “Community” Supporting Partnership is geared towards small businesses with fewer than 5 employees, while the “Enterprise” tier was designed with a focus on large organizations and their unique business needs. We’ve also added new benefits including complimentary Individual Memberships for staff and additional marketing opportunities on You can learn more about the new tiers and benefits here. Advertising & Sponsorships

We’ve heard your input about diversifying revenue away from DrupalCon even further.  We are exploring additional advertising and sponsorships opportunities on over the next few weeks, please stay tuned for updates on our advertising programs soon.

DrupalCon North America shifts for 2020

You may have seen the recent news that DrupalCon Minneapolis was officially canceled due to COVID-19.  Visit to learn more about the cancellation and the launch of our first virtual DrupalCon Global event.  

Thank you to the DrupalCon Minneapolis sponsors that have pledged to keep their dollars intact, regardless of the outcome of the event.  Now that we have officially gone virtual, we are working on translating DrupalCon Minneapolis sponsorship benefits to DrupalCon Global 2020. We are weaving sponsor plans into our platform selection and program updates, which will be finalized at the end of the month. Stay tuned for updates in May!

Community Driven Fundraising Efforts

In closing, we’d like to thank and celebrate a few of the unique individual fundraisers happening throughout the community.

Gábor Hojtsy opened the individual community fundraising efforts with an offer to donate €9 for each module the community update to be compatible with the upcoming Drupal 9 release. The offer has been so successful that, after only a few days, the €900 Gábor put into the fund was running out and the fund was boosted to €2250 by donations from Ron Northcutt and Ofer Shaal.

Jeff Geerling was clearly inspired to create a video telling the world how important the Drupal project has been to his life, how helping the Drupal Association helps Drupal and making a generous offer to donate $1 for every person who watches and likes his video, up to $1000. Of course, now that donation will be tripled. 

Kevin Kaland (that’s Kevin with the amazing wizard’s hat we all see at Drupal events) is the maintainer of the FillPDF module project and has a patreon page to sustain work on the module. He has pledged that, if you join his patreon page, he will donate double your subscription to the Drupal Association.

Finally, the community have helped in many other creative ways and these initiatives are still coming in. We were delighted to see that Kirsten Pol’s son (who has his own d.o account, of course) made a special #DrupalCares mascot that we absolutely love!

And as a reminder, here are the ways you can help too!

  • DrupalCon Sponsors…
    … can commit to pledging your full sponsorship to the Association, regardless of what shape DrupalCon takes this year. This will prevent the gap from getting wider.
  • Drupal Businesses…
    … Can join the supporting partner program, or increase your partner level. Organizations can also make tax deductible donations above and beyond their partnership tier.
  • Individuals…
    … Can join or renew the Drupal Association membership program, or make tax deductible individual donations.
  • Everyone…
    … can help us get the word out! The Drupal Association has deep, deep roots within the community, and tight relationships with those of you who build your livelihoods on Drupal. Unfortunately, there are 10 times as many end-users of Drupal out there who may not even know that the Association exists. Would you leverage your networks to help us reach them?

Four Kitchens: Four Kitchens’ Commitment to the Drupal Association

Planet Drupal - Thu, 2020/04/23 - 6:26pm

We’ve been making big websites for 14 years, and almost all of them have been built on Drupal. It’s no exaggeration to say that Four Kitchens owes its success to the incredible opportunities Drupal has provided us. There has never been anything like Drupal and the community it has fostered—and there may never be anything like it ever again.

That’s why it’s crucial we do everything we can to support the Drupal Association. Especially now.

The impacts of COVID-19 have been felt everywhere, especially at the Association. With the cancellation of DrupalCon Minneapolis, the Drupal Association lost a major source of annual fundraising. Without the revenue from DrupalCon, the Association would not be able to continue its mission to support the Drupal project, the community, and its growth.

The Drupal community’s response to this crisis was tremendous. For our part, we proudly joined 27 other organizations in pledging our sponsorship fees to the Association regardless of whether, or how, DrupalCon happened. I ensured my Individual Membership was still active, and I made a personal contribution.

But we need to do more.

You can help by joining us in the #DrupalCares campaign.

The #DrupalCares campaign is a fundraiser to protect the Drupal Association from the financial impact of COVID-19. While the Drupal project is used on the front lines of the Drupal fight, the Drupal Association itself is at risk because we are unable to hold our primary fundraising event, DrupalCon, in May as planned. Your support will help keep the Drupal Association strong and able to continue accelerating the Drupal project.

The Drupal Association

The outpouring of support has been… Inspiring. First, project founder Dries Buytaert and his partner Vanessa Buytaert pledged their generous support of $100,000. Then, a coalition of Drupal businesses pledged even more matching contributions. We are proud to count ourselves among the dozens of participating Drupal businesses.

Any individual donations, increased memberships, or new memberships through the end of April will be tripled by these matching pledges, up to $100,000, for a total of $300,000.

Please join us in supporting the Drupal Association. Your contribution will help ensure the continued success of the Association and the Drupal community for years to come.

Give to #DrupalCares through April to help the Association receive a 3:1 matching contribution. 

The post Four Kitchens’ Commitment to the Drupal Association appeared first on Four Kitchens.


InternetDevels: Why hire remote Drupal developers: during Corona crisis and always

Planet Drupal - Thu, 2020/04/23 - 5:50pm

Everyone is looking for positive news, and we got it for you. Drupal web development in times of Covid-19 continues — severe crises even open new perspectives! One of the characteristics of a good web development company is that it only becomes stronger in hard times.

Read more
Categories: Professional Drupal tech support for your website’s smooth work

Planet Drupal - Thu, 2020/04/23 - 5:05pm
We offer Drupal support services at very affordable prices through our quick, easy-to-apply, and reliable Drupal helpdesk. Learn more about the tech support by WishDesk in this post.
Categories: Authenticated User Cart with Gatsby and Drupal commerce

Planet Drupal - Thu, 2020/04/23 - 3:29pm
Authenticated User Cart with Gatsby and Drupal commerce Body

We are building a decoupled E-commerce site with Gatsby and Drupal commerce. As you are well aware of the fact that in all the web applications one of the most important features is user authenticated browsing. I will not go into the details of why user-authenticated browsing is important as you will find plenty of blog posts on that.

This blog post is aimed at users who may find themselves struggling like I did while trying to add the user authentication functionality to a Gatsby site. So let us get started.

  • User should be able to register
  • User should be able to log in as an authenticated user
  • User should be able to add products to their cart as an authenticated user
  1. Your Drupal commerce site should be up and going with all the commerce modules enabled that are provided by default.
  2. You should be able to fetch your Drupal data in your Gatsby site.
  3. Also, we will need the commerce cart API module which provides a RESTful interface to interact with our cart in Drupal.
Let’s Get started
  1. Go to REST option under web services and enable all the cart and user resources with the below permissions.

We are done from the Drupal end here. Let’s move to the Gatsby end now.

On Gatsby End 1. Register

The first thing we will do is add user registration functionality.

export const registerUser = async (name, password, email) => { const token = await fetch(`${url}rest/session/token?value`); const sessionToken = await token.text(); if (sessionToken) { const res = await fetch(`${url}user/register?_format=hal_json`, { method: 'POST', headers: { 'Content-Type': 'application/hal+json', 'X-CSRF-TOKEN': sessionToken, }, body: JSON.stringify({ _links: { type: { href: `${url}rest/type/user/user`, }, }, name: { value: name }, mail: { value: email }, pass: { value: password }, }), }); const data = await res.json(); return data; } };

Create your UserRegistration form and pass all the valid arguments to the registerUser function. Now submit your form to see your user registered on the Drupal end under the People tab. In case you get any permission issues, check under config/people/accounts to see if visitors are allowed to register.

Now that our user is registered. Our next step is to log in.

2. Login

Our log in functionality is based on the React Context API. So it is necessary you know how the Context API works.

Visit this link and copy four of the below-mentioned files:

  1. drupalOauth.js.
  2. drupalOauthContext.js
  3. withDrupalOauthConsumer.js
  4. withDrupalOauthProvider.js

Place all four files in a single directory named drupal-OAuth. Next, wrap your base component with DrupalOAuthConsumer to initialise the context provider. Your base component will look something like this:

import drupalOauth from '../components/drupal-oauth/drupalOauth'; import withDrupalOauthProvider from '../components/drupal-oauth/withDrupalOauthProvider'; // Initialize a new drupalOauth client which we can use to seed the context provider. const drupalOauthClient = new drupalOauth({  drupal_root: 'your drupal root url',  client_id: 'your simple OAuth consumer Id',  client_secret: 'Your simple OAuth consumer key', }); // ... the component definition goes here ... export default withDrupalOauthProvider(drupalOauthClient, Layout)

Now to create your sign in or login form take a look at below code:

import React, {Component} from 'react'; import { FaSpinner } from 'react-icons/fa'; import withDrupalOauthConsumer from '../DrupalOauth/withDrupalOauthConsumer'; class SignIn extends Component { constructor(props){ super(props); this.handleSubmit=this.handleSubmit.bind(this); } state = { processing: false, username: '', password: '', error: null, }; handleSubmit = () => { event.preventDefault(); this.setState({ processing: true }); const { username, password } = this.state; if(!username && !password) { this.setState({ processing: false }); this.setState({error: "User name and password doesn't exist"}) } else { this.props.drupalOauthClient.handleLogin(username, password, '').then((res) => { localStorage.setItem('username', JSON.stringify(username)); if(res !==undefined){ this.setState({ open: false, processing: false }); this.setState({ error: 'You are now logged in'}); this.props.updateAuthenticatedUserState(true); setTimeout(() => { document.location.href="/"; }, 3000); } else { this.setState({ processing: false }); this.setState({error: "User name and password doesn't exist"}) } }); } }; render() { const { error, processing } = this.state; return ( Login Now! {error &&


} username this.setState({ []: }) } /> {errors.password &&


} Password this.setState({ []: }) } /> { processing ? FaSpinner : Login } ); } } export default withDrupalOauthConsumer(SignIn);

When you submit the form Drupal will take care of generating the OAuth token and return it to you. To check this you can wrap your component with DrupalOAuthConsumer, and check via the props.userAuthenticated.

To understand in-depth how the code works. You can follow this link.

One thing to note here is that the above code does not take into account the user login on Drupal end. So to be able to log in on Drupal end add the drupalLogIn code to your drupalOauth.js file and call it inside the fetchOauthToken function. So that every time user tries to log in on Gatsby end, user session get’s initiated on Drupal end as well.

/** * Login request to Drupal. * * Exchange username and password. * @param username * @param password * @returns {Promise} * Returns a promise that resolves to JSON response from Drupal. */ const drupalLogIn = async (username, password) => { const response = await fetch(loginUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ name: username, pass: password, }), }); if (response.ok) { const json = await response.json(); if (json.error) { throw new Error(json.error.message); } return json; }

Remember we are only taking into account the login functionality here. If you are trying to implement the logout functionality as well, make the below piece of code work same as login.

/** * Logout request to Drupal. * * Logs the user out on drupal end. */ const drupalLogout = async () => { const oauthToken = await isLoggedIn(); const logoutoken = oauthToken.access_token; if (logoutoken) { const res = await fetch(`${process.env.GATSBY_DRUPAL_ROOT}/user/logout?_format=json`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${logoutoken}`, }, }); if (res.ok) { return true; } } };

Also, take into account that drupalOauth.js is a class service. So drupalLogin and drupalLogout are the implementation of a class and need some modifications.

Authenticated Commerce Cart

Now that our user is logged in and registered, our next step is to post the data to our commerce cart.

If you go through the commerce cart API documentation. It explains how commerce cart API module works. To post data to the cart as an authenticated user you must be logged in. Once you are logged in. We can POST, GET, UPDATE our cart. Go through below code. Which is fairly simple to understand. We are just taking the access token generated by simple OAuth from Drupal end on login that we have already stored in our browser local storage and sending it as a bearer token as part our request header to the Drupal end so it can recognise that the user is Authenticated.

import axios from 'axios'; const TokenGenerator = require('uuid-token-generator'); const url = process.env.GATSBY_CART_API_URL; class CartService { getCartToken() { const tokgen = new TokenGenerator(); const oauthToken = JSON.parse(localStorage.getItem('drupal-oauth-token')); var myHeaders = new Headers(); let cartToken = ''; if(!oauthToken) { cartToken = (localStorage.getItem('cartToken') !== null) ? JSON.parse(localStorage.getItem('cartToken')) : tokgen.generate(); myHeaders.append('Commerce-Cart-Token', cartToken); myHeaders.append('Content-Type', 'application/json'); localStorage.setItem('cartToken', JSON.stringify(cartToken)); } else { cartToken = oauthToken.access_token; localStorage.setItem('cartToken', JSON.stringify(cartToken)); myHeaders.append('Authorization' , `Bearer ${cartToken}`,); myHeaders.append('Content-Type', 'application/json',); } return myHeaders; } getCartItem = async () => { const header = await this.getCartToken(); const res = await fetch(`${url}cart?_format=json`, { method: 'GET', headers: header }); const cartData = await res.json(); return cartData; } addCartItem = async (id, quantity) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/add?_format=json`, { method: 'POST', headers: header, body: JSON.stringify([{ purchased_entity_type: 'commerce_product_variation', purchased_entity_id: id, quantity: quantity }]) }) const data = await res.json(); return data; } updateCartItem = async (quantity, order_item_id, order_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items/${order_item_id}?_format=json`, { method: 'PATCH', headers: header, body: JSON.stringify({ "quantity": quantity }) }) const data = await res.json(); return data; } removeCartItem = async(order_id, order_item_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items/${order_item_id}?_format=json`,{ method: 'Delete', headers: header, }) if (res.status == 204) { const data = await this.getCartItem() return data; } } removeCart = async(order_id) => { const header = this.getCartToken(); const res = await fetch(`${url}cart/${order_id}/items?_format=json`,{ method: 'Delete', headers: header, }) if (res.status == 204) { const data = await this.getCartItem() return data; } } } const CartHandler = new CartService(); export default CartHandler;

This will allow you to post the cart data as an anonymous user when you are logged in as well as authenticated user once you are logged in. (Add uuid-token-generator) to your packages to make it work.

To add a product to your cart you can simply import the CartService class into your component and use it as :

import CartHandler from '../Services/CartService'; CartHandler.addCartItem(variationId, quantity);

This is it. Cheers! We are done here. We have been able to successfully register the user, authenticate the user and post data to our commerce cart.

P.S -  If you face any issues. Kindly mention in the comments.


Danish Shah Thu, 04/23/2020 - 18:59

1xINTERNET blog: The Drupal heart is beating strong

Planet Drupal - Thu, 2020/04/23 - 11:14am
The Drupal heart is beating strong hadda 2020-04-23 - 11:14 Category Drupal Planet Drupal 22. April 2020

Yesterday was a good day for the Drupal community, because it very clearly showed how much power can be released when we stick together

The world has been upside down the last few weeks because of the COVID-19, affecting individuals and businesses around the world. To meet unforeseen financial troubles due to the cancellation of DrupalCon Minneapolis, the Drupal association reached out to the community for help. 


Viral donations for the Drupal Association 

#DrupalCares went viral where individuals and companies were encouraged to help the Drupal Association with donations.

Last week Dries and Vanessa Buytaert announced that they would match individual donations up to $100k which then lead to a group of dedicated business leaders in the Drupal ecosystem coming together and deciding to match for another $100k

That means that every $1 donation will become $3. Now that's what I call a positive viral affect! 

1xINTERNET supports the Drupal project

1xINTERNET has always been a driving force when it comes to supporting the Drupal project and the Drupal Association, and therefore we didn’t think twice about taking part. Our whole team is deeply dedicated and I'm so proud of our employees at 1xINTERNET that also donated individually to the project.

Here we are in a powerful group of companies that today announced that together they will match individual #DrupalCares contributions for another $100,000, because we believe in the power of Drupal. We all have the same goal, to see Drupal thrive and grow and continue to be the force it is. 


It made my day to receive these positive news about the power of the Drupal community and what we are capable of. Last August I wrote a blogpost about Contributing to Open Source where I highlighted my opinion of the importance of being an active member in our community. I'm now more convinced of how important it is and I'm pretty sure a lot of you agree with me.

#DrupalCares Challenge

We see the purpose highlighted at this time when online presence has never been as important with the world physically shutting down around us. Drupal provides infrastructure for many public health organizations and health care systems that now are delivering information about the COVID-19 pandemic situation to millions of people as well as many Higher Educational websites providing important information to students all over the world.

I encourage you to take part and keep the Drupal heart pumping.

See all information about the status of the #DrupalCare project, its not too late to visit the  donation  page and take part.


Gábor Hojtsy: First week's update on the Drupal 9 Module Porting Challenge; organising a porting day on April 28, 2020

Planet Drupal - Thu, 2020/04/23 - 9:40am

I launched the Drupal 9 Module Porting Challenge a week ago, and wow it is going well! I pledged to donate €9 for each newly Drupal 9 compatible project to the #DrupalCares campaign up to a total of €900. Since then Ron Northcutt joined on April 20 with another €900 and Ofer Shaal joined on April 21 with another €450, so the challenge now goes to a total of €2250! Our donation will potentially be matched by Dries and Vanessa Buytaert and then a group of organisations will match it again for a potential total of €6750 donated.

State of the challenge

After a week, my original budget is almost spent, so I am preparing to donate it tomorrow! Let's make Ron and Ofer donate their whole pool as well! We are standing at €837 of €2250 covered by 93 newly Drupal 9 compatible projects in one week.

According to our static analysis at least, over 3600 projects only need a single line info.yml file change and a new release. It is worth checking if one of your projects are in there so we don't let Ofer and Ron keep their money either! ;)

Porting day on April 28, 2020

Some projects will admittedly not be as easy as a one line change though, so I am organising a Drupal 9 porting day for April 28, 2020. I commit to be available in European times to consult on fixing deprecation issues and would love to see you there! Let's meet online in the #d9readiness channel on Drupal slack ( We'll use slack threads to discuss projects to help coordinate the work. We may use other tools as needed to speed up the process, still exploring the possibilities. Stay tuned! For now, if you can be available for even one hour, you are welcome to join!

Categories: Blog: Owen Lansbury, co-founder of PreviousNext: DrupalSouth, running code sprints in the sun & GovCMS

Planet Drupal - Thu, 2020/04/23 - 8:23am

A co-founder of PreviousNext and a member of the Drupal Association Board of Directors, Owen Lansbury is a key figure in the Drupal world, with his company also largely responsible for the mass adoption of Drupal in the Australian government. Find out more about Owen's journey with Drupal in our interview.


OSTraining: How to Create a Bartik Subtheme in Drupal 8

Planet Drupal - Thu, 2020/04/23 - 6:00am

Subthemes inherit the theme resources of their parent theme. If you want to build your site with Bartik, which is the default theme in a Drupal installation, you will have to create a subtheme. That way, you can make CSS, JS or template overrides to the subtheme, without having to worry about losing those changes when the parent theme gets updated.

Keep reading to learn how!


Tandem's Drupal Blog: Altering Views Ajax in Drupal 8

Planet Drupal - Thu, 2020/04/23 - 2:00am
April 23, 2020 A straight forward guide on how to have your JavaScript fire after each Drupal 8 Views AJAX call is made. Overview We have a client that had a unique situation with one of their views exposed filters setup. We had a set of checkboxes with a set of corresponding images (that were checkboxes with images for labels) that could also ...
Categories: A Guide to Loading External JavaScript in Drupal

Planet Drupal - Wed, 2020/04/22 - 7:49pm
Better understand the approaches to add external JavaScript dependencies to your Drupal theme, project, or custom module.

Lullabot: When to Upgrade from Drupal 8 to Drupal 9

Planet Drupal - Wed, 2020/04/22 - 6:16pm

As the release of Drupal 9 approaches, organizations are starting to think about when to upgrade to Drupal 9. Quick Drupal adoption isn't automatic. Historically, it's taken years for some significant Drupal versions to gain traction. With a relatively short window between the Drupal 9 release and Drupal 8's end-of-life, however, organizations must move more quickly to adopt Drupal 9 or make other arrangements.


Dcycle: Deploying Drupal to Kubernetes, no previous knowledge required

Planet Drupal - Wed, 2020/04/22 - 4:27pm

Kubernetes is a way of deploying resilient, scalable applications to the cloud.

  • Resilient because Kubernetes is designed to recover if something goes wrong.
  • Scalable because with Kubernetes, your application is not linked to a single virtual machine (VM), but rather to a cluster of VMs which you can scale up or down transparently.

What Kubernetes is not is a magic bullet. Before investing too much in Kubernetes, you are encouraged to read “Let’s use Kubernetes!” Now you have 8 problems, by Itamar Turner-Trauring, Python Speed, March 4th, 2020.

In this article, we will create a Kubernetes cluster and deploy a minimum viable Drupal installation to it, with the following features (this list will be our success criteria at the end of this article):

  • Minimal vendor lock-in: we will avoid vendor-specific resources such as database and volume storage where possible, prefering our own containers.
  • Deployment of Drupal alongside other applications: we will deploy applications other than Drupal to demonstrate how your Drupal app can coexist nicely on a Kubernetes cluster.
  • Secret management: Your Drupal application probably has secrets: environment-specific information such as API keys, or database passwords which should not be in the codebase. We will see how to manage these in Kubernetes.
  • LetsEncrypt: We will serve our different cluster applications via HTTPS using an Nginx reverse proxy, with set-it-and-forget-it automatic certificate renewals.
  • Volumes: Our Kubernetes applications will store their data in volumes which can be backed up. In the case of Drupal, the MySQL database and the /sites/default/files directory will be on volumes. All application code will be on containers, as we will see later.
  • Automation of incremental deployments: deployment should generally be as automated as possible; most modern applications see deployments to production several times daily. In the context of this tutorial we are not recommending Kubernetes on production just yet, but rather to serve development environments; the performance and security concerns related to Kubernetes on production are outside the scope of this article, and frankly at the time of this writing I haven’t yet used Kubernetes on production myself.
  • Easy local development: although having a local version of Kubernetes is possible, it can make your laptop really, really hot. We will use Docker and docker-compose rather than Kubernetes to develop our code locally.
  • Branch staging environments: we will spin up environments per GitHub branch and destroy the environments when the branch gets deleted.

Notice that I haven’t gotten into the jargon of Kubernetes: nodes, pods, deployments, services; for me this has taken a while to get my head around, so my approach in this article will be to introduce concepts only as we need them. You can always refer to the glossary at the end of this article if you’d like quick definitions.

This tutorial is presented in several sections for your convenience:

Kubernetes is a way of deploying resilient, scalable applications to the cloud.


Mediacurrent: Updating Drupal 8 Modules to Drupal 9

Planet Drupal - Wed, 2020/04/22 - 1:23pm

Drupal 9 is rapidly approaching with a release planned, at the time of writing this blog, of June 3, 2020. In addition to much anticipated updates to core (use of Symfony 4.4), there also comes the removal of a ton of deprecated code. This blog will help you prepare for Drupal 9 with answers to your most pressing questions like:

  • Why is code being deprecated? 

  • How will the release of Drupal 9 affect my site? 

  • What's the best way to update a Drupal contrib module to work with Drupal 9? 

Deprecating Code

What is deprecated code? Simply put, code becomes depreciated when it is no longer the best way to achieve the original goal. We deprecate code instead of outright deleting it to provide backwards compatibility and to make sure we don’t release code that breaks sites.

If you have spent any time programming in Drupal 8, I am sure you have found yourself using strategies available to you in Drupal 7, take Node::load() for example. If you go to the API docs you will see a warning that this method is deprecated and will be removed in Drupal 9. Under the hood, Node::load() uses the Drupal 8 EntityTypeManager to get the node storage and load it which is the accepted way to do it. Deprecating and removing deprecated code should be seen as a healthy sign of an open source project as it proves progress is being made to keep it fresh with the latest best practices. 

How This Will Impact You

What does this mean for module developers and site maintainers? Fortunately, if your site works for Drupal 8.9.x it will work for 9.x as the only change between the releases is the removal of deprecated code. After updating to 8.9.x, you’ll want to update each contrib module currently installed on your site. Even so, the best way to be 100% confident your site is Drupal 9 ready is to use the drupal checker command line tool to scan your custom and contrib code. 

How to Install and Run Drupal-Check  

To run the drupal checker  on your project, use composer to install it, and run it in the directory you want to scan:

composer global require mglaman/drupal-check cd path/to/module/to/test drupal-check *

This will print a report that you can share with your internal development team, or if it is in regards to a contrib module, make a patch and fix it yourself.

Making a Contrib Module Ready for Drupal 9

Now that we know about the awesome drupal-checker CLI tool, we are going to use it to make sure one of our favorite modules, YAML Content, is Drupal 9 ready. YAML content already has an open Drupal 9 readiness issue, but if you have to create a new one, the issue should look something like this:

Note how we’ve added the project name to the title and added the issue tag of “Drupal 9 compatibility”, this will make it easier to find in the issue queue.  

If you are new to contributing or just looking for an easy way to set up a local development environment, take a look at my previous blog, Get Drupal 8.6 Running Locally in 5 Steps.  

These are the steps we are going to follow:

  1. Start with Drupal 8.8.x or 8.9.x
  2. Install/update drupal-check:
  3. $ composer global require mglaman/drupal-check
  4. Download module using git:
  5. $ git clone
  6. Run drupal-check:
  7. $ drupal-check *
  8. Update the info.yml file(s) (remember that some projects include more than one module!) by removing the “core:” line and adding this one in its place:
  9. core_version_requirement: ’^8 || ^9’
  10. Fix all deprecations that are reported.
  11. Upload patch(es).

Drupal-check will print out the file, line number, deprecation message and the total number of errors. At this time, we have 11 errors for yaml_content:

Writing a Patch to Fix Deprecated Code

While patching the issue it is important that we follow best practices and use dependency injection rather than calling the drupal service container. Luckily this patch has two different examples of dependency injection, one via service.

yaml_content.service.yml services: ... yaml_content.load_helper: class: Drupal\yaml_content\Service\LoadHelper arguments: - '@yaml_content.content_loader' - '' - '@string_translation' - '@file_system' - '@messenger' src/Service/LoadHelper.php /** * @var \Drupal\Core\Messenger\MessengerInterface $messenger * The messenger. */ protected $messenger; /** * Constructs the load helper service. * * @param \Drupal\yaml_content\ContentLoader\ContentLoaderInterface $content_loader * The content loader service to use for content imports. * @param \Drupal\Core\Logger\LoggerChannelInterface $logger * The logging channel for recording import events. * @param \Drupal\Core\StringTranslation\TranslationInterface $translation * String translation service for message logging. * @param \Drupal\Core\File\FileSystemInterface $file_system * The file system. * @param \Drupal\Core\Messenger\MessengerInterface $messenger * The messenger. */ public function __construct(ContentLoaderInterface $content_loader, LoggerChannelInterface $logger, TranslationInterface $translation, FileSystemInterface $file_system, MessengerInterface $messenger) { $this->loader = $content_loader; $this->logger = $logger; $this->fileSystem = $file_system; $this->messenger = $messenger; $this->setStringTranslation($translation); }

This allows us to replace drupal_set_message() with $this->messenger->addMessage().

For an example of dependency injection within a plugin, take a look at File.php in the patch attached to the issue.

While preparing modules for Drupal 9 readiness it is equally important to update the tests. The drupal-check command found failures in the test files but that is only for known existing deprecation in Drupal8 and PHPUnit 4, not the new dependency injection we added. We’ve touched LoadHelper.php and File.php which both have tests.  If you are unfamiliar with writing automated tests, there’s no better time to learn than now. However, it is my opinion that you push up the patch first and tag the issue with needs review. This will kick off the tests on and you may get help writing tests from the community. 


In this blog we’ve reviewed why Drupal 9 is removing deprecated code, how to create an issue for a contrib module, how to install and run drupal-check and how to write a patch to fix deprecated code. Now is the best time to start testing and getting your site ready for Drupal! Here are some extra resources that may help you get you started:


Agaric Collective: Going online together to save our lives

Planet Drupal - Tue, 2020/04/21 - 7:36pm

Anthropologist Kasey Qynn Dolin noted of our societal moment that COVID-19 has thrown into sharp relief:

We expected going online would lead to mass democratization and access to information that empowers large groups of people.

Instead, we got outsourced.

Online connectivity gave people who own means of production the ability to outsource work in a way that offloads expenses— the cost of the things which generate the conditions for the wealthy and powerful to profit in the first place. Some of this, like shifting the expenses of maintaining fleets of vehicles off of a corporation's balance sheet, have been celebrated as technology-enabled innovations in business models. This is usually a big charade, a technological gloss on what is just another, relatively minor, attempt to concentrate wealth and power. Meanwhile, the biggest return on capital and the biggest harmful effects on people come from practices that business media don't focus on.

The world going online has helped the owning class shift the costs of workers simply living (health care, child care, retirement, sustenance or more-than-sustenance wages) onto people, communities, and whole nations less able to hold global corporations to account.

There are a couple big reasons this happened.

First, technology is not neutral, and it tends to serve the needs of those who shape it.

Even with the incredible historical happenstance of US military money flowing to academic researchers who developed and incubated an Internet that was computer-to-computer rather than hierarchical…

…and even with the impressive tradition of technologists making decisions openly and favoring adopting standards by rough consensus that allow unaffiliated parts to work with one another…

…the services built on the Web and other Internet-based protocols and standards reflect the desire for control (for wealth and power) held by corporations, governments, and venture capitalists— because these are the entities that have been spending the money and increasingly calling the shots for the past twenty years.

Second, the same reason a miracle was required to make the Internet distributed in the first place has worked against many of the technology built on the Internet being peer-to-peer— it's hard to come to agreement on protocols and hard to make them easy to use. It's easier to build software and services ultimately within one organization's control, and the organizations with the resources to do even this have tended to be the same ones centralizing power (with notable exceptions such as Wikipedia and the Internet Archive).

Similarly to networked computers, in the world of organized humans it's very hard to develop ways to build shared power. It is much easier to use communications technology to move work and consequences farther from those who already hold centralized power.

However, these facts working against us don't mean we have to take our struggle for our human rights and justice entirely offline. And struggle we must, because the people who hold wealth and power now are seeing, in this health and economic crisis, just how much can be denied us without threatening their wealth and power.

A lot of the technology developed for business as usual, even the proprietary stuff we don't actually control like Slack and Google Docs, can be put to use by movements for justice and liberty. There are a lot of similarities in what people need to work together, whether it's in companies or in community groups. That's not to say that the movement to build truly free as in freedom alternatives to these is not good and important. Indeed, the development of free libre open source software is downright great and vital when led by or done in direct collaboration with groups marginalized by capitalism that do have different needs, such as a threat model that must take into account government repression and fascist threats.

But we need to concentrate our finite time on building technology corporate and political masters would never want built.

We need to focus on that which builds shared power. We need to build ways to share power.

Power is organization. People organized in large groups can hold even global corporations to account. We can replace existing structures, as proves needed, to gain the sustenance needed for life; to gain the justice of a common share of all that nature has given and all that humanity has worked for; and to gain the freedom to do what we will with it all.

Any group with that level of power is unlikely to keep true to universal human rights and and all the rest unless power stays distributed within it— ideally throughout all society.

Formal democracy, however flawed or perfected, has never been enough and will never be enough.

We need ways of communicating and making decisions that work well and keep power distributed.

Sharing the power inherent in controlling communication and in making decisions requires sharing the work of both.

There's endless creativity required in getting people to see a better world is possible, and infinite strategy needed to achieve it. Thinking about how to share power while building power is necessary, but it is too much to have to figure out from scratch while doing everything else. It's as unrealistic to expect every group of people who give a damn to craft tech for mass democracy and distributed power as it is to expect every group of people to make their own word processing and web publishing software .

Which is why we need to build online tools for sharing the power that organizing gives us.

One indispensable piece, unsolved in practice but in theory solvable technically, is distributing the power of coordinated messaging. Coordinated messaging, in turn, is the root of both collective decision-making and coordinating action.

A person who is part of a movement has a piece of information they think every person in the movement should know, or that they think should be spread as widely as possible to the public. They have have to go through some process that is the same for everybody, such as getting any two people in the movement to approve the content and crafting of the message. Then the proposed communication goes not to a standing committee but to a small group of people randomly drawn from the movement and asked to decide if it's something everybody should see now, or not.

That's the technology I want to build to make us all going online finally lead to mass democratization and power for all people over their own lives.

Join me.

Read more and discuss at


Dries Buytaert: A 2-for-1 match for Drupal Association donations

Planet Drupal - Tue, 2020/04/21 - 6:22pm

Last week, Vanesssa and I pledged to match $100,000 in individual contributions to the Drupal Association.

Then today, 29 organizations in the Drupal community pledged another $100,000 to match Vanessa's and my pledge!

For every $1 you donate, the Drupal Association now gets $3. 🚀

So far 700 people have contributed roughly $72,000 to #DrupalCares. Because both matching gifts apply to all individual donations or memberships from the start of the campaign, we're up to $216,000 (3 x $72,000).

It's been heartwarming to see that so many have stepped up to provide support.

The various creative responses have also been amazing. One of my favorite examples is Gábor Hojtsy's: Gábor will donate €9 for every Drupal module that gets updated to Drupal 9. Best of all, his €9 donation will also be matched 2-for-1. For every module that gets updated in the next two weeks, €27 could get fundraised for the Drupal Association. Since Gábor announced his challenge 5 days ago, 65 modules have been updated already. It raises money for the Drupal Association and it helps the Drupal community prepare for the Drupal 9 release later this year. Such a clever idea and what a difference it can make!

Thank you again to all of the individuals and organizations who have graciously donated to the Drupal Association so far. Every contribution matters and means so much! We hope those of you reading this will join us in donating or launching creative campaigns.


Promet Source: County and Municipal Websites: The New Town Square

Planet Drupal - Tue, 2020/04/21 - 6:10pm
Covid-19 has upended daily life, and in many cases, revealed trends that were a long time in the making.   Work-at-home requirements brought the essential need for online connections and services to the forefront.    More so than ever before, county and municipal government websites serve as a virtual town square and the place for: