# How HelloGitHub Generates Both Chinese and English Versions of Monthly Issues

> Discover how HelloGitHub generates synchronized Chinese and English issues by parallel markdown sources and an automated placeholder replacement system using Python scripts.

- Repository: [削微寒/HelloGitHub](https://github.com/521xueweihan/HelloGitHub)
- Tags: internals
- Published: 2026-02-25

---

**HelloGitHub maintains parallel markdown sources in `content/` and `content/en/` directories, then uses [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py) to inject these into language-specific templates—producing synchronized bilingual issues through an automated placeholder replacement system.**

The open-source project `521xueweihan/HelloGitHub` publishes a monthly curated list of interesting GitHub projects. To serve its global audience, the repository implements a sophisticated **generating both Chinese and English versions** workflow that keeps content synchronized across languages without manual copy-pasting or layout duplication.

## Parallel Source Files for Bilingual Content

HelloGitHub stores each monthly issue as two independent markdown files representing the **single source of truth** for each language.

- **Chinese source**: `content/HelloGitHub<NN>.md` (where `<NN>` is the issue number)
- **English source**: `content/en/HelloGitHub<NN>.md`

Both files contain the full issue body—including project titles, descriptions, and screenshots—but in their respective languages. Authors edit these raw content files directly, while the surrounding layout and styling remain separate in template files.

## The Template-Based Generation Pipeline

The generation logic lives in [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py). This script merges language-specific content with standardized templates to produce the final publishable markdown.

### How Template Injection Works

The system uses two placeholder flags that the Python script replaces at runtime:

- `{{ hello_github_num }}` — Replaced with the issue number (e.g., `87`)
- `{{ hello_github_content }}` — Replaced with the full text of the source markdown file

For Chinese issues, the script loads [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) from the repository root. For English issues, it loads [`template_en.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template_en.md). Both templates share identical placeholder structures but contain language-specific surrounding text (headers, footers, and formatting).

### Generating Issues via Command Line

From the repository root, maintainers execute the script with specific arguments to generate either language:

```bash

# Generate Chinese issue #87

python script/make_content/make_content.py 87

# Generate all Chinese issues at once

python script/make_content/make_content.py all

# Generate English issue #87 (automatically routes to content/en/)

python script/make_content/make_content.py en/87

```

When the script detects a forward slash in the argument (e.g., `en/87`), it splits the string into language and issue number, then routes to [`content/en/HelloGitHub87.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/en/HelloGitHub87.md) instead of the default Chinese path.

### Core Python Logic

The `make_content()` function in [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) handles the file resolution and string replacement:

```python
def make_content(num):
    # Template selection: template.md (Chinese) or template_en.md (English)

    template_path = os.path.join(os.path.abspath(os.curdir), 'template.md')
    
    # Language routing logic

    if '/' in num:  # e.g., "en/87"

        lang, issue = num.split('/')
        content_path = os.path.join('content', lang, f'HelloGitHub{issue}.md')
    else:
        content_path = os.path.join('content', f'HelloGitHub{num}.md')
    
    # Placeholder replacement

    template_data = read_file(template_path).replace(NUM_FLAG, num)
    content_data = read_file(content_path)
    output_data = template_data.replace(CONTENT_FLAG, content_data)
    
    write_file(os.path.join(output_path, f'HelloGitHub{num}.md'), output_data)

```

This approach ensures that **content authors** focus purely on writing project descriptions in their language, while the **automation** handles layout injection and file naming conventions.

## Design Benefits of the Dual-Language Workflow

The repository's architecture provides several advantages for maintaining bilingual content at scale:

- **Separation of concerns** — Writers edit pure markdown without touching HTML or layout code; the template manages the visual structure.
- **Independent updates** — Because Chinese and English sources exist as separate files ([`content/HelloGitHub87.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/HelloGitHub87.md) vs. [`content/en/HelloGitHub87.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/en/HelloGitHub87.md)), translators can update English content without creating merge conflicts in the Chinese version.
- **Idempotent generation** — Running [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) repeatedly produces identical output; changing a source file automatically updates both language versions after regeneration.
- **Scalable architecture** — Adding a third language requires only a new subfolder (`content/<lang>/`) and a matching `template_<lang>.md` file. The existing Python script requires no modifications to support additional languages.

## Summary

- HelloGitHub uses **parallel markdown files** in `content/` (Chinese) and `content/en/` (English) as the canonical source for each monthly issue.
- The **[`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script** merges these sources with language-specific templates using placeholder replacement (`{{ hello_github_content }}` and `{{ hello_github_num }}`).
- **Command-line arguments** control the output language: plain numbers generate Chinese issues, while `en/<number>` generates English versions.
- The **template-based approach** separates content from layout, enabling independent translation workflows and scalable multilingual expansion.

## Frequently Asked Questions

### How does the script know which language template to use?

The [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script determines the language by checking for a forward slash in the input argument. If you pass `en/87`, it splits the string, sets the working directory to `content/en/`, and loads [`template_en.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template_en.md). For plain numbers like `87`, it defaults to the repository root and uses [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) for Chinese generation.

### Can contributors submit projects in both languages?

Yes. The repository includes separate GitHub issue templates located at [`.github/ISSUE_TEMPLATE/submit-cn.yaml`](https://github.com/521xueweihan/HelloGitHub/blob/main/.github/ISSUE_TEMPLATE/submit-cn.yaml) for Chinese submissions and [`.github/ISSUE_TEMPLATE/submit-en.yaml`](https://github.com/521xueweihan/HelloGitHub/blob/main/.github/ISSUE_TEMPLATE/submit-en.yaml) for English submissions. These templates guide contributors to provide project recommendations in their preferred language, which editors later compile into the monthly source files.

### What happens if I regenerate an issue after editing the source file?

Regeneration is **idempotent and overwrite-safe**. Running `python script/make_content/make_content.py 87` re-reads [`content/HelloGitHub87.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/HelloGitHub87.md) and [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md), performs the placeholder substitution fresh, and overwrites the previous generated file with the updated content. This ensures the published issue always reflects the latest edits to the source markdown.

### Is it possible to add a third language to this workflow?

Yes. The architecture supports additional languages through directory convention. Create a new folder such as `content/fr/` for French, add a `HelloGitHub<NN>.md` file for each issue, and create a corresponding [`template_fr.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template_fr.md) in the repository root. The script's routing logic (`if '/' in num`) automatically handles any language code prefix without requiring code changes.