Template Inheritance
Template Inheritance
Section titled “Template Inheritance”Template inheritance is one of YAPL’s most powerful features, allowing you to create a hierarchy of templates where child templates can extend parent templates, inheriting their structure while customizing specific parts.
Basic Inheritance
Section titled “Basic Inheritance”Parent Template
Section titled “Parent Template”Create a base template base/system.md.yapl
:
# System Prompt
{% block persona %} You are a helpful AI assistant.{% endblock %}
{% block output_format %} Respond in markdown format.{% endblock %}
{% block guidance %} Be concise and accurate.{% endblock %}
Child Template
Section titled “Child Template”Create a child template that extends the base:
{% extends "base/system.md.yapl" %}
{% block persona %} You are a specialized coding assistant with expertise in {{ language | default("programming") }}.{% endblock %}
{% block guidance %} {{ super() }} Always include code examples when relevant.{% endblock %}
When rendered, the child template inherits the structure from the parent but overrides specific blocks.
The extends
Directive
Section titled “The extends Directive”The {% extends %}
directive must be the first non-comment line in a template:
{# This is a comment - OK before extends #}{% extends "path/to/parent.yapl" %}
{# Everything else comes after extends #}{% block content %} ...{% endblock %}
Path Resolution
Section titled “Path Resolution”Template paths are resolved relative to the current template’s directory:
prompts/├── base/│ └── agent.md.yapl├── specialized/│ └── coder.md.yapl # extends "../base/agent.md.yapl"└── tasks/ └── review.md.yapl # extends "../base/agent.md.yapl"
Blocks
Section titled “Blocks”Blocks define sections that can be overridden by child templates. Block names can contain letters, numbers, underscores, colons, and hyphens:
Defining Blocks
Section titled “Defining Blocks”{% block block_name %} Default content goes here.{% endblock %}
Overriding Blocks
Section titled “Overriding Blocks”Child templates can completely replace block content:
{% extends "base.yapl" %}
{% block persona %} You are a completely different assistant.{% endblock %}
The super()
Function
Section titled “The super() Function”Use {{ super() }}
to include the parent block’s content:
Extending Parent Content
Section titled “Extending Parent Content”# Parent template{% block guidance %} - Be helpful - Be accurate{% endblock %}
# Child template{% block guidance %} {{ super() }} - Include code examples - Explain your reasoning{% endblock %}
Result:
- Be helpful- Be accurate- Include code examples- Explain your reasoning
Conditional Super
Section titled “Conditional Super”{% block guidance %} {% if include_base_guidance %} {{ super() }} {% endif %} Additional specific guidance here.{% endblock %}
Best Practices
Section titled “Best Practices”1. Use Meaningful Block Names
Section titled “1. Use Meaningful Block Names”<!-- Good -->{% block interaction_guidelines %}{% block error_handling %}{% block output_formatting %}
<!-- Avoid -->{% block stuff %}{% block content %}{% block misc %}
2. Document Block Purpose
Section titled “2. Document Block Purpose”{# Define the agent's core personality and role #}{% block persona %} You are an AI assistant.{% endblock %}
{# Specify what the agent can and cannot do #}{% block capabilities %} You can help with various tasks.{% endblock %}
3. Use Super Strategically
Section titled “3. Use Super Strategically”<!-- Good - extends parent content -->{% block guidelines %} {{ super() }} - Additional specific guideline{% endblock %}
<!-- Good - replaces when needed -->{% block persona %} You are a completely different type of assistant.{% endblock %}
Template inheritance allows you to build sophisticated prompt hierarchies while maintaining clean, maintainable code. Combined with mixins and variables, it provides a powerful foundation for scalable prompt engineering.