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 Coverage 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.6.tar.gz (13.5 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.6-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: py_template_engine-0.2.6.tar.gz
  • Upload date:
  • Size: 13.5 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.6.tar.gz
Algorithm Hash digest
SHA256 5104255123e2076f62c8ce3115ee0db4743577c1c5804549f25efb239aef5422
MD5 653852dcbae398188fbbef58dd4c3c8d
BLAKE2b-256 346536369a9230234712139aac004325d729ec6f97c7c11ad5d440abe5400a29

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for py_template_engine-0.2.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b241e4ef64137157b762500e9fff537b0bef24e59537e5d287cc7c2e9fce038e
MD5 7c225dc5d95f181e62d6f4ba55d54d01
BLAKE2b-256 2a109f1e5533343faecc2bfd4c683916eb9cc17f30ab01fc327f4e4038a13e13

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