# Template Content Creation Workflow

**Last Updated:** 2026-03-25  
**Purpose:** Outline-first, block-by-block drafting for template pages—replace incremental word-count chasing with comprehensive content creation.

## Overview

This workflow parallels [CONTENT_CREATION_WORKFLOW_2026.md](../../content/blog/CONTENT_CREATION_WORKFLOW_2026.md) for blog posts. Template pages use **content blocks** (4–7 blocks) instead of H2s. Each block is written to full depth from the outline before moving on—no "add until word count."

**Cross-surface data map:** [CONTENT_CREATION_DATA_CHECKLIST.md](../../content/CONTENT_CREATION_DATA_CHECKLIST.md) compares blog orchestrators (`run-new-post-pipeline.php`, `run-post-improvement-pipeline.php`) with template orchestrators **`run-new-template-pipeline.php`** and **`run-template-improvement-pipeline.php`** and lists typical `data/` outputs.

**Step 0:** Ensure SISTRIX collected. Run `run-new-template-pipeline.php` without `--skip-sistrix` (pipeline rejects it). Output: `keywords-sistrix.json` with real API data.

## Data Flow

```mermaid
flowchart LR
    S[collect-template-keywords-sistrix] --> KW[keywords-sistrix.json]
    KW --> E
    A[collect-template-competitor-analysis] --> B[competitor-analysis.json]
    B --> C[analyze-template-competitor-depth]
    C -->     D[competitive-depth-analysis.md]
    D --> E[CONTENT_OUTLINE.md]
    KW --> E
    E --> F[generate-template-section-briefs]
    F --> G[data/section-briefs.md + section-briefs.json]
    G --> H[Content creation or generate-template-content-blocks --use-ai]
```

## Core Principles

1. **Outline-First:** No content writing until CONTENT_OUTLINE.md is complete with section briefs (key points, target words, formats per block)
2. **Block-by-Block Drafting:** Write one block at a time, to full depth from outline before moving on
3. **Sync to content-blocks.json:** Edit `content/content.md`; run `sync-template-content-blocks.php` to update JSON
4. **Completeness Over Word Count:** Focus on covering all outline key points, PAA, and content gaps—not hitting a number

## Prohibited

- **Incremental word-count chasing:** Adding filler sentences to reach target
- **"Add a paragraph here"** without outline-driven purpose
- **Patching content** piecemeal until word count
- **Adding filler** solely to reach target

## Workflow Steps

### Step 1: Complete Outline with Section Briefs

Before writing content:

1. Ensure CONTENT_OUTLINE.md has section briefs for each block:
   - **Target words:** ~X (from target ÷ block count)
   - **Key points:** 2–5 bullet points from PAA, competitor, content gaps
   - **Formats:** Table | List | Section
   - **PAA covered:** Which PAA questions this block addresses

2. Generate section briefs from data (outputs both .md and .json with PAA per block, competitor H2s, suggested internal links, format_recommendation from CONTENT_OUTLINE):

   ```bash
   php v2/scripts/templates/generate-template-section-briefs.php --template=id
   ```

3. **Review format_recommendation** in section-briefs.json: ensure at least one table, steps, or callout per template. When SERP_ANALYSIS or competitive-depth recommends tables (e.g. "Block 3: Add §622 BGB table"), set Planned format: section + table in CONTENT_OUTLINE for the matching block. Copy relevant items from `data/section-briefs.md` or use `data/section-briefs.json` for AI content generation. Update CONTENT_OUTLINE.md PAA matrix, competitor H2 mapping, or content gap checklist.

4. Run `check-template-outline-block-overlap.php` before writing; merge or rephrase overlapping blocks:

   ```bash
   php v2/scripts/templates/check-template-outline-block-overlap.php --template=id
   ```

5. Review [ANTI_FLUFF_CHECKLIST.md](../../content/blog/ANTI_FLUFF_CHECKLIST.md) before drafting—no filler.

6. **Redundancy check (outline):** For each block, verify it covers a distinct angle. No two blocks answer the same question.

### Step 2: Block-by-Block Drafting

Write each block in order:

1. **Open section brief** (from outline or data/section-briefs.md)
2. **Write to full depth** – 2+ paragraphs or 1 paragraph + list/table per block
3. **Cover all key points** from the section brief
4. **Include formats** (table, list) where recommended
5. **Ordio mentions in body** – Add 2–4 contextual Ordio mentions in the main content
6. **Internal links inline** – Integrate links to related tools, product pages naturally
7. **Do not move on** until the block meets depth requirements

Each block should be substantive—no placeholder or thin content.

**Per-block redundancy check:** Before moving to the next block, ask: "Did I repeat content from a previous block?" If yes, cut the repeat or replace with a cross-reference.

### Step 3: Sync to content-blocks.json

Edit `content/content.md` (one file per template). Sync when ready:

```bash
php v2/scripts/templates/sync-template-content-blocks.php --template=id
```

Do not apply incrementally. Sync when the full draft is complete.

**Generate vs sync:** `generate-template-content-blocks.php` creates scaffold from outline; it skips templates with >300 words to avoid overwriting. For templates with existing content, use `sync-template-content-blocks.php` to update JSON from content.md. Use `--force` with generate to overwrite.

### Step 3.5: Format and Heading Review

Before sync, verify:

- **No duplicate headings:** Block heading (H2 from component) is not repeated as H3 in content. Start blocks with intro paragraph or subsection H3.
- **H3 variety:** Subsections use varied phrasing—avoid "Compliance-Checkliste" or similar in every H3. Mix question-style ("Wie funktioniert...?") and declarative ("Deine Vorteile", "Prüfpunkte im Überblick").
- **Hierarchy:** H2 → H3 → H4 (no skipping). Cards: use H3 for card titles, not H4.

### Step 4: Validation

Run validation before finalizing (includes block type variety check):

```bash
# Block structure
php v2/scripts/templates/validate-template-content-blocks.php --template=id

# Competitor comparison (block count, word count, formats)
php v2/scripts/templates/compare-template-to-competitors.php --template=id

# Internal links (min 3, canonical URLs)
php v2/scripts/templates/validate-template-internal-links.php --template=id

# Content completeness (PAA, gaps, formats, definition)
php v2/scripts/templates/validate-template-content-completeness.php --template=id
```

All validators should pass. If validation fails, **address specific gaps**—do not add filler.

**AI content generation:** Use `generate-template-content-blocks.php --template=id --use-ai` to generate blocks via Gemini (requires section-briefs.json and GEMINI_API_KEY). Review [TEMPLATE_AEO_GEO_CHECKLIST.md](TEMPLATE_AEO_GEO_CHECKLIST.md) before finalizing.

## Learnings & Improvements

### lebenslauf-vorlage (2026-03-03)

**Key learnings:**

1. **Primary keyword normalization:** `validate-template-content-blocks.php` normalizes keywords (lowercase, spaces instead of hyphens) before checking presence. Ensure the exact normalized keyword appears in content body, not just frontmatter.

2. **FAQ JSON structure:** `add-template-faqs.php` expects `"answers"` key in `faq-answers-optimized.json`, not `"faqs"`. Verify JSON structure matches script expectations.

3. **Duplicate link detection:** Browser MCP analysis can identify duplicate internal links in content blocks. Consolidate duplicate links into single, contextual mentions.

4. **Internal link validation:** `validate-template-internal-links.php` requires minimum 3 unique internal URLs. Use `template-internal-link-targets.json` to identify relevant product/tool pages for contextual linking.

5. **OG image (pre-publish):** Add or confirm slug in `v2/scripts/og-images/og-image-specs.json`. For marketing parity, generate with Gemini right panel: add `VISUAL_DESCRIPTIONS` + `VISUAL_ONLY_PROMPTS` in `generate-og-image-gemini.py`, then `python3 v2/scripts/og-images/generate-og-images.py --type={template-slug} --gemini-visuals`. Wire `v2/config/og-image-registry.php` and run `validate-og-images.py` + `validate-og-logo.py`. Checklist: [NEW_PAGE_OG_AND_SOCIAL_CHECKLIST.md](../og-images/NEW_PAGE_OG_AND_SOCIAL_CHECKLIST.md). SVG-only generation is acceptable if Gemini is unavailable; do not ship with only the generic `template.webp` default.

6. **Schema validation:** Schema is automatically generated via `template-schema-generator.php` and includes FAQPage, Product, BreadcrumbList. Run `validate-template-faq-schema.php` to verify structure.

7. **Slug-keyword alignment:** `validate-template-slug-keyword-alignment.php` validates that template slugs match primary keywords. lebenslauf-vorlage passes validation (primary: "lebenslauf klassisch vorlage download").

8. **LLMs metadata:** `validate-llms-metadata.py` validates LLM context files. Ensure new template entries are added to both `llms.txt` and `llms-full.txt` with correct ACAO format.

9. **Internal linking from blog:** `add-template-to-related-carousels.php` automatically adds template to related blog posts based on keyword matching. Run after publication to maximize internal linking.

10. **Content sync:** Always run `sync-template-content-blocks.php` after editing `content.md` to keep `content-blocks.json` in sync.

**Process improvements:**

- Added duplicate link detection to browser validation checklist
- Clarified FAQ JSON structure requirements in workflow
- Documented primary keyword normalization behavior in validation scripts
- Added internal link target reference to workflow

## References

- [TEMPLATE_CONTENT_WORKFLOW.md](TEMPLATE_CONTENT_WORKFLOW.md)
- [TEMPLATE_CONTENT_DEPTH_GUIDELINES.md](TEMPLATE_CONTENT_DEPTH_GUIDELINES.md)
- [ANTI_FLUFF_CHECKLIST.md](../../content/blog/ANTI_FLUFF_CHECKLIST.md)
