CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jinja2

A very fast and expressive template engine for Python applications

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

extensions-custom-syntax.mddocs/

Extensions and Custom Syntax

Extensible plugin system for adding custom template syntax, processing logic, and integration with external tools. Includes built-in extensions for internationalization, loop controls, expression statements, and debugging.

Capabilities

Extension Base Class

Base class for implementing custom template extensions with hooks for preprocessing, parsing, and code generation.

class Extension:
    def __init__(self, environment):
        """
        Initialize extension.
        
        Parameters:
            environment: Jinja2 environment instance
        """
    
    def bind(self, environment):
        """
        Bind extension to different environment.
        
        Parameters:
            environment: New Jinja2 environment instance
            
        Returns:
            Extension: New extension instance bound to environment
        """
    
    def preprocess(self, source, name, filename=None):
        """
        Preprocess template source before parsing.
        
        Parameters:
            source: Template source code
            name: Template name
            filename: Template filename
            
        Returns:
            str: Preprocessed template source
        """
    
    def filter_stream(self, stream):
        """
        Filter token stream before parsing.
        
        Parameters:
            stream: Token stream iterator
            
        Returns:
            Iterator: Filtered token stream
        """
    
    def parse(self, parser):
        """
        Parse extension tags and return AST nodes.
        
        Parameters:
            parser: Jinja2 parser instance
            
        Returns:
            Node: AST node for extension functionality
        """
    
    def attr(self, name, lineno=None):
        """
        Create extension attribute node.
        
        Parameters:
            name: Attribute name
            lineno: Line number for debugging
            
        Returns:
            Node: Attribute access AST node
        """
    
    def call_method(self, name, args=None, kwargs=None, dyn_args=None, dyn_kwargs=None, lineno=None):
        """
        Create extension method call node.
        
        Parameters:
            name: Method name
            args: Method arguments
            kwargs: Method keyword arguments
            dyn_args: Dynamic arguments
            dyn_kwargs: Dynamic keyword arguments
            lineno: Line number for debugging
            
        Returns:
            Node: Method call AST node
        """

Internationalization Extension

Built-in extension for internationalization and localization support using gettext-style translation functions.

class InternationalizationExtension(Extension):
    """
    Extension for internationalization support.
    
    Adds:
        - {% trans %}...{% endtrans %} blocks for translatable text
        - {% pluralize %} for plural forms within trans blocks
        - Automatic message extraction for translation tools
    
    Usage:
        env = Environment(extensions=['jinja2.ext.i18n'])
        env.install_gettext_translations(translations)
    """

Usage example:

from jinja2 import Environment
import gettext

# Setup translations
translations = gettext.translation('messages', 'locale', languages=['es'])

env = Environment(extensions=['jinja2.ext.i18n'])
env.install_gettext_translations(translations)

template_str = '''
{% trans %}Hello World!{% endtrans %}
{% trans count=items|length %}
There is {{ count }} item.
{% pluralize %}
There are {{ count }} items.
{% endtrans %}
'''

Expression Statement Extension

Extension that adds the {% do %} tag for executing expressions without output.

class ExprStmtExtension(Extension):
    """
    Extension that adds {% do %} tag for expression statements.
    
    Adds:
        - {% do expression %} for executing expressions without output
        - Useful for variable assignments and side effects
    
    Usage:
        env = Environment(extensions=['jinja2.ext.do'])
    """

Usage example:

from jinja2 import Environment

env = Environment(extensions=['jinja2.ext.do'])

template_str = '''
{% set items = [] %}
{% do items.append('first') %}
{% do items.extend(['second', 'third']) %}
Items: {{ items | join(', ') }}
'''

Loop Controls Extension

Extension that adds {% break %} and {% continue %} statements for loop control.

class LoopControlsExtension(Extension):
    """
    Extension that adds loop control statements.
    
    Adds:
        - {% break %} to exit loops early
        - {% continue %} to skip to next loop iteration
    
    Usage:
        env = Environment(extensions=['jinja2.ext.loopcontrols'])
    """

Usage example:

from jinja2 import Environment

env = Environment(extensions=['jinja2.ext.loopcontrols'])

template_str = '''
{% for item in items %}
    {% if item is number and item < 0 %}
        {% continue %}
    {% endif %}
    {% if item is string and item == 'STOP' %}
        {% break %}
    {% endif %}
    Item: {{ item }}
{% endfor %}
'''

Debug Extension

Extension that adds the {% debug %} tag for debugging template context and variables.

class DebugExtension(Extension):
    """
    Extension that adds {% debug %} tag for template debugging.
    
    Adds:
        - {% debug %} to print current template context
        - Useful for development and troubleshooting
    
    Usage:
        env = Environment(extensions=['jinja2.ext.debug'])
    """

Usage example:

from jinja2 import Environment

env = Environment(extensions=['jinja2.ext.debug'])

template_str = '''
User: {{ user.name }}
{% debug %}
Age: {{ user.age }}
'''

Extension Loading

Extensions can be loaded by name or class when creating environments.

# Load by string name
env = Environment(extensions=['jinja2.ext.i18n', 'jinja2.ext.do'])

# Load by class
from jinja2.ext import InternationalizationExtension, ExprStmtExtension
env = Environment(extensions=[InternationalizationExtension, ExprStmtExtension])

# Add after environment creation
env.add_extension('jinja2.ext.loopcontrols')
env.add_extension(DebugExtension)

Custom Extension Development

Basic Custom Extension

Example of creating a custom extension that adds a {% cache %} tag:

from jinja2 import nodes
from jinja2.ext import Extension

class CacheExtension(Extension):
    tags = {'cache'}  # Tags handled by this extension
    
    def parse(self, parser):
        lineno = next(parser.stream).lineno
        
        # Parse cache key
        cache_key = parser.parse_expression()
        
        # Parse optional timeout
        timeout = None
        if parser.stream.current.test('name:for'):
            next(parser.stream)  # consume 'for'
            timeout = parser.parse_expression()
        
        # Parse body
        node = parser.parse_statements(['name:endcache'], drop_needle=True)
        
        # Create cache node
        return self.call_method('_cache_support', 
                              [cache_key, timeout, nodes.List(node)],
                              lineno=lineno)
    
    def _cache_support(self, cache_key, timeout, body):
        """Runtime cache support method."""
        # Implementation would check cache, render if needed, store result
        cache = getattr(self.environment, '_cache', {})
        
        if cache_key in cache:
            return cache[cache_key]
        
        # Render body and cache result
        result = ''.join(body)
        cache[cache_key] = result
        
        if not hasattr(self.environment, '_cache'):
            self.environment._cache = cache
            
        return result

# Usage
env = Environment(extensions=[CacheExtension])
template_str = '''
{% cache 'expensive_computation' for 300 %}
    {{ expensive_function() }}
{% endcache %}
'''

Advanced Extension Features

Extensions can modify parsing behavior, add global functions, and integrate with the compilation process:

class AdvancedExtension(Extension):
    def __init__(self, environment):
        super().__init__(environment)
        # Add global functions
        environment.globals['custom_func'] = self.custom_function
    
    def preprocess(self, source, name, filename=None):
        # Modify source before parsing
        return source.replace('[[', '{%').replace(']]', '%}')
    
    def filter_stream(self, stream):
        # Modify token stream
        for token in stream:
            if token.type == 'name' and token.value == 'old_keyword':
                token = token._replace(value='new_keyword')
            yield token
    
    def custom_function(self, *args, **kwargs):
        """Custom global function available in templates."""
        return f"Custom: {args} {kwargs}"

Utility Functions

def babel_extract(fileobj, keywords, comment_tags, options):
    """
    Babel message extraction function for i18n extension.
    
    Parameters:
        fileobj: File-like object containing template source
        keywords: Extraction keywords
        comment_tags: Comment tags to extract
        options: Extraction options
        
    Returns:
        Iterator: Extracted messages with line numbers and context
    """

Types

class ExtensionEnvironment:
    """
    Extension execution environment providing access to parsing and compilation context.
    
    Attributes:
        environment: Jinja2 environment instance
        parser: Current parser instance (during parsing)
        compiler: Current compiler instance (during compilation)
    """

class ExtensionRegistry:
    """
    Registry for managing loaded extensions and their capabilities.
    
    Attributes:
        extensions: Dictionary of loaded extension instances
        tags: Set of all registered tag names
    """

docs

bytecode-caching.md

environment-templates.md

error-handling-debugging.md

extensions-custom-syntax.md

filters-data-processing.md

index.md

meta-analysis.md

native-types.md

security-sandboxing.md

template-loaders.md

tests-conditionals.md

tile.json