Planet Drupal

Subscribe to Planet Drupal feed
Drupal.org - aggregated feeds in category Planet Drupal
Updated: 22 hours 2 min ago

Lullabot: Drupal JavaScript Initiative: The Road to a Modern Administration UI

9 May 2018 - 4:19am

It's now been over 10 years since Drupal started shipping jQuery as part of core, and although a lot of Drupal's JavaScript has evolved since then it's still based on the premise of progressive enhancement of server-side generated pages. Meanwhile, developing sites with JavaScript has made huge strides thanks to popular rendering frameworks such as React, Angular, and Vue. With some of the web's largest sites relying on client-side only JavaScript, and search engines able to effectively crawl them, it's no longer imperative that a site provides fallback for no JavaScript, particularly for specialised uses such as editorial tasks in a content management system.

At DrupalCon Vienna, the core JavaScript team members decided to adopt a more modern approach to using JavaScript in Drupal to build administrative interfaces, with efforts centred around the React framework from Facebook. To try this out, we decided to build a prototype of the Database Logging page in React, and integrate it into Drupal.

Why Not Vue or Angular?

We chose React because of its popularity, stability, and maturity. Many client projects built with Drupal have successfully leveraged the model of annotating Drupal templates with Angular or Vue directives for quite some time now, but we were wary of building something so tightly coupled with the Drupal rendering monolith. We're very aligned with the API-first initiative and hope that through this work we can create something which is reusable with other projects such as Vue or Angular. The choice of library which renders HTML to the browser is the easiest part of the work ahead, with the hard problems being on the bridge between Drupal and the front-end framework.

What We Learned From The Prototype undefined

As we anticipated, rendering something in React was the easy part— our early challenges arose as we realized there were several missing exposed APIs from Drupal, which we addressed with help from the API-first initiative. Having completed this, we identified a number of major disadvantages to our approach:

  • Although we were creating a component library that could be re-used, essentially we were embedding individual JavaScript applications into different pages of a Drupal theme
  • Our legacy JavaScript was mixed in on the page alongside the new things we were building
  • The build process we currently have for JavaScript can be frustrating to work with because Drupal doesn't have a hard dependency on Node.js (and this is unlikely to change for the time being)
  • A developer coming from the JavaScript ecosystem would find it very unfamiliar

The last point in particular touches on one of the biggest tensions that we need to resolve with this initiative. We don't want to force Drupal's PHP developers also to have to know the ins-and-outs of the JavaScript ecosystem to build module administration forms, but we also don't want developers coming from the world of JavaScript—with promises of "We use React now, so this will be familiar to you!"—to then have to learn PHP and Drupal's internals as well. Having discussed this at length during our weekly initiative meetings, we decided to build an administration interface that is completely separate from Drupal itself, and would only consume it's APIs (aka decoupled). The application would also attempt to generate administration forms for some configuration scenarios.

Hello, world!

We began building our decoupled administration application based on the Create React App starter-kit from Facebook. This is an extremely popular project that handles a lot of the complexities of modern JavaScript tooling and creates a very familiar starting point for developers from the JavaScript ecosystem. So far we haven't needed to eject from this project, and we're enjoying not having to maintain our Webpack configurations, so fingers crossed we can continue with this approach indefinitely.

The first page we decided to build in our new application was the user permissions screen so we could experiment with editing configuration entities. One of the challenges we faced in the implementation of this was the inability to get a list of all possible permissions, as the data we had available from Drupal's API only gave us permissions which had been enabled. We created an Admin UI Support module to start providing us with these missing APIs, with the intention to contribute these endpoints back to Drupal once we have stable implementations.

undefined

We chose to use GitHub as our primary development platform for this initiative, again because we wanted to be in a place familiar to as many developers as possible, as well as to use a set of workflows and tools that are common across the greatest number of open source projects and communities. Using GitHub and CircleCI, we've created an automated build process which allows Drupal developers to import and try out the project with Composer, without requiring them to install and run a build process with Node.js. Over the long-term, we would love to keep this project on GitHub and have it live as a Composer dependency, however, there are logistical questions around that which we'll need to work through in conjunction with the core team.

A New Design

Having got the architectural foundations in place for our application, we then turned to the team working on redesigning the admin UI to collaborate more closely. One of the features we had already built into our application was the ability to fall-back to a regular Drupal theme if the user tried to access a route that hadn't been implemented yet. Using this feature, and trying to keep in mind realistic timelines for launching a fully decoupled admin theme, the team decided that our current path forward will involve several parallel efforts:

  • Create new designs for a refreshed Seven-like theme
  • Adapt the new designs to a regular Drupal theme, so the fallback isn't jarring for the user
  • Build sections of the administration interface in the new React application as designs become available, hopefully starting with the content modeling UI
undefined Hard Problems

We still have a lot of issues to discuss around how the administration application will interact with Drupal, how extensible it can be, and what the developer experience will be like for both module authors and front-end developers. Some of the major questions we're trying to answer are:

  • How and what is a Drupal module able to do to extend the administration UI
  • We're not looking to deprecate the current Drupal theming system, so how can modules indicate which "mode" they support
  • If a module wants to provide its own React component, do we want to include this in our compiled JavaScript bundle, and if so how do we build it when Drupal has no requirement to include Node.js
  • How can modules provide routes in the administration UI, or should they become auto-generated
  • How do we handle and integrate site building tools such as Views, or do we replace this with the ability to swap in custom React components
Forms

How we're going to handle forms has been a big point of discussion, as currently Drupal tightly couples a form's schema, data, validation, and UI. Initially, we took a lot of inspiration from Mozilla's react-jsonschema-form project, which builds HTML forms from JSON schema and separated out these concepts. Nevertheless, a major issue we found with this was it still required a lot of form creation and handling to happen in Drupal code, instead of creating good API endpoints for the data we want to fetch and manipulate.

undefined

The approach we're currently looking at is auto-generating forms from configuration entities and allowing a module to provide a custom React component if it wants to do something more complex than what auto-generation would provide. Here's a working (unstyled!) example of the site information form, which has been auto-generated from an API endpoint.

undefined

We're now looking to augment configuration entities with metadata to optionally guide the form display. (For example, whether a group of options should be a select dropdown or radio buttons.

Try It Out and Get Involved

We have a Composer project available if you want to check out our progress and try the administration interface out (no previous Drupal installation required!). If you're looking to get involved we have weekly meetings in Slack, a number of issues on GitHub, our initiative plan on drupal.org, and lots of API work. You can also join us in-person at our next sprint at Frontend United in June.

A very special thank you to my initiative co-coordinators Matt Grill and Angie Byron, as well as Daniel Wehner, Ted Bowman, Alex Pott, Cristina Chumillas, Lauri Eskola, the API-First initiative, and all our other contributors for everyone's stellar work on this initiative so far!

⬅️✌️➡️  

Categories: Drupal

OPTASY: Reservoir or Decoupling Drupal Made Easy for Anyone: Non-Drupal Developers and Editors

9 May 2018 - 12:55am
Reservoir or Decoupling Drupal Made Easy for Anyone: Non-Drupal Developers and Editors admin Wed, 05/09/2018 - 07:55

Here's how the ideal decoupling Drupal scenario looks like:

Stripping Drupal to its essential role, that of a robust and flexible content repository, with no Drupal expertise needed. Then using it to back your front-end with; one that you'd be free to build by leveraging any modern (JavaScript) technology of your choice.

… a Drupal back-end content store that would still preserve all its content editing and managing functionalities, needless to add.

Luckily, this is no longer “daydreaming”. Not since Reservoir, the headless Drupal distribution, has been available. 

Here are some of its “promises” or well-known challenges, if you prefer, that this distribution's geared at solving:
 

Categories: Drupal

Valuebound: E-Commerce Solutions and Third-Party Integration Options within Drupal Ecosystem

8 May 2018 - 9:45pm

Drupal has several options and solutions to develop different types of websites including e-commerce portals. Drupalers have redefined the way e-commerce sites used to operate by developing a range of plugins and modules for high-end security, tailored web content, third-party integration, and other utilities. These modules primarily aim at enhancing end users experience, providing a user-friendly interface, flexibility, and reliability.

There are several e-commerce options within Drupal along with options to integrate third-party APIs, which I’ll discuss in a later section. Let’s first discuss the options…

Categories: Drupal

PreviousNext: Making your Drupal 8 kernel tests fail when there is an exception during cron

8 May 2018 - 7:39pm

Several times in the past I've been caught out by Drupal's cron handler silently catching exceptions during tests.

Your test fails, and there is no clue as to why.

Read on to find out how to shine some light on this, by making your kernel tests fail on any exception during cron.

by Lee Rowlands / 9 May 2018

If you're running cron during a kernel test and expecting something to happen, but it doesn't - it can be hard to debug why.

Ordinarily an uncaught exception during a test will cause PHPUnit to fail, and you can pinpoint the issue.

However, if you're running cron in the test this may not be the case.

This is because, by default Drupal's cron handler catches all exceptions and silently logs them. This is colloquially known as Pokemon exception handling.

The act of logging an exception is not enough to fail a test.

So your test skips the exception and carries on, failing in other ways unexpectedly.

This is exacerbated by the fact that PHP Unit throws an exception for warnings. So the slightest issue in your code will cause it to halt execution. In an ordinary scenario, this exception causes the test to fail. But the pokemon catch block in the Cron class prevents that, and your test continues in a weird state.

This is the code in question in the cron handler

<?php try { $queue_worker->processItem($item->data); $queue->deleteItem($item); } // ... catch (\Exception $e) { // In case of any other kind of exception, log it and leave the item // in the queue to be processed again later. watchdog_exception('cron', $e); }

So how do you make this fail your test? In the end, it's quite simple.

Firstly, you make your test a logger and use the handy trait to do the bulk of the work.

You only need to implement the log method, as the trait takes care of handling all other methods.

In this case, watchdog_exception logs exceptions as RfcLogLevel::ERROR. The log levels are integers, from most severe to least severe. So in this implementation we tell PHP Unit to fail the test with any messages logged where the severity is ERROR or worse.

use \Drupal\KernelTests\KernelTestBase; use Psr\Log\LoggerInterface; use Drupal\Core\Logger\RfcLoggerTrait; use Drupal\Core\Logger\RfcLogLevel; class MyTest extends KernelTestBase implements LoggerInterface { use RfcLoggerTrait; /**    * {@inheritdoc}    */   public function log($level, $message, array $context = []) {     if ($level <= RfcLogLevel::ERROR) {       $this->fail(strtr($message, $context));     }   } }

Then in your setUp method, you register your test as a logger.

$this->container->get('logger.factory')->addLogger($this);

And that's it - now any errors that are logged will cause the test to fail.

If you think we should do this by default, please comment on this core issue.

Tagged Drupal 8, Drupal Development, Drupal testing, PSR-3
Categories: Drupal

Palantir: Retheming Palantir.net for Our Audience

8 May 2018 - 1:47pm
Retheming Palantir.net for Our Audience brandt Tue, 05/08/2018 - 15:47 Alex Brandt May 8, 2018

The new www.palantir.net is a decoupled instance of Drupal 8 that allows us greater flexibility to feature content that is most relevant to our site visitors.

When we first migrated our website (https://www.palantir.net) from Drupal 7 to Drupal 8 in the summer of 2016, it was an exciting time for our marketing team. From an editorial perspective, Drupal 8 is a much easier to use interface than D7, and it instantly allowed us greater flexibility with our content.

However, even though we now had a more flexible site, we still felt like the digital experience for our audience missed a few marks. We quickly established a list of goals for phase two of the redesign, and these goals were related to both the overall digital experience and internal business goals.

The Overall Digital Experience

With the next iteration of our site, we wanted to focus on making the site more intuitive for visitors and also surface content in a way that was most beneficial to them. Would future clients prefer to filter case studies by service category or industry? What were visitors hoping or expecting to find on the homepage? What kind of information about Palantir were potential new hires trying to find?

These questions informed the following goals for the site:

  • To be simple and easy to use by having meaningful (and working) filters, allowing users to filter by industry, and curating collections around topics that most interest our audience.
  • To inspire applicants by demonstrating solid work, showcasing our cultural story, and making it easy to find career information.
  • To tell the story of Palantir with crisper messaging, improved visuals, and better storytelling throughout via weaving client testimonials with staff stories and case studies.
  • To be future forward by creating a visual theme with a timeless solution.
Business Goals

We also had a few items we wanted to address that related to our overall business goals. Our website is an important sales and marketing tool for us, and we wanted to make sure it was doing its job. We needed the new site to:

  • Showcase our work better by making it more prominent, showing more visuals and making our visuals more consistent.
  • Capture leads and bring in more business by making it easy for people to contact us no matter where they are on the site, and by simplifying newsletter sign-up.
  • Elevate the Palantir brand by creating a newly themed site that in itself is a demonstration of our design and development skill, showcasing our work in a superior way, and talking more intelligently — but concisely — about ourselves, our work, and our services.
The Process

Just like we recommend for our clients, we began our process with a Discovery phase. One of our web strategists, Michelle Jackson, completed a competitive analysis to inform next steps. A few of the things she evaluated were:

  • What are our peers doing right?
  • What are the current industry standards?
  • What are agencies that we aspire to emulate doing?

The results from this analysis helped us prioritize our wishlist of future site features. We then handed off this wishlist to the designer on the project, Carl Martens. Carl worked through the design phase which included creating wireframes, moving things into a prototype, and then building out the new theme in partnership with Ken Rickard, who completed all of the development. The design was done using our standard process: we built in a modular way using site components, and then compiled them into a living style guide. Particular attention was paid to typographic details, use of color, and how to most effectively use images.

Another design problem we needed to solve was one common to all companies that list their team members: what do you do when a new employee joins the team, and you don’t have a photo for them that matches the others? Even our photographer (who only does our headshots once per year) said, “all my clients have this problem. Let me know when you figure it out!” We thought of several options on how to fix this, and ended up with the chalkboard solution. It allows us to inject some personality into our page while not distracting from the other headshots by having it be a headshot in a different style or lighting.

We decided it was best to do a decoupled instance for this site. More details about the technical implementation of the decoupled Drupal instance can be found in Ken's upcoming blog post.

New Features and Integrations

The latest version of www.palantir.net has an abundance of new features that allow us to weave storytelling throughout the site.

Searchable Homepage

Our previous homepage had much of the important content buried beneath the fold. To fix this, we wanted to turn our homepage into a hub where site visitors could search for content that was relevant to them, no matter where that content lived on the site. The new homepage can filter all of our content by both topic and industry, and helps surface the most relevant pieces of content for our audience. The new homepage also features a collapsible side navigation, so you can see more relevant content at one time.

Topic-Based Collection Pages

Tying into the goals of our searchable homepage, we curated new collection pages based on topics we thought our audience would search for most (which include Planning, Business Strategy, Security, Design & UX, Development, Governance, Content Strategy and Accessibility). That way when someone asks, “what do you do for accessibility?” we can send them directly to a curated page that shows blog posts and case studies specific to that topic. These collection pages can be found at the bottom of our services page.

 

Culture and Careers Content

With the next iteration of the site, we wanted to make sure we were catering to the audience who might be interested in working for us in the future. We achieved this by showcasing all of the great things about working at Palantir, and on these pages we included more images to help show rather than tell that information. Our new Culture and Careers page houses much of the information a potential new Palantiri might look for, including what we think are the key elements of our culture. It also links to our Benefits page which outlines the many perks of working for Palantir, and to our current openings.

Case Studies That Tell a Story

Some of the most important pieces of content on our site are our case studies. It is vital as an agency to be able to showcase our work and capabilities dynamically. The old version of our case studies were extremely text-heavy and did not feature nearly enough visual representation of the process or final product of each project.

The new format of our new case studies are broken into different chunks of content, with the ability to show each bit of information in a way that fits what is being communicated. We can then weave each of these pieces together into one comprehensive, dynamic storyline. By breaking the case studies into smaller, more visual pieces, they are much easier to scan too. We still have to update some of our older case studies, so this is still a work in progress.

 

Updated Services Page

One would think a services page would be the first page to be refined on a business’ site, but somehow our previous services page was a complete afterthought. Buried in the footer, it was a glorified bulleted list. This page was a high priority for us to fix, because we wanted to make sure potential clients could find information about what services we provide. The new services page is easy to find in the main site navigation, and in addition to the afore-mentioned collections, it also features information about our partnerships.

Hubspot Integration

Hubspot is a new sales and marketing tool for us that we have been implementing since the beginning of the year. It helps us track new project opportunities on the sales side, and it also houses all of our marketing tools. One of the new Hubspot tools that we have implemented on our new site is called a lead flow. Lead flows are abbreviated contact forms that we can choose to display on specific pages, granting our site visitors a quick way to subscribe to our email newsletter.

Always Evolving

In true agile fashion, we had an MVP with the goal of launching by DrupalCon Nashville, but we plan to keep iterating and improving the site in the coming months. So, what do we have planned next?

  • New photos for new staff
  • Video that reiterates the Palantir story
  • A timeline of the history of Palantir
  • Listing of awards and press mentions (Great Place to Work, Clutch.co, etc.)
  • Rewriting and adding more case studies
Accessibility

Of course, we also want to make sure our site is accessible. In addition to baking accessibility into our process along the way, we use a tool provided by our partner, Siteimprove, to scan our site and determine if it meets accessibility standards. Siteimprove is a great tool because it flags both quality assurance items (like misspellings and broken links) as well as accessibility requirements (like those provided by WCAG and AA). We use the reports provided by Siteimprove to continuously clean up our content and ensure an enjoyable digital experience for all users.

Tell Us What You Think

So far we’ve had one client tell us this: “The redesign clearly marks a maturation and growth of Palantir. If progressing towards a more serious, trustworthy, and refined company was the goal, I think you nailed it.” We sure hope so!

We’d love to hear what you think about the new site. Share your thoughts on Twitter (@palantir) or by reaching out through our contact form.

Design Development Drupal Site Building Strategy
Categories: Drupal

OSTraining: How to Build User Profiles With Fields in Drupal 8

8 May 2018 - 1:26pm

By default, a Drupal 8 user account collects only very basic information about the user. 

And, most of that information is not visible to visitors or other users on the site.

Fortunately, Drupal makes it easy to modify and expand this profile so that people can add useful information about themselves such as their real name (versus a username), address, employer, URLs, biography, and more.

Categories: Drupal

OSTraining: How to Manage User and Role Permissions in Drupal 8

8 May 2018 - 1:23pm

This tutorial is all about managing uses on your Drupal 8 site.

I'll show you how to control who can do what on your site:

  • Who can create, delete, and edit content?
  • Who can upload modules and themes?
  • Who can modify menus and blocks?

You also see how to make user accounts more interesting. You do this by allowing users to add more information about them. 

Categories: Drupal

ADCI Solutions: How to send the JSON data from a Drupal 8 site?

8 May 2018 - 10:11am

Imagine a situation: your mobile application needs to get some information from your Drupal 8 site. How can you do it? There are several ways to create and send data with JSON, and we will consider three of them.

Learn about the data sending in Drupal 8

Categories: Drupal

Hook 42: Drupal 8 Interviews: Spotlight on Eduardo Garcia

8 May 2018 - 8:07am

For this month’s Drupal 8 Interview we were excited to catch up with Eduardo Garcia. He is the CTO of both WeKnow and anexus. WeKnow is a Drupal and Symfony consulting and training firm. Anexus is a company that supports the development of Drupal Console.

Most people in the open source and Drupal community know him as Enzo. His companies are mostly distributed and he likes to think of himself as a distributed person because of his love for travel. He is a native Colombian who lived in Costa Rica for more than 14 years. He currently resides in Australia with his family.

Categories: Drupal

Web Wash: How to Add Menus using Toolbar Menu in Drupal 8

8 May 2018 - 8:00am

With the Toolbar Menu module, you can add as many menus as you need to the toolbar of your Drupal installation. By default, a Drupal 8 installation has 3 menu links in its toolbar.

1. Manage - Administration of the whole Drupal site, 2. Shortcuts - Links added by the admin to administrative pages used frequently, 3. User Name - Link to the profile page

This module works also with the Admin Toolbar module, which improves the default toolbar providing dropdown menus. In this tutorial, we’re going to cover the usage of the Toolbar Menu module.

Categories: Drupal

Amazee Labs: Progressive Decoupling: 1 Modern Javascript

8 May 2018 - 7:52am
Progressive Decoupling: 1 Modern Javascript

In this series we’ll take a closer look at progressive decoupling in Drupal 8. We’ll go through the project setup, check the tools and libraries and discuss potential applications. Let’s start with the definition.

Blazej Owczarczyk Tue, 05/08/2018 - 16:52 Progressive decoupling

Decoupled Drupal is a thing for quite a while now. There seem to be two ways of doing it. We either let the Javascript take control and use Drupal only as a data store (fully decoupled) or let Drupal do the heavy lifting and use the front end frameworks to render discrete parts of the site (progressive decoupling). The first option seems to be much more popular now, even despite the fact that it’s expensive and forces us to re-implement a lot of things that Drupal does well. Why is that?

I think there are two main reasons. Firstly, and this is a huge pain point, there is no out-of-the-box way to use modern Javascript in Drupal contrib and custom code. Whoever wrote a line of ES6 never wants to go back to the stone-age JS that is understood by IE. Luckily, this is something we can fix and, in this and the next posts, we’ll see how to do that.

Another question, which arises quickly after solving the problem above, is how to import packages from npm. JavaScript projects usually have a package.json file containing all the dependencies and importing them in the code is as easy as calling the require function. We don’t have such a central place to declare JS dependencies in Drupal projects. In the later posts, we’ll see how this can be worked around right now and, hopefully, try to define the shape of the ideal solution for the future. But now let’s get back to the language.

Modern JavaScript

Regardless of which front-end framework we choose, we’re going to need the ability to write our code in modern JavaScript. It’s been a while since ES6 (or ES2015) was released. There was ES7 (2016) and ES8 (2017), each adding new features. These new functions decrease the WTF/h rate when developing and, arguably, can even make the language likeable, which was rather unimaginable a decade ago. Let’s go through some of the most interesting ones.

Deconstructing assignment

Reduces the redundancy when getting values from arrays and objects.

Property shorthand

Reduces redundancy when composing objects out of variables.

Spread syntax

Makes it possible to compose objects out of other objects.

Arrow functions

Make function definitions more compact.

It’s especially useful for higher order functions. A click handler, for instance, can be created like this.

Default parameter values Classes

Object Oriented Programming is much more intuitive now.

Example from http://es6-features.org

Template literals

These friendly creatures make it possible to insert variables into strings.

We’ve defined what we mean by decoupling Drupal and have shown some of the cool new features available in EcmaScript 6 and above (for a comprehensive comparison see http://es6-features.org/). All these functions have something in common, namely none of them are supported by our beloved IE. In the next post we’ll see how to overcome that and use modern JavaScript in our modules and themes.

Categories: Drupal

Chromatic: Migrating File Fields to Media Entities without the Migrate Module

8 May 2018 - 7:00am

Learn how to update your content model to use media entities without the overhead of a traditional migration.

Categories: Drupal

Mediacurrent: Mediacurrent Top Drupal 8 Modules: Drupalcon 2018 Edition

8 May 2018 - 5:18am

Welcome to the latest edition of the top modules for Drupal 8! Below I recap my newest list that I presented at Drupalcon, Nashville along with updated descriptions. I have also included labels to indicate which modules are best suited for intermediate users versus modules that are universally easy to install and configure.

As an added bonus I now have all of these modules and dependencies available through Github/Packagist for easy setup. 

Just run “composer create-project mediacurrent/mc_top_modules” to get started in minutes, enjoy!

ESSENTIALS LIST
  1. Admin Toolbar (Beginner) - The admin toolbar. It’s a module that you might think would just be in core. We use this on every project because navigating through menus in Drupal is a real pain without rollover menus.
  2. Component Libraries (Intermediate) - If you are doing any Twig theming this module is going to help you with your Twig file includes.
  3. Devel (Intermediate) - Devel can help you debug problems in Twig templates. Another feature that is handy is the ability to generate dummy content.
  4. Entity Browser / Media Entity Browser (Beginner) - The Media Entity Browser module gives you the ability to use a nice little library pop-up to upload, browse and search for different types of media.
  5. Field Group (Beginner) - This is a helpful module for cleaning up your content types. You can organize fields into tabs, accordions, etc. to give your content editors a better experience.
  6. Google Analytics (Beginner) - Google Analytics is a simple module that allows site admins the ability to easily add basic tracking.
  7. Linkit (Beginner) - This module gives you an autocomplete popup inside of Wysiwyg for adding links.
  8. Metatag (Beginner) - Maintained by Mediacurrent’s very own Damien McKenna, this module lets you configure all of your meta tags for SEO purpose.
  9. Panels / CTools / Page Manager (Intermediate) - Panels is a great site building tool for creating custom layouts with a drag and drop interface.
  10. Paragraphs / Entity Reference Revisions (Intermediate) - The paragraphs module is a Mediacurrent favorite for a couple of reasons. Paragraphs are like mini-content types that can handle a variety of use cases.
  11. Pathauto / Token (Beginner) - The pathauto module lets you set up clean alias patterns for all of your content. If you want all of your blogs to have the path /blog/[title of the blog with hyphens instead of spaces] - this will be the module that you use.
  12. Redirect (Beginner) - Almost every new site needs to incorporate 301 redirects for old page URLs. The redirect module gives site admins an easy interface for creating those redirects in Drupal.
  13. Search API (Intermediate) - The Search API suite of modules is a fantastic way to configure your site searches. By default this Search API DB is enabled but you can easily swap out for Apache Solr. The Search API Pages module is also handy for getting a site search up and running quickly.
  14. Simple Sitemap (Intermediate) - A pretty easy to configure module for creating XML sitemaps for search engines.
  15. Stage file proxy (Beginner) - A great module for downloading images to your local environment auto-magically rather than having to continually migrate those images manually.
  16. Webform (Beginner) - This module is awesome because it makes it easy to make any and all kinds of forms on your site. This is a must-have module if you plan on managing forms within Drupal.
NOTABLE MENTIONS

Below are a list of notable mentions that didn’t make the essentials list but are still worth checking out.

  1. CKEditor Media Embed (Beginner) - A lot of content out there on the web includes social media callouts. This module makes it a lot to easier to include that content inside of your Wysiwyg.
  2. Colorbox (Beginner) - The Colorbox module integrates is a popular lightbox library of the same name with Drupal Views and fields. You will need to download the Colorbox library to your libraries folder, otherwise this module is very easy to set up.
  3. Commerce (Intermediate) - If you have done any e-Commerce you have probably heard about the Commerce suite of modules for Drupal. This allows you to add products to your site and checkouts, payment options and more.
  4. DropzoneJS (Intermediate) - Pretty much everywhere you go on the web you see a drag and drop upload option. So why not have that in your Drupal project? This module makes it relatively easy to do so but there is some configuration required along with the need to download the DropzoneJS library.
  5. Entity embed / Embed (Intermediate) - This module lets you embed any Drupal entity anywhere. The most common use case for this is embedding media within Wysiwyg. When paired with the Media Entity Browser, for example this gives editors a powerful tool for embedding media from a library. Both the Lightning & Thunder distributions have good examples of this implementation.
  6. External Links (Beginner) - Over the years we have seen that most clients want the option to force external links to open up in a new window or tab. This module makes that feature request very easy. All you do is check one checkbox and essentially you are done.
  7. Focal point / Crop (Intermediate) - The problem we are trying to solve with these modules is supporting different kinds of crops from the same source image. This solution is probably the easiest I’ve found both on the developer and the content editor. This module tries to crop around the focus of the image rather than just arbitrarily cropping from the center.
  8. Geolocation (Beginner) - I like that the Geolocation module makes it simple to add a point on a map and have that map render in a field. Easy to input and easy to format, with plenty of options for configuration.
  9. Honeypot (Beginner) - Do you ever get spam? While there are a lot of options for anti-spam measures (including captches) this solution has an algorithm that does not burden the end user and is pretty effective.
  10. Lightning Install Profile (Beginner) - Lightning is a general purpose Drupal distribution that focuses on the media and editorial enhancements. Not only is it a good started distribution for Drupal development, it is also a good learning tool. It often is easier to learn how to configure and use a module by examining how it’s implemented on a pre-configured distribution like Lightning.
  11. Scheduler (Beginner) - The scheduler module lets you schedule the publishing and unpublishing of your content. Note that it is going to use cron to make this happen so you need to verify that your cron is configured correctly.
  12. Slick / Slick views / Slick media (Intermediate) - The Slick suite of modules adds functionality to allow site builders to create slideshows and carousels. There are several related modules that integrate with every aspect of Drupal. The hardest part is the initial setup of library dependencies. Once that is done these modules are very easy to configure within the Drupal admin.
  13. Taxonomy Access Fix (Beginner) - This project addresses the fact that core doesn’t have granular enough permissions. The Taxonomy Access Fix module therefore adds in additional permissions to fill in the gaps.
  14. Viewsreference (Beginner) - Last but not least the Viewsreference module gives editors the ability to select a View from a field. At Mediacurrent we combine this field with a Paragraph type to give editors an easy, flexible interface for embedding Views onto a page.

Did I miss any modules you think should have made this list? Let me know on Twitter at @drupalninja!

Additional Resources
Top Drupal 7 Modules: Final Edition | Blog
Top Drupal Marketing Automation Modules | Blog
Top Reasons to Choose Drupal | Blog

Categories: Drupal

Appnovation Technologies: Using React library on Drupal: There's more....

8 May 2018 - 12:00am
Using React library on Drupal: There's more.... Following up from my post last week, I wanted to add some additional material regarding React on Drupal...I hope you'll find it useful... Bonus - Extend the components to Drupal regions The react image gallery module provides a very easy way to display an image gallery on any piece of content, however what happen if we want to ...
Categories: Drupal

Jacob Rockowitz: It is okay for you to plan an exit strategy, we should be okay with off-boarding contributors, and everyone says goodbye

7 May 2018 - 4:32pm

People come and go from open source projects and communities

Most people would agree that everyone should contribute something back to Open Source at some point in their careers. We have to realize that an ongoing Open Source contribution to a project can't be sustained forever. We might graduate from college, get a new job, need a break to travel, have kids, help raise grandkids, retire and even get bored with a project. While we need to improve open source sustainability, we also need to accept the reality that people continually come and go from open source projects.

Developer burnout should not be part of open source

Up until recently, I felt that 'burnout' was the only talked about method when people left the Drupal community. Up until DrupalCon, I thought that once I committed to supporting something, like a module, I was obligated indefinitely or at least until I burned-out from supporting it.

In my new year blog post title, Webform, Drupal, and Open Source...Where are we going?, I stated…

...and I don't think I am the only one.

Are we expecting too much?

Jeff Eaton's presentation titled "You Matter More Than The Cause" addresses burnout and how it impacts the sustainability of teams and he says…

I think we need to stomp out the concept of developer burnout in Open Source and equate developer burnout to poorly-managed companies and organizations.

Planning an exit strategy can prevent burnout

One of many valuable lessons I learned at Adam Goodman's Teamwork and Leadership Workshop at DrupalCon Nashville was that it’s okay to plan an exit strategy, it’s even something that can ultimately help the community and potentially...Read More

Categories: Drupal

Palantir: Supporting Innovation Through Contribution

7 May 2018 - 12:18pm
Supporting Innovation Through Contribution brandt Mon, 05/07/2018 - 14:18 George DeMet May 8, 2018

Companies, agencies, and organizations that contribute to the Drupal project and community play a key role in supporting and sustaining a culture of innovation.

Drupal has a long and rich history of supporting and sparking innovation. Drupal 8 in particular represents a fundamental shift in thinking about how websites and other digital experiences are built. With its modular architecture, improved APIs, configuration management, and native web services support, Drupal 8 is well-positioned to help connect people, technology, and information in ways that have never before been possible.

Companies, agencies, and organizations that contribute to the Drupal project and community play a key role in supporting and sustaining a culture of innovation. This contribution can take on many forms, including setting aside time for employees to contribute to the Drupal project and community, sponsoring people to work exclusively on Drupal, and donating money to sponsor Drupal initiatives and events.

Impact of Contribution on Innovation

An ever-growing body of research into open source ecosystems is shedding light into the ways that different forms of contribution have on innovation for firms who contribute as well as the projects that benefit from those contributions. Firms that contribute to Drupal are generally driven by extrinsic motivators, such as the belief that working with the community will help them develop better products, or provide them with increased visibility and status within the community, which in turn helps drive sales and/or recruit talent.

Jonathan Sims, a professor of strategy at Babson College, has spent years studying how firms in the Drupal ecosystem engage with each other and the project to promote open innovation. In a 2016 paper published in the Oxford Journal of Industrial and Corporate Change, he found that while the impacts of contribution on a firm’s productivity are usually marginal, contribution does help expand social ties and can shift strategic posture and promote innovation.

While contributing code is associated with stronger social ties and more incremental innovations, providing help or support to others in the community is associated with a more conservative strategic posture, but more radical innovations. Firms that primarily contribute code to projects like Drupal are more likely to be building on top of someone else’s work and/or collaborating with someone else to solve a shared problem. Providing help on the other hand, is much more context-dependent and is more likely to lead to new questions and possible new insights, thus providing more opportunities for radical innovation within a given domain.

The Virtuous Cycle

Regardless of what form contribution takes, participating in an open source ecosystem like Drupal requires that firms be open and willing to share their knowledge and intellectual property with others. Drupal project lead Dries Buytaert has discussed how companies and organizations like Pfizer and Hubert Burda Media are not only sharing Drupal contributions with their competitors, but also challenging those competitors to contribute back as well. He argues that by working together, these organizations not only gain a competitive edge, but also reap the benefits of accelerated innovation:

“Those that contribute to open source are engaging in a virtuous cycle that benefits their own projects. It is a tide that raises all boats; a model that allows progress to accelerate due to wider exposure and public input.”

We’ve seen this virtuous cycle play out countless times at Palantir. One example is from several years ago, when we found that out that on many of the projects that we worked on, clients often had a specific set of expectations around content workflow and editorial access based on their experience with other platforms, and that all too often, Drupal didn’t meet those expectations out of the box. In response to this business need, we created and released a suite of modules called Workbench that provided a unified interface and tools to enable authors and editors to focus on managing their content.

While Palantir team members did the initial heavy lifting on the code development for Workbench, over time, other firms (including some of our competitors) started using and extending the system, building on top what we had released. Thanks to the efforts of those involved in the Drupal Workflow Initiative, the moderation functionality of Workbench was added to Drupal core as the Content Moderation module, making the software better for everyone. This in turn makes Drupal a more attractive choice than competing platforms and expands the market for the firms that work with it.

Extrinsic and Intrinsic Motivation

In contrast to the external incentives that drive most firms to contribute to open source projects like Drupal, individuals are more likely to be driven by intrinsic motivators to contribute. Not only do they get to feel like they’re part of something bigger than themselves, but participating in the Drupal community is also a good way to form social ties with other like-minded people who want to see their contributions make a difference in the world.

Despite the large number of individual contributors to the Drupal project, a very small number do the majority of the work. Contribution data on Drupal.org reveals that nearly half of the people who contributed code to the project got just one credit, while the top .4% of all contributors (30 people) accounted for over 17% of the total credits.

One likely reason for this imbalance is Drupal’s reputation for having a steep learning curve. User research conducted by Whitney Hess and the Drupal Association in 2014 found that while the project is good at onboarding people at the entry level of engagement, the transition to higher levels is much more challenging and is where many people end up dropping out of the project.

Providing resources and support to help more people move up the contribution ladder helps spread the burden across more shoulders, introducing new perspectives and reducing burnout, particularly within the core developer community. Having more engaged community members also helps mitigate one of the historical hurdles to Drupal adoption, which is the shortage of skilled developer talent.

Firms that work in the Drupal ecosystem can both address the talent shortage problem and support innovation within their own organizations by supporting professional development opportunities that help their employees “level up” existing skills and pass on knowledge to less experienced team members. For many organizations, this is also a much more economical and sustainable way to build and grow a Drupal team than relying exclusively on hiring from a limited and increasingly in-demand pool of existing “rockstar” talent.

Removing Barriers to Contribution

It is vitally important for any open source project to remove barriers to contribution, whether real or perceived, because they undermine both the intrinsic motivations of individual contributors and the extrinsic motivations of companies, agencies, and other organizations. Likewise, it’s important for projects not to place too much emphasis on extrinsic motivators, as that can also undermine intrinsic motivation. In this way, recognizing different kinds of contribution can be a delicate balancing act.

Over the last few years, the Drupal Association and others have worked to help track and acknowledge more forms of contribution on Drupal.org by improvements to user and organizational profile pages, adding the ability for organizations to receive credit for work on projects and issues, and tying case studies directly to organizations as well as individual contributors. Along with paid sponsorships, these improvements enable companies and organizations who contribute to the project and community to receive greater visibility on Drupal.org, which benefits both sales and recruiting efforts.

Other forms of contribution, such as local event and user group sponsorship and organization, writing documentation, and providing mentorship are less easy to measure, but also critically important to the health of the project. In a paper presented at DrupalCon Barcelona in 2015, David Rozas, a sociologist and computer scientist who studies the technical and social aspects of technology, argued that these kinds of “community-oriented” contributions are actually more important to a project’s long-term sustainability than code contributions because they are emotional experiences that serve to strengthen the project’s sense of community.

Firms that are not in a position to contribute code to Drupal can contribute time and/or money toward efforts that help promote the project and community, such as local and regional events or Drupal Association partnership programs and special initiatives. These kinds of contributions can often have a greater impact on innovation than code alone.

Thank You for Your Support!

Drupal boasts one of the largest and most diverse communities of any open source project, which along with a culture that supports and values contribution, has enabled it to become a leading platform for digital innovation. With the support of the companies, organizations, and individuals that use and contribute back to it every day, Drupal is poised to inspire innovation for many years to come.

Community Drupal Open Source People Workbench
Categories: Drupal

Palantir: Conscious Decoupling: The Case of Palantir.net

7 May 2018 - 10:31am
Conscious Decoupling: The Case of Palantir.net brandt Mon, 05/07/2018 - 12:31 Ken Rickard May 9, 2018

Our new site uses VueJS to produce single page applications. By tying these applications to content creation, our content editors can create dynamic new pages without needing an engineer.

Alex Brandt recently wrote about the new redesign of the new Palantir.net site: what the goals were, what we wanted to improve, and the process by which we approached the project. I want to speak more from a development viewpoint around how we decoupled the new www.palantir.net site in order to create better relationships between content.

A major goal of our 2018 redesign was to feature more content and make it easier for people to surface topics that interest them. The strategic plan and design called for a system that allows people to filter content from the home page and other landing pages (such as our Work page).


In the modern web, people expect this filtering to take place without a page refresh. Simply select the filter and the content should update immediately.

This presents an opportunity to explore methods for achieving this effect. In addition, the following features were desired:

  • The ability to feature specific content at the top of the page
  • A process to insert content other than Drupal pages into the list display
  • A way to select what types of content appear on the page
  • A method to restrict the total count of items displayed on the page
  • The ability to add one or two filters to the page; or none at all

From the developer’s point-of-view, we also added:

  • The ability to allow editors to create and configure these dynamic pages without additional programming

The design and development of the new site followed our understanding of what “content” means to different teams. We know that understanding how to implement the design requirements isn’t enough. We had to think through how editors would interact with (and control) the content.

There is a lot of talk around “decoupled” Drupal these days — the practice of using Drupal as an editing environment and then feeding data to a front-end JavaScript application for rendering. Certainly we could have chosen to decouple the entire site. That process, however, brings extra development time and overhead. And in our case, the site isn’t large enough to gain any advantage from rapidly changing the front-end.

So instead we looked at ways to produce a dynamic application within Drupal’s template system. Our technical requirements were pretty standard:

  • A template-driven JavaScript content engine
  • Rendering logic (if/else and simple math)
  • Twig compatibility
  • A single source file that can be served from CDN or an application library

This last requirement is more a personal preference, as I don’t like long, fixed dependency chains during development. I specifically wanted a file I could drop in and use as part of the Drupal front-end.

Based on these requirements and a few basic functionality tests, we settled on the VueJS library. Vue is a well-documented, robust framework that can be run server-side or client-side. It provides DOM-manipulation, templated iteration, and an event-driven interaction API. In short, it was perfect for our needs.

Even better, you can start using it immediately:

 

At the core of Vue.js is a system that enables us to declaratively render data to the DOM using straightforward template syntax. Vue uses the handlebars syntax -- familiar to Twig users -- to define and print variables set by the application:


  {{ message }}

var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

When working with Twig, which also uses handlebars to wrap variables, we must wrap VueJS variables in the {% verbatim %} directive like so:


  {% verbatim %}{{ item.slug }}{% endverbatim %}

Unless you hardcode variables, Vue pulls all of its data via JSON, which can be provided out-of-the-box by Drupal’s Views module.

To make the application work, we needed to provide the following elements:

  • A JSON feed for content to display, with featured items at the top
  • A JSON feed for each filter to use
  • A JSON feed for insert content

The first elements -- content -- consists of two JSON directives controlled by editors. First, there is a Featured Content field that can be used to select content for the top of the page:

Editors may choose to only populate this content, and they may choose as many items as they wish. Below this content, we optionally add additional content based on type. Editors may select what types of content to add to the page. For the homepage, we include four content types:

Editors may then select which filters to use, if any are desired. Two options are available, but one can be selected. The filters may be sorted as desired.

Further, if the editor selects the Filter by Type option, the first filter will be replaced by a Content Type list taken from the selections for the current page. This technique is made easier by the dynamic nature of the VueJS application, which is expecting dynamic content. It has the added bonus of making the work future proof, as editors can add and adjust pages without additional coding.

Lastly, editors can add “insert” content to the page. These inserts are Drupal Paragraphs -- custom fielded micro-content -- that optionally appear sprinkled through the content.

These inserts leverage Vue’s logic handling and template system. Here is a code snippet for the inserts:

 
   
     
       
          {% verbatim %}{{ item.link_text | decode }}{% endverbatim %}
          {% verbatim %}{{ item.slug | decode }}{% endverbatim %}
       
     

   
   
     
       
         
            {% verbatim %}{{ item.slug | decode }}{% endverbatim %}
         
         
            {% verbatim %}{{ item.author | decode }}{% endverbatim %}
             
               
                {% verbatim %}{{ item.link_text | decode }}{% endverbatim %}
               

             
             
                {% verbatim %}{{ item.link_text | decode }}{% endverbatim %}
             
           
         
       
     
   
   
     
       
          {% verbatim %}{{ item.slug | decode }}{% endverbatim %}
          {% verbatim %}{{ item.link_text | decode }}{% endverbatim %}
       
     
   
 

The v-if directive at the start tells the application to only render the entire template if the parent_id property is present. Since that property is unique to Paragraphs, this template is skipped when rendering a blog post or case study.

In cases of content types, we have a standard output from our JSON feed, so one template covers all use-cases:

 
 
   
   
      {% verbatim %}{{ item.type }}{% endverbatim %}
      {% verbatim %}{{ item.title | decode }}{% endverbatim %}
     
   
   
      {% verbatim %}{{ item.dates | decode }}{% endverbatim %}
      {% verbatim %}{{ item.location | decode }}{% endverbatim %}
   
   
     
      {% verbatim %}By {{ item.author_display }}{% endverbatim %}
   
   
      {% verbatim %}{{ getLinkText(item.type) }}{% endverbatim %}
   
   

 
 

Note the v-bind directive here. Vue cannot parse variables directly in HTML tag properties, so it uses this syntax to interact with the DOM and rewrite the element.

Other nice features include adding method calls like {{ getLinkText(item.type) }} that let Vue perform complex calculations on data elements. We also use Vue’s extensible filter system {{ item.summary | decode }} to perform actions like HTML escaping.

For instance, we pass the index position, content type, and background image (if present) to the getClass() method of our application:

// Get proper class for each cell.
getClass: function(index, type, image) {
  var $class = '';
  if (index == 2 || index == 5 || (index > 12 && index % 5 == 1)) {
    $class = $class + ' grid-item--lg';
  }
  if (type == 'Case Study') {
    $class = $class + ' grid-item--cs grid-item--dark';
  }
  else if (type == 'Collection') {
    $class = $class + ' grid-item--collection';
    if (index % 2 == 1) {
      $class = $class + ' grid-item--dark';
    }
  }
  else {
   $class = $class + ' grid-item--default';
  }
  if (image === undefined || image.length === 0) {
    if (index % 2 == 1) {
      return $class + ' grid-item--dark';
    }
    return $class;
  }
  return $class + ' grid-item--dark';
},

This technique lets us provide the light and dark backgrounds that make the design pop.

The end result is exactly what we need to deliver the experience the audience expects. And we get all that within a sustainable, extensible platform.

Is a decoupled Drupal site right for you? For us, a dynamic (yet not fully decoupled) instance made the most sense to improve the experience for our site users. We’d love to discuss whether or not the same flexibility would be beneficial for your site. Drop us a line via our contact form, or reach out via Twitter (@palantir).

Design Development Drupal Site Building
Categories: Drupal

Lucius Digital: Lucius launches Drupal platform for SOS Children's Villages

7 May 2018 - 8:03am
The new platform for SOS Children's Villages was recently launched, after 3 sprints with a lead time of 3 months and a team of 6 people on average, we are proud to announce this new platform.
Categories: Drupal

Oliver Davies: Creating a Custom PHPUnit Command for Docksal

5 May 2018 - 5:00pm

This week I’ve started writing some custom commands for my Drupal projects that use Docksal, including one to easily run PHPUnit tests in Drupal 8. This is the process of how I created this command.

Categories: Drupal

Oliver Davies: Creating a Custom PHPUnit Command for Docksal

5 May 2018 - 5:00pm
What is Docksal?

Docksal is a local Docker-based development environment for Drupal projects and other frameworks and CMSes. It is our standard tool for local environments for projects at Microserve.

There was a great talk recently at Drupaldelphia about Docksal.

Why write a custom command?

One of the things that Docksal offers (and is covered in the talk) is the ability to add custom commands to the Docksal’s fin CLI, either globally or as part of your project.

As an advocate of automated testing and TDD practitioner, I write a lot of tests and run PHPUnit numerous times a day. I’ve also given talks and have written other posts on this site relating to testing in Drupal.

There are a couple of ways to run PHPUnit with Docksal. The first is to use fin bash to open a shell into the container, move into the docroot directory if needed, and run the phpunit command.

fin bash cd /var/www/docroot ../vendor/bin/phpunit -c core modules/custom

Alternatively, it can be run from the host machine using fin exec.

cd docroot fin exec '../vendor/bin/phpunit -c core modules/custom'

Both of these options require multiple steps as we need to be in the docroot directory where the Drupal code is located before the command can be run, and both have quite long commands to run PHPUnit itself - some of which is repeated every time.

By adding a custom command, I intend to:

  1. Make it easier to get set up to run PHPUnit tests - i.e. setting up a phpunit.xml file.
  2. Make it easier to run the tests that we’d written by shortening the command and making it so it can be run anywhere within our project.

I also hoped to make it project agnostic so that I could add it onto any project and immediately run it.

Creating the command

Each command is a file located within the .docksal/commands directory. The filename is the name of the command (e.g. phpunit) with no file extension.

To create the file, run this from the same directory where your .docksal directory is:

mkdir -p .docksal/commands touch .docksal/commands/phpunit

This will create a new, empty .docksal/commands/phpunit file, and now the phpunit command is now listed under "Custom commands" when we run fin.

You can write commands with any interpreter. I’m going to use bash, so I’ll add the shebang to the top of the file.

#!/usr/bin/env bash

With this in place, I can now run fin phpunit, though there is no output displayed or actions performed as the rest of the file is empty.

Adding a description and help text

Currently the description for our command when we run fin is the default "No description" text. I’d like to add something more relevant, so I’ll start by adding a new description.

fin interprets lines starting with ## as documentation - the first of which it uses as the description.

#!/usr/bin/env bash ## Run automated PHPUnit tests.

Now when I run it, I see the new description.

Any additional lines are used as help text with running fin help phpunit. Here I’ll add an example command to demonstrate how to run it as well as some more in-depth text about what the command will do.

#!/usr/bin/env bash ## Run automated PHPUnit tests. ## ## Usage: fin phpunit <args> ## ## If a core/phpunit.xml file does not exist, copy one from elsehwere. ## Then run the tests.

Now when I run fin help phpunit, I see the new help text.

Adding some content Setting the target

As I want the commands to be run within Docksal’s "cli" container, I can specify that with exec_target. If one isn’t specified, the commands are run locally on the host machine.

#: exec_target = cli Available variables

These variables are provided by fin and are available to use within any custom commands:

  • PROJECT_ROOT - The absolute path to the nearest .docksal directory.
  • DOCROOT - name of the docroot folder.
  • VIRTUAL_HOST - the virtual host name for the project. Such as myproject.docksal.
  • DOCKER_RUNNING - (string) "true" or "false".

Note: If the DOCROOT variable is not defined within the cli container, ensure that it’s added to the environment variables in .docksal/docksal.yml. For example:

version: "2.1" services: cli: environment: - DOCROOT Running phpunit

When you run the phpunit command, there are number of options you can pass to it such as --filter, --testsuite and --group, as well as the path to the tests to execute, such as modules/custom.

I wanted to still be able to do this by running fin phpunit <args> so the commands can be customised when executed. However, as the first half of the command (../vendor/bin/phpunit -c core) is consistent, I can wrap that within my custom command and not need to type it every time.

By using "$@" I can capture any additional arguments, such as the test directory path, and append them to the command to execute.

I’m using $PROJECT_ROOT to prefix the command with the absolute path to phpunit so that I don’t need to be in that directory when I run the custom command, and $DOCROOT to always enter the sub-directory where Drupal is located. In this case, it’s "docroot" though I also use "web" and I’ve seen various others used.

DOCROOT_PATH="${PROJECT_ROOT}/${DOCROOT}" DRUPAL_CORE_PATH="${DOCROOT_PATH}/core" # If there is no phpunit.xml file, copy one from elsewhere. # Otherwise run the tests. ${PROJECT_ROOT}/vendor/bin/phpunit -c ${DRUPAL_CORE_PATH} "$@"

For example, fin phpunit modules/custom would execute /var/www/vendor/bin/phpunit -c /var/www/docroot/core modules/custom within the container.

I can then wrap this within a condition so that the tests are only run when a phpunit.xml file exists, as it is required for them to run successfully.

if [ ! -e ${DRUPAL_CORE_PATH}/phpunit.xml ]; then # If there is no phpunit.xml file, copy one from elsewhere. else ${PROJECT_ROOT}/vendor/bin/phpunit -c ${DRUPAL_CORE_PATH} "$@" fi Creating phpunit.xml - step 1

My first thought was that if a phpunit.xml file doesn’t exist was to duplicate core’s phpunit.xml.dist file. However this isn’t enough to run the tests, as values such as SIMPLETEST_BASE_URL, SIMPLETEST_DB and BROWSERTEST_OUTPUT_DIRECTORY need to be populated.

As the tests wouldn't run at this point, I’ve exited early and displayed a message to the user to edit the new phpunit.xml file and run fin phpunit again.

if [ ! -e ${DRUPAL_CORE_PATH}/phpunit.xml ]; then echo "Copying ${DRUPAL_CORE_PATH}/phpunit.xml.dist to ${DRUPAL_CORE_PATH}/phpunit.xml." echo "Please edit it's values as needed and re-run 'fin phpunit'." cp ${DRUPAL_CORE_PATH}/phpunit.xml.dist ${DRUPAL_CORE_PATH}/phpunit.xml exit 1; else ${PROJECT_ROOT}/vendor/bin/phpunit -c ${DRUPAL_CORE_PATH} "$@" fi

However this isn’t as streamlined as I originally wanted as it still requires the user to perform an additional step before the tests can run.

Creating phpunit.xml - step 2

My second idea was to keep a pre-configured file within the project repository, and to copy that into the expected location. That approach would mean that the project specific values would already be populated, as well as any customisations made to the default settings. I decided on .docksal/drupal/core/phpunit.xml to be the potential location.

Also, if this file is copied then we can go ahead and run the tests straight away rather than needing to exit early.

If a pre-configured file doesn’t exist, then we can default back to copying phpunit.xml.dist.

To avoid duplication, I created a reusable run_tests() function so it could be executed in either scenario.

run_tests() { ${PROJECT_ROOT}/vendor/bin/phpunit -c ${DRUPAL_CORE_PATH} "$@" } if [ ! -e ${DRUPAL_CORE_PATH}/phpunit.xml ]; then if [ -e "${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml" ]; then echo "Copying ${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml to ${DRUPAL_CORE_PATH}/phpunit.xml" cp "${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml" ${DRUPAL_CORE_PATH}/phpunit.xml run_tests "$@" else echo "Copying ${DRUPAL_CORE_PATH}/phpunit.xml.dist to ${DRUPAL_CORE_PATH}/phpunit.xml." echo "Please edit it's values as needed and re-run 'fin phpunit'." cp ${DRUPAL_CORE_PATH}/phpunit.xml.dist ${DRUPAL_CORE_PATH}/phpunit.xml exit 1; fi else run_tests "$@" fi

This means that I can execute less steps and run a much shorter command compared to the original, and even if someone didn’t have a phpunit.xml file created they could have copied into place and have tests running with only one command.

The finished file #!/usr/bin/env bash #: exec_target = cli ## Run automated PHPUnit tests. ## ## Usage: fin phpunit <args> ## ## If a core/phpunit.xml file does not exist, one is copied from ## .docksal/core/phpunit.xml if that file exists, or copied from the default ## core/phpunit.xml.dist file. DOCROOT_PATH="${PROJECT_ROOT}/${DOCROOT}" DRUPAL_CORE_PATH="${DOCROOT_PATH}/core" run_tests() { ${PROJECT_ROOT}/vendor/bin/phpunit -c ${DRUPAL_CORE_PATH} "$@" } if [ ! -e ${DRUPAL_CORE_PATH}/phpunit.xml ]; then if [ -e "${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml" ]; then echo "Copying ${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml to ${DRUPAL_CORE_PATH}/phpunit.xml" cp "${PROJECT_ROOT}/.docksal/drupal/core/phpunit.xml" ${DRUPAL_CORE_PATH}/phpunit.xml run_tests "$@" else echo "Copying phpunit.xml.dist to phpunit.xml" echo "Please edit it's values as needed and re-run 'fin phpunit'." cp ${DRUPAL_CORE_PATH}/phpunit.xml.dist ${DRUPAL_CORE_PATH}/phpunit.xml exit 0; fi else run_tests "$@" fi

It’s currently available as a GitHub Gist, though I’m planning on moving it into a public GitHub repository either on my personal account or the Microserve organisation, for people to either use as examples or to download and use directly.

I’ve also started to add other commands to projects such as config-export to standardise the way to export configuration from Drupal 8, run Drupal 7 tests with SimpleTest, and compile front-end assets like CSS within custom themes.

I think it’s a great way to shorten existing commands, or to group multiple commands into one like in this case, and I can see a lot of other potential uses for it during local development and continuous integration. Also being able to run one command like fin init and have it set up everything for your project is very convenient and a big time saver!

Resources
Categories: Drupal

Pages