Added support for featured videos and optionally removing features from article header
This commit is contained in:
parent
d3ab5f343d
commit
cc38f170f5
9 changed files with 476 additions and 92 deletions
|
|
@ -5,11 +5,10 @@ date = 2025-02-27T07:07:07-05:00
|
|||
draft = false
|
||||
categories = ['thoughts']
|
||||
tags = ['hugo', 'web']
|
||||
disableToc = true
|
||||
showFeature = false
|
||||
+++
|
||||
|
||||
First Post!!!
|
||||
<!--more-->
|
||||
|
||||
## Social anxiety or introvert, chicken or egg?
|
||||
|
||||
I have been an introvert for as long as I can remember, and while I don't want this to turn into a self-help post, suffice it to say that I have never made a personal website primarily because it makes the hairs on the back of my neck stand up. Let today be the day that I face my fears and finally launch this site.
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ categories = ['references']
|
|||
tags = ['hugo', 'markdown']
|
||||
+++
|
||||
|
||||
This cheatsheet is intended as a quick reference and showcase of the markdown syntax used in Hugo and Congo.
|
||||
<!--more-->
|
||||
|
||||
{{< lead >}}
|
||||
This cheatsheet is intended as a quick reference and showcase of the markdown syntax used in Hugo and Congo.
|
||||
{{< /lead >}}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,57 +0,0 @@
|
|||
---
|
||||
title: "TOC Disable Example"
|
||||
description: "Example showing how to disable the table of contents in markdown files"
|
||||
date: 2025-01-27
|
||||
draft: false
|
||||
categories: ['examples']
|
||||
tags: ['toc', 'markdown', 'hugo']
|
||||
disableToc: true # This disables the table of contents for this page
|
||||
---
|
||||
|
||||
{{< lead >}}
|
||||
This page demonstrates how to disable the table of contents in markdown files.
|
||||
{{< /lead >}}
|
||||
|
||||
## How to Disable TOC
|
||||
|
||||
To disable the table of contents in any markdown file (including `index.md` files), simply add the `disableToc: true` parameter to the front matter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Your Page Title"
|
||||
description: "Your page description"
|
||||
disableToc: true # This disables the TOC
|
||||
---
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### For Individual Pages
|
||||
Add `disableToc: true` to the front matter of any markdown file to disable the TOC for that specific page.
|
||||
|
||||
### For Index Pages
|
||||
For `index.md` files that serve as list pages, you can also use the `cascade` parameter to apply the setting to all pages in that section:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: "Section Title"
|
||||
cascade:
|
||||
disableToc: true # Disables TOC for all pages in this section
|
||||
---
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
When `disableToc: true` is set:
|
||||
|
||||
1. The table of contents will not be displayed on the page
|
||||
2. The TOC JavaScript will not be loaded (improving performance)
|
||||
3. The TOC highlighting functionality will be disabled
|
||||
|
||||
## Note
|
||||
|
||||
This feature works for both:
|
||||
- Individual article pages (using the `single.html` template)
|
||||
- List/index pages (using the `list.html` template)
|
||||
|
||||
The TOC will still be generated by Hugo, but it won't be displayed or have JavaScript functionality when disabled.
|
||||
|
|
@ -7,9 +7,6 @@ categories = ['references']
|
|||
tags = ['LSI', 'TrueNAS Scale', 'Broadcom', 'Update', 'SAS3Flash', 'HBA']
|
||||
+++
|
||||
|
||||
Navigating Broadcom and LSI HBA updates on TrueNAS Scale.
|
||||
<!--more-->
|
||||
|
||||
{{< lead >}}
|
||||
Navigating Broadcom and LSI HBA updates on TrueNAS Scale.
|
||||
{{< /lead >}}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
<article class="mt-6 flex max-w-prose flex-row">
|
||||
{{- $images := $.Resources.ByType "image" }}
|
||||
{{- $videos := $.Resources.ByType "video" }}
|
||||
{{- $thumbnail := $images.GetMatch (.Params.thumbnail | default "*thumb*") }}
|
||||
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $thumbnail }}
|
||||
{{- if not $feature }}
|
||||
{{- $feature = $videos.GetMatch (.Params.feature | default "*feature*") }}
|
||||
{{- end }}
|
||||
{{- with $feature }}
|
||||
<div class="flex-none pe-4 sm:pe-6 ">
|
||||
<a
|
||||
|
|
@ -12,6 +16,21 @@
|
|||
{{ end }}"
|
||||
aria-label="{{ $.Title | emojify }}"
|
||||
>
|
||||
{{ if eq .ResourceType "video" }}
|
||||
<video
|
||||
class="w-24 rounded-md sm:w-40 max-h-[7.5rem]"
|
||||
autoplay
|
||||
loop
|
||||
muted
|
||||
playsinline
|
||||
{{ if $.Site.Params.enableImageLazyLoading | default true }}
|
||||
loading="lazy"
|
||||
{{ end }}
|
||||
aria-label="{{ $.Params.featureAlt | default $.Params.thumbnailAlt | default "" }}"
|
||||
>
|
||||
<source src="{{ .RelPermalink }}" type="{{ .MediaType }}">
|
||||
</video>
|
||||
{{ else }}
|
||||
<img
|
||||
alt="{{ $.Params.featureAlt | default $.Params.thumbnailAlt | default "" }}"
|
||||
{{ if eq .MediaType.SubType "svg" }}
|
||||
|
|
@ -27,6 +46,7 @@
|
|||
loading="lazy"
|
||||
{{ end }}
|
||||
/>
|
||||
{{ end }}
|
||||
</a>
|
||||
</div>
|
||||
{{- end }}
|
||||
|
|
@ -70,7 +90,15 @@
|
|||
</div>
|
||||
{{ if .Params.showSummary | default (.Site.Params.list.showSummary | default false) }}
|
||||
<div class="prose py-1 dark:prose-invert">
|
||||
{{ $summary := .Summary | emojify }}
|
||||
{{ $summary := "" }}
|
||||
{{ $hasManualSummary := findRE "<!--\\s*more\\s*-->" .RawContent }}
|
||||
{{ if $hasManualSummary }}
|
||||
{{ $summary = .Summary | emojify }}
|
||||
{{ else if .Description }}
|
||||
{{ $summary = .Description | emojify }}
|
||||
{{ else }}
|
||||
{{ $summary = .Summary | emojify }}
|
||||
{{ end }}
|
||||
{{ $summary := replaceRE "<h[1-6][^>]*>(.*?)</h[1-6]>" "$1" $summary }}
|
||||
{{ $summary := replaceRE "\\s*<br\\s*/?>" " " $summary }}
|
||||
{{ $summary := replaceRE "\\s+" " " $summary }}
|
||||
|
|
|
|||
23
layouts/partials/video.html
Normal file
23
layouts/partials/video.html
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{{ $video := .video }}
|
||||
{{ $class := .class }}
|
||||
{{ $lazy := .lazy }}
|
||||
{{ $alt := .alt }}
|
||||
{{ $autoplay := .autoplay | default true }}
|
||||
{{ $loop := .loop | default true }}
|
||||
{{ $muted := .muted | default true }}
|
||||
|
||||
{{ with $video }}
|
||||
<video
|
||||
{{ with $class }}class="{{ . }}"{{ end }}
|
||||
{{ if $autoplay }}autoplay{{ end }}
|
||||
{{ if $loop }}loop{{ end }}
|
||||
{{ if $muted }}muted{{ end }}
|
||||
playsinline
|
||||
{{ with $lazy }}loading="lazy"{{ end }}
|
||||
{{ with $alt }}aria-label="{{ . }}"{{ end }}
|
||||
>
|
||||
<source src="{{ .RelPermalink }}" type="{{ .MediaType }}">
|
||||
{{ with $alt }}{{ . }}{{ end }}
|
||||
</video>
|
||||
{{ end }}
|
||||
|
||||
|
|
@ -1,8 +1,12 @@
|
|||
{{ define "main" }}
|
||||
{{ partial "background-images.html" . }}
|
||||
{{- $images := .Resources.ByType "image" }}
|
||||
{{- $videos := .Resources.ByType "video" }}
|
||||
{{- $cover := $images.GetMatch (.Params.cover | default "*cover*") }}
|
||||
{{- $feature := $images.GetMatch (.Params.feature | default "*feature*") | default $cover }}
|
||||
{{- if not $feature }}
|
||||
{{- $feature = $videos.GetMatch (.Params.feature | default "*feature*") }}
|
||||
{{- end }}
|
||||
<article class="prose max-w-full dark:prose-invert glass">
|
||||
<header class="max-w-prose">
|
||||
{{ if .Params.showBreadcrumbs | default (.Site.Params.article.showBreadcrumbs | default false) }}
|
||||
|
|
@ -22,17 +26,23 @@
|
|||
{{ partial "article-meta.html" (dict "context" . "scope" "single") }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .Params.showFeature | default true }}
|
||||
{{ with $feature }}
|
||||
<div class="prose">
|
||||
{{ $altText := $.Params.featureAlt | default $.Params.coverAlt | default "" }}
|
||||
{{ $class := "mb-6 rounded-md" }}
|
||||
{{ if eq .ResourceType "video" }}
|
||||
{{ partial "video.html" (dict "video" . "alt" $altText "class" $class "lazy" false "autoplay" true "loop" true "muted" true) }}
|
||||
{{ else }}
|
||||
{{ $webp := $.Page.Site.Params.enableImageWebp | default true }}
|
||||
{{ partial "picture.html" (dict "img" . "alt" $altText "class" $class "lazy" false "webp" $webp) }}
|
||||
{{ end }}
|
||||
{{ with $.Params.coverCaption }}
|
||||
<figcaption class="-mt-3 mb-6 text-center">{{ . | markdownify }}</figcaption>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</header>
|
||||
<section class="prose mt-0 flex max-w-full flex-col dark:prose-invert lg:flex-row">
|
||||
{{ if and (not (.Params.disableToc | default false)) (.Params.showTableOfContents | default (.Site.Params.article.showTableOfContents | default false)) (in .TableOfContents "<ul") }}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,387 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, initial-scale=1.0">
|
||||
<title>Matrix Synapse Docker Guide</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@700;800&family=Archivo+Black&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #0a0a0a;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#scaler {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
width: 1280px;
|
||||
height: 720px;
|
||||
background: linear-gradient(135deg, #0d1117 0%, #1a1f2e 50%, #0d1117 100%);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 30px 90px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
/* Animated grid background */
|
||||
.grid-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(rgba(0, 255, 159, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0, 255, 159, 0.03) 1px, transparent 1px);
|
||||
background-size: 40px 40px;
|
||||
animation: gridPulse 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes gridPulse {
|
||||
0%, 100% { opacity: 0.6; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Glowing orbs */
|
||||
.orb {
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
filter: blur(80px);
|
||||
opacity: 0.4;
|
||||
animation: float 8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.orb-1 {
|
||||
width: 400px;
|
||||
height: 400px;
|
||||
background: radial-gradient(circle, #00ff9f 0%, transparent 70%);
|
||||
top: -100px;
|
||||
right: -100px;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.orb-2 {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
background: radial-gradient(circle, #00bfff 0%, transparent 70%);
|
||||
bottom: -80px;
|
||||
left: -80px;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
|
||||
.orb-3 {
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
background: radial-gradient(circle, #7c3aed 0%, transparent 70%);
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
animation-delay: 4s;
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
||||
33% { transform: translate(30px, -30px) scale(1.1); }
|
||||
66% { transform: translate(-30px, 30px) scale(0.9); }
|
||||
}
|
||||
|
||||
/* Content container */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 60px 80px;
|
||||
}
|
||||
|
||||
/* Matrix logo section */
|
||||
.logo-section {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.matrix-logo {
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
background: linear-gradient(135deg, #00ff9f 0%, #00bfff 100%);
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 42px;
|
||||
font-weight: 800;
|
||||
color: #0a0a0a;
|
||||
box-shadow: 0 8px 32px rgba(0, 255, 159, 0.3);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.matrix-logo::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
background: linear-gradient(45deg, transparent 30%, rgba(255, 255, 255, 0.3) 50%, transparent 70%);
|
||||
animation: shine 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes shine {
|
||||
0% { transform: translateX(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(200%) rotate(45deg); }
|
||||
}
|
||||
|
||||
.matrix-logo-text {
|
||||
font-family: 'Archivo Black', sans-serif;
|
||||
font-size: 36px;
|
||||
color: #ffffff;
|
||||
letter-spacing: -1px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Main title */
|
||||
.main-title {
|
||||
font-family: 'Archivo Black', sans-serif;
|
||||
font-size: 82px;
|
||||
line-height: 0.95;
|
||||
color: #ffffff;
|
||||
margin-bottom: 30px;
|
||||
letter-spacing: -3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.title-line-1 {
|
||||
display: block;
|
||||
background: linear-gradient(90deg, #ffffff 0%, #00ff9f 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.title-line-2 {
|
||||
display: block;
|
||||
color: #ffffff;
|
||||
margin-left: 120px;
|
||||
}
|
||||
|
||||
/* Tech badges */
|
||||
.tech-badges {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
.badge {
|
||||
padding: 12px 24px;
|
||||
background: rgba(0, 63, 39, 0.9);
|
||||
border: 2px solid rgba(0, 255, 159, 0.3);
|
||||
border-radius: 8px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #00ff9f;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: 0 4px 16px rgba(0, 255, 159, 0.1);
|
||||
}
|
||||
|
||||
/* Docker compose visual */
|
||||
.docker-visual {
|
||||
position: absolute;
|
||||
right: 80px;
|
||||
bottom: 80px;
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
.terminal-window {
|
||||
background: rgba(13, 17, 23, 0.95);
|
||||
border: 1px solid rgba(0, 255, 159, 0.2);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
.terminal-header {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.terminal-dot {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.dot-1 { background: #ff5f56; }
|
||||
.dot-2 { background: #ffbd2e; }
|
||||
.dot-3 { background: #27c93f; }
|
||||
|
||||
.terminal-content {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.terminal-line {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.terminal-prompt {
|
||||
color: #00ff9f;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.terminal-command {
|
||||
color: #00bfff;
|
||||
}
|
||||
|
||||
.terminal-comment {
|
||||
color: #6e7681;
|
||||
}
|
||||
|
||||
.terminal-yaml {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.yaml-key {
|
||||
color: #ff7b72;
|
||||
}
|
||||
|
||||
.yaml-value {
|
||||
color: #a5d6ff;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
background: #00ff9f;
|
||||
animation: blink 1s step-end infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* Decorative elements */
|
||||
.deco-line {
|
||||
position: absolute;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent, #00ff9f, transparent);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.deco-line-1 {
|
||||
width: 300px;
|
||||
top: 180px;
|
||||
left: 80px;
|
||||
}
|
||||
|
||||
.deco-line-2 {
|
||||
width: 200px;
|
||||
bottom: 200px;
|
||||
right: 520px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scaler">
|
||||
<div class="thumbnail">
|
||||
<div class="grid-bg"></div>
|
||||
<div class="orb orb-1"></div>
|
||||
<div class="orb orb-2"></div>
|
||||
<div class="orb orb-3"></div>
|
||||
<div class="deco-line deco-line-1"></div>
|
||||
<div class="deco-line deco-line-2"></div>
|
||||
|
||||
<div class="content">
|
||||
<div class="logo-section">
|
||||
<div class="matrix-logo">[m]</div>
|
||||
<div class="matrix-logo-text">Synapse</div>
|
||||
</div>
|
||||
|
||||
<h1 class="main-title">
|
||||
<span class="title-line-1">Self-Host</span>
|
||||
<span class="title-line-2">Your Server</span>
|
||||
</h1>
|
||||
|
||||
<div class="tech-badges">
|
||||
<div class="badge">Docker</div>
|
||||
<div class="badge">Compose</div>
|
||||
<div class="badge">Matrix</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="docker-visual">
|
||||
<div class="terminal-window">
|
||||
<div class="terminal-header">
|
||||
<div class="terminal-dot dot-1"></div>
|
||||
<div class="terminal-dot dot-2"></div>
|
||||
<div class="terminal-dot dot-3"></div>
|
||||
</div>
|
||||
<div class="terminal-content">
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-prompt">$</span>
|
||||
<span class="terminal-command">docker compose up -d</span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-comment"># Starting services...</span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"><span class="yaml-key">synapse:</span></span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"> <span class="yaml-key">image:</span> <span class="yaml-value">matrixdotorg/synapse</span></span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"> <span class="yaml-key">ports:</span></span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"> - <span class="yaml-value">8008:8008</span></span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"> <span class="yaml-key">volumes:</span></span>
|
||||
</div>
|
||||
<div class="terminal-line">
|
||||
<span class="terminal-yaml"> - <span class="yaml-value">./data:/data</span><span class="cursor"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function scaleContent() {
|
||||
const scaler = document.getElementById('scaler');
|
||||
const scaleX = window.innerWidth / 1280;
|
||||
const scaleY = window.innerHeight / 720;
|
||||
const scale = Math.min(scaleX, scaleY);
|
||||
scaler.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
scaleContent();
|
||||
window.addEventListener('resize', scaleContent);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Reference in a new issue