Drupal Planet

Double Whammy! Upgrading to Drupal 10 and Gatsby 5 at the same time

Decoupling your frontend (Gatsby) from your backend (Drupal) is the Holy Grail. Change/update one without affecting the other. But what happens when both frameworks release a new version at the same time?

Honestly, this isn't the scare story that the headline and intro make it out to be. And there was about 5 months between the release of Gatsby 5 and Drupal 10, but I didn't have spare time to upgrade this site and also wanted to wait a little bit to make sure the plugins I was using were Gatsby 5-compatible.

Upgrading from Gatsby 4 to 5

There was a lot to upgrade here. Gatsby 5 needs Node 18, React 18, Gatsby Image 3, and lots more. Trying to get them all in position took a bit of trial and error between dependencies being locked in package-lock.json and deeper inside the node_modules directory. The short story is: delete your package-lock.json file, delete your node_modules directory, delete your .cache directory, and run a clean install.

Next issue, I am using esm for imports and running my local npm commands, but esm doesn't work with Gatsby 5, or works natively, or something like that I can't remember exactly. The fix for this was to rename gatsby-config.js and gatsby-node.js to gatsby-config.mjs and gatsby-node.mjs respecitely, then edit the files to work with the new syntax I needed.

Following that, I had issues with embedding images in the body field of my blogs. I use the Drupal media module to add images to my website and the media embed widget to embed them in my body field, however I don't want Gatsby to render the <drupal-media> tag, as that will just be empty in Gatsby land. Rather, I need to find the id of the media item that is being called, then use <GatsbyImage /> to render it (after finding/filtering it via a GraphQl query). The package I had been using for that was called React HTML Parser, but of course that doesn't work with React 18, so I had to remove that and use HTML React Parser (which looks like a much better package).

Finally, with that all working locally, I could push my changes to GitHub and let GitHub actions do it's magic to compile the site for me. Except, GitHub actions uses Node 12 by default. Grand, I'll move my site to Cloudflare pages ... oh no, that uses Node 16. Right, so I'll move it to Netlify. Actually, I probably could have moved it to Netlify, but then someone answered an issue I had replied to on GitHub with a way to use whatever version of Node you want with GitHub actions, and that worked a treat. Now, to upgrade my site from Drupal 9 to Drupal 10!

Upgrading from Drupal 9 to Drupal 10

Right, the easy part. Drupal has this romantic idea of easy updates from 8+. Upgrading from 8 to 9 proved tricky for me, until I eventually removed Devel module, but can't remember the exact issue. I had a similar issue with Drupal 9 to Drupal 10. My custom theme depended on Classy, but that is removed in Drupal 10. The fix for this was a dance around adding Classy/Stable to my composer.json so I'd have the contrib versions of these, running the upgrade, getting lost because there's issues with other things in the vendor directory that specify Twig 2 in their composer.json files. Then backtracking, uninstalling my custom theme (remember, I don't need it since I have a decoupled site), installing Olivero as my default them (it's beautiful, thanks to everyone who worked on it!), deleting composer-lock.json, deleting the vendor directory, removing any modules that were hanging around not being used such as Inline Entity Form and others, and running the update script. Which ... failed ... ouch! The problem this time? It wouldn't add YAML 6 because of an issue with Drush wanting YAML 4, then realising I was using Drush 10, but that doesn't work with PHP 8 (and is EOL in any case). Once I edited composer.json to require Drush 11, the script ran fine, the update when fine, and I, your humble author, had himself a snazzy Drupal 10 website.

And now...

It looks like my original idea behind decoupling this website was a good idea. It meant I could update my frontend Gatsby at my own leisure, with no effect on the backend, and could then update Drupal at my own leisure and even remove the custom theme without the frontend being affected. Win. Win.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Simplified Drupal Field Template (but the same markup rendered)

Simplified version of Drupal field template

Here's a small edit to the Drupal field template we could make so it's much easier to read.

Everytime I look at the Drupal field template, I struggle with the conditions nested inside it - if label, if multiple, else not multiple but still label, etc, etc. ... so I thought, "why not make it simpler".

Here's the original field template:

{% if label_hidden %}
  {% if multiple %}
    <div{{ attributes.addClass(classes, 'field__items') }}>
      {% for item in items %}
        <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
      {% endfor %}
    </div>
  {% else %}
    {% for item in items %}
      <div{{ attributes.addClass(classes, 'field__item') }}>{{ item.content }}</div>
    {% endfor %}
  {% endif %}
{% else %}
  <div{{ attributes.addClass(classes) }}>
    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
    {% if multiple %}
      <div class="field__items">
    {% endif %}
    {% for item in items %}
      <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
    {% endfor %}
    {% if multiple %}
      </div>
    {% endif %}
  </div>
{% endif %}

and here is my updated version which will render the same markup for us:

<div{{ attributes.addClass(classes) }}>
  {% if not label_hidden %}
    <div{{ title_attributes.addClass(title_classes) }}>{{ label }}</div>
  {% endif %}
  <div class="field__items">
    {% for item in items %}
      <div{{ item.attributes.addClass('field__item') }}>{{ item.content }}</div>
    {% endfor %}
  </div>
</div>

What's the difference? In mine, we do an explicit check for a field label and either render it or not. Following that, we render the field items, without checking if they are "multiple" or not. Now, this does cause a small difference with the original template - it means we always render a container div with a class of ".field__items". However, I see this as a feature. It means we get the exact same markup on single fields as we get on fields with multiple items.

Why is this a feature? Well, it means when writing our CSS and we want to target the immediate ".field__item", we don't have to do something like this:

/* If multiple */
.field--news-authors > .field__items > .field__item  {
  color: red;
}

/* If only one item */
.field--news-authors > .field__item {
  color: red;
}

Enforcing a consistency in our classes and having a much easier to read template is good.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

This is an AI Generated Article about "Drupal Security Best Practices"

While searching for a clickbait generator to post something funny on an internal team chat, I came across writecream.com which claims to write high quality AI-generated articles. Here's what it came up with for an article titled "Drupal Security Best Practices".

Drupal Security Best Practices: What You Need To Know And How To Secure Your Site.

Drupal is an open source content management framework that has become a favorite choice for many businesses. It has proven to be a secure and flexible tool that has been used by a wide variety of businesses over the past few years. This article will teach you how to secure your Drupal website and what you need to do to keep it secure.

1. Why is security important?

Drupal is a free and open source content management system. Security is a must-have for a Drupal site, which is why it is imperative that you know the best practices for securing your site. Drupal security best practices include using a secure password, using a firewall, and implementing a password policy. You should also make sure that your Drupal site is not vulnerable to any external threats. Drupal security best practices are important for a Drupal site.

2. Drupal security best practices: What you need to know

Drupal is a powerful and flexible content management system. It has plenty of features and is designed to work with a wide variety of content. Drupal is a great option for people who want a customized website that is easy to use and allows a lot of flexibility. However, with any powerful software, there are also many security risks. This article will help you learn about the most important Drupal security best practices and how to secure your site.

3. How to secure your Drupal website

The Drupal Security Best Practices article is a great resource for anyone who wants to learn how to secure their Drupal website. It is a must-read for anyone who is considering using Drupal as their web platform of choice. It is also a great resource for anyone who is just starting to learn how to use Drupal. The best way to secure your Drupal website is to use the recommended security settings. The Drupal security best practices article discusses these recommended settings and provides information on how to implement them. It also provides links to sites that can help you learn more about Drupal security.

4. Conclusion.

One of the most important things you can do to ensure your Drupal site is secure is to follow best practices for securing your site. This includes implementing a firewall, keeping your site up to date with the latest security patches, and following best practices for securing passwords. There are many other things you can do to secure your site, but these are the most common. It's important to realize that these changes won't guarantee that your site is secure, but they will increase your chances.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Programmatically adding all your (Irish) council's services to a LocalGov Drupal website

Irish Service Catalogue for LocalGov Drupal websites.

Thanks to Tipperary County Council for making this work open source, so any council in Ireland can automatically publish all their council services on their website.

Steps to perform to add all of your council's services to an LGD site:

  1. Install the LocalGov Irish Service Catalogue module
  2. Install the LocalGov Multilingual module
  3. Add your LGMA Council ID
  4. Click Import
  5. Done!

 

One thing I forgot to show in the video is the services listing page, which allows visitors to easily find your services. Here's a screenshot of it:

Irish Service Cataloge Listing Page

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Creating a Drupal Field Group Programmatically

How to create a Drupal field group programatically in Drupal 8, 9, 10, etc.

While working on adding a new module to the LocalGov Drupal distribution, I came across an interesting dilemma. I was adding a new module that creates some fields (Irish service type, Irish service id, Irish service ...)  on an existing content type (services content type). This would mean that if anyone council in Ireland installed my module, they would automatically have a listing of all services that their council provides (via the Irish LocalGov Services API).

Once I was finished creating my fields, facets, views, etc I created some field groups to group the Irish fields together on the 'Manage Form Display' page, then exported my config. Next when I tried to import the config on a new install of the site, it wouldn't import because there was already values in the database from LocalGov Drupal core for the services 'Manage Form' display. Simple fix: put my config into /config/optional instead of config/install in my module, and then rebuild the site. This time the config did import, except I couldn't see any of the fields on my /node/add/service node creation form? Reason - since there was already config for the form display in the active config, Drupal ignored my config for the same item in /config/optional. But ... the fields were there in the database - created via the field.field.field_name.yml files that were imported.

That when I realised that I was missing two things:

  1. Place the fields on the manage form display page (they were currently in the 'Disabled' region), and
  2. Place the "Irish Council Services" vertical tab on the manage form display page (I couldn't see it anywhere).

The first item wasn't too difficult since the fields already existed. But the second was very tricky to figure out (at least for my small brain), because the vertical tab hadn't been created since the config that would create it had been passed over by Drupal.

To get around this, I needed to create the vertical tab programmatically in hook_install() when the module was being installed. Turns out, it's pretty easy, but no amount of searching on Google turned up any results. Thanks to Ekes on the LocalGov Drupal Slack for some pointers. Here's the code I used (I needed this to apply to 3 content types, hence the foreach loop):

/**
 * Implements hook_install().
 */
function localgov_irish_service_catalogue_install() {
  // Since the core.entity_form_display.yml file already has a value in the DB for the services 
  // content types, it does not get imported a second time on install. This means our tabs for 
  // the 'Manage Form Display' page need to be created manually.
  $bundles = [
    'localgov_services_landing',
    'localgov_services_sublanding',
    'localgov_services_page',
  ];

  foreach ($bundles as $bundle) {
    $group_irish_services = new stdClass;
    $group_irish_services->group_name = 'group_irish_service_catalogue';
    $group_irish_services->context = 'form';
    $group_irish_services->entity_type = 'node';
    $group_irish_services->bundle = $bundle;
    $group_irish_services->mode = 'default';
    $group_irish_services->label = 'Irish Service Catalogue';
    $group_irish_services->region = 'content';
    $group_irish_services->parent_name = 'group_tabs';
    $group_irish_services->weight = '100';
    $group_irish_services->children = [
      'localgov_irish_service_topic',
      'localgov_irish_service_category',
      'localgov_irish_service_municipal',
      'localgov_irish_service_type',
      'localgov_irish_service_user_type',
      'localgov_irish_service_lgma_id',
      'localgov_irish_service_reference',
    ];
    $group_irish_services->format_type = 'tab';
    $group_irish_services->format_settings = [
      'classes' => '',
      'show_empty_fields' => false,
      'id' => '',
      'formatter' => 'closed',
      'description' => '',
      'required_fields' => true,
    ];
    field_group_group_save($group_irish_services);
  }
}

 

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Creating a Colour-picker field for Drupal

Demo/tutorial on how to create a color-picker field for a Drupal website (since color module is now deprecated).

The source code for this Localgov Microsites Colour Picker Fields module is available on GitHub.

TL;DR

  1. Create a template suggestion for the input field for the fields you want to use a colour picker with.
  2. Add 2 inputs to that template - text input and color input.
  3. Add some JavaScript to say "if either of these inputs are changed, update the other one to match". 

 

Here's an abridged version of the colour picker on CodePen.

 

See the Pen Colour Picker Input by Mark Conroy (@markconroy) on CodePen.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Braindump: Choosing an e-commerce solution for Drupal

Here's a braindump to a question I answered on Slack today about choosing an e-commerce solution for Drupal.

In terms of a Drupal-native solution, there really isn’t any other option than Drupal Commerce.

You could use another platform like Shopify and use the Drupal Shopify module to import your products to Drupal for display. It looks like a decent approach but the module is only in an alpha state and hasn’t had a release in almost 2 years.

A headless platform like Big Commerce is also worth looking at, but the Big Commerce module only has 2 sites using it (in the whole world), and is itself built on top of the Drupal Commerce module.

In short, it looks like all roads lead to Drupal Commerce. Well done and thanks very much to the Centarro team for all their hard work on it.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

What is the schema.org Blueprints module?

Schema.org Blueprints Module video screenshot

I took the schema.org blueprints module for a spin in a "box-opening" video. I was amazed!

How easy is it to use? Well, it took me a few minutes to figure a few things out, but it's as simple as:

  1. Choose the content type you want
  2. Accept the default fields
  3. Choose if you want to add more fields types by just saying "yes" or "no" and then they get created automatically for you
  4. Enjoy a website with content created to meet schema.org standards and receive thanks from your SEO folks.

Go try out the Schema.org Blueprints module for yourself. Hat tip to Jacob Rockowitz for creating it.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

Sneak Peak: Proof-of-Concept of Customisable Footer for a LocalGov Drupal Microsite

LocalGov Drupal Customisable Microsite Footer, with colour scheme based on Essex County Council colours

Here's a short video giving a proof-of-concept for how to create a customisable footer for a microsite based on LocalGov Drupal and Group Module.

Note: this is VERY MUCH a proof-of-concept. What you see here may or may not end up in the final product.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).

LocalGov Drupal on the Talking Drupal Podcast

Talking Drupal Screenshot - talking about LocalGov Drupal

I had great fun on the Talking Drupal podcast, where myself, Will, and Finn shared thoughts and experiences of the LGD distribution that we've been working on.

Myself, Will, and Finn were asked on to the Talking Drupal show recently to talk about building a distribution for local councils in the UK and Ireland.

Join the "Something nice ..." newsletter

The full title is "Something nice, something quirky, something else".

I send an email once a week with something nice, something quirky, and something else that I think is interesting (all with a web development theme, of course).