While putting together Cade Not Found, I found myself looking for a way to create easily sortable, partial content for the page that could be inserted and rendered at build time. I wanted to use my existing tools (Bear & pre-commit) and not monkey with data.

Partial content seemed a natural solution. Surprisingly, there isn’t a pre-defined shortcode to accomplish the task. Go go DDG, surely someone has desired the same. After some keyword wrangling, a couple solutions popped up. They got me close, but I wanted more. Here’s what I came up with:

{{- $file := (.Get 0) }}
{{- if (fileExists $file) }}
    {{- $file_content := readFile $file }}
    {{- if (strings.HasSuffix $file ".sort.md") }}
        <!-- Automatically sort any file with a .sort.md extension -->
        {{- $sorted := split $file_content "\n" | sort }}
        {{- delimit $sorted "\n" | $.Page.RenderString }}
    {{- else if (strings.HasSuffix $file ".md") }}
        <!-- Render typical markdown -->
        {{- $file_content | $.Page.RenderString }}
    {{- else if (strings.HasSuffix $file ".txt") }}
        <!-- Render txt files as plain text -->
        <code>{{ $file_content }}</code>
    {{- else }}
        {{- errorf "Unsupported file type: %s" (path.Ext $file) }}
    {{- end }}
{{- else }}
    {{- errorf "File not found: %s" $file }}
{{- end }}

It autodetects a few formats based on the file extension and handles them accordingly. Simple to extend should another format be useful.

Save it as <hugo_root>/layouts/shortcodes/partial.html.

Use it in your pages with:

{{< partial "path/to/really/cool/file.sort.md" >}}

My workflow

A few solutions for managing static-built sites exist, but none satisfy my needs for one reason or another (poor mobile support, quirky interfaces, convoluted/designed for teams, etc.).

This works for me, YMMV.

Author in Bear

Edit notes in Bear. Tag with #cadenotfound/stubs

* [@CADELab](https://twitter.com/cadelab) - University of Utah College of Engineering IT Support
* [@CADEWinery](https://twitter.com/cadewinery) - Napa Valley Winery
* [Cades Cove](https://en.m.wikipedia.org/wiki/Cades_Cove) - valley in Great Smoky Mountains National Park
* [CADE Museum](https://www.cademuseum.org/) - STEM museum in Gainesville, FL

By sorting at build time, I’m able to use Bear’s append function to easily add new Cades without worrying about order.

Check it out, sorted without effort.

Export with bear-exporter

Soon to be released, bear-exporter simplifies dumping Hugo-ready markdown (and much more).

bear-exporter notes \
  --export \
  --format hugo \
  --tag cadenotfound/stubs \
  --output content/cade-not-found \

For transparency, I’m manually renaming the exported notes from .md to .sort.md. Should be easy to implement in bear-exporter though.


Pre-commit applies acceptance checks prior to git commit using the git hook system. It’s convenient and makes it a lot harder to commit garbage.

Check out pre-commit if you haven’t seen it in action before.

Pre-commit configuration for cade.pro:

# See https://pre-commit.com for more information
  - repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v3.3.0
      - id: trailing-whitespace
      - id: end-of-file-fixer
      - id: check-added-large-files
      - id: check-toml
      - id: check-yaml
  - repo: https://github.com/cadeef/pre-commit-hooks-blog
    rev: init
      - id: auto-commit-message
        stages: [prepare-commit-msg]
      - id: check-orphan-tags
      - id: check-placeholders
      - id: fix-bear-export-quirks
      - id: markdown-link-check
      - id: markdownlint
        args: ["-r", "~MD013,~MD029,~MD002,~MD026"]

On Mobile: Pre-commit checks are also triggered by push events at GitHub. I use Working Copy to push changes from mobile to get similar feedback.


A Netlify build is triggered on success.

Netlify’s bread and butter seems to be Jamstack. They offer a nice service at reasonable prices.

That’s how the sausage is made. With luck you might find my rambling helpful.