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.