I'm blogging about Emacs, Drupal, php and exciting subjects

PHP Readonly Classes and Immutable Data Patterns

Readonly properties arrived in PHP 8.1. Readonly classes — where every property is implicitly readonly — arrived in PHP 8.2. Together they enable a clean immutability model for value objects, DTOs, and configuration records without boilerplate. This article covers the full semantics, all the sharp edges, how to implement "wither" patterns for functional updates, and how Drupal codebases can adopt these patterns today.

Setting Up Emacs for PHP Development: LSP, Tree-sitter, and Xdebug

Emacs is a serious PHP development environment once you wire the right packages together. This guide covers a complete, production-grade Emacs setup for PHP in 2026: language server integration with Eglot, Tree-sitter syntax highlighting, code formatting, and step-through debugging via DAP Mode and Xdebug 3. All configuration targets Emacs 29+ with use-package.

Drupal Views: Advanced Techniques for Custom Displays and REST Exports

Views is the most used module in the Drupal ecosystem and also the most underused — most developers barely scratch the surface of what it can do programmatically. This article covers the techniques that move you beyond the UI: contextual filters with argument validation, relationship chaining, REST and JSON:API-style exports, Views hooks, and generating view output programmatically in custom code.

Headless Drupal with Next.js: A Practical JSON:API Integration Guide

Decoupled Drupal separates the content management backend from the presentation layer. Drupal handles content modelling, editorial workflows, and permissions; Next.js handles rendering, routing, and performance. The bridge between them is Drupal's JSON:API module, which ships in core and exposes every entity type as a standardised REST API with zero configuration. This guide covers everything you need to go from a fresh Drupal install to a working Next.js frontend that statically generates content at build time and revalidates on-demand.

PHP OPcache Configuration for Production: Tuning for Maximum Performance

OPcache is the single most impactful PHP performance setting you can tune. Without it, PHP parses and compiles every script on every request. With a well-tuned OPcache, compiled bytecode is served from shared memory — no disk reads, no compilation. This guide covers every production-relevant directive, preloading for Drupal/frameworks, JIT configuration for PHP 8+, and the Docker-specific concerns that trip up most setups.

Drupal Migrate API: Importing Content from CSV and Legacy Databases

The Migrate API is the canonical way to move data into Drupal 11 — whether that means a one-off CSV import, a recurring feed from a legacy database, or a full Drupal 7 upgrade. It implements an ETL (Extract–Transform–Load) pipeline via plugins, and every step is swappable. This article walks through two real scenarios: importing nodes from a CSV file and pulling records from a legacy MySQL database.

Core Concepts

Every migration is a YAML configuration entity composed of three sections:

Nginx Rate Limiting: Protecting Your API and Login Pages from Abuse

Brute-force login attempts, credential stuffing, and API scraping are routine threats for any public-facing server. Nginx's built-in rate limiting module stops these attacks at the edge — before PHP even starts. This guide covers the full directive set, burst configuration, exempting trusted IPs, protecting Drupal's login and JSON:API endpoints, and avoiding the most common misconfiguration that lets bursts overwhelm your server.

Composer Autoloading Deep Dive: PSR-4, Classmap, and Files Strategies

Most PHP developers know just enough about Composer autoloading to make it work. But when class resolution fails in a Drupal module, a package publishes duplicate class definitions, or a legacy library throws "class not found" mid-request, you need to understand what the autoloader is actually doing. This article covers all four autoloading strategies, how they interact, and the performance trade-offs that matter in production.

Drupal Custom Theme from Scratch with Twig in Drupal 11

Drupal 11's theming system uses Twig 3, a modern templating engine that keeps logic out of templates and makes overriding core HTML straightforward. The recommended starting point is the Starterkit — a generator that scaffolds a fully functional sub-theme from Drupal core's stable base, so you own all the HTML from day one without inheriting any styles you did not choose.

Interaction to Next Paint (INP): What Developers Need to Know and Fix

Interaction to Next Paint (INP) replaced First Input Delay (FID) as a Core Web Vital in March 2024. Where FID only measured the delay before the browser started handling the first interaction, INP measures the full latency of every interaction on a page — from user input to the next visual update. A slow click handler that blocks the main thread for 300 ms will generate a poor INP score even if FID was perfect.

The threshold: good is 200 ms or below, poor is above 500 ms. Measured at the 75th percentile across all interactions in a session.

Subscribe to