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:
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.
Here’s a Bash script that creates or updates TOML i18n files based on languages defined in the site configuration. It parses output from hugo --i18n-warnings to create keys as needed.
There must at least one content page for each language.
Example of created file:
date_created=" "
date_modified=" "
title=" "
The values are a single space instead of an empty string to prevent creation of duplicate keys if you were to run the script twice or more.
Bash script
#!/usr/bin/env bash
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 i18n files.
mkdir -p "i18n"
for language in "${languages[@]}"; do
touch "i18n/${language}.toml"
done
# Create array of missing translations. Example:
#
# en|date_created
# en|title
# es|date_created
# es|title
readarray -t translations < <(hugo --i18n-warnings | 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 "$@"