Structure of project¶
A typical Almoststatic project has the following structure:
├── content
│ ├── include
│ ├── media
│ ├── pages
│ └── config.yaml
├── templates
├── flaskapp.py
└── write_static.py
flaskapp.py is a Flask app used to built your site. It can be minimalist if you only need to develop a static site or you can build a complete web app with some static contents.
write_static.py you can write a little script to write the static pages.
templates is the default location for Jinja template files, but you can add
custom folders to search before default folder or move templates
elsewhere.
content is the directory containing all directives and data for Almoststatic.
it should contains at least a media
folder for static contents, a pages
folder for page declarations, and a config.yaml
configuration file.
Note
Flask has it’s own standard method to deliver static
contents but with
Almoststatic it’s suggested to use it’s method because it’s easier to
configure and automate static generation, but if needed the two methods can
be combined, see sample in source code.
The content/media
folder¶
The media folder stores media (images, videos, etc…), css and javascript files.
You can create any subfolder structure based on your needs to organize your site,
then in templates and pages you can get them with get_media
command.
The content/pages
folder¶
This folder must contain only *.yaml
files with page declarations. It can
be structured in any subfolders structure and the url of pages will be the
same of the path plus the name of file.
Other content
subfolders¶
Pages can access to included
contents, see Embedding and including. You can
organize them into folders under content
folder.
The config.yaml
file¶
A typical config.yaml file looks like this:
---
# global configuration settings
config:
# home path for content yaml files
content: "content"
# home path for jinja2 templates
templates: ["custom","templates"]
# folder for yaml page files within content
pages: "pages"
# folder for media files within content
media: "media"
# name of default template for pages
templ_name: "page.html"
# url prefix for static pages
static_url: ""
# during development disable cache to enable auto reloading of templates
cache: True
# macros available in all pages
macros:
$flask: '[Flask](https://flask.palletsprojects.com){: target="_blank"}'
# default metadata for pages
meta:
title: "My page"
description: "A site built with Almoststatic"
author: "Almoststatic"
tags: [Almoststaic, Flask, Python, html]
generator: "Almoststatic"
# specific globals for this site
slogan: Build your own static and almost static sites with Almoststatic
MainMenu:
- name: Home
url: index
- name: Pages
drop:
- name: About
url: about
- name: Our products
url: products
- name: 404
static_out: True
url: nopage
- name: Static
static_out: True
url: write_static
The config
section contain configuration parameters, all can be omitted
if default values are ok.
Note
You can add folders to template directive, i.e. with templates: ["custom","templates"]
Template files first are searched in "custom"
folder and if not found in
"templates"
folder.
The meta
section contain default metadata values for pages, all can be
omitted.
The rest of definitions are free. This is a good place to store menus of site.
The content of config.yaml
file is also added to Jinja2 globals environment
variable so it is available on each page and each widget as a dict. So if you
have a custom menu called EnglishMenu
you can access to it in templates as
config['EnglishMenu']
or even with a value of a variable as in config[page.menu]
The flaskapp.py
file¶
Almoststatic has 2 classes. The first is Almoststatic that have the rendering engine and don’t need Flask, but only Jinja2. The second is FlaskAlmoststatic which bind Almoststatic into a Flask app.
In a Flask app you can include Almoststatic in this way. First initialize the system with:
app = Flask(__name__)
app.config['FAS_CONFIG'] = "./content/config.yaml"
fas = FlaskAlmoststatic()
fas.init_app(app)
Then write a route to serve static pages:
@app.route('/<path:page>')
def fas_pages(page):
page_text = fas.build_page(page)
if not page_text:
return page_not_found(404)
return make_response(page_text)
As you can see, the core of Almoststatic is the method build_page
which
do all the job.
Within the app you can combine static contents and dynamic content and do everything that Flask can do.
The write_static.py
script¶
When your site is done, you can write a little script to publish static pages. A minimalistic example is:
import almoststatic
a = almoststatic.Almoststatic()
a.load_config()
STATIC_URL = '/'
MEDIA_PREFIX = 'media'
DESTINATION = '../_static_site'
OUT_PAGES = ['write_static', 'write_done']
a.write_static(destination=DESTINATION,
media_prefix=MEDIA_PREFIX,
static_url=STATIC_URL,
out_pages=OUT_PAGES)
a.write_json_meta(destination=DESTINATION)
The most important call is to write_static
method, which require parameters
to configure url’s and paths.
This do not copy media files and do not publish pages anywhere, but it’s easy to extend the script to do all you need.