Very simple low-feature almost-static blog built with flask and a dash of jQuery
Here's an example
Write posts in markdown using the online editor with live preview. Provides a near-static paginated blog page, where each post has its own customisable url.
Aimed at people who want a lightweight blogging platform without using a pre-baked system like Wordpress. This is the raw dough of blogging platforms.
The basics are there, but you'll need to flavour it and cook it before eating. By which I mean style to taste with sass, add navigation/assets/title bars etc with html, implement any features you want/need, and start adding content.
What this currently does
- Reads a markdown-formatted plaintext file of posts and generates a (almost) static html blog page
- Notices when the posts file has been updated to add new posts without a server restart
- Gives each post an id and a url of its own under /post/id. Posts can be safely deleted without affecting the id or url of other posts. Custom urls can be given to posts
- Get a post's own page by clicking on its title
- Compatible with all markdown syntax, easy to add links, images, etc
- Upvote posts by clicking an upvote button
- Tag posts with categories and be able to view all posts from a certain category
- Mark posts as 'draft' to give them a draft url without publishing them to the main page
- An admin login page - you'll need SSL if you want to use this feature, otherwise a MITM could steal your password and have free reign over editing the blog posts
- Edit and add posts on the admin page and upload images
- (Live) markdown preview
- Search posts
- Display the latest
xposts and paginate the others
- Post published date
What is planned
- Allow image size to be changed
- Limit post size on main page, either expand post or go to its own page to see the full thing
- RSS feed
Flask backend, jQuery used for upvote button. Since there are no user accounts upvotes are unlimited. Redis is used for storage of each post's upvotes. The posts themselves are stored in a plain text file as shown below.
Markdown syntax is used for post formatting. In branch SimpleFormat you can find the old, simpler method of post formatting if you prefer.
sass styles/main.scss static/main.css
virtualenv -p python3 p3env
pip install -r requirements.txt
The first thing to do is replace all the keys in
keys. You should hash your admin password and store the hash on line 3. The other two keys are for signing cookies and form security, so make sure they are long and random.
flask run once the env var is set
/login and enter your password to login. A 30 minute session cookie is generated.
Add posts by editing the
posts file. The server notices the edit and provides the new post on page reload
You can also add posts on the admin page by logging in. Currently, you are presented with all available posts which means that you can edit, delete, and add all posts freely. To make this a bit safer, whenever you edit posts on the admin page a pre-edit backup is stored in the /backup folder on the server.
Upload images using the form provided. Admins are assumed to be trusted so the server currently does not test for filename shenanigans or check the filetype (no check for uploading to
../../../home/username/.bashrc). Duplicate filenames are incremented so images aren't overwritten.
In each post you can specify tags, markdown, and a custom url.
A post takes this form:
///postcustom_url tag1 tag2 ///markdown # my title ...etc
Add images by putting them in /static/img or uploading them via the admin page. Include them in posts with markdown syntax
![alt text](/static/img/filename). At the moment you have to manually type in
Tags are included by putting them under
///post, and will be stripped of space and special characters.
Posting dates are automatically added but you can add/edit them yourself if you want.
draft is a reserved tag for marking draft posts. Draft posts will be available under
/tags/draft and you need to be logged in to view it. Making the post live is as simple as removing its
The number after
///post is the post id. This is automatically added if it is not there. All posts are scanned and the max id is incremented to produce the value for the next id. This means that you can assign custom ids to posts if you want, but if it is not unique only one of the posts will have its own unique url.
Customising post urls
You can give your post a custom url by adding the desired suffix in place of the id, for example, if I wanted my post to be found at
/post/mypost the post tag in the posts file would be this
///postmypost. Please note that only url-safe characters should be used for this.
PyEmbedMarkdown is used to support iframes (Youtube, embeddable content)
The posts file is updated by adding a new post to the top and looks like this:
///post1 myTag1 myTag2 ///markdown # title this is my title ### text this is my text ///post0 draft # title this is my title 2 ### text this is my text 2
Note that you do not have to manually specify the post id or the date, these are automatically added if they're not there.