Mar 19 2020
Mar 19

It's a very sad week for us at Hook 42. COVID-19 has hit our clients and our families hard, and we regret to announce that we're closing up shop at the end of the month.

Hook 42 has been driven by our core values since we started in 2012: honesty, quality, community, ongoing improvement, work/life balance, and humor. We've loved being part of the open source community, in particular, the Drupal community all these years. We will always have fond memories of working with an amazing team, great clients, and wonderful community members.


drupal drop held up by community members with phrase it takes a village

The biggest reason we focused on Drupal all these years was because of the awesome people in the Drupal community. We've had so many fun and interesting times at Drupal events around the world, both big and small. From so many DrupalCons to the Santa Cruz and SF Drupal User Groups to BADCamp to Stanford Web Camp, it's always been a joy to hang out with the community at BoFs, sessions, after-hour events, and our favorite "hallway track".

We sincerely hope that we've made a positive impact on the Drupal community. We have engaged in many ways, through speaking, organizing, volunteering, mentoring, training, and code contributions, because we believe in open source and we believe in actively participating in the community to make it a better place for everyone.

As individuals, we hope to continue to be involved in open source communities in the future and look forward to seeing your wonderful faces again. Please feel free to reach out to us individually to connect.

Clients & Partners

We've had some amazing clients and partners along the way and want to give a big thanks to those both past and current. We wish you all the best. Please keep in touch!


We'll miss the Hook 42 team so much! We want to thank everyone on the team from the bottom of our hearts for being part of the Hook 42 family. We also sincerely thank all past "alum" team members as you are an essential part of our history.

The team has been an amazing bunch to work with, and you'd be lucky to work with them too. They are brilliant and supportive and always determined to do a great job. They go above and beyond to help each other, even now, during these difficult and trying times.

Here they are in alphabetical order with a short blurb that doesn't do them justice. Please reach out to them if you are looking for amazing team members. Contact us directly if you want any additional information. They all have our sincere endorsements.

Note: We've worked with many other great team members not listed here but we've focused on people who are either current employees or contractors who've recently worked 15+ hours/week for several months.

Chris Darke | Senior Developer

Chris is a veteran on the team and is open to working on almost anything. He's a versatile full stack developer who's got strong expertise in Drupal, React, Elasticsearch, and AWS microservices. When not geeking out, he's also keen on the outdoors and enjoys scuba diving, biking, surfing, and photography. We'll miss Chris' British accent and warm humor.

For more details, check out Chris' profiles: Hook 42 | LinkedIn | Drupal.org

Darryl Richman | Senior Developer

Darryl's been creating awesome Drupal sites since 2007 and has been with Hook 42 since 2013! With an eye for detail, he's a solid backend developer who's well versed in module development, site building, databases, and migrations. When not coding, Darryl is often traveling around the US and Europe on his motorcycle. We'll miss hearing about Darryl's grand adventures and getting his advice on beer and BBQ.

For more details, check out Darryl's profiles: Hook 42 | LinkedIn | Drupal.org

Ellen Doornbos | Developer

While one of our newer team members, we've been super impressed with Ellen's attention to detail, communication, and positivity. She's a certified accessibility expert and a great backend developer. She has helped our team with automation tools, migrations, audits, custom modules, and even some front-end theming. When not doing tech, Ellen can be found crafting or in the garden cultivating her wildflowers. We'll miss Ellen's earnestness and helpfulness.

For more details, check out Ellen's profiles: Hook 42 | LinkedIn | Drupal.org

Jason Flatt | Senior Developer

Jason has been with the team a long time and his attention to detail and dedication is amazing. He's a strong backend developer who can architect great solutions with Drupal or Backdrop, and has been working with Drupal since 2004. When Jason's not working, he's spending time with his family, or working on personal software projects because he enjoys software development so much. We'll miss Jason's dry humor and straightforwardness.

For more details, check out Jason's profiles: Hook 42 | LinkedIn | Drupal.org

Jonathan Daggerhart | Architect

Jonathan is a very experienced architect and full stack developer who can tackle any Drupal or WordPress project with ease. He can create solid modules, plugins, and themes of any complexity with smart architectures that follow best practices. Jonathan has been a great mentor to others on the team, taking personal interest in the growth and success of every team member who reaches out for help. When not doing tech, he enjoys role-playing games and watching movies. We'll miss Jonathan's Southern accent and charm.

For more details, check out Jonathan's profiles: Hook 42 | LinkedIn | Drupal.org

Joseph Flatt | Developer

Joseph is one of the youngest Drupal developers we've known, but don't let that fool you. He's a very experienced backend developer who started programming in his teens. Joseph is skilled with both Drupal and Backdrop. Joseph has a passion for improving website performance and solving Rubik's cubes. We'll miss hearing about Joseph's latest personal record-breaking Rubik's cube solves on meetings.

For more details, check out Joseph's profiles: LinkedIn | Drupal.org

Kristen Littlefield | Project Manager

As one of the newest team members, Kristen dove in and picked up a bunch of client projects without missing a beat. She's a veteran PM, mostly in the web development space, whether it be a Drupal or WordPress website and a focus on digital accessibility. When not managing web projects, she gracefully manages a busy household and enjoys hosting football parties. We'll miss her compassion and fun-loving spirit.

For more details, check out Kristen's profiles: Hook 42 | LinkedIn

Melissa Kraft | Project Manager

Melissa joined the team when there was a huge need for project management and she didn't even bat an eye. We were amazed at how little time it took to transition the projects to her and getting feedback from the clients on how impressed they were with her skills. Melissa has worked with web projects for many years and it shows. She's also great at whipping up new recipes for her family and friends. We'll miss Melissa's candor and upbeat attitude.

For more details, check out Melissa's profiles: Hook 42 | LinkedIn | Drupal.org

Lindsey Gemmill | Senior UX Designer

Lindsey's title is Senior UX Designer, and she has amazing design, UX, branding, and accessibility skills (a Certified Web Accessibility Professional). If that isn't enough she has also been our entire marketing department. She ran our social media, created landing pages, wrangled the team to write blog posts, created marketing roadmaps, rebranded the company, and much more. She's incredibly fast, creative and proactive. When unplugging, Lindsey likes to go to the beach and camping with her dogs. We'll miss Lindsey's can-do attitude and passion.

For more details, check out Lindsey's profiles: Hook 42 | LinkedIn | Drupal.org

Michelle Darling | Front End Developer

Michelle is our newest team member and in a very short time has shown us that her capabilities extend well beyond our expectations. Michelle showed off her serious front-end mastery by jumping right into projects that needed her expertise. Whether it's Drupal, WordPress, or Shopify, she's got the front-end covered while ensuring accessibility and usability are front and center. When not at work, Michelle can be found outdoors on a hike, reading, and enjoying music. We'll miss Michelle's determination and good attitude (and her great hair!).

For more details, check out Michelle's profiles: Hook 42 | LinkedIn | Drupal.org

Ryan Bateman | Architect

Ryan Bateman started with Hook 42 as a developer and quickly proved his chops to be promoted to senior developer and then architect. He's a very skilled full stack developer in Drupal, React, Gatsby, among other web systems and frameworks. When not producing awesome websites or mentoring team members, Ryan can be found doing all-things-outdoors in Alaska, or even hosting his own radio show. We'll miss Ryan's conscientiousness and thoughtfulness.

For more details, check out Ryan's profiles: Hook 42 | LinkedIn | Drupal.org

Ryan Nelson | Director of Operations & Projects

Ryan Nelson has been an integral part of the team for almost a year and worked closely with Aimee in a previous company. He is a master of calm and can talk with anyone about anything. With 20 years' industry experience under his belt, he helped with so many things that it's hard to list but includes strategy, hiring, operations, HR, project management, process improvement, accounting, and people management. He's been the "go to" person on the management team for anything and everything. When not at work, Ryan enjoys traveling the globe (he has been to 5 continents!) and spending quality time with his wife. We'll miss Ryan's pleasantness and good humor.

For more details, check out Ryan's profiles: Hook 42 | LinkedIn | Drupal.org

Will Long | Senior Developer

Will's a very seasoned senior Drupal and PHP developer who you can throw any project at. Whether its complex business logic, a difficult migration, or streamlining a CI environment, he thrives on solving difficult problems. When not in the tech world, Will enjoys hanging out with his family and friends. We'll miss Will's positivity and grit.

For more details, check out Will's profiles: LinkedIn | Drupal.org

What's Next?

As one door closes, others open. What's next for the amazing people that were part of the Hook 42 adventure?


We were planning on going to DrupalCon Minnesota as a team. Sadly, that won't happen. But Hook 42 has four confirmed speakers: Jonathan, Ryan, Aimee & Kristen. Aimee & Kristen still plan to speak at DrupalCon, and we're hoping to meet up with Hook 42 alums at the event when it does happen. We have other events penciled in as well such as Stanford Webcamp, GovCon, and BADCamp, so we're sure we'll see you in the Drupalverse in the future.

If you are looking for speakers, mentors, volunteers, trainers, etc., ping us and we'll see what we can do!


We're placing some clients with the team members to continue projects. For other clients, we've been reaching out to web agencies who might be a good fit for future support.

If you are potentially interested in client introductions, please let us know and provide your current rate sheet or typical blended rate, so we can see if it aligns with current contracts. We will only introduce clients if it is a good fit for the client and for the agency or contractor.


The team members above are open to new opportunities. We can vouch for them and they'll vouch for each other. Maybe grab a few and you'll have a ready-made team! :)

If you have contract or employee opportunities, you can also send them to us directly and we'll pass along the information as we'll be in communication with the team in the coming weeks to help find them new work homes.

Aimee and Kristen

illustration of kristen and aimee

With Hook 42 going away, Aimee & Kristen will be spending time with their families and figuring out what the future holds. We could not have created such a wonderful company without the love and support of our friends and family. Thank you for the many hours of support you have given the both of us over the years.  We are open to discuss opportunities!

Aimee is passionate about accessibility, multilingual, and web architectures. After a much-deserved break to care for herself, her family and to dance. Aimee is looking forward to opportunities to follow her passions to support learning, growth, and community. She’ll be finally back in the Drupal issue queues instead of mentoring and supporting other’s contributions in the queues - she’s missed the hands-on work and loves the technology. 

To connect, check out Aimee's profiles: Hook 42 | LinkedIn | Drupal.org

Kristen is planning for some much-needed rest and reconnecting with her kids, husband, and mom. Then, she's hoping to get back into the Drupal issue queues for a bit because she finds that fun! :) After recharging and contributing, she'll be looking for something different in the next chapter, and is open to ideas, however crazy they may seem!

To connect, check out Kristen's profiles: Hook 42 | LinkedIn | Drupal.org

Both of us hope to say "hi" in person to former Hook 42 and client team members as well as community members as soon as the quarantines are over!

so long and thanks for all the fish


the word bye in 8 languages around the drupal drop
Mar 13 2020
Mar 13

There’s bad data everywhere, but nowhere is it more insidious than when you encounter it for the first time while trying to migrate a website. Bad data, in this case, is defined as any data that doesn’t conform to the expectations of the migrator and their code, whether that’s because of bad data entry, surprising contextual requirements, or historical changes in value patterns. It can come at you from a variety of directions and can have surprising origins. Discovering your bad data early, and the reasons for it, can point to issues that may exist in other parts of the migration and can also give you clues on how to effectively deal with it.

Forewarned is forearmed, so identifying bad or surprising data early allows your migration to go more smoothly and will make your client a lot happier. Here are some approaches and tips to make that migration go more smoothly.

Finding Bad Data

You may have already created a set of spreadsheets for the new site that indicate where the content in the old site is coming from, and what transformations may be needed to get it there. Just assuming that you know what the data in the old site looks like, however, is a pitfall waiting to snare you. Even if you’ve looked at a handful of records for each source object or field, you may not find the data that’s in there waiting to bite you and your migration code.

For many fields, it can be useful to do queries on a snapshot of the old database. Fields that have a limited number of distinct values should have a distinct() query run against them. For example, a field that should have a ‘Y’ or ‘N’ value, may also have ‘y’ or ‘n’ values, too, or even ‘true’, ‘false’, 0, 1, ‘’, NULL, ‘t’, ‘f’, and so on.  Find all the outliers before you begin coding, so you can take them into account. For a yes/no field like this, you may want to code a process plugin that can interpret all of them into a single pair of values that you can then reuse on other fields in your migration.

Date Data

Dates are particularly troublesome fields. If the old database field is not in ISO date format, you may find that dates are recorded in all sorts of ways. Converting them all correctly for use in a MySQL date or datetime field can be difficult. Often the easiest thing to do is not try to do it yourself, but rather use PHP’s strtotime() function. But that may not be good enough if your dates might be outside of the timestamp epoch (roughly, 1970 - 2038). Then you’ll have to fallback on PHP’s date class.

This brings up the next issue with dates:  they may have contextual problems. Is it ok if you find a date that’s 100 years in the future or 100 years in the past? Often, dates need to be range checked somehow.

Another problem dates can have is timezones. Often, dates don’t have an associated timezone in a database. You may need to know the default timezone for the old system, or perhaps where the client is located. Timezone date calculations are surprisingly finicky to get right.

Deeper Waters

If there are unstructured text fields in the old data, you may need to watch out for data that is outside the “normal” 7 bit ASCII code page. Even Western European languages have codes outside of this range, things like ø, ç, ü and so on, including currency signs like £ and €. Then there is multibyte string data, used for representing characters on the vast number of code pages for languages that use other alphabets or other special-purpose glyphs, like for math and physics.  

There can also be problems with characters that have been entered for various symbols: emojis that employ character codes that are specific to Windows or the Mac and cause problems in their native forms.

If your MySQL database is not set up right, it might reject inserting such data. Choosing a “reasonable” format can be a challenge sometimes, but usually, the better answer is to detect these situations and write some custom code to fix them, to convert the wacky characters into something acceptable and displayable.

Unstructured Text

A common problem often seen when migrating older Drupal sites, but can also happen with other technologies as well, is that text fields will have self-referencing data encoded in it. A very common situation is that images on the site are inserted into the text with an <a> tag:  < href="https://www.hook42.com/blog/successfully-migrating-bad-data-drupal/sites/default/files/my_file_name.jpg">, for example. This may not work correctly on the new site, especially if, as a part of the migration, the existing files have been reorganized.  

In Drupal 7 sites, you may instead see a blob of JSON that is a media entity reference. You will have to find these and use the mapping tables created when the media entities were migrated to change them. You will probably have to find another way to deal with them, as media entities in Drupal 8 are not yet integrated into the default CKEditor WYSIWYG fields.

Getting Cozy with Your Data

While investigating the existing data, be sensitive to changes in patterns. Maybe you’re dealing with an e-commerce system and the states that an order goes through start having a different pattern at some point in time in the data. This can indicate a point when the old system was modified or upgraded, and your assumptions about what data you’ll see and how to migrate it across to the new system need to take this into account.

This is true especially if you’re migrating off a system that no longer has any technical support. Maybe because the company that implemented isn’t around anymore or is otherwise not available, or the software in use is obsolete. You may have to guess how data objects are constructed out of the database tables. There may be extra tables no longer in use - but do they have historic information that you should be capturing and moving? You will need to have several sessions with the client to ask them about particular examples in their data. Puzzling this out when the client themselves doesn’t know how their system works can keep you up at night.

You’ll have to try to rebuild the original designer’s mindset to understand how they structured the data. If the data has any complexity to it, you will have to learn how related data objects are referenced, and rebuild these connections correctly in Drupal.

Sometimes references are conditional on the state of one or more fields. For example, if there’s an original order field in the order table, maybe that is only filled in when this order is actually a return. What does the order total field represent in this case? Should it be positive or negative? These are the kinds of issues to be sensitive to. Often an initial audit of an old site won’t find these items.

Data Issues at Many Levels

These are just a few areas where problems pop up when migrating into Drupal. Issues pop up in the raw data, in the context around the data and in the actual meaning of the data. Finding and fixing these can require a great deal of careful testing and creative solution development. Being aware of the issues beforehand and following through during development can lead to a smoother, faster migration process, and a fuller understanding of what problems the client is trying to solve.

Remember to use your favorite database tool to investigate your incoming data fields like the ones above: 

  • Look at select and checkbox lists to verify that the values are consistent throughout.  
  • Check date fields for good and consistent formatting and “reasonable” data ranges, and consider if there are any timezone issues. 
  • Look at the content of unstructured text.  Are there character set issues?  Internal HTML references to the old site, especially regarding images?
  • Be sure to deeply investigate how the old system is structured, especially if you don’t have access to a technical resource for the old system. Verify that you understand how, and why, the data in the old system are structured the way they are.
Feb 28 2020
Feb 28

Last Updated March 7, 2020

This article is a summary of the state of Drupal 9 along with lists of key dates, ways to contribute, and other resources. If I missed any important information or there's a mistake, please contact me via email or, more reliably, via Twitter, and I'll try to update the post quickly.

In this article, I will cover:

What's Special About Drupal 9?

Drupal 9 is obviously the "major version" after Drupal 8, but there is something particularly special about Drupal 9. Where previous major versions have often departed wildly from their predecessors (looking at you Drupal 8!), Drupal 9.0 will be functionally equivalent to the final minor version of Drupal 8. The exact final minor version number will depend on when Drupal 9.0 is ready.

According to the Drupal.org D9 docs:

"Drupal 9 will be a cleaned-up version of Drupal 8. It will be the same as the last Drupal 8 minor version with our own deprecated code removed and third-party dependencies updated."

This is good news as it makes updating from Drupal 8 to Drupal 9 much, much easier than for previous major version updates. To see a video of updating a simple site, check out the DrupalCon Amsterdam Driesnote starting at around 43:10 minutes. And, to get a really nice overview of the Drupal 9 release, I highly recommend looking at the D9 slides created by Gábor Hojtsy. As an added bonus, these slides have been made available for anyone to present at any event around the world.

Illustration of Drupal 8 on same "release track" as Drupal 9 compared to older versions of Drupal via drupal.org/docs/9/how-drupal-9-is-made-and-what-is-included Illustration of Drupal 8 on same "release track" as Drupal 9 compared to older versions of Drupal via drupal.org/docs/9/how-drupal-9-is-made-and-what-is-included

Deprecation & Third-Party Dependency Updates

The two areas that need to be addressed to make Drupal 9 a reality are 1) removing deprecated code, and 2) updating third-party dependencies.

Deprecated code is old code that has been replaced with new code while the old code remains to ensure backward compatibility. With deprecated code, the intention is always to remove it at some point. Any code that relies on deprecated code will obviously break once the deprecated code is removed. Thus, Drupal core and contributed projects that want to support the Drupal 9 version need references to all deprecated code removed. There are already a number of issues open to fix these outlined in the stats section later.

Drupal 8 leverages many third-party software libraries including CKEditor 4, jQuery UI 3.2, Twig 1, and Symfony 3. Since Drupal exposes third-party APIs, when these APIs change, it affects Drupal's backward compatibility. Drupal only breaks backward compatibility in major version updates.

For Drupal 9, some key third-party libraries will be updated and some won't be updated to their most recent major releases. Because CKEditor 5 has changed the editor architecture significantly and CKEditor 4 is supported until 2023, CKEditor 5 will be updated in Drupal 10 and will be optional in Drupal 9. On the other hand, the jQuery UI dependency is being phased out, so only a subset of the library will be available in Drupal 9. On the front-end, Twig 1 will be updated to Twig 2.

The most pressing lifecycle impact is that Symfony 3 has an end of life in November 2021. Drupal 9 will use Symfony 4.4 which was recently released. To give ample time to update Drupal 8 sites, the D9 planned release date is June 3, 2020. If that date slips, the backup plan is to release Drupal 9 by the end of 2020. See the estimated dates below.

Symfony releases calendar via symfony.com/releases Symfony releases calendar via symfony.com/releases 

Recent Stats

Here are some approximate Drupal stats based on recent data. Note: Some drupal.org issues aren't tagged "properly" so there may be other issues not represented below.



Contributed Project D9 Issues: "Drupal 9 compatibility" tag

  • Open: 788+
  • Fixed/Closed: 738+

Core D9 Issues: "Drupal 9" tag and 8.x version, or 9.0.x-dev version

  • Open: 447+
  • Fixed/Closed: 566+

Top 200 Modules D9 Status

  • From DrupalCon Amsterdam Driesnote
    • Ready Now: 32 (16%)
    • Pretty Close: 100 (50%)
    • Needs Work: 68 (34%)
  • As of March 7, 2020 from Drupal 9 Deprecation Status
    • No Problems Found: 50 (25%)
    • All Problems Fixable Now: 33 (16.5%)
    • Some Problems Fixable Now: 79 (39.5%)
    • Needs Manual Review: 30 (15%)
    • Only Problems Fixable Later: 2 (1%)
    • No Results: 6 (3%)
Graph of top 200 modules' D9 status from https://dev.acquia.com/drupal9/deprecation_status Graph of top 200 modules' D9 status from dev.acquia.com/drupal9/deprecation_status

Core Usage: 1,044,972

  • 5.x: 509
  • 6.x: 36,187
  • 7.x: 706,978
  • 8.0.x to 8.8.x: 301,243
    • 8.0.x: 1,328
    • 8.1.x: 1,992
    • 8.2.x: 3,786
    • 8.3.x: 7,374
    • 8.4.x: 5,380
    • 8.5.x: 19,424
    • 8.6.x: 39,472
    • 8.7.x: 88,386
    • 8.8.x: 134,101
  • 8.9.x: 54 (may be inaccurately reported in the usage tracker)
  • 9.x: 0

Builtwith Usage

Drupal 8 usage via trends.builtwith.com/cms/Drupal-8 Drupal 8 usage via trends.builtwith.com/cms/Drupal-8

Key Dates

Future dates are estimated and are based on major and minor releases. The releases are happening every 6 months on the first Wednesday of the month. Additional dates are available in the release cycle documentation.

Quarterly timeline of Drupal 9 releases and Drupal 7 & 8 end of life via https://www.drupal.org/docs/9/drupal-9-release-date-and-what-it-means Quarterly timeline of Drupal 9 releases and Drupal 7 & 8 end of life via drupal.org/docs/9/drupal-9-release-date-and-what-it-means

Pre D9 Release

D9 Release

  • Beta Requirements Done by March 13, 2020
    • Mar 2020: 8.9.0-beta1 & 9.0.0-beta1 Releases
    • May 2020: 8.9.0-rc1 & 9.0.0-rc1 Releases
    • Jun 2020: 8.9.0 & 9.0.0 Releases
  • Beta Requirements Done by April 28, 2020
    • Apr 2020: 8.9.0-alpha1 Release
    • May 2020: 9.0.0-beta1 Release
    • Jun 2020: 8.9.0 Release
    • Aug 2020: 9.0.0 Release
  • Beta Requirements Done by August 31, 2020
    • Apr 2020: 8.9.0-alpha1 Release
    • Jun 2020: 8.9.0 Release
    • Aug 2020: 9.0.0-beta1 Release
    • Dec 2020: 9.0.0 Release

Post D9 Release

Drupal 10 Release!

Drupal 9 Coordinators

Lots of people are working on Drupal 9, but here are the coordinators from the D9 initiative page.

Drupal 9 Coordinators via drupal.org/about/strategic-initiatives/drupal9 Drupal 9 Coordinators via drupal.org/about/strategic-initiatives/drupal9

Gábor Hojtsy

Jess (xjm)

Nathaniel Catchpole (catch)

Ryan Aslett (mixologic)

Checking Status

Drupal 9 is always changing, so here are some ways to keep in the loop.


Even if you don't have your own Twitter account you can check these accounts for regular Drupal 9 updates.

Twitter account @DropIsMoving maintained by @webchick and @gaborhojtsy at twitter.com/dropismoving Twitter account @DropIsMoving maintained by @webchick and @gaborhojtsy at twitter.com/dropismoving


Drupal 9 readiness meetings generally happen every 2 weeks on Mondays so you can join the meeting (in Slack) or check the meeting notes afterward.

Kanban Board & Issue Queues

  • Tag: Drupal 9 Compatibility (Contributed Projects)
  • Tag: Drupal 9 (Core)
  • Branch: Drupal 9.0.x-dev (Core)

Ways to Contribute

There are many ways to contribute to Drupal 9. Remember, you don't have to be a coder to help out! Here are some ideas:

Tag issues for removing deprecated code

There was some previous confusion as to what tags to use for issues related to removing deprecated code in preparation for Drupal 9. People used many tags including "Drupal 9", "Drupal 9 compatibility", "Drupal 9 readiness", "D9Readiness", "D9 port", "D9 upgrade path", "Drupal 9 Deprecated Code Report", and "Drupal 9 Deprecated Code Report and dependency injection issues".

After a discussion in November in the Slack #d9readiness channel with Gábor Hojtsy, we've clarified the tags that should be used. Please avoid using other tags and use the following, so that it is easier to find issues to work on. At that time, I went through many issues to update their tags to match these guidelines. There are likely some that were missed, so if you see issues that aren't tagged or are using different tags, please update them. When making new issues, keep these in mind as well.

  • "Drupal 9" - This is for core issues for D8 versions as it was used before the D9 branch was available. For changes happening on the D9 branch, this tag is unnecessary.
  • "Drupal 9 compatibility" - This is for contributed project issues.
Issues tagged with "Drupal 9 compatibility" in drupal.org issue queue Issues tagged with "Drupal 9 compatibility" in drupal.org issue queue

Create issues for deprecated code

There are lots of contributed D8 projects that can be updated. Check the issue queue first to make sure the project doesn't have an issue created already. Then you can use the deprecation checking tools to see if there are issues. If there aren't deprecation problems, it's still good to create an issue and then mark it as fixed so it's clear that the code has been checked.

When creating new Drupal 9 issues for contributed projects, please use the "Drupal 9 compatibility" tag rather than other D9 tags that are listed above. When creating new Drupal *core* issues, you don't have to tag them as long as you're using the 9.0.x-dev or 9.1.x-dev for the version. If you have a Drupal 8 issue that needs to be tagged for D9, use the "Drupal 9" tag.

Create, review, and/or test patches to fix deprecated code

You can search for issues using the Kanban boards and issue queues (see above). If you know how to create patches, many of the updates are straightforward. The issues should have a report of what is deprecated and needs updating. If not, use the deprecation checking tools. If you don't know how to create patches, but can review code, you can review existing patches to make sure they fixed the deprecations correctly.

Help with stabilizing experimental Drupal 8 core code

There are some experimental projects that need finalizing before 8.9 so they will make it into D9 as stable. Here are some issues that you can help with to make that happen.



Participate in strategic core initiatives

There are always strategic core initiatives in progress, and there are some exciting ones for Drupal 9 that could use your help. If you have ideas for other initiatives, discuss your ideas in the #contribute Slack channel.

In addition, there are some active D8 initiatives that will benefit Drupal 9. Some are more active than others. Check out the issue queues for activity:

Training, Speaking, or Mentoring at Events

Spread the word about Drupal 9 by going to local, regional, or international events. Check out Drupical to find Drupal-specific events, but also consider going beyond these into the wider tech world to help with Drupal adoption. If you like speaking at events, Gábor Hojtsy has provided "State of Drupal 9" slides for anyone to use. If you find any mistakes or have suggestions, leave comments on the slides. For contribution sprints, you can mentor other community members and help them work on Drupal 9 issues.

Additional Resources

There are many Drupal 9 resources available, but here are some to start with:

And Remember…

"The big deal about Drupal 9 is … that it should not be a big deal." -Dries

p.s. A big thank you to Lindsey Gemmill for her review and painstaking formatting of this post! And thanks to Gábor Hojtsy for reviewing and providing feedback and more resources.

Last Updated March 7, 2020

  • MARCH 7, 2020: Updated mostly based on feedback from Gábor Hojtsy
    • Added more links to resources section
    • Updated the top 200 modules' D9 status data
    • Adjusted key dates alpha and beta info
    • Updated link to last D9 readiness meeting
    • Added some images so this isn't just a wall of text :)
Feb 21 2020
Feb 21

Horray! Today is the day. We are officially announcing our return to DrupalCon 2020 in Minneapolis. We're sorry we kept you waiting so long, but we were still finalizing some moving pieces. With the recent announcement of accepted sessions for this year's DrupalCon, the cat is finally out of the bag.

This year we will be fully immersed in all things Drupal and open source. Some of our team will be leading sessions, some mentoring, and some manning a booth. Whatever it is, we're excited for another fun conference filled with amazing opportunities to learn and grow from fellow community members. We're honored to be able to be involved, to be sponsoring, and to be part of a community that has proven time and time again to be inclusive and open to curious minds.

Accepted Sessions

We'll start first by telling you what exactly it is we'll be talking your ears off about this year. While we're in Minneapolis for DrupalCon 2020 you can look forward to a diverse lineup of topics. Although the full schedule is to be determined, and don't worry we'll update you on when you can hear one of our sessions a little later, we're anxious to let you know what we know. For now, here are the topics you can expect to hear from our team.

Build Healthy Multilingual Relationships: Nest Entities Correctly

First up, we have CEO Aimee Hannaford teaming up with Christian López Espínola from Lingotek to give a great session about multilingual relationships...in a matter of tech speak of course!

As component-based design principles evolve, the actual implementation in Drupal can be performed in many ways. Most, if not all, component-based site building approaches rely on Entity Relationships. Adding multilingual support that is Correct and Predictable can be a challenge to configure. In this session, we'll surface best practices of Multilingual configuration with entity relationships.

You can read the full session description for healthy multilingual relationships on the DrupalCon website.

Progressively Enhance your Workflow with CI: A Roadmap

Next, we have another duo working together, architects Jonathan Daggerhart and Ryan Bateman. Together they are teaming up to provide a clearer pathway to integrating CI into your project process.

Adding Continuous Integration (CI) services to projects is often seen as an expensive and time consuming operation. At worst, clients may even perceive CI as an expensive set of developer tools that rarely benefit a project in any meaningful way. However, by changing our perspective and looking at CI as a progressive enhancement, slowly adding more and more helpful automations to our projects, CI can become the time-saving technology many projects desperately need.

You can read the full session description for progressive CI workflow on the DrupalCon website.

Getting Started With Nightwatch.js For Automated Testing

Architect Jonathan Daggerhart will be leading a solo session built around the capabilities of Nightwatch.js and Drupal. By the end of this session, you should be very familiar with the capabilities of Nightwatch.js, how you can use it for functional testing of any website (including your Drupal sites), as well as use it for unit testing your contributions to Drupal.

You can read the full session description for Nightwatch.js and Drupal on the DrupalCon website.

Preparing yourself and your site for Drupal 9

Last, but certainly not least, we have CTO Kristen Pol leading a session on a particularly hot subject...how do you prepare yourself for Drupal 9? The release of Drupal 9 is fast approaching, hopefully on June 3, 2020 but, worst case, by December 2020. Drupal 9 is a large departure from previous major releases. The only changes between Drupal 9 and the last release of Drupal 8 is it will have deprecated code removed and 3rd party dependencies updated. This will make it the easiest upgrade ever.

You can read the full session description to prepare youself, and your website, for Drupal 9 on the DrupalCon website.

Women In Drupal Sponsorship

We are proud and honored to be part of a community that acknowledges a safe space for women. As a woman-owned business, we are excited to be sponsoring the Women in Drupal Lunch again for DrupalCon 2020. Last year we led a Q&A session with those who attended our lunch to get each other talking about the ups and downs we've had along the journey to success within the tech community. To prepare yourself for what that might sound like this year, you can read some reflections from our owners about what it's like to be a woman in technology from our post last year on women's equality.

With all of that said, we're looking forward to another great opportunity to connect with the women, and those who support them and identify as them, in our community. We can't wait to see you all again. Also, we'd like to take this as an opportunity to welcome all newcomers too. The more the merrier!

We're Feeling Boothy

We have made one of the biggest commitments ever this year, by having a booth for the entire duration of DrupalCon. We wanted to make sure you'd always be able to find us while we're there. Whether you have questions about services we offer, a session we've given, or you're just looking for an old friend to say hello to, now you'll know exactly where to find us!

Our team cannot express enough just how excited we are to be returning for another DrupalCon. We hope you all share the same excitement as we do, and look forward to the journey we're about to embark on together. 

Feb 13 2020
Feb 13

Welcome! If you need to update your Drupal 8 site to the latest feature branch, this post is for you. 

Drupal 8.8.0 introduced many exciting changes. On the heels of this release, we also saw a security release for Drupal 8.8.1, which covers four distinct security advisories (SAs). Drupal 8.7.11 also has fixes for those SAs, but developers might consider this a golden opportunity to take care of both updates at once.

This post will cover four common pitfalls of upgrading to the 8.8.x branch:

  • Pathauto version conflicts
  • New sync directory syntax
  • Temporary file path settings
  • Composer developer tools


These instructions assume you are:

  • Maintaining a Drupal 8 site on version 8.7.x
  • Using Composer to manage dependencies
  • Comfortable using the command line tool Drush

Pathauto version conflicts

The Pathauto module has been around for a long time. With over 7 million downloads and 675K reported sites using Pathauto, chances are high that this section applies to you.

Drupal core 8.8.0 introduced the path_alias module into core. However, this module conflicts with the Pathauto contrib module at version 8.x-1.5 or below. If you have Pathauto installed on your site, you must first update to Pathauto 8.5-1.6 or later. 

I strongly suggest updating Pathauto as a first step, and deploying all the way to production. The order of operations is important here, because updating Pathauto after core will result in data loss. While the release notes say it is safe to update “before or at the same time” as core, it is good to have some extra precaution around the sequence of events. 

Visit the full change record for more details: Drupal 8.8.0 requires pathauto version 8.x-1.6 or higher if installed.

Diagnosing path alias issues

What if I neglect to update Pathauto? How can I identify the symptoms of this problem? After running drush updb, I would expect to see this SQL error:

[error]  SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '7142' for key 'PRIMARY': INSERT INTO {path_alias}

This Drupal core bug report provides more detail. It also describes how to walk it back to a working state if you encounter this problem.

New sync directory syntax

The configuration management system introduced a new sync directory syntax for 8.8.0. The default location for Drupal’s config sync is sites/default/files/config_[HASH]. It is very common practice to customize this location. It makes config files easier to understand and manage. If you do customize this location, note that Drupal no longer uses the $config_directories variable. 

Here is what a custom config sync directory might have looked like in Drupal 8.7.x or lower. In your settings.php file:

$config_directories['sync'] = dirname(DRUPAL_ROOT) . '/config';

Now in Drupal 8.8.x, this setting should be updated to look like this:

$settings['config_sync_directory'] = dirname(DRUPAL_ROOT) . '/config';

Read the full change record for more technical details: The sync directory is defined in $settings and not $config_directories.

Diagnosing sync directory issues

You can tell right away if there is a problem with your sync directory if config files are showing up in an unexpected place. You can also use drush to discover the current value of your config sync directory. 


$ drush php
>>> Drupal\Core\Site\Settings::get('config_sync_directory')
=> "/var/www/html/foo/bar"


drush php-eval '$path = Drupal\Core\Site\Settings::get("config_sync_directory"); print $path;'

Here are a few more ways to retrieve the same information, using the drush status command.

For Drush 8 only:

drush status config_sync

For Drush 9 or 10:

drush status --fields=%paths

Temporary file path settings

In this new feature release, the old procedural function file_directory_temp() is deprecated. Drupal now uses the FileSystem service instead, and this has implications if you are setting a custom value for temporary file storage.

To customize the temporary file location the old way, you may have something like this in your settings.php file:

$config['system.file']['path']['temporary'] = '/tmp';

Change this setting to the new syntax before running database updates:

$settings['file_temp_path'] = '/tmp';

Read the full change record to learn more: file_directory_temp() is deprecated and moved to the FileSystem service.

Diagnosing temp directory issues

Take a look at your database logs. In Drupal’s logs at /admin/reports/dblog, you can filter on “file system”. Any errors about temporary file placement may indicate an issue.

Composer developer tools

Composer Support in Core is just one of many strategic initiatives in the Drupal community. Some early ways of using Composer are now deprecated in favor of this new support. For example, Drupal now has an official Composer template project. If you used the unofficial template (but recommended at the time) drupal-composer/drupal-project to install Drupal before, you will have a bit of updating to do.

Manually edit composer.json to remove deprecated packages. Remove this line:

   "require-dev": {
        "webflo/drupal-core-require-dev": "^8.7.0"

And replace it with this one:

   "require-dev": {
        "drupal/core-dev": "^8.8"

Then edit the require statement for Drupal core itself: 

   "require": {
        "drupal/core": "^8.8"

Now that composer.json is up to date, you can go ahead and run Composer updates in the usual way, with composer update --lock.

If you are starting a new Drupal 8 site from scratch, refer to this guide on Starting a Site Using Drupal Composer Project Templates. It has instructions on how to use the new recommended way of handling Composer templates, using drupal/recommended-project.

Diagnosing deprecated Composer tools

Without following the steps above, if you try to run composer update, Composer will fail with this error:

Your requirements could not be resolved to an installable set of packages.

Depending on what package versions are installed, and the syntax of your composer.json file, the rest of the error output will vary. Here is an example:

The requested package webflo/drupal-core-require-dev (locked at 8.7.11, required as ^8.8) is satisfiable by webflo/drupal-core-require-dev[8.7.11] but these conflict with your requirements or minimum-stability.

The important thing to know here is that Composer is being helpful. It is preventing you from upgrading a deprecated package. 

You can verify this by using the Composer prohibits command:

$ composer prohibits drupal/core:^8.8
webflo/drupal-core-require-dev  8.7.11  requires  drupal/core (8.7.11)                                 
drupal/core      8.8.0  requires   typo3/phar-stream-wrapper (^3.1.3)                   
drupal-composer/drupal-project  dev-my-project  does not require  typo3/phar-stream-wrapper (but v2.1.4 is installed)

Or its alias:

$ composer why-not drupal/core:^8.8

But wait! There’s more!

These are just a few pitfalls. There are other considerations to make before updating to 8.8.x. Make sure to read the release notes carefully to see if any other advisories apply to you.

Feb 04 2020
Feb 04

The Central NJ Drupal Group hosts one of my favorite Drupal camps in the northeast, and this year’s DrupalCamp NJ was no exception.

Location, Location, Location

Princeton University uses Drupal heavily, and gives back to the community by hosting the monthly Web Developers Central NJ Meetup and the annual camp.

This year’s camp was held in a new location, which will give us room to grow in the future. It is also closer to Princeton’s beautiful main campus.

I have a personal connection to the new venue. The three buildings we used are very close to Fine Hall, where I spent five years earning my Ph.D. (That is the “Looking Back” part of my title.) I know I am at my alma mater when I see this color scheme:

conference tables with orange table cloths and black chairs

Another thing I like about the venue is that I can stay in a reasonably priced hotel on the not-so-beautiful Route 1, then walk to campus along the D&R Canal. A two-mile walk is a great way to start the day, and it makes my new FitBit so happy!

Training: The Great Gatsby

Last year at BADCamp, I helped Ryan Bateman with an all-day training session on using Gatsby and Drupal’s Umami installation profile to create a decoupled site. On Thursday, I was the primary presenter for this training, and Adam Bergstein generously offered to assist.

I wanted to rearrange the slides, and for technical reasons I had a lot of work to do updating the presentation to work with Drupal 8.8. I think the session went well, but I also have ideas for doing a better job the next time I have a chance to present it.

Sessions and BoFs and Migrate API, oh my!

Handling HTML Markup with Drupal’s Migrate API

During the first session slot, I talked about wrangling HTML markup with regular expressions vs. proper parsing and some work that Marco Villegas and I did to make proper parsing easier in the context of Drupal’s Migrate API. The session page has a link to the recording and the slides. I had a pretty good-sized audience, and they asked good questions.

room showing about 25 training attendees smiling

The first time I presented this material was last year at New England Drupal Camp. That was extra fun, since Marco and I gave the presentation together. He lives in South America, so that was the first time that we met in person.

On the plus side, I got some help from Lindsey Gemmill, so my slides for this session look great. This is the first presentation using reveal.js that has Hook 42 branding, and I think we will see a lot more of these in the future!

For the rest of the day, I went to a mix of regular and Birds of a Feather (BoF) sessions. I did my best to take notes at all of these, and I save these to my Conference Notes repository on GitLab.

Using Machine Learning to Help with Daily Workflows

First was a session on Machine Learning (ML). Danny Teng and Neha Bhomia gave some background on ML.

Danny Teng and Neha Bhomia standing in front of presentation title screen

Then they talked about two Drupal modules.

The first is Drupal Rekognition, which will get alt text for images using the AWS Rekognition service. Thanks to my colorful hat, I was the subject of a live demo:

Drupal backend displaying ai generated alt text for picture of me at camp

It is nice to know that AWS Rekog-nizes me as a Person, but what is this about Home Decor?

The second module is still in development. Its goal is to recognize malicious IP addresses. In order to do this, they need to train their ML model. They already have a database of GET requests from several large Drupal sites. They need help identifying which requests are legitimate. For example, there are several legitimate bots (search engines, uptime monitoring services) as well as actual people. Then there are the 404 errors because someone is trying to access wp-login.php on a Drupal site.

If you would like to help train the model, then contact [email protected].

All things HAX

After lunch, I went to a BoF on Headless Authoring eXperience (HAX). I had not heard of this before, and the description got me curious. I have still not had a chance to try it out, but it seems to be a system for editing web components. I will have to check with the front-end specialists at Hook 42 to see whether they are interested. From the description of the session, I thought it might be a sort of content editor that works through the front end of decoupled Drupal sites; maybe it also does that.

Securing Drupal’s Auto-Update Infrastructure

In an attempt to combat the post-lunch blahs, the organizers scheduled a coffee break after the first afternoon session. After that, I went to a BoF that was basically a working session among five members of the Drupal Security Team.

There is an initiative to enable automatic updates of Drupal sites. Most of the work so far is available in the contrib Automatic Updates module. The goal is to make it easier to keep a Drupal site up to date, especially when a security update is released.

This BoF was about the infrastructure behind that initiative. The nightmare scenario is that someone might hack the automatic-update process. Then, instead of making sites more secure by keeping them up to date, the system would install hacked code on every site that was set up for automatic updates.

To avoid this, the Security Team is working on protocols and infrastructure to prevent such hacking. At this BoF, the team discussed adopting The Update Framework (TUF) as the basis for Drupal’s system of automatic updates. This is a standard already adopted by many large companies, and the protocol is very similar to what the Security Team already designed on its own.

Progressively Decoupled Drupal, for everyone!

For my last session, I chose one on web components and HAX, a follow-up to the BoF I attended after lunch.

The four presenters made the case for concentrating front-end development on web components.

  • This technology has been under development for years but has only recently been adopted by all the major browsers.
  • You can use the components that you develop in your current theme, without the headaches of switching to a fully decoupled site all at once.
  • When you are ready to decouple, you will be able to use those components in whichever front-end framework you choose.
  • You can also use your web components on completely different systems: WordPress, Gatsby, Jekyll, etc.
  • Since the web component lives in its own repository, you can update it in one place and see the effect in hundreds of sites that use the component.

I am not sure exactly how that last point works. Updating to the new component has to be automatic, but not too automatic, since there is a danger that the new version of a web component will break existing sites.

Mentoring & Collaboration

The last day of the camp was devoted to contributing back to Drupal.

I started the day by sitting in on the workshop for first-time contributors, in case AmyJune Hineline, the presenter, had technical questions that a back-end developer and core contributor could answer.

I spent the rest of the day reviewing two issues.

The first issue is one that I have been following for some time: Drupal core should inform the user of the security coverage for the site’s installed minor version including final 8.x LTS releases. The problem is that, with Drupal 9 around the corner, we want to make sure that the site status report advises site administrators to upgrade to that and not to a non-existent version 8.10 when the time comes. The other problem is that the existing code in the core Update module is a bit of a mess, so working with it is a challenge.

Ted Bowman has been the primary developer for this issue. I have taken on the reviewer role, which means:

  • I should not contribute patches myself, and
  • My aim is to help Ted and others get their patches to a point where the core committers like what they see.

The second issue was Add more strict checking of hook_update_last_removed() and better explanation. This issue was tagged for usability review, in order to get some advice on the wording of a new error message. As a member of the Drupal Usability team, I often do such reviews, either on my own or at one of our weekly meetings. I am not an expert at UX design in general, but I am pretty good at word-smithing, and I think I was able to suggest an improvement for this issue.

I’ll Be Back!

With a full three-day schedule, DrupalCamp NJ is one of my favorite camps, up there with BADCamp and MidCamp. Since I was giving a training session, this was the first year I participated in all three days.

I got to spend time with some friends like Adam Bergstein and AmyJune Hineline, and I met several new (to me) people: the people who attended my training and my session, and @mixologic, who I have previously only known through issues on drupal.org and on Slack.

I also had a chance to revisit the town and the campus where I spent five years, which brought back some fond (and amusing) memories.

I expect that DrupalCamp NJ will also be my first Drupal camp of 2021.

Jan 31 2020
Jan 31

For this article, we enlisted front end developer, Abby Milberg, to give us a little inspiration for Drupal 8 theme building. Abby is the expert here, so I'll let her take it away.

What is a preprocess function?

A preprocess function creates or modifies variables and render arrays (arrays of data structured in specific ways that Drupal knows how to render as HTML) before they’re rendered and/or passed to a template.

Why not just use Twig?

In many cases, it's possible to achieve the same final output by using either a preprocess function or putting logic directly in the relevant Twig template. For many themers like myself, especially those coming from a front-end background unrelated to Drupal and PHP, the latter can seem like the path of least resistance. It's important to consider the pros and cons of each approach for each use case, though. While Twig has an important role to play, preprocess functions offer a wide range of advantages: they're easily reusable, performant, and by separating programmatic logic from your templates, you can easily access the full power of the Drupal API. Furthermore, the data structures you modify or create will remain intact and accessible from other parts of your Drupal project, such as custom modules.

Example #1:

Adding bundle and view-mode classes to entities

If you're using a base theme, whether a core option like Classy or contrib option like Bootstrap, these classes probably exist out of the box. I prefer to start with a blank slate (no base theme), though, which means that most entities have no classes unless I add them. On the downside, I have to spend a few minutes adding them myself. On the upside, though, these functions are completely reusable from project to project and let me set up the classes precisely how I choose.

 * Implements hook_preprocess_node().
function mytheme_preprocess_node(&$variables) {
  // Get the node's content type
  $type = $variables['node']->getType();

  // Get its view mode
  $mode = $variables['view_mode'];

  // Make sure we have a class array
  if (!isset($variables['attributes']['class'])) {
    $variables['attributes']['class'] = [];

  // Add our classes
  $variables['attributes']['class'][] = 'node--type-' . $type; // ex: node--type-article
  $variables['attributes']['class'][] = 'node--mode-' . $mode; // ex: node--mode-teaser
  $variables['attributes']['class'][] = 'node--type-' . $type . '--mode-' . $mode; // ex: node--type-article--mode-teaser

This isn't only useful for nodes. We can follow this same basic model for any type of entity: media, taxonomy terms, bricks, paragraphs, custom entities, you name it. Here are two more examples:

 * Implements hook_preprocess_media().
function mytheme_preprocess_media(&$variables) {
  // Get the media entity's bundle (such as video, image, etc.)
  $mediaType = $variables['media']->bundle();

  // Make sure we have a class array, just like with the nodes
  if (!isset($variables['attributes']['class'])) {
    $variables['attributes']['class'] = [];

  // Add a class
  $variables['attributes']['class'][] = 'media--type-' . $mediaType; // ex: media--type-video

 * Implements template_preprocess_block().
function mytheme_preprocess_block(&$variables) {
  // Custom block type helper classes.
  if (!isset($variables['elements']['content']['#block_content'])) {
    // This checks whether we actually have a custom, fielded block type, or if
    // we're working with a generic out-of-the-box block.

  // Get the block type name
  $bundle = $variables['elements']['content']['#block_content']->bundle();

  // Make sure we have a class array
  if (!isset($variables['attributes']['class'])) {
    $variables['attributes']['class'] = [];

  // Add our class
  $variables['attributes']['class'][] = 'block--bundle-' . $bundle;

Example #2:

Building a link (the "Drupal way")

The Drupal API has its own ways of handling lots of data structures, including links. Why would we want to preprocess a link? The following example builds a link using hard-coded values, but the real value of preprocessing links comes from pulling in values from various fields on your node (text, link, images, etc.) and building the exact markup that suits your use case. These fields and how you wish to combine them will likely be different on every project.

// These are required at the top of your file in order to use Link and Url later
// in the preprocess function.
use Drupal\Core\Link;
use Drupal\Core\Url;

 * Implements hook_preprocess_node().
function mytheme_preprocess_node(&$variables) {
  // Use URL::fromUri to turn a plain uri into a Drupal URL object.
  // It might need another URL::fromXYZ function, depending on input.
  // See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Url.php/class/Url/8.9.x
  // for more possibilities.
  // If you pull your URL from a Drupal link field, it will probably be a URL object already.
  $my_url = URL::fromUri('https://www.some-url.com/');

  // Set the text or markup you want inside the link. Note the use of t() to
  // ensure that Drupal's multilingual functionality recognizes the text.
  $my_text = t('Click Me!');

  // Set any attributes you want as an array.
  $link_options = [
    'attributes' => [
      'target' => '_blank',
      'class' => ['btn', 'btn--large'],

  // Apply the options to the URL

  // Build the final link.
  // See https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Link.php/function/Link%3A%3AfromTextAndUrl/8.9.x
  $variables['my_full_link'] = Link::fromTextAndUrl($my_text, $my_url)->toString();
  // You can now render this link in a Twig template by calling {{ my_full_link }}

Example #3:

Adding placeholder text to the Drupal search block

I find myself using this one on every project - when's the last time you got a design that didn't call for the search bar to have placeholder text? Luckily, it's short and usually requires no modifications.

 * Implements hook_form_FORM_ID_alter().
function mytheme_form_search_block_form_alter(&$form, $form_state) {
  // Adds placeholder text to the search field.
  $form['keys']['#attributes']['placeholder'] = t('Search');

Example #4:

Changing field template suggestions

Out of the box, Drupal gives us lots of options for templates that each field can use. Sometimes, though, you may want to point multiple different (programmatically unrelated) fields to the same Twig template. A common use case that I personally employ on most projects is something like field__bare - a field template I create that has no wrapper divs, labels, or classes, but simply renders the field's contents. There are plenty of other design reasons that you might want different fields to point to the same template, though.

 * Implements hook_theme_suggestions_HOOK_alter().
function mytheme_theme_suggestions_field_alter(array &$suggestions, array $variables) {
  // Set custom template suggestions for fields.
  // Switch based on field names
  switch ($variables['element']['#field_name']) {
    case 'field_something':
    case 'field_something_else':
      // Add this to the list of templates that those fields will look for
      // The file field--bare.html.twig would go in
      // mytheme/templates/field
      $suggestions[] = 'field__bare';
    case 'field_another_one':
      // The file field--another-template.html.twig would go in
      // mytheme/templates/field
      $suggestions[] = 'field__another_template';

Example #5:

Helpful page-level classes

Last but not least, by using hook_preprocess_html, we can apply a variety of useful classes to a page's <body> element This can be particularly useful if we need to change something in global elements, like the header and footer, based on a page's content or a user's role. Here are a few examples:

 * Implements hook_preprocess_html().
function mytheme_preprocess_html(&$variables) {
  // Apply a special class to the homepage, which often has no distinct content
  // type but often needs special design treatment.
  $variables['attributes']['class'][] = \Drupal::service('path.matcher')->isFrontPage() ? 'frontpage' : '';

  // Apply a class at the page level based on content type if we're on a node
  // page. Also helpful when you need to modify global elements that appear
  // outside the node itself.
  $variables['attributes']['class'][] = isset($variables['node_type']) ? 'page-node-type--' . $variables['node_type'] : '';

  // Check whether the viewer is logged in.
  $variables['attributes']['class'][] = $variables['logged_in'] ? 'logged-in' : 'logged-out';

Jan 16 2020
Jan 16

My goal in this post is to explore creating a Drupal powered mobile app with React Native. With no prior experience with React Native or React JS myself, this is truly an exploratory quest. I do have some experience with Angular 2-7 and AngularJS before it, so I admit I might have some more familiarity with concepts and code structure. 

What is necessary however, is an understanding of a few core things, namely Javascript 6 (ES6), as React Native supports and uses it, as well as Promises and HTTP Requests.

To explore React Native, I opted to replicate the sample ReactJS + NextJS sample application available on GitHub and visible here powered by this Drupal site as a React Native application. In the process, I’ll explain the core concepts I felt I had to learn and provide code where applicable.

While its not necessary to know ReactJS at all to get started with the React Native tutorial, as it assumes you have no prior knowledge of React or React JS, it would probably be helpful if you were at least a little familiar with ReactJS. I myself spent a little time familiarizing myself with how ReactJS works and even building a simple application before starting to work with React Native.

Building the application

Disclaimer: My aim is not to create a beautifully styled app, but simply get something up and working as quickly as possible. I added minimal styling. The app was built on a Mac for iOS. So let's begin.

You can find the finished code on GitHub.

First, create a new project, I named mine DrupalReactNative:

react-native init DrualReactNative

Project Structure

The first decision I made was how to structure the project. I came to Atomic Design because I stumbled upon an article that pointed out React follows the same principles as Atomic Design. I’d never used Atomic Design outside of the context of CSS, so I did look for examples of how this was implemented in React. 

cd DrupalReactNative/
mkdir src
cd src
mkdir components
cd components
mkdir atoms molecules organisms pages templates

After some research, specifically looking at the site I was building, I settled on the following folder structure and breakdown of files:

preview of folder structure on a bright blue background

This is by no means the “correct” way to organize folders, but this is what I settled on. We will come back to the code later.

Additional Libraries

I chose to use React Navigation (and related required modules) to handle the app navigation, and despite React implementing the straightforward Fetch API for network requests, I was a little lazy and used React Native Rest Client for network requests. This made the networking tasks even easier and React Native Vector Icons for menu icons.

From root directory:

npm install react-navigation react-navigation-stack
npm install react-native-gesture-handler react-native-rest-client
npm install react-native-screens react-native-reanimated
npm install react-native-vector-icons

Then install the pods for IOS:

cd ios
pod install

You will then have to manually install Vector Icons.

Note: I found the only thing that worked was adding font to Xcode. Failure to do this will result in an unknown font error when trying to compile.


At this point, on running react-native run-ios, you should get the default app with the default screen. Now we will replace the contents of the App.js file with the following:

import React from 'react';
import RecipeApp from './src/RecipeApp';

const App = () => {
  return (
      <RecipeApp />

export default App;

Then create the referenced file, RecipeApp.js in the src directory:

import React from "react";
import { createAppContainer,} from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import HomePage from "./components/pages/Homepage/index";
import Recipes from "./components/pages/Recipes/index";

const MainNavigator = createStackNavigator({
    Homepage: HomePage,
    Recipes: Recipes,
    initialRouteName: 'Homepage',
    headerMode: 'none',

const RecipeApp = createAppContainer(MainNavigator);
export default RecipeApp;

The code references 2 custom items which we will also create.

First, the homepage which will be in the pages folder in the components directory:

import React from 'react';
import { Text, View, Button } from 'react-native';

export default class HomePage extends React.Component{
  render() {
    return (
      <View style={{margin: 20, marginTop: 30, flex: 1}}>
        <Text style={{marginTop: 10, fontSize: 28, fontWeight: 600}}>Contenta + React Native</Text>
        <View style={{flex: 1, flexDirection: 'row'}}>
            style={{flexDirection: 'row'}}
            onPress={() => {

            style={{flexDirection: 'row'}}
            onPress={() => {
        <View style={{flex: 1}}>
          <Text style={{fontSize: 24, fontWeight: 600}}>Home</Text>
          <Text>Lorem Ipsum</Text>

I added some very basic styling. It’s worth mentioning that styling in ReactNative, like styling in React, is in JavaScript, hence the camel case code.

I practically repeat the same for the Recipes page, which should now give us 2 screens and a working navigation:

import React from 'react';
import { Text, View, Button } from 'react-native';

export default class Recipes extends React.Component{
  render() {
    return (
      <View style={{margin: 20, marginTop: 30, flex: 1}}>
        <Text style={{marginTop: 10, fontSize: 28, fontWeight: 600}}>Contenta + React Native</Text>
        <View style={{flex: 1, flexDirection: 'row'}}>
            style={{flexDirection: 'row'}}
            onPress={() => {

            style={{flexDirection: 'row'}}
            onPress={() => {
        <View style={{flex: 1}}>
          <Text style={{fontSize: 24, fontWeight: 600}}>Recipes</Text>
          <Text>Ipsum Lorem</Text>

With that you should have an app with two screens and screen to screen navigation.

Components and Data

With the basic structure in place, we can now jump to creating components and retrieving data. For this I copied most of the structure of the React + NextJS repo and updated the code for React Native. 

I had to create a custom class to transform the JSON:API response into a usable object (JSON:API, part of Drupal core, is one of the key modules used in Contenta as it’s API first). This was necessary because all attempts to normalize the response using various libraries failed. The following code is used to process all incoming responses:

import React from 'react';

export default class Transform extends React.Component {
  transformJson(obj) {
    let nodes = [];
    if (typeof obj.data.type !== 'undefined' && obj.data.type == 'recipes') {
      item = obj.data;
      const node = {
        id: item.id,
        title: item.attributes.title,
        difficulty: item.attributes.difficulty || '',
        ingredients: item.attributes.ingredients || [],
        numberofServices: item.attributes.numberofServices || 0,
        preparationTime: item.attributes.preparationTime || '',
        instructions: item.attributes.instructions || '',
        totalTime: item.attributes.totalTime || '',
        image: transformJsonGetImage(obj, item.relationships.image.data.id),
          typeof item.relationships.category !== 'undefined'
            ? transformJsonGetCat(
            : '',
      nodes[0] = node;
    } else {
      obj.data.forEach(function(item, index) {
        const node = {
          id: item.id,
          title: item.attributes.title,
          difficulty: item.attributes.difficulty || '',
          ingredients: item.attributes.ingredients || [],
          numberofServices: item.attributes.numberofServices || 0,
          preparationTime: item.attributes.preparationTime || '',
          instructions: item.attributes.instructions || '',
          totalTime: item.attributes.totalTime || '',
          image: transformJsonGetImage(obj, item.relationships.image.data.id),
            typeof item.relationships.category !== 'undefined'
              ? transformJsonGetCat(
              : '',
            typeof item.relationships.tags !== 'undefined'
              ? transformJsonGetTags(obj, item.relationships.tags)
              : '',

    return nodes;
// Gets tags.
export function transformJsonGetTags(res, obj) {
  let tags = [];
  obj.data.forEach(function(item, index) {
    tags.push(transformJsonGetCat(res, item.id, 'tags'));
  return tags;
// Gets category of item.
export function transformJsonGetCat(obj, id, type = 'tags') {
  name = '';
  obj.included.forEach(function(item, index) {
    if (item.id == id && item.type == type) {
      name = item.attributes.name;

  return name;
// Gets image
export function transformJsonGetImage(obj, id) {
  fid = '';
  src = '';
  obj.included.forEach(function(item, index) {
    if (item.id == id && item.type == 'images') {
      fid = item.relationships.thumbnail.data.id;
  obj.included.forEach(function(item, index) {
    if (item.id == fid && item.type == 'files') {
      src = item.attributes.url;
  return src;

Now to update the homepage:

The homepage contained 5 components and api calls to supply data.

import React from 'react';
import {View} from 'react-native';
import Header from '../../../components/organisms/Header/index';
import {ScrollView} from 'react-native-gesture-handler';
import RecipeApi from '../../../api/recipe';
import PromotedRecipes from '../../organisms/PromotedRecipes/index';
import Transform from '../../../utils/Transform';
import MonthEdition from '../../organisms/MonthEdition/index';
import HomeWidgets from '../../organisms/HomeWidgets/index';
import RecipeList from '../../organisms/RecipeList/index';
import styles from '../../templates/styles';

export default class HomePage extends React.Component {
  constructor(props) {
    this.state = {
      promotedItems: [],
      latestRecipes: [],

  initialize = () => {
    recep = new RecipeApi();
    t = new Transform();
    try {
        .then(response => response)
        .then(responseJson => {
          const transformed = t.transformJson(responseJson);
          this.setState({promotedItems: transformed});
        .catch(error => {
    } catch (e) {}
    try {
        .then(response => response)
        .then(responseJson => {
          const transformed = t.transformJson(responseJson);
          this.setState({latestRecipes: transformed});
        .catch(error => {
    } catch (e) {}
  componentDidMount() {

  render() {
    return (
      <View style={styles.container}>
        <ScrollView stickyHeaderIndices={[0]}>
          <Header navigation={this.props.navigation} style={styles.header} />
            <MonthEdition navigation={this.props.navigation} />
            <HomeWidgets />

I won't get into the details of each component on the homepage and will just link to the repository here.

The Recipe page contains 2 components, a node view of a node ID is supplied and a component that displays 10 recipes if there is no Node ID. Again, I won't get into the details of those components. 

import React from 'react';
import {View, Text, StyleSheet, ScrollView, Button} from 'react-native';
import NodeView from '../../organisms/NodeView/index';
import RecipeApi from '../../../api/recipe';
import Transform from '../../../utils/Transform';
import styles from '../../templates/styles';
import Header from '../../organisms/Header/index';
import RecipeList from '../../organisms/RecipeList/index';

export default class Recipes extends React.Component {
  constructor(props) {
    this.state = {
      nodes: [],
      allNodes: [],

  initialize = () => {
    recep = new RecipeApi();
    t = new Transform();
    nid = this.props.navigation.getParam('nid', null);
    if (nid) {
      try {
          .then(response => response)
          .then(responseJson => {
            const transformed = t.transformJson(responseJson);
            this.setState({nodes: transformed});
          .catch(error => {
      } catch (e) {}
    } else {
      try {
          .then(response => response)
          .then(responseJson => {
            const transformed = t.transformJson(responseJson);
            this.setState({allNodes: transformed});
          .catch(error => {
      } catch (e) {}
  componentDidMount() {

  goBack() {
      allNodes: [],
      node: [],
  render() {
    return (
      <View style={styles.container}>
          <Header navigation={this.props.navigation} style={styles.header} />
          <Button title="Go back"
            onPress={() => {
            {this.state.allNodes.length > 0 ? (
            ) : (
                nid={this.props.navigation.getParam('nid', '')}

The finished product looks something like this:

Four mobile screens displaying umami recipe and home page built with react


There was only a slight learning curve getting up to speed on most things with React Native and as such I certainly think an experienced developer could easily make the transition. 

Prior to using ReactNative, there was a certain mystique, but it turned out to not be less complicated than I anticipated. There were certainly some challenges finding the right documentation for versions of modules I was using, but this is not unlike many Open Source projects. A few modules mentioned in tutorials or documentation I tried to follow were updated or deprecated, but save for a few issues with this, it was relatively straightforward to get the app up and running. 

Judging from my experience so far, I may certainly be a convert to React Native and will explore opportunities to build more Drupal powered native apps.

Dec 10 2019
Dec 10

When maintaining a Drupal 8 site in production, it’s often necessary to make changes within the site’s database, specifically when it comes to modifying settings or data that is not handled by Drupal’s YAML file-based configuration management API. Some common examples of settings or data not handled by the configuration management API include the following:

  • Field values of actual nodes;
  • Field settings that cannot be altered via the admin UI once those fields are populated with data;
  • Database schemas/data models;
  • Menu items;
  • Taxonomy terms;
  •  and more...

It’s fairly common that the needs of clients may necessitate changes to such data and settings. When that is the case, Drupal’s Update API provides an efficient, well-documented method for making changes to the database layer. The basic methods of tapping into the Update API are either (1) via an implementation of the hook hook_update_N() within the MODULE_NAME.install file in a custom module, or (2) via an implementation of the hook hook_post_update_NAME() within a MODULE_NAME.post_update.php file in a custom module. In case you’re not familiar with writing update hooks in general, my previous blog post provides a good example of what one might look like.

Deciding Which Update Hook to Use

If you are researching Drupal’s Update API you may find that the majority of tutorials focus on implementations of hook_update_N() rather than hook_post_update_NAME(). There is one key difference between the two hooks that you need to consider when choosing which one to implement: hook_update_N() is primarily meant for making changes related to configuration and/or database schemas (i.e., structural updates to a site), as suggested by the Drupal.org documentation. For this reason  hook_update_N() should not be used for CRUD operations to update entity data (e.g., the field values on specific nodes), because “loading, saving, or performing any other CRUD operation on an entity is never safe to do (because these tasks rely on hooks and services)”. Instead, if you need to update data like entities, you should implement hook_post_update_NAME(), which Drupal runs in a fully loaded state with all of its APIs available, after any hook_update_N() implementations are run.

In the example below, we will be implementing hook_post_update_NAME() in order to programmatically update hundreds of node field values.

Pushing the Boundaries of your Update Hook

More often than not, you’re probably used to implementing update hooks to achieve relatively simple and straightforward tasks, such as programmatically updating a field value across a handful of nodes. However, because Drupal is so good at being able to store massive amounts of content, sometimes you’ll need to update more than just a handful of nodes. Instead, you might need to update hundreds, if not thousands, of entities all at once.

Technically, you could write your update hook in such a way that those thousands of nodes are updated at one time, one immediately after the other. While that might work fine locally in testing, when you don’t care as much about performance, that style of memory-intensive or long-running update could pose a serious threat to the stability and performance of your site during deployment.

Instead, when it comes to implementing such memory-intensive update hooks, it’s best to reach for Drupal’s Batch API. Luckily, Drupal has made this relatively simple to do when implementing update hooks specifically. In the documentation for hook_update_N() and hook_post_update_NAME(), batch updates are explicitly mentioned as a best practice “if running your update all at once could possibly cause PHP to time out.” As stated in that same documentation, “in this case, your update function acts as an implementation of callback_batch_operation(), and $sandbox acts as the batch context parameter.” To see what this means, it’s probably easiest to look at an example.

Batch API: the better way to process thousands of node updates in one go

The following code is an update hook that I recently had to implement. Within this update hook, the code comments will describe how I was able to use Drupal’s Batch API within the hook, in order to ensure that I could process hundreds of node updates without significantly affecting the live production site’s performance.

For a bit of background context, this particular site had two content types referred to here as FOO and BAR. Any given BAR node was meant to exist only as a child in relation to a parent FOO node (within a one-way, BAR-to-FOO relationship), and every FOO node should have a child BAR node at all times. However, the problem was that, due to an initial architectural decision, not all FOO nodes had a child BAR node at all times, because the creation of the child BAR node was only triggered by a specific action taken by a user. Therefore, we needed to write an update hook to create a child BAR node for any and all FOO nodes that we're currently missing a referring child BAR node.

In summary: for every FOO node, make sure there is also a BAR node. Currently, many FOO do not have a corresponding BAR. Let’s begin!

 * @file
 * docroot/modules/custom/my_module/my_module.post_update.php

 * Creates a BAR node for any FOO node that does
 * not yet have a corresponding BAR node.
function my_module_post_update_create_missing_nodes(&$sandbox) {

  // On the first run, we gather all of our initial
  // data as well as initialize all of our sandbox variables to be used in
  // managing the future batch requests.
  if (!isset($sandbox['progress'])) {

    * To set up our batch process, we need to collect all of the
    * necessary data during this initialization step, which will
    * only ever be run once.

    * We start the batch by running some SELECT queries up front
    * as concisely as possible. The results of these expensive queries
    * will be cached by the Batch API so we do not have to look up
    * this data again during each iteration of the batch.
    /** @var \Drupal\Core\Database\Connection $database */
    $database = \Drupal::database();
    // Fetches node IDs of FOO nodes with BAR node references.
    $FOOs_with_BAR_refs = $database
      ->query("SELECT DISTINCT field_FOO_ref_target_id FROM {node__field_FOO_ref}")
    // Fetches NIDs of FOO nodes without BAR node references.
    $FOOs_without_BAR_refs = $database
        "SELECT nid FROM {node_field_data}
        WHERE type = :type
        AND status = :status
        AND nid NOT IN (:nids[])",
          ':type' => 'FOO',
          ':status' => 1,
          ':nids[]' => $FOOs_with_BAR_refs,

    * Now we initialize the sandbox variables.
    * These variables will persist across the Batch API’s subsequent calls
    * to our update hook, without us needing to make those initial
    * expensive SELECT queries above ever again.

    // 'max' is the number of total records we’ll be processing.
    $sandbox['max'] = count($FOOs_without_BAR_refs);
    // If 'max' is empty, we have nothing to process.
    if (empty($sandbox['max'])) {
      $sandbox['#finished'] = 1;

    // 'progress' will represent the current progress of our processing.
    $sandbox['progress'] = 0;

    // 'nodes_per_batch' is a custom amount that we’ll use to limit
    // how many nodes we’re processing in each batch.
    // This is a large part of how we limit expensive batch operations.
    $sandbox['nodes_per_batch'] = 18;

    // 'FOOs_without_BAR_refs' will store the node IDs of the FOO nodes
    // that we just queried for above during this initialization phase.
    $sandbox['FOOs_without_BAR_refs'] = $FOOs_without_BAR_refs;


  // Initialization code done. The following code will always run:
  // both during the first run AND during any subsequent batches.

  // Now let’s create the  missing BAR nodes.
  $node_storage = \Drupal::entityTypeManager()->getStorage('node');

  // Calculates current batch range.
  $range_end = $sandbox['progress'] + $sandbox['nodes_per_batch'];
  if ($range_end > $sandbox['max']) {
    $range_end = $sandbox['max'];

  // Loop over current batch range, creating a new BAR node each time.
  for ($i = $sandbox['progress']; $i < $range_end; $i++) {
    $BAR_node = $node_storage->create([
      // NOTE: title will be set automatically via auto_entitylabel.
      'type' => 'BAR',
      'field_FOO_ref' => [
        'target_id' => $sandbox['FOOs_without_BAR_refs'][$i],
    $BAR_node->status = 1;

  // Update the batch variables to track our progress

  // We can calculate our current progress via a mathematical fraction.
  // Drupal’s Batch API will stop executing our update hook as soon as
  // $sandbox['#finished'] == 1 (viz., it evaluates to TRUE).
  $sandbox['progress'] = $range_end;
  $progress_fraction = $sandbox['progress'] / $sandbox['max'];
  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $progress_fraction;

  // While processing our batch requests, we can send a helpful message
  // to the command line, so developers can track the batch progress.
  if (function_exists('drush_print')) {
    drush_print('Progress: ' . (round($progress_fraction * 100)) . '% (' .
    $sandbox['progress'] . ' of ' . $sandbox['max'] . ' nodes processed)');

    // That’s it!
    // The update hook and Batch API manage the rest of the process.


Simple Solutions are Easier

As seen in the code above, Drupal’s Update API makes it relatively straightforward to quickly leverage its Batch API for memory-intensive and long-running update operations. With everything being managed by a simple $sandbox array of variables, we can tackle even the largest update operations on our sites with simple, yet efficient, batched processing.

Nov 21 2019
Nov 21

With another DrupalCon wrapped up, it always takes some time for everything experienced to coalesce, and a couple of weeks after getting back from Amsterdam, I was thinking about the major takeaways this time round.


This was my first year attending a European DrupalCon, which is now organized by Kuoni Congress instead of the Drupal Association. It was also my first year rocking up on my own, without being sure who I would bump into and who I would be going to the dinners and parties with. I really appreciated being part of the Mentoring team as they were a great crowd to hang out with, and having helped out in previous years, but mostly on the periphery, it was also great to get more deeply involved. Many will know that it takes years to build up a good network of people you can talk to about upcoming sessions, the latest tech, or the best place for a stiff drink. For those attending for the first time, this can make the DrupalCon feel a bit more intimidating. This ties into the topic of the Driesnote which was regarding the barrier for entry of Drupal compared to other CMSs and how that needs to be something that we can improve upon, along with the ‘first experience’.

Part of the effort to make things easier for beginners is to reduce the mystery surrounding Drupal and getting everyone contributing in some shape or form. We have been iterating on the slides for the First Timer Workshops and the process for Contribution Days, and it is really encouraging to see gradual improvements paying off, and with plenty of great ideas to come. This time we saw over 300 attendees, 30 mentors, with 216 issues worked on!

An overall emphasis on all forms of contribution, with less focus on purely code commits, means that maybe live commits in Contribution Days are a thing of the past, but ideas for ways to wrap up and celebrate contributions are always welcome!


Sessions were well spread, and luckily I didn't find myself having to make too many tough decisions about which session to miss. Luckily all of the sessions have Kevin Thull's little black box which just records everything with a blinking red light for posterity, although some presenters got mixed up and turned it off (to be then turned on again).

Of course with the limited space in the printed program it's easy to turn to the app for checking the details of any session, but this was where I did have an issue in that it took a good 4 clicks from the title of a session to get any more details about it, with many not having details available. Something to improve upon for next year I am sure!

display of a variety of cheese

In Summary

A beautiful city with some great food (even great vegan options), an awesome mentoring team, a highly biased trivia night judging panel who can't understand Unicodeunicode apparently, and a fun event with plenty to learn from and share with others.

And finally for some stats:

There were 300 people attending contribution day, 30 mentors, 216 issues that were worked on!

Nov 12 2019
Nov 12

As our team continues to contribute to the Drupal community, we've been attending a variety of Drupal Core meetings. After each meeting, we put together an overview or recap of key talking points from each discussion. Sometimes recaps are provided after the meetings, in those cases we simply organize those thoughts, with commentary of our own if needed, to have all the recaps in one place. This article breaks down highlights from meetings this past week, November 4th through November 8th.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Out of the Box Meeting

November 05, 2019

This meeting was short and sweet, covering two exciting Umami media updates.

  1. Umami is now using media images, instead of regular images and media-library. That is now stable in core! Shout out to Ofer Shaal on his excellent work implementing this.
  2. Enabled the ability to add media-library items when using CKeditor. You can now utilize the WYSIWYG editor to embed media images with the new "Media" button in the toolbar. 

Admin UI Meeting

November 6, 2019

  • happens every Wednesday at 2:30pm UTC
  • is chat only (no audio or video)
  • happens in threads so keep an eye on those notifications
  • there are about 5-10 minutes between topics for people who are multitasking to follow along.
  • the agenda is public and anyone can add new topics in the document

Creating a clearer contribution process

Right now there's some confusion around how to contribute to Claro and the processes. There is also confusion about where to look for start working on it. Organizers are addresing the concerns outlined below:

There is a need to update the project itself with link to the instructions, and documentation of the following:

  • Claro from 8.8 is in core, and development for it happens there & how to get to the issue queue.
  • How to contribute to the Claro independent project.

Migration Meeting

November 7, 2019

This meeting:

  • Is for core migrate maintainers and developers and anybody else in the community with an interest in migrations
  • Usually happens every Thursday and alternates between 1400 and 2100 UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public agenda anyone can add to
  • Transcript will be exported and posted to the agenda issue. For anonymous comments, start with a bust in silhouette emoji. To take a comment or thread off the record, start with a no entry sign emoji.

The following issues were discussed in last week's meeting:

Nov 04 2019
Nov 04

As our team continues to contribute to the Drupal community, we've been attending a variety of Drupal Core meetings. After each meeting we put together an overview or recap of key talking points from each discussion, or provide recaps given after the meeting to have all in one place. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

This past week, with DrupalCon Amsterdam in full swing, we had the majority of the meetings cancelled, so the only update we have this week is from Benji's attendance at the Migration meeting. We hope everyone had a great time in Amsterdam!

Migration Meeting

October 31, 2019

This meeting:

  • Is for core migrate maintainers and developers and anybody else in the community with an interest in migrations
  • Usually happens every Thursday and alternates between 1400 and 2100 UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public agenda anyone can add to here.

We reviewed the issues marked Needs Review (NR). It was a quiet meeting, but:

Oct 28 2019
Oct 28

As our team continues to contribute to the Drupal community, we've been attending a variety of Drupal Core meetings. After each meeting we put together an overview or recap of key talking points from each discussion, or provide recaps given after the meeting to have all in one place. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Drupal Usability Meeting 

October 22, 2019

Meetings are for anyone interested in usability and accessibility. Since these are two of the Drupal core gates, initiative leads often attend these meetings to request reviews of their current issues.

  • Meetings take place on Tuesdays at 19:30 UTC.
  • Meetings are held using Zoom. A link is posted to the #ux channel in the Drupal Slack account.
  • Recordings are available on YouTube. Recent meetings use the standard format “Drupal Usability Meeting YYYY-MM-DD” to make them easier to find.
  • This week’s recording: Drupal Usability Meeting 2019-10-22

This week, we discussed just one issue, familiar from the meeting two weeks ago:

The good news is that Jennifer Hodgdon and our own Benji Fisher have already done a lot to improve that problematic Select list. The bad news is that the original problem described in the issue title still seems to have no good solution. Here is part of the comment that Angie Byron posted to summarize the meeting:

Benji’s demo was great; he showed how the current select list is a complete CF with multiple problems, and also shows how the current patch vastly improves upon it, in several ways:

  1. The default "Sort" list is, ironically, unsorted. LOL. So fields are in whatever order, and good luck to you trying to find what you need, even if it's not one of these more ambiguously named fields. This issue instead puts them into alphabetical order, and even accounts for post-translation labels. Wonderful. Thank you to Jennifer for working on this.
  2. The patch makes it so the "Sort" drop-down doesn't show up until you've selected one or more content types to reference. Awesome! This is a core UX concept called progressive disclosure, where you hide complexity until the point at which you actually need it. Great stuff. Thank you to Benji for working on this.
  3. EVEN MORE AWESOME, the patch limits the choices in the select list to only fields that are attached to the selected content types. So you cannot sort by "Vendor SKU" in a situation where you've selected "Article" and "Recipe" to reference, but not "Vendor." AMAZING. A+++ would select again. Thank you to Benji for working on this.

Migration Meeting

October 17, 2019

This meeting:

  • Is for core migrate maintainers and developers and anybody else in the community with an interest in migrations
  • Usually happens every Thursday and alternates between 1400 and 2100 UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public agenda anyone can add to here.

We reviewed the following issues:

Angie Byron mentioned that she and Gabor have Tweeted about multilingual migrations, looking for real-world testing. You can view the tweets and respond accordingly here.

We noticed that there are currently 8 issues marked RTBC that have been waiting 1 to 7 weeks.

Out of the Box Initiative Meeting 

October 22, 2019

  • Keith Jay made great quality video, and he’s going to add it to issue later this week.
  • Ofer Shaal was helping to get things ready for Drupal 9. Figured out Drush 11 is required for Drupal 9.  Also, he made some changes for Allow embedding media in CKEditor in Umami. That patch Needs Review.
  • Keith Jay, Mark Conroy, and Ofer Shaal were working on reviewing issues: Configure Umami to use Layout Builder to deliver original recipe content type designs and Fix Umami's responsive layout styles using DIFFY.
Oct 21 2019
Oct 21

As our team is expanding, and many people are contributing to the Drupal community, we've been attending a variety of Drupal Core meetings. After each meeting we put together an overview or recap of key talking points from each discussion. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Drupal 9 Readiness Meeting

October 14, 2019

Meetings are for core and contributed project developers as well as people who have integrations and services related to core. Site developers who want to stay in the know to keep up-to-date for the easiest Drupal 9 upgrade of their sites are also welcome.

  • Usually happens every other Monday at 18:00 UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public Drupal 9 Readiness Agenda anyone can add to.
  • The transcript will be exported and posted to the agenda issue.
  • Transcript will be exported and posted to the agenda issue. For anonymous comments, start with a bust in silhouette emoji. To take a comment or thread off the record, start with a no entry sign emoji.

During this week's meeting, the following items were discussed:

  • Drupal 9 branch is open! Next steps on it especially in the next two weeks.
  • Drupal 8.8.0-alpha1 commit freeze is nearly upon us! Update on D9 readiness issues that we need in 8.8. (jQuery, polyfills, Doctrine, others?)
  • DrupalCon Amsterdam plans! 
    • Gábor Hojtsy will try to support a Drupal 9 contrib contribution event, looking for drupal.org projects. To apply for help with your project, do so via Twitter.
    • We’ll be working on removing core deprecated APIs too. We’ll need to make sure not to step on toes for both. Also the ongoing novice work to make sure change records and trigger errors are correctly included for core deprecations
  • Tooling for JS deprecations
  • Deprecated scaffold files
  • When contrib should specify `core_version_requirement` key?

Out of the Box Initiative Meeting

October 15, 2019

Migration Initiative Meeting

October 17, 2019

This meeting:

  • Usually happens every Thursday and alternates between 14:00 and 21:00 UTC.
  • Is for core migrate maintainers and developers and anybody else in the community with an interest in migrations.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public migration meeting agenda anyone can add to.
  • Transcript will be exported and posted to the agenda issue.
  • For anonymous comments, start with a bust in silhouette emoji. To take a comment or thread off the record, start with a no entry sign emoji.

The following issues were reviewed at this week’s meeting:

The Migrate maintainers were pretty happy that we will be able to remove some long-deprecated APIs now that Drupal 9 is really here (in the sense that the branch has been opened).

Drupal Core Cross Initiative Meeting

October 17, 2019

UX + Admin UI


  • Claro just got into 8.8 (congrats!!!)
  • Views UI issue was resolved (yayyy)
  • Initial Roadmap defined
  • All alpha/beta criteria met for 8.8 and reviewed/approved/committed.


There are currently no blockers for UX / Admin UI.

Next steps:

  • Planning Drupalcon sprints
  • Next design/development goals for Claro (for stable roadmap and release)



  • Workspaces just got into 8.8 (congrats!!!)
  • Framework / PM review completed
  • Still working on sub-workspace capability, needs review & validation (last issue prior to the stable release)

Next steps:

  • One remaining issue, adding sub-workspace capability to be completed
  • Final issue to be filed for stable review



  • We discovered a Stable blocker last week on a front-end issue which needed immediate attention on a large patch (in a good state currently, main concerns addressed)
    • Issue: Presentation items were in the module code
  • All other issues are resolved


Only Stable blocker left is Move some representational classes in Media Library to Classy and others to Seven and/or Claro, as appropriate.

Next steps:




  • Must resolve installation issue referenced above
  • Build test framework

Next steps:

  • 3 issues need help:



  • Added the ability to exclude modules from core, contrib modules can now use this new API.
  • Didn’t make quite enough progress on the use cases for config environment module. (This being in Alpha makes the cmi2 ineligible for core 8.8 release, it’ll be in the queue for 9.1 as a result.)


Config env module

Next steps:
Continue working on the config env module and its plan.

Drupal 9


  • D9 branch now has 7.2 php version
  • Need vendor updates & reroll the symfony 4 patch (later today)
  • Continuing discussions on Twig dependencies related to Symfony ⅘ versions
  • Multilingual migration path needs review on 2 key issues:
  • Drupalcon Contribution Day: #ImadeDrupal9! Spread the word to use the hashtag.
  • Portions of doctrine and jQueryUI have been forked into core due to the fact that we couldn’t get everything deprecated.
  • Working on a tutorial.


Next steps:

Oct 14 2019
Oct 14

As our team is expanding, and many people are contributing to the Drupal community, we've been attending a variety of Drupal Core meetings. After each meeting we put together an overview or recap of key talking points from each discussion. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Drupal Usability Meeting 

October 8, 2019

Meetings are for anyone interested in usability and accessibility. Since these are two of the Drupal core gates, initiative leads often attend these meetings to request reviews of their current issues.

  • Meetings take place on Tuesdays at 19:30 UTC.
  • Meetings are held using Zoom. A link is posted to the #ux channel in the Drupal Slack account.
  • Recordings are available on YouTube. Recent meetings use the standard format “Drupal Usability Meeting YYYY-MM-DD” to make them easier to find.
  • This week’s recording: Drupal Usability Meeting 2019-10-08

This week, we discussed two issues:

The Media issue deals with a workflow challenge. If a field allows a limited number of Media entities, how do we let content editors choose from new (uploaded) items and those already in the media library? We agreed that the existing solution had too much information on the form and should be hidden by default. Sites that want to use the existing workflow can enable it.

When adding an entity-reference field, a site builder can choose how the options (presented to the content editor) will be sorted. The sort fields are presented to the site builder in a select element, with several problems:

  • the options are not sorted
  • different sort fields may have the same label
  • when a field is reused, it may have different labels

An example of the last point: in the Umami demo theme, the title field is labeled “Title” on the Article content type and “Recipe Name” on the Recipe content type. In this situation, the current behavior is to show one of the labels, seemingly at random.

Out of the Box Initiative Meeting

October 8, 2019

Admin UI Meeting

October 09, 2019

  • Meetings are for core and contributed project developers as well as people who have integrations and services related to core. 
  • Usually happens every other Wednesday at 2:30pm UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • There are roughly 5-10 minutes between topics for those who are multitasking to follow along.
  • The Admin UI Meeting agenda is public and anyone can add new topics in the document.

This weeks Admin UI meeting touched on important disccusion items such as:

  • Beta status/inclusion into core: any important issue we need to unblock asap?
  • Start a plan to implement layout changes into the admin UI, or next-gen designs.
    • It comes from the need to change some regions, like adding a right sidebar region available outside the node form, sticky action regions or a redesign of the Toolbar. The problem is that it isn’t only changes to the theme, it will need changes beyond it and we need to start a plan to get feedback and proposals.
    • Conclusion is to create an ideas issue with wireframes to prepare a meeting during DrupalCon.
  • Claro Documentation for the new Claro theme is still missing a few items. 
    • Recommended block configuration needs to be documented.
    • How to switch from Seven (if there are any steps required besides enabling the theme).
Sep 06 2019
Sep 06

Our team has always been engaged and hands-on when it comes to web accessibility and inclusion. Through learning, teaching, auditing, remediating or supporting others doing the same, providing information access to all is at the core of how we run our business. Inclusivity, equality, and global access is still very much a work in progress for humanity. Any step that Hook 42 can take towards improving inclusion and access, you bet we’re going to do it. This year’s Bay Area Drupal Camp (BADCamp) is no exception.

This camp is packed with content covering accessibility topics. Aimee and Lindsey leading a web accessibility training session on Thursday. On Friday and Saturday, there are four sessions that will touch base on accessible best practices. Thank you to each of the presenters for broadening the audience one of our favorite subjects. We hear you, and are so happy to join in on the discussion!

Web Accessibility Sessions at BADCamp

Your Code is Terrible!, presented by Jayson Jaynes, will cover the topic of semantic HTML. In the talk, Jayson will explain its importance, how to best practice it, and what developers benefit from by understanding it. The best part? Jayson will explore some tools that make creating semantic code in Drupal easier and how to utilize your new tools to ensure accessibility compliance.

It's a Bird... It's a Plane... It's ¯\_(ツ)_/¯? Using Machine Learning to Meet Accessibility Requirements, presented by Danny Teng and Neha Bhomia, will explore a new world where manual input for alt tags becomes a thing of the past. The pair will explore how machine learning can be leveraged to take care of the tedious task of alt text generation. 

Shine a Light on Me, presented by Paul Sheldrake, will cover a broad overview of a chrome extension, Lighthouse, that checks pages for not only accessibility compliance, but site performance and SEO concerns as well. Paul will cover the basics for why it’s important to run these scans, and how Lighthouse can help make that process a little better for everyone.

SVG Magic!, by Anthony Horn, will talk about the glory that SVGs behold. There is more to an SVG than putting scalable vector on the web, and Anthony will walk through exactly what that entails from animation to accessibility compliance and everything in between.

Web Accessibility Training at BADCamp

Our accessibility training session at BADCamp, Web Accessibility Training, will take place on Thursday from 8:00 am to 5:00 pm. We hope you’re ready for a deep-dive into all things inclusion on the web. 

Aimee and Lindsey will cover as much as they can squeeze into one full-day crash course. The course starts at accessibility laws and principles, works through design, content, media, code, and testing tools. We cover the topic with both a broad but deep approach for all attendees to gain the most exposure to such a big topic. 

At the end of the day, our goal is to make sure everyone becomes an advocate for web accessibility! We hope you’ll gain a better understanding of where your organization stands with accessibility, what specific role you’ll play in ensuring your websites stay compliant, and how you can show others where to go in order to apply accessible best practices in their areas of expertise.

It’s going to be a busy camp, and we are thrilled to be part of such a hot topic in the web community. If you want to chat further about accessibility, you can always stop by our booth while you’re there to pick our brains. We’re always in the mood to talk accessibility!

Sep 03 2019
Sep 03

Our lead community developer, Alona Oneill, has been sitting in on the latest Drupal Core Initiative meetings and putting together meeting recaps outlining key talking points from each discussion. This article breaks down highlights from meetings this past week.

You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide assistance on, we encourage you to get involved.

Out of the Box Initiative Meeting

August 27, 2019

Mark Conroy (markconroy) and Ofer Shaal (shaal) talked about:

Drupal Getting Involved Guide Refresh Meeting

August 27, 2019

This meeting:

  • Usually happens on alternate Tuesdays.
  • Is text only!
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • Has a public agenda issue anyone can add to: Meeting - Getting Involved Guide - 27 August 2019
  • Meeting transcripts are still a work in progress, but please comment on the meeting agenda issue so we can grant you credit for attending/contributing!

During the meeting, the following topics were discussed:


We have consensus on Personas! The issue, Consensus on contribution personas, tracks all of the progress. We need to store those personas as they are in somewhere we can easily reference.

Writing Style Toolset

Loving that we know the styles are already agreed in issue Evaluate, pick, and configure checking/linting tools for the Getting Involved Guide. The toolset is making great progress so far.

Proposed outline 

The outline needs a review - how do we make it attractive and welcoming to new potential contributors? Find documentation and progress updates in the issue Proposed Outline for the Getting involved Guide.

Community Section

Admin UI Meeting 

August 28, 2019

  • Meetings are for core and contributed project developers as well as people who have integrations and services related to core. 
  • Usually happens every other Wednesday at 2:30pm UTC.
  • Is done over chat.
  • Happens in threads, which you can follow to be notified of new replies even if you don’t comment in the thread. You may also join the meeting later and participate asynchronously!
  • There are roughly 5-10 minutes between topics for those who are multitasking to follow along.

Beta & Stable Blockers Revision

  • Field cardinality can be unpostponed after table drags has been finished.
  • Cards issue is blocked by action links so that could use some help.
  • Image and file fields are blocked by design work.
  • Status report page is blocked on design unless we go with the existing one for beta.
  • Probably Media designs won’t be on time, so probably the Media should be moved to stable.
  • We need some help with accessibility revisions.

Layout Redesign: Max-width Limit

We opened this issue for Layout Redesign after facing some problems with Card Style Updates with wide screens.

Customizable Settings

Looking to determine what we would like to have as customizable options. The discussion is started in the issue Provide form for customizable settings.

Aug 28 2019
Aug 28

Join Hook 42 for Another Exciting BADCamp

Some of our team will be at BADCamp this year with a combination of to-do's and goals. Our team is not only going to be on-site for training, sessions, booth-sitting, and attending sessions, we're also behind the scenes helping organize and plan for this year's event. Our sponsorship, and those of many other amazing donors, is going towards putting together another BADCamp you don't want to miss!

We're excited to be so hands-on for this event and would like to send a special thank you to those involved in the planning and coordination that have embraced Hook 42's participation thus far. The variety of ways we can contribute to this event and make an impact is extensive, and our team is happy to be giving back to an amazing community. We can't wait for October!

Hook 42 Trainings at BADCamp

We're excited to have four of our team members teaming up to give two trainings this year. The first, Adam Bergstein and Ryan Bateman will be talking about GatsbyJS and Drupal 8. In this training you'll learn how to take a brand new Drupal 8 site running the Umami Demonstration Install Profile and build a recipe blog front-end using GatsbyJS and React, with no React experience required! 

We'll also have Aimee Hannaford and Lindsey Gemmill giving training on web accessibility, covering a beginning to end high-level dive into how to be inclusive on the web. For more information about each training, visit the respective training page BADCamp website linked below.

Hook 42's Adam Bergstein and Ryan Bateman deliver a full day Drupal 8 and GatsbyJS training at BADCamp 2019

Hook 42's Aimee Hannaford and Lindsey Gemmill deliver a full day web accessibility training at BADCamp 2019

Registration For Training Sessions Is Now Open!

There is limited availability for training sessions, so sign up soon. Each room holds approximately 30 people. If you're interested in one of our training sessions, or any other training at BADCamp this year, please be sure to register to reserve your spot. See the training detail page on the BADCamp website for more information.


Beyond full-day training, our team will also be giving a few sessions at BADCamp. We're passionate about the topics we submit to camps and conferences and are excited to be sharing our ideas and expertise with all of you.

Hook 42's Adam Bergstein and Ryan Bateman deliver a session at BADCamp

Hook 42's Aimee Hannaford and Ryan Bateman deliver a session at BADCamp

Hook 42's Lindsey Gemmill delivers a session at BADCamp

Hook 42's John QT Nguyen and Pantheon's David Needham deliver a session at BADCamp

We Hope To See You There

If we aren't behind the computer talking, you can find us out and about. Our team will be fully immersed in BADCamp 2019, so we're just as excited to attend the other amazing presentations selected for this year's event as we hope you are.

Hook 42 will also have a booth at the event this year. We're always looking to make new connections with people at these events and can't wait to talk about the amazing things our team has to offer. Whether you're a new face or an old face, come stop by and say hello!

Aug 26 2019
Aug 26

August 26th is a special day for the owners of Hook 42. As a woman-owned company, we are very familiar with the adversity women face in the workplace. We’re even more familiar with how intense that can get depending on the industry you’re in.

Our inspiration for starting Hook 42 was a culmination of many different things, but one of those things was creating our own voice outside of a male-dominated workforce. The signs were clear that everywhere we looked we found areas of improvement, so our owners took things into their own hands and built a business to solve those problems. 

Hook 42 strives to be a fully inclusive workplace, and we encourage our team to voice their opinions and work towards a better version of themselves, no matter what it takes. 

But what does this philosophy have to do with today specifically?

National Women’s Equality Day and National WebMistress Day fall on August 26th. Both of these topics are influenced by a history of inequality and strive to create an inclusive space that gives everyone an equal opportunity. We’d like to take time to recognize the fights that were won and those we’re still fighting today with the celebration of these two holidays.

A Little Bit of History

The United States Congress passed the 19th Amendment to the Constitution granting women full and equal voting rights on this day in 1920. [ source ]

“Later, On July 30, 1971, Rep. Bella Abzug (D-NY) presented a bill designating August 26th as Women’s Equality Day. That year, rallies, celebrations and political debate filled the country on August 26th. By 1973, Congress passed a joint resolution declaring the day to be observed on August 26th of each year. Every year since each president declares this day as Women’s Equality Day commemorating the certification of the 19th Amendment to the United States Constitution.” [ source ]

We’re predicting that it is no coincidence Kat Valentine founded National WebMistress Day on this very same day quite some years later. In only its third year, National WebMistress Day is putting a more granular focus on supporting equal rights for women and recognizing the adversity women face in the technology industry.

As members of that industry, we want to share our support for every woman in tech that is fiercely making an effort to leave their mark and find their place in a chaotic environment. We’re 100% behind supporting the wave-making, change-inducing women of tech and cultivating that same culture right within our company.

We talked to the ladies within Hook 42 to gather some insights into their journey within tech so far, and what the future holds. Let’s continue to drive change, and support those who are advocating these rights.

The Women of Hook 42


What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Don’t dress down. You don’t need to compromise your personal appearance to fit into the “hoodie and t-shirt crew”. If you want to rock your comfort wear then embrace it!

Believe in yourself. You are the only one that can affect change around you. Make goals, strive to reach them, and calibrate when you need to. You are the only one that can improve yourself and your life.

And enjoy the journey. 

How can people be an ally to women in tech?

Be supportive in all aspects of a woman’s life. The tech industry has long days, off-hours, and overtime baked into its core. This combined with the added mental and physical workload we may experience outside of work thrives on a supportive culture.

What helps you push boundaries in tech?

Technology is one of the fastest platforms to implement and execute change. I love bringing peace to chaos and to create new “things” that help improve our lives. Being able to leverage technology for good is a big driver for me.

Is there a woman in tech you look up to, maybe a mentor? (Can be someone you've never talked to but are just inspired by)
Gerri Sinclair. She balances a loving family and a wonderful extended group of friends while bringing bold technology changes through the years. Thank you for all of your energy and impact on technology Madame Modem!

What are you looking to accomplish with your career in tech?

I like to have a place where people can feel they can work safely where they can grow in their personal and professional lives. I like to build cool things. My goal is to have more people be able to have positive interactions which said cool things. :) I’m working to extending the tech environment beyond the tech to include the human side of things, like growth, authenticity, inclusion, and accessibility.

Were there struggles in your journey? Do you still face them? How did you push past it?

There are and have been many struggles in my journey. Some struggles have changed over time, some are still the same. Struggles include breaking through glass ceilings, having to work harder / smarter / stronger / faster than men, and being criticized for having the courage to lead the charge and search out brave new worlds.

Mentors, friends, professional guidance, education, and grit got me through the struggles. Once again, a person (me) is fully responsible for my own actions, regardless if I’m advised in one way or another.


What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Even though you hear a lot about bad things about being a woman in tech, you can find nice communities who will welcome you and be supportive. If you are in a bad environment in tech (no matter what gender), try to talk to other people in tech who are in healthy environments and consider switching before leaving.

How can people be an ally to women in tech?

Be a good person and call out bad behavior. Try to show that you welcome others in your groups with your words and actions (e.g. the "Pac-Man Rule"). Be open to differing opinions when offered respectfully.

What helps you push boundaries in tech?

Having a supportive community helps us stand on the shoulders of giants and continue to innovate.

What fuels your passion to keep doing what you do every day?

Seeing something I helped build used by real people, in real life.

Is there a woman in tech you look up to, maybe a mentor? (Can be someone you've never talked to but are just inspired by)

Although there are a lot of great people in the Drupal community, there are 3 people who are amazing role models for all genders who immediately pop into my head: Angie Byron, Amanda Gonser, and Gábor Hojtsy.

What are you looking to accomplish with your career in tech?

Using the skills I have for giving back to the greater good and improving humanity.

Were there struggles in your journey? Do you still face them? How did you push past it?

Yes, often. Some things that may help: stay away from toxic people, give yourself permission to fail, give yourself permission to say "no" without guilt, be kind to yourself, and talk to people who have gone through similar things so you know you aren't alone.


What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Keep learning and never give up.

How can people be an ally to women in tech?

Support, mentor, and encourage.

What fuels your passion to keep doing what you do every day?

I like working in tech. I’m passionate about what I do and am looking forward to learning new things and grow professionally. I have a dream to become a successful woman, and this dream keeps me going.


How can people be an ally to women in tech?

Start nurturing curiosity at a young age. Encourage the girls and young women in your life to have bold dreams, because that’s the age where kids start conceptualizing what is “possible” and “impossible.” When I was little, I wanted to be an actress or a ballet dancer, but I never dreamed of being a scientist, astronaut, engineer, or inventor. Young people need to hear and see that women totally belong in every sector of public life.

What fuels your passion to keep doing what you do every day?

I’m lucky to have a strong network of family and friends who are my cheerleaders. My community has supported me every step of the way, and so far I’ve had a diverse, and storied career. I’m a career-changer, and my background is primarily in education, so I didn’t find my way into the tech world until recently. My passion comes from knowing who I am, where I come from, and the community that’s helped me along the way.

What are you looking to accomplish with your career in tech?

Build amazing websites and web applications! Make the digital universe a little more accessible with every project I touch. Along the way, I hope to encourage other underrepresented folks in the tech industry to keep chasing their curiosity.


What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Do more research. It’s amazing to see how many companies flourish in the tech industry. I didn't know how well rounded it was until I got into it myself.

How can people be an ally to women in tech?

I feel there is a stigma around women in the tech industry that they aren't as smart or as innovative as a lot of men. I feel that if women were given the chance to prove themselves, that they are willing to improve their skills and show they want to learn and progress, there would be a lot more women in the industry and a lot more women-owned companies.

What fuels your passion to keep doing what you do every day?

My passion to do what I do every day comes from the great people I work with. Not only do they support me and encourage me to expand my knowledge, but they give me opportunities every day. My coworkers, leaders, and bosses all work hard to make this company run smoothly, and I strive to work like them. I want to prove that I am capable of taking on challenges and exceeding expectations. I want to be a better me everyday.


What would you tell your younger woman-self if you had the chance to give her advice based on what you know now about the tech industry?

Confidence from a woman might seem to be threatening, but continue to show your value and stand tall. Make sure the words you use are thoughtfully crafted before raising concerns and contradictions. The strong voice of a woman is often mistaken, so delivery is important. Take the time to think before you react in conflicting situations. 

How can people be an ally to women in tech?

When you see something awry, say something. If a woman confides in you, listen with the intent to help. See us based on our level of experience, not based on our gender. Fight our fights with us, and support our equality in the workplace.

What fuels your passion to keep doing what you do every day?

There are two parts of this for me, the first being the people around me. If it wasn’t for the support system I have inside and outside of the office, it would be much harder to hold my head high in the moments of struggle. 

I also thoroughly enjoy what I do and had the luxury of choice in deciding where my career would take me. Every career path comes with struggles, and being able to work through them and come out with something to show for is very rewarding for me and makes the work even more enjoyable.

Were there struggles in your journey? Do you still face them? How did you push past it?

There have always been struggles. My confidence is quite frequently confused with attitude. Things men often receive praise for, like telling it like it is and not backing down, are things women get reprimanded for. Not letting that defeat me, and keeping my head held high is what helps push past the discrimination. It’s not just men that take offense to it either, other women are often threatened by frequent requests to do better, and be better for all of us. There is a fine line between intimidation and confidence when conversing with women, and its a struggle I face daily and work to eliminate. It's in part learning how receptive people are to certain words, and others being open to strong opinions coming from a variety of people.

Knowing who I am and keeping sight of my worth, not letting other people’s opinions of me think any differently of myself, and knowing that my experiences and education are just as valid and just as those around me are how I stay my course. That confidence that gets "in the way" is also what keeps me going every day.

What About You?

Do you want to share your support for the women around you? It's imperative that we cultivate an environment of acceptance and one where everyone feels welcome. Take a moment to give a special shout-out to a woman in tech, or any woman you know that deserves some recognition.

Aug 13 2019
Aug 13

A great place to start a conversation about decoupled Drupal is evaluating Contenta CMS. While Contenta CMS is not necessarily something you must have to build a decoupled Drupal 8 site, it is designed to do it. You can relatively easily create a vanilla Drupal site that supports a decoupled application, but Contenta has already solved many of the related problems.

So what is Contenta CMS exactly? 

Contenta CMS is an API-first Drupal 8 distribution intended to be used to build fully decoupled Drupal sites. It was built by the developers of many of the modules you may end up using as you build your decoupled site, using their defined best practices to address typical needs and challenges. It is meant to be 100% decoupled, and only uses Drupal 8 as an administrative backend with no user-facing HTML content. This is something you could change if you desired to do so.

At first it seemed like a magical, mysterious system. However, Contena uses core and well-known contributed modules with only a single custom module that provides a few customizations. With only a few small tweaks, you could conceivably have a base system for your decoupled project with Contenta CMS as you would any Drupal 8 project.


The main difference between Contenta CMS and a site you would conceivably build yourself lies in the only custom module the distribution comes with, Contenta Enhancements. This module primarily does a few things:

  • creates a new, streamlined administration toolbar for a decoupled site,
  • provides some additional local tasks menu items giving easy access to necessary configuration,
  • alters the node view to display JSON instead of HTML, allowing for easy viewing of node structure, and
  • disables certain routes not needed or necessarily useful for a decoupled site.

Because this is a Drupal module, you’re perfectly fine installing it in your own clean Drupal 8 install to try to replicate Contenta along with the contributed modules used.

Key Modules

The following modules make up the underlying Contenta architecture.


Consumers is a utility module that allows other modules to define users of the API and then further allows administrators to manage access control for each consumer. 

Decoupled Router

As the module description states, "Decoupled Router provides an endpoint that will help you resolve path aliases and redirects for entity related routes. This is especially useful for decoupled applications where the editor wants full control over the paths available in the consumer application (for instance a React app)."

To further understand the purpose of Decoupled Router, read the great post (and series) by the module creator.

JSON:API (now part of Drupal 8.7 Core)

JSON:API is a plug and play module that fully implements the JSON:API Specification that without configuration exposes your Drupal entities via a REST API.


JSON:API Extras extends the JSON:API module by allowing customizations and management of API endpoints. The JSON:API module does not offer any configuration options.


While JSON:API exposes Drupal entities via a REST API, JSON-RPC exposes Drupal administrative actions that would otherwise not be easily accessible or handled using the REST API.


The OpenAPI is a utility module that allows your Web Services to be discoverable using the OpenAPI standard and thus neatly documented for testing and development when used in addition the OpenAPI UI and either something like OpenAPI UI Redoc or another similar module.


OpenAPI UI helps provide a user interface within Drupal for displaying your OpenAPI standards-based API explorer for your Drupal site.

OpenAPI UI Redoc

This module provides a plugin that implements Redoc for use with OpenAPI UI to display from within Drupal. This is akin to GraphiQL in the GraphQL standard.

preview of redoc in drupalOpenAPI UI using Redoc in Contenta


SimpleOauth is an implementation of the OAuth 2.0 Authorization Framework RFC for Drupal allowing you to use Oauth 2.0 for user authentication.


The subrequests module allows aggregated requests and responses to be sent to Drupal. For example, instead of sending a request for a node and then the node’s associated taxonomy terms, it allows you to send a single request that returns all the data you’d need. The goal being to make decoupled applications more efficient by reducing requests. An excellent article on the motivation for this module can be found on Lullabot’s blog.

Installing Contenta

To get started, head over to the Contenta install page. After installing, run: drush runserver to run server, then access to view site.

preview of contenta home screen

Upon logging in, you will find a familiar interface, with some slightly different links available, with all but the “API” link leading to common Drupal administration pages, and the “Advanced Link” exposing the default Drupal administration toolbar.

preview of contenta admin screen

You should be now ready to begin building your decoupled site. In the following posts in this series, I will explore doing just that.


By adding and configuring the above modules to a new or existing Drupal 8 site (I can’t stress enough that you must install modules using composer), configuring CORS (if needed), you should be ready to begin developing your decoupled application using the technology of your choosing so at this point I wish you happy trails!

*P.S. The folks that brought you ContentaCMS also created ContentaJS, “a nodejs server that proxies to Contenta CMS and holds custom code”. It’s certainly not necessary to begin your decoupled journey, but it does provide some handy features that I think could be extremely useful.

Aug 06 2019
Aug 06

Author’s Note: No rabbits were harmed in the writing of this post.

This summer, I had the opportunity to attend Decoupled Days 2019 in New York City. The organizers did a fabulous job of putting together an extremely insightful, yet approachable, program for the third year of the conference to date.

In case you haven’t heard of the event before, Decoupled Days is somewhat of a boutique conference that focuses solely on decoupled CMS architectures, which combine a CMS like Drupal with the latest front-end web apps, native mobile and desktop apps, or even IoT devices. Given the contemporary popularity of universal Javascript (being used to develop both the front and back ends of apps), this conference also demands a strong interest in the latest JavaScript technologies and frameworks.

If you weren’t able to attend this year, and have the opportunity in the future, I would highly recommend the event to anyone interested in decoupled architectures, whether you’re a beginner or an expert in the area. With that in mind, here are a few of the sessions I was able to attend this year that might give you a sense of what to expect.

Christopher Bloom (Phase2) gave an excellent performance at his session, giving all of us a crash course in TypeScript. He provided a very helpful live demo of how TypeScript can make it much easier and safer to write apps in frameworks like Vue.js, by allowing for real-time error-checking within your IDE (as opposed to at runtime in your browser) and providing the ability to leverage ES6 Class syntax and decorators together seamlessly.

Jamie Hollern (Amazee Labs) showed off how it’s possible to have a streamlined integration between your Drupal site and a fully-fledged UI pattern library like Storybook. By using the Component Libraries, GraphQL, and GraphQL Twig contributed modules in concert with a Storybook-based style guide, Jamie gave a fabulous demonstration of how you can finally stick to the classic DRY (Don’t Repeat Yourself) principle when it comes to a Drupal design system. Because Storybook supports front-end components built using Twig markup, and allows for populating those components using mock data in a GraphQL format, we can use those same Twig templates and GraphQL queries within Drupal with almost no refactoring whatsoever. If you’re interested in learning more about building sites with Drupal, GraphQL, and Twig, Amazee Labs has also published an “Amazing Apps” repo that acts as a sample GraphQL/Twig sample project.

For developers looking to step up their local development capabilities, Decoupled Days features two sessions on invaluable tools for doing decoupled work on your local machine.

Kevin Bridges (Drud) showed how simple and straightforward it can be to use the DDEV command-line tool to quickly spin up a Drupal 8 instance (using the Umami demo site profile, for example), enable the JSON:API contributed module in order to expose Drupal’s data, and then install (using gatsby-cli) and use a local Gatsby.js site to ingest and display that Drupal data.

Matt Biilman (Netlify) also demonstrated the newly launched Netlify Dev command-line tool for developers who use Netlify to host their static site projects. With Netlify Dev, you could spawn an entire local environment for the Gatsby.js site you just installed using DDEV, which will be able to locally run all routing rules, edge logic, and cloud functions. Netlify Dev will even allow you to stream that local Gatsby.js site to a live URL (i.e., on Netlify) with hot-reloading, so that your remote teammates can view your site as you build it.

As usual, Jesús Manuel Olivas (WeKnow) is always pushing the Drupal community further and further, this time by demonstrating his own in-house, Git-based CMS called Blaze, which is a platform that could potentially replace the need for Drupal altogether. Blaze promises to provide the lightest-weight back-end possible for your already light-weight, static-site front-end. In lieu of a relatively heavyweight back-end like Drupal, Blaze would provide a familiar WYSIWYG editor and easy content modeling with a few clicks. The biggest wins from using any Git-based CMS, though, are the extremely lowered costs and lightning-fast change deployments (with immediate updates to your code repo and CI/CD pipeline).

Jul 29 2019
Jul 29

This year, Drupal GovCon had an amazing turnout. So great that the registration was at full capacity and had to cap attendance at 1,500 people!

Our team had an amazing time exploring Bethesda, from the conference grounds to the thriving community around it. While there we enjoyed conversing with the community, and forging new relationships. We learned many things, and shared our experiences with many others as well. Overall, it was a great environment for exploration and growth.  

From Hook 42 we had a first-time ever Drupal event attendee, an experienced Drupal veteran, and a goldilocks somewhere in the middle community member join forces. With the variety of community involvement just from our team alone, there were many different expectations attending this event and each person had their own goals and takeaways from this experience. We’re excited that an event can bring so many different people together and provide an experience that resonates with many different community members. Here's what we took away from this GovCon this year.

Aimee's Thoughts

GovCon 2019 delivered another great experience for me. I am a huge advocate of GovCon. I have found great value in my time spent here and look forward to returning each year. This camp is such a well run event that consistently delivers an inclusive, supporting and rewarding experience. I very much enjoyed my time there as a speaker, member and participant. I appreciated the structured content as well as the well attended after events where I got a chance to catch up with old friends, and meet many new people.

The sessions line up at GovCon 2019 was packed full of talented and useful information. There was so much I couldn’t attend that I’m especially grateful for the YouTube recordings. A big shout out for Kevin Thull and the team for getting these up!

It was an honor to be able to deliver my keynote, CommYOUnity: Fostering Healthy Contribution, at GovCon. Community is such a vital, core value to Drupal and that community is built on you and me. When we can build healthy relationships and make time to take care of ourselves we’re actively working on taking care of the community.

Thanks again for the wonderful opportunity and great experience GovCon!

Ryan's Thoughts

First, I wanted to give a big thank you to the event staff and volunteers who made GovCon 2019 possible. I am a first time GovCon attendee and had a great time. I knew when and where the sessions I was interested in were and found my way around NIH easily. The great planning and coordination that went in to GovCon made my experience very enjoyable.

Janessa Worrell and Brianna McCullough, from Acquia, gave a great presentation on governance, "Winter is Coming: How to Use Good Governance to Prevent your Organization from Becoming a Game of Thrones". They brought awareness to some of the harder to reach topics that help an organization align to make better project decisions and did it in an entertaining and informative way.

It was a pleasure to meet David Minton and Stephen Pashby from DesignHammer and then later see their presentation on estimation, "Successful Project Estimation: How To Get Your Weekends Back". Their modeling on historical throughput with detailed task tracking is an engaging idea I think we could put to use. 

I really appreciate the community that came together to share their thoughts and experiences and I look forward to my next opportunity to attend.

Lindsey's Thoughts

I’m semi-local to DC, and very familiar with the area so much so that I would come here as a child on field trips and such. I wasn’t coming here with the excitement of exploring the local community and the city, but more so with the intention of bonding with the Drupal community itself. Making connections with people that are experiencing similar situations as I evolve within the Drupal world is very important to me.

I spent most of my time holding down the booth, talking with many people about the great things our team has to offer. It’s a great way for a new Drupal-member to get to know a lot of people. For the first time ever, I experienced the joy of seeing connections I made at another Drupal event, and seeing their faces in the community again. Those bonds are already strengthening and I couldn't be happier! I am getting to understand just how connected our community really is.

When I wasn’t at the booth I attended sessions about accessibility. One common theme in all of them is that the speaker always shared empowering experiences that would resonate with the audience. They weren't necessarily technical, or Drupal related, but they provided a very humanistic connection to an issue that is usually backed by threatening legal concerns. 

I enjoyed hearing Shawn Brackat from Forum One sharing a story of a blind couple receiving a 3D model of an ultrasound, and Catharine McNally from Phase2 sharing her stories about growing up deaf and receiving the first ever study on cochlear implants. These are aspects of accessibility that people really bond with. Being inclusive is more than just avoiding a lawsuit. It’s about making things easier for everyone, and providing ways to accommodate those that do things differently. Everyone experiences things differently, disability or not, and it's important that we keep that in mind as we build digital experiences for the masses.

I enjoyed participating in my first GovCon in a variety of ways. Whether that was sitting at the booth, attending sessions, or dinner with great friends - I have had so many wonderful experiences. I’m already looking forward to next year.

Wrapping Up

The community always goes above and beyond, providing experiences that everyone can resonate with. GovCon did not fall short of those high standards. We’re so thankful to all of the organizers, and happy to have been one of many great sponsors that can help support events like these. All of us had a wonderful time, and we’re happy to be so involved with a community that has a great ecosystem. We’re already planning our next event... we’ll see you in Denver!

Jul 26 2019
Jul 26

We’ve recently wrapped up another great Drupal event, at Drupal Camp Asheville. The sponsorship our team provided, in conjunction with the support of many others, helped the camp achieve many goals that we are proud to have been a part of. 

The experiences our team had stood up to the expectations of all Drupal events,

From Hook 42, we had three people who were able to participate this year, and each member of our team had different expectations going in, and learned many valuable things. Here’s what they have to say.

Danita’s Experience

Although it was only my second year of attending Drupal Camp Asheville, it already feels like “home.” One of the highlights of any Drupal camp or con or meetup is getting to see old friends and meeting new ones, and this camp doesn’t disappoint. An added bonus was getting to hang out with two Hook 42 colleagues (including Jonathan, one of the camp organizers), something that doesn’t happen often enough with a remote team.

On Friday, I joined a fairly packed room for a full-day training on CSS Grid and Flexbox with Wes Ruvalcaba, Senior Front-end Developer at Lullabot. Along with how to use Grid and Flexbox, Wes shared some tips and tricks he uses when theming Drupal websites. Even though I’ve used both Grid and Flexbox before, I came away from that all-day training with a better understanding of when and how they are “supposed” to be used - and to quit using “floats” for layout!

Sessions I attended on Saturday included one on contributing back to Drupal presented by Amy June Hinelline, Kanopi’s Community Ambassador. It was a good reminder that anyone (not just super-experienced coders) can do something to contribute and that our contributions make the community stronger.

In addition to the trainings and sessions and “hallway track” conversations, the social events and just the location of the camp in Asheville make this a not-to miss camp. I know I can’t wait until next year. 

Jonathan Experience

Another great year at Drupal Camp Asheville. On Thursday we all gathered to play games and hangout at the Wedge. Friday I gave my full-day “Essential Drupal 8 Developer Training”, and it went really well. I had a full class with lots of great questions and comments, and like last year, my voice started to give out. I didn’t record the training this year, but it was basically the same as 2018. Videos, slides, and code examples for the training are all available online.

Saturday we had an amazing group of presenters show off some of their best work and discuss topics they are passionate about. As an organizer, we made a lot of effort ensuring that there were great sessions for almost any topic related to Drupal or Drupal adjacent. We had everything from improving client interactions to an overview of the JSON:API, from understanding Drupal 8’s caching mechanisms to a discussion of emotional labor in communities, and from working effectively as a remote team to data analysis and visualization.

All sessions were recorded and uploaded to YouTube. Full playlist Drupal Camp Asheville 2019 sessions

As an attendee, it was really great to see the old guard and meet some of the new. I had a great chat with a new Drupal developer who is implementing a chat bot for his university, enjoyed tacos and beverages with the creators of Backdrop CMS, and talked about video games with friends as we hiked up to Catawba Falls. It’d be difficult to list each great interaction I had because there were good people and fun conversations happening practically the whole time. 

Biased opinion: I can’t recommend Drupal Camp Asheville enough. Thanks to all the hard work by our Director April Sides, the camp is well managed and a wonderful, casual, and considerate event for everyone. Hope to see you there next year! 

Group photo of drupal asheville attendees waving

Jul 11 2019
Jul 11

For the past several years (2016, 2018, 2019) Dries has written articles aimed at helping people decide if and how one should decouple Drupal; a general survey of the state of decoupled/headless Drupal. In his most recent post he mentioned the pace of innovation has been accelerating due to the number of Content Management channels and JavaScript frameworks to support. I’ve been particularly excited about the JavasScript frameworks and hoped to find more in-depth coverage of this.

Much to my chagrin, from numerous conversations with Front-End developers as well as other Full Stack developers, I’ve found that knowledge in the community about a lot of the innovations happening outside the traditional Drupal or Open Source world has not grown as fast. Much of the content being published, in my opinion, doesn’t necessarily do a great job of covering some of the better possibilities out there and potentially leave readers and attendee’s of talks un-informed on just what the possibilities are.

Understandably, everyone can’t be expected to know everything about everything, but I believe there’s an opportunity for the community to leverage some of the powerful tools that exist with the knowledge we have to increase the use case for Drupal.

Show ‘Em What We’ve Got

Today, unlike the days of yesteryear, many members of the community are already equipped with the tools to build truly native mobile applications thus eliminating the need for Java or Swift since JavaScript and TypeScript based languages can be just as effective. 

In the interest of raising more awareness of what’s out there, I’ve decided to explore some of the most popular frameworks for building native mobile apps from a single codebase using technologies familiar or learnable by many. With that, I’ll be exploring their ease of integration with Drupal.

Exploring The Possibilities

Over the next several months I will explore and evaluate some of the tools available for native mobile app development, as well as Drupal tools, modules, and distributions that facilitate this. I will also go through the process of building actual apps to provide insight into the research you may not have the time to do yourself. 

The tools I will explore, in addition to core and contrib Drupal modules, will include:

  • ContentCMS (API-first Drupal distribution)
  • ReactNative (Framework for building mobile apps with ReactJS)
  • Tabris (Framework for building native mobile apps with JavaScript or TypeScript)
  • NativeScript (Framework for building native mobile apps with JavaScript, TypeScript, Angular or VueJS)
  • Appcelerator Titanium (Framework for building native mobile apps with JavaScript)
  • Fuse (Framework for building native mobile apps with JavaScript)

My hope is that by the end of the series, there might be a few converts to Drupal-powered native mobile development both from the Drupal side and from the frontend development side. WordPress is already ahead of Drupal on this with several plugins that convert WordPress sites into native mobile apps, so we have some catching up to do.

Jul 01 2019
Jul 01

Our lead community developer, Alona Oneill, breaks down highlights from Drupal Core Initiative Meetings this past June. You'll find that the meetings, while also providing updates of completed tasks, are also conversations looking for community member involvement. There are many moving pieces as things are getting ramped up for Drupal 9, so if you see something you think you can provide insights on, we encourage you to get involved.

CMI 2 Initiative Updates

Status of CMI 2

Major patches are being reviewed and hopefully will land after it gets a change record.

Next steps for CMI 2

  • A final review from Lee to be completed.
  • The config environment module, different configuration in different environment, is in production.
  • At a stage where nothing is needed from Core Cm or FM’s.

Composer Updates

Status of Composer

A patch went in to use composer as a dev requirement and we're on the road to making core test builds and upgrades. The scaffolding patch was reviewed and moved to RTBC.

Next steps for Composer

  • Need core maintainers to review the testing framework from miles 23.
  • Need core team to help with the scaffolding issue.

Workflow Updates


There are two major patches being worked on at the moment:

Would also like to see the issue to allow 'syncing' content to be updated in content moderation without forcing the creation of a new revision be updated. Content moderation is working with this as it allows people to moderate any content within the workspace via the user interface.

Stable release

Upgrade path is on hold until this approach is validated or approved. Workspace merging is currently in need of an issue.

Next Steps for Workflow

Get release managers and fm review is needed on issue #3062434. Get FM review on issue #2803717 because it currently needs additional input. An issue for workspace merging also needs to be created. We're trying to get the first 2 issues into 8.8 (and 8.7).

Drupal 9 Updates


  • Drupal check got a release last week by mglamman with all deprecation error messages.
  • Upgrade Status has new features in dev that categorizes error messages on actionability. The action items are, supported, deal with it now, not supported, deal with it later, or deprecated for Drupal 9.
  • Explaining in the UI of the module to help them engage with contribution maintainers.
  • There is low-level planning in the works to:
    • Identifying work to manage dependencies and defining the process to do this work.
    • Issues related for info:
    • We are asking for investment from Acquia to complete some of the work.
    • Core jQuery UI discussions are continuing.
    • Symfony 5 branch is now open! The branch requires a min php 7.2. For Symfony 4 the php requirement is 7.1.

Drupal 9 Blockers

Cannot complete deprecation list for 8.8 because November is when we’ll get the list from Symfony for the SF5 release.

Next steps for Drupal 9

  • Continue to keep tabs on what is happening with Symfony 4 and 5 changes.
  • Review the list of items being deprecated for 8.8 with RM/FM.
  • Make a decision on if the team goes with Sf4 or Sf5.
  • Confirmation on the resourcing ask for Drupal 9 work.
  • Confirming the front end deprecation process.
  • Identifying critical path items and sequencing for Drupal 9 work.

Claro Updates


We have one group working on admin ui theme, Claro. There is a lot of contribution progress from both front-end developers and designers. The Alpha 3 release of Claro was released in the middle June.

Another team is working on react-based decoupled admin ui, however there is not much momentum at the moment. So far, a component library has moved forward with limited resources.

Next steps

The team is on track for getting in 8.8, likely as a beta. This will address open issues with designers,  address changes that developers need to make which have already been found, and work on get approval from RM/FM on moving the theme toolbar CSS to the Seven theme.


  • At Devdays++ accessibility improvements and fixes were worked on and signed off by RM/Media team consensus.
  • Drag and drop zone for file uploads was discussed at the UX meeting as the current design was causing accessibility issues.
  • The plans for WYSIWYG are complete and ready to be worked on moving forward. 
  • Media metadata issues are now unblocked.

Next steps

  • Continue prototyping on the accessibility solutions to be compatible with drag/drop zone for file uploads.
  • Keep working with contributors and community members to find solutions that could incubate there.
  • Keep working on WYSIWYG.
  • Resource and allocate people to work on metadata.

Migrate Updates


The current migration is not as user-friendly as we’d like. We need a better user experience.


There is a large list of things generated from Angie Byron on the experience:

  • Running a pre-flight check will reveal if your data has an issue. We need a better way to check that issues you’d run into are uncovered and fixed before they migrate.
  • Solution needs to not mess with the command line and be more intuitive.
  • Working with UX to find an appropriate solution.
  • Currently have 4 migration maintainers with limited additional resources. We need more people writing code!

Next steps

We will continue with the multilingual upgrade path and keep working on preflight check to improve the migration experience. 

It Takes A Village

Thank you for being involved in the community, we're happy to be helping spread the word about the progression of a great platform. Please check back for frequent meeting recaps to gather insights on the latest Drupal Core developments and find ways to get involved. Our community thrives when we all come together!

Jun 20 2019
Jun 20

For years, community members from Chattanooga talked about their local camp. These community members routinely support other camps, through attendance, volunteerism, and by giving talks. It was our time to return the favor.

Hook 42 not only sponsored the event, but delivered a training and two sessions. From our team Jonathan and Adam attended, and they really enjoyed the time there.

Adam’s Experience

I was grateful to have the opportunity to deliver a full-day training on GatsbyJS on Friday and one of the featured talks on Saturday. I want to recognize my training peer Ryan Bateman who helped out with many of the preparations for the training. I also want to thank attendees who came to either. 

The training was an end-to-end GatsbyJS primer. We set up a Pantheon instance running Umami. We walked through a series of primers and hands on lessons. Most in the room were able to deliver a working Gatsby recipe site to Netlify. It was fun to cover so much material and watch people go from nothing to a functional site. Feedback was positive and it was very helpful to have the super fast Chattanooga internet speeds.

I prepared a brand new talk entitled “Evolving Priorities: Tech, Community, and Impact.” I looked at topics like technical skills, emphasizing the needs of people, and changing our individual frame of reference to what has an impact on the world. I also shared some thoughts on the evolution of Drupal, both from a community and a product. I appreciated those who attended and subsequently gave me feedback for future improvements.

Many people from other close by camps were able to attend. It was so nice to see friends from Asheville and Atlanta to show their support for the deserving Chattanooga crew. Doug Vann, Mike Herchel, Aaron Feledy, and Jordana Fung, among others, also attended from the broader community. It was great spending time with everyone.

I found the camp to be friendly and represent the spirit of those giving back to the Drupal community. Organizers selflessly volunteered their time and committed to helping their guests have a wonderful time. In particular, I was able to go to Rembrandt coffee, Freemont (burger and craft beer night), and Heaven and Ales brew pub. It was a beautiful area with green scenery and beautiful waterways.

Jonathan's Experience

And so we meet again. 2019 was my 2nd year at Drupal Camp Chattanooga, and it was even better than the first. Hanging out with the locals and those visiting from other areas is one of my favorite parts of attending a Drupal Camp. Last year I had to rush home and didn’t get much of a chance to get the full experience, but this year was different in all the best ways.

We started the camp off right with a game night at Code Journeymen’s offices and had a rambunctious night of accusing people of fascism while enjoying each other’s company. It was a welcoming and comfortable atmosphere that, as a camp co-organizer myself, I admired greatly.

After I had a short adventure of being lost in the parking lot, the camp itself seemed to go off without a hitch. They had a lot of really great presentations. I evolved my priorities with Adam, learned about fixing my mistakes as a developer with Jordana Fung, finally got to see Mike Herchel’s Front-end Performance talk, and over lunch looked at some code and talked about custom composite/rich fields with Hawkeye Tenderwolf. It was great times all around.

It was also a great enjoyment to have the opportunity to give my presentation, Glitch: Love to Learn the web again, as the Glitch product and community are a topic I’m very excited about. Reception of the talk seemed to be good as well. There were multiple outstanding questions that I tried my best to answer, and I even remembered to repeat one of them back on microphone for the recording. Otherwise, it was basically a blur of me gushing over Glitch. Check it out!

After camp wrapped up, we were off to the arcade. Rather, a pinball museum, where we played some games older than anyone I’ve ever met and played on another machine that had to weigh over 1,000lbs. We enjoyed a round of pizzas and beverages before hitting the town, exploring a few of Chattanooga’s secrets.

All-in-all, what a great camp experience. As a co-organizer of Drupal Camp Asheville I have some sense of what it takes to make a camp happen, and those Chattanooga folk make the hard work look easy. I can’t recommend enough that you try to attend Drupal Camp Chattanooga 2020.

*Image taken at Drupal Camp Chattanooga, borrowed from Twitter.

Jun 10 2019
Jun 10

This post was written by Adam Bergstein with input and feedback from Aimee Degnan and Ryan Bateman.

Hook 42 recently had a project that required the use of Kubernetes. Kubernetes is an orchestration tool that helps solve many enterprise problems when using multiple containers. People often want redundancy and scale across a series of containers or the same set of containers across multiple machines. Kubernetes helps solve this. It also can help perform orchestration tasks during failures or to distribute load between containers. Managing containers at scale can be a challenge and the goal of Kubernetes is to help.

We have long been tracking the efforts of Lagoon, a promising open source continuous integration and continuous delivery (CI/CD) hosting platform that is developed with Kubernetes. CI/CD is built around the concept of rapid deployments of ongoing, frequent changes. This lowers the risk presented by larger, fixed deployments by promoting smaller, more routine deployments. Lagoon not only offers hosting-related tools, but the platform is able to run locally as well. The CI/CD capabilities helped create testable environments as we pushed changes through our development workflow. We want to share our experience. 

Understanding Considerations

There are some key concepts to understand how Lagoon works before diving in.


Drupal applications require a “source of truth” for persistent content, which includes a Drupal application’s managed files and database. Production environments (or pre-production before a system is launched) conventionally serve as the source of truth environment within a development workflow. Content is subsequently pulled from the source of truth and it is only managed by changes made directly on the production system. Where code can be pushed through environments, content should always get pulled from production. 


Code repositories are critical for managing code and deployments. Each change is one or more commits that can be staged within specific branches. Changes can be merged into other branches, rolled back if there is an issue, and audited as a series of changes. 

Hosting providers offer varying conventions and integrations tied to code repositories. As a simple example: both Pantheon and Acquia offer their own Git repositories commonly synchronized with a Github or Gitlab repository. The Github/Gitlab repositories offer development tools like pull requests or integrations to help support team-based workflows. 


Both repositories and hosting platforms expose relevant hooks that are useful for performing actions during DevOps events. This is how automation can be built into specific changes. Automation is critical for any CI/CD infrastructure, as it’s not manageable or practical to manually rebuild environments as each frequent change occurs. 

Creating and maintaining branches, tags, and pull requests tied to repositories create opportunities for automation that are commonly leveraged repository events in our DevOps infrastructure. Even synchronizing between two repositories can be a useful DevOps trigger, as this signifies code is ready for some degree of deployment or testing. 

Any sort of deployment found in CI/CD workflows often require rebuilding containers. This is common for all environments. Persistent aspects may be left untouched, while the containers for a given environment are rebuilt as new changes are deployed.

On-demand Environments

Cloud infrastructures changed the traditional way of understanding environments. On-demand environments are a result of rapid change and are transient. This is in contrast to an environment traditionally configured on a bare metal server. On-demand environments are commonly provisioned with new branches, tags, or pull requests and destroyed when the changes are deployed. They are not intended to persist.

In a CI/CD workflow, incremental changes are verified before the production deployment. Development-specific branches and pull requests can build new environments known as on-demand environments. Persistent contents from the “source of truth” are copied with changes pushed to a branch on a new environment. This helps to verify and mimic production behavior with the new change. And, the environment subsequently goes away when the change is deployed.

Fixed Environments

Hosting providers still commonly offer “fixed” environments as people are not often comfortable merging an on-demand environment right into production. But, fixed environments exist for an intended purpose. As an example, a production environment is intended to be what end-users access. Other environments are commonly used to vet changes before a production launch. Vetting may include any of the following purposes: proper deployment, stakeholder approval, automated tests, and verified with the most recent code (changes pushed while the code was developed and/or staged). The same fixed environments can be uniquely configured and used in those capacities in a more permanent capacity.

Exploring Lagoon

Every hosting platform has a set of best practices tied to their platform that drives intended use. While any platform, like Lagoon, can seem opinionated, our focus is to connect the aforementioned concepts to their specific Lagoon equivalent. 

Repositories, Hooks, and Events

Lagoon, at this point, attaches to a remote repository, like Github or Gitlab. Lagoon integrates through the repository platform, via a webhook or continuous integration system. The hook is intended to be invoked during specific events like branch creation and/or pull request to help create the CI/CD on-demand environments. This approach shaped our development and release workflow to the Lagoon platform, which we elaborate more on below. 

Fixed Environments

The first thing our team did was set up fixed environments tied to specific branches. This met the need of having changes go through a conventional development, staging, and production release cycle. Within Github, there are subsequent branches for each fixed environment. As a best practice, each branch was locked within Github. This is to ensure a branch was not accidentally removed, which may remove a fixed environment entirely. 

Github repositories often leverage “master” as the default branch. We’ve selected that as our branch for our development server. This is useful for pull requests, as “master” is selected by default and our team didn’t need to worry about selecting the wrong branch. Doing so may trigger a code deployment to another, unintended environment.

On-demand Environments

Lagoon maintains two events for provisioning on-demand environments. The first is pull requests. Pull requests seem to be useful if you are operating in a pure CI/CD environment where changes can be tested as an environment tied to the change. But, pull requests often are not created until a potential change is ready to be reviewed and possibly merged. This would be ideal for an environment to do smoke testing. But, we desired to have environments for work-in-progress as well, where anyone could push a commit to a branch, demonstrate some work, or get help on something. We opted not to use pull requests for that reason.

The second provisioning event is through a branch pattern. This leverages a naming convention to create on-demand environments. Lagoon monitors the creation of any branch that matches the pattern and creates an environment. This is helpful for the initial testing of changes.

Release Workflow 

Our release workflow is based on staggered branches. Changes are pushed to the on-demand branches and prepared for initial review. A pull request is made for the code review and smoke testing occurs on the on-demand environment. Once the pull request is merged into master, our development server is rebuilt (any commits pushed to master trigger a rebuild of the development server). We close all on-demand branches at this point, which subsequently removes the environment on Lagoon. 

Once the merge is complete, additional quality assurance, client review, and automated testing occurs through development and staging environments. This happens by making a pull request from the master to staging branches, creating a release candidate. 

With all of the verification passing, we are able to initiate the release. This is done via a pull request from the staging to production branches. Once the pull request is accepted, the production release occurs. All of this is automated thanks to the hooks and events tied to the Lagoon platform.


Lagoon rebuilds environments on every push to a branch. In our workflow, accepted pull requests push vetted code to branches. Persistence becomes a major factor when environments can be rebuilt in this fluid manner. 

Lagoon also provides the ability to configure what environment is deemed the production environment. This is subsequently protected within Lagoon and persistent. The “production” branch, and its subsequent environment, represent the source of truth for database and files. Rebuilding the database and files on a production release is risky, so this mechanism needs to exist to differentiate from the other more fluid environments that get rebuilt more routinely. These protection mechanisms helped avoid production data being overwritten through the API or any unintended impact by a production deployment and subsequent rebuild. Not only that, but this helps identify what data needs to be routinely backed-up and maintain high fidelity.


All non-production environments should automatically load a copy of the production database and files when new changes are pushed to the subsequent branch. Verifying changes before being released to production was a critical DevOps automation for us.  We leverage hooks in Lagoon (defined in the .lagoon.yml file) with Drush commands and aliases to identify the environments that synchronize the database and files from production every time an environment is rebuilt.  

Code artifacts were also a vital part of our DevOps automation. We leveraged Composer to build the Drupal codebase (using the great Composer template for Drupal projects - drupal-composer/drupal-project) and Gulp to build the theme. Custom code was committed to the repository. This allowed us to easily and routinely evaluate changes to core and contrib.

Once our code was built, we executed Drush commands to import the configuration, run database updates, and clear caches to ensure changes were properly deployed. While this does not catch every possible nuance in deploying code (e.g. rebuilding entities), we automated a significant portion of this that should minimize the need for running manual commands. 


Lagoon is doing some innovative work, especially for Drupal teams looking for a CI/CD platform adopting rapid releases. Their “infrastructure as code” implementation, through their Docker images and .lagoon.yml configuration, enable rapid, effective change at the heart of DevOps that can help continuous learning and the subsequent predictability of automation. 

As expected, coming from the perspective of using other hosting platforms like Acquia and Pantheon, there was some learning to adapt to the fluid CI/CD nature of the platform. Lagoon’s local implementation replaced our standard MAMP, DDEV, and Lando setups. Being able to add in restrictions, like branch locking, was beneficial to our teams transition when configuring the infrastructure. Also, there were some different conventions, like leveraging drush aliases through Lagoon’s CLI container and not through a local Drush, that were unique. But, many of our existing knowledge and concepts were the same or could easily be mapped to their Lagoon equivalent.

After some trial and error, we were able to share some feedback with the Amazee team on improvements to their documentation and relevant code samples we felt could help others. Hopefully shaping the path forward for others being onboarded can make it easier to digest for those new to the platform.

Overall, Lagoon shows a lot of promise for modern workflows. While different than other hosting platforms, Lagoon enabled our team to work effectively and efficiently from start to finish. We’re excited to see how the platform evolves and continues to provide solutions capable of rapidly changing to our customer’s needs. 

Jun 05 2019
Jun 05

Hook 42 is headed to Tennessee for our next community event. Not only have we proudly sponsored Drupal Camp Chattanooga, you'll also find us doing a Gatsby.js training as well as giving talks about topics we hold near and dear to our hearts. Come say hello if you're there.



We're very excited that Adam Bergstein will be conducting this year's keynote in Chattanooga. You don't wanna miss it!

Change is the only constant in life. As technologists, the landscape around us is constantly shifting. We must evolve or become irrelevant. How do we do so? It's a gradual thing, but it also happens so quickly. Together we're going to explore considerations around that evolution and how we can embrace the changes. 

Topics include the limitations of technical skills, a purpose-driven perspective, and evolving ourselves. When evaluating Drupal, Adam shares how the product and community have evolved in the past and opportunities for the future. You can take away some perspective on how to approach change and evolve professionally.

Glitch: Love to learn the web again

Jonathan Daggerhart is talking about one of his favorite community tools - Glitch! You may not be entirely sure what Glitch is, but we promise you'll leave with more excitement than ever for learning new web technologies again. Jonathan will be covering the basics of Glitch, demoing it, and you to use it for fun and profit! Bonus points if you are already using Glitch today.

Man sitting at desk typing on laptop with gatsby.js logo on the screen



Adam Bergstein is leading an all day training on Friday, June 7th, diving deep into Gatsby.js. Make sure you bring your laptop, as this training is very hands-on. We're ensuring everyone participating can leave with a more developed sense of what Gatsby.js can do and how you can implement it in the future. In this training session, Adam will go over setting up your environment followed by primers and follow along exercises that cover the following items:

  • Setting up Gatsby
  • Basic GraphQL & Gatsby
  • Test Drupal GraphQL
  • Recipe Listing Page (plus responsive images)
  • Recipe Detail Page
  • Updating Recipe List
  • Deployment

We hope you're ready to get your hands dirty with this training.

See You In Tennessee

We're excited for our trip to Tennessee. Yet again our ambitious team is always rushing to be first in line for the growth of our community. We enjoy trading stories with all of you, which is why it is important for us to share our experiences and methodologies that we've fine-tuned along the way. Chattanooga is just another stop on the community train for the Hook 42 team, and we couldn't be more excited to watch our community learn and grow together. We hope to see many familiar faces this year and make some new friends along the way.


May 31 2019
May 31

How to create a custom Facets query for your Drupal 8 faceted search app

When it comes to allowing users to search a site easily, a faceted search app can be an unparalleled solution. Being able to quickly drill down into search results using specific, easy-to-understand parameters is something that most users now simply expect from any site’s search app.

For Drupal 8 sites, the Facets module makes it relatively simple to create your own faceted search app, whether you’re using the Drupal core Search module or the very popular Search API module to manage your search functionality.

In the case of a site using Search API, the Facets module works particularly well in parallel with more powerful search engine backends like Apache Solr and Elasticsearch. Facets within a search app can take all shapes and sizes, and the Facets module provides a few plugins types that, in concert with each other, can be leveraged to programmatically create any sort of facet you may need for your search app. Because the Facets module relies on the Entity API within Drupal 8, these plugins should appear relatively familiar to most Drupal 8 developers:

  • \Drupal\facets\Entity\Facet
    • Describes the facet entity itself, whose data is received via a widget plugin and parsed by processor plugins
  • \Drupal\facets\Entity\FacetSource
    • Describes the source of the data being fed into the facet
  • \Drupal\facets\QueryType\QueryTypePluginBase
    • Describes the type of query being made against the search backend.
  • \Drupal\facets\Widget\WidgetPluginBase
    • Describes the widget that the user interacts with to control the search UI.
  • \Drupal\facets\Processor\ProcessorPluginBase
    • Describes the processor that translates the user input from the widget into data that can be used within the query.

The Facets module (along with its submodule Facets Range Widget) provides 4 basic query types:

  • \Drupal\facets\Plugin\facets\query_type\SearchApiString
    • The most comment facet query type, based on searching for simple strings.
  • \Drupal\facets\Plugin\facets\query_type\SearchApiGranular
    • Used for numbers-based facets that provide a spectrum of values between a set step size.
  • \Drupal\facets\Plugin\facets\query_type\SearchApiRange
    • Used for queries that allow users to select a range of possible numerical values.
  • \Drupal\facets\Plugin\facets\query_type\SearchApiDate
    • Used for queries to allow users to choose (ranges of) date values.

NOTE: These query types are to be used within the context of a Search API backend, rather than the Drupal core Search module.

So how do we do it?

I’d like to offer a brief example of how you might go about writing your own custom query types for a faceted search app using the Search API and Facets modules.

In our recent scenario, we needed a way to allow users to query against our search backend using numerical values, but in the format of comparing their chosen number value against searchable values using a specific comparison operator. In this case, our users were students who needed to be able to search for specific academic or volunteer programs. They also needed to be able to filter results based on a length of time (in weeks) that would be greater than or less than a specified value.or example, users would need a facet that allowed them to filter results by: any length of time, 1+ weeks, 2+ weeks, 3+ weeks, etc.

With this requirement in mind, the 4 basic query types listed above were not quite up to the task. Instead, we needed to write a custom "Integer Comparison" query type that would take in two key pieces of data. A number to compare values against and a comparison operator with which to make those comparisons. From our example use case above, we only needed the number from the user, because we would be setting the comparison operator (“>=“ AKA “greater than or equal to”) in configuration. However, we wanted to write a generic enough query type that could allow for any basic comparison operator in the future. This is the result:

In the code above, the two key pieces of data (the user-input number and the configuration-defined comparison operator) are $value['int’] and $value['op’]. However, in order to get these two simple values, we also needed to write a custom processor that could receive the raw input in from our facet widget and process that input into those two simple $value['int’] and $value['op'] values.

To understand what’s happening in the preQuery method above, you just need to know that the slider widget we implemented on the frontend had its possible data values encoded in a format like this:

Finally, in the code above, you’ll notice the one method getQueryType(), which is needed to specify which query type the processor should pass its data along to (in this case, our custom integer_comparison query type). In order to make our new query type plugin and processor plugin aware of each other, we need to implement one last hook in our module:

Contributed Customization

We're always looking for ways to customize integrations to fit the specific needs of project goals and we understand that out of the box solutions aren't always going to work. For example, the Facets module itself provides a submodule called Facets Range Widget that allows users to search using a range of numbers or dates. However, the default behavior of this facet assumed the use of a bounded range, as opposed to what we needed, which was an infinite range starting from a definite value. In that case, it was simpler for us to quickly create the exact facet query type that we needed, rather than wrestling with the defaults provided by the Facets module. We were only able to do that thanks to the Facets module’s highly extensible plugin system that leverages the contributed Search API and core Entity API of the Drupal ecosystem. That is why, even when we have a need for custom code, it is always a helpful first step to start from the strong contributed code provided by the Drupal community.

May 17 2019
May 17

This past week I had the pleasure of attending Drupaldelphia, a great event that is part of Philadelphia Tech Week. This helped introduce the Drupal community to a broader audience from the Philadelphia area. It was nice to see new attendees curious to learn about Drupal and what we’re doing. It was a pleasure to be able to meet, and greet, many of these individuals throughout the event.

Some beloved community members like Tim Plunkett, Chris Urban, and Anson Han call Philadelphia home. All participants got first hand exposure to our community in Philadelphia, which I consider to be vibrant and growing. It was great for those of us local to Philadelphia, and those we welcomed that came from afar.

Community Discussion

There was something for everyone and it’s always refreshing to see how much cool stuff is happening within the community. Here are a few of the talks I enjoyed this year:

If you were not able to attend, never fear. Kevin Thull recorded all talks, which are now up on drupal.tv


Hook 42 at Drupaldelphia

Thanks to Hook 42 for sponsoring an event near and dear to me. I live in Pennsylvania and consider this event one of my local camps. It’s not a large event, but it is made up for in the connections forged and overall quality of the event. I’m glad to have been able to speak twice this year.

For my first talk, I spoke about SimplyTest.me. I shared historically where the system has been, what challenges we face today, and where we’re heading. The system represents a labor of love on my part and I’m grateful to be able to spend some of my community time at Hook 42 helping maintain it. The system has a vibrant future and we’re doing some really great things with TugboatQA, one-click demos, Drupal 8, and an Open Collective that should help pave the way for a future inclusion program. 

The second talk was titled, “Impact Through Contribution: A Community for All.” During this talk, I present a path to contribution as “A Hero’s Journey”. This is a known storytelling technique written by Joseph Campbell where characters follow a conventional arc to achieve deeply impactful transformation. I shared stories of those who have had a huge impact and talked about some of the creative efforts happening in the community. I offered some thoughts on areas of growth and improvement for our community. It’s my belief that everyone can have an impact and bring new, creative ways to contribute that make our community stronger. We need to do everything we can to help make that happen.

Final Reflections

It’s such a great time to be with people, talk about cool things we’ve been doing, and help our community progress together. As an example, attendees were able to come together and discuss some outstanding issues on Layout Builder where consensus was formed on some next steps. Taking this conversation purely outside of the issue queue allowed people to learn and help move forward one of the most innovative new tools offered by Drupal.

I had a lot of fun in the city of Philadelphia as well. I can get good cheesesteaks in Central PA, so I needed to think bigger for my time there. I went to not one, but two, different Belgian restaurants where I enjoyed mussels and fries. For breakfast, I enjoyed excellent coffee and an almond croissant that was acquired from Bluestone Lane.

Another great Drupaldelphia came and went. The sessions were great and it was spectacular to connect with those that attended. It had a friendly, lighthearted, low-key feeling that allowed everyone to get something meaningful from the event. I thank the organizers, sponsors, and attendees who made it possible. I’m already looking forward to attending this jawn next year.

May 08 2019
May 08

In case you missed it, Stanford Drupal Camp changed their name to Stanford Web Camp. This transformation marks an important step in the Stanford journey from the camp's inception 10 years ago. We’re happy to be part of the evolution of the Stanford community as they expand into a more inclusive web atmosphere.

Experience Stanford

At Stanford Web Camp, attendees and presenters will discuss a variety of topics about the web from development to accessibility, and everything in between. All of these discussions will take place on the Stanford campus, in sunny California. We're officially inviting you to come explore “The Farm” with Hook 42 and learn other fun Stanford lingo while you’re on site!

As part of the camp, Hook 42’s Aimee Degnan will be giving two talks – one focusing on accessibility and the other on SiteBuilding. So, if you missed Aimee’s talk on a11y tools at DrupalCon 2019 - you can see it live, in-person at Stanford Web Camp! 

Discover Accessibility Tools

Join us to listen to Aimee’s talk, “Which Accessibility Tools are Right For You?“ What you can expect to gain is a broad overview of all the tools that are available in the accessibility testing spectrum. We hope you’ll leave with a better understanding of what the tools are, and how they can be utilized. There are a lot of options out there, and just knowing where to start can be a difficult path.

Aimee will explore the following:

  • Which tools are right for you?
  • Will only one tool fit all of your needs? ;)
  • Build vs. buy some vs. buy vs. free? Is "free" really free?

Level Up Your Layouts

Aimee's second discussion will explore View Modes and Layout Builder. Level up your layout! Component Based SiteBuilding with Layout Builder & View Modes is for those who are familiar with Drupal and are interested in harmonizing tools to streamline component building in the platform.

With Layout Builder in Core, it is essential to build a View Mode and Layout Builder strategy. You can harness the power of View Modes to move beyond Teaser and Paragraphs for display flexibility. Come out and learn how you can build a more streamlined process utilizing the benefits of View Mode and Layout Builder.

The talk will be structured as follows:

  • View Modes in Core
  • Architecting View Modes for your site
  • Lessons Learned with View Modes
  • View Modes and Layout Builder

Join Hook 42 at Camp

Stanford Web Camp is completely free and open to the public, we encourage all of you to explore other sessions and join a community of motivated professionals as we talk about the latest trends and developments in our industry. Come out and say hello to Hook 42, we’re eager to meet new people, connect with old friends, and discuss all things tech.

See you soon! 


May 03 2019
May 03

It’s been almost a month since DrupalCon 2019. We can’t believe how time flies! While we were there, we had a variety of things going on at many different levels. Just as fast as the time since DrupalCon has flown past us, our time in Seattle felt like a tiny blip. 

From organizing summits, lunches, BoFs and presentations, our team was just as busy behind the scenes of DrupalCon this year, as we were being attendees. There were so many ways for us to really dive into the DrupalCon experience and we’re already looking forward to the next one! In the meantime, we put together a recap of our time in Seattle.

Presenting & Involvement

The most notable thing about our team, is how involved we are in our community, and DrupalCon 2019 was no exception. From 7 talks, a lunch sponsorship, a summit training and BoF organizations, Hook 42 had many members participating in DrupalCon. We are thankful for the opportunities provided to us to be able to participate in many areas. We know we had an unforgettable experience this year, and we hope we were able to help all of you achieve that same feeling.

DrupalCon is its own unique experience every year. My heavy involvement in community efforts this year was truly eventful. Pun fully intended! I’m glad to have had the opportunity to work closely with those outside my day-to-day operations at Hook 42 to bring together expertise that normally isn’t co-packaged together. 

~ Aimee

In case you were unable to catch us in the act, here is a list of all the ways our team was working at DrupalCon.

Aerial view of Adam Bergstein and other coffee BoF attendeesPhoto Credit: Chris Urban

Being Prepared for the Unpredictable

A Full Team Website Takeover

Our team set out on a mission to band together and tackle some internal items while all together. When the decision was made to extend the level of effort into those items, nobody batted an eyelash! It was an incredible tribute to the stamina, talents and dedication of our team members have to completing tasks. We did a full hotel lobby takeover for the majority of the trip, in between sessions of course, to spend time taking the Hook 42 website from a D7 website to a D8 website. It’s a very rare occasion, when all of us are in one place, focusing on one item, and working hard to ensure a successful migration into the new system. All of those involved still can’t stop talking about it! 

Our little secret, an easter-egg if you will, to those who are so dedicated to continue reading. A redesign of the Hook 42 website is in the works. Unfortunately you’re going to have to wait a little bit for that one! We’re just glad we finally upgraded to D8!

Hook 42 team takes over hotel lobby to work on new D8 website

Presenting On The Fly

Secondly, Kristen Pol was invited to co-present on a talk with Lingotek. Talk about being prepared for anything! Being a support-member in the audience quickly turned into providing insights to a room full of eager listeners. With additional help from Aimee Degnan, our team was able to put together additional assets to provide the Lingotek team for the collaborative presentation. A huge shout-out to those involved for coming together for last-minute changes and helping solidify a great talk.

Lingotek’s session, Avoiding Trouble Spots When Creating a Multilingual Site, explored the challenges multilingual websites create, and Kristen took the charge head-on to be a co-presenter on the subject. It was a great experience for everyone. 

A Chance To Have Fun

Whether it’s with new friends, old friends, or colleagues - every year DrupalCon allows us to forge connections that stay with us for a long time. The team took a day to explore Seattle together. We had a full team lunch, took an underground tour of the city, and took advantage of a rather sunny day in Seattle to walk around and take in the beautiful city.

Hook 42 team on Seattle underground tour

Meeting Our Newest Team Members

We also had quite a few new faces on our own team this year. DrupalCon allowed us a place to all come together and meet in person. Lindsey, Emanuel and Michael were all able to join our team on a cross-country trip to Seattle. Yes, all of them are spread across the East Coast! 

I always love to meet with the Hook 42 team in person since they are just a great group of people. We were also lucky to have a few new team members since our last in-person gathering.

~ Kristen

Other Connection Opportunities

Outside of the team, we were also able to say hello to a lot of familiar faces that we usually only get to see once a year at DrupalCon. Whether it was in a session, during lunch, at dinner or ending the day over a few drinks, we are thankful to be able to have seen so many of our Drupal community members and re-connect. Our team was able to use DrupalCon as a way to take time away from the computer and get some quality face-to-face time with others in the community.

DrupalCons are as much about the community as they are about learning new Drupal things. While sessions where you can learn a lot of new things about Drupal are the focus, one of the best parts is bumping into old friends or sitting down next to someone new and chatting about a common interest in Drupal and web development.

~ Danita

A Place To Learn

Our team is never disappointed when we leave DrupalCon. We’re always coming away with new ideas, new thoughts, and new procedures for how we do our jobs. It’s the most important takeaway from all of this - is that DrupalCon is always providing content that is spread across a variety of skillsets and interests. This year’s focus on inclusivity made our designer especially happy - you can read all about her first ever DrupalCon experience here.

Although the new schedule reduced the total number of days of sessions at the conference, I felt like as usual DrupalCon provided an awesome environment for everyone to come together and share their experience and expertise.

~ Ryan

Some Favorite Sessions:

Presentation Title Screen, PEGA Build for Change

Migration Workflow Diagram Preview

Glitter rainbow Drupal 8 unicorn

Elevated Third presentation title screen

Drake YOLO

diagram depicting design feedback and front end pairing with backend to build the website

meme - wrote PHP unit test, only took 4.5 hours, yes!

Team Benefits

DrupalCon is imperative to the health of our team in many ways. For starters, it's one of the only times our full team is in one place at one time, and that alone is enough of a reason to enjoy all DrupalCon has to offer. Our team also uses the event to provide thought leadership to the community. We take the time to also learn from other experts in the field on unfamiliar topics or expanding expertise in a certain area. Giving back to the community in more ways than one as a culmination of the event is really what ties it all together. 

It's such a heart warming experience, like seeing 500 of your closest friends once a year. It's a celebration of wins, sharing of knowledge, and a real feeling of connection. This year had such a pleasant vibe and was a nice reflection of our community, which goes well beyond tech.

~ Adam

Thank you to DrupalCon, and thank you to Seattle, for having such an amazing line-up of things to do for all of us that attended!

May 02 2019
May 02

Hook 42 is heading to Philadelphia for Drupaldelphia. Phew, that’s a mouthful to say! Not only are we proud to be sponsoring such a wonderful event, we’re excited to announce that Adam Bergstein will be giving two talks this year.

Dropping the Knowledge

To say we're excited about Adam's talks would be an understatement. To have a chance to share insights and experiences with other eager-to-learn individuals is something Adam enjoys, and he's looking forward to doing it again at Drupaldelphia.

Better Together: Impact Through Contribution

Adam will discuss his journey through the Drupal-verse, and explore ways to make a big community feel easier to navigate. With so many moving pieces, and people involved, it can be overwhelming at times to know what to do and where to find help. The moral of the story? When we all come together and pitch in, we can accomplish big things! Join Adam for an insightful journey through the community, and explorations of togetherness that make Drupal great.

SimplyTest.me - A Community Case Study

SimplyTest.me is a long-standing, free service that has the served Drupal community with an easy-to-use tool for creating Drupal sandboxes. During this case study, we’ll share the motivations behind SimplyTest.me and how the tool aims to lower the barrier of entry for those participating in the community. We’ll walk through the various use cases and features of the tool and examine how that helps anyone participate in our community. 

We hope you’ll come say hello if you stop in on one of Adam's sessions! If you're not interested in Adam's talks, don't fret! There are plenty of other interesting things happening at Drupaldelphia this year. Take a look at their website to browse other sessions, we're positive there is something for everyone. 


Understanding the importance Drupaldelphia has on the community, we felt it necessary to spread the love and give back to our Drupal family. We enjoy helping our community in many ways, and sponsorship is just another way to contribute to a community that helps so many people develop valuable skills and long-lasting relationships.

The development of our community important to us. Providing support that paves a way for those to come together and learn from each other is a core value of Hook 42 and it applies to more than just our team. Thats why we try to be part of its growth just as much from the outside as we do from the inside. 


Beyond the sponsorship and presentations, we’re happy to be back in the city of brotherly love. Those attending are looking forward to exploring the town and seeing some familiar faces. We hope you'll join Hook 42 in Philly for some good food, good culture and community contribution.

The real question though – when you get to Philly will you be going to Pat’s or Geno’s? Choose wisely!


Apr 17 2019
Apr 17

DrupalCon 2019 was a bit different for me. I have attended previous DrupalCons, usually sitting in the back of the room just taking in all that I could from experts around the world. This year, however, I had the opportunity to be a speaker. Not only was I afforded the opportunity to speak, but I had two separate sessions accepted.

Talking the Talk

Being my first DrupalCon as a speaker, I might have had a few butterflies in my stomach when I arrived. Those quickly faded, and overall, my sessions on Stanford Cantor Arts Center Redesign and A Survey of Emerging Technology were very well received. I had an absolute blast presenting! Special shout-out to my partners in crime, Kristen Pol and Adam Bergstein, for making the transition from attendee to speaker fairly painless.

Stanford Cantor Arts Center Redesign

This talk was a broad review of our work with Stanford Cantor Arts Center that takes a deeper look at a few problems we faced during the build. There were complexities within the content structure and architecture that we needed to be able to accommodate. Flexibility was the most important part of this website. We walked through the solution to leverage UI Patterns module that allowed component based design, making the build process more practical while allowing content editors the ability to adjust as they see fit on certain areas of the site. 

Listen to the full talk on YouTube.

A Survey of Emerging Technology

Together, Adam Bergstein and I highlighted a set of tools that we know integrate well with Drupal and are used to tackle common roadblocks within the environment. I specifically spoke to the value of GraphQL and Gatsby.JS.

GraphQL provides a common interface for API queries. It is specifically notable for the ability to get information in a sole request, versus JSON requests that require multiple attempts before getting all the data. As far as its ability to play nice with Drupal, there is currrently a GraphQL module that is updated and supported by our community. The biggest benefit of using it within Drupal is for standardizing those onboarding into Drupal. Where they may hit roadblocks coming from the outside in, GraphQL makes the Drupal transition easier.

Gatsby.JS is a static site generator that uses static markup, but can still display dynamic information. What is great is you can bring your own backend into Gatsby.JS. Benefit, getting rid of a lot of vulnerabilities by not having any server-side code running. The vulnerability of a CMS is no longer a worry.

Other technologies covered were Hubspot, ElasticSearch, Pattern Lab, and Cypress.io.

You can watch the full video on YouTube.

More Than Presenting

Group of Hook 42 Team Members Working in Sprint Room

Beyond speaking, I had a fantastic time hanging out with the team, as usual. Every time we’re in the same location together I’m reminded of how talented, intelligent, and funny everyone is. It was especially awesome to get a chance to greet our three newest members of the team (Michael, Emanuel, and Lindsey) in person.

We spent a sizable chunk of pre-conference time sprinting on our company website, which was an amazing team-building exercise and really showed how much we can accomplish when we work together. So hopefully you’re reading this on the flashy, fancy new-and-improved hook42.com!

Overall, DrupalCon never ceases to provide an endless amount of opportunity. From spending time with colleagues, to working hard on new efforts, and even having new experiences like being a first-time speaker, I always look forward to what DrupalCon has to offer.

When I began my career at Hook 42, I made it a goal of mine to one day speak at DrupalCon. A long-term goal, but one that I worked very tirelessly to achieve. Getting the opportunity to share my expertise with others on the stage in Seattle felt like the perfect culmination of two years of hard work to get there. It felt amazing to check off my list.

Mar 12 2019
Mar 12

Every year community members from across the globe meet in Orlando for Florida Drupal Camp. This year Adam, Ryan, and Jonathan from Hook 42 attended. It was a fantastic time to connect with people, to learn, and enjoy some warmer weather. Plus, alligators!

Ryan and Adam led a training on connecting Drupal 8 and Gatsby.JS. The training utilized a set of Docker images that help people build everything from end-to-end on their own system. Attendees used the Umami demo, installed JSON API, and configured Gatsby.JS to pull recipes from Drupal. It was well attended and there was a lot of collaboration in the room. Our team appreciated all of those that attended - especially as we worked through technical and wifi issues. 

Ryan and Adam also gave a talk on emerging technology related to Drupal. Some of the topics included Cypress.io, Hubspot, ElasticSearch, GraphQL, Gatsby.JS, and Pattern Lab. It’s important for community members to find and use the right tool for the right job. As Drupal community members, we must be mindful of how these complementary technologies can serve us. You can watch the recording of the session on Drupal TV.

Team Member Reflections


I look forward to this camp each year, and once again this year did not disappoint. Thank you to “the Mikes”, Kyle, and Jordana for volunteering again. The time spent with the community was uplifting and encouraging - even if it was a bit tiring giving both a training and a session. The time spent with my colleagues Jonathan and Ryan, having barbeque, and drinking craft beer with the community all brought a lot of energy. I was able to reconnect with many friends and I always treasure those opportunities. Also, Jonathan and I unintentionally packed the same hoodies and Drupal Camp Asheville shirts. Twinsies!

The session quality was outstanding! Most notably, there were some incredibly great non-technical, people-focused sessions provided by Jordana Fung and Qymana Botts. I strongly recommend seeing both. Thanks, as always, to the amazing Kevin Thull, all sessions are recorded and posted to Drupal TV.
At the end of camp, on the contribution day, I was able to work on the proof-of-concept integrating SimplyTest.me and Tugboat QA. The result of which is a new Tugboat QA contributed module based on a Backdrop CMS module port.


This wasn’t just my first time to Florida Camp, it was my first time in the state of Florida in general! What a great experience. I had a great time at the camp and really enjoyed speaking with a wide array of folks about decoupled Drupal and Gatsby.js, both through the training Adam and I conducted as well as hallway conversations. Brian Perry’s talk comparing various static site generators and their compatibility with Drupal proved really insightful. I was really excited about his demo of the Tome static site generator, which runs within Drupal itself.

Thanks a ton to the organizers - the camp was a lot of fun and I look forward to attending again next year!


My second time at Florida Drupal Camp was as good as, if not better, than my first. As a Drupal Camp organizer myself, I find Florida Drupal Camp to be inspiring. They manage to pull off being extremely well organized while maintaining a very casual air to the whole weekend. 

As an attendee, I had a unique (for me) experience this year. I went to Drupal Camp Florida without a computer and it was great! Without a laptop always in front of me I found myself more attentive to the session and more engaged in the camp in general. I enjoyed it so much that I will likely avoid taking my computer to future camps.

The sessions I attended were all wonderful and there are a few I’m still thinking about today. Here is a quick list, and my takeaways:

  • How to keep Drupal relevant in the Git-based and API-driven CMS era
    The Drupal island appears to be shrinking as the overall landscape for approaches to web development grows. It doesn’t hurt keeping an eye on the new ways to solve old problems.
  • How to Hire and Fire Your Employer
    Always a fan of these “being human” talks. In this one, April encouraged me to continuously evaluate my values as a person and how they match any given employer. “Life is too short to be miserable” is a powerful perspective to maintain.
  • An Introduction to Gulp
    I’ve been using Gulp and similar technologies for a number of years, but have almost always used someone else’s configuration. Tim makes it look easy to get started writing my own tasks, and I’m really looking forward to doing so on my next project.
  • The problem with Paragraphs, a return to rich fields!
    Maybe the only actual Drupal session I attended, it’s always great to see Hawkeye and get his perspective. In this session he opened my eyes to some serious problems with the Drupal community’s go to approach to solving complicated fields, the paragraphs module. By the end of the session, I was ready to start making custom rich/composite/compound fields for future projects.

Another top-notch Drupal Camp Florida in the bag. I’ll definitely be back next year, and if you’ve never been I highly recommend it.

Mar 08 2019
Mar 08

Look out for Hook 42 at DrupalCon 2019 in Seattle!

It’s that time again, another DrupalCon is fast approaching and our team couldn’t be more excited for this year’s Seattle event. We’ve got a lot in store for you this year, from presentations, BOFs, sponsorships, partnership collaborations, and using our listening ears. You’ll find our team distributed all about.

We’re bringing a stacked line-up of knowledge and experiences to drop on 'ya this year. Not only that, we’re looking forward to hearing all the ups and downs you’ve had this past year, and how we’re all growing together within the Drupal community. 

Let’s get to sharing!


Join us at the Performance and Scalability Summit on Monday. Hook 42 and Tandem have worked with the Drupal Association to line up leading speakers to cover scaling performant Drupal websites to scaling efficient Drupal development teams. The Performance and Scalability Summit is the place for developers, DevOps professionals, decision makers, and other technical stakeholders to plan for growth.


To hear from our experts, find us at one of our talks where we’ll review insights our team has experienced first-hand and how we’re adapting to the new and old needs of evolving technology.

Database Query Optimization in Drupal

Kristen talks all things database, and walks through how to put the sluggish operations behind you to optimize your Drupal environment. Covering the basic optimization steps isn’t always enough, exploring options past the basics will help streamline your Drupal environment for both front-end and back-end users.

Accessibility Deep Dive Workshop

Aimee is teaming up with Caroline Boyden, from UC Berkeley, to take a closer look at accessibility. Together, they’ll use real-world examples of how accessibility is best implemented, and how every member of your team can be part of accessibility, from designers to developers to content authors and everything in between.

Which Accessibility Tools are Right for You?

Aimee breaks down the best tools for implementing and testing accessibility, and the benefits and areas of improvement for these tools. Taking a look at what is available today, and how your team can take advantage of these tools to increase your website’s accessibility.

Drupal 8 Case Study – Stanford Cantor Arts Center Redesign

Kristen and Ryan join forces to walk through one of Hook 42’s latest client projects. Focusing on the implementation of good design and development, and how Drupal was the perfect place to house the dynamic technical needs of the team at Stanford.

A Survey of Emerging Technologies That Complement Drupal

Adam and Ryan are teaming together to talk about the latest tech to take advantage of Drupal’s flexibility and ability to interact well with modern advancements on the web.

Considerations of Federated Search and Drupal

Adam shines the light into federated search, its importance, and how you can implement this applications within Drupal. Taking a close look at how to pair the application with Drupal to minimize risk and increase cross-platform communications.


Women in Drupal Luncheon

We’re proud to sponsor the Women in Drupal Luncheon, fostering inclusivity and empowerment within the Drupal community. We’ll gather to enjoy delicious food, talk shop, and relax amongst professionals.



VP of Engineering, Adam Bergstein maintains the SimplyTest.me service leverage by the Drupal community for testing and prototyping community contributions. Join him for a BOF on Wednesday! We want to chat with you all things about our go-to browser testing tool for all our Drupal projects.

Adam is also sorting out the Drupal Coffee Exchange meetup. 


Lingotek Session: Avoiding Trouble Spots When Creating a Multilingual Site

Our partner, Lingotek, has organized a session revolving around the challenges with multilingual websites. Through the session you’ll learn about common challenges with multilingual websites, and how you can get ahead of those issues. We’ll be there to support Lingotek and help answer questions during the session.

We Hope To See You There

If you haven’t already registered for DrupalCon Seattle, get on it! We’re ready for yet another amazing DrupalCon adventure, and we’re looking forward to seeing old and new faces in the crowd.



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