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** is a little script used to write the static pages.
**templates** is the default location for Jinja template files, but you can add
custom folders to search before the 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. If needed, the two methods can be
combined; see the sample in the 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 retrieve them with the ``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 as the path plus the name of file.
Other ``content`` subfolders
----------------------------
Pages can access to ``included`` contents, see :doc:`embedding`. You can
organize them into folders under the ``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 contains configuration parameters, all can be omitted
if default values are ok.
.. note::
You can add folders to the template directive, i.e. with ``templates: ["custom","templates"]``
Template files are first searched in the ``"custom"`` folder and, if not found, in the
``"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 for the 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 has the rendering
engine and doesn'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('/')
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
does 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.
This does not copy media files and does not publish pages anywhere, but it's
easy to extend the script to do all you need.