Alexandre Jesus (@adbjesus)

Hello, world!

2022-08-29 (updated on 2023-08-01)

I have been thinking of starting a blog for a while, mostly to write about stuff that makes no sense to publish academically, but also to improve my writing skills. I expect to mostly write about Programming, Emacs, Linux, and other tech topics. But we will see where it goes.

In this first post I will quickly go over the implementation and deployment of this site. You can find the source code for the website at https://git.adbjesus.com/adbjesus.com.

Static Site Generator

Since this site will contain static content, I've decided to go with a static site generator. In particular, I chose Zola. The main reason for using Zola and not something else is that I am familiar with its implementation language (Rust). This can allow me to easily contribute to the project to fix any issue or scratch any itch.

In terms of styling, I'm using simple templates and CSS I implemented myself, which match the light/dark system theme option set by the user. Something I am not yet doing, is using syntax highlighting for code in blog posts. Although Zola supports this, it does not support some of the languages that I want, such as Emacs Lisp and Nix, and it is using old and buggy Sublime syntaxes. There is currently an open issue to replace the current system. Another option, would be to use a javascript based syntax highlighter. However, I would rather keep my site javascript-free. As a result, since I don't consider it to be a critical feature for now, I will not implement any syntax highlighting for the time being.

Using Org

One issue I had with Zola is that it does not suppor Org for writing content (see this issue). However, I would prefer to use it instead of markdown because I prefer and am more comfortable with its syntax, but also because I want to be able to use Org Babel to execute code within the .org file directly when writing posts for which executing code is useful.

Nonetheless, this proved not to be an issue for my simple use case because I can automatically convert .org files to .md files (following the CommonMark spec) using pandoc, and the ox-pandoc package for Emacs. To setup ox-pandoc to export .org files to CommonMark I have the following in my Emacs configuration:

(use-package ox-pandoc
  :ensure t
  :after org
  :custom
  (org-pandoc-menu-entry
   '((?c "to cmk." org-pandoc-export-to-commonmark)
     (?C "to cmk and open." org-pandoc-export-to-commonmark-and-open))))

Then, I put the index.org for a blog post inside a dedicated folder for that post:

content
└── blog
   └── 01-hello-world
      ├── index.org
      └── ... // other files

The index.org file includes some metadata in its header for both Zola and ox-pandoc. For example, for this post I'm using the following header:

#+TITLE: Hello, world!
#+DATE: 2022-08-25
#+PANDOC_METADATA: slug:hello-world
#+PANDOC_EXTENSIONS: commonmark+yaml_metadata_block
#+PANDOC_OPTIONS: standalone:t
#+PANDOC_OPTIONS: shift-heading-level-by:2

The TITLE, DATE, and PANDOC_METADATA fields are added to the exported markdown metadata block. To add the metadata block to the generated markdown file we set the yaml_metadata_block pandoc extension in PANDOC_EXTENSIONS, and the standalone:t option in PANDOC_OPTIONS. The last line is used to start the generated headings' levels at 3 for styling purposes.

Finally, I use the C-c C-e p c shortcut to generate the markdown file, which goes into the same folder, i.e.:

content
└── blog
   └── 01-hello-world
      ├── index.org
      ├── index.md
      └── ... // other files

You can find the Org source for this post here.

Deploying with Nix

I deploy this site to my NixOS server using the declarative NixOS configuration capabilities. For this I have a flake.nix in the repository of this site (edit: as of 2023-08-01 the flake no longer uses flake-utils but the idea is the same, you can check the latest version on the repository):

{
  description = "My personal website";

  inputs = {
    nixpkgs = {
      url = "github:nixos/nixpkgs/nixos-22.05";
    };

    flake-utils = {
      url = "github:numtide/flake-utils";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = import nixpkgs { inherit system; };
      in rec {
        packages.website =
          pkgs.stdenv.mkDerivation {
            name = "website";
            src = self;

            buildInputs = [ pkgs.zola ];

            buildPhase = ''
              zola build
            '';

            installPhase = ''
              mkdir -p $out cp -Tr public $out/public
            '';
          };

        packages.default = self.packages.${system}.website;
      }
    );
}

Then I add this repository to the inputs section of the NixOS flake.nix configuration file.

inputs.website = {
  url = "git+https://git.adbjesus.com/website";
  inputs.nixpkgs.follows = "nixpkgs";
};

and use the nginx.virtualHosts option to deploy it:

services.nginx.virtualHosts = {
  "adbjesus.com" = {
    default = true;
    forceSSL = true;
    enableACME = true;
    locations."/" = {
      root = "${website.packages.x86_64-linux.website}/public";
    };
  };
};

In the future, I will write more about my NixOS configuration using flakes, which I use to manage my personal computers and server.

Edits