How I Made This Website
Table of contents
Opening Statement
Hello, World! This is my very first blog post, a milestone for me.
I know little to nothing about web development! Sure... I know the rough anatomy of a website: a frontend for UI / UX and a backend for computational resources beyond client side processing and for data / content management. A frontend contains a markup language such as HTML that describes where and how to place text, styling provided by CSS, and perhaps Javascript to make it "dynamic." That is the extent of my knowledge.
For any project, we need to define our requirements. The requirements for my personal website are as follows:
- Shall support brain dumping, the act of projecting my tech thoughts into a tangible medium such as blog posts
- Shall support rapid development and deployment (minimal overhead to draft content and publish)
- Shall provide a simple user interface so that content / information can easily be consumed and navigated including links to Socials and beyond
- Shall not require 3rd party integrations, complex applications, or data forms / database
- Shall have 99.9% uptime, reliable, and quick load times at minimal expense
After committing to the requirements above (with no intent to burden myself with feature creep), I could not help myself but reminisce in the past when I was kid browsing the Internet in the early 2000s. Yeah, it was not necessarily the 90s but close enough in time to recognize that websites back then were simple yet efficient. It dawned on me that my requirements corresponded to a "static" website with blogs.
Should be simple enough... right? *nervous laughter*
It really is... with the help of Static Site Generators or SSG(s) for short!
Static Site Generators
In a nutshell, static site generators (SSGs) are tooling which converts content written in familiar formats such as Markdown
or reStructuredText
into web pages with advanced styling.
Here is a diagram:
+------------------------+
| |
| |
| |
| STATIC SITE GENERATOR |
Content in ---------------->| (Applies HTML / CSS +-------------> A full blown
.md or .rst | Magic) | website!
format | |
| |
| |
+------------------------+
So, SSGs effectively reduced the amount of time to stage and deploy this website! It enables me to dedicate most of my time towards content generation and eliminates the need for me to do web development (HTML / CSS work)!
There are many open source SSGs available! Here is a list of generators: https://jamstack.org/generators/. This website was built using Pelican. My strategy for choosing Pelican was based on my familiarity with the language used by the generator, Python. The docs were also easy to follow!
Most generators offer website "themes" and plugins for added styling and complexity. The theme I used is Papyrus. At time of website creation, this theme had recent support, as determined by its commit history. It offered me a very simple, elegant UI with searching capabilities.
Markdown Guides
For my website, I use Markdown for its content. Here are some helpful resources:
- https://www.markdownguide.org/getting-started/ <-- a fantastic catch-all resource for Markdown markup language with tutorials
- https://emojipedia.org/ <-- emojis that can be embedded in Markdown files 😃😉
Pelican De-Briefing
As mentioned previously, Pelican is a static site generator.
For a website, the general project structure is as follows:
.
├── content
│ ├── assets
│ │ └── images
│ │ ├── 1276786_200470_115070_p4Q3Nv0Nq.jpg
│ │ ├── photo-of-me.jpeg
│ │ └── test_image.jpeg
│ ├── blogs
│ │ ├── random
│ │ │ └── how-i-made-this-website.md
│ │ └── software
│ │ └── article-ebpf.md
│ └── pages
│ ├── about-me.md
│ └── projects.md
├── Makefile
├── package.json
├── pelicanconf.py
├── publishconf.py
├── __pycache__
│ └── pelicanconf.cpython-310.pyc
├── tasks.py
The ./content/
path is comprised of articles, pages, and static assets. Articles are essentially blogs that are presented in reverse chronological order on the main landing page of the website as a list and catalogued under the "Archive", "Categories", and "Tags" pages. Pages create a seperate stream of information and are added as a new element to the menu, think "About Me" or "Contact" pages. Finally, static assets are anything aside from text, think pictures, videos, etc.
Pages are found under the ./content/pages
directory (configurable path) and articles, otherwise. Static assets are found under the ./content/assets
directory (configurable path).
Settings of the project go in pelicanconf.py
and publishconf.py
. We can separate "development" settings from "production" settings using these 2 config files respectively. Note: publishconf.py
includes pelicanconf.py
A Makefile
is provided to allow POSIX systems to run convenience scripts for automation. We can also use Invoke
. I use the Makefile
.
Step by step breakdown
Since Pelican is Python based, let's create a virtual environment to isolate dependencies from other local Python projects:
python3 -m venv /path/to/project
cd /path/to/project
source ./bin/activate
Now, let's install everything we need for the website (from the perspective of my system)
# Download https://pip.pypa.io/en/stable/installation/#get-pip-py and install pip
python3 get-pip.py
# Install Pelican Markdown version
python3 -m pip install "pelican[markdown]"
# Install git
sudo apt install git
# Download pelican-themes https://github.com/getpelican/pelican-themes (where I discovered Papyrus and used it here)
git clone --recursive https://github.com/getpelican/pelican-themes ~/pelican-themes
# Download dependencies for Papyrus
python3 -m pip install pelican-search
python3 -m pip install pelican-neighbors
python3 -m pip install pelican-readtime
mkdir ~/pelican-plugins
git clone https://github.com/ingwinlu/pelican-toc.git ~/pelican-plugins
python3 -m pip install beautifulsoup4
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo apt install build-essential
sudo apt install openssl-dev
cargo install stork-search --locked
To generate Pelican base project structure and generate automation scripts, do:
cd /path/to/project
pelican-quickstart
The answers provided here determines the autogenerated Makefile
and tasks.py
file.
Finally, copy the contents of the example pelicanconf.py
settings file found in the Papyrus theme GitHub repo to your local project as needed: https://github.com/aleylara/Papyrus/tree/main#settings
We are now ready to generate site!
To generate the static site, do:
pelican content
This will build website based on artifacts in the ./content
directory and place generated output in the ./output
directory.
To view the website locally, do:
pelican -r --listen
The -r
flag auto-reloads changes made to the ./content
directory so we can modify and view in our local web browser!
Woohoo, we are done!
Hosting
There are so many website hosting services. I decided to use AWS. Let us see how that goes...