This first appeared as a guest post at Pantheon.io.
This post is for development teams tackling their first non-trivial Drupal 8 build, with multiple developers, and a timeline of several months.
At Jackson River, our teams consist of three lead folks in the following roles: project manager, backend developer, and frontend developer. We are each experienced in building Drupal sites, but this Drupal 8 build was a first for each of us. Our goal was to have a coordinated, sequential approach that supports an easy progression from one task to the next, allowing both developers to work simultaneously without getting in the way of each other. We’re here to share what has worked well for us and what we’ve learned.
Scoping New Features: The Technical Overview Document
Each time we scope out a new feature, it is added to a Technical Overview document outlining:
- Examples in designs
- An overview of the feature requirements
- Logic and workflow requirements that don’t work well in a structural build spreadsheet
- Implementation options* and directives, including possible build approaches and any definite requirements such as specific content types, blocks, views, or modules.
Note: It’s important to list implementation options for each requirement. For example, a landing page could be implemented as a panels page, a content type, or a custom route with blocks.
Once the entire list is assembled, both patterns and outliers become more obvious. This document then guides the more detailed implementation plan spreadsheet, which lists every content type, view, field, view mode, and more.
After initial discussion as a group to narrow down approaches, acquire assets, etc., backend and frontend development are able begin simultaneously.
Because we develop a pattern library based on designs once they’re provided to us, it is possible to go forward with layout and theming while configuration and custom module work are underway in parallel. We’ve found that the twig templating system makes it easy to dummy out blocks or pages, where variables from real content may be filled in later on.
An Example: Paging Through Content
Let’s say that we will have a queue of content (a series or list) we’ll want to page through in a certain order at the bottom of some pages. Since that queue will have metadata (such as a “series” title or description) and could be used in other contexts, it will be built as its own content type.
- Series content type / field configuration and testing
- Pager and styling, inclusion by content type/field values
Initial development is carried out in different Git branches in this project. We use a pretty linear branching model, based heavily on Vincent Driessen’s gitflow. Most work happens in feature branches, which then get merged into the develop branch. When we’re ready to deploy some work, we merge the develop branch into the release branch, remove development packages, then merge into master, which is always production-ready. We also have a sandbox branch/environment which is identical to master, for client testing.
Here’s our working branch list:
• config: for site configuration, content structure, and most custom modules (such as search functionality or custom field formatters)
• theme: for templates, styles, and supporting modules (such as those providing custom page routes or new twig filters)
• Other feature branches such as search and access-control
• develop: where the previous two branches meet for testing and implementation
• release: where deployable code is prepared, primarily by removing development packages
• master: production ready code
• sandbox: identical to master
While the series content type and supporting structure are being built in config, the actual pager theming can move along in theme. A great benefit here is that each branch generally represents different types of files and config. Most of the changes that happen in the config branch are in the config directory, but sometimes in custom modules too. Most of the changes in the theme branch are in the theme directory. So merge and sync conflicts are relatively uncommon, and analyzing them tends to be straightforward. Contrib module additions and updates can happen in either branch, so merging into develop frequently minimizes any potential conflicts.
In this example, we are adding a pager to the bottom of a content type. We can write the conditions into that content type’s template right away and then build a separate pager template for styling. The Twig file for that pager will at first contain dummy content (e.g. titles and link hrefs), so that we can test it out on our pages. Finally, that pager can be embedded in the actual pages for styling with example content.
When the series structure has been pushed from config to develop, the develop branch can be merged into the theme, so that the new content type is available to the front end.
Now we have data we can pull into the pager, so it’s time to write a Twig filter which will fetch a given page’s siblings in a series, and which can provide the right values to the embedded pager. Once that filter is tested and the previously-styled pager template has been updated to incorporate filter output (series item title, URL, etc.), the front-end work is complete.
The theme branch is now merged back into develop, and the feature is ready to test in an appropriate environment (perhaps associated with develop, or in another release branch).
At this point, the team can review the completed feature, and the project manager can contact the client regarding any questions that may have arisen in testing.
This approach has worked very well for us. In Drupal 7, merging and deploying configuration changes were fraught with merge conflicts and database update challenges. The uniform and widespread use of Drupal’s excellent configuration-management system has completely removed those headaches for us. And having theme work and config work happen simultaneously has saved time and allowed us to work as a closely-coordinated team on this project.