Platform
Translated product copy for GoCommerce
A Go package that serves catalogue content in the language a shopper asked for. The engine already negotiates the language and has a port for overrides; this module is the table behind that port — product titles, descriptions and the two SEO fields, per language, written through three admin routes.
- Platform module
- 2 settings
- 9 tests
- 3 API operations
- ext/translations
What it does
In the package’s words, the engine already had every part of this except the words. Config.Languages declares what a store serves, each request is negotiated down to one of them, and every public product read asks a translator port for overrides. Before this module nothing implemented that port, so a store configured for English and French negotiated French correctly and was then handed the English title.
It translates four product fields: title, description, seo_title and seo_description. A field with no translation keeps the product’s stored text — half a translation is common, and an English description beats an empty one.
A regional tag falls back to its language: a row stored for fr serves a shopper asking for fr-CA, and a row stored for fr-CA wins over it. Lookups are batched, one query for a page of products rather than one per product.
Configuration
The module has no settings of its own — translations.New() takes none. Whether it does anything is decided by the engine’s language list, set in gocommerce.Config.
| Setting | Environment variable | Required | What it does |
|---|---|---|---|
Languages | — | Yes | The engine’s setting, not the module’s: the tags the store serves. The module has nothing to serve until there is a language besides the default. |
DefaultLanguage | — | No | The language the catalogue itself is written in, en unless set. A request in the default language skips the translator entirely. |
The module reads its Config struct, not the environment. The variable names are the ones the package’s own example or the reference binary uses; in your own main() you choose where each value comes from. Where a setting has a panel label, the admin’s settings drawer can hold it too, and a value typed there wins over Config.
Setting it up
- Declare the languagesSet Languages in gocommerce.Config — en, fr and de in the package’s example — with the catalogue’s own language as the default.
- Install the modulePass translations.New() to gocommerce.New in your own main(), as below. Neither the reference binary nor examples/store installs it.
- Write translationsPUT /api/admin/x/translations/product/{id}/{language} with fields for title, description, seo_title or seo_description. An unknown field is refused; an empty one is dropped.
- Ask in a languageThe storefront sends ?lang=fr or an Accept-Language header on product reads, and gets French where it exists and the stored text where it does not.
main.go
import (
"github.com/itswadesh/gocommerce/core"
"github.com/itswadesh/gocommerce/ext/translations"
)
app, err := gocommerce.New(gocommerce.Config{
// DBURL, Addr and the rest of your Config, then:
Languages: []string{"en", "fr", "de"},
}, translations.New()) The package doc’s own example, with its imports; the first language listed is the default unless DefaultLanguage says otherwise. Import path github.com/itswadesh/gocommerce/ext/translations.
How it works
-
Behind the engine’s port
The module registers as the engine’s one Translator. Every public product read — the listing, a single product, a category’s or a collection’s products — asks it for overrides in the negotiated language.
-
One query per page
A page of fifty products is one lookup, not fifty: the port is batched, and the exact tag and its primary language are fetched together.
-
Failure falls back
If a lookup fails, the engine logs it and serves the stored text rather than failing the request — a shopper would rather read the default language than an error page.
-
An allow-list of fields
Only title, description, seo_title and seo_description are accepted, and anything else is refused with the list of what is. A typo is an error, not a row that silently never applies.
-
Empty means absent
Blank fields are dropped, and a write that empties every field deletes the row — so a product never claims a language it has no text in.
-
Catalogue rights
Reading translations needs catalog.read and writing them catalog.write. In the package’s words, somebody trusted to rewrite the English title is trusted to write the French.
What it does not do
Read these before an order depends on it. No store is known to run GoCommerce in production yet, so these come from the code, not from anyone’s experience.
- Products onlyCategory and collection names are not translated — the engine has no hook for them — so a French catalogue still shows its navigation in the default language. Variants are refused too.
- No admin screenTranslations are written through the admin API. The admin has no screen for them yet.
- No flag, no quick startNeither the reference binary nor examples/store installs it. Using it means a main() of your own.
- Any tag is storedThe API accepts any language tag, but only the languages in Config.Languages are ever served; a translation into an undeclared one is stored and never read.
- Not in search or feedsThe Meilisearch index and the product feeds carry the stored text. Translated copy reaches the storefront’s product reads and nothing else.
- Nothing automaticIt stores and serves text somebody wrote. There is no machine translation.
FAQ
Questions about the Translations module
How does the store pick a language?
An explicit ?lang= wins, then Accept-Language in the client’s order of preference, then the default. Only languages in Config.Languages are considered, and a ?lang= the store does not serve falls back to the default.
What exactly is translated?
Four product fields: title, description, seo_title and seo_description. Anything without a translation keeps the product’s stored text.
Are category names translated?
No. The engine applies translations to products only, so category and collection names — and so the navigation — stay in the default language. The package says so rather than leaving it to be discovered.
Is there a screen for entering translations?
Not yet. They are written with PUT /api/admin/x/translations/product/{id}/{language} and read back with GET /api/admin/x/translations/product/{id}, using an admin token or a signed-in operator with the catalogue rights.
Source
Everything on this page is read from ext/translations in the GoCommerce repository, MIT licensed. When this page and the code disagree, the code is right and this page is out of date.
Try it against a store of your own
The one-command stack gives you GoCommerce’s API and admin on your own machine in minutes. Add this module to it and try it on test orders before a real one depends on it.