# How HelloGitHub Ensures Consistent Formatting Across All Monthly Issues

> Learn how HelloGitHub guarantees consistent monthly issue formatting. Discover their Python script that injects Markdown into templates for identical structure every time.

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

---

**The HelloGitHub project enforces uniform layouts by using a Python generator script that injects issue-specific Markdown into a shared template file, replacing standardized placeholders to produce every monthly issue with identical structure.**

The HelloGitHub repository curates interesting open-source projects in a monthly magazine format, requiring strict visual consistency across dozens of issues. To ensure consistent formatting across all monthly issues, the project employs a deterministic build system centered on [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py) rather than manual copy-pasting.

## The Template-Driven Architecture

The system separates static layout elements from unique content using two core components that guarantee structural uniformity.

### Static Layout Template ([`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md))

At the project root, [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) serves as the master skeleton containing common headers, tables of contents, footers, and placeholder markers. This file defines the visual identity—including title formatting, logo placement, directory structure, "Tips" sections, and update schedules—that remains identical across every monthly issue.

### Issue-Specific Content Storage

Individual articles and project highlights reside in dedicated issue folders as `content<num>.md` files (e.g., [`45/content45.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/45/content45.md)). These files contain only the unique Markdown for that month's curated projects without any boilerplate formatting, ensuring that editorial work focuses purely on content rather than layout.

## The Python Generation Engine

Located at [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py), the generator script orchestrates the merge process through deterministic string replacement logic implemented in the `make_content` function (lines 54–68).

### Placeholder Flag System

The script recognizes two mandatory placeholder strings defined at lines 21–22:

```python
CONTENT_FLAG = '{{ hello_github_content }}'   # Marks where unique articles insert

NUM_FLAG     = '{{ hello_github_num }}'       # Marks where issue number appears

```

### Content Generation Workflow

The core generation logic executes a four-step pipeline to assemble each monthly issue:

1. **Template Loading**: Reads [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) from the project root
2. **Number Substitution**: Replaces `{{ hello_github_num }}` with the target issue number
3. **Content Injection**: Reads the issue-specific file (`content<num>.md`) and substitutes `{{ hello_github_content }}`
4. **File Writing**: Outputs the final `HelloGitHub<num>.md` to the issue directory

```python
def make_content(num):
    template_path = os.path.join(os.path.abspath(os.curdir), 'template.md')
    output_path   = os.path.join(os.path.abspath(os.curdir), num)
    content_path  = os.path.join(output_path, 'content' + num + '.md')

    # Substitute issue number into template

    temple_data = read_file(template_path).replace(NUM_FLAG, num)
    
    # Load unique content for this monthly issue

    content_data = read_file(content_path)
    
    # Merge content into template structure

    output_data = temple_data.replace(CONTENT_FLAG, content_data)
    
    # Write final formatted issue

    write_file(os.path.join(output_path, f'HelloGitHub{num}.md'), output_data)
    print(f'Make 《GitHub月刊{num}》 successful！')

```

## Batch Regeneration Commands

When editors update common sections like headers or footers, they modify only [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) and regenerate the entire series with a single command. This ensures that layout changes propagate instantly across all historical monthly issues without manual editing of individual files.

```bash

# Regenerate all monthly issues with updated template

python make_content.py all

```

For targeted updates to specific editions, maintainers can generate individual issues:

```bash

# Generate only issue 45

python make_content.py 45

```

## Summary

- **Template Separation**: The [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) file contains all static formatting elements shared across the HelloGitHub monthly issue series, ensuring visual consistency.
- **Placeholder System**: Dual flags (`{{ hello_github_content }}` and `{{ hello_github_num }}`) mark precise injection points for dynamic content and issue numbering.
- **Automated Generation**: The [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script deterministically merges templates with issue-specific Markdown stored in numbered directories.
- **Batch Operations**: The `python make_content.py all` command enables global template updates across the entire back catalog of monthly issues.

## Frequently Asked Questions

### What happens if the template file is modified?

When [`template.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/template.md) changes, running `python make_content.py all` regenerates every monthly issue with the new layout. This ensures retroactive consistency across all published issues in the HelloGitHub repository without requiring manual updates to historical files.

### Where are the issue-specific content files stored?

Individual monthly issue content resides in numbered directories (e.g., `45/`) as [`content45.md`](https://github.com/521xueweihan/HelloGitHub/blob/main/content45.md) files. The generator locates these via the pattern `content<num>.md` relative to the issue number folder, keeping editorial content separate from presentation logic.

### Can the generator create a single issue without affecting others?

Yes. The [`make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/make_content.py) script accepts specific issue numbers as arguments (e.g., `python make_content.py 45`), allowing targeted updates to individual monthly issues while leaving the rest of the series unchanged.

### What are the exact placeholder strings used in the template?

The template uses two specific mustache-style markers: `{{ hello_github_content }}` for article injection and `{{ hello_github_num }}` for issue numbering. These constants are defined at lines 21–22 of [`script/make_content/make_content.py`](https://github.com/521xueweihan/HelloGitHub/blob/main/script/make_content/make_content.py) and must match exactly for the generation process to succeed.