A second language, one release later
1.9 brought the second language: one post, a text in each language, an /en/ tree beside the root. The first site to run it for real was the one the engine grew up on, and a month of that showed what no test shows. The 1.10 changelog has over thirty entries about the second language. This is not their list. It is about what a second language needs that the first one does not.
A name that inflects
site.author stands in sentences: "na osobním webu Daniela Šnora". Czech inflects a name, so the configuration holds the genitive, and the pages in English took it over, case and all. 1.10 adds site.author_name: the name as it stands alone — under a hero title, as the person the structured data names, on the pages of a language other than the site's own. Without it author is used everywhere, as before. A language that does not inflect never needed it, which is why nobody wrote it.
A series has a name in every language
A series is named the way its posts write it, and that is one name. Over translated posts stood an untranslated one: "Nový Sean.cz" over an English listing. series: in config/site.<lang>.yml gives a series the name that language shows — over its listing, in the sentence that places a part, in the page's title — keyed like tags: by the name the posts write or by its slug. The series itself stays one thing: one address, one set of parts. And /series/, the index of series, is each language's own, with the names it gave them:
The new Sean.cz 23 2026
Zprávobot.news 19 2026
Mastodon 2 2022–2026
An old address belongs to a translation
This is the case no design thinks up. For years the site had some posts twice: in Czech and in English, two posts, two addresses. With the second language they became one post with a translation, and the second one's address was left hanging: a post's former_slugs could only send to the post in the site's own language, so an English reader with an English link landed on the Czech page. A translation may now carry former_slugs of its own; the redirect stands at the site's root and in that language's tree, check asks of it what it asks of any old address, and saving the translation again keeps it. On the site this was measured on, that is 68 posts.
And the other half of the same thing: a translation whose slug: was changed used to move its page and write down nothing, while a post renamed by its own slug has always kept a redirect. Now the old address goes into that language's former_slugs by the same save.
The exception, or the rule
A site of several languages was asked about every post whether it may go out without the words of all of them: publish and schedule refused until --allow-partial was said, the wizard asked, a post from a phone with publish: yes stayed a draft. Right for a site that means to publish everything in every language. A question with one answer for the site where a translation is the exception — and on the one this was measured on, that is 142 English texts over 6,912 posts. publishing.allow_partial: true in config/site.yml gives that answer once. Only true does; doctor names a value that is neither true nor false, and a program learns it from props --json. Left out, nothing changes.
What check and doctor learned
The rest are things the second language brought with it and the first never knew. doctor said "0 problems" about a language configuration no language builds on: a language in site.locales with no file, a translation of a widget the site lacks, an empty tag label. The advice for a site with no locale file sent ui_language where it is refused. A language with a borrowed interface — Slovak, say, for which the engine has no texts of its own — was named in the switch by its code, "SK" beside "English"; language_name: in its file names it. A chain of fallback: [cs, en] ran past the site's own language and showed a German reader English. Three pages of the second language — the search, the cheat sheet, the 404 — named the first language's page as their canonical address. On a site of three languages the switch could not get from one text of a post to the other when the language in between had none. And an export left without the translations: the documented way to move an installation carried a site of two languages out as a site of one.
Each of those has its line in the changelog. What they share is that they did not show up in the writing but in the running: on a site where the second language is the exception and not the rule, where old pairs of posts were being merged, and where the installation was moved.
A table without reproach
./blog.sh check --languages says today, on that site: 6,912 posts, written in Czech 6,912, in English 142, without English 6,770. It is a description of a state, not a judgement, and --json hands it to a program, which --languages used to refuse. A second language is not a feature one line in the configuration switches on. It is a second site over the same archive, with everything a site has — names, series, old addresses, rules for when a post may go out. 1.9 built it. 1.10 left it standing in the rain for a month.
The 1.9 piece is here: Two languages, one site.

Comments