<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kevin Reynen</title>
    <description>The latest articles on DEV Community by Kevin Reynen (@kreynen).</description>
    <link>https://dev.to/kreynen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F469095%2F6e925f11-6ce6-4fc6-a638-ef918621db6b.jpg</url>
      <title>DEV Community: Kevin Reynen</title>
      <link>https://dev.to/kreynen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kreynen"/>
    <language>en</language>
    <item>
      <title>Managing Drupal Like Salesforce</title>
      <dc:creator>Kevin Reynen</dc:creator>
      <pubDate>Thu, 08 May 2025 19:31:54 +0000</pubDate>
      <link>https://dev.to/kreynen/managing-drupal-like-salesforce-54ia</link>
      <guid>https://dev.to/kreynen/managing-drupal-like-salesforce-54ia</guid>
      <description>&lt;p&gt;These are the links and resources from my presentation at &lt;a href="https://webcamp.stanford.edu/session/managing-drupal-like-salesforce" rel="noopener noreferrer"&gt;https://webcamp.stanford.edu/session/managing-drupal-like-salesforce&lt;/a&gt;. The &lt;a href="https://www.youtube.com/watch?v=MDOMyV6IqlE&amp;amp;t=3s" rel="noopener noreferrer"&gt;recording is available on YouTube&lt;/a&gt;, but it captured presenter mode instead of the presentation.&lt;/p&gt;

&lt;p&gt;The difference in the amount our dev team has been able to contribute before vs. after completing the customized &lt;br&gt;
version of the training Mike Anello did for the University of Denver.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o4jiuqvxvuej98gojpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3o4jiuqvxvuej98gojpd.png" alt="Image description" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://mediaspace.du.edu/media/D10%20Contribution%20Animation/1_x8yhqfz4" rel="noopener noreferrer"&gt;https://mediaspace.du.edu/media/D10%20Contribution%20Animation/1_x8yhqfz4&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The module we are using that provides a UI within Drupal export config YML changes as a PR is appropriately named &lt;a href="https://www.drupal.org/project/config_pr" rel="noopener noreferrer"&gt;Config PR&lt;/a&gt;. I included screenshots of the steps required to enable GitHub's new Fine Grained Access Token in &lt;a href="https://www.drupal.org/project/config_pr/issues/3509254" rel="noopener noreferrer"&gt;https://www.drupal.org/project/config_pr/issues/3509254&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the presentation, I asked users to use Pantheon's new roadmap site to indicate that &lt;a href="https://roadmap.pantheon.io/c/115-github-gitlab-and-bitbucket-integration" rel="noopener noreferrer"&gt;GitHub, GitLab, and Bitbucket integration&lt;/a&gt; is a feature they would use. A few days after my presentation, Pantheon announced that &lt;a href="https://www.thedroptimes.com/48831/pantheon-spring-2025-update-introduces-github-integration-drupal-module-enhancements-and-trust" rel="noopener noreferrer"&gt;Native GitHub Integrations were available for public beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One "trick" I didn't highlight enough is the use of a &lt;a href="https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21entity.api.php/function/hook_entity_presave/11.x" rel="noopener noreferrer"&gt;hook_ENTITY_TYPE_presave&lt;/a&gt; to adjust role access based on the environment the user is authenticating on. This is much easier to do in an enterprise environment where we are leveraging a module like &lt;a href="https://www.drupal.org/project/simplesamlphp_auth" rel="noopener noreferrer"&gt;simpleSAMLphp_auth&lt;/a&gt; or &lt;a href="https://www.drupal.org/project/samlauth" rel="noopener noreferrer"&gt;samlauth&lt;/a&gt; is often configured to update values passed with the SAML post like first name, last name, email, etc. &lt;/p&gt;

&lt;p&gt;By checking $_ENV['PANTHEON_ENVIRONMENT'] before determining which role to assign the user to, we can grant site builders full admin access on the dev, test and multidev environments. A simple example of this would be something like this function in your install profile.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function ducore_user_presave(UserInterface $user) {
  $site_builders =  array('first1.last1','first2.last3','first3.last3');
  // Check to see if this user is on the list of campus or system support users
  if (in_array(strtolower($user-&amp;gt;getAccountName()), $site_builders)) {
    //check to see if the Pantheon environment is live
    if (isset($_ENV['PANTHEON_ENVIRONMENT']) &amp;amp;&amp;amp; php_sapi_name() != 'cli') {
      if ($_ENV['PANTHEON_ENVIRONMENT'] != 'live') {
        $user-&amp;gt;addRole('administrator');
      } else {
        $user-&amp;gt;addRole('site_admin');
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A more &lt;a href="https://github.com/University-of-Denver/drupal-composer-managed/blob/master/web/profiles/custom/ducore/ducore.profile#L21" rel="noopener noreferrer"&gt;complicated example&lt;/a&gt; that handles developers, site builders and role limited to adding and removing users from sites is available for reference in the University of Denver's GitHub Repo.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>webdev</category>
      <category>softwaredevelopment</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Features Salesforce and Drupal have in Common - Project Browsing (Part 1)</title>
      <dc:creator>Kevin Reynen</dc:creator>
      <pubDate>Wed, 22 Feb 2023 15:02:24 +0000</pubDate>
      <link>https://dev.to/kreynen/features-salesforce-and-drupal-have-in-common-project-browsing-part-1-163j</link>
      <guid>https://dev.to/kreynen/features-salesforce-and-drupal-have-in-common-project-browsing-part-1-163j</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;A few months ago, Aaron Crosman posted &lt;a href="https://spinningcode.org/2022/09/what-i-brought-from-drupal-to-salesforce/"&gt;What I Brought from Drupal to Salesforce&lt;/a&gt;. While I've done a lot of CMS/CRM integration work, I've only been integrating Drupal with Salesforce and its related services for a few years. I still consider myself new to Salesforce development and I'm still learning about the &lt;a href="https://github.com/SFDO-Community-Sprints"&gt;open source side of Salesforce&lt;/a&gt; at events like &lt;a href="https://sfdo-community-sprints.github.io/docs/sprints/"&gt;Salesforce Community Sprints&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If I do get something wrong, please let me know and I'll update the posts.&lt;/p&gt;

&lt;p&gt;Another reason for writing a series highlighting some of the similarities between Salesforce and Drupal is to respond to a recent post by Jacob Rockowitz questioning &lt;a href="https://www.jrockowitz.com/blog/schemadotorg-future"&gt;whether his Blueprint project that leverages Schema.org had a future&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I briefly mentioned Blueprints in a &lt;a href="https://www.youtube.com/watch?v=o1xmVu-3qJs"&gt;presentation at BADCamp&lt;/a&gt;, but I wanted to dive in deeper into Blueprint as well as some of the other features starting to mature in "modern Drupal" where I've seen similar approaches working well in Salesforce. &lt;/p&gt;

&lt;p&gt;To keep myself sane, I'm breaking this up into 3 parts;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project Browsing - Project Browser and AppExchange &lt;/li&gt;
&lt;li&gt;Schema Management - Blueprint and Educational Data Architecture&lt;/li&gt;
&lt;li&gt;Advanced Configuration Management - Config Patch GitLab API and GearSet &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Browser and AppExchange
&lt;/h2&gt;

&lt;p&gt;The UI in the work coming out of the Drupal Association's Project Browser Initiative is very similar to Salesforce's AppExchange (and &lt;a href="https://install.salesforce.org/"&gt;MetaDeploy&lt;/a&gt;, AppExchange for open source and Commons supported Salesforce packages).&lt;/p&gt;

&lt;p&gt;Visually, the UX of the Project Browser and AppExchange are very similar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P7Q0-Thk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzf6zksqeevi2dzuawg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P7Q0-Thk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uzf6zksqeevi2dzuawg5.png" alt="Image description" width="880" height="629"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M1hhFSvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi6tgeec8as1nops8m89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M1hhFSvx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi6tgeec8as1nops8m89.png" alt="Image description" width="880" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Out of the box, Project Browser isn't really that exciting for developers. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So I can search for modules inside the application I'm building and then go to Composer to &lt;code&gt;composer require drupal/[PROJECT NAME]&lt;/code&gt;? Why would anyone get excited about this?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The exciting part of Project Browser isn't using it to browse the same projects on Drupal.org in a different UX, it's being able to customize that experience for a specific use case or infrastructure. A feature that gives users a list of projects they can install directly on a test/sandbox version of their site is a game changer in a higher ed use case.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I know?
&lt;/h2&gt;

&lt;p&gt;On the CMS side, we wrote something similar to Project Browser the University of Colorado in Drupal 7 we called &lt;a href="https://www.drupal.org/project/profile_module_manager"&gt;Profile Module Manager&lt;/a&gt;. While the colorado.edu sites are now run from a &lt;a href="https://www.atlassian.com/git/tutorials/monorepos"&gt;monorepo&lt;/a&gt;/&lt;a href="https://docs.pantheon.io/guides/custom-upstream"&gt;custom upstream&lt;/a&gt; approach on Pantheon, the original on-prem infrastructure paired Profile Module Manager with a custom devops solution to add a "bundle" of code to a site's codebase. The user experience of Profile Module Manager within Web Express in D7 and Project Browser with a customized project feed in D10 will be very similar.&lt;/p&gt;

&lt;p&gt;Project Browser won't really be exciting until it can be combined with the Auto Update Initiative work. That work requires Composer 2.3.5 or later which many hosts (including Pantheon) do not support yet. &lt;/p&gt;

&lt;p&gt;On the CRM side, when browsing packages and clicking &lt;strong&gt;Get It Now&lt;/strong&gt; of free packages will bring up a prompt asking you where to install the package based on instances you have registered with the account you are authenticated with... or to spin up a new sandbox to test just this package.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wLkATRap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vn9n6nlnnj7g8fz451c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wLkATRap--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0vn9n6nlnnj7g8fz451c.png" alt="Image description" width="880" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While Drupal's Project Browser UX is designed to be used with the CMS instance you are planning to install the package on, it's not hard to imagine large, Drupal centric hosts like Acquia or Pantheon offering customized Project Browser feeds that list platform friendly/approved modules. &lt;/p&gt;

&lt;p&gt;Modern Drupal still has to define a way to install front end dependencies required by PHP projects. Salesforce solves this to a certain extent with &lt;a href="https://lwc.dev/"&gt;Lightning Web Components, their open source Web Component foundation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;While there is some traction around &lt;a href="https://www.drupal.org/project/drupal/issues/2873160"&gt;#2873160&lt;/a&gt; to use &lt;a href="https://github.com/thecodingmachine/nodejs-installer"&gt;NodeJS installer for Composer&lt;/a&gt; and &lt;a href="https://www.drupal.org/project/drupal/issues/3340712"&gt;#3340712&lt;/a&gt; to get single directory components into Core, this is still going to be a challenge.&lt;/p&gt;

&lt;p&gt;It is also important to acknowledge that most packages you can install through the different Salesforce project browsing services are NOT free or open source. Between the AppExchange and MetaInstall services, you'll find 4 different types of packages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://install.salesforce.org/products#open-source-commons"&gt;Free, Open and Transparently Maintained on GitHub&lt;/a&gt; - The Summit Events package maintained primarily by staff from the University of St. Thomas at &lt;a href="https://github.com/SFDO-Community/Summit-Events-App"&gt;https://github.com/SFDO-Community/Summit-Events-App&lt;/a&gt; is a good example code maintained openly with BSD license.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://install.salesforce.org/products#salesforce.org-products"&gt;Free, maintain by Salesforce&lt;/a&gt; - The Educational Data Architecture (EDA) is a good example of this. I'll write more about EDA in Part 2.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://appexchange.salesforce.com/appxSearchKeywordResults?keywords=salesforce&amp;amp;price=free"&gt;Free, Closed Source&lt;/a&gt; - You'll find a mix of free loss leader products, feature limited version with a paid upgrade, and free package that requires a service subscription, but the source of these packages cannot be modified.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://appexchange.salesforce.com/appxSearchKeywordResults?keywords=salesforce&amp;amp;price=paid"&gt;Paid, Closed Source&lt;/a&gt; - 75% of packages charge. Most use a per licensed user/per month model. Some offer free trials.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Paid plugins are more common in the WordPress ecosystem, but the underlying &lt;a href="https://wordpress.org/about/license/"&gt;plugin code is considered a derivative of WordPress where distribution triggers the GPL-2.0 or later licensing requirement&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Where I think this is going to get interesting is the potential for more commercial Drupal packages in SaaS offerings. We've already seen some large hosts charge for value added services for sites hosted on their infrastructure like Acquia Site Studio. We may see more groups exploit the &lt;a href="https://saivenn.co/2021/10/17/saas-and-gpl-v3-the-5-minute-guide/"&gt;GPL SaaS Loophole&lt;/a&gt; enabling customers to install commercial modules and themes from customized Project Browsers. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As long as the end-user is interacting with your software over a network and you control the hardware / infrastructure the software is running on, that is not considered distribution.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While different than traditional, pure GPL Drupal sites, after seeing the quality in competing packages in Salesforce, I personally think a tier of commercial, closed source modules would be good for Drupal.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>php</category>
      <category>salesforce</category>
    </item>
    <item>
      <title>Change My View: D8 isn't the best upgrade path for 1000 D7 EDU sites</title>
      <dc:creator>Kevin Reynen</dc:creator>
      <pubDate>Tue, 21 Jun 2022 17:59:13 +0000</pubDate>
      <link>https://dev.to/kreynen/change-my-view-d8-isnt-the-best-upgrade-path-for-1000-d7-edu-sites-1e87</link>
      <guid>https://dev.to/kreynen/change-my-view-d8-isnt-the-best-upgrade-path-for-1000-d7-edu-sites-1e87</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This was original posted at &lt;a href="https://www.colorado.edu/webcentral/2018/04/11/change-my-view-d8-isnt-best-upgrade-path-1000-d7-edu-sites"&gt;https://www.colorado.edu/webcentral/2018/04/11/change-my-view-d8-isnt-best-upgrade-path-1000-d7-edu-sites&lt;/a&gt; back in April of 2018 and referenced in  &lt;a href="https://www.reddit.com/r/drupal/comments/8b87ky/change_my_view_d8_isnt_the_best_upgrade_path_for/"&gt;https://www.reddit.com/r/drupal/comments/8b87ky/change_my_view_d8_isnt_the_best_upgrade_path_for/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because many of the issues I raised back then are being addressed in &lt;a href="https://www.drupal.org/project/ideas/issues/3274999"&gt;Drupal's Distribution Modernization Initiative&lt;/a&gt;, I wanted to be able to reference this post&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like many other Drupallers, I'm in Nashville this week. Unlike previous DrupalCons, I'm less excited about being here than previous year. While my team at the University of Colorado Boulder currently manages 1000 D7 sites, it looks increasingly less likely that we'll be upgrading to D8.&lt;br&gt;
Angela “Herder of Cats” Byron recently tweeted...&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--luBc1clE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/1422462603566010371/VykrdGlw_normal.jpg" alt="webchick profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        webchick
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/webchick"&gt;@webchick&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      OK, time for our semi-annual poll/group therapy session. ;)&lt;br&gt;&lt;br&gt;What are the 5 top things you or your clients run into problems with on &lt;a href="https://twitter.com/hashtag/Drupal"&gt;#Drupal&lt;/a&gt; 8?
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      20:36 PM - 09 Mar 2018
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=972209445097816064" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=972209445097816064" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=972209445097816064" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;
 

&lt;p&gt;The last time she tweeted this, we responded with a few specific issues we had at the time. After maintaining a handful of D8 sites in production for a few months and meeting with 20+ developers and designers from teams at all campuses in the University of Colorado system earlier this year, we now have a more comprehensive list to answer the question of why the University of Colorado Boulder isn't moving forward with updating the Express install profile to D8.&lt;/p&gt;

&lt;p&gt;We've already written and presented about some of these, but my goal at DrupalCon is to find people who will convince me that we're wrong or point out what we're missing. I can't emphasize this enough that we really want to be proven wrong and pointed in the right direction about some of these so we can stop evaluating options other than D8:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When running 1000 sites, D8 requires much more CPU and memory resources to render the same HTML output as D7. Because &lt;a href="https://www.drupal.org/project/drupal/issues/1792310"&gt;D8's core can't be run from symlinks&lt;/a&gt;, it doesn't support &lt;a href="https://www.etsy.com/codeascraft/atomic-deploys-at-etsy/"&gt;atomic deployments&lt;/a&gt; or efficient opcode caching when running 1000 copies of the same codebase. This leaves traditional multisite or containers as options. Multisite's limitations are well known. Containers add complexity and require more resources that provide little benefit when running Drupal as a service.&lt;/li&gt;
&lt;li&gt;D8 seems slower than D7 or other PHP alternatives. Everything from updating with Composer, menu routing, and editing pages. While this isn't as much of an issue for users browsing the sites since the output is cached and served by Varnish, the slow renders are very noticeable to editors and developers.&lt;/li&gt;
&lt;li&gt;Install profile inheritance is still unstable. Despite 6 years of development, being included in popular D8 distributions like Lightning, and &lt;a href="https://dri.es/distributions-remain-a-growing-opportunity-for-drupal"&gt;Dries blogging about it&lt;/a&gt;, it is unclear this &lt;a href="https://www.drupal.org/project/drupal/issues/1356276"&gt;core patch&lt;/a&gt; will ever be committed. Acquia drove the patch in a different direction for over a year trying to make a base profile's dependencies optional. When we &lt;a href="https://www.drupal.org/project/demo_umami_subprofile"&gt;suggested making the Umami demo a sub-profile of Standard&lt;/a&gt;, it became clear how few members of the core team knew anything about profile inheritance or supported updating core to support it.&lt;/li&gt;
&lt;li&gt;Our experience with highly promoted D8 "successes" like Webform wasn’t great. The D7 version of Webform reports more than &amp;gt; 440K installs. The D8 version, ~32K reported installs. This isn't a criticism of @jrockowitz or the Webform code. He is doing amazing work, but we felt the lack of a larger base of developers contributing fixes and &lt;a href="https://2017.drupalcampcolorado.org/session/d8-webform-and-webform-views-integration.html"&gt;extending Webform when working with Webform and Views&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;D8’s Layout Initiative isn’t a good match for how we currently manage Drupal as a service. Now that the dust has settled on 8.5.0, we'll post more on this soon.&lt;/li&gt;
&lt;li&gt;We're finding fewer well-maintained contrib projects. While using contrib projects can be golden handcuffs that only get you 80% of a solution with options and assumptions you end up fighting against in the end, we've mastered the embrace and customized/extend/contribute back approach. We rely heavily on contrib and actively contribute back. We maintain or co-maintain projects used by more than 100K D7 sites. When we find fewer D8 contributions to meet even 80% or our needs, it makes less sense to develop our own solutions for Drupal than a leaner, faster framework.&lt;/li&gt;
&lt;li&gt;The "let's throw everything in core" approach results in an increase in critical security releases for code we aren't using. This is an issue in environments with distributed development, systems, networking and security teams, where a security team is periodically scanning for known vulnerabilities with tools like &lt;a href="https://www.qualys.com/"&gt;Qualys&lt;/a&gt;, &lt;a href="https://www.arachni-scanner.com/"&gt;Arachni&lt;/a&gt; or &lt;a href="https://www.tenable.com/products/nessus/nessus-professional"&gt;Nessus&lt;/a&gt;. With something like &lt;a href="https://www.drupal.org/sa-core-2018-001"&gt;sa-core-2018-001&lt;/a&gt;, these scans don't care that the Comments module is disabled or even deleted. They scan the code looking for anything less than Drupal 8.4.3 and report that the entire code base is a security issue. We can respond to the issue by explaining that it is mitigated by X, but that fact remains that more code in core will likely translate to more staff time applying security updates to 1000+ sites. &lt;a href="https://www.drupal.org/project/ideas/issues/2873800"&gt;Ideas like what @davidhernandez suggested package Drupal both framework (essential core) and product (core)&lt;/a&gt; aren't getting the same attention from the DA as demos and other improvements to attract non-technical users to Drupal. LTS support services offered for D6 aren't really enough since they aren't altering the code fingerprint that the security scans are looking for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wish moving from D7 to D8 was an obvious move for us. It would make my job much easier. After watching the normal stability requirements ignored to sneak Umami into 8.5 and realizing that &lt;a href="https://www.drupal.org/drupalorg/blog/whats-new-on-drupalorg-january-2018"&gt;the initiatives DA was promoting for core (automatic updates, project browser, telemetry and in site announcements from the DA)&lt;/a&gt; are NOT features we'd use in our service, it's becoming increasingly clear our needs no longer align with what is driving the priorities of the Drupal project. When I evaluate D8 through the Umami demo, it's clear that we aren't even the target audience for what the project wants to highlight to people evaluating it. When we evaluate a framework, product or service, part of what we evaluate is the cost to maintain. When fatal errors are acceptable in a demo after a core update, we question whether we'll be able to easily apply upgrades if the developers most familiar with this framework can't upgrade the demo?&lt;br&gt;
&lt;a href="https://www.drupal.org/project/project_distribution?f%5B0%5D=&amp;amp;f%5B1%5D=&amp;amp;f%5B3%5D=sm_field_project_type%3Afull&amp;amp;f%5B4%5D=&amp;amp;text=&amp;amp;solrsort=iss_project_release_usage%20desc&amp;amp;op=Search"&gt;The Express install profile we've developed and use at multiple campuses is the 5th most popular D7 distribution on Drupal.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's not that the entire University of Colorado system is against D8 either. Both the University of Colorado Colorado Springs (UCCS) and Auraria Library are both using D8, but for very different use cases than the Web Express service we offer for free on the Boulder campus.&lt;/p&gt;

&lt;p&gt;UCCS is moving from &lt;a href="https://www.ingeniux.com/"&gt;Ingeniux&lt;/a&gt; to D8. For those of you who aren’t familiar with Ingeniux, it is a XML/XLST static site generator with limited features for dynamic content.  UCCS initial D8 offering has similar limitations to Ingeniux, but they are leveraging Migrate to move sites from Ingeniux to Drupal very quickly.  They are also hosting their Drupal 8 sites themselves on the most advanced server architecture within the CU system which will set them up well to add new features in the future.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://library.auraria.edu/"&gt;Auraria Library&lt;/a&gt; is another high profile D8 site.  This site has more features and functionality than the UCCS sites, but it also has a small development team supporting a small group of content editors and is hosted on Pantheon.&lt;/p&gt;

&lt;p&gt;While D8 makes sense for both of these use case, neither of these groups had insights on how we could overcome what we think are D8's short comings for the ~1000 sites we manage for the University of Colorado Boulder.&lt;/p&gt;

&lt;p&gt;While I'd prefer to continue maintaining D7 sites while developing new projects in D8, the &lt;a href="https://www.drupal.org/project/drupal/issues/2608496"&gt;lack of clarity from the DA around the EOL of D7&lt;/a&gt; is forcing us to invest time in evaluating alternatives now. When I read that &lt;a href="https://symfony.com/blog/new-in-symfony-4-1-fastest-php-router"&gt;Symfony 4.1's router is now the fastest PHP router&lt;/a&gt;, I get both excited and terrified. I'm excited since, in some ways, this would prove everyone that pushed to get off the island and collaborate with the larger PHP community right. I'm terrified because I realize that Drupal going from Symfony 3 to Symfony 4 most likely means D8 to D9. If D9 means the end of support for D7 and quarterly justification for running software our security team views as insecure, we have to go all in on a direction other than D8 soon.&lt;/p&gt;

&lt;p&gt;We've spent some time trying to answer the question, "if not Drupal, then what?" If we can't figure out how to make D8 work for us, I'll post more about what we found when evaluating alternatives to D8. This week, I'm focused on trying to make D8 work well when hosting Drupal as a Service in higher ed.&lt;/p&gt;

&lt;p&gt;If you see me at DrupalCon, PLEASE change my view. I won't be hard to spot.&lt;/p&gt;

&lt;p&gt;I've started a thread on &lt;a href="https://www.reddit.com/r/drupal/comments/8b87ky/change_my_view_d8_isnt_the_best_upgrade_path_for/"&gt;r/drupal/&lt;/a&gt; for everyone who's not at DrupalCon.&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>php</category>
    </item>
    <item>
      <title>Guide to Drupal 9 on Heroku</title>
      <dc:creator>Kevin Reynen</dc:creator>
      <pubDate>Fri, 25 Sep 2020 21:57:42 +0000</pubDate>
      <link>https://dev.to/kreynen/guide-to-drupal-9-on-heroku-2f11</link>
      <guid>https://dev.to/kreynen/guide-to-drupal-9-on-heroku-2f11</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;In this guide I will:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explain Why It Made Sense for Us to Use Drupal 9 on Heroku and Why It Might Not Make Sense for You&lt;/li&gt;
&lt;li&gt;Create a New Drupal 9 Project That is Ready to Patch&lt;/li&gt;
&lt;li&gt;Install Drupal Locally using PostgreSQL on Lando&lt;/li&gt;
&lt;li&gt;Setup a cloud file system module (Flysystem) for system files (in part 2)&lt;/li&gt;
&lt;li&gt;Setup a cloud file system module (Cloudinary) for user contributed files (in part 2)&lt;/li&gt;
&lt;li&gt;Deploy to Heroku (in part 2)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Some Background on Why We are Using Drupal 9 on Heroku&lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;After a decade of using a utility knife of a CMS that was Drupal 5, 6 and 7 to create solutions for hundreds of different use cases, I really thought I had created my last Drupal site after DrupalCon Nashville back in 2018. At the time I managed a development team responsible for more than ~1000 Drupal 7 for the University of Colorado, but I couldn’t get excited about a complete rewrite of the Web Express install profile and all the custom modules and configuration that made offering Drupal as a Service cost effectively. &lt;a href="https://www.reddit.com/r/drupal/comments/8b87ky/change_my_view_d8_isnt_the_best_upgrade_path_for/" rel="noopener noreferrer"&gt;I begged someone to change my views on Drupal 8 in Nashville&lt;/a&gt;, but left Nashville disappointed and disillusioned about who Drupal was for. &lt;/p&gt;

&lt;p&gt;Instead of continuing to shake my first at the sky, I took an opportunity to transition to a new role at the University of Colorado focusing on CRM/Salesforce solutions. In my new role with my new team, suggest that a logical path forward for this team for the Drupal 7 Commerce solution they had been using to process millions of donors in donations each year was to host smaller applications that integrated tightly with Salesforce on Heroku. Heroku can be expensive, but it provides a nice mix of preconfigured buildpacks and devops build, test and review tools perfect for small development teams without dedicated system admin or devops teams. &lt;/p&gt;

&lt;p&gt;As many of you might have guessed, despite the freedom Heroko and modern javascript front ends offers, most projects still require basic CMS features. We didn't need everything Drupal offers, but we still wanted to enable non-technical SME to edit content and manage media assets. We used Contentful integrated with Cloudinary on a few projects. While Contentful is great to rapidly model content, we ran into limitations when building sophisticated, contextual forms. Staff who edited content in multiple applications found the process of jumping from app to app cumbersome and confusing. Contentful was a great Ron Popeil style “set it an forget it” style solution for simple apps, but the work required to build coherent UX frontend for multiple applications using Contentful as a decoupled backend was similar to work required to use an open source CMS solution as the backend.  After evaluating several of the newer CMS solutions designed specifically for a decoupled implementation like Strapi, we ended up looking at Drupal again and I'm glad we did. Drupal 9 addressed many of the issues we had with Drupal 8 and is much easier to use with an Enterprise hosting environment like Heroku.&lt;/p&gt;

&lt;p&gt;Because we were already hosting other applications on Heroku, we thought we’d at least try running the current release of Drupal 9 on Heroku. With a few exceptions, it worked surprising well. &lt;a href="https://www.fomfus.com/articles/how-to-create-a-drupal-8-project-for-heroku-part-1" rel="noopener noreferrer"&gt;Federico Martínez’s posts on getting Drupal 8 running on Heroku&lt;/a&gt; really helped, but there are some important changes between versions 8 and 9. I’ve also taken Federico's approach further with a local deployment experience Drupal developers would be more familiar with.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/kristen_pol/status/1306686034399248386" rel="noopener noreferrer"&gt;Kristen Pol’s recent tweet about the issues she had when attempting to use Drupal 9 on traditional Drupal hosts like Pantheon and Acquia&lt;/a&gt; motivated me to write this up.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1306686034399248386-975" src="https://platform.twitter.com/embed/Tweet.html?id=1306686034399248386"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1306686034399248386-975');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1306686034399248386&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DISCLAIMER:&lt;/strong&gt; If you aren’t running other applications on Heroku, this is unlikely to your best or most cost effective solution for hosting Drupal. While Kristen ran into issues with Platform.sh, I personally think this is best option if you are running Drupal and other modern, PHP applications. If you are only running Drupal, I'd wait to see what Pantheon has to offer with Drupal 9.1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a new Drupal 9 Project That is Ready to Patch &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;If you aren’t familiar with using Composer for package management, it’s similar to npm. Assuming you have Composer installed, typing these commands into your terminal will quickly copy these projects and all their dependencies to you local machine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;composer create-project drupal/recommended-project drupal-on-heroku
cd drupal-on-heroku
composer require drush/drush
composer require drupal/core-composer-scaffold
composer require cweagans/composer-patches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point we’ve told Composer what code we want to include in the project. Including cweagans/composer-patches gives use the ability to patch core and contrib which we will need to get Flysystem and Cloudinary working in Drupal 9.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Drupal Locally using PostgreSQL on Lando &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In Federico’s example, he used &lt;code&gt;php -S 127.0.0.1:8888 -t web&lt;/code&gt; to spin up a local PHP server and install Drupal using the UI. We’re going to install Drupal using Lando and Drush instead. &lt;/p&gt;

&lt;p&gt;If you haven't already installed Lando, follow &lt;a href="https://docs.lando.dev/basics/installation.html" rel="noopener noreferrer"&gt;Lando official guide for your platform first&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;lando config&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;? From where should we get your app's codebase? current working directory
? What recipe do you want to use? drupal9
? Where is your webroot relative to the init destination? web
? What do you want to call this app? drupal-on-heroku
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we start Lando, we need to make a few changes in the .lando.yml and create a defaults.env that we’ll use to mimic Heroku’s Config Vars.&lt;/p&gt;

&lt;p&gt;Open .lando.yml with your editor of choice. If you followed the prompts correctly, you should see something like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: d9-test
recipe: drupal9
config:
  webroot: web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace that with the following configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: d9
recipe: drupal9
config:
  webroot: web
  php: 7.4
  xdebug: true
services:
  postgres:
    type: postgres:12
    portforward: true
    creds:
      database: drupal9
events:
  post-start:
    # Sleep for a few seconds since Drush load appears to be a race condition.
    - sleep 5
    - drush status
    # Turn on dev modules excluded from config export.
    - drush en config dblog devel devel_generate update webprofiler --debug
    - drush cr
excludes:
  - vendor
  - web/core
  - web/private
env_file:
  - defaults.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create defaults.env in the project root directory with your editor of choice. Add the following variable.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DATABASE_URL=postgres://postgres:@postgres:5432/postgres&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create or modify your .gitignore to add defaults.env. That isn't as important for this step, but it will be important that you do not reveal your Cloudinary or S3 configuration in future once those have been added to the defaults.env.&lt;/p&gt;

&lt;p&gt;We are finally ready to run &lt;code&gt;lando start&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;You will likely get this error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Symfony\Component\Console\Exception\CommandNotFoundException]                                                                                                                       
  Command pm:enable was not found. Drush was unable to query the database. As a result, many commands are unavailable. Re-run your command with --debug to see relevant log messages.  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;lando info&lt;/code&gt; to confirm that the default Postgres port is used on your local configuration. &lt;/p&gt;

&lt;p&gt;Now run &lt;code&gt;Run drush si –db-url=pgsql://postgres:@postgres:5432/drupal&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;After the install is finished, we need to update the settings.php to parse the database values from the environmental variables. Like many could hosts, Heroku can swap your applications between database instances as needed. We this happens, database credentials in the Config Vars are automatically updated. The database connection credentials are also different in each Review App, staging and production instance. As a result, hard coding these values in a settings.php file (or letting the Drupal install do this) is going to cause problems.&lt;/p&gt;

&lt;p&gt;Open web/sites/default/settings.php in your editor of choice and update the database credentials used during the install to this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Add database credentials from parsed environmental variable.
// This also works for Lando since it uses the same DATABASE_URL variable.
$parsed_creds = parse_url(getenv('DATABASE_URL'));

// Need to correct scheme based on Drupal naming conventions.
$scheme = $parsed_creds['scheme'] == 'postgres' ? 'pgsql' : $parsed_creds['scheme'];
$databases['default']['default'] = [
  'database' =&amp;gt; explode('/', $parsed_creds['path'])[1],
  'username' =&amp;gt; $parsed_creds['user'],
  'password' =&amp;gt; $parsed_creds['pass'],
  'prefix' =&amp;gt; '',
  'host' =&amp;gt; $parsed_creds['host'],
  'port' =&amp;gt; $parsed_creds['port'],
  'namespace' =&amp;gt; 'Drupal\\Core\\Database\\Driver\\' . $scheme,
  'driver' =&amp;gt; $scheme,
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Congratulations!&lt;/em&gt;&lt;/strong&gt; You now have a local copy of Drupal 9 running with a Heroku friendly configuration that can be deployed on Heroku. In the next part, I will walk through how to configure Flysystem and Cloudinary with Heroku's Addons for those services. &lt;/p&gt;

</description>
      <category>php</category>
      <category>drupal</category>
      <category>heroku</category>
    </item>
  </channel>
</rss>
