Planet Drupal

Subscribe to Planet Drupal feed - aggregated feeds in category Planet Drupal
Updated: 20 hours 46 min ago

Hook 42: Drupal Core Initiative Meetings Recap - October 21 - 25, 2019

28 October 2019 - 10:21am
Drupal Core Initiative Meetings Recap - October 21 - 25, 2019 Lindsey Gemmill Mon, 10/28/2019 - 17:21
Categories: Drupal

Acro Media: Drupal Commerce Checkout: An Example of Being Headless Ready

28 October 2019 - 7:45am

Drupal Commerce 2, like Drupal 8, was a big change from previous versions. The code base is much different and it’s quite a learning curve when moving from Drupal 7 to the more complex approaches in Drupal 8. However, this is good. The new versions are modern and all around better. I’ve had a number of revelations while working with Drupal Commerce 2 and Drupal 8 that made me smile. In this post, I’ll explore one revelation I had while working with Drupal Commerce 2’s checkout handling and how it’s forward-thinking development has paved the way (and encourages all new checkout panes to follow suit) for headless ecommerce using Drupal.

Drupal Commerce 2 checkout is not a form… say what!?

Generally, when you think of checkout, you think of it as a sequence of events and one big final submission. This is further driven home by the idea that you can, and should, be able to go back and edit your checkout choices before the final submission. In Drupal Commerce 2, going back and forth between checkout steps is supported, but there is no final submission handler that saves everything.

Wait, what? That’s right, there’s no need to save all the data on the checkout form once checkout is completed. You see, all checkout panes (a step in the checkout process) have a submission event that gets called when it's time to save the data. So if you’re going to save data in a checkout pane, you gotta do it after your customer has moved forward in the checkout process but before your customer is ready to commit to the checkout pane’s final value state (complete checkout). Submission is perceived to be at the end of checkout, not before.

On the surface that might make sense, in fact, this workflow being so obvious might even blind you to the implications. Since each pane is basically handling its own submission workflow, you can’t allow your form state to persist choices and not make a decision until the end. You’re probably, like me, thinking that saving data and reacting to data is the same thing. But this assumption is old, out of date, incompatible with best practices, and in checkout for Commerce 2, causes design problems.

Explanation through an example: A checkout newsletter subscription

A common want is to include a little checkbox underneath a contact information email field where new or returning customers can opt-in to a newsletter. Sure, that’s no big deal, right?

Our customer expects that things in checkout aren’t real until they complete checkout (i.e. nothing is saved until they actually place the order). On the other hand, Drupal Commerce 2 expects all panes to save their data after a “continue to next-step” button gets clicked, submitting that pane.

Here’s how the checkbox would be made using our current form submission logic:

  1. Create a CheckoutPaneBase object that collects data through a checkbox
  2. On the pane form submission, subscribe the customer to your newsletter

Do you see the problem? If we react on pane submission (our only choice in our current way of thinking), we’ll subscribe the customer to our newsletter well before they are done with checkout. In fact, each time they see the first page of checkout and proceed to the second, they will be subscribed to our newsletter. Not only is this not what the customer would expect, but subscribing them multiple times is totally unnecessary and would likely cause problems. Subscribing the customer on pane form submission is the wrong approach.

This is where things get really trippy – and awesome and beautiful and wonderfully clever and great. You see, Drupal 8, which Commerce 2 is built around, has been designed to not require forms, form states and value persistence in order to trigger important actions. This is a whole new way of thinking and maybe the most important to our discussion. Previous to this, most Drupal 7 developers would have assumed that all forms require user-facing interfaces that would be submitted, but that is a pretty brutal assumption and has plagued a lot of Drupal installations over the years. If that was still the case, then form submissions are something that headless implementations of Drupal would never really trigger. There must be a better way.

Headless decoupling breeds better code using events

If checkout was a single form with a final submission handler that submitted payment, subscribed users to newsletters, saved addresses to profiles, and did all the things you would expect all at once, then all the code that manages these things would have to react to a single form submission.

However, if we use Drupal's built in event system instead, we suddenly have much greater degree of control. But before we get into that, let’s first take a quick look at what events are and where they come from.

Drupal 8 made a big shift towards being object oriented by adopting Symfony within its framework. Symphony provides a number of components useful in modern object oriented programming, one of which is events. Events in Drupal 8 give developers a new way to extend and modify how interactions with core and other modules work. If you’re already familiar with Drupal 7, events are basically meant to replace hooks. Drupal 8’s event system documentation helps us to understand the basic concepts and components making up the event system.

  • Event Subscribers - Sometimes called "Listeners", are callable methods or functions that react to an event being propagated throughout the Event Registry.
  • Event Registry - Where event subscribers are collected and sorted.
  • Event Dispatcher - The mechanism in which an event is triggered, or "dispatched" throughout the system.
  • Event Context - Many events require specific set of data that is important to the subscribers to an event. This can be as simple as a value passed to the Event Subscriber, or as complex as a specially created class that contains the relevant data.

Source: documentation, Subscribe to and dispatch events (link)

Getting back to our checkout scenario, if you use the events system and your checkout completion is simply a state transition from Draft to Completed, then other modules could subscribe to that transition event, take the saved data from the different pane submissions, and do whatever they want with it.

Do you see the beauty here? By forcing checkout panes to submit before the final submission, we (module builders, implementers, etc.) have a baked-in reason to store checkout decisions on the order so that order events can access them separately, giving us the ability to create orders with checkout decisions saved that can skip checkout completely and still have the events trigger the needed actions. This is quite powerful and opens up a whole new world of possibilities. Of course, since this is an implicit design choice, it’s up to the author of the module or code to see the reasons and embrace them.

Entity + event-based instead of form-based

So to complete our newsletter subscription pane example using our new knowledge of events instead of form submissions, here’s what we would do:

  1. Create a CheckoutPaneBase object that collects data through a checkbox and saves it to the order (either through a field value or the ->setData typed data interface.
  2. Save this value on pane submission but don’t act on the value (i.e. don’t subscribe the user)
  3. Create an event subscriber and use the transition event you want to use as a trigger. Completing checkout makes the most sense.
  4. Treat the order value as a "request subscription to newsletter." Then, when the event fires and the event subscriber runs, it can look for the saved value and set the user to subscribed or not after it returns. This allows us to handle someone going through an event twice for some reason, like for multiple orders, etc.

Your customer gets subscribed to your newsletter when they, and you, expect them to. No forms needed. ISN’T THAT AMAZING!

Thanks to the many authors of Drupal Commerce 2, including Bojan Živanović and Matt Glaman, that implemented this design choice years ago, many modules and implementations are simply technically better and likely ready for headless implementations now that headless is all-the-rage.

And best of all, from a developer standpoint, this also means the bulk of your most critical automated tests that interact with your code doesn’t have to access the checkout form. They simply have to have orders that get transitioned. This makes writing tests, which equates to better code, simpler.

Your Drupal Commerce experts

As a full service Drupal agency, Acro Media has significant expertise in digital commerce architecture, ecommerce consulting and design, customer experience, Drupal development and hosting architecture. We would love the opportunity to work with you.

Categories: Drupal

Spinning Code: Salesforce Queries and Proxies in Drupal 8

28 October 2019 - 7:04am

The Drupal 8 version of the Salesforce Suite provides a powerful combination of features that are ready to use and mechanisms for adding custom add-ons you may need.  What it does not yet have is lots of good public documentation to explain all those features.

A recent support issue in the Salesforce issue queue asked for example code for writing queries. While I’ll address some of that here, there is ongoing work to replace the query interface to be more like Drupal core’s.  Hopefully once that’s complete I’ll get a chance to revise this article, but be warned some of those details may be a little out of date depending on when you read this post.

To run a simple query for all closed Opportunities related to an Account that closed after a specific date you can do something like the following:

$query = new SelectQuery('Opportunity'); $query->fields = [ 'Id', 'Name', 'Description', 'CloseDate', 'Amount', 'StageName', ]; $query->addCondition('AccountId', $desiredAccountId, '='); $query->conditions[] = [ "(StageName", '=', "'Closed Won'", 'OR', 'StageName', '=', "'Closed Lost')", ]; $query->conditions[] = ['CloseDate', '>=', $someSelectedDate]; $sfResponse = \Drupal::service('salesforce.client')->query($query);

The class would need to include a use statement for to get Drupal\salesforce\SelectQuery; And ideally you would embed this in a service that would allow you to inject the Salesforce Client service more correctly, but hopefully you get the idea.

The main oddity in the code above is the handling of query conditions (which is part of what lead to the forthcoming interface changes). You can use the addCondition() method and provide a field name, value, and comparison as lie 10 does. Or you can add an array of terms directly to the conditions array that will be imploded together. Each element of the conditions array will be ANDed together, so OR conditions need to be inserted the way lines 11-14 handle it.

Running a query in the abstract is pretty straight forward, the main question really is what are you going to do with the data that comes from the query. The suite’s main mapping features provide most of what you need for just pulling down data to store in entities, and you should use the entity mapping features until you have a really good reason not to, so the need for direct querying is somewhat limited.

But there are use cases that make sense to run queries directly. Largely these are around pulling down data that needs to be updated in near-real time (so perhaps that list of opportunities would be ones related to my user that were closed in the last week instead of some random account).

I’ve written about using Drupal 8 to proxy remote APIs before. If you look at the sample code you’ll see the comment that says: // Do some useful stuff to build an array of data.  Now is your chance to do something useful:

<?php namespace Drupal\example\Controller; use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\Cache\CacheableJsonResponse; use Drupal\Core\Cache\CacheableMetadata; class ExampleController extends ControllerBase { public function getJson(Request $request) { // Securely load the AccountId you want, and set date range. $data = []; $query = new SelectQuery('Opportunity'); $query->fields = [ 'Id', 'Name', 'Description', 'CloseDate', 'Amount', 'StageName', ]; $query->addCondition('AccountId', $desiredAccountId, '='); $query->conditions[] = [ "(StageName", '=', "'Closed Won'", 'OR', 'StageName', '=', "'Closed Lost')", ]; $query->conditions[] = ['CloseDate', '>=', $someSelectedDate]; $sfResponse = \Drupal::service('salesforce.client')->query($query); if (!empty($sfResponse)) { $data['opp_count'] = $sfResponse->size(); $data['opps'] = []; if ($data['opp_count']) { foreach ($sfResponse->records() as $opp) { $data['opps'][] = $opp->fields(); } } } else { $data['opp_count'] = 0; } // Add Cache settings for Max-age and URL context. // You can use any of Drupal's contexts, tags, and time. $data['#cache'] = [ 'max-age' => 600, 'contexts' => [ 'url', 'user', ], ]; $response = new CacheableJsonResponse($data); $response->addCacheableDependency(CacheableMetadata::createFromRenderArray($data)); return $response; } } Cautions and Considerations

I left out a couple details above on purpose. Most notable I am not showing ways to get the needed SFID for filtering because you need to apply a little security checking on your route/controller/service. And those checks are probably specific to your project. If you are not careful you could let anonymous users just explore your whole database. It is an easy mistake to make if you do something like use a Salesforce ID as a URL parameter of some kind. You will want to make sure you know who is running queries and that they are allowed to see the data you are about to present. This is on you as the developer, not on Drupal or Salesforce, and I’m not risking giving you a bad example to follow.

Another detail to note is that I used the cache response for a reason.  Without caching every request would go through to Salesforce. This is both slower than getting cached results (their REST API is not super fast and you are proxying through Drupal along the way), and leaves you open to a simple DOS where someone makes a bunch of calls and sucks up all your API requests for the day. Think carefully before limiting or removing those cache options (and make sure your cache actually works in production).  Setting a context of both URL and User can help ensure the right people see the right data at the right time.

Categories: Drupal Blog: Why creative agencies should partner with a development agency

28 October 2019 - 2:41am

In this post, we’ll dive into the main benefits for creative and design agencies of partnering with a skilled and reliable development agency as opposed to taking care of all their dev work in-house. 

Categories: Drupal

Symphony Blog: Speed up your Drupal 8 sites with image lazy loading

28 October 2019 - 1:43am

Recently, we involved in a local project with It is a directory of restaurants, cafes, entertainments, services, real properties ... in Ecopark Hanoi, Vietnam. This site is based on our best selling directory theme BizReview.

On this site, there is a page which lists all kindergartens around the area. It has 20 listings and will continue to grow. It is a very typical page built with Drupal views.

read more

Categories: Drupal

Centarro: Launching Centarro Support at DrupalCon Amsterdam

27 October 2019 - 8:09pm

We shared our thoughts about eliminating barriers to Drupal Commerce growth earlier this year in response to a blog series by Drupal project lead Dries Buytaert. We laid out a roadmap that included closing the feature gap with our competitors and finding ways to better reach and support end users of our software. We've addressed the feature gap through numerous module releases since then, and we're launching the next phase, Centarro Support for Drupal Commerce developers and teams, here at DrupalCon Amsterdam.

Categories: Drupal

Love Huria: Understanding Time complexity - Big O Notations

25 October 2019 - 5:00pm

Lately, I have gotten an interest in algorithms, the first one I chose to understand deeply is how sorting algorithms work and their time complexity. However, this post is not to explain sorting algorithms, instead, we will take a step back and understand time complexity [Big O Notation] in the simplest way possible.

Before we go any further, let’s understand what is an Algorithm:

An Algorithm is a step by step instruction, telling a program to execute in a certain way to solve a particular problem. And it’s pretty obvious, that when we run a program in any language,...

Categories: Drupal

Drupal Association blog: Meet us at Booth 3 at DrupalCon Amsterdam

25 October 2019 - 12:05pm

Our staff will be at Booth 3 ready to talk with you about the Drupal community, how you can get more involved as a contributor, and to hear about your needs. 

Make sure you....

✓ pick up some Drupal stickers

✓ show your support by signing up for membership or partner programs

Session highlights
  • Tuesday at 16h15, in G107, attend the Drupal Association Townhall with our Executive Director Heather Rocker (hrocker), CTO Tim Lehnen (hestenet), and our Board Chair Adam Goodman (adamgoodman). We'll be taking questions and diving into topics important to the community.
  • Wednesday at 11h30, in G107, we're holding our public board meeting. All are welcome to attend!
  • Also on Wednesday, if you're curious about what the Engineering Team is working on, come to the Infrastructure Update session in G103 at 17h15.

See you soon!

Categories: Drupal

Hook 42: Hook 42 Earns Five Stars in First Review on Clutch

25 October 2019 - 10:00am
Hook 42 Earns Five Stars in First Review on Clutch Lindsey Gemmill Fri, 10/25/2019 - 17:00
Categories: Drupal

Pantheon Blog: Improving Speaker Diversity in Drupal Events

25 October 2019 - 8:37am
Image: by Rob Shea
Categories: Drupal

1xINTERNET blog: 1xINTERNET with three nominations for the Splash Awards

25 October 2019 - 5:41am
1xINTERNET with three nominations for the Splash Awards hadda Fri, 10/25/2019 - 14:41

The third international Splash Awards are taking place next Monday night in Amsterdam. This night we will celebrate the best Drupal projects from 2019 with our colleagues from all over Europe. We are very happy at 1xINTERNET to be nominated for three of our projects and grateful at the same time for our amazing clients. 

Categories: Drupal

Srijan Technologies: Create Once Publish Everywhere with Drupal

25 October 2019 - 2:00am

Long gone are the days, when cellphones were used just for calling purposes and desktops were switched on to browse the web. Today, information and entertainment can be accessed from anywhere and from any device.

Categories: Drupal

Mark Shropshire: Understanding Progressive Web Apps and Why You Should Care

24 October 2019 - 8:40pm

I had the pleasure of presenting on PWAs (Progresivei Web Applications) at DrupalCamp Atlanta 2019. I focused on the overall benefits of PWAs and how to set them up with GatsbyJS and Create React App. It turned out that Drupal PWAs were completely covered in the presentation Meet the Progressive Web App module by Christoph Weber and Alex Borsody. It was great to see so much attention given to the importance of PWAs!

I hope you checkout these PWA talks and related implementation techniques. There are big wins around making sure all of our websites and web applications utilize PWA related technology.

Below you will find my DrupalCamp Atlanta presentation deck and video:

Blog Category: 
Categories: Drupal

Consensus Enterprises: DrupalCamp Ottawa 2019: Automate All the Things

24 October 2019 - 7:55pm
On Friday, October 18th, I presented at DrupalCamp Ottawa 2019. That’s the annual gathering of the Drupal community in Ottawa, Ontario, Canada. Session information: Ever heard of infrastructure-as-code? The idea is basically to use tools like Ansible or Terraform to manage the composition and operation of your cloud systems. This allows infrastructure to be treated just like any other software system. The code can be committed into Git which allows auditability, and reproducibility.
Categories: Drupal

Consensus Enterprises: Exposing Drupal's Taxonomy Data on the Semantic Web

24 October 2019 - 7:22pm
As a content management framework, Drupal provides strong support for its taxonomical subsystem for classifying data. It would be great if such data could be exposed via the Simple Knowledge Organization System (SKOS) standard for publishing vocabularies as linked data. As Drupal becomes used more and more as a back-end data store (due to features such as built-in support for JSON:API), presenting this data in standard ways becomes especially important.
Categories: Drupal

Mark Shropshire: Flutter + Firebase (with Drupal) Presentation at Flutter Developers Charlotte

24 October 2019 - 9:44am

I had a great time presenting and taking part in the Flutter Developers Charlotte meetup last night. My talk was on the work I am doing around Flutter, Firebase, and Decoupled Drupal. Thanks to everyone who made it out and I appreciate the chance to share and learn!

Flutter and Firebase are a great match for rapid prototyping and full on production ready redeployment for native mobile applications. This talk included a demo of a Flutter application that reads content from a Contenta CMS API (Drupal distribution) and reads/saves related data to a Firebase Firestore. The application is a companion application for a pseudo Recipe Magazine, Unami.

Below are the links I referenced in the presentation for convenience: Blog Category: 
Categories: Drupal

Drudesk: Why to build a mobile app with Drupal for your business

24 October 2019 - 6:48am

In the world of PCs, smartphones are much smaller than their desktop “brothers” but their significance keeps growing bigger and bigger. More and more users prefer to interact with brands using them.

So website owners hurry up to make their website mobile-friendly, considering the mobile boom, as well as Google’s mobile-first indexing that shows the search giant primarily takes into account the website’s mobile display.

Categories: Drupal

Mediacurrent: Mediacurrent Returns to Acquia Engage US as a Partner Sponsor

24 October 2019 - 5:27am

This year’s annual Acquia Engage US conference is coming to New Orleans in November. The event brings together hundreds of business and technology leaders across the Acquia community to tackle today’s top digital challenges.

Engage is a mainstay on our calendar—we’ve returned to participate and sponsor every year since 2015, and can’t wait to be back.

Acquia Engage is a unique conference opportunity to connect with digital leaders. It has always been a must-attend...It's a fun, informative, and collaborative forum to share ideas and best practices...

Press release quote from Mediacurrent co-founder Dave Terry

 Here are a few upcomig highlights for this year’s event:

Our Team of Drupal Rockstars Are Attending

We have a diverse team of Mediacurrent team members attending, so drop by our booth with your most pressing digital strategy and Drupal questions. This team has launched dozens of enterprise Drupal 8 projects using the most advanced Drupal 8 architecture and distributions (Lift, Site Factory, decoupled, and more). 

Lately, we’ve been focused on gearing up for Drupal 9 with our Rain install profile, increasing conversion rates with Lift as a personalization tool, and decoupling Drupal with Gatsby.


Dave Terry - Partner, Client Services
Josh Linard - VP of Sales
Jay Callicott - VP of Technical Operations
Kevin Basarab - VP of Delivery 

Acquia Engage Awards Finalists

We’re excited to be selected as finalists in two categories for the 2019 Acquia Engage Awards.  These awards recognize the amazing sites and digital experiences that leading digital agencies are building with the Acquia Platform. Winners will be announced during the event.

  • Best Return on Investment: CAS, a Division of the American Chemical Society and Mediacurrent partnered to launch a new Drupal 8 platform with responsive design and significant improvements to site speed and layout—all within a tight launch timeline.  
  • Open Source Giants: The Rain install profile was created by Mediacurrent to add out-of-the-box editorial, administrative and media enhancements to the core Drupal 8 installation. Modeled after distributions 'Acquia Lightning' and 'Thunder', the Rain profile packages and pre-configures many core and contributed modules to make building Drupal websites faster and easier. Best of all, it’s free and open source.
Lift Personalization Partners

We’ve expanded our long-time partnership with Acquia by becoming an official Lift implementation partner. Our team and clients are loving the latest release of Acquia Lift that puts website personalization directly into the hands of marketers (no coding needed). If you’re evaluating Lift for your business or looking to ramp up your personalization strategy in 2020, we can help.  

Connect with Us 

Stop by our booth and pick up a t-shirt and tell us what you love about Acquia Engage. 

Will you be at Engage 2019? Book a meeting with our team or message us on the Acquia Engage app!

Categories: Drupal