Skip to main content

PyPI PyPI - License GitHub Workflow Status

Flask-Themer

Simple theme support for flask apps.

Flask-Themer is inspired by the (seemingly) abandoned flask-themes project, but has been written from scratch for Python 3.8+. However, it is not immediately compatible with flask-themes and does not seek to be. Flask-Themer tries to have little opinion on how you actually structure your project and its themes and does not require a particular metadata format/file.

Flask-Themer releases follow Semantic Versioning. Flask-Themer has 100% test coverage and considers it an error to fall below 100%.

Installation

Install the latest release from PyPi:

pip install flask-themer

or get the latest development version from GitHub:

git clone https://github.com/TkTech/flask-themer.git
cd flask-themer
python setup.py develop

Quickstart

Flask-Themer usage is usually very basic, and once setup you likely won't need to touch it again. Let's do a quickstart. Notice how we import render_template from flask_themer instead of flask.

Our app.py looks like this:

from flask import Flask
from flask_themer import Themer, render_template

app = Flask(__name__)
themer = Themer(app)


@themer.current_theme_loader
def get_current_theme():
    # This is where you would look up the current user's theme if one was
    # logged in, for example.
    return 'default'

@app.route('/')
def hello_world():
    return render_template('hello.html')

And next to it we have a directory called themes with a directory called default inside of it. Our themes/default/hello.html looks like this:

Hello world!

That's it! By default Flask-Themer will look for a themes directory next to your project and assume all the directories inside of it are themes. You can change what directory it looks for with THEMER_DEFAULT_DIRECTORY, or specify the template loaders explicitly to overwrite the default:

from flask_themer import Themer, FileSystemThemeLoader

app = Flask(__name__)
themer = Themer(app, loaders=[
    FileSystemThemeLoader(app, os.path.join(
        app.root_path,
        'also_themes'
    ))
])

Using Themes From Templates

Two template globals are added once Flask-Themer is setup, theme() and theme_static() (just like flask-themes). These methods look up the currently active theme and look for the given path in that theme, returning a special path that Jinja can use to load it.

{% extends theme("base.html") %}

{% block header %}
    {{ super() }}
    <link rel="stylesheet" href="{{ theme_static("bootstrap.css") }}">
{% endblock %}

Themes can also extend other themes using the theme argument:

{% extends theme("base.html", theme="my_parent_theme") %}

Theme Loaders

Theme loaders are the mechanism by which Flask-Themer discovers what themes are available. You can create a custom loader to get themes from a ZIP file, or a database for example. Usually if you create a new ThemeLoader you'll also need to create a new Jinja template loader so Jinja knows how to read individual templates. Lets do a very minimal example that loads just a single theme from a ZIP file.

from zipfile import ZipFile
from flask_themer import ThemeLoader, Theme
from jinja2.loaders import BaseLoader, TemplateNotFound

class ZipFileTemplateLoader(BaseLoader):
    def __init__(self, *args, archive, **kwargs):
        super().__init__(*args, **kwargs)
        self.archive = archive

    def get_source(self, environment, template):
        try:
            return (self.archive.read(template), None, False)
        except KeyError:
            raise TemplateNotFound(template)


class ZipFileThemeLoader(ThemeLoader):
    def __init__(self, path_to_zip):
        self.archive = ZipFile(path_to_zip)

    @property
    def themes(self):
        yield Theme(
            name='my_dumb_theme',
            theme_loader=self,
            jinja_loader=ZipFileTemplateLoader(archive=self.archive),
        )

    def get_static(self, theme, path):
        return self.archive.read(path)

And then to use our new loaders we update our previous example:

...
themer = Themer(app, loaders=[
    ZipFileThemeLoader('my_dumb_theme.zip')
])
...

Pretty simple right? You can see how we could easily create a loader to load multiple themes from an archive, or load a user's customized theme from a database.

Metadata

Release files for flask-themer 2.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flask-themer 2.0.0
File Size Uploaded
flask-themer-2.0.0.tar.gz 7.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for flask-themer 2.0.0
File Interpreter ABI Platform
flask_themer-2.0.0-py3.8.egg Legacy Egg format - - Details
flask_themer-2.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.1 kB

Release files / flask-themer-2.0.0.tar.gz

Download URL flask-themer-2.0.0.tar.gz
Size 7.0 kB
Tags Source
SHA-256 checksum
How to use checksums
c8dbea370ad88d9d13e5d0c360f9678bb219bfbab7a7d0cb4f00ff89ac09a275
BLAKE2b-256 checksum
How to use checksums
46d5af8aad885ea0b96425adda4c24f2f2e30c12770d478f27b2f3895bacf184
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.8.16

Release files / flask_themer-2.0.0-py3.8.egg

Download URL flask_themer-2.0.0-py3.8.egg
Size 10.1 kB
Tags Egg
SHA-256 checksum
How to use checksums
bea76d0833a7a4db217822327b1d53604e34320123f03fd30686a311beabc9f0
BLAKE2b-256 checksum
How to use checksums
4d95e5640f821b07f230423b5ff642f8db76caf8aa0cf59202d4242f60ca173f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.8.16

Release files / flask_themer-2.0.0-py3-none-any.whl

Download URL flask_themer-2.0.0-py3-none-any.whl
Size 6.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e34cc5bccf4fafb7d04f5de6e2219cc001f6485f7b0640dc5b728f8de88c2b57
BLAKE2b-256 checksum
How to use checksums
f3ed806e4e8079ea0a7e9b0df3fb6e45af97c0377924cfbd664c0f1353e88144
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.8.16

Release history Release notifications | RSS feed

This release

2.0.0 This release

3 release files

1.4.3

3 release files

1.4.1

3 release files

1.4.0

3 release files

1.3.0

3 release files

1.2.0

3 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page