Note
If you already have a Flask project which you want to convert to static html, Flask-Frozen is up to the task.
If you just want to generate static HTML, refer to Which Static Site Generator To Use.
The latest version is Version 0.15
(Jun 27, 2017
), but it generally works well.
Another issues that it is pretty slow as it run in sequential (about 1 page per second) and hardly utilize a single CPU fully. It might be possible to hack the code to utilize multiple CPU.
Install & Setup
pip install Frozen-Flask
Create static.py
# import flask app from your existing applicationfrom application import appfrom flask_frozen import Freezer# optional# from flask_minify import minify# minify(app=app, html=True, caching_limit=0) # , js=True, cssless=True# default to application root directory (same level as "templates") named "build"FREEZER_DESTINATION = '../build' # MimetypeMismatchWarning: Filename extension of u'new-york' (type application/octet-stream) does not match Content-Type: text/html; charset=utf-8# If the urls are '/new-york', it will warn of MimetypeMismatchWarning# You could either disable warning, or change path to '/new-york/', which generate 'new-york/index.html'FREEZER_IGNORE_MIMETYPE_WARNINGS = True# If run the static generation for 30 minutes and then it crashed, this will only generate files which are not generated yet (basically continue from last run)# If you change the page code and the content is different, it will not regenerate the pageFREEZER_SKIP_EXISTING = True# This is useful during development as you might want to remove certain @freezer.register_generator to speed up the process, but don't want those generated files to be deletedFREEZER_REMOVE_EXTRA_FILES = False# load the above FREEZER_ configurationsapp.config.from_object(__name__)freezer = Freezer(app, with_static_files=True, log_url_for=False, with_no_argument_rules=False)@freezer.register_generatordef url_generator(): yield '/' yield '/about'@freezer.register_generatordef venues_generator(): from application.models import Venue items = Venue.query(Venue.is_active == True) for _item in items: # yield f"/venues/{_item.url_name}" yield 'venue.show', {'url_name': _item.url_name}if __name__ == '__main__': freezer.freeze()
python static.py
Flask Routing
If the route is @app.route('/about')
, it will generate about
file.
If the route is @app.route('/about/')
, it will generate about/index.html
file.
If the route @app.route('/about/privacy')
, you must change @app.route('/about')
to @app.route('/about/')
, as generated about
must be a directory in order for privacy
to be generated within it.
└── about
├── index.html
└── privacy
NOTE: You can use @app.route('/about/', strict_slashes=False)
for optional trailing slashes, and still generate about/index.html
.
References: