Fast and simple WSGI micro web-framework for small web applications with no dependencies other than the Python Standard Library.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Built-in template engine with support for external template systems including Jinja2, Mako, and Cheetah, plus template rendering functions and decorators.
Render templates with data and use templates as decorators.
def template(name, **kwargs):
"""
Render a template with keyword arguments.
Parameters:
- name: str, template name or template string
- **kwargs: template variables
Returns:
str: rendered template
"""
def view(tpl_name, **defaults):
"""
Decorator that renders a template with the return value of the wrapped function.
Parameters:
- tpl_name: str, template name
- **defaults: default template variables
Returns:
function: decorator function
"""
def mako_template(name, **kwargs):
"""
Render a Mako template.
Parameters:
- name: str, template name
- **kwargs: template variables
Returns:
str: rendered template
"""
def jinja2_template(name, **kwargs):
"""
Render a Jinja2 template.
Parameters:
- name: str, template name
- **kwargs: template variables
Returns:
str: rendered template
"""
def cheetah_template(name, **kwargs):
"""
Render a Cheetah template.
Parameters:
- name: str, template name
- **kwargs: template variables
Returns:
str: rendered template
"""
def mako_view(tpl_name, **defaults):
"""
View decorator using Mako template engine.
Parameters:
- tpl_name: str, template name
- **defaults: default template variables
Returns:
function: decorator function
"""
def jinja2_view(tpl_name, **defaults):
"""
View decorator using Jinja2 template engine.
Parameters:
- tpl_name: str, template name
- **defaults: default template variables
Returns:
function: decorator function
"""
def cheetah_view(tpl_name, **defaults):
"""
View decorator using Cheetah template engine.
Parameters:
- tpl_name: str, template name
- **defaults: default template variables
Returns:
function: decorator function
"""Usage:
# Direct template rendering
@route('/hello/<name>')
def hello(name):
return template('hello.html', name=name, title='Greeting')
# Template decorator
@route('/user/<id:int>')
@view('user.html')
def show_user(id):
user = get_user(id)
return {'user': user, 'title': f'User {id}'}
# Inline template
@route('/simple')
def simple():
return template('<h1>Hello {{name}}!</h1>', name='World')Bottle's SimpleTemplate engine with Python-like syntax.
class SimpleTemplate:
def __init__(self, source, **options):
"""
Create template from source string.
Parameters:
- source: str, template source code
- **options: template options (name, filename, lookup, encoding, etc.)
"""
def render(self, **kwargs):
"""
Render template with variables.
Parameters:
- **kwargs: template variables
Returns:
str: rendered template
"""
@property
def code(self) -> str:
"""Generated Python code for this template."""
@property
def syntax(self) -> str:
"""Template syntax tokens."""
def set_syntax(self, syntax):
"""Set template syntax tokens."""Template syntax:
<!-- Simple variable substitution -->
<h1>Hello {{name}}!</h1>
<!-- Python expressions -->
<p>Price: ${{price * 1.08}}</p>
<!-- Conditional statements -->
% if user.is_admin:
<p>Admin panel</p>
% end
<!-- Loops -->
% for item in items:
<li>{{item.name}} - ${{item.price}}</li>
% end
<!-- Include other templates -->
% include('header.html')
<!-- Python code blocks -->
<%
import datetime
now = datetime.datetime.now()
%>
<p>Generated at {{now}}</p>Adapters for popular Python template engines.
class Jinja2Template:
def __init__(self, source, **options):
"""
Jinja2 template adapter.
Parameters:
- source: str, template source or filename
- **options: Jinja2 environment options
"""
def render(self, **kwargs):
"""Render Jinja2 template with variables."""Usage:
# Configure Jinja2
from bottle import Jinja2Template
Jinja2Template.settings = {
'autoescape': True,
'loader': jinja2.FileSystemLoader('./templates')
}
@route('/jinja/<name>')
@view('hello.j2', template_adapter=Jinja2Template)
def jinja_hello(name):
return {'name': name}class MakoTemplate:
def __init__(self, source, **options):
"""
Mako template adapter.
Parameters:
- source: str, template source or filename
- **options: Mako template options
"""
def render(self, **kwargs):
"""Render Mako template with variables."""class CheetahTemplate:
def __init__(self, source, **options):
"""
Cheetah template adapter.
Parameters:
- source: str, template source or filename
- **options: Cheetah template options
"""
def render(self, **kwargs):
"""Render Cheetah template with variables."""Configure template search paths and caching.
class BaseTemplate:
settings = {} # Global template settings
@classmethod
def search(cls, name, lookup=None):
"""
Search for template file.
Parameters:
- name: str, template name
- lookup: list, search paths
Returns:
str: template file path
"""
@classmethod
def global_config(cls, key, *args):
"""Get or set global template configuration."""Configuration options:
# Set template search paths
SimpleTemplate.settings['lookup'] = ['./templates', './views']
# Enable template caching
SimpleTemplate.settings['cache'] = True
# Set default encoding
SimpleTemplate.settings['encoding'] = 'utf-8'
# Custom template syntax
SimpleTemplate.settings['syntax'] = '<% %> % {{ }}'Automatic template rendering plugin for return values.
class TemplatePlugin:
def __init__(self):
"""Template plugin for automatic template rendering."""
def apply(self, callback, route):
"""Apply plugin to route callback."""The template plugin automatically renders templates when:
Template file discovery and loading.
def cached_property(func):
"""Decorator for cached template properties."""
class ResourceManager:
def __init__(self):
"""Manage template and resource files."""
def add_path(self, path):
"""Add template search path."""
def lookup(self, name):
"""Find template file in search paths."""Template-specific exceptions.
class TemplateError(BottleException):
def __init__(self, message):
"""Base template error exception."""
class StplSyntaxError(TemplateError):
def __init__(self, message, source=None, line=None):
"""Simple template syntax error."""Using template inheritance with external engines:
# With Jinja2
@route('/page')
@view('page.j2', template_adapter=Jinja2Template)
def page():
return {
'title': 'My Page',
'content': 'Page content here'
}Template file (page.j2):
{% extends "base.j2" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<p>{{ content }}</p>
{% endblock %}Create custom template engine adapters:
class CustomTemplate:
def __init__(self, source, **options):
self.source = source
self.options = options
def render(self, **kwargs):
# Custom rendering logic
return self.source.format(**kwargs)
# Use custom adapter
@route('/custom')
@view('template.txt', template_adapter=CustomTemplate)
def custom():
return {'message': 'Hello Custom!'}Global template context and helpers:
# Add global template functions
import bottle
def url_for(route_name, **kwargs):
return bottle.url(route_name, **kwargs)
def current_user():
return request.environ.get('user')
# Make available in templates
SimpleTemplate.defaults = {
'url_for': url_for,
'current_user': current_user,
'app_name': 'My App'
}Install with Tessl CLI
npx tessl i tessl/pypi-bottle