# How the HelloGitHub Template System Replaces `{{ hello_github_content }}` Placeholders

> Discover how the HelloGitHub template system replaces {{ hello_github_content }} placeholders. Learn about the Python script that handles markdown content substitution for dynamic issue generation.

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

---

**The HelloGitHub template system uses a Python script to perform simple string substitution, replacing `{{ hello_github_content }}` in a static markdown template with issue-specific content read from individual markdown files.**

The `521xueweihan/HelloGitHub` repository automates the creation of monthly issues through a lightweight templating engine. This system separates static layout elements from dynamic content using placeholder tokens, enabling consistent formatting across all published issues.

## Placeholder Definitions in [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py)

The core generator defines two substitution tags in [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py). These constants determine where dynamic data injects into the static template:

- **`{{ hello_github_content }}`** — Marks the insertion point for the issue's main markdown body
- **`{{ hello_github_num }}`** — Reserved for the issue number identifier

These placeholders are defined at lines 21–22 of the script, establishing the contract between the template structure and the content generation logic.

## Step-by-Step Replacement Process

When you execute `python script/make_content/make_content.py <number>`, the HelloGitHub template system performs a six-stage pipeline:

### 1. Template Loading

The script reads [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) from the current working directory into memory (lines 55–56). This file contains the static skeleton with both placeholder tokens positioned where content should appear.

### 2. Issue Number Injection

The script substitutes `{{ hello_github_num }}` with the numeric identifier passed via command line (line 61). This connects the static template to a specific issue directory.

### 3. Content File Reading

The system locates the issue-specific markdown file (e.g., [`content/HelloGitHub05.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/HelloGitHub05.md)) and loads its entire contents into a string variable (lines 63–64).

### 4. Content Placeholder Replacement

The script performs the critical substitution at line 65, replacing the `{{ hello_github_content }}` token with the full text of the issue-specific markdown file loaded in the previous step.

### 5. Output Generation

The merged result is written to `HelloGitHub{num}.md` inside the issue's folder (lines 67–68), completing the transformation from template to publishable content.

## Running the Content Generator

Generate a single issue by passing the issue number as an argument:

```bash
python script/make_content/make_content.py 05

```

This command:
- Reads [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md)
- Replaces `{{ hello_github_num }}` with `05`
- Inserts [`content/HelloGitHub05.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/HelloGitHub05.md) at the `{{ hello_github_content }}` position
- Outputs [`05/HelloGitHub05.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/05/HelloGitHub05.md)

To regenerate all historical issues at once:

```bash
python script/make_content/make_content.py all

```

The `make_all_content()` function iterates through numeric directories, applying the same placeholder replacement logic to each issue.

## Key Files in the Template System

| File | Purpose |
|------|---------|
| [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py) | Core engine defining placeholders and executing string substitution |
| [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) | Static skeleton containing `{{ hello_github_content }}` and `{{ hello_github_num }}` tokens |
| [`content/HelloGitHubXX.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content/HelloGitHubXX.md) | Issue-specific markdown that replaces the content placeholder for issue **XX** |

## Summary

- The HelloGitHub template system uses **simple string substitution** rather than a complex templating engine like Jinja2
- Two placeholders control content injection: `{{ hello_github_content }}` for the main body and `{{ hello_github_num }}` for the issue identifier
- The [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script reads [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md), performs sequential replacements, and writes merged output to issue-specific directories
- This architecture separates presentation formatting from content creation, enabling consistent monthly issue generation

## Frequently Asked Questions

### What templating engine does HelloGitHub use?

HelloGitHub does not use a dedicated templating engine like Jinja2 or Mustache. Instead, it implements **simple Python string replacement** using the `str.replace()` method. The [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script defines placeholder constants and substitutes them with actual content using basic string operations.

### Where is the `{{ hello_github_content }}` placeholder defined?

The placeholder is defined as a constant in [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py) at lines 21–22. The script assigns the string literal `"{{ hello_github_content }}"` to a variable, which it later uses to locate and replace the token within [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md).

### Can I use this template system for my own newsletter?

Yes, the architecture is highly portable. You would need to adapt three components: the [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) file containing your layout and placeholder tokens, the [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script (potentially modifying the placeholder constants), and the content directory structure where individual issue markdown files are stored. The string-based replacement logic requires no external dependencies beyond standard Python libraries.