# pablotron.org

## Overview

[Hugo][] backend for [pablotron.org][].

Content is divided into three [sections][]:

|Section Type|Description|Permalinks|
|------------|-----------|---------|
|`posts`|Blog entries.|`/YYYY/MM/DD/SLUG/`|
|`articles`|Long-form articles.|`/articles/SLUG/`|
|`projects`|Programming projects.|`/SLUG/`|

The 10 most recent `posts` are shown on the home page blog in reverse
chronological order.  A list of all `posts`, grouped by year, is shown
on the [archive][] page in reverse chronological order.

`articles` are long-form content that doesn't fit nicely as blog posts.

`projects` have a repository link and a brief description.  Eventually I
may add more information (release history, signatures, etc).

Put assets (images, files, etc) for articles and posts in
`static/files/{articles|posts}/$SLUG`.  Use the built-in `figure`
shortcode to reference images in content, because it supports more
attributes and is responsive (grep existing content for examples).

Use [mathyd][] to generate [SVGs][svg] for math posts and articles,
rather than pulling in [MathJax][].

## Usage

The `bin/new` script allows you (me) to quickly create new content by:

1. Expanding a section template ([Hugo][] calls these templates
   "archetypes") draft content.
2. Opening the draft content in your editor.

## Add Post

To add a new post:

    # easy version
    bin/new post some-blog-post

    # longer version
    hugo new --editor $EDITOR  posts/$(date +%Y-%m-%d)-some-blog-post.md

## Add Article

To add a new article:

    # easy version
    bin/new article some-article

    # longer version
    hugo new --editor $EDITOR  articles/some-article.md

## Add Project

Update `data/projects.yaml` and then run `bin/gen-projects.rb`.

**Note:** If you want to add [Go][] module, you can set the `type` of
the entry to `go`, like so:

    - name: "example-go-mod"
      type: "go"
      slug: "example-go-mod"
      repo: "https://github.com/pablotron/example-go-mod"
      text: "Example Go module."

Adding a `type: go` property in `data/projects.yaml` adds a `go_import`
property to the project front matter, which adds a `<meta
name="go-import" content="...">` element to the header of the generated
page.

## Edit Navbar Menu

To add or edit navbar menu entries:

    # edit navbar menu entries
    vim data/menu.yaml

## Serve Locally

To serve this site locally:

    # serve hugo locally on port 1313
    hugo serve -D --minify --disableFastRender

**Notes:**
* `-D` shows draft content,
* `--minify` generates minified HTML, and
  [`html/template`][html-template] is aware of `<pre>` and `<code>` so
  inline code blocks work correctly.
* `--disableFastRenderer` may be unnecessary, but the fast
  renderer cache was giving me grief while doing theme development.

## Minify Images

Notes:

1. Use `svgmin` to shrink [SVGs][svg].
2. Use [`pngquant`][pngquant] to shrink [PNGs][png].
3. Use `gm convert -define web:lossless=true foo.{png,webp}`
   to compress PNGs and convert them to `webp`s.
4. Use `gm convert foo.{png,webp}`
   to compress JPEGs and convert them to to `webp`s.
5. Use the `pe-figure` shortcode for progressive enhanced `figure` tags
   with a fallback image.

## Article Image Carousels

Articles support image "carousels" at the top and bottom of the page
(carousel is a bit of a misnomer, because the images are currently a
single row of identical-width columns).

See `content/articles/about.md` for a real example, but in general:

1. Add a `carousel` section to the article front matter with `top` or
   `bottom` keys.
2. Add an array of images under `top` or `bottom`.  The parameters for
   the images are virtually identical to those used by the `pe-figure`
   shortcode, with the addition of a `link` and `link_tip` keys.

Here is a reasonably complete example:

```yaml
carousel:
  # top carousel (shown before content)
  top:
    - link: "/files/about/20231001-me-river.jpg"
      link_tip: "Hi!"
      css: "image"
      sources:
        - "/files/about/20231001-me-river-1024.webp"
        - src: "/files/about/20231001-me-river-1024.webp"
          width: 1024
          height: 879
    - link: "/files/about/20231110-me-fridge.jpg"
      link_tip: "Fridge magnets, I guess?"
      css: "image"
      sources:
        - "/files/about/20231110-me-fridge-1024.webp"
        - src: "/files/about/20231110-me-fridge-1024.jpg"
          width: 1024
          height: 879

  # bottom carousel (shown after content)
  bottom:
    - link: "/files/about/me-super-cool.jpg"
      tip: "Younger me... Suave ;)."
      css: "image"
      sources:
        - "/files/about/me-super-cool-1024.webp"
        - src: "/files/about/me-super-cool-1024.jpg"
          width: 1024
          height: 655
```

## Robots.txt

The contents of `static/robots.txt` are from [this site][robotstxt-ai]
and used to prevent the entire site from being indexed by LLM crawlers.

## Deploy Site

To clone site repo:

```bash
# clone upstream repo (note wireguard hostname)
git clone k3.wg:/git/sites/pablotron.org.git
```

Then:

* make changes as usual
* commit changes
* push to upstream repo

The push will trigger a hook which runs
`/data/www/pablotron.org/data/bin/hook/deploy.rb`, which will:

1. Pull the latest changes from the git repository
2. Run [Hugo][] to rebuild the site.
3. Update the `htdocs` symlink for the live site.
4. Remove stale site builds.
5. Log the time taken for each step.

See `bin/hook/` for additional information.

# Theme

The current theme is `hugo-pt2021` and is stored in this repository as
`themes/hugo-pt2021`.

Includes the following shortcodes:

* `table`: Enhanced [CSS][]-only table shortcode.  See
  [hugo-shortcode-table][].
* `sup`: Superscript.
* `pe-picture`: Progressive enhancement `picture` shortcode.
* `pe-figure`: Progressive enhancement `figure` shortcode.

`hugo-pt2021` is depends on the following:

* [Bulma 0.9.3][bulma]: CSS framework.
* Several icons from [Feather Icons][feathericons].

The [Bulma][] [SASS][] is:

1. Stripped of extraneous styles.  See `assetes/style.sass`.
2. Combined with a small amount of `pt2021`-specific styling.  See
   `assets/style.sass`.
2. Converted from [SASS][] to [CSS][], minified, and fingerprinted
   using [Hugo Pipes][hugo-pipes].  See `layouts/partials/head.html`.
3. Written to `public/style.$HASH.css`.

[hugo]: https://gohugo.io/
  "hugo static site generator"
[sections]: https://gohugo.io/content-management/sections/
  "content sections"
[pablotron.org]: https://pablotron.org/
  "the hottest site on the net"
[archive]: https://pablotron.org/archive/
  "post archive"
[bulma]: https://bulma.io/
  "modern CSS framework"
[feathericons]: https://github.com/feathericons/feather
  "beautiful open source icons"
[hugo-pipes]: https://gohugo.io/hugo-pipes/
  "hugo asset processing pipeline"
[sass]: https://sass-lang.com/
  "Syntactically Awesome Style Sheets"
[css]: https://en.wikipedia.org/wiki/CSS
  "Cascading Style Sheets"
[go]: https://golang.org/
  "Go programming language"
[html-template]: https://pkg.go.dev/html/template
  "Go's built-in HTML template renderer"
[mathyd]: https://github.com/pablotron/mathyd
  "TeX to SVG rendering daemon and docker image."
[mathjax]: https://mathjax.org/
  "JavaScript LaTeX renderer."
[svg]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
  "Scalable Vector Graphics"
[png]: https://en.wikipedia.org/wiki/PNG
  "Portable Network Graphics"
[hugo-shortcode-table]: https://github.com/pablotron/hugo-shortcode-table
  "CSS-only table shortcode for Hugo."
[hugo-shortcode-pe]: https://github.com/pablotron/hugo-shortcode-pe
  "Progressive enhancement picture and figure shortcodes for Hugo."
[pngquant]: https://pngquant.org/
  "Lossy compression of PNG images."
[robotstxt-ai]: https://robotstxt.com/ai
  "AI / LLM User-Agents: Blocking Guide"