Monadical-SAS / monadical.com

🖥️ Custom Flask + Jinja2 static site generator and content powering Monadical.com
https://monadical.com
10 stars 4 forks source link
devops flask github-pages jinja2 static-site-generator wget

Monadical

monadical.com build

Simple static site powering Monadical.com.

A small Python/Flask server in ./server renders the HTML+Jinja2 templates inside templates/ with data from content.json (+ other .json files) and staticfiles static/ and serves the site dynamically on http://127.0.0.0.1:5000. Then a bash script ./build uses wget to download the rendered pages from http://127.0.0.0.1:5000 as static HTML into the output/ folder, which is then served statically by Github Pages to visitors on https://monadical.com.

The rebuild+deploy process is run automatically by CI/CD for any changes to master, however, you can run ./server and ./build locally as well.

Quickstart

# install the dependencies
apt install wget python3   # for Ubuntu/Debian
brew install wget python3  # for macOS
pip3 install -r requirements.txt   # or use pipenv / do this inside a virtualenv

# edit some json, html, css, etc. files to make your desired changes
# e.g. nano team.json

# then start/restart the development server
env FLASK_DEBUG=True ./server

# and open it in your browser to view your changes
open http://127.0.0.1:5000

Common Tasks

Adding a new post/team Member/etc.

Note: to publish a new blog post quickly you can use our mini-webapp https://monadical.com/publishing/

  1. prepare the content to be added
    • for posts and reports, create a new markdown document on https://docs.monadical.com, click Publish and get the public URL like https://docs.monadical.com/s/Skcz_hUhM
    • for job listings, create a new markdown document on https://docs.monadical.com, click Publish and get the public URL
    • for team members, get a forward-facing headshot photo of the team member, run it through https://remove.bg, crop it square, and change it to greyscale
  2. edit content.json/team.json/etc. to add a new entry (copy and paste a previous entry to match the existing style), add any images under static/. For blog posts, add them under the POSTS key. For reports, add them under REPORTS.
  3. PR your change on github and wait for approval from another team member to merge
  4. once merged, check that the autobuild deployed after a few minutes and verify that it looks good on https://monadical.com

Making design/layout/content changes

  1. edit content.json, team.json, etc. any other .json files containing dynamic data used on the site (e.g. pages, posts, team members, job listings, etc.)
  2. edit/add any new relevant .html files under templates/
  3. test the page looks correct on all devices/resolutions using the debug server on http://127.0.0.1:5000
  4. rebuild site with ./build, commit, push, and PR your changes
  5. once merged, check that the autobuild deployed after a few minutes and verify that it looks good on https://monadical.com

Adding new features/endpoints/core functionality

For example, lets say you want to add an XML RSS feed feature for the blog posts.

  1. add any new Python requirements to requirements.txt, Pipfile, and .github/workflows/deploy.yml (if any apt/brew requirements are needed, add them to the README quickstart as well)
  2. add the code to serve your new endpoint to the ./server file (match the style of other endpoints), e.g. /posts/feed.xml would render some RSS XML as a response
  3. update the ./build script to download your new endpoint to a static file in the output/ folder, e.g. output/posts/feed.xml
  4. verify that the new endpoint works correctly both when served from the development server http://127.0.0.1:5000/posts/feed.xml and viewed via the static output file:///.../monadical.com/output/posts/feed.xml (see Testing below)

Note: the endpoint URL in ./server must match the static file path generated by ./build exactly, e.g. do not serve /posts/rss in flask and download it to output/posts/feed.xml in ./build. The name, path, and extension must all be the exactly the same so that the dynamic site served by Flask matches the static site served by Github Pages.


Codebase Layout

/
    server            # the main Python/Flask code powering the server
    build             # the main bash/wget script used to build the static site from flask -> filesystem

    .github/workflows/deploy.yml  # CI/CD job to run ./build on changes to master (rebuilds the `output/` folder for Github Pages)

    output/           # the output folder where the statically generated site gets built into (it's just a symlink to docs/)
    docs/             # Github Pages serves the live version of the site from this folder

    CNAME             # this tells Github Pages to serve our site on https://monadical.com

    content.json      # all the dynamic content used to generate the site is in json files
    team.json         # this data is used to fill out the Jinja2 html templates, generate posts, etc.
    open-positions.json
    stacks.json
    ...

    templates/        # all HTML/Jinja2 templates used to generate the site are in here
        base.html     # the main base template that all other pages inherit from
        posts.html    # the base template that all blog posts inherit from
        index.html    # the homepage template (inherits from base.html)
        ...
        projects/     # you may edit this folder manually to add new projects showcases
            ...

        posts/        # do not edit this folder manually!
            ...       # these templates are autogenerated from content.json during the build process 

    static/           # static assets used to generate the site, e.g. images, css, js, etc.
        core/
            css/      # the main CSS files for the site
            img/      # images/icons/textures used for the core design and layout (i.e. not as part of long-form body content)
        robots.txt
        ...           # use all lowercase with hyphens instead of spaces in filenames
        team.jpg      # loose files in the static folder like this are used in longform body content       

    stevie-king/      # the mini webapp used by employees to easily publish new posts without having to manually edit the json files     
        index.html    # use by visiting https://monadical.com/publishing/

    etc/              # example config files for hosting the site e.g. using nginx under supervisord

    2020/             # snapshot archives of past versions of the site (no longer used)
    2019/

Command Line Interface

Run the development server

env FLASK_DEBUG=True ./server
# autoreloads on html file changes, but restart it manually when .json files change

open http://localhost:5000

Build the static site

This step is normally done automatically by Github Actions, but you should also run it locally to verify significant changes don't break anything.

./build

# then check the changes in `output/`, commit everything to git, push, and PR your changes

Static HTML output will be produced in output/, and can be rsyned to a server using build script or manually with: rsync -r output/ monadical.com:/opt/monadical.com/output

Get a list of the page & post urls without running the server

./server --pages
./server --posts

Note: this is only used by the ./build process to get a list of dynamic URLs for wget to download (e.g. the blog posts urls are not known until Flask reads content.json, so we use this flag to ask the Flask server to give us the URLs we need to download). If a URL is static (i.e. not an entry in a list somewhere in a json file), simply hardcode it wherever it is needed (e.g. /posts/feed.xml), you do not need to add a CLI flag to get static URLs.


Testing

Development Server

Run the Flask dev server when making changes to quickly verify that they're correct.

env FLASK_DEBUG=True ./server
# autoreloads on html file changes, but restart it manually when .json files change

open http://localhost:5000

Static Output

You can verify that the static html output is correct by running a small HTTP server from the output directory like so:

cd output/
python3 -m http.server --bind 0.0.0.0 8000

open http://localhost:8000

Manual UI Testing

Test every significant UI/CSS/layout change in the following resolutions:

For more, see: https://mediag.com/blog/popular-screen-resolutions-designing-for-all/

3rd Party Testing Tools

You can use 3rd party tools to verify that our pages look good to humans and search engines, load quickly, and are accessible to people with screen readers / visual impairment.

Monadical Inc. © 2022
All rights reserved.
v1.0.3