Templates
Since v1.0, Flask S3 Viewer ships a single unified UI built with
Tailwind CSS + HTMX, with light/dark mode and inline heroicons.
The legacy base/ and mdl/ template bundles are removed and the
template_namespace constructor argument is deprecated — passing it
emits DeprecationWarning and is otherwise ignored.
Use the CLI to scaffold a copy of the bundled templates into your own
repository, edit them, then point the viewer at the scaffolded
directory via template_folder=.
Scaffold the templates
See help.
flask_s3_viewer -h
=================== Flask S3Viewer Command Line Tool ====================
optional arguments:
-h, --help show this help message and exit
-p PATH, --path PATH Enter the directory path where the template will be
located.
--with-static Also copy the bundled static assets (CSS / HTMX /
core.js) alongside the templates.
Copy just the Jinja templates (most common):
flask_s3_viewer -p ./fsv-templates
Or fork the whole UI bundle (templates + static/css/app.css + HTMX +
core.js) when you need to restyle from scratch:
flask_s3_viewer -p ./fsv-templates --with-static
After scaffolding, the directory contains:
layout.html— page chrome, theme toggle, brand widget,extra_headblockfiles.html— full listing page_file_list.html— HTMX partial swapped on navigation / search / pagination_pagination.html— pager partial_upload_form.html— upload UI partialerror.html/_error_panel.html— error states
Wire the override
Point the viewer at the scaffolded directory:
1FlaskS3Viewer(
2 app,
3 namespace='my-bucket',
4 template_folder='./fsv-templates',
5 config={...},
6)
Behind the scenes the extension prepends a FileSystemLoader to the
Flask app’s Jinja loader via ChoiceLoader, so any template you
didn’t override still resolves against the bundled defaults and other
blueprints’ templates remain unaffected.
Inject CSS / JS without forking
For the common case where you only need to add a stylesheet, script, or
meta tag, extend layout.html and use the extra_head block — no
template_folder= needed if you place this template on Flask’s
existing search path:
{% extends "flask_s3_viewer/layout.html" %}
{% block extra_head %}
<link rel="stylesheet" href="{{ url_for('static', filename='custom.css') }}">
{% endblock %}
Branding without overriding templates
If you only want a custom title and logo, prefer the constructor options over a template override:
1FlaskS3Viewer(
2 app,
3 namespace='my-bucket',
4 title='ACME File Vault',
5 logo_path='/opt/acme/assets/logo.svg', # local file, auto-inlined as data: URI
6 # logo_url='https://cdn.acme.io/logo.svg', # alternatively, any URL
7 config={...},
8)
logo_path reads the file once at construction time and embeds it as
a data: URI, so you don’t need to expose it via a separate static
route. logo_url accepts any browser-resolvable URL. logo_path
takes precedence over logo_url when both are provided.