Monadical
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/
- prepare the content to be added
- for posts, create a new markdown document on https://docs.monadical.com, click
Publish
and get the public URL likehttps://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
- 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 understatic/
- PR your change on github and wait for approval from another team member to merge
- 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
- 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.) - edit/add any new relevant
.html
files undertemplates/
- test the page looks correct on all devices/resolutions using the debug server on
http://127.0.0.1:5000
- rebuild site with
./build
, commit, push, and PR your changes - 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.
- add any new Python requirements to
requirements.txt
,Pipfile
, and.github/workflows/deploy.yml
(if anyapt
/brew
requirements are needed, add them to the README quickstart as well) - 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 - update the
./build
script to download your new endpoint to a static file in theoutput/
folder, e.g.output/posts/feed.xml
- 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 outputfile:///.../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:
-
xs
(<576px
), e.g.320px
(iPhone 5 in portrait mode) -
sm
(≥576px
), e.g.667px
(iPhone 6 in landscape mode) -
md
(≥768px
), e.g.768px
(iPad Mini in portrait mode) -
lg
(≥992px
), e.g.1024px
(iPad Pro in portraid mode) -
xl
(≥1200px
), e.g.1280px
(Chromebook Pixel) -
xxl
(≥1400px
), e.g.1440px
(Any 2k, 4k, etc. modern hi-res laptop/desktop monitor)
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.
-
Test OG/meta tags and social preview, e.g.:
-
Test SEO and pagespeed insights, e.g.
- https://developers.google.com/speed/pagespeed/insights/?url=https%3A%2F%2Fmonadical.com%2Fposts%2Fhow-to-make-remote-work-part-two-zulip.html
- https://freetools.seobility.net/en/seocheck/check?url=https%3A%2F%2Fmonadical.com%2Fposts%2Fhow-to-make-remote-work-part-two-zulip.html&crawltype=1
- https://seositecheckup.com/analysis
- https://sitechecker.pro/app/main/project/2082903/progress?guest_project_id=2082903&guest_project_title=https:%2F%2Fmonadical.com
-
Test accessibility, e.g.
Monadical Inc. © 2022
All rights reserved.
v1.0.3