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)
| File | Size | Uploaded | |
|---|---|---|---|
| flask-themer-2.0.0.tar.gz | 7.0 kB | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|