How Translations Are Managed and Implemented in tldr-pages
The tldr-pages project manages translations through parallel directory structures and automated Python sync scripts that propagate changes from English source files to localized versions using standardized templates.
The tldr-pages repository maintains command-line cheat sheets in dozens of languages, requiring a robust system to keep content synchronized across locales. Rather than using monolithic localization files, the project implements a file-based architecture where each language mirrors the English directory structure. This design enables automated synchronization through shared utilities in scripts/_common.py that detect locales, discover page paths, and apply language-specific boilerplate.
Directory Structure and Locale Detection
Translations reside in sibling directories to the main pages/ folder, following the naming convention pages.<locale> (e.g., pages.fr/, pages.pt_BR/). Each directory maintains identical platform subdirectories (common/, linux/, osx/, windows/) as the English source, allowing tooling to process all languages uniformly.
The get_locale() function in [scripts/_common.py](https://github.com/tldr-pages/tldr/blob/main/scripts/_common.py) extracts the language code from the parent directory name:
def get_locale(path: Path) -> str:
pages_dirname = path.parents[1].name # e.g. "pages.fr"
if "." in pages_dirname:
_, locale = pages_dirname.split(".")
else:
locale = "en"
return locale
This function parses the directory structure to return "fr" for files in pages.fr/ and "en" for files in the base pages/ directory. The get_pages_dirs() function discovers all translation directories automatically by scanning for folders starting with "pages":
def get_pages_dirs(root: Path) -> list[Path]:
return [
d for d in root.iterdir()
if d.name.startswith("pages") and not d.is_symlink()
]
Translation Templates
Standardized boilerplate for recurring sections like "More information" and "See also" lives in contributing-guides/translation-templates/. These Markdown files contain placeholder text that translators customize for each language.
The get_templates() function in _common.py reads these template files and returns a dictionary mapping locale codes to their specific translations:
def get_templates(root: Path, filename: str):
template_file = root / "contributing-guides/translation-templates" / filename
with template_file.open(encoding="utf-8") as f:
lines = f.readlines()
# … parses markdown sections …
return templates # { "fr": "...", "es": "...", ... }
For example, more-info-link.md contains localized versions of the > More information: <https://example.com> line, which sync scripts substitute with actual URLs while preserving the translated text.
Automated Sync Scripts
Four Python utilities in the scripts/ directory propagate changes from English pages to translations:
set-more-info-link.py– Updates documentation URLsset-page-title.py– Synchronizes command headingsset-alias-page.py– Manages alias redirect pagesset-see-also.py– Maintains cross-reference sections
Each script imports helpers from _common.py and follows the same pattern: detect the locale, load the appropriate template, modify the target file, and optionally stage changes with Git.
The link synchronization logic in set-more-info-link.py demonstrates this workflow:
def set_link(path: Path, link: str, dry_run: bool = False,
language_to_update: str = "") -> str:
locale = get_locale(path)
if language_to_update and locale != language_to_update:
return ""
with path.open(encoding="utf-8") as f:
lines = f.readlines()
# locate description block
for i, line in enumerate(lines):
if line.startswith(">") and desc_start == 0:
desc_start = i
if not lines[i + 1].startswith(">") and desc_start != 0:
desc_end = i
break
new_line = config.templates[locale].replace("https://example.com", link)
if lines[desc_end] == new_line:
return "" # nothing to do
if re.search(r"^>.*<.+>", lines[desc_end]): # existing link
lines[desc_end] = new_line
action = "updated"
else: # add link
lines.insert(desc_end + 1, new_line)
action = "added"
status = get_status(action, dry_run, "link")
if not dry_run:
with path.open("w", encoding="utf-8") as f:
f.writelines(lines)
return status
This function locates the description block (lines starting with >), determines whether to update an existing link or insert a new one, and applies the locale-specific template before writing changes.
Practical Workflow for Maintainers
Contributors use these scripts through a command-line interface that supports dry-run verification and Git staging. The typical workflow involves updating the English source first, then propagating changes across all translations.
# Add a "More information" link to the English page
python3 scripts/set-more-info-link.py -p common/tar https://tldr.sh/pages/common/tar
# Preview changes across all translations without writing files
python3 scripts/set-more-info-link.py -S -n
# Apply changes and stage modified files for commit
python3 scripts/set-more-info-link.py -S -s
The -S or --sync flag instructs the script to read the English source and apply it to all language directories. The -n flag enables dry-run mode for safety, while -s stages changes using Git.
Summary
- Parallel directory architecture separates translations into
pages.<locale>/folders that mirror the Englishpages/structure. - Locale detection occurs through
get_locale()in_common.py, which parses directory names to determine language codes. - Translation templates in
contributing-guides/translation-templates/provide standardized boilerplate for common sections across all languages. - Sync scripts (
set-more-info-link.py,set-page-title.py, etc.) automate propagation of changes from English sources to translations using shared utilities for file discovery and template application. - Git integration allows maintainers to stage changes automatically via the
-sflag, streamlining the contribution workflow.
Frequently Asked Questions
How does tldr-pages determine the language of a specific page?
The repository uses the get_locale() function in scripts/_common.py to inspect the parent directory name. If the directory is pages.fr, the function returns "fr"; for pages.pt_BR, it returns "pt_BR"; and for the base pages directory, it defaults to "en". This inference happens at runtime whenever a sync script processes a file.
What are translation templates and where are they stored?
Translation templates are Markdown files containing boilerplate text for recurring elements like "More information" links and "See also" sections. They reside in contributing-guides/translation-templates/ and provide the canonical wording that translators adapt. The get_templates() function loads these files and maps content to specific locales for use by synchronization scripts.
How do sync scripts handle existing content in translations?
Scripts like set-more-info-link.py parse the target file to determine whether content exists or needs insertion. For documentation links, the script checks if a URL pattern already exists using regex; if found, it updates the line with the new link while preserving the translated text from the template. If no link exists, the script inserts a new line after the description block, ensuring content is added without overwriting unrelated text.
Can I synchronize changes to only one specific language?
Yes. All sync scripts accept a language_to_update parameter (typically via the -L flag) that filters processing to a single locale. When specified, the script compares the detected locale from get_locale() against the requested language and skips files that do not match, allowing targeted updates without affecting other translations.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →