plugin-banner (a README Experience)

A Micro.blog plugin for dropping page-specific banners into your theme. Its code lives here

Great. How does it work?

How It Works

Pick somewhere in your custom theme that you'd like banner images to appear. My site invokes the banner partial from layouts/_default/baseof.html, which is the backbone of all my pages save for post pages (which use layouts/post/baseof.html). Once you know where you want banner images to appear, plop this bit of code in the template:

{{ if templates.Exists "partials/plugin-banner/banner.html" }}
{{ partial "plugin-banner/banner.html" . }}
{{ end }}

The plugin's banner partial will insert something kinda like the following (from my homepage):

<div id="banner-home" class="banner-image"></div>

The id value is generated from the page's path and the class value is configured via plugin parameters.

Wait … what makes the images show up?

Magic

F$&k off … you've done that one already.

Fine, I'll tell you.

What Makes the Images Show Up

You figure out which images you'd like to show up as banners for which pages. Once you've done so, you register these assignments by editing the data template that lives at data/plugin_banner/Images.toml (or better yet … in a template you've created in your custom theme that lives at data/plugin-banner/Images.toml). The file starts out all…

# Banner image registration
#
# Register banner images by relative page path.
###############################################

# '/my/page/path/' = 'my-image-url.jpg'

and, if you're me, configuring the plugin to generate the banners composing that collage up top, it ends up looking all:

# Banner image registration
#
# Register banner images by relative page path.
###############################################

# '/my/page/path/' = 'my-image-url.jpg'

'/' = 'https://moondeer.blog/uploads/2021/8135337116.png'
'/about/' = 'https://moondeer.blog/uploads/2021/955619b235.jpg'
'/cloud/' = 'https://moondeer.blog/uploads/2021/547d825d8a.jpg'
'/bookshelf/' = 'https://moondeer.blog/uploads/2021/27a279361f.jpg'
'/gallery/' = 'https://moondeer.blog/uploads/2021/8585a4a081.jpg'
'/categories/perspectives/' = 'https://moondeer.blog/uploads/2021/f5f64b49bb.jpg'
'/categories/projects/' = 'https://moondeer.blog/uploads/2021/74512379fa.png'
'/categories/poetry/' = 'https://moondeer.blog/uploads/2021/02bec3693a.png'
'/categories/music/' = 'https://moondeer.blog/uploads/2021/b604ce0519.png'
'/categories/programming/' = 'https://moondeer.blog/uploads/2021/0d2564a5e5.png'
'/categories/microblog/' = 'https://moondeer.blog/uploads/2022/f4de364e94.jpg'
'/categories/critters/' = 'https://moondeer.blog/uploads/2021/e0dfd20403.png'
'/categories/stream-of-consciousness/' = 'https://moondeer.blog/uploads/2021/b48fce578f.png'
'/categories/inside-the-art/' = 'https://moondeer.blog/uploads/2021/8c4669346c.jpg'
'/categories/biographical-tripe/' = 'https://moondeer.blog/uploads/2021/ac4a187662.png'
'/categories/artsy-fartsy/' = 'https://moondeer.blog/uploads/2021/608bfd1756.png'
'/perspectives/' = 'https://moondeer.blog/uploads/2021/f5f64b49bb.jpg'
'/projects/' = 'https://moondeer.blog/uploads/2021/74512379fa.png'
'/poetry/' = 'https://moondeer.blog/uploads/2021/02bec3693a.png'
'/music/' = 'https://moondeer.blog/uploads/2021/b604ce0519.png'
'/programming/' = 'https://moondeer.blog/uploads/2021/0d2564a5e5.png'
'/critters/' = 'https://moondeer.blog/uploads/2021/e0dfd20403.png'
'/stream-of-consciousness/' = 'https://moondeer.blog/uploads/2021/b48fce578f.png'
'/inside-the-art/' = 'https://moondeer.blog/uploads/2021/8c4669346c.jpg'
'/biographical-tripe/' = 'https://moondeer.blog/uploads/2021/ac4a187662.png'
'/artsy-fartsy/' = 'https://moondeer.blog/uploads/2021/608bfd1756.png'
'/plausible/' = 'https://moondeer.blog/uploads/2022/50a7a18be8.jpg'
'/programming/plugins/' = 'https://moondeer.blog/uploads/2022/f4de364e94.jpg'
'/2021/' = 'https://moondeer.blog/uploads/2022/ad662657fb.jpg'
'/2020/' = 'https://moondeer.blog/uploads/2022/487bd2af82.jpg'
'/2022/' = 'https://moondeer.blog/uploads/2022/91f7c53987.jpg'

And there you have it. That's what makes the images show up.

Okay, smart-ass … why, then … why do the images show up?

Why the Images Show Up

Magic

For f$&k's sa…

Just f$&kin' with ya bud (plus I'm still kinda phonin' it in, and that sh$t is universal … humor included).

The images show up because the plugin takes your image assignments and generates a stylesheet for decorating all those <div> tags that got injected.

Stare in wonder at the majestic application of resources.ExecuteAsTemplate:

{{ with .Scratch.Get "plugin-banner.Parameters" }}

.{{ .Style.ClassName }} {
  background-color: {{ .Style.Color }};
  height: {{ .Style.Height }};
  width: {{ .Style.Width }};
  background-position: {{ .Style.Position }};
  background-repeat: {{ .Style.Repeat }};
  background-size: {{ .Style.Size }};
  position: relative;
    
  {{ $URLs := .Banners.URLs }}
  
  {{ range $id, $index := .Banners.IndexByID }}  
    &#{{ $id }} { background-image: url({{ index $URLs $index }}); }  
  {{ end }}
  
}

{{ end }}

Wait … what's all that Style stuff?

All That Style Stuff

The style stuff allows for the customization of the appearance of that class we slapped on all the <div> tags. The parameter values are located in the data template that lives at data/plugin_banner/Style.toml (or better yet … in a template you've created in your custom theme that lives at data/plugin-banner/Style.toml … see how this works?). The file, full of default values, looks like this (if this isn't your first Style.toml, you'll notice this is before I went all block-based):

# Parameter values used to generate the stylesheet.
###################################################

# The class name to attach to the banner image.
#
ClassName = 'banner-image'

# The background-color CSS property value for the image.
#
Color = 'inherit'

# The height CSS property value for the image.
#
Height = '300px'

# The width CSS property value for the image.
#
Width = '100%'

# The background-position CSS property value for the image.
#
Position = 'center'

# The background-repeat CSS property value for the image.
#
Repeat = 'no-repeat'

# The background-size CSS property value for the image.
#
Size = 'cover'

Given these, default parameters, and my image assignments, you end up generating a Sass file that is all:

.banner-image {
  background-color: #516189;
  height: 300px;
  width: 100%;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  position: relative;
  
  &#banner-2020 { background-image: url(https://moondeer.blog/uploads/2022/487bd2af82.jpg); }
  &#banner-2021 { background-image: url(https://moondeer.blog/uploads/2022/ad662657fb.jpg); }
  &#banner-2022 { background-image: url(https://moondeer.blog/uploads/2022/91f7c53987.jpg); }
  &#banner-about { background-image: url(https://moondeer.blog/uploads/2021/955619b235.jpg); }
  &#banner-artsy-fartsy { background-image: url(https://moondeer.blog/uploads/2021/608bfd1756.png); }
  &#banner-biographical-tripe { background-image: url(https://moondeer.blog/uploads/2021/ac4a187662.png); }
  &#banner-bookshelf { background-image: url(https://moondeer.blog/uploads/2021/27a279361f.jpg); }
  &#banner-categories-artsy-fartsy { background-image: url(https://moondeer.blog/uploads/2021/608bfd1756.png); }
  &#banner-categories-biographical-tripe { background-image: url(https://moondeer.blog/uploads/2021/ac4a187662.png); }
  &#banner-categories-critters { background-image: url(https://moondeer.blog/uploads/2021/e0dfd20403.png); }
  &#banner-categories-inside-the-art { background-image: url(https://moondeer.blog/uploads/2021/8c4669346c.jpg); }
  &#banner-categories-microblog { background-image: url(https://moondeer.blog/uploads/2022/f4de364e94.jpg); }
  &#banner-categories-music { background-image: url(https://moondeer.blog/uploads/2021/b604ce0519.png); }
  &#banner-categories-perspectives { background-image: url(https://moondeer.blog/uploads/2021/f5f64b49bb.jpg); }
  &#banner-categories-poetry { background-image: url(https://moondeer.blog/uploads/2021/02bec3693a.png); }
  &#banner-categories-programming { background-image: url(https://moondeer.blog/uploads/2021/0d2564a5e5.png); }
  &#banner-categories-projects { background-image: url(https://moondeer.blog/uploads/2021/74512379fa.png); }
  &#banner-categories-stream-of-consciousness { background-image: url(https://moondeer.blog/uploads/2021/b48fce578f.png); }
  &#banner-cloud { background-image: url(https://moondeer.blog/uploads/2021/547d825d8a.jpg); }
  &#banner-critters { background-image: url(https://moondeer.blog/uploads/2021/e0dfd20403.png); }
  &#banner-gallery { background-image: url(https://moondeer.blog/uploads/2021/8585a4a081.jpg); }
  &#banner-home { background-image: url(https://moondeer.blog/uploads/2021/8135337116.png); }
  &#banner-inside-the-art { background-image: url(https://moondeer.blog/uploads/2021/8c4669346c.jpg); }
  &#banner-music { background-image: url(https://moondeer.blog/uploads/2021/b604ce0519.png); }
  &#banner-perspectives { background-image: url(https://moondeer.blog/uploads/2021/f5f64b49bb.jpg); }
  &#banner-plausible { background-image: url(https://moondeer.blog/uploads/2022/50a7a18be8.jpg); }
  &#banner-poetry { background-image: url(https://moondeer.blog/uploads/2021/02bec3693a.png); }
  &#banner-programming { background-image: url(https://moondeer.blog/uploads/2021/0d2564a5e5.png); }
  &#banner-programming-plugins { background-image: url(https://moondeer.blog/uploads/2022/f4de364e94.jpg); }
  &#banner-projects { background-image: url(https://moondeer.blog/uploads/2021/74512379fa.png); }
  &#banner-stream-of-consciousness { background-image: url(https://moondeer.blog/uploads/2021/b48fce578f.png); }
}

Okay … but what does the generated CSS look like?

Fuuuuuuck … fine. I'll show you the generated CSS.

The Generated CSS

How the generated CSS comes out depends on how you've got the third data template configured. It lives at data/plugin_banner/Config.toml and it looks like this:

# Debug and build related parameters.
#####################################

# Theme version, printed to HTML comment when the plugin loads.
#
Version = '4.0.1'

# Whether to print HTML comments for debugging purposes.
#
DebugPrint = false

# Whether to provide subresource integrity by generating a 
# base64-encoded cryptographic hash and attaching a .Data.Integrity
# property containing an integrity string, which is made up of the
# name of the hash function, one hyphen and the base64-encoded hash sum.
#
Fingerprint = true

# Output style for /assets/sass/toc.scss. 
# Valid options are nested, expanded, compact and compressed
#
SassOutput = 'compact'

Read the comments, I took the time to write them. As for how the CSS files comes out, if you set SassOutput equal to compressed like I have, given the default style values and my registered images, it comes out all:

.banner-image{background-color:#516189;height:300px;width:100%;background-position:center;background-repeat:no-repeat;background-size:cover;position:relative}.banner-image#banner-2020{background-image:url(https://moondeer.blog/uploads/2022/487bd2af82.jpg)}.banner-image#banner-2021{background-image:url(https://moondeer.blog/uploads/2022/ad662657fb.jpg)}.banner-image#banner-2022{background-image:url(https://moondeer.blog/uploads/2022/91f7c53987.jpg)}.banner-image#banner-about{background-image:url(https://moondeer.blog/uploads/2021/955619b235.jpg)}.banner-image#banner-artsy-fartsy{background-image:url(https://moondeer.blog/uploads/2021/608bfd1756.png)}.banner-image#banner-biographical-tripe{background-image:url(https://moondeer.blog/uploads/2021/ac4a187662.png)}.banner-image#banner-bookshelf{background-image:url(https://moondeer.blog/uploads/2021/27a279361f.jpg)}.banner-image#banner-categories-artsy-fartsy{background-image:url(https://moondeer.blog/uploads/2021/608bfd1756.png)}.banner-image#banner-categories-biographical-tripe{background-image:url(https://moondeer.blog/uploads/2021/ac4a187662.png)}.banner-image#banner-categories-critters{background-image:url(https://moondeer.blog/uploads/2021/e0dfd20403.png)}.banner-image#banner-categories-inside-the-art{background-image:url(https://moondeer.blog/uploads/2021/8c4669346c.jpg)}.banner-image#banner-categories-microblog{background-image:url(https://moondeer.blog/uploads/2022/f4de364e94.jpg)}.banner-image#banner-categories-music{background-image:url(https://moondeer.blog/uploads/2021/b604ce0519.png)}.banner-image#banner-categories-perspectives{background-image:url(https://moondeer.blog/uploads/2021/f5f64b49bb.jpg)}.banner-image#banner-categories-poetry{background-image:url(https://moondeer.blog/uploads/2021/02bec3693a.png)}.banner-image#banner-categories-programming{background-image:url(https://moondeer.blog/uploads/2021/0d2564a5e5.png)}.banner-image#banner-categories-projects{background-image:url(https://moondeer.blog/uploads/2021/74512379fa.png)}.banner-image#banner-categories-stream-of-consciousness{background-image:url(https://moondeer.blog/uploads/2021/b48fce578f.png)}.banner-image#banner-cloud{background-image:url(https://moondeer.blog/uploads/2021/547d825d8a.jpg)}.banner-image#banner-critters{background-image:url(https://moondeer.blog/uploads/2021/e0dfd20403.png)}.banner-image#banner-gallery{background-image:url(https://moondeer.blog/uploads/2021/8585a4a081.jpg)}.banner-image#banner-home{background-image:url(https://moondeer.blog/uploads/2021/8135337116.png)}.banner-image#banner-inside-the-art{background-image:url(https://moondeer.blog/uploads/2021/8c4669346c.jpg)}.banner-image#banner-music{background-image:url(https://moondeer.blog/uploads/2021/b604ce0519.png)}.banner-image#banner-perspectives{background-image:url(https://moondeer.blog/uploads/2021/f5f64b49bb.jpg)}.banner-image#banner-plausible{background-image:url(https://moondeer.blog/uploads/2022/50a7a18be8.jpg)}.banner-image#banner-poetry{background-image:url(https://moondeer.blog/uploads/2021/02bec3693a.png)}.banner-image#banner-programming{background-image:url(https://moondeer.blog/uploads/2021/0d2564a5e5.png)}.banner-image#banner-programming-plugins{background-image:url(https://moondeer.blog/uploads/2022/f4de364e94.jpg)}.banner-image#banner-projects{background-image:url(https://moondeer.blog/uploads/2021/74512379fa.png)}.banner-image#banner-stream-of-consciousness{background-image:url(https://moondeer.blog/uploads/2021/b48fce578f.png)}

See yas ☾𐂂