Proper way to translate a theme

Hi, I’m trying to translate my theme in different languages. I have already changed all of my strings from foo to {{ i18n "foo" }}, and now I just need to extract and translate them.

I see other themes (like Ananke) have an i18n folder where all translations are stored. I’d like to do the same thing, and as far as I understood from the docs, I need to use goi18n.

I tried, and ran goi18n extract just to get an empty active.en.toml file.

I don’t know how other themes do it, and the documentation lacks this information, so please if anyone wants to help me, what is the proper way to extract strings for translation? Thanks.

The “proper” way is to have an en.toml in your i18n folder with translations for your strings. One file per language. I read about goi18n extract but it did not work when I tried it and there are posts here on the forum too about it not working as expected. So it’s mostly handywork then. Not sure if this is a problem with the function name in Hugo or something upstream.

You can however run hugo and hugo server with a parameter so it tells you if a translation id could not be found:

hugo --i18n-warnings

This is probably the least worst solution, thanks. Honestly I think hugo should have some way to properly extract i18n strings and save them to a file, having to manually extract them is not ideal.

This Bash script adds missing key/value pairs to i18n files, creating new files if needed. The new values are a single space instead of an empty string to prevent creation of duplicate keys if you run the script more than once.

Existing key/value pairs are not modified.

There must at least one content file per template for each language.

i18n-add-misssing-keys.sh
#!/usr/bin/env bash

#------------------------------------------------------------------------------
# Adds missing key/value pairs to i18n files, creating new files if needed.
#
# The new values are a single space instead of an empty string to prevent
# creation of duplicate keys if you run the script more than once.
#
# Existing key/value pairs are not modified.
#
# There must at least one content file per template for each language.
#------------------------------------------------------------------------------

main() {
  declare -a languages
  declare language
  declare -a translations
  declare translation
  declare key

  # Create array of languages defined in site configuration.
  readarray -t languages < <(hugo config | grep "languages" | sed 's/languages = map\[/\]/' | sed 's/:map/\n/g' | head -n-1 | awk -F'[\\]]' '{print $2}' | sed 's/ //g')

  # Create missing i18n files.
  mkdir -p "i18n"
  for language in "${languages[@]}"; do
    touch "i18n/${language}.toml"
  done

  # Create array of missing translations. Example:
  readarray -t translations < <(hugo --printI18nWarnings | grep "i18n" | sort | awk -F'|' '{print $3 "|" $4}')

  # Update i18n files.
  for translation in "${translations[@]}"; do
    language=$(awk -F'|' '{print $1}' <<< "${translation}")
    key=$(awk -F'|' '{print $2}' <<< "${translation}")
    echo "${key} = ' '" >> "i18n/${language}.toml"
  done
}

set -euo pipefail
main "$@"

Try it:

git clone --single-branch -b hugo-forum-topic-33718 https://github.com/jmooring/hugo-testing hugo-forum-topic-33718
cd hugo-forum-topic-33718
cat README.md
3 Likes

This looks to me not like the toml markup (or maybe I am doing something wrong or too explicit):

[contactform_email]
other = "Your Email Address"

My slugs are in brackets and then it’s an other for most of the items.

That script can be changed for my needs :slight_smile:

Items without pluralization rules

i18n/es.toml

about = "acerca de"
help = "ayuda"

template

{{ i18n "about" }} --> acerca de
{{ T "help" }}     --> ayuda

Items with pluralization rules

i18n/pl.toml

[day]
one = "{{ . }} miesiąc"
few = "{{ . }} miesiące"
many = "{{ . }} miesięcy"
other = "{{ . }} miesiąca"

template

{{ T "day" 1 }}   --> 1 miesiąc
{{ T "day" 2 }}   --> 2 miesiące
{{ T "day" 5 }}   --> 5 miesięcy
{{ T "day" 1.5 }} --> 1.5 miesiąca

Reference: https://unicode-org.github.io/cldr-staging/charts/37/supplemental/language_plural_rules.html

2 Likes

We need to update the docs about this. I always used the other method. Overkill probably :smiley: