27 Aug 2026

feedDrupal.org aggregator

LakeDrops Drupal Consulting, Development and Hosting: Six Small ECA Models That Make Drupal Editors Happy

Six Small ECA Models That Make Drupal Editors Happy

Small improvements at the content editor's desk accumulate into a better CMS.

Jürgen Haas

This article introduces six new ECA Guide library recipes that improve the Drupal content editing experience through small, focused changes. They can draft metadata on first save, add access-aware edit links to teasers, prevent invalid dependent select values, offer field-level actions, fill several form fields without saving, and show contextual guidance beside a form. The point is not to apply all six recipes unchanged. They are well-architected starting points for a real editorial irritation. For editors, that means less repeated work and fewer avoidable mistakes. For organisations, it means more consistent content and a practical route to improving the CMS without turning every detail into a custom development project. The article also gives a simple choice: Field Widget Actions for one field, Form API Ajax for several form fields, and HTMX endpoints for nearby content. Production concerns still matter, especially permissions, validation, managed data, and AI review.

27 Aug 2026 3:30pm GMT

Berliners blog: Rebuilding a data-driven Drupal site: From ctools plugins to Layout Builder blocks

Rebuilding a data-driven Drupal site: From ctools plugins to Layout Builder blocks

In the previous post, I described why we chose Layout Builder and how Layout Builder IPE restored the frontend editing workflow we had used with Panels IPE.

With the editing workflow in place, we still had to rebuild the elements that editors placed on their pages.

The Drupal 7 site used custom ctools content type plugins for maps, charts, figures, lists and tables. Editors placed and configured these plugins, while the plugins retrieved the information and rendered the result. I will call both these ctools plugins and the block plugins that replaced them page elements.

berliner

27 Aug 2026 1:06pm GMT

Specbee: 16 Drupal AI modules that can make your website smarter

We rounded up 16 Drupal AI modules and sorted them for you. Deploy now, pilot on staging, or just keep an eye on it. Check it out!

27 Aug 2026 6:25am GMT

DDEV Blog: DDEV August 2026: Star Us on GitHub, PhpStorm Plugin Comes Home

Nancy Lewis: Corn Lake Park in Clifton, Colorado, watercolor painting of a river bend lined with trees and mountains in the background

Help DDEV Grow: Star Us on GitHub

If you use DDEV, a simple way to mention the project is to star the GitHub repository. Head over to github.com/ddev/ddev↗ and click Star. It takes five seconds, and it can help us - a star count is one of the things new users, sponsors, and and AI check before trusting an open source tool. If you're already a star, thank you!

DDEV IntelliJ/PhpStorm Plugin Lands in the DDEV Org

The DDEV Integration plugin for IntelliJ/PhpStorm↗, maintained by @AkibaAT, has been transferred into the ddev GitHub organization. This was on our 2026 plans list, and it's great to see it land. Awesome maintainer AkibaAT has kept the plugin in excellent shape, and this move gives it a permanent home alongside the rest of the DDEV ecosystem.

What's New on the Blog

Community Highlights

Knecht.works Ships Sandbox Rollback - Following up on last month's beta-tester call, the team at knecht.works has added sandbox rollback to their agency dashboard, letting each automated DDEV run boot into its own disposable environment. Read the update↗

TYPO3 Snapshot: Pull and Anonymize Production Data Locally - Ramon Herrmann released Snapshot, an open-source TYPO3 extension that pulls databases and fileadmin from live/staging into a local DDEV environment, with built-in anonymization for GDPR compliance. Read the announcement↗

Quick DDEV Previews: A Self-Hosted Preview Service - Matthias Andrasch built a proof-of-concept service that spins up DDEV preview environments from any branch of a connected GitHub repository, based on Samuel Reichör's technical work. Screencast: Using it on Hetzner VPS↗View the repo↗

Community Tutorials from Around the Web

DDEV Training Starting Up Again This Fall

Live training is back for the fall, three sessions open to everybody.

Upcoming DDEV Live Contributor and User Training Sessions

Zoom Join Info:
Link: Join Zoom Meeting
Passcode: 12345

Events & Community

DrupalCamp Tokyo 2026 - ANNAI presented on AI-driven Drupal development and sustainable open-source CMS strategy, including using DDEV with git worktree to run parallel Drupal environments. Read the report↗ (Japanese) - for English coverage of git worktree with DDEV, see Contributor Training: git worktree for Multiple DDEV Projects and Using git worktree with TYPO3.


Governance


Sponsorship Update

A steady month - thank you to everyone who contributes!

July 2026: ~$9,931/month (82.8% of goal)

August 2026: ~$10,038/month (83.7% of goal)

If DDEV has helped your team, consider sponsoring. → Become a sponsor↗

Contact us to discuss sponsorship options that work for your organization.


Stay in the Loop-Follow Us and Join the Conversation

Compiled and edited with assistance from Claude Code.

27 Aug 2026 12:00am GMT

26 Aug 2026

feedDrupal.org aggregator

Gspikes: Drupal vs WordPress Performance: What Core Web Vitals From 2.9 Million Sites Actually Show

We analyzed 79 months of Chrome UX Report field data covering every Drupal and WordPress site Google measures - 2.9 million origins in July 2026 alone. Drupal has led on Core Web Vitals in every single month since 2020, and the entire gap traces to one metric. The numbers, the honest caveats, and what to fix on whichever platform you run.

26 Aug 2026 11:43pm GMT

The Drop Times: DrupalCamp Colorado 2026 Puts Long-Term Drupal Practice in Focus

A training day can introduce a workflow. Thursday's speakers are asking what happens when Drupal systems must survive staff turnover or move content safely between environments.

26 Aug 2026 2:59pm GMT

Omega8.cc: Drupal CMS Runs on Ægir

Waiting for your hosting panel to grow a Drupal CMS platform? The wait ended in late 2025: it has been running on Ægir for many months, rebuilt from the upstream Composer template as BOA releases ship, tracking the version the Drupal project currently publishes. Enabling it is one symbol in a platform list your account already carries, installing a site on it is the usual short panel task, and one honest warning applies: the interactive browser wizard does not run here, the complete package installs unattended, and the deliberately plain front page it greets you with is exactly what a healthy install looks like. From that minute the machine treats it as a normal Drupal 11 site: nightly backups, one-task HTTPS, cloning, Drush, and calm platform-to-platform updates by design - on a server where Pressflow 6, Drupal 7 and Backdrop veterans still serve next door, because continuity here means the whole line stays alive at once.

26 Aug 2026 2:10pm GMT

Stuart Clark (Deciphered): Drupal site settings over JSON:API, per consumer

In April 2022 I wrote about decoupling configuration with Config Pages, and ended it with a guess at where I'd go next:

One of my future experiments with Druxt will be to look at the options of using the Drupal Consumers module alongside Drupal theme settings as a solution.

That experiment is now a module. Decoupled Settings serves the site and theme configuration Drupal already holds over JSON:API, and lets every frontend override just the values it needs. It went up on Drupal.org this week.

Core's JSON:API is an entity API. Content entities and config entities alike, so node types, image styles and views are all in there. What it has never exposed is simple configuration, and there's a good argument that it shouldn't by default, because plenty of what sits in system.site is nobody's business.

But a decoupled frontend still needs the boring stuff:

So every decoupled build solves it locally, and most of the ways to solve it end up keeping a second copy of the site name somewhere.

Continue reading →

26 Aug 2026 9:20am GMT

Dries Buytaert: Finding related posts with embeddings

I added a new feature to my blog: a list of related posts at the bottom of each post. I implemented it using embeddings, and this note documents how.

I looked at how other content management systems identify related posts: most use shared tags, backlinks, manual curation, or embeddings. I chose embeddings, which compare the meaning of each post, because they can uncover connections without shared tags, existing links, or manual curation.

Embeddings turn meaning into numbers

An embedding model reads text and returns a vector: a long list of numbers. The model I use, bge-base-en-v1.5 from the Beijing Academy of Artificial Intelligence (BAAI), returns 768 numbers for each post. I started with a smaller model that returns 384 numbers and moved up because the matches were better. BAAI's own benchmarks point the same way, though the gap is modest.

You can think of those 768 numbers as coordinates in a high-dimensional meaning space, where each dimension captures some pattern the model learned from text. For one of my posts, the first handful of those coordinates looks something like this:

[ 0.021, -0.045, 0.038, -0.012, 0.007, ..., 0.019 ]   (768 numbers total)

Conceptually, it is a bit like tagging each blog post with hundreds of auto-generated tags, except that these tags are unnamed (they are just numbers) and distributed (meaning is spread across all of them). Together, the 768 numbers place the post near other posts with similar meaning.

This is what lets two posts match even when they use different words. During training, the model learns that certain words and phrases appear in similar contexts or play similar roles, so it places them near each other in the space. It does not need "car" and "automobile" to share any letters to learn that they are used in related ways.

Raw cosine similarity makes everything look related

Once every post has an embedding vector, the next question is how to compare them. This is where I had to dust off a little math. Fortunately, it turned out to be mostly high-school math: averages, angles, and multiplication.

The standard way to compare two vectors is cosine similarity. Imagine each vector as an arrow pointing away from the origin. Cosine similarity measures the angle between two of these arrows and then takes the cosine of that angle, which is where the name comes from.

Two arrows pointing almost the same way sit at a small angle, and the cosine of a small angle is close to 1, so the posts are related. As the arrows spread apart, the cosine falls: at a right angle it is 0, and for arrows pointing in opposite directions it drops to -1, so unrelated posts score closer to 0 or even negative.

In practice, these raw cosine values can be misleading, because embedding models rarely spread their vectors evenly in every direction. They tend to pack most vectors into a narrow cone, a property called anisotropy, so the scores cluster in a high, narrow band. On my blog, the raw cosine similarity between two randomly chosen posts is almost always between 0.5 and 0.75, with a median of 0.64.

The practical effect is that almost any two posts look somewhat similar. An old post about the founding of Acquia shows the problem. It covers a lot of ground: Drupal, my PhD, Red Hat and IBM backing Linux, venture capital, and personal reflection. Because it touches so many subjects, its vector sits close to the average of all my posts, and it scored high against almost the entire archive. Its best match scored 0.876, and its hundredth best still scored 0.770.

Mean-centering reveals what makes each post distinct

Anisotropy has several known fixes, from lightest to heaviest. The lightest is mean-centering, which is what I use and what the rest of this section explains.

All-but-the-top removes the average and the next few strongest directions. Whitening stretches the space so every direction carries equal weight (the name comes from white noise). I have not tried these others. Mean-centering is one subtraction per vector with no matrix algebra, which keeps the code plain PHP, and it was enough.

You compute the average vector across all posts and subtract it from every post's vector. Subtracting the average vector from each post removes what all posts have in common, so what remains is what makes each post distinct. That average points down the middle of the cone, the direction my whole blog tends to lean.

A modern model like bge-base-en-v1.5 already suffers less from anisotropy than older or simpler encoders: it is trained with contrastive learning, which pushes unrelated texts apart, and version 1.5 was tuned specifically to spread out its similarity scores. On my corpus, centering still made the scores much more useful.

An example might help. Imagine three posts with only two numbers each instead of 768:

A = (0.90, 0.10)
B = (0.85, 0.80)
C = (0.80, 0.75)

At first glance, all three posts look somewhat similar. In every post the first number is high and close to the others (0.90, 0.85 and 0.80), so it dominates the comparison. But a number that barely changes from post to post tells you little about how they differ, so that first number is not very useful.

The average (mean) of the three vectors is:

mean = (0.85, 0.55)

Now subtract that average from each post:

A = ( 0.05, -0.45)
B = ( 0.00,  0.25)
C = (-0.05,  0.20)

Now the picture is clearer. B and C both have a positive second number, so they point in roughly the same direction; A's second number is negative, so it points somewhere else.

Before centering, everything looked similar. After centering, the comparison focuses on what is different from the average.

Normalization reduces comparison to a dot product

After centering, each vector has a length as well as a direction. Length says how far a post sits from the average, and direction says in what way it differs.

I want to rank posts by what they are about, not by how unusual they are, so only the direction matters. Hence, we normalize each vector by dividing it by its own length, which scales it to length 1 and moves it onto the unit circle (or, in 768 dimensions, the unit sphere), leaving only its direction.

It also makes the comparison cheaper. Cosine similarity is normally the dot product divided by the product of the two vectors' lengths. If both vectors have length 1, that denominator is 1 × 1 = 1, so the expression reduces to the dot product alone: multiply the two lists number by number, then add the results.

Using the same example, the centered vectors for B and C are:

B = ( 0.00, 0.25)
C = (-0.05, 0.20)

First, normalize each vector to length 1. A vector's length is the square root of the sum of its squared numbers (good old Pythagoras, only with more numbers). B has length √(0.00² + 0.25²) = 0.25, while C has length √((-0.05)² + 0.20²) ≈ 0.206, so dividing each vector by its own length gives:

B ≈ ( 0.00, 1.00)
C ≈ (-0.24, 0.97)

Then take the dot product:

(0.00 × -0.24) + (1.00 × 0.97) = 0.97

That is a strong match: the closer the score is to 1, the more the two posts point in the same direction. B and C are nearly aligned.

A, after normalization, points mostly downward. Next to B:

A ≈ ( 0.11, -0.99)
B ≈ ( 0.00,  1.00)

Multiplying them the same way:

(0.11 × 0.00) + (-0.99 × 1.00) = -0.99

That is not a match at all.

The PHP code is shorter than the explanation

The production code does the same arithmetic, just with 768 numbers per post instead of two:

public static function center(array $raw): array {
  if ($raw === []) {
    return [];
  }
  $mean = array_fill(0, count(reset($raw)), 0.0);
  foreach ($raw as $vector) {
    foreach ($vector as $i => $value) {
      $mean[$i] += $value;
    }
  }
  $count = count($raw);
  foreach ($mean as $i => $sum) {
    $mean[$i] = $sum / $count;
  }
  $centered = [];
  foreach ($raw as $nid => $vector) {
    $norm = 0.0;
    foreach ($vector as $i => $value) {
      $vector[$i] = $value - $mean[$i];
      $norm += $vector[$i] * $vector[$i];
    }
    // A vector sitting exactly on the mean centers to zero; fall back to 1.0
    // so the division below never hits a zero norm.
    $norm = sqrt($norm) ?: 1.0;
    foreach ($vector as $i => $value) {
      $vector[$i] = $value / $norm;
    }
    $centered[$nid] = $vector;
  }
  return $centered;
}

public static function topMatches(array $source, array $pool, int $self): array {
  $scores = [];
  foreach ($pool as $nid => $vector) {
    if ($nid === $self) {
      continue;
    }
    $similarity = 0.0;
    foreach ($source as $i => $value) {
      $similarity += $value * $vector[$i];
    }
    $scores[$nid] = $similarity;
  }
  arsort($scores);
  return array_keys(array_slice($scores, 0, 3, TRUE));
}

While my explanation was long, both PHP methods are relatively short. In center(), each vector has the corpus mean subtracted, then is divided by its own length. In topMatches(), I calculate the cosine similarity between one post and every other post, then keep the three highest.

You might expect a vector database to replace all of this. It would replace some of it: storing a vector and asking for the closest three would remove topMatches(), but it would not remove center(). Centering is optional, but it meaningfully improved my results.

A vector database likely makes centering harder. Today I store raw vectors and subtract the average when I compare them, so a new post does not change anything I have stored. A vector database would search what I stored, so the subtraction would have to happen before storing. I'd have to update all stored vectors for every new post or every edit, which feels more complex. Maybe vector databases have a good answer for that; I have not looked.

One-time embeddings, occasional ranking

You might wonder how expensive it is to generate these embeddings and compare all these vectors. It turns out to be fast and cheap.

There are two kinds of work, and they happen at different times. Generating an embedding calls an AI model, but happens only once after a post is created or edited. Ranking uses ordinary PHP arithmetic and happens occasionally, when Drupal rebuilds a page's cached related-post list.

I run the model on Cloudflare Workers AI. To generate an embedding, my server makes an HTTPS call that passes the post's text to Cloudflare, which runs the model and returns the 768-number vector. That round trip takes about 250ms. It happens on the first view after a post is created or edited, and the vector is then cached. The model is deterministic, so the same text always produces the same 768 numbers.

Cloudflare bills Workers AI usage in units it calls Neurons and includes 10,000 free each day. Embedding my full archive of roughly 1,500 posts used roughly 4,000 Neurons, and a new post costs about three. Embedding my blog is basically free.

Calculating the related posts never calls the AI model. It all happens in Drupal, my website's content management system. When Drupal needs to build one of the related posts lists, it loads all the stored vectors, centers them, and scores the current post against all the others: roughly 1,500 dot products, each over 768 numbers. This takes around 250ms on my site. After a list has been built, it is cached.

In other words, my website never loads model weights; it just stores the 768 numbers that come back. The machine-learning compute lives at Cloudflare's edge, and my server stays a plain PHP application. None of this needs a vector database or a machine-learning framework: one HTTP call generates the embedding, a key-value store caches it, and a few dozen lines of arithmetic choose the related posts.

Tags are too blunt, backlinks only capture the links I remembered to make, and manual curation does not scale. All three need me to notice the connection first. Using embeddings might sound a bit scary, but they turned out to be easy to implement, fully automated, and able to surface posts I would never have thought to link.

26 Aug 2026 8:40am GMT

Très Bien Blog: A tool to painlessly update a heavily patched Drupal site

A tool to painlessly update a heavily patched Drupal site

Picture a Drupal 10.6 website with a several months stale composer.json: 120 contrib modules, 47 patches. You need to update it to Drupal 11.4. Many hours will be spent checking I don't want to deal with this several times a year so I improved the Drupal-Code-Query MCP server with a few more tools.

theodore

26 Aug 2026 8:35am GMT

Tag1 Insights: A Warm Afterglow from Laracon US 2026

Moshe Weitzman, Sr. Architect & Project Lead at Tag1 and the first American to contribute to the Drupal platform, attended LaraCon US 2026 in Boston and shares the concrete takeaways.

Laracon US came to my hometown of Boston this year, and a few weeks later I'm still glowing. Here are the moments that stuck with me.

Whimsy-Driven Development

My favorite session was Whimsy-Driven Development by Christina Martinez. Watch it if you want to rekindle the joy of building software. We can build anything we can imagine today, and Christina gives us permission and encouragement to do exactly that. I joined her Silly Software Club on the spot. I haven't built any silly software yet, but I did make a silly image announcing my blended family's upcoming vacation to Mexico.

Moshe's family beach photo, mariachi-style: sombreros, guitars
Moshe's family beach photo, mariachi-style: sombreros, guitars. Akumal 26' Mas guacamole por favor.

The Vibes

The day after Laracon wrapped, I attended The Vibes, a daylong summit about NativePHP. NativePHP is an epic piece of software that lets PHP developers build fully native mobile apps, with no web view required. What I loved most was the kindness and enthusiasm of the project's leaders, Simon Hamp and Shane Rosenthal, who walked us through NativePHP like proud parents. The pride was earned. If anyone has a silly mobile app idea, let's build it together.

The Vibes logo

Laravel and Drupal, Compared

I spend most of my time in the Drupal world, so I couldn't help comparing. The two projects have a lot in common: both are mature open source projects with deep communities. Drupal launched in 2001 and Laravel in 2011, making them 25 and 15 years old. I think Laravel's velocity outpaces Drupal core's. Drupal has more contributors, yet somehow ships less. Some of that is by design: Drupal core emphasizes process: coding standards, esoteric workflows (like issue forks), code review gates, strong backward compatibility. That discipline has real benefits, and it attracts contributors who value it, though others gravitate toward contrib, where the pace is faster. Laravel, by contrast, runs on a "we must ship" mantra. There's something to learn from both cultures. I commend Taylor Otwell for his relentless focus on shipping. It's paying off.


Image credit: Meet Boston

26 Aug 2026 12:00am GMT

25 Aug 2026

feedDrupal.org aggregator

The Drop Times: Rybbit Analytics Maintainer Explores Embedded Dashboards and No-Code Event Tracking for Drupal

For Drupal sites with logged-in experiences, the integration can use existing user attributes to segment journeys and activity, extending Rybbit beyond anonymous traffic reporting.

25 Aug 2026 1:52pm GMT

Specbee: Are you building a Drupal module that already exists? Meet Module Scout

Building a Drupal module? We built Module Scout that uses AI to search Drupal.org's live project directory and help you find existing modules before you start from scratch.

25 Aug 2026 10:21am GMT

Webpro Company blog: When a Drupal module becomes unsupported because of a security risk

On 19 August 2026, the Drupal.org security advisory page included several contributed projects that the security team marked unsupported because of known security issues. That is not just another update notice. A site owner needs to know whether the module is used on their site and what to do when there is no fixed release. On 19 August 2026, the Drupal.org security advisory page listed several contributed projects that were marked unsupported because of security issues. Examples included Screenshot, Link content parser and Gammu SMS Daemon. A week earlier, advisories also included Quick Tabs, External Authentication, Entity Share Websub, Diff and Commerce PayPal. Not every advisory affects every Drupal site. Some modules are very specific. Some risks apply only under certain…

25 Aug 2026 6:00am GMT

Peoples Blog: If AI Can Build an Application, Why Do We Still Need Software Developers?

If AI can build an application from a simple description, why do we still need software developers?It is a question I have been thinking about recently. AI can now generate code, create interfaces, work with databases, connect APIs and turn an idea into a working prototype surprisingly quickly. I use AI in my own development work, and it has changed the way I build things. Tasks that once took hours can often be completed much faster, and experimenting with new ideas has become much easier.

25 Aug 2026 4:09am GMT

Cheppers: ExperienceKit: Why University Websites Break at Scale, and How to Fix It

No one decides to have an inconsistent university website. It happens one reasonable decision at a time: a department needs a page and the central team is booked, so a local admin builds it. A lab hires a student to make something "more modern." A program office, tired of waiting, spins up a page builder subscription on a corporate card. Each choice makes sense in the moment. Sum a decade of them across two hundred departments, and you get the site every university web team recognizes: thousands of pages, dozens of visual dialects, and a governance document nobody has opened since it was ratified.

25 Aug 2026 12:00am GMT