Understand the Blog Template
devenv.nix
package.json
treefmt.toml
.devcontainer.json
.editorconfig
.envrc
.eleventy.config.js
_config/
_data/
_includes/
content/
drafts/
css/
public/
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.
- ← Previous
First Blog Post [follow-up]