# How Translations Are Managed and Implemented in tldr-pages

> Learn how tldr-pages manages and implements translations using parallel directories and automated Python scripts to sync changes from English source files to localized versions effectively.

- Repository: [tldr pages/tldr](https://github.com/tldr-pages/tldr)
- Tags: internals
- Published: 2026-03-05

---

**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`](https://github.com/tldr-pages/tldr/blob/main/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)](https://github.com/tldr-pages/tldr/blob/main/scripts/_common.py) extracts the language code from the parent directory name:

```python
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"`:

```python
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/`](https://github.com/tldr-pages/tldr/tree/main/contributing-guides/translation-templates). These Markdown files contain placeholder text that translators customize for each language.

The `get_templates()` function in [`_common.py`](https://github.com/tldr-pages/tldr/blob/main/_common.py) reads these template files and returns a dictionary mapping locale codes to their specific translations:

```python
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`](https://github.com/tldr-pages/tldr/blob/main/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`](https://github.com/tldr-pages/tldr/blob/main/set-more-info-link.py)** – Updates documentation URLs
- **[`set-page-title.py`](https://github.com/tldr-pages/tldr/blob/main/set-page-title.py)** – Synchronizes command headings
- **[`set-alias-page.py`](https://github.com/tldr-pages/tldr/blob/main/set-alias-page.py)** – Manages alias redirect pages
- **[`set-see-also.py`](https://github.com/tldr-pages/tldr/blob/main/set-see-also.py)** – Maintains cross-reference sections

Each script imports helpers from [`_common.py`](https://github.com/tldr-pages/tldr/blob/main/_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`](https://github.com/tldr-pages/tldr/blob/main/set-more-info-link.py) demonstrates this workflow:

```python
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.

```bash

# 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 English `pages/` structure.
- **Locale detection** occurs through `get_locale()` in [`_common.py`](https://github.com/tldr-pages/tldr/blob/main/_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`](https://github.com/tldr-pages/tldr/blob/main/set-more-info-link.py), [`set-page-title.py`](https://github.com/tldr-pages/tldr/blob/main/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 `-s` flag, 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`](https://github.com/tldr-pages/tldr/blob/main/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/`](https://github.com/tldr-pages/tldr/tree/main/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`](https://github.com/tldr-pages/tldr/blob/main/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.