Personal blog with a Codelabs section and Light / Dark / Cyber theme switcher. Built for GitHub Pages.
- Jekyll 4 – Markdown posts, static site
- Modern Sass – Dart Sass via
jekyll-sass-converter3.x (no legacy Ruby Sass) - Themes – Light, Dark, Cyber (neon accents); choice persisted in
localStorage - Codelabs – List in
_data/codelabs.yml; put standalone codelab HTML underlabs/<name>/ - Speaking decks – List in
_data/decks.yml; put standalone deck HTML underdecks/<name>/ - SPA-like nav – In-site links (with
data-pjax) update content without full reload
Requires Ruby 3.1+ (e.g. rbenv install 3.2 or system Ruby). The project uses Jekyll 4 and Dart Sass; the lockfile pins current versions.
bundle install
bundle exec jekyll serveOr use the helper scripts:
./bin/start
./bin/stopBy default, the site runs at http://127.0.0.1:4000. You can override the port with PORT=4001 ./bin/start and stop that port with PORT=4001 ./bin/stop.
The scripts install missing gems into /tmp/personal-blog-bundle by default; override that with PERSONAL_BLOG_BUNDLE_PATH=/path/to/bundle ./bin/start.
Live site: https://zarin.io
The site is built with Jekyll 4 and Dart Sass, so it does not use GitHub’s built-in Jekyll 3 stack. Deployment is via GitHub Actions:
- Push to this repo (
zarinlo/zarinlo.github.io). - In Settings → Pages → Build and deployment, set Source to GitHub Actions.
- Confirm Custom domain is
zarin.io(see rootCNAMEfile). - The workflow
.github/workflows/pages.ymlbuilds on push tomasterand deploys_siteto Pages.
- Posts: Add
.mdfiles in_posts/with front matter (layout: post,title,date). - Codelabs: Add entries to
_data/codelabs.ymland place each codelab’s files underlabs/<name>/(e.g.labs/my-codelab/index.html). Useurl: /labs/my-codelab/in the YAML. - Speaking decks: Add entries to
_data/decks.ymland place each deck’s HTML underdecks/<name>/(e.g.decks/think-ai/index.html). Useurl: /decks/think-ai/in the YAML. Point Speaking table deck links in_data/recognition.ymlto the same URL.
After pushing to master, allow 1–2 minutes for GitHub Pages to rebuild, then verify:
- https://zarin.io/labs/ loads the codelabs listing page
- https://zarin.io/decks/ loads the speaking decks listing page
- Menu Codelabs and homepage View all links work
- Individual codelab URLs work (e.g.
/labs/springboot-api/) - Individual deck URLs work (e.g.
/decks/think-ai/) - Browser back from a codelab or deck returns to
/labs/or/decks/respectively - https://zarin.io/sitemap.xml includes
/labs/and/decks/
Both /labs/ and /decks/ use the same pattern:
| Listing page | App source folder | Live app URL | |
|---|---|---|---|
| Codelabs | labs.md → /labs/ |
labs/<name>/ |
/labs/<name>/ |
| Decks | decks.md → /decks/ |
decks/<name>/ |
/decks/<name>/ |
Listing pages are Jekyll markdown at the repo root. App HTML lives in the matching folder and is copied into _site at build time by _plugins/copy_section_apps.rb. Add <script src="/assets/js/section-app-nav.js"></script> before </body> on each standalone app page so the browser back button returns to the listing.
Cards are rendered from _data/codelabs.yml via _includes/codelab-grid.html and from _data/decks.yml via _includes/deck-grid.html.