WordPress is great for getting things up and running, but it's big and bloated and far from a finely honed solution to our specific problem.
The biggest one is that even when writing a custom theme with caching plugins enabled, WordPress will always love to hammer the database. It's easy to scale up servers, but it isn't cheap.
Enter Pelican, a Python-based static site generator. It will take Markdown source files of articles and pages and turn them into a fully static directory of HTML, CSS, JavaScript, and images. That way you'll at most need to set proper cache-control
per-file and dick around an .htaccess
file.
There's not really a good way to systemically install Pelican plugins other than to include them as submodules (it even tells you as much), so when you clone this repo, you should use the recursive option.
$ git clone --recursive https://github.com/workingmirror/blog.git
Then you need to set up the Python environment.
$ pyenv virtualenv 2.7.10 blog
$ cd blog/
$ pip install -r requirements.txt
There are also front end dependencies for the admin interface, for which you'll need Yarn.
$ yarn install
We do something a little different from Pelican's suggested usage in that we manually organize our content files.
Within the /content/
directory, you'll find a hierarchy that should be fairly logical. The highest folders are years, and those contain months, and those contain individual Markdown files.
├── content
│ ├── {{YEAR}}
│ │ ├── {{MONTH}}
│ │ │ ├── {{YEAR}}-{{MONTH}}-{{DAY}}-{{SLUG}}.html
│ │ │ └── ...
│ │ └── ...
│ └── ...
│ ├── images
│ └── pages
└── ...
This is so that when you crack open this repo in Sublime or ls
it in your shell, they are at least ordered in some reasonable way.
This includes naming individual posts in the {{YEAR}}-{{MONTH}}-{{DAY}}-{{SLUG}}.html
pattern.
Title: Some Sort of Review
Date: 2017-01-02T03:04:05+00:00
Modified: 2017-02-03T04:05:06+00:00
Category: Reviews
Subcategories: Movies
Tags: Movie Title, Movie Director, Lead Actor
Slug: some-sort-of-review
Authors: Firstname Lastname
Summary: Read all about it!
Featured: http://i.imgur.com/bF1gdy6.jpg
A lot of the metadata should be self-explanatory. Title
, Date
, etc.
Author
should be whatever the key value is in the AUTHORS
dictionary in pelicanconf.py
. This means that whenever there is a new author, a new item should be added to AUTHORS
.
Featured
is the main header image for the post, similar to the Featured Image in WordPress. It should be the absolute URL to the image.
Pelican supports only a single Category
out of the box, so we have a custom attribute with Subcategories
, which works a lot more like Tags
in that it supports a comma-separated list of other categories. For that reason, here is the preferred structure.
News
Reviews
Previews
Features
Opinion
Movies
Video Games
Television
Technology
- Or whatever
Subcategories
are completely optional, but you should upgrade the Subcategories
value to the Category
if there is nothing in Category
you would use for your post.
Reviews require some special metadata to help populate structured data. This helps web crawlers find the information they need.
All reviews require the following.
- The first item in
Tags
should be the product title Rating
- a one-out-of-ten numerical value indicating the review scoreRelease
- formatted date string for when the reviewed product was releasedWebsite
- URL of product website (can be the Wikipedia page)
Genre
- the film's genre; don't shorten names (i.e., "science fiction" instead of "sci-fi")Director
- comma-separated if there are multiple directorsCast
- just the leads or any substantially impactful supporting castDuration
- use the ISO 8601 duration format (e.g.,PT1H30M
)
Genre
- using whatever Wikipedia lists is usually a safe betDeveloper
- comma-separated if there are multiple studios involvedPublisher
- make sure it's publishing arm if it's also a development studioDirector
- we'll also take the lead designerPlayers
- the player count the game allowsPlatforms
- all available platforms at the time of review
Season
- numerical season of the show being reviewedGenre
- almost always choose to usesitcom
overcomedy
Showrunner
- just for the season being reviewedCast
- keep it to the regular castPlatforms
- restrict it to the platforms it premiered on likeNetflix
orHBO
We use the liquid_tags
plugin.
When embedding images, you can use full-image
as a class name to create a responsive image.
Go ahead and generate the content.
$ pelican content
$ ./node_modules/.bin/webpack --config webpack.config.js
And then launch a server.
$ cd output/
$ python -m SimpleHTTPServer
Since this is all based on Markdown files being committed to this repository, new writers need to first acquire a GitHub account.
Then, that user needs to be added to the Working Mirror organization.
Finally, there's a big ol' AUTHORS
dict in pelicanconf.py
that contains all the required information for when we generate pages. It should follow this structure.
AUTHORS = {
'Lando Calrissian': {
'email': '[email protected]',
'bio': 'You can totally trust me.',
'twitter': 'lando',
'facebook': 'lando',
'instagram': 'lando',
'website': 'http://landocalrissian.com/',
},
}