15 Oct 2026

feedDrupal.org aggregator

Talking Drupal: Talking Drupal #574 - UN Open Source Week

Today we are talking about the UN, Open Source, and Drupal with guests Tim Lehnen & Henry Poole. We'll also cover Live Update as our module of the week.

For show notes visit: https://www.talkingDrupal.com/574

Topics

Resources

Guests

Henry Poole - civicactions.com henry-poole Tim Lehnen - drupal.org hestenet

Hosts

Nic Laflin - nLighteneddevelopment.com nicxvan John Picozzi - epam.com johnpicozzi Tim Sharp - tea-sharp

MOTW Correspondent

Martin Anderson-Clutz - mandclu.com mandclu

15 Oct 2026 6:00pm GMT

The Drop Times: Drupal Developer Explains DevDeck's Design as Windows Beta Arrives

A tool that tracks every pull request, pipeline and local site can quickly become another source of noise. DevDeck's developer decided the answer lies in how loudly it speaks, not what it hides.

15 Oct 2026 3:01pm GMT

Nonprofit Drupal posts: October 2026 Drupal for Nonprofits Chat

Join us THURSDAY, October 15 at 1pm ET / 10am PT, for our regularly scheduled call to chat about all things Drupal and nonprofits. (Convert to your local time zone.)

We don't have anything specific on the agenda this month, so we'll have plenty of time to discuss anything that's on our minds at the intersection of Drupal and nonprofits. Got something specific you want to talk about? Feel free to share ahead of time in our collaborative Google document at https://nten.org/drupal/notes!

All nonprofit Drupal devs and users, regardless of experience level, are always welcome on this call.

This free call is sponsored by NTEN.org and open to everyone.

Information on joining the meeting can be found in our collaborative Google document.

15 Oct 2026 2:25pm GMT

Dries Buytaert: One description, inside and outside Drupal

My website has a custom photo album module that I've maintained for about twenty years. It helps me manage more than ten thousand photos. In my DrupalCon Rotterdam keynote, I talked about making that module work with AI assistants. You can watch that part of the keynote. I didn't have time on stage to go into the details, so I'm doing that in this post.

To let assistants find and edit my photos, I used the contributed Tool module, which provides Tool API, to expose my module's operations as tools. These include finding photos and updating a photo's caption or alt text.

Most of these tools are public methods on Drupal services I already had, like the one that searches my photos. A few PHP attributes are usually enough for Tool API to expose an existing method, so AI assistants can call it over MCP, the Model Context Protocol.

To describe a tool to other software, Tool API needs to know what data it accepts and returns: what each value is called, what type it is and what it means.

My album module doesn't store photos as Drupal entities (I know, I know), so Drupal has no field definitions for them. Instead, it keeps them in its own database table and loads each photo into an instance of Image, a plain PHP class. I added PHP attributes to the getters for the properties I wanted to expose, like this one for the alt text:

#[ToolProperty(description: 'Plain text describing the image for screen readers.', media_type: 'text/plain')]
public function getAlt(): string { 
  ... 
}

From attributes like this one, Tool API generates JSON Schema, a format for describing JSON data. MCP and OpenAPI, a standard for describing HTTP APIs, both use this format. So do Drupal's Single Directory Components, which use it to describe the data passed to reusable interface components.

In my album module, I use the same descriptions of my photo data to tell AI assistants what my tools return, generate TypeScript types for a React app that searches my photos, and define the inputs for my Drupal components.

The same tools also connect my site to various workflow systems. A workflow built with ECA, FlowDrop, Maestro, n8n or Activepieces can call the same photo-search tool an AI assistant calls, without requiring a separate integration with my album module.

A module maintainer exposes an operation once, and several kinds of software can use it.

Image.php Describes a photo once, in PHP attributes Tool API Generates JSON Schema from those attributes AI assistants Find, read and edit my photos over MCP Claude, or any other MCP client Front ends Search my photos with TypeScript types from OpenAPI React, Next.js, mobile apps Workflow systems Search my photos in workflows built without code ECA, FlowDrop, Maestro, Activepieces Drupal components Render my photos with props from a generated schema.json Single Directory Components, Drupal Canvas

This is why I said in my keynote that I believe the Tool module, built by Michael Lander and team, is one of the most important modules in Drupal right now. A module's capabilities can become available to assistants, front ends and workflows without its maintainer having to build for each one separately.

I think every Drupal module should work this way, which is why I featured it in my keynote and why I launched a broader effort around this called Rosetta.

The goal is for Drupal's own systems and software outside Drupal to work from shared descriptions of data and operations. Below, I'll walk through what I built and tested with my album module.

Drupal needs shared descriptions of data and operations

More of the work on a site happens outside Drupal every year: in AI assistants, in front ends built with JavaScript frameworks, and in orchestration platforms that connect Drupal to other systems. As I explained in AI and the great CMS unbundling, those systems still need the content management, governance and observability that Drupal already provides.

Drupal has entities, fields, permissions, revisions, workflows, content moderation and tens of thousands of contributed modules. But making a module's capabilities available to an assistant, a workflow or a front end still too often requires some integration work.

Keynote slide titled "The capabilities are here, but access is still too hard".
A slide from my DrupalCon Rotterdam 2026 keynote: Drupal has the capabilities, but making them available to other software is still too hard.

Installing a Drupal module should make its capabilities available to software already connected to a site: new tools for assistants, new operations for workflows, and new capabilities for front-end developers.

In my album module, I should only have to describe a photo once and implement photo search once, not write a separate integration for every assistant, front end or workflow system.

In Drupal, we already know why shared descriptions matter. When a site builder adds a field to a content type, Drupal stores a definition for it: its type, its label and whether it's required. Content editing forms, Views and JSON:API all reuse that definition.

CCK, Drupal's Content Construction Kit, let site builders define a field once, and Drupal used that definition for the edit form, the display and the database. Views let them list, filter and sort data from any module that described its data. Rosetta is about extending that kind of reuse to more of a module's data and operations.

Shared descriptions of data and operations could be Drupal's next CCK and Views moment.

User interfaces also keep changing: web pages, then native mobile apps, then headless front ends, then chat, and now AI assistants and agents. I don't know what comes after agents. But if modules describe their data and operations, new interfaces can build on the capabilities we already have. The next interface reads the description and gets to work. That won't make Drupal immune to change, but it makes us fast to adapt, and fast to adapt helps us win.

The question then becomes how to make that practical for thousands of module maintainers. Tool API gives us a starting point, alongside years of work on Typed Data, Single Directory Components, JSON:API, Drupal Canvas Code Components, Modeler API, and more. We need the people behind that work to help shape the approach, including whether Tool API, or parts of it, belongs in Drupal Core.

That's why I'm organizing the Rosetta Sprint: a few days for the people behind these projects to get together in person to compare the existing approaches, identify what is missing and agree on next steps with the relevant maintainers and Core committers.

Describe existing data and expose functions as tools

Tool API supports two ways to define a tool: (1) you can write a dedicated plugin class that Drupal discovers as a tool, or (2) add PHP attributes to an existing public method on a class registered as a Drupal service.

I started with a dedicated plugin class but ultimately switched to PHP attributes. Attribute support was still experimental when I started, and I helped improve Tool API as I used it (#3583030, #3583031, #3583032, #3583041, #3583085). The attribute support is now merged and available in Tool API's development version. Dedicated plugin classes remain fully supported.

I'll show the basic pieces here rather than walk through a full tutorial. Here is how the method that searches my photos becomes the find_images tool, simplified a little:

/**
 * Searches the images.
 *
 * @param string $query
 *   Words to look for in the title, caption or alt text.
 *
 * @return \Drupal\album\Image[]
 *   The matching images.
 */
#[ToolMethod(
  id: 'find_images',
  label: 'Find images',
  description: "Searches the site's images. …",
  operation: ToolOperation::Read,
  permission: 'access content',
)]
public function search(string $query): array {
  // The search code is unchanged.
}

The method body stays the same: it takes a search query and returns the matching images. The #[ToolMethod] attribute gives the tool its ID, label and description. It also declares that the operation reads data and that the caller needs the access content permission. The search code must still enforce any restrictions on which photos the caller can see.

Tool API reads the input's name and type, query and string, from the method signature. When type information is missing, Tool API tries to infer it from the method signature and docblock. Here, the Image[] return annotation tells Tool API that the array contains Image objects.

Knowing that the result is a list of Image objects doesn't tell other software which properties a photo has. I describe those with #[ToolProperty] attributes on the Image class's getters, like getAlt() above.

The attributes also explain what each property means. In PHP, a title, a caption and a URL can all be strings, but other software needs to know which is plain text, which contains HTML and which is a URL. I illustrated that distinction in the keynote:

Keynote slide titled "Three strings can mean three different things".
A slide from my DrupalCon Rotterdam 2026 keynote: all three values have PHP's string type, but #[ToolProperty] attributes describe the title as plain text, the caption as HTML and the URL as a URI.

Tool API only includes the photo properties I explicitly describe with #[ToolProperty]. The attribute can go on a public class property or a getter method. On getUrl(), it exposes the returned value as a photo property named url; it doesn't make the getter a callable tool.

Under the hood, Tool API uses Drupal's Typed Data API to represent these descriptions and can generate JSON Schema from them.

Drush, MCP, ECA, FlowDrop, Maestro and my album module's custom HTTP route can all call the same runner, ToolRunner::run(). That means the same permission checks and input validation apply whichever way a tool is called. The runner also distinguishes invalid input from denied access or an execution failure, so each integration doesn't have to work that out for itself.

As mentioned, PHP attributes aren't the only way to define a tool. A dedicated plugin class is a bit more verbose, but it has some advantages. For example, it doesn't have to live in the module it exposes. A separate module can define the tools and call the original module's services and APIs, with no changes to its code. Tool Belt currently takes that separate-module approach for Drupal Core operations, like creating content and updating fields. That means we can add tool support for existing modules without waiting for their maintainers to adopt Tool API.

If you maintain a module, try exposing one useful operation as a tool. If you get stuck, or Tool API can't describe the data you need, open an issue. Your feedback can help us improve Tool API before its first stable 1.x release. Tool API is still young, so you can help shape it.

AI assistants can handle complex tasks without developers

I actually started with search. A while ago, I exposed my blog's search to AI agents and wrote about it several times: as an MCP tool, through an API catalog and with Agentic Resource Discovery. That code started out custom, but I've since updated it to use Tool API as well.

Later, I added the album tools. My album module provides seven. The ones I use most are find_images and get_image, which find and read photos, and update_image, which changes a photo's title, caption or alt text.

I've used these tools to write titles and alt text for whole albums. Here are a few other things I ask an assistant to do:

The album tools and find_posts often work together. If I have an album from a trip and a blog post about the same trip, an AI assistant can call find_posts while it writes alt text for the album's photos, and use the post as context. It picks up details such as where we went, who was there and what the trip was for. The alt text gets better, without me having to point the assistant at the post.

My album module's admin screens can't do any of these tasks quickly, and some tasks have no screen at all. Before these tools, I either had to run SQL queries on the database or didn't do the task at all. To fix missing alt text, I'd query for the photos without it, then open each photo's edit screen in a browser. Updating dozens of images that way gets tedious.

Now an assistant finds the photos and drafts the alt text, and I review and approve its suggestions in Claude. It's at least 10 times faster than my old workflow.

I've been writing SQL for nearly 30 years, so I could always do these jobs myself. Many site owners can't. They ask a developer for help, or the job never gets done. Tools can remove that dependency. Photos are just my example. Any operation a module exposes as a tool becomes something a site owner can ask for directly, without waiting for a developer.

AI assistants can handle complex tasks without dedicated UIs

When an assistant calls get_image, it gets the photo's properties and the photo itself, so it can see what it's describing. In Claude, an interface I built also displays the photo in the chat. It uses MCP Apps, an MCP extension that lets a server provide an HTML interface the client renders in the conversation.

Every module has tasks that are too rare or too specific to justify a screen of their own. A maintainer can build screens for everyday work and make rare or specialized tasks available through tools. I've already removed parts of my album module's interface, like the button that generated alt text with a language model, because an assistant now does that job. I expect to remove more.

Shared descriptions can also make it easier to tailor interfaces to the people using them. Tool API can already generate a form from a tool's inputs and apply the same validation constraints when the tool is called without a form. Michael Lander is exploring this further in his Data Surface prototype, where forms and tools use the same definitions of accepted values and validation rules.

An organization could build admin screens around its own workflow while reusing those definitions and validation rules. With the right prompting, assistants can already build interfaces around these tools. For a batch of photo updates, that could be a table of images and proposed alt text where I can review and approve the changes. Over time, I expect assistants to recognize when an interface would help with a task and build one without being asked.

Michael's work builds on Drupal's configuration validation, and it is a good example of what I mean when I say Drupal has an accidental AI advantage. Wim Leers began advocating for configuration validation in 2022. AI wasn't part of his case. Years later, Michael can reuse those validation constraints to power forms and tools from one definition, and in Validation-first, Wim describes how the same precision helps AI tools generate valid Drupal Canvas code components.

JavaScript front ends can use the same tools as AI assistants

But that is not all. With my album data and operations described, I decided to make the same data and tools available to front-end developers. I wrote two pieces of connecting code: a shared HTTP route that calls read-only tools, and a generator that produces an OpenAPI document from their definitions. Together, they take under 150 lines of PHP.

The route uses the URL to identify the tool and the query string to supply its arguments. For example, a request to /api/find-images?query=ski calls find_images with ski as its query and returns the result as JSON. I didn't write another photo search or a separate route for each tool.

The auto-generated OpenAPI document, available at https://dri.es/openapi.json, describes those endpoints, their parameters and their responses. It uses the same #[ToolMethod] and #[ToolProperty] attributes the MCP tools use.

OpenAPI is a 15-year-old standard for describing HTTP APIs, so it's supported by many developer tools. Swagger UI, for example, lists my endpoints and lets you try them. This video shows the document, then Swagger UI reading it and calling the API for "driesnote":

Many front-end developers use TypeScript, which adds static types to JavaScript. A type can describe an image as an object with a string alt and a string title. The TypeScript compiler checks the code against those types before it runs, and editors like VS Code show type errors as you write.

To see what this gives a front-end developer, I asked Claude Code to build a small React app that searches my photos from the browser. The app knows nothing about Drupal, and building it didn't require any Drupal knowledge either. All Claude Code had was my site's URL and its generated OpenAPI document.

I'm not a front-end developer, so it was interesting to watch. Claude used a code generator called openapi-typescript to turn my OpenAPI document into TypeScript types in under a second. A small library called openapi-fetch then uses those types, so the compiler can check the request paths and parameters in the app's code.

The whole app is a single React component of 45 lines, and I wrote no additional Drupal code for it. In this video, it searches for "driesnote":

The HTTP route and OpenAPI generator are prototype code on my site. Nothing in them is specific to photos, so they shouldn't be something each site or module has to write. They belong in shared infrastructure that works for any module's tools. JSON-RPC is one place that could happen: if JSON-RPC supported Tool API, it could expose tools from other modules without each module writing its own JSON-RPC integration.

Workflows can call module operations as tools

Inside Drupal, ECA, FlowDrop and Maestro can call tools as steps in a workflow. The ECA Tool module, for example, makes tools available as ECA actions.

In the keynote, Shibin Das showed a FlowDrop workflow he built with my album module's tools. It searches my photos and lists my albums, first without any AI, then with an agent that decides which tools to use:

Workflow systems can also expose tools of their own. ECA calls its workflows "models", and the ECA Tool module exposes each Tool event in a model as a separate tool. One model can therefore offer several tools. Maestro can expose public workflow templates as tools, using their variables as inputs.

A workflow that is also a tool can be used like any other tool. A Maestro workflow can call a tool exposed by ECA, through the same Tool API integration it uses to call my photo search. Neither system needed a direct integration with the other. I still find that a little hard to get my head around, but I love it and see the potential.

Automation platforms outside Drupal need a way to call those tools too. Last year, Jürgen Haas and I built the Orchestration module to connect Drupal with Activepieces. It lets Activepieces call tools defined through Tool API, run AI agents and trigger ECA models, while events in Drupal can trigger workflows in Activepieces. I described that setup in Connecting Drupal with Activepieces. Other platforms can call Drupal's tools over MCP, for example through n8n's MCP Client node.

Tools compose. An assistant can combine them in a single task, a workflow can chain them, and a workflow can be one of the tools in another workflow. Once a system can call Drupal's tools, it can reuse that connection for operations from different modules.

That is the orchestration shift: a stack becomes a network, and workflows coordinate work across applications. Drupal can be a node in that network, with its modules offering operations that other systems can call. For agencies building those workflows, Tool API makes Drupal's capabilities available as reusable steps.

Drupal components can share data descriptions

So shared descriptions help JavaScript front ends and other applications use Drupal's data, but they can also help Drupal's own rendering system, even when no AI assistant or external application is involved.

My photos are rendered using Single Directory Components, or SDCs. Each component keeps its Twig template, CSS and metadata in one folder. Its .component.yml file declares the component's inputs, called props, and describes the data they accept.

My album module already describes a photo's properties with #[ToolProperty] attributes. I was also maintaining descriptions of those same properties in each photo component's .component.yml file. When I changed what a photo property contained, I had to remember to update both descriptions.

So I wrote a Drush command that reads the PHP attributes and generates a shared schema.json file. My album module's generated photo schema describes properties such as alt and caption: their types and what they contain. Each photo component's .component.yml file now references that shared description instead of describing those properties again. When I change what a photo property contains, I update its PHP attribute and run the command.

Moving the descriptions into a shared file creates a new problem. Anything that reads a component's .component.yml now finds a reference to schema.json, not the property definitions. A tool that builds a component catalog, showing what data each component expects, has to find and resolve that reference itself. Core's component API doesn't do it for them: it returns the reference without the photo's property definitions.

Pierre Dureau's merge request in Core issue 3352063 addresses that gap, though it isn't merged yet. With it applied on my site, Core's component API followed the reference and loaded the photo property definitions, without any changes to the schema file.

That matters for generative UI. Frameworks like OpenUI and A2UI let an AI agent assemble an interface from a catalog of components, so they need to know which components exist and what props each one accepts. With this change, an integration could build that catalog from Drupal's API instead of writing its own reference resolver. Tools that read the component files directly still need to learn to follow these references. The SDC add-on for Storybook, a tool for developing and previewing components, doesn't yet follow the Drupal-specific references I use.

The same goes for the generator. Other module maintainers shouldn't each have to write one like mine. My experiment uses Tool API's property descriptions, but describing data and generating schemas are useful beyond tools. Some of that support could belong in Drupal Core, benefiting both SDC and the Icon API, which uses JSON Schema to describe icon settings such as size and color.

My approach only covers components built to render my module's photos. General-purpose components define their own inputs and still need a way to get Drupal's data. Drupal describes entity fields with Typed Data, while SDC describes props with JSON Schema. UI Patterns already handles much of the work between them, including which data sources can supply a prop. Rosetta should build on that work too.

Make shared descriptions standard practice

The same photo descriptions and operations now support AI assistants, a React app, workflows inside and outside Drupal, and Drupal components.

I want more module maintainers to adopt Tool API: describe their modules' data once and expose useful operations as tools. That should become a normal part of developing and maintaining a Drupal module.

We should also provide the HTTP integration, OpenAPI generator and component schema generator as shared Drupal infrastructure. Module maintainers shouldn't each have to write that connecting code.

My prototypes show this working for one module. Rosetta is about making that reuse work across Drupal. We need to work with the relevant maintainers and Core committers to decide what belongs in Tool API, its integrations and Drupal Core.

If you maintain a module, try exposing one useful operation as a tool and using it with another system. Share what worked, and open an issue when you find something Tool API can't describe or do.

Thanks to Jamie Abrahams, Mateu Aguiló Bosch, Ronald te Brake, Shibin Das, Pierre Dureau, Matt Glaman, Jürgen Haas, Marcus Johansson, Randy Kolenko, Michael Lander, and Fons Vandamme for reviewing this post and sharing their experience.

15 Oct 2026 12:26pm GMT

The Drop Times: Two Drupal Modules Split Critical and Deferred CSS Delivery

Headers and hero sections often change between mobile and desktop layouts. Faster first paint depends on which styles a site sends first.

15 Oct 2026 6:10am GMT

14 Oct 2026

feedDrupal.org aggregator

Dynamosys Insights: Drupal 11.4.10 Fixes Critical Security Flaw: What Site Owners Should Do Now

A blue Drupal emblem stands behind a shield with a padlock beside the words “Drupal 11.4.10 Security Update.

Drupal 11.4.10 addresses three core security vulnerabilities, including a critical remote code execution flaw. Site owners should prioritize the appropriate core update and check whether separate Gin or Entity List updates also apply.

14 Oct 2026 7:20pm GMT

Darren Oh: Try the Drupal AI demo!

Try the Drupal AI demo!

The Drupal AI demo was unveiled at DrupalCon Rotterdam. It showcases how you can use AI in your Drupal site right now.

Darren Oh

14 Oct 2026 6:59pm GMT

Security advisories: Drupal core - Moderately critical - Cross-site scripting - SA-CORE-2026-016

Project:
Project machine name:
drupal
Date:
2026-October-14
Vulnerability:
Cross-site scripting
Affected versions:
>= 10.3.0 < 10.6.19 || >= 11.0.0 < 11.3.19 || >= 11.4.0 < 11.4.10 || >= 12.0.0-alpha1 < 12.0.0-beta2
CVE IDs:
CVE-2026-108514
Description:

The Navigation module doesn't sufficiently sanitize certain attributes, which can lead to a cross-site scripting (XSS) vulnerability.

This vulnerability is mitigated by the fact that an attacker must have a role with permission to enter HTML tags containing specific data attributes, or the administer menu permission.

Solution:

Install the latest version:

Drupal 11

  • If you use Drupal 11.4.x, update to Drupal 11.4.10.
  • If you use Drupal 11.3.x, update to Drupal 11.3.19.
  • Drupal 11.2.x and below are end-of-life and do not receive security coverage.

Drupal 10

  • If you use Drupal 10.6.x, update to Drupal 10.6.19.
  • Drupal 10.5.x and below are end-of-life and do not receive security coverage.

Drupal 8 and Drupal 9 have both reached end-of-life.

Fixed By:
Coordinated By:

14 Oct 2026 5:25pm GMT

Security advisories: Drupal core - Moderately critical - Cross-site scripting - SA-CORE-2026-015

Project:
Project machine name:
drupal
Date:
2026-October-14
Vulnerability:
Cross-site scripting
Affected versions:
>= 8.9.0 < 10.6.19 || >= 11.0.0 < 11.3.19 || >= 11.4.0 < 11.4.10 || >= 12.0.0-alpha1 < 12.0.0-beta2
CVE IDs:
CVE-2026-108515
Description:

The Drupal core Link module provides a field type that can be used for internal and external URLs.

The module does not sufficiently sanitize certain markup in some circumstances, which can lead to cross-site scripting (XSS) vulnerabilities.

Solution:

Install the latest version:

Drupal 11

  • If you use Drupal 11.4.x, update to Drupal 11.4.10.
  • If you use Drupal 11.3.x, update to Drupal 11.3.19.
  • Drupal 11.2.x and below are end-of-life and do not receive security coverage.

Drupal 10

  • If you use Drupal 10.6.x, update to Drupal 10.6.19.
  • Drupal 10.5.x and below are end-of-life and do not receive security coverage.

Drupal 8 and Drupal 9 have both reached end-of-life.

Reported By:
Fixed By:
Coordinated By:

14 Oct 2026 5:25pm GMT

Security advisories: Drupal core - Critical - Remote code execution - SA-CORE-2026-014

Project:
Project machine name:
drupal
Date:
2026-October-14
Vulnerability:
Remote code execution
Affected versions:
>= 8.9.0 < 10.6.19 || >= 11.0.0 < 11.3.19 || >= 11.4.0 < 11.4.10 || >= 12.0.0-alpha1 < 12.0.0-beta2
CVE IDs:
CVE-2026-108097
Description:

A remote code execution vulnerability exists within the Field UI module in Drupal core.

The vulnerability is not directly exploitable with core alone, but multiple serious exploit paths exist with contributed modules. At least one known exploit path does not require authentication. Custom code may also expose the vulnerable functionality.

The vulnerability can be mitigated by uninstalling the core Field UI module (field_ui), which will provide protection while sites are updated.

Drupal Steward protection:

This issue is being protected by Drupal Steward. Sites that use Drupal Steward are already protected from some known attack vectors, but the protection offered will not cover all possible exploits. Sites should upgrade in the near future in case additional attack vectors are discovered.

Solution:

Install the latest version:

Drupal 11

  • If you use Drupal 11.4.x, update to Drupal 11.4.10.
  • If you use Drupal 11.3.x, update to Drupal 11.3.19.
  • Drupal 11.2.x and below are end-of-life and do not receive security coverage.

Drupal 10

  • If you use Drupal 10.6.x, update to Drupal 10.6.19.
  • Drupal 10.5.x and below are end-of-life and do not receive security coverage.

Drupal 8 and Drupal 9 have both reached end-of-life.

Release packaging may still be in progress for this security announcement. If you are unable to access a release, wait 30-45 minutes and then check again.

Reported By:
Fixed By:
Coordinated By:

14 Oct 2026 4:10pm GMT

The Drop Times: LocalGov Drupal Recognised as a Digital Public Good

A council-developed publishing platform has completed an international standards review. Two initially unmet requirements reveal what the assessment demanded.

14 Oct 2026 2:03pm GMT

Dynamosys Insights: Drupal 11.4.9: A Steadier Sidebar and Better CKEditor Setup

Drupal 11.4.9 addresses a shifting navigation sidebar, updates CKEditor 5, and makes editor toolbar configuration more flexible through recipes. Here's what the release means for content teams, developers, and site owners.

14 Oct 2026 1:17pm GMT

Gspikes: Website Migration Timeline: How Long 29 Real Drupal Migrations Took

We read all 462 case studies on drupal.org and coded every migration that says how long it took. Median: 7.5 months from kickoff to launch. Small relaunches took weeks; multi-site platforms took a year or more.

14 Oct 2026 8:39am GMT

Gábor Hojtsy: Released Translation Template Extractor 3, a tool for the modern Drupal age

Released Translation Template Extractor 3, a tool for the modern Drupal age

If you ever translated Drupal software, you used the Translation Template Extractor (potx) at least indirectly, even if you never heard of it. It reads the source code of Drupal core and contributed projects, and collects the translatable strings. Every string translated on localize.drupal.org was extracted by potx. Developers and translators also use it to extract strings of their own modules and themes, on a web UI or with Drush.

Gábor Hojtsy

14 Oct 2026 7:17am GMT

13 Oct 2026

feedDrupal.org aggregator

Aten Design Group: Extending Editoria11y with Custom Content Checks in Drupal

Extending Editoria11y with Custom Content Checks in Drupal Joel Steidl Drupal

An editor copies a link from an email, adds it to a page, and publishes. The link text looks right. The destination opens. Nothing about the normal authoring workflow suggests a problem.

But the saved URL may not be the destination the editor intended to publish. Microsoft Safe Links can wrap an address in a long, encoded URL that sends visitors through a security-checking redirect service.

On of our client's websites, a custom Editoria11y check helps editors recognize these links and replace them with the original destination. It adds site-specific guidance to a tool already used for accessibility feedback.

A Content Problem Worth Flagging

Microsoft Safe Links is a legitimate security feature, not evidence that a link is spam or malicious. The problem here was context: a URL copied from an email was becoming a public website link.

A simplified example looks like this:

<https://gcc02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fexample.com%2Fmeeting>

The intended destination is https://example.com/meeting. Publishing the wrapper makes that destination harder to inspect and introduces dependence on another redirect service. The addresses can also be difficult to read and maintain.

Those are good reasons for an editorial warning. They are not proof that every Safe Link violates WCAG or cannot be used with a screen reader.

The useful question was narrower: could the website identify this recurring content pattern and give editors a practical next step?

Discovering an Existing Extension Point

Editoria11y brings accessibility feedback into the page context. Its custom-test capability lets developers add checks beyond the standard set without building a separate reporting interface.

Princeton's documentation includes an example for email-obfuscated URLs, providing a starting point for both detection and integration. The extension builds on that existing capability rather than introducing a separate checking system.

A Small Drupal Integration

The custom module, custom_editoria11y, handles the Drupal integration. Its metadata declares a dependency on Editoria11y. A library definition registers the custom JavaScript and depends on the contrib module's library.

The PHP attachment hook checks for the view editoria11y checker permission before attaching that library. This keeps the extra script scoped to users authorized to use the checker rather than delivering it to public visitors.

JavaScript handles detection and feedback. Although we might informally call this a custom rule or plugin, it is not a Drupal PHP Plugin API class. It is an event-driven JavaScript test delivered through a Drupal module.

That division keeps the implementation small: Drupal controls availability, the custom script identifies the content pattern, and Editoria11y provides the warning interface.

How the Custom Test Runs

Editoria11y's custom-test lifecycle has four steps: register the expected callbacks, listen for ed11yRunCustomTests, add results, and dispatch ed11yResume when finished.

Our script increments options.customTests through the Drupal integration's options override. That tells the checker to wait for one additional completion event before drawing its tooltips.

The count represents completing test callbacks, not matching links. A callback that finds ten links still sends one completion event. A callback that finds none must finish too.

The rule searches for anchors using a[href*="safelinks.protection.outlook.com"]. This catches different Safe Links subdomains without maintaining a list of regional prefixes. It is substring matching, however, not comprehensive URL-host validation; the same text elsewhere in an address could also match.

The following excerpt shows the site's v3 integration. It assumes the options override and tooltip helper are already defined:

document.addEventListener('ed11yRunCustomTests', function () {
  Drupal.Ed11y.findElements(
    'customSafeLinks',
    'a[href*="safelinks.protection.outlook.com"]'
  );
 
  Drupal.Ed11y.elements.customSafeLinks?.forEach(function (element) {
    Drupal.Ed11y.State.results.push({
      element,
      test: 'customSafeLink',
      type: 'warning',
      content: customSafeLinkContent(element.getAttribute('href')),
      position: 'beforebegin',
      dismiss: false,
    });
  });
 
  document.dispatchEvent(new CustomEvent('ed11yResume'));
});

Using findElements keeps the search within the configured content roots and respects selector-based exclusions. Results enter the existing checker workflow rather than a separate alert system.

The tooltip names the issue, displays the encoded address, and asks the editor to replace it with the original URL. When available, new URL(href).searchParams.get('url') extracts the destination as an additional hint. If parsing fails or the parameter is missing, that hint is omitted.

Displayed URL strings are sanitized with Drupal.Ed11y.sanitizeHTML. In this v3 implementation, tooltip content is a DOM element, with a .title child supplying its heading.

The rule does not rewrite content or block publication. The editor remains responsible for checking and replacing the link.

Maintaining the Rule Through an Upgrade

An upgrade from Editoria11y 2.2.6 to 3.0.2 required migrating the custom module to the v3 API.

The migration changed more than a version constraint. The custom code moved from older Ed11y references to Drupal.Ed11y, changed the sanitization helper, and pushed results into Drupal.Ed11y.State.results. Tooltip construction moved from the older message-registration approach and HTML strings to DOM-element content. Result properties also changed, including explicit warning severity and the dismissal setting.

The lesson is practical: extending a supported tool avoids owning an entire checker, but the extension still has an API contract. Major upgrades require reviewing that contract and testing the custom feedback, not just confirming that the base module loads.

Testing and Extending Thoughtfully

For ongoing maintenance, a focused regression checklist should cover matching and ordinary links, missing destination parameters, configured exclusions, permission boundaries, safe tooltip rendering, and completion events when no matches exist.

Additional checks could flag obsolete internal domains or temporary campaign URLs. Those are possibilities, not features delivered in this project. Each proposed rule should have a recognizable problem, a clear correction, and a manageable risk of false positives.

Multiple extensions also need to coordinate the shared options override rather than replace one another's callbacks. The expected completion count must stay aligned with the listeners actually running.

Princeton's custom-test documentation is a useful starting point. Check examples against the installed version, especially when maintaining an older integration.

Give Editors an Actionable Next Step

The value of this extension is specific feedback at the point where someone can act on it. Instead of asking editors to remember every problematic URL pattern, the website identifies one and explains what to change.

Custom tests can support content standards alongside accessibility checks. They do not replace human review or establish accessibility compliance. They make the existing editorial workflow more useful, one well-defined problem at a time.

Philip Stier

13 Oct 2026 8:53pm GMT

Freelock Blog: Drupal Meets Matrix 03 - Better Conversations with Advanced Comment Threads

Drupal Meets Matrix 03 - Better Conversations with Advanced Comment Threads

Drupal Meets Matrix 03

John Locke

Commenting in Drupal hasn't noticeably changed in 15 years. That changes now.

dev corner icon
Dev Corner

13 Oct 2026 5:00pm GMT