Skip to main content
Penyaskito Blog

Main navigation

  • Home
Language switcher
  • English
  • Español
User account menu
  • Log in

Breadcrumb

  1. Home

Drupal

By penyaskito , 18 April, 2026

Your SKILLs don't matter: deterministic checks do

Your SKILLs don't matter

Or better said: you are sharing them with the wrong goal.

Every other LinkedIn/Slack post is talking about LLMs. But most specifically, it's dozens of developers sharing their SKILLs repo as the best SKILLs ever that will make you write the perfect code.

I've written only a very few of them, and I am already tired of copying them over from project to project. So I might create the next best-drupal-skills-ever repo. And you might look at it. But I'm 90% sure it won't work for you. Because my preferences and code quirks aren't yours.

Code standards should be (and they are) enforced. We have PHP_CodeSniffer for that. We have PHPStan for that. Don't write a non-deterministic skill. If you really care about enforcing it, write a deterministic rule. LLMs are pretty good at creating these.

If you can't write a deterministic rule, or you think it's not worth it, probably it's just your personal preference.

Deterministic checks (a Drupal Canvas story)

The Drupal Canvas module has created quite a few phpstan custom rules and phpcs custom rules. 

There's some team consensus on them. We've suffered bugs because of their absence. Most of the time, they are caught in code reviews, but that requires an extra back and forth. With LLMs becoming more and more popular, I'm not discovering anything new to you: the open source bottleneck is code reviews, not creating code. You should avoid at all costs an extra code review.

As an example, we are disallowing implementing hook_schema for Drupal Canvas and its submodules. In this case, we are leaping ahead of Drupal core, but we don't know when that will land and become the standard way in the Drupal ecosystem. We just think it benefits us already, and that becomes our standard. And we deterministically enforce it. Having this as a SKILL would be just useless context 95% of the time, burning your tokens, and only applied to AI-generated code, not any human written code: humans still write code, right? RIGHT?

Share your SKILLs

Don't get me wrong, share your SKILLs. Use permissive licenses for them. Share knowledge with others and learn from others.

But at the end of the day, when the hype ends, I'd expect SKILLs repos to become like dotfiles repos. Everyone has their preferences. Each project has different needs. Starting from someone else's might be a good starting point if you aren't familiar with the tech. But at the end, you MUST customize them to your own preferences and your project needs.

Tags

  • Drupal
  • Drupal AI
  • Drupal Canvas
  • Drupal planet
  • AI
  • LLMs
  • SKILLs
  • phpcs
  • PHPStan
By penyaskito , 13 April, 2026
Image
Generic Feed icon, licensed GNU GPL-2.0-or-later

Droople Reader, my new way of consuming RSS feeds

In my last post, I explained how I leveraged the Dashboard and Aggregator modules for being up to date with the Drupal CMS ecosystem progress. And one of the keys there is that I lack a nice RSS feed reader.

If you've been in the internet long enough, and I ask you what's the product you miss the most, I'm pretty sure 80% of the people would answer Google Reader. It's been already 13 years since Google killed it. Google Reader was absolutely the best Feed reader, and was very successful in converting the reading experience into a social network. You could track your own feeds, but also create conversations around them and read what your friends found interesting. When it died, the communities spread into different alternatives, and for me, nothing compared at all. Google didn't only kill Google Reader, but also my interest in consuming feeds. While other social networks like Twitter became the de-facto (non)standard of connecting with ""feeds"", it never felt the same. And now even Twitter is gone (not dead, but dead in practice).

So for the last years, I've been using this site with the aggregator module. Of course, none of the social features were there anymore, but also the experience was far from ideal.

In the last weeks, I've been playing with LLM assisted code agents (Claude Code). I doubted if I should write a blogpost on my position on them before even hitting publish on this one, but others have done much better. The TL;DR: I don't like it, it's addictive gambling, I mostly don't feel good using it, but I've been getting shit done and my personal usage or non usage of it has zero impact while I have a burger for dinner and buy a new macbook every 5 years. I invite you to get informed about the pros and cons of LLMs and the consequences of adopting them. If those are a lot of links and you only have 1 hour to spare, this video I saw this weekend it's an excellent summary of how I feel about it: How to (Anti) AI Better, by Dr Fatima. The TL;DR of the TL;DR: shaming won't work, AI literacy and understanding the consequences will.

Even if I declare myself a hater-and-late-adopter, unless you've been hiding in a cave, you probably have read that the smaller the task and the more precise you are in your prompts, the better will be the results you get. For myself, adopting my friend Mateu open-source AI-task-manager has made a difference in being disciplined about it.

Here's how I started this weekend.


❯ /tasks:create-plan I'm planning to create a feed reader, as Google
Reader was in the time, where I can mark things as read, so it only
shows the non-read items. I want it to use the aggregator module
under the hood. Start drafting an overall plan.

One of the good things about these skills is that they will question you before moving further:

⏺ I have a few questions before drafting the plan:
⏺ User answered Claude's questions:
 ⎿  · Is this feed reader for you only (single-user, admin-only),
or should it support multiple users each with their own read/unread
state? → Single user (me only)
    · Where should the feed reader UI live? → Admin page only
    · How should marking items as read work? → Auto-read on view
    · Should items be grouped/filterable by feed source, or shown
as a single chronological stream? → Both (filterable)

I never YOLO, so I have the opportunity of giving feedback about every single step, even cancelling them.

❯ I want to track read per user, just in case. For ajax, I want to use the
new htmx api in core. The module name is Droople Reader (machine_name:
drooplereader), a wordplay of the defuct Google Reader. It will be its own
module, and its own git repo. For now create it in the "custom" folder though

This highlighted one of the problems I've found. Sometimes what you feel it's important, can be ignored by the agent. Even if I explicitly say this will be its own repo, it ignored it. And I didn't notice this again until when I was already done!

I had another opportunity though, as this will only draft a Markdown plan that you can ask Claude to edit, or edit manually. Before writing the plan, you will see a preview and you can give more feedback. One thing I had in mind, but I never prompted, is that I had in mind a Single-Page Application built in React. Sometimes hallucinations are not bad, it can actually get creative. One example here is that I didn't think of using the Views module, but it suggested it. I decided to follow that train and I gave this feedback:

❯ When the row scrolls into view I don't want to mark it as read, but at the
end of the post. I didn't say to use views, but that's a good suggestion.
However, we should load a reduced amount of items, and they should load the
next ones that belong to the existing filter dinamically. Each item should
allow me to mark as unread, as I might want to revisit later.

And it questioned me again:

⏺ Good clarifications. Let me make sure I understand the UX correctly
before rewriting the plan.
⏺ User answered Claude's questions:
 ⎿  · For the infinite scroll, how many items should load initially
and per subsequent batch? → 10 initially, 10 more
    · For 'mark as unread', should the item reappear immediately
in the list, or just be flagged for next visit? → Stay in place visually

After that, I get another preview of the plan, including how self-validation will work. Claude tends to create one-off scripts, so I was explicit about this. I could use AI-Task-Manager hook system instead, by editing POST_PLAN.md, but I haven't explored that yet.

❯ For self-validation, I like your suggestion, but it should be
FunctionalTests or KernelTests, as Drupal permits. No one-off tests.
Avoid FunctionalJavascript tests when possible, but you are allowed if
we want to test the htmx interactions.

After this, I get a new draft of the plan. As noted before, the smaller the tasks, the best outputs we will get. After I was satisfied with the overall plan at a high level, it found some minor inconsistencies and self-corrected the plan. Now I was ready to dump MarkDown into my folder, and go for the next step:

❯ /tasks:generate-tasks 5

(5 is this plan id for this project)

As noted before, the smaller the tasks, the better. This will not only divide and conquer, but associate tags to the tasks, so if you happen to use different skills or agents, it will pick the best agent for the job. Each task will be another Markdown file, that you can refine at any point.

⏺ Task generation complete. Created 8 tasks
in .ai/task-manager/plans/05--feed-reader/tasks/

I won't get into the details of each, but here's the summary it presented me with:

Task Group Skills Dependencies
01 - Module scaffolding + ReadTracker backend drupal-backend, database —
02 - Views integration backend drupal-backend 01
03 - Controller + routing backend drupal-backend, php 01, 02
04 - Frontend assets frontend js, css 03
05 - Kernel tests testing drupal-testing 01, 02
06 - Functional tests testing drupal-testing 03, 04
07 - FunctionalJavascript test testing drupal-testing, js 04, 06
08 - Documentation documentation docs 03

Here I found some things that I would have changed. Not lots of them relevant enough, and I was already impatient (remember the gambling mention before? Did you ever heard about tilt?) to see what it will come with. But the only thing that really annoyed me was the usage of twig templates for the UI. I asked Claude to use single-directory components (note I didn't say SDC) instead when possible. Another case where I could have defined extra guardrails with AI-Task-Manager hooks.

❯ For the front-end tasks, you should try to use single-directory
components, to avoid having too much rendering logic into the twig
templates themselves.

It read the necessary context, even to learn that we use the SDC acronym, and updated everything that was affected.

⏺ Now I have a clear picture of how SDC works in modules:
#type => 'component', #component => 'module_name:component_name',
#props, #slots. Let me update the affected tasks.
⏺ Now let me update the tasks. Task 2 no longer needs hook_theme()
since SDC handles that. Task 3 controller uses
#type => 'component' instead of #theme.
Task 4 is restructured around components/ directory.
⏺ Updated the plan and tasks 01, 02, 03, and 04 to use Single
Directory Components. Here's a summary of the changes:
- Plan: Module structure now shows components/reader-page/ and
components/reader-item/ instead of templates/ and css/ directories.
No hook_theme() mentioned.
- Task 01 (scaffolding): Libraries file simplified to just scroll-read
JS library. Directory structure shows components/ instead of
templates/ and css/.
- Task 02 (Views integration): Removed hook_theme() from acceptance
criteria and hooks — SDC auto-discovers components.
- Task 03 (controller): Uses ['#type' => 'component',
'#component' => 'drooplereader:reader-item',
'#props' => [...]] render arrays instead of #theme.
- Task 04 (frontend): Fully restructured around two SDC components
(reader-page and reader-item) with co-located .component.yml, .twig,
and .css files. The scroll-read.js behavior stays as a standalone
library since it's page-level, not component-scoped.

I was satisfied with this, so wanted to move ahead. 

❯ /tasks:refine-plan 04 <--- wrong one!

But I was even more impatient, so I even mistyped the plan id. 🤯 It assumed I meant 5 and asked me for confirmation 🤯 
Then started self-correcting and asked another round of clarification questions:

⏺ Issues found:
1. Plan still references drooplereader-item.html.twig (line 162) in the
"Reader Page and Infinite Scroll" section — should reference SDC
component instead.
2. HX-Location vs HX-Redirect: The plan says mark-all-read uses
HX-Location header, but the task files reference HX-Redirect. These
have different semantics in HTMX — HX-Redirect does a full page load,
HX-Location does an HTMX-driven navigation. For "mark all as read"
where we want a clean page refresh, HX-Redirect is the right choice.
3. Sentinel double-fetch: The buildSentinel() method in the controller
plan calls loadItems() to check if more items exist — this results in
executing the View twice per page load (once for the actual items, once
to check if a sentinel is needed). A simpler approach: always render
the sentinel, and have the load-more endpoint return empty content
(no sentinel) when there are no more items.

I re-triggered the task generation, and it did an analysis (to be fair, I haven't checked yes how it works) to see if it should divide further any task:

❯ /tasks:generate-tasks 05
⏺ Tasks already exist for this plan from the previous generation.
Let me check their current state and regenerate them with the
refinements applied.
⏺ Now running the POST_TASK_GENERATION_ALL hook — complexity review
and blueprint update.
 Complexity sanity check (all tasks ≤ 4):
 - Task 01 (scaffolding + ReadTracker): 2 skills, well-defined — ~3
 - Task 02 (Views integration): 1 skill, moderate — ~3
 - Task 03 (controller): 2 skills, 5 methods but pattern-based
   — 4 (documented)
 - Task 04 (SDC components + JS): 2 skills, 2 components
   + JS behavior — ~4
 - Task 05 (kernel tests): 1 skill, focused — ~3
 - Task 06 (functional tests): 1 skill, 4 test classes
   but formulaic — ~3
 - Task 07 (FunctionalJS): 2 skills, single test class — ~3
 - Task 08 (docs): trivial — ~1
 No task exceeds 5. No merging or splitting needed. The blueprint in
 the plan already reflects the correct 8 tasks and 6 phases. Let me
 verify it's still accurate after refinements.

Finally time to start creating some code... while I went for a hike with my dog 🐕. As it will create a new feature branch, I feel kinda safe, but I still never pre-accept anything:

❯ /tasks:execute-blueprint 05
✳ Create feature branch for plan 05… (49s · ↑ 589 tokens)
⎿ ◼ Create feature branch for plan 05
  ◻ Create module scaffolding
  ◻ Phase 1: Foundation - Task 01
  ◻ Phase 2: Data Layer - Task 02
  ◻ Phase 3: Application Layer - Tasks 03, 05
  ◻ Phase 4: Presentation - Tasks 04, 08
  ◻ Phase 5: Integration Testing - Task 06
  ◻ Phase 6: E2E Testing - Task 07
  ◻ Post-execution validation and archival
  ◻ Implement ReadTracker service › blocked by #5 … +8 pending, 8 completed

After I came back, I noticed that this should be its own git repo and Claude forgot. But I let it continue. 

I started to see some code patterns that, even if not bad per-se, it's not the best way to do things with Drupal Core 11.3. But I don't have any specific Claude skills for Drupal development, so it's definitely good enough. Definitely not worse than what most senior Drupal devs would write. As a simple example, it didn't use services auto-wiring and auto-configuration (Drupal Canvas is going to have a PHPStan rule for this!):

2 drooplereader.read_tracker:
3 class: Drupal\drooplereader\ReadTracker
4 - arguments: ['@database']
4 + arguments: ['@database', '@datetime.time']

When it can parallelize or reduce the required context needed, it will, and even launch subagents in the background.

⏺ Phase 2: Data Layer — Executing Task 02: Views integration. Let me
launch this as a subagent since it's a substantial implementation task.

I won't go into more details of the coding process. I will say though that the SDC components it generated were pretty bad compared to what even a junior Drupal developer might write. Fair enough, front-end is not my fort, I didn't give any details about which components I expected, and how their props and slots should look like. But at this point, I was good with it. I will iterate on this project anyway, and I was willing to see something working (will it work?). Also, in retrospect, there aren't many SDCs in this site, so probably the only examples it could inspect are the SDC core tests ones.

A more worrying matter though, after it finished all the tasks is this response:

❯ Did you ever run the tests?
⏺ No, I didn't. The plan's self-validation section explicitly called
for running the tests, and the POST_EXECUTION hook required it too.
Let me run them now.

It never attempted to run the tests it created! On the other hand, I had some composer dependencies that were blocking installing a phpunit version compatible with Drupal 11.3. It figured out by itself how to resolve the dependencies hell, always asking for my confirmation.

Those tests were good, and detected some issues in the views config it generated. Claude corrected that, and after self-correcting another last issue, all tests passed.

⏺ All 28 tests green across all three levels:
Level Tests Status
Kernel (ReadTrackerTest) 7 Pass
Kernel (ReadStatusFilterTest) 4 Pass
Functional (ReaderPageTest) 4 Pass
Functional (MarkReadEndpointTest) 4 Pass
Functional (InfiniteScrollTest) 4 Pass
Functional (MarkAllAsReadTest) 3 Pass
FunctionalJavascript (ScrollReadTest) 2 Pass
Total 28 All pass

I tested the result in my browser. Astonishing. A couple of bugs here and there, but let's be honest: remember my starting prompt?

❯ /tasks:create-plan I'm planning to create a feed reader, as Google
Reader was in the time, where I can mark things as read, so it only
shows the non-read items. I want it to use the aggregator module
under the hood. Start drafting an overall plan.

That's a pretty high level definition of the requirement! Probably it doesn't even know what Google Reader was (I don't recall Claude asking to search about it). I audited this for security issues, and even if I'm not 100% satisfied with e.g. how it handles controller arguments, there are no security issues.

You can see a quick video of the result here (showcasing some of the bugs too, as not marking as read the last element of the feed):

Remote video URL
Demo of Droople Reader first iteration, purposely including bugs! 🐛

I expected this to be my weekend proof of concept. I was done by Friday 10pm, with a full MVP that I can start using immediately. It took me longer to write this blogpost than the entire process. I didn't go even close to the token limits in the two session usage limit windows this spanned. 

Should you take into account all the ethical considerations before/while/after using LLMs? Definitely. 

Can you get quick good technical results with LLMs? Also true. 

What's next? During the next weeks I plan to solve all the bugs, review all the code again, then review it again one more time, and probably release this on Drupal.org. Would you use it?

Thanks a lot to Mateu "e0ipso" for technical review of this blogpost related to my usage of AI-Task-Manager. 

Disclaimer: Opinions are definitely my own, not Mateu's or my clients as a contractor.

Tags

  • Drupal
  • Drupal planet
  • Claude Code
  • RSS Feeds
  • Droople Reader
  • LLMs
  • AI-Task-Manager
By penyaskito , 11 April, 2026
Image
Screenshot of a Dashboard including the Digest feeds using aggregator

How I keep up with changes in Drupal

I started working with Drupal 15 years ago. I had previous experience contributing to open-source projects, but PHP wasn't my strength, and to be fair, it took me a bit to understand Drupal and most of my work could be done via site building. Some months later, I decided it had to change and attended the Drupal Developer Days 2012 at Barcelona (wow! the site is online! 🤩🤩). There were coding sprints planned on the Drupal 8 Multilingual Initiative, which actually was the beginning of this blog. I blogged about my own progress every day. 

Keeping track of what was going on in an initiative was affordable, thanks to the great job Gábor Hojtsy did leading it. We had IRC, our weekly meetings... I followed the D8MI tag on Drupal.org issues, but that was a manual process. I tried every single thing I could think of for tracking the issues I actively worked on, those that I had an interest in, and those where I would like to help if I had the time. Nothing really worked well for me.

On Jul 1st, 2013 (almost 13 years ago!) I decided to subscribe by email to ALL Drupal Core issues. All, because you cannot subscribe by email to a tag. So it was all, or missing information that I cared about. This was a huge game changer.

First, the filters + labels system I developed — using different tags with associated colors in Gmail — helped me keep track of every issue I was involved in or that had certain tags.

Second, because search is amazingly fast (and works even when there are Drupal.org outages).

And third, because I have a backup of Drupal.org core issues 😜

Image
Tracking Drupal issues with Google Mail tags
Tracking Drupal.org issues with GMail

But the real game changer is seeing things passing by. As you can see, I learnt quickly that infoxication was stressful, and assumed that Inbox-Zero wasn't for me, so I learnt to ignore the number of unread mails. But just by scanning those labels I could have a big picture of what was going on because of the email subject. If something catches my attention, I open the email, learn more about the issue, and there's a high chance I will follow it.

This, plus being on drupal.org and Slack, kept me pretty well informed. So good that this has worked for me for 13 years.

But priorities change, and that an issue exists doesn't always mean that it will land. Tracking what's actually making it into the project is a different beast. I was missing this piece of information between the noise of every single issue. Reading every commit for me was out of the question.

I think it was in 2023 when I met Marco Villegas (marvil07). What a great and passionate guy. So passionate that he shared that he would go through the last commits to Drupal Core, read them, and create and share a journal summarizing what was every commit about. He spoke about it in DrupalCon Barcelona 2024, and you can check his session Following Drupal core development: Is it possible to understand every added change? on YouTube.

But what's a blogpost these days without AI? Dries himself shared recently about his new process for following Drupal projects, and how AI is helping him to summarize the information for the increasing number of projects he needs to track. This is a huge resource. 

For the last month, I often visited his Drupal Digests, and looked around the repo to read the digests, but issue numbers are not super-helpful to keep track. Dries built this to scratch his own itch, so it's highly focused on RSS feeds. And my problem is that I don't really use RSS feeds anymore. Turns out, that wasn't entirely true.

I helped build the Dashboard module for Drupal CMS. There's an aggregator module (used to be, but no longer in Core) that I had installed in this blog, and where I already had some of the feeds I care about. And I visit this blog a lot to create drafts that go nowhere. 1+1 = 2.

So my email process is now complemented by a Dashboard, using the aggregator module provided blocks.
It didn't look pretty, so I had to include some custom CSS. This is how it looks now:

Image
Screenshot of a Dashboard including the Digest feeds using aggregator
Screenshot of a Dashboard including the Digest feeds using aggregator

If you want to replicate this, you'll need to inject a CSS similar to

/*
* Aggregator block theming
*/
.block-aggregator-feed-block {
  margin-block-start: var(--space-s);

  & .item-list ul {
    margin-block-start: 0;
    margin-inline-start: 0.875em;
    list-style-position: outside;

    li {
      list-style-type: none;
      margin: 0 0 0.25em 0.25em;
      padding: 0;
      padding-block-end: var(--space-m);
      padding-inline-end: var(--space-s);
    }
  }

  & a {
    text-decoration: none;
    color: var(--color-absolutezero);

    &:hover {
      text-decoration: underline;
      text-underline-offset: 2px;
    }
  }

  .more-link {
    margin-block-end: var(--space-m);
    margin-inline-end: var(--space-l);

    a {
      text-decoration: underline;

      &:hover {
        text-decoration: none;
      }
    }
  }
}

I considered including this in the Dashboard module styles itself, but might be too much opinionated. What do you think? Edited: created issue to discuss.

And how do you keep track of what's going on in Drupal?

 

Tags

  • Drupal
  • Drupal Core
  • Drupal planet
  • Dashboard Initiative
By penyaskito , 4 April, 2026

Quarterly Contributions summary for 2026 Q1

One year ago I started tracking my own contributions to Drupal.org and posting a report on my Mastodon account. See the last quarter of 2025 report as an example. The goal is not to flex (it would be cheating given that Acquia sponsors me for working on Drupal Canvas almost full time); and this is far from being a good way of tracking contributions or your own productivity, but it's better than nothing. 

Still, it helps me evaluate where I've been focusing (out of necessity, from being nerdsniped, or just for fun), and check if I need to balance that for my "volunteer" contributions. In this last year I've been appointed as Drupal CMS committer (which includes maintainership of 20+ projects 😱😱😱), and Drupal Core subsystem maintainer for Content Translation and Language modules. So tracking where my efforts go is really helpful for self-accountability.

And to be fair, I spent more time maintaining this blog than writing, so finding a new topic that is recurrent is a good way to force me to keep it up to date 😅.

In the last 4 quarters I've been tracking this, it's been ~1 credit per day among all projects. Last quarter I had credits at 1295 issues. As of now, it's 1376. So 81 new credits, vs 93 last quarter, which is a little below 1 credit/day.

Breaking those down:

Canvas: 143 (+61)
Core: 150 (+8)
CMS*: 42 (+4)
Dashboard: 61 (+3)

I also enjoy contributing to projects like DDEV, which helps me learn Golang and clear my mind from working on the same stack. Recently I've been working on Add --project/-p flag to ddev exec command to target a named DDEV project from any directory and it was just merged! 

And I've been pushing a bit this quarter to keep the Drupal Canvas development DDEV add-on up to date, with several improvements and releases.

Hope to write again before July 1st!

Happy coding! 🎉🎉

Tags

  • contributing
  • quarterly-report
  • Drupal
  • Drupal Core
  • Drupal Canvas
  • DDEV
By penyaskito , 30 August, 2025
Image
DrupalCon Barcelona 2024 Drupal CMS Track Leads Keynote participants looking at the podium, where Gábor Hójtsy was introducing the keynote

Catching Up on the Dashboard Initiative

I haven't kept up with updating this blog, so this is a short summary of what happened, and where we are with the Dashboard Initiative.

Our initial goals

When the Dashboard Initiative was announced, the goal was to get this into Drupal Core. 

As with most initiatives, we started in a sandbox, then moved to a contrib module.

Based on the above, our idea was

  • providing a very simple Dashboard framework,
  • according to Drupal core standards,
  • based on layout builder,
  • providing a set of blocks that could cover the requirements for 80% of sites
  • that users would see first thing when they log in to their site,
  • and with nice defaults for the standard profile in Drupal core.

We had weekly meetings, where we worked on defining what the defaults for the Standard profile would be (with Aaron, Cristina and Megh leading the way), while the module was steadily progressing. We attended many events, where we (Cristina, Pablo and I) spoke about the initiative, gathered lots of interesting feedback, and could work on sprints where we got dozens of new contributors to help with the initiative.

Fast-forward to the Drupal Starshot initiative

And that was our plan for DrupalCon Portland 2024. But we were surprised with the Drupal Starshot announcement. Our session about the dashboard, scheduled just after the keynote, was quite an experience for Pablo and me.

The Drupal Starshot initiative has evolved, but its foundation was packaging a new version of Drupal providing a great out-of-the-box experience. So we pivoted and the Dashboard initiative became one of the Starshot Tracks that would become Drupal CMS 1.0.

In a few months we were able to redefine our goals and implement what was needed to launch Drupal CMS on January 2025, which included the Dashboard 2.0.0 first release.

Shortly after, I was appointed as one of the few Drupal CMS committers, which I consider a huge honor. 

Is becoming part of Drupal Core still the goal?

Drupal CMS is the promoted option for downloading on drupal.org. In DrupalCon Atlanta 2025, exploring a marketplace of site templates was announced, which would be based on Drupal CMS 2.0. Given that, having the dashboard as part of Drupal Core shouldn't be a priority, even if it would be satisfying.

In Dries' July 2025 update to the Drupal core strategy 2025-2028, you can find good arguments for both including it or not including it. If I leave my bias aside, I'm 50-50. The tie-breaker would be adoption.

Dashboard adoption

Before 2.0.0 was released, I worked on a proof-of-concept for updating Dashboards with Layout Builder module to be based on Dashboard, to ensure this was possible with an automatic upgrade path. That's feasible, but never really happened.

Of course, Dashboard adoption is great. Even if it's short-lived, since it's part of Drupal CMS and the future site-templates on top of it. So I'm looking at what distributions outside of that are adopting it.

The last releases of the Varbase distribution moved to Dashboard already (and they have been really collaborative on issues on the Dashboard queue, thanks!). 

Drupal Commerce introduced its own dashboard functionality in their 3.x releases [1]. I think adoption on high profile distributions/modules like Commerce would help make the point on having this as part of Core. 

Another case I'm looking at is drupal.org itself. With their upgrade to Drupal 10, it is quite possible some kind of dashboard is needed on drupal.org too for feature parity with what we have today. Opening an issue to see if they already have something in mind is on my to-do list.

What's next then?

If we look at our initial goals, providing a set of blocks that could cover the requirements for 80% of sites is not something I'm looking at right now. Thanks to Drupal's new recipes system, I don't think that belongs in the dashboard module itself anymore, but on dedicated recipes (as Drupal CMS proves) or modules.

We've been working on bugs, minor features (like our new coffee integration!), and keeping up with new core releases and PHP new features. We just released 2.1.0-beta1, which should be shortly followed by 2.1.0.

So to be honest, I don't know what's next. Feedback is welcome on the issue queue or at the #dashboard channel on Drupal Slack.
 

[1] I was corrected that this happened with Commerce 2.37.
 

Photo by Paul Johnson, available for publishing under Creative Commons Licence with attribution via Flickr.

Tags

  • Drupal
  • Drupal Core
  • Drupal planet
  • Dashboard Initiative
  • Drupal CMS
By penyaskito , 22 July, 2023
Image
Two dashboards mockup

Introducing The Dashboard Initiative

Last year, during DrupalCon Prague, Cristina approached me with an idea to include Dashboards in core. We met with Sascha, and since then a team emerged and we have been meeting more or less regularly defining how this would look like, and creating some proof of concepts.

What are we trying to solve?

When you log in to your Drupal site, you land on the /user page. There you can see how old your account on this site is. Useful, huh? Unless you have customized this behavior with contributed or custom modules, now you need to think about why you logged in, and go to wherever you can do what you wanted to do, which usually will take you several steps.

There's a big chance that this journey will start at the Content page, if you are a content manager or a content editor, but you might be a site builder, a site admin, or be responsible for other duties on your website. So we need a landing area where the content shown makes sense based on your recurring tasks. This is where customizable dashboards come into play.

Wearing multiple hats

Users often have multiple roles, or they might want to perform different tasks which might be unrelated to each other. The initial idea was to have a dedicated dashboard for each role.  That evolved into the idea that a user should have access to different dashboards, where groups of tasks and information might be grouped by their nature, not neccessarily by their role. You might wear your content manager hat one minute, and later you might need to perform some SEO duties.

So nothing should block you from having unlimited dashboards, and use the permissions system to give access to them to different roles.

Is this aligned with Drupal core goals?

Drupal Core Product Manager Lauri Eskola recently stated the three tracks were most efforts are concentrating in Drupal Core: 

  • Reduce the time it takes for site builders to become proficient with Drupal.

  • Empower site builders to deliver engaging editorial experiences.

  • Reduce the cost of keeping Drupal applications secure.

Adding dashboards helps with the second track, enabling site builders to make editors´ lives easier by providing customized dashboards based on their editors´ needs. There would be benefits to the other two tracks as well. Having clear journeys on some common tasks for different roles will help site builders to become proficient in Drupal; and can reduce the cost of keeping Drupal applications secure if we surface the need for security updates on the dashboard and make it easy to get up to date with security updates or news from the Drupal project and the Drupal Association.

How to get this into Drupal core

When new ideas go into core, usually they are introduced as Experimental modules, and that's also our aim. Similar to other existing admin tools (like the content listing admin page) in Drupal core, our approach is based on progressive enhancement. This translates to:

  • If you don't enable dashboard, you will be redirected to /user as of right now. Drupal core Standard profile cannot depend on an experimental module, so it won't be installed by default (for now).

  • We will ship Dashboard module with default dashboards for common tasks in core. 
  • If Layout Builder is also installed, you will be able to customize the layouts and blocks of those dashboards on the UI. 

How to get involved?

For now, we've been working in a sandbox, and we also have a GitHub project that contains an easy-to-evaluate site with some demo content, and triggers a Tugboat that we can use as demo or to manually test changes. Thanks to Tugboat.qa for providing that, and James for helping out setting it up!

If you want to help, we welcome you at the #dashboard channel on Drupal Slack.

Thanks to Gábor Hójtsy, Lauri Eskola and Cristina Chumillas for reviewing this blogpost.

Tags

  • Drupal
  • Drupal Core
  • Drupal planet
  • Dashboard Initiative
By penyaskito , 1 May, 2021
Image
XHGui screenshot, showing a debugging session of a Drupal site

Profiling Drupal, WordPress or any php application with DDEV, XHProf and XHGui

I've been a very late adopter of Docker containers. Probably because most of my work in the last years was not dependent on the PHP version, so I used the same PHP version and MySQL/MariaDB as RDBMS every time. For a server I managed I played with LXC as a container system, and served quite well, but I didn't really need to touch it often, and my friend Andrés helped most of the times. Docker seemed confusing to me and, hold my beer, I thought it wouldn't stay, so I didn't really want to learn it. You might say now that my career as seer is over.

Not easily but I got to understand it, and really embraced and loved tools like docker-compose on top of docker. And when I had to work on a Drupal site using Postgres, my best bet was DDEV, abstracting docker-compose complexities but with all the freedom to customize it for your needs.  So that's my platform of choice most of the times in terms of local environments now. And lucky us, it's open source.

And the implicit non-enforced well-citizen contract of opensource is that you have to contribute back if you get the chance to improve it*. In minor contributions I've done before I found the DDEV community really encouraging and welcoming, thanks Randy! So lately I was in the need of  detecting performance bottlenecks in a site, and I've been working on integrating the provided XHProf with XHGui into DDEV. I recently contributed the recipe so you can use it too in less than 5 minutes! See it here: XHGui integration in DDEV documentation. 

* Needed clarification: not saying that you have to give back, not everyone has the same privilege than I do. But *if you did accomplish it already, try to contribute it*. 

If you enable XHProf, already provided with DDEV, it already monitors your application, but you need to collect that profiling report and send it somewhere where you can explore it in a friendly way. That's where perftools/php-profiler comes into play. It has the ability to manage which data you want to profile, and send it to XHGui. XHGui will run on a separate container, will receive the data profiled, store the data in a mongodb database in another container, and render it to you on the browser, where you can see several listings, graphs and images that will help you understand what's going on on your application. You can also compare different requests to a same page, so you see how the performance evolves too. Interpretation of that data is a complex topic on its own, so I won't go deeper here.

So the good news is that you can integrate that now into any project you have with DDEV, in less than 5 minutes. The docs are specific for Drupal 8+ (a composer project) and WordPress (a non-composer project, kudos to roots/bedrock for changing that), so that probably covers examples for any PHP application out there.  Hope this helps!

As a bonus track, I also worked on a DDEV command for enabling/disabling xhprof without having to restart  your project, type a very long command or ssh into the container. That's on that DDEV-contrib page too, but it's probably going to be accepted upstream in DDEV soon too.

Thanks Randy "rfay" Fay, Andrey "andypost" Postnikov and Mateu "e0ipso" Aguiló for the feedback, help and inspiration on working on this! 

Tags

  • docker
  • docker-compose
  • php
  • XHProf
  • DDEV
  • XHGui
  • WordPress
  • Drupal
  • Drupal planet
By penyaskito , 26 April, 2021
Image
Selenium IDE screenshoot, removing spam

A personal site upgrade from Drupal 7 to Drupal 9: some migration tips

Welcome to just another blog with complex infrastructure for just a few visits. It was about time.

This post was intended to be a detailed guide about how I used Drupal migrate tools for upgrading from D7 to D9, but, being fair, it was quite straight forward, so I will just share some tips. Take into account that my last attempt to blog lost its pace quite fast, so I could have been migrating it manually and probably had saved some time. But as someone who contributed to the migrate initiative and the Drupal to Drupal migrations, it's quite a shame that I never actually used it in a real project. 

My source site was a D7 site using the blog module, which has been removed from core in D8. I could just use the contributed version linked above, but I wanted to use an "article" content type from now on. Instead of creating a custom migration, I thought I would give a chance to the Drupal Migrate UI.

So even if we are not using a custom migration and we don't have to think about content mapping and such, there is basic cue that you need to take into account: upgrading your site is the best time for taking the trash out.

Upgrading your site is the best time for taking the trash out. E.g. delete spam.

So first steps would be removing spam. I had used a free Mollom account in the past (RIP, thanks for your service), but I didn't rethink my spam prevention strategy when it was discontinued. Thousands of comments and registered users were in my database, and that was slowing down a lot my first attempts to migrate. I hacked Drupal 7 so the comment and user forms filtered data that I was sure it was spam by altering their queries, and allowing me to delete more content at once. Then I recorded with Selenium IDE some automation for deleting those, as even if scripting or some SQL queries might be faster, sometimes I just enjoy watching the browser do stuff for me.

After that, the process was mostly straightforward. Install Drupal Migrate UI and its dependencies, follow the process and complete. But your content after the migration needs to be audited, so you didn't miss content or config in the process. Specially since the Drupal upgrade process doesn't support rollbacks yet (don't worry if you have your custom migrations, in that case it's supported).

Audit your content after your migration. You might have missed something.

In my case, I had to restart again as my multilingual content was not being migrated. I quickly figured out that the settings must be in place before your content is migrated. Install the multilingual modules if that's your case, and review your translation strategy and the related content translation settings before migrating, e.g. content types and taxonomies. 

If you have multilingual content, review your strategy and according settings before upgrading.

In my case, I had used tags in Spanish and English, and those were not mapped to each other when they were the same concept in the source site. From now on, and thanks to the vast improvements in multilingual support from D8 on, I wanted to change that. I did those mappings by hand, and here we are. 

I picked the new experimental Olivero theme and the new experimental Claro admin theme because they look great, but also because testing them is a good way of helping out them move forward.

I leave for another moment my choice of contrib modules for the site, some issues I needed to workaround by a small custom module, and my infrastructure setup based in docker containers. I promise that I will make that happen before another ton of years pass.

Tags

  • multilingual
  • migration
  • hello-world
  • Drupal
  • Drupal planet
By penyaskito , 10 November, 2012
Image
Penyaskito presenting in front of a blackboard full of math formulaes

Drupalcamp Spain 2012

On October 20th and 21st took place in Madrid the 3rd edition of the biggest Drupal event in Spain, Drupalcamp Spain 2012. On Saturday I participated on a panel with Pedro Cambra, Ramon Vilar, Juampy Novillo and José Reyero about how to contribute to Drupal, with modules, themes, translations, documentation, marketing, events... The slides we used as guide are available on Slideshare:

Contribuir en Drupal: Por dónde empiezo? from Christian Lopez

On Sunday, I made a session where I tried to explain the changes in multilanguage between Drupal 7 and Drupal 8, that will be a reality hopefully on August 2013. The slides are also available in Slideshare:

Multilenguaje en Drupal 8 from Christian Lopez

The videos of every session will be available soon at the Vimeo channel of the Spanish Drupal Association.

That weekend took place the first Assembly of the Spanish Drupal Association, where I was nominated as a Board Member. I hope to contribute with them spreading Drupal use in Spain.

And after a very busy weekend, a plane to Frankfurt. But that's part of another story.

Post image: Some rights reserved by Pedro Lozano

Tags

  • Drupal
  • Drupalcamp
  • Drupalcamp Spain
  • AED
  • multilingual
  • contributing
  • sessions
  • slideshare
  • Drupal planet
By penyaskito , 24 September, 2012

Git workflow with submodules for Drupal deployment

Maybe you've seen the great article on Drupal Deployment with Git Submodules, by Randy Fay. I manage this site using that strategy, but some times I forget how every operation is done. So here I'm collecting them for my own reference.

For fetching all the new info from submodules: 

git submodule foreach git fetch origin

Now we go into each module folder and use:

git pull 

If we wanted to switch to a different branch, we should use:

git branch -a # we see the available branches 
git checkout 7.x-2.x # the different branch 

For committing it, we go back to the contrib folder and do:

git add contrib-module-name 

Then, we use:

drush updb --debug -y 

Maybe we see some warnings because of unresolved dependencies. In that case, add the new submodule:

git submodule add --branch 7.x-1.x git://git.drupal.org/project/entity.git sites/all/modules/contrib/entity 

Finally, updating core:

git merge drupal/7.x drush updb --debug -y 

Ok, so we've done this on our DEVELOPMENT site. If everything is OK, now it's time to update the server, after doing a backup:

git pull
git submodule update --init 
drush updb --debug -y

Tags

  • git
  • git submodules
  • workflow
  • Drupal

Pagination

  • 1
  • Next page
Drupal

Monthly archive

  • April 2026 (4)
  • August 2025 (1)
  • April 2025 (1)
  • July 2023 (1)
  • December 2021 (1)
  • May 2021 (2)
  • April 2021 (1)
  • September 2014 (1)
  • November 2012 (1)
  • September 2012 (2)
  • August 2012 (3)
  • June 2012 (6)

Recent content

Your SKILLs don't matter: deterministic checks do
2 days ago
Droople Reader, my new way of consuming RSS feeds
1 week ago
How I keep up with changes in Drupal
1 week 2 days ago

Recent comments

That's a great idea! I would…
2 days ago
D.org integration
4 days 22 hours ago
Can't blame you 😜For me…
5 days 21 hours ago

Blogs I follow

  • Mateu Aguiló "e0ipso"
  • Gábor Hojtsy
  • Pedro Cambra
  • The Russian Lullaby, davidjguru
  • Can It Be All So Simple
  • Maria Arias de Reyna "Délawen"
  • Matt Glaman
  • Daniel Wehner
  • Jacob Rockowitz
  • Wim Leers
  • Dries Buytaert
  • arcturus
  • Drupal Core AI digest
  • Drupal CMS AI digest
  • Drupal Canvas AI digest
  • Drupal AI AI digest
  • Drupal Patterns AI digest
  • Trisha Gee
  • Très Bien Tech, by _nod
  • Moshe Weitzman
  • Drupal core change records
  • Ed Zitron's Where's Your Ed At
  • Sebastian Bergmann (phpunit.expert)
  • PHP Reads
Syndicate

Footer

  • Drupal.org
  • LinkedIn
  • GitHub
  • Mastodon
  • Twitter
Powered by Drupal

Free 🇵🇸