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.
# 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
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 and reports, 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/
. For blog posts, add them under the POSTS key. For reports, add them under REPORTS. - 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
- 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
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.
/
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/
env FLASK_DEBUG=True ./server
# autoreloads on html file changes, but restart it manually when .json files change
open http://localhost:5000
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
./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.
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
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
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/
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