| name | run2_placeholder-replacement |
| description | Robust pattern-based template processing with conditionals, data validation, and comprehensive placeholder replacement. |
Template Processing with Placeholders and Conditionals
Overview
Process Word document templates by:
- Handling conditional sections (keep/remove based on data)
- Replacing all placeholders with data values
- Validating complete replacement
Placeholder Pattern
Use double-brace format: {{PLACEHOLDER_NAME}}
placeholder = f"{{{{{key}}}}}"
Conditional Section Pattern
Format
{{IF_CONDITION_NAME}}content here{{END_IF_CONDITION_NAME}}
Both markers must be within the same paragraph or cell (inline).
Processing Logic
import re
def process_conditionals(text, data):
"""
Replace {{IF_KEY}}...{{END_IF_KEY}} sections.
- If data[KEY] is "Yes" (case-insensitive): keep content, remove markers
- Otherwise: remove entire section including markers
"""
pattern = r'\{\{IF_(\w+)\}\}(.*?)\{\{END_IF_\1\}\}'
def replacer(match):
key = match.group(1)
content = match.group(2)
condition_value = data.get(key, '').strip()
if condition_value.lower() == 'yes':
return content
else:
return ''
return re.sub(pattern, replacer, text, flags=re.DOTALL)
Complete Workflow
1. Load Data and Template
import json
from docx import Document
with open('data.json') as f:
data = json.load(f)
doc = Document('template.docx')
2. Process Conditionals
for para in doc.paragraphs:
para.text = process_conditionals(para.text, data)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
para.text = process_conditionals(para.text, data)
3. Replace Placeholders
def replace_all_placeholders(doc, data):
"""Replace all {{KEY}} placeholders with data values"""
for key, value in data.items():
placeholder = f"{{{{{key}}}}}"
value_str = str(value)
for para in doc.paragraphs:
if placeholder in para.text:
para.text = para.text.replace(placeholder, value_str)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
if placeholder in para.text:
para.text = para.text.replace(placeholder, value_str)
replace_all_placeholders(doc, data)
4. Validate and Save
def verify_no_placeholders(doc):
"""Check that all placeholders have been replaced"""
remaining = []
for para in doc.paragraphs:
if '{{' in para.text:
remaining.append(para.text)
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
if '{{' in para.text:
remaining.append(para.text)
return remaining
remaining = verify_no_placeholders(doc)
if remaining:
print(f"Warning: {len(remaining)} unreplaced placeholders found")
for text in remaining:
print(f" {text}")
else:
print("All placeholders successfully replaced")
doc.save('output.docx')
Data Type Handling
Converting to String
All values are converted to strings:
value_str = str(value)
Handling Missing Keys
By default, data.get(key, '') returns empty string if key missing.
For safer processing:
def replace_with_validation(doc, data):
for key, value in data.items():
if not isinstance(value, (str, int, float)):
value = str(value)
Regex Considerations
Conditional Pattern with DOTALL
Use re.DOTALL (or re.S) for patterns spanning multiple lines if content contains newlines:
re.sub(pattern, replacer, text, flags=re.DOTALL)
Case-Insensitive Comparison
For conditions:
if condition_value.lower() == 'yes':
Robustness Checklist