suasuasuasuasua

Understand the Blog Template

I am going to be looking at the repo at this point in time (called a hash).

devenv.nix

I use devenv to define per-project development shells. The packages come from nixpkgs. Since devenv uses nix and nixpkgs under the hood, you get two important benefits: 1) a reproducible build with the lockfile (devenv.lock) and 2) an elegant way to define all dependencies in a unified interface.

You might be thinking, "doesn't package-lock.json" do that for you already? Yes, but only for the project dependencies. This does nothing for external tooling and programs. Is this overkill for a personal website? Maybe. But it scratches the OCD in my brain.

In the devenv.nix, you'll find declarations for packages, languages, git-hooks, and more. As an aside, devenv has a long list of features like processes, services, and containers that I haven't even scratched the surface of.

# devenv.nix
#
# nix is a domain specific language (DSL) and has a
# json-like structure
{
  # https://devenv.sh/packages/
  packages = with pkgs; [
    git
    pre-commit
    treefmt
    # ...
  ];

  # https://devenv.sh/languages/
  languages.javascript = {
    enable = true;
    pnpm = {
      enable = true;
      install.enable = true;
    };
  };

  # https://devenv.sh/git-hooks/
  git-hooks.hooks = {
    treefmt.enable = true;
  };
}

This is something that I added and was not in the template repository. I do think that it's worth mentioning because it's so cool (and because I'm such a fan for it). I would use a pure flake.nix devShell, but I've found that it can be tricky and you'll often spend more time debugging the flake file than actually doing useful work. Maybe that's just a skill issue.

package.json

The package.json file specifies the properties of the package like the name, version, dependencies, website links, and more. It's pretty straight forward and standard file for any web-based project with javascript or typescript.

treefmt.toml

treefmt is another program that I've recently fell in love with. The idea is that treefmt unifies the interface for all your formatters. This is especially useful in a multi-programming language project like a web app.

For my website, I'll admit that this isn't super helpful since I use prettier for most of the files. Again, this is something that I personally added to the repository and was not present in the template.

.devcontainer.json

This file is used to spin up a devcontainer, which is another layer of dependency isolation and reproducibility. The base image also uses nix and reads from the devenv.nix and devenv.lock files, so I thought that was funny. It's like a double condom of safety.

devcontainers are super easy to do in VSCode. I've been trying to get remote-nvim to work, but it's been finicky because I'm using nixvim on NixOS and nix-darwin machines (probably).

.editorconfig

EditorConfig is a file that defines a set of standards regardless of which text editor or IDE you are using. This is a project that I recently learned about and think is super neat.

Some editors recognize EditorConfig and work out of the box. Other editors require you to download a plugin.

.envrc

The .envrc tells direnv what to load when you enter the project directory. My .envrc loads up the devenv shell. Moreover, direnv is going to watch the devenv.nix file for any changes and rebuild the shell. Super useful.

# .envrc
use devenv

If this feels sus, that's fine. You don't have to use direnv, and if you are, you can just disable it in the directory with direnv block.

.eleventy.config.js

I think this is the most important file of the website. In here, we setup 11ty just how we need it according to the specs. From what I understand, we add many plugins for the blog, setup pre-processors for drafts, copy folders (like public/) around, add watch targets, templating files, and more.

_config/

There is a single file here called filters.js. From what I can tell, this file is used to define helper filter functions for the blog posts. Inside of eleventy.config.js, we import and add that file (the exported function) as a plugin.

According to 11ty, plugins are "custom code that Eleventy can import into a project from an external repository." That's really cool! So that means that we can extend Eleventy in tons of different ways, and there is support for doing that locally or from someone else's code online. I'll definitely have to spend time researching the plugin ecosystem to see what is out there.

At the top of eleventy.config.js, there's a block of imports from @11ty, which are a bunch of different plugins that make the blog a blog. I won't dive into what each plugin does right now, but I'll do more research along the way.

_data/

This folder is global data that is exposed to every template in the 11ty project. This means we can ensure consistency across all the web-pages without horribly hardcoding everything and inevitably messing something up.

There are two files in this folder: eleventyDataScheme.js and metadata.js. I'm not one hundred percent sure about the first file, but it seems to do something with validating whether a post is draft content or not. The second file defines some metadata about the website and author. This file was easy to fill in, and I'm guessing that I can add literally whatever else property I want to track about myself or the website.

_includes/

This is a folder with template files for rendering the html pages. This blog starter pack uses nunjucks (.njk). The language is a bit archaic in my opinion, but the idea is that it's a combination of html and some njk logic that helps you generate web-pages.

For example, we have one file called postslist.njk which lists all the blog posts. There are another three files under layouts/ called base.njk, home.njk, post.njk which are pretty self explanatory.

The nunjucks files themselves somewhat read like html, but they also have special logic for iterating over collections, getting time, accessing attributes, etc.

content/

The content/ directory is where I will be primarily working, particularly under blog/ when I write posts. This directory has more .njk files that define pages like tags, the index, and more. This directory seems like a step up above the _includes folder with higher level logic and organization. You can either write md files with the js preamble to identify the page; or, if you need additional nunjucks logic, you can do that instead.

blog/

This is where all my blog posts live. I am currently writing them in markdown (.md) for simplicity. They will be organized by date in year, month, and day order. Currently, the slug contains the entire filename which I don't like. I would like to enumerate the posts so I can easily count how many I have and allow for easier navigation. Also, I want something like the tags page but for the year, month, and date respectively.

Again, not sure how easy this is to achieve, but it would be a nice stretch goal and quality of life improvement as I write more and more posts.

drafts/

I will be putting my drafts under this folder as I am writing them. I just learned that all I have to do is add draft: true to the preamble block so that the pre-processor can skip this file. It will still be compiled in development, but not during a build.

feed/

The feed folder has data for an rss feed to my blog posts. You can use something like miniflux to subscribe.

css/

The CSS folder is pretty straightforward. It controls the styling of the website. I probably won't be messing around with this too much in the beginning stages, so my website will look rather plain.

public/

The public folder will contain images and other assets in use throughout the website. Currently, there is nothing there, but I have left a .gitkeep as a placeholder until I do.


Overall, the blog template isn't too difficult to understand. Everything feels very logical and intuitive. The biggest challenge for me right now is just figuring out the 11ty ecosystem and idiomatic ways to do things.