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

Drupal's default robots.txt stops working when you add a second language

Drupal ships a sensible robots.txt. It blocks the admin paths, the login and registration forms, the search pages, and the node creation forms. For a single-language site it does the job.

I run a site in Danish and Swedish. On that site, almost none of those rules do anything.

The proof

Google open sourced the matcher that Googlebot uses, and there is a Python port of it. So this is not an interpretation of the specification. It is the actual matching code, run against Drupal's actual default file.

Puppet to Ansible: how the concepts map, and where the mapping breaks

Both tools do the same job. You describe how a machine should be configured, you keep that description in version control, and the tool makes the machine match. Most of what you learned from Puppet still applies.

The problem is the part that does not. Four differences are structural rather than cosmetic, and each one produces a specific kind of bad Ansible that is written almost exclusively by people who know Puppet well. This article covers the mapping first, then the four places where the mapping actively misleads you.

Adding a second OpenSearch node: what you get, and what you don't

I have two servers and one OpenSearch node. The obvious move is to put a node on the second server and call it a cluster.

That works, and it is worth doing. But it does not give you high availability, and the reason is counterintuitive enough that a lot of people find out during their first outage. So this article covers the setup and the limitation together.

I allowed every crawler, and half of them still backed off

My robots.txt blocks nothing. Every page carries a meta robots tag permitting indexing. Google crawls the site happily and indexes almost everything within a few days of publication.

And when an AI assistant tried to read one of my articles, it was refused.

Not throttled, not rate-limited — refused, with a robots-level rejection, on a URL that no robots directive anywhere on my site excludes. The homepage fetched fine. Article pages did not. Google saw no problem at all.

Addresses you're allowed to write down: documentation ranges and the rest of the reserved map

Every example IP in the previous article was 203.0.113.10. That is not a number I invented, and it is not a real server. It comes from TEST-NET-3, one of three IPv4 ranges the IETF reserved specifically so that technical writers have addresses they can safely put in front of readers.

The reason these exist is not tidiness. It is that documentation leaks into production, reliably and at scale, and an address in an example is an address someone will eventually paste into a config file.

Bootstrapping a new server: the first fifteen minutes

You have a fresh Ubuntu box and a root password in an email. Everything you know about infrastructure says configuration should be codified, reviewed, version-controlled and applied by a tool. And none of that helps yet, because Ansible needs SSH access, a user, and a Python interpreter — none of which exist.

Cross-encoder reranking: what it costs, and whether you need it

Reranking is usually introduced as the next thing you add after hybrid search. Retrieve broadly, then rescore the top candidates with a model that reads query and document together. Relevance improves, everyone is pleased.

The part that gets skipped is that you have just put a transformer forward pass into your request path — once per candidate, on every search. So let us start with the bill.

Your robots.txt probably doesn't block Google from what you think it does

Here is a robots.txt that appears in some form on a very large number of sites:

User-agent: *
Disallow: /admin/
Disallow: /private/

User-agent: Googlebot
Disallow: /nogoogle/

Read it the way anyone would: everyone is kept out of /admin/ and /private/, and Googlebot is additionally kept out of /nogoogle/.

That is not what it says. Googlebot is free to crawl /admin/ and /private/, and Bingbot is not.

Dependency inversion in Symfony: what autowiring made easy, and what it made optional

Autowiring is one of the better things to happen to PHP. Typehint a class in a constructor, and Symfony finds it, builds it, and hands it over. No configuration, no factory, no container gymnastics. A generation of PHP developers now writes dependency injection without ever thinking about it, which is exactly what good tooling should achieve.

It also quietly made dependency inversion optional, and most codebases have taken the option.

Personas from search logs: what your users actually wanted, in their own words

The standard criticism of user personas is that they are fiction. Someone runs a workshop, the team invents "Marketing Mary, 34, values efficiency, enjoys yoga," and it goes on a wall. Nobody can say whether Mary is right, because nothing about her is falsifiable. She was assembled from assumptions, and she reflects them back with the authority of a laminated poster.

Subscribe to