Blog update with Zola
Vokinloksar33 August 27, 2024 #tech #blogIt's been a long time since my first creation of this blog with jekyll (year 2018), and there's been several pain points to use it:
- jekyll and ruby are just way too unfamiliar from my tech zone.
- AWS codebuild with container commands + Github trigger/auth is complex (comparing to netlify)
- and it felt out-dated
So after several days of tweaking with zola (I also build a custom zola theme myself for other purpose), and searching for the most appropriate (and maybe the only) theme, I finally migrate my old blog to this better place.
First, why:
- zola is build using Rust, which is future-proof and fast, and most importantly to my interest.
- Other JAMStack related tools just not seems to be on par. For example, I tried to use Eleventy for this task, I did, took me about a week to abandon it because I don't want to depend on a javascript eco system and my experience with 11ty is quite painful.
- For the blog theme, I thought my requirements are simple:
- with pagination
- with a posts page to see all posts.
- with RSS subscription
- can make the tags page become useful
- not too fancy and not too dull
but it turns out the only theme that I want to use is this Abridge theme. Huge thanks for them.
On the deploy side:
- Netlify is simply faster than AWS flow, every aspect (consider I did use AWS a lot).
- Netlify provides free TLS encryption and CDN whereas for aws I would use cloudfront which will introduce way more redundancy (trust me).
So, here it is. Hope I can have more fruits in this newly-built nimble and modern place.
Reference: the script to transcribe jekyll yaml into zola toml
import yaml
import toml
import re
from dateutil import parser
from datetime import datetime
import os
from pathlib import Path
import glob
def convert_jekyll_to_zola(jekyll_front_matter: str) -> str:
# Load Jekyll front matter (YAML format)
jekyll_front_matter_cleaned = re.sub(r'^---\n|---$', '', jekyll_front_matter, flags=re.MULTILINE).strip()
try:
data = yaml.safe_load(jekyll_front_matter_cleaned)
except yaml.YAMLError as e:
print(f"Error parsing YAML: {e}")
return ""
# Zola uses "title", "date", and "tags" as standard keys
# Customize as needed
zola_front_matter = {
"title": (data.get("title", "") or ""),
"date": str(parser.parse(str(data.get("date", ""))).strftime("%Y-%m-%d")),
"description": data.get("description", data.get("excerpt", "")),
"draft": data.get("published", True) is False, # Zola uses `draft = true` for unpublished posts
"taxonomies": {
"tags": (data.get("tags", "") or "").split()
},
"extra": {
"thumbnail": data.get("image", "")
}
}
# Convert to TOML format
try:
zola_toml = toml.dumps(zola_front_matter)
except Exception as e:
print(f"Error converting to TOML: {e}")
return ""
return zola_toml
def process_files(input_dir: str, output_dir: str):
# Ensure output directory exists
Path(output_dir).mkdir(parents=True, exist_ok=True)
# Find all markdown files in the input directory
input_files = glob.glob(os.path.join(input_dir, '*.markdown'))
for input_file in input_files:
# Read the contents of the input file
with open(input_file, 'r', encoding='utf-8') as file:
content = file.read()
# Separate front matter and content
front_matter_match = re.search(r'^---\n(.*?)\n---\n(.*)', content, re.DOTALL)
if not front_matter_match:
print(f"Skipping {input_file}: No valid front matter found.")
continue
jekyll_front_matter = front_matter_match.group(1)
markdown_content = front_matter_match.group(2)
# Convert Jekyll front matter to Zola format
zola_front_matter = convert_jekyll_to_zola(jekyll_front_matter)
# Build the new Zola content
new_content = f"+++\n{zola_front_matter}+++\n{markdown_content}"
# Write the new content to a file in the output directory
output_file = os.path.join(output_dir, os.path.basename(input_file))
with open(output_file, 'w', encoding='utf-8') as file:
file.write(new_content)
print(f"Converted {input_file} to {output_file}")
if __name__ == "__main__":
input_directory = "./input" # Replace with your source directory
output_directory = "./output" # Replace with your destination directory
process_files(input_directory, output_directory)