Translation and RTL
Two different jobs, and it saves a lot of time to keep them apart:
- The words the theme and the plugin print — "Get directions", "Open until", "Posted by" — ship
as translatable strings with a
.pottemplate each. - Your own content — each dish, service, hours row, slip and booking row — is a record, and translating records is what a multilingual plugin does.
The two .pot files
| File | Text domain | Covers |
|---|---|---|
table-and-type/languages/table-and-type.pot |
table-and-type |
Every string in the theme: templates, patterns, the style variation titles. |
table-and-type-core/languages/table-and-type-core.pot |
table-and-type-core |
Every string in the companion plugin: the admin screens, the blocks, the slip refusal messages, the Guide. |
Both are plain GNU gettext templates. Open one in Poedit or Loco Translate, translate it, and save
the .po/.mo pair into the matching languages/ directory — or, better, into
wp-content/languages/themes/ and wp-content/languages/plugins/, where an update cannot overwrite
them.
No en_US translation ships; English is the source.
Multilingual plugins
| Plugin | Status |
|---|---|
| Polylang (free) | Tested. Offered through the theme's plugin screen. |
| WPML | Documented, untested. Every content type and every field is registered for the REST API with a schema and translatable labels, which is what WPML needs to see them — but we have not run it and we do not claim compatibility. |
Every record is an ordinary post or term, so a multilingual plugin translates each dish, service, hours row, slip and booking row as its own translated record. Nothing about the card is special-cased.
Two things to check after you switch a multilingual plugin on:
- Slips are dated records, not strings. A translated slip is a second record with its own window. Post it, or let the untranslated one show.
- The derived sentences — the open status, the booking line, the freshness stamp — are built from the records in the language of the record. Translate the records and the sentences follow.
Why dish names stay French
On the demo, the dish names stay in French on the English page: croque Mireille, soupe de courge, kouign-amann. That is not an untranslated string — it is a decision, and it is marked in the page.
A dish name is a proper name on a printed card. A café in Montréal does not translate tartine aux champignons into mushroom toast on the English page; it prints the name and puts the explanation on the line underneath, which is exactly what the excerpt is for.
So each dish carries a language of its own name:
- Settings › Site details › Language of product names sets the default —
frin the demo. - Dishes › the dish can override it per dish.
The card then wraps that name in <span lang="fr">. A screen reader switches its pronunciation
dictionary and says kouign-amann the way it is said, instead of reading it as English. Set the
field to your own language, or clear it if your dish names are in the page's own language.
Right-to-left
RTL is supported. The theme's layout is written in logical properties — start and end rather than left and right — so it mirrors when WordPress is running in an RTL locale. The card, the slip lane, the price rail and the mobile panel all follow.
One thing does not mirror, on purpose: times and prices stay in their own reading order, which is what a bilingual RTL site actually prints.
If you find an RTL layout problem, it is a bug and we want to hear about it — see Support.