Skip to main content

A Python template engine with support for variables, functions, conditionals, loops, and includes

Project description

๐Ÿš€ Python Template Engine

A powerful, lightweight template engine for Python with support for variables, functions, conditionals, loops, and file includes. Built for simplicity and extensibility.

PyPI version Tests Python License Downloads

โœจ Features

  • ๐Ÿ”ค Variable substitution - {{name}}, {{user.email}}
  • โšก Function calls - {{get_time()}}, {{utils.format()}}
  • ๐Ÿ”€ Conditionals - {{#IF condition}}...{{#ELSE}}...{{/IF}}
  • ๐Ÿ”„ Loops - {{#EACH items AS item}}...{{/EACH}}
  • ๐Ÿ“„ File includes - {{#INCLUDE file_path}}
  • ๐ŸŽจ Template rendering - {{#RENDER template_path}}
  • ๐Ÿงช Fully tested - Comprehensive test suite with 73 tests
  • ๐ŸŽฏ Type hints - Full type annotation support
  • ๐Ÿ—๏ธ Extensible - Modular architecture for custom engines

๐Ÿš€ Quick Start

Installation

From PyPI (Recommended)

# Install from PyPI
pip install py-template-engine

From Source

# Clone the repository
git clone https://github.com/zimmer-yan/py-template-engine.git
cd py-template-engine

# Create virtual environment (recommended)
python3 -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install in development mode
pip install -e .

Direct from GitHub

# Install directly from GitHub
pip install git+https://github.com/zimmer-yan/py-template-engine.git

Basic Usage

from py_template_engine import TemplateEngine

# Simple variable substitution
template = "Hello {{name}}!"
engine = TemplateEngine(template_string=template)
result = engine.render(name="World")
print(result)  # Output: Hello World!

๐Ÿ“– Template Syntax

Variables

<!-- Basic variables -->
<h1>{{title}}</h1>
<p>Welcome {{user.name}}!</p>

<!-- Nested object access -->
<span>{{user.profile.email}}</span>

Functions

<!-- Function calls -->
<p>Current time: {{get_time()}}</p>
<p>Formatted date: {{utils.format_date()}}</p>

Conditionals

<!-- IF/ELSE statements -->
{{#IF user_logged_in}}
    <p>Welcome back, {{username}}!</p>
{{#ELSE}}
    <p>Please log in to continue</p>
{{/IF}}

<!-- Nested conditions -->
{{#IF user}}
    {{#IF user.is_premium}}
        <span class="premium">Premium User</span>
    {{/IF}}
{{/IF}}

Loops

<!-- EACH loops -->
<ul>
{{#EACH items AS item}}
    <li>{{item}}</li>
{{/EACH}}
</ul>

<!-- Loop with objects -->
{{#EACH users AS user}}
    <div class="user">
        <h3>{{user.name}}</h3>
        <p>{{user.email}}</p>
    </div>
{{/EACH}}

File Operations

<!-- Include raw file content -->
{{#INCLUDE includes/header.html}}

<!-- Render template with full processing -->
{{#RENDER user_template}}

๐Ÿ’ก Advanced Examples

Complete Web Page Template

<!DOCTYPE html>
<html>
<head>
    <title>{{page_title}}</title>
</head>
<body>
    {{#INCLUDE header.html}}
    
    <main>
        {{#IF featured_posts}}
            <section class="featured">
                <h2>Featured Posts</h2>
                {{#EACH featured_posts AS post}}
                    <article>
                        <h3>{{post.title}}</h3>
                        <p>{{post.excerpt}}</p>
                        <time>{{post.format_date()}}</time>
                    </article>
                {{/EACH}}
            </section>
        {{/IF}}
        
        {{#RENDER templates/blog_content.html}}
    </main>
    
    {{#INCLUDE footer.html}}
</body>
</html>
from py_template_engine import TemplateEngine

engine = TemplateEngine(template_path="page.html")
result = engine.render(
    page_title="My Blog",
    featured_posts=[
        {
            "title": "Getting Started",
            "excerpt": "Learn the basics...",
            "format_date": lambda: "2024-01-15"
        }
    ],
)

Dynamic Dashboard

# Context data
dashboard_data = {
    "user": {
        "name": "Alice Johnson",
        "role": "admin",
        "notifications": 5
    },
    "stats": [
        {"label": "Users", "value": 1247},
        {"label": "Revenue", "value": "$52,340"},
        {"label": "Orders", "value": 89}
    ],
    "is_admin": True,
    "get_alert_class": lambda count: "danger" if count > 10 else "info"
}

template = """
<div class="dashboard">
    <h1>Welcome {{user.name}}</h1>
    
    {{#IF is_admin}}
        <div class="admin-panel">
            <h2>Admin Controls</h2>
            <p>Notifications: <span class="{{get_alert_class()}}">{{user.notifications}}</span></p>
        </div>
    {{/IF}}
    
    <div class="stats">
        {{#EACH stats AS stat}}
            <div class="stat-card">
                <h3>{{stat.label}}</h3>
                <p class="value">{{stat.value}}</p>
            </div>
        {{/EACH}}
    </div>
</div>
"""

engine = TemplateEngine(template_string=template)
result = engine.render(**dashboard_data)

๐Ÿ—๏ธ API Reference

TemplateEngine

class TemplateEngine:
    def __init__(self, template_path: Optional[str] = None, 
                 template_string: Optional[str] = None) -> None:
        """
        Initialize template engine with either file path or string.
        
        Args:
            template_path: Path to template file
            template_string: Template content as string
            
        Raises:
            ValueError: If neither template_path nor template_string provided
        """
    
    def render(self, **kwargs) -> str:
        """
        Render template with provided context variables.
        
        Args:
            **kwargs: Template context variables
            
        Returns:
            Rendered template as string
        """

๐Ÿงช Testing

Run the comprehensive test suite:

# Activate virtual environment
source .venv/bin/activate

# Run all tests with pytest
pytest tests -v

# Run specific test file
python tests/test_template_engine.py

# Run with coverage
pytest tests --cov=py_template_engine

Test Coverage: 63 tests covering all features:

  • Variable substitution (basic + nested)
  • Function calls (simple + nested objects)
  • Conditional logic (IF/ELSE + nested)
  • Loop processing (EACH + complex data)
  • File operations (INCLUDE + RENDER)
  • Error handling & edge cases

๐Ÿ”ง Development

Project Structure

py-templater/
โ”œโ”€โ”€ py_template_engine/          # Main package
โ”‚   โ”œโ”€โ”€ __init__.py
โ”‚   โ”œโ”€โ”€ TemplateEngine.py        # Main engine
โ”‚   โ”œโ”€โ”€ TemplaterInterface.py
โ”‚   โ””โ”€โ”€ sub_engines/             # Individual processors
โ”‚       โ”œโ”€โ”€ VariableTemplater.py
โ”‚       โ”œโ”€โ”€ FunctionTemplater.py
โ”‚       โ”œโ”€โ”€ IfTemplater.py
โ”‚       โ”œโ”€โ”€ EachTemplater.py
โ”‚       โ”œโ”€โ”€ IncludeTemplater.py
โ”‚       โ””โ”€โ”€ RenderTemplater.py
โ”œโ”€โ”€ tests/                       # Test suite
โ”œโ”€โ”€ examples/                    # Usage examples
โ””โ”€โ”€ pyproject.toml              # Project configuration

Adding Custom Engines

Create custom template processors by extending TemplaterInterface:

from py_template_engine.TemplaterInterface import TemplaterInterface
import re

class CustomTemplater(TemplaterInterface):
    def render(self, template: str, **kwargs) -> str:
        return re.sub(
            r'{{#CUSTOM (.*?)}}',
            lambda m: self.process(m.group(1), **kwargs),
            template
        )
    
    def process(self, content: str, **kwargs) -> str:
        # Custom processing logic
        return f"Processed: {content}"

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Write tests for your changes
  4. Ensure all tests pass (pytest tests)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.


Happy templating! ๐ŸŽ‰

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_template_engine-0.2.0.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_template_engine-0.2.0-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file py_template_engine-0.2.0.tar.gz.

File metadata

  • Download URL: py_template_engine-0.2.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for py_template_engine-0.2.0.tar.gz
Algorithm Hash digest
SHA256 2b3594cf31ad293b106fc2a96996b84ebdfe1576bca74251766946002a74c56b
MD5 9fb5303e9ec38680f6f62cb2f2207b02
BLAKE2b-256 d85801a5d157de73684dbf5fc0895f807a45ac2a5d86323036638befe637468b

See more details on using hashes here.

File details

Details for the file py_template_engine-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for py_template_engine-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8abce14e4076e76faa37cd3f7d09044028217ca746ff6c59ffc392b324e88cb0
MD5 b7d934d99e895819dec6f38a4b8fe56a
BLAKE2b-256 61bd3058628c17ad3be5dca9b2f53d465b4c8d6a7f47190d0354b99231b242b3

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page