Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Oct 08 2020
Oct 08

If you've followed Pantheon's Build Tool Instructions and used Pantheon's Example Drops 8 Composer as the base to take advantage of CircleCI then you've encountered Behat tests. Behat tests are extremely valuable for testing site functionality before new code goes to production or a shared code stream. However, on a custom site these default tests provided by Pantheon are likely to fail if you've made even a benign change like deleting Tags vocabulary on a Drupal standard installation.

The first few times I encountered these tests and inevitable failures, I would summarily delete or comment out the Behat test and proceed with development as normal. "We'll come back to those later", I always said. One of the barriers to taking full advantage of the Behat scaffolding that Pantheon provided was that there wasn't obvious guidance on how to run the tests locally before they caused failures in CircleCI builds. 

However, with just a few file changes to your Lando-based project, you can have these tests running locally. Good test coverage can give developers confidence when pushing code and reduces the chance of breaking basic existing functionality. An investment in tests early in a project can save time and headaches later on and build confidence in the development team.

(These instructions assume Drops 8 2.3.1 composer-based installation.)

  1. Add a drush alias file with url and db-url settings to drush/lando.aliases.drushrc.php.1

    $aliases['epihc'] = array(
      'uri' => 'https://epihc.lndo.site/',
      'db-url' => 'mysql://pantheon:[email protected]:3306/pantheon',
  2. Add lando-specific behat config to tests/behat/behat-lando.yml.

            - FeatureContext
            - Drupal\DrupalExtension\Context\DrupalContext
            - Drupal\DrupalExtension\Context\MinkContext
            - Drupal\DrupalExtension\Context\MessageContext
            - Drupal\DrupalExtension\Context\DrushContext
            - FailAid\Context\FailureContext
          goutte: ~
          base_url: https://epihc.lndo.site/  # Replace with your site's URL
          blackbox: ~
          api_driver: 'drush'
            alias: 'lando.epihc'
  3. Add Behat tooling to the Lando config and restart/rebuild lando to .lando.yml.

        description: Run behat tests.
          - appserver: /app/vendor/bin/behat --config=/app/tests/behat/behat-lando.yml
  4. Run lando behat in terminal to run the tests.

The final task will be to update the Behat tests for your particular site's needs. Your main test file is at tests/behat/features/content.feature. Luckily Behat uses natural language and is pretty easy to write

Other things to know:

  • Check out your dev dependencies for the packages that are working together to make the tests Drupal friendly. The Behat Drupal Extension page has some good references.
  • We use Pantheon, Drops-8, and Lando as a starting point for many of our projects but other approaches are equally valid. 
  • If you need to debug the actual build process on CircleCI, go to .ci/test/behat/run
  • Behat tests aren't appropriate for every use case. Visual regression tests, linters, code sniffers, and/or unit test have their place as well. 

Hopefully these instructions will help you get started on your test-driven way!

1 Replace pantheon with drupal8 when using the drupal8 Lando recipe. This database setting is required for Behat to run drush commands. 

Paragraphs vs. ECK for Drupal 8

Jun 27 2016
Jun 27
Jun 27 2016
Jun 27

Paragraphs has become a popular site building tool for Drupal. In the feedback to our recent blog post, some asked why the Chapter Three team has not fully embraced the module. Most of our Drupal 8 sites use Entity Construction Kit with Inline Entity Form (ECK/IEF) to achieve what others do with Paragraphs.

Slice TemplateThe Slice Template design could be created using Paragraphs or Inline Entity Form.

This post seeks to explain why one might choose one module (or set of modules) over the other for semi-structured content in Drupal 8.

We'll be using our colloquial term "slice" to refer to a paragraph-like entity created with the ECK/IEF approach.


Both approaches allow for the creation of horizontal chunks of structured content that require no technical knowledge to create, and allow for flexible displays. Both work with Drupal's multilingual system. Both use Drupal's Entity API system, and are therefore fieldable. The theming experience of working with ECK and Paragraphs is similar; both return render elements and provide some template suggestions for bundles and view modes.

Site Builder Experience

After installation, Paragraphs are immediately available to be added to nodes. If you neglect to add paragraph types, you are given a convenient link to go do so.

The difference between a bundle and an entity can be a bit confusing the first time you use ECK/IEF.

First, set up ECK Entity types then Bundle types. Then add references to the Bundle type as a field on each Content type. Finally configure the form display on each Content type that uses Inline Entity Form. Additionally, each time you add a new Bundle type, you'll have to add it to each field that the type needs to make it available. The learning curve is small, but it exists nonetheless.

Winner: Paragraphs

Content Editing Experience

On the form configuration page you can choose whether (1) all form items are opened completely, (2) each paragraph is accessed by accordion, or (3) users see exactly what they see on the front end. You can also choose the display of the paragraph type selector. 

While you'll have to use the Inline Entity Form Preview (IEFP) module if you want preview display, all the other form options provided by Paragraphs (and more) are available using ECK/IEF. IEFP also provides the ability to choose a configurable "Preview" view mode. While this is extra site building work, it facilitates a better content editing experience. Rich content parts can be condensed and rendered in a more "edit-mode" appropriate way. For example, images can be set to render at smaller sizes, and entity references can be shown as labels, instead of rendering directly inline, etc. This can be managed on a case by case basis.

Working with many attached entities can be a slow and downright painful experience. Drupal's TableDrag functionality allows editors to re-order content parts, but doesn't perform very well with many pieces of content. All of these modules, and Drupal in general, would benefit from an investment in improving TableDrag functionality.

Winner: Tie
Comparison of Slice vs Paragraph Content Editing ExperiencesInline Entity Form next to Paragraphs in "Preview" mode. The content editing experiences of Paragraphs and ECK/IEF can be very similar.


Entity Reference Revisions is a requirement for Paragraphs so it is innately revision-friendly without any extra configuration.

Alas, there isn't any out-of-the-box support for revisions using ECK/IEF on Drupal 8 at the time of this posting. Contributors to this Drupal.org issue for Inline Entity Form, many of whom are Chapter Three employees, are working toward a solution. 

Winner: Paragraphs


Drupal's default search indexes Paragraph entities as part of their parent nodes without any extra configuration.

ECK entities are also indexed by core Drupal search. Just make sure that fields are being displayed, and users have permission to view the custom entities.

Winner: Tie

Reusable Entities

This issue sums it up. If you want to reuse the same paragraph on multiple pages, you're out of luck. It's possible, though, to reference other kinds of entities inside a paragraph.

You can easily reuse slices with the ICK/IEF set up. You can just as easily restrict that functionality from users. It's important to have strong naming conventions if your users can reuse entities. A potential drawback of the Entity system is that each entity/slice has a required title field whether you plan to display that title or reuse the content.

Winner: ECK/IEF


Configuration options are limited to exactly what is expected of the module. Use the included Paragraphs Type Permissions module for more user-level control.

With the ECK/IEF you have lots of options. You can limit which slice types are available to a field; you can change naming conventions in the UI; you can set permissions per type; you can choose whether or not the user can use existing slices; and much much more.

Additionally, ECK and IEF are useful for structured content that is not tied to a node nor should be classified as a paragraph type. In a recent project, we created Entities called "chunks" to hold things like accordion sets, newsletter links, calls-to-action, and featured content.

Winner: ECK/IEF

Unique URL

Paragraphs are only accessible by visiting the referenced container (like the node).

Each Entity has its own url. But in most cases, there's no need for these types of entities to have one and it's best to use a module like Rabbit Hole to obscure it.

Winner: Paragraphs


There are many blog posts, tutorials, and Drupal camp sessions dedicated to using the Paragraphs module as a site builder.

Beginner tutorials about ECK/IEF aren't as prevalent. If you get stuck on a custom feature, you may have to spend more time searching for answers. 

Winner: Paragraphs


The Paragraphs module is great for what it was designed. It is an easy-to-use solution to a common configuration problem. It is also the only Drupal contrib choice if you need structured content to be revisionable. Site builders without a development team, and those without the time or desire to dig in and customize the experience beyond Paragraphs' default offerings, will find it especially attractive.

Nearly the exact same functionality, however, can be achieved by using Entity Construction Kit and Inline Entity Form. While the initial set up may not be intuitive, and will take more time upfront to configure, it is also more extensible and customizable.

For smaller sites with simpler specs, Paragraphs might be all you need. If you're looking a more custom solution that can be extended in the future, Entity Construction Kit + Inline Entity Form is the way to go.

At Chapter Three, we build relationships with clients that often last for years. We know that priorities and technical specifications change. We typically choose ECK/IEF over Paragraphs either because of a particular specification in the initial build, or because we know we'll need more flexibility in the long-term. With a little more effort up-front, we deliver a first-rate content editing experience and meet the ever-changing needs of our clients.

Jacine LuisiJaesin MulenexDaniel Wehner, and Mark Feree contributed to this post.

Presentation: Drupal 8 Theming

Apr 27 2015
Apr 27
Apr 27 2015
Apr 27

This presentation was given at San Diego Drupal CampSan Francisco Drupal Users Group, and Stanford Drupal Camp.

The goal was to give users as a step-by-step instruction manual for building a theme in Drupal 8. While not a requirement, some familiarity with previous Drupal versions (and Drupallisms like 'node' and 'hook') will be helpful. The first half is the nuts and bolts details of name conventions and folder structures. The second half is all about the amazing things that can be done with Drupal's new theme engine, Twig. Anyone who has grumbled about adding that one extra div (or removing it) will be pleased at the unprecendented control that Drupal themers and front-end developers from any platform now enjoy. The included code samples can also be used as a bare-bones starter theme. 

Slides here: http://git.io/z-slides

See the latest code here: http://git.io/zakiya

Let us know what you think in the comments below!

About Drupal Sun

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

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

See the blog post at Evolving Web

Evolving Web