Last updated: 2020-12-15
I think there are too many apps and tools, all of which accomplish slightly overlapping tasks with no interoperability between them.
I'm at the point in my career where it makes more sense to shapen the tools in my toolbox instead of focusing on adding more. When I set out on starting my own blog, I wanted to engage is a manner that would add value in this direction (See: Axioms of Development).
Why not just use one of (<medium> <wordpress> <blogger> <wix> <ghost> <tumblr> <etc>)?
Because I want something that will fit within my workflow with minimal deviations. I don't need the ability to write posts on my phone. I don't want a fancy UI that slows down the user experience. I don't want to write in a special box and worry about my internet connection. I want control over what happens and how.
This website is powered by the magic of vimwiki + fastapi.
Vimwiki is a wonderful tool that integrates into my existing workflow. Love the ability to jump into and out of a link without having to use my mouse while typing. Lets me use all my vim shortcuts while editing and keeps the mental overload of using tools to a minimal. I can also write these offline and push changes when i'm ready. I don't really care to write this stuff on my phone. I'm sure other people find value in it, but how often can you really write good content on your phone that you just have to publish immediately? Just use Twitter for that idea and move on with life.
Fastapi because I wanted a python webserver that's easy to use and performant.
Steps to reproduce:
But what about a database? Don't need one. The content is processed into raw html. No need to keep any persistant state.
But what if I want to save information on how many people are reading my posts? Track it all in memory and periodically write to a file. Do you really care if you occasionally lose 5 minutes worth of information? When you start up, load it back into memory.
vimrc:
let blog = {} let blog.path = '~/blog/' let blog.path_html = '/path/to/git/templates/' let blog.template_path = '/path/to/git/vimwiki/' let blog.template_default = 'theme' let blog.template_ext = '.html' let blog.nested_syntaxes = {'python': 'python', 'c++': 'cpp'} let g:vimwiki_list = [blog]
theme.html:
<!DOCTYPE html> <html> <head> <link rel="Stylesheet" type="text/css" href="/static/css/template.css"> <link rel="Stylesheet" type="text/css" href="/static/css/style.css"> <title>%title%</title> <meta http-equiv="Content-Type" content="text/html; charset=%encoding%"> </head> <body style="margin: 0px"> <div class="topnav"> <a style="font-style: normal; text-transform: capitalize;" class="active" href="/">Home</a> <a style="font-style: normal; text-transform: capitalize;" href="/%title%">%title%</a> </div> <div class="container"> <p style="text-align: right; font-weight: bold;">Last updated: %date%</p> %content% </div> </body> </html>
app.py:
from fastapi import ( FastAPI, Request ) from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.responses import RedirectResponse app = FastAPI(docs_url=None, redoc_url=None) app.mount("/static", StaticFiles(directory="blog/static"), name="static") templates = Jinja2Templates(directory="blog/templates") @app.get("/favicon.ico") async def favicon(): return RedirectResponse('static/favicon.ico') @app.get("/") async def home(request: Request): return templates.TemplateResponse("index.html", {"request": request}) @app.get("/{entry}") async def get_entry(entry: str, request: Request): # You probably want to sanitize inputs here return templates.TemplateResponse(f'{entry}', {"request": request})