My Blog

My blogging workflow: based on Emacs

During the holiday at home these past few days, I decided to pick up Emacs again. So, I went ahead and completely reconfigured my Emacs setup, covering both my usual writing ( Org , LaTeX , etc.) and programming (mainly C++ ). After finishing this setup tinkering, I remembered I had an unused domain name I wanted to utilize, so I decided to build this blog. Actually, I had been considering setting up a blog for a while but always gave up, mainly due to a lack of motivation for writing. Over the weekend, on the way to Parksvill , I read Li Xiaolai’s book “The Truth of Attention”, which made me feel it’s necessary to strengthen my habit of written output.

This blog post briefly documents how I set up this workflow, mainly involving several parts: configuration in Emacs , usage of hugo and its templates, and using GitHub Pages .

I am using the combination of Emacs + Hugo + Github Pages. Since I’m quite used to writing Org documents, after writing my blog posts in Org within Emacs, I directly use ox-hugo to export them to Markdown, and then push them to GitHub for serving. Here, I primarily referred to the ox-hugo official documentation. The configuration in Emacs is mainly to handle the export from Org files to Markdown files. I adopted the ‘One post per Org subtree’ approach, where each article is a second-level heading. Each first-level heading represents a separate section. There isn’t much to say about this part; just configure and organize your Org documents according to the official documentation. One thing to pay special attention to is that the top of the Org file needs the hugo_base_dir configured, and each post needs its export filename configured via EXPORT_FILE_NAME . Once configured, you can write your blog posts just like you normally write Org documents. Theoretically, all formats supported by Org can be used directly, but be aware that some formats might produce unexpected behavior when exporting to Markdown. When you need to export, you can use the Emacs shortcut C-c C-e H H to export to a Markdown document.

To use Hugo to generate the static site, you can install the environment locally and preview the generated web pages. For Hugo installation, refer to the official documentation. Here I recommend a very simple theme, hugo-bear; configure it according to its documentation. After configuration, run hugo server locally to ensure you can successfully preview the website.

To serve the website online, there are many options. There are paid and free solutions, such as cloudflare or GitHub Pages . I personally use GitHub Pages . GitHub Pages is essentially a service for serving static files. Therefore, before that, you still need to use Hugo to generate the static files from the Markdown files. Since GitHub has the Action feature, it’s very convenient to automatically generate these static files after we Push the code to the remote . As for configuring the Action , I directly asked ChatGPT , and the provided script can be used directly. Save this script to the .github/workflows/deploy.yml file in your blog’s code repository.

  name: Deploy Hugo site to Pages

on:
  # Runs on pushes targeting the default branch (e.g., main)
  push:
    branches:
      - main

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

# Default to bash
defaults:
  run:
    shell: bash

jobs:
  # Build job
  build:
    runs-on: ubuntu-latest
    env:
      HUGO_VERSION: 0.146.6
    steps:
      - name: Install Hugo CLI
        run: |
          wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
          && sudo dpkg -i ${{ runner.temp }}/hugo.deb
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
          fetch-depth: 0
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v5
      - name: Build with Hugo
        env:
          # For maximum backward compatibility with Hugo modules
          HUGO_ENVIRONMENT: production
          HUGO_ENV: production
        run: |
          hugo \
            --gc \
            --minify \
            --baseURL "${{ steps.pages.outputs.base_url }}/"
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3 # Upload the built html files
        with:
          path: ./public

  # Deployment job
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build #
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4 #

Additionally, you need to go into the repository’s setting to enable Pages using Actions. You can also configure your custom domain there. Refer to this screenshot:

Summary

At this point, the entire workflow should be up and running. This very article was published using this process. To summarize, here are the key steps for writing a blog using Emacs:

Configure ox-hugo and organize your org files according to the documentation requirements. Install and configure the hugo site locally, including the theme. Configure Github Pages and set up a custom domain. Configure the Github workflow to support automatic publishing after a Git Push. After that, you can write entirely within Emacs and conveniently publish your text as online articles. Going forward, there is still room for optimization, including using Org mode’s Capture template feature to quickly create posts, configuring different versions for Chinese and English, and adjusting styles, etc. I hope this article is helpful for friends with similar needs. You can also directly refer to my complete source code: Blog Source Code

References

#Blog #Emacs #Hugo