Revamp the guides section: taxonomy, single-page structure, and new landing/filter UX (#25338)

## What

A full revamp of the `/guides` section — taxonomy, structure, and UX.

Preview: https://deploy-preview-25338--docsdocker.netlify.app/guides/

### Taxonomy & structure
- Replaces the sprawling 24-tag set with a focused 9-tag taxonomy
aligned to use case / SDLC: **Languages & frameworks, AI, Testing,
CI/CD, Security, Databases, Deployment, Admin, Hands-on labs**.
- Removes the languages taxonomy entirely (`data/languages.yaml` and all
`languages:` front matter).
- Collapses all multi-page guide series into single pages, with aliases
so old sub-page URLs continue to resolve.
- Deletes redirect-only shim pages and flattens directory-wrapped single
pages.

### Landing page (`/guides/`)
- A clean index: hero, then category sections listing each guide as a
plain **title / summary** row.
- **Browse rail** (sticky, left): click a topic to filter the page to
just that topic's guides; "All guides" resets. A count + Clear bar
appears while filtering.
- **Text filter**: instant client-side search over title, summary, and
tags. Topic filter and text search are mutually exclusive and share the
same flat-list view.
- No more "Featured guides" section.

### Guide content pages
- Removes the left sidebar for the guides section (mobile drawer kept).
- Centered reading column (`92ch`) with the TOC taking the remaining
width.
- Summary rendered as a lead paragraph under the h1.
- TOC scrollbar auto-hides until hover; breadcrumbs render at a
consistent size inside and outside `prose`.

## Notes
- Deep full-text search across guide bodies is still handled by the
existing site-wide Pagefind (⌘K); the landing filter is the fast
metadata-narrowing surface.
- `series.html` is retained — it's still used by `get-started` pages.

## Validation
- Site builds clean locally (Hugo dev server, no errors / broken refs).
- All collapsed sub-page URLs redirect via aliases.

## Follow-ups

- Prune guides that we no longer need/want
- Tighten the guides that span too many concepts (e.g. language guides;
remove cicd/deploy/sscs)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
David KarlssonandClaude Sonnet 4.6 authored and GitHub committed 2026-07-01 10:47:10 +02:00
1 parent ef2165d47c
commit f02e2a5633
302 files changed
+23207 -24782

No files matched your search

+1 -1
View File
@@ -1,5 +1,5 @@
<aside
class="sticky top-16 h-[calc(100vh-64px)] min-w-52 space-y-4 overflow-y-auto py-4 w-full"
class="scrollbar-hover sticky top-16 h-[calc(100vh-64px)] min-w-52 space-y-4 overflow-y-auto py-4 w-full"
>
{{ partial "github-links.html" . }}
<div id="TableOfContents" class="overflow-x-auto">
+5
View File
@@ -1,5 +1,10 @@
{{ partial "breadcrumbs.html" . }}
<h1 data-pagefind-weight="10">{{ .Title | safeHTML }}</h1>
{{- if and (eq .Type "guides") .Params.summary }}
<p class="mt-0 text-lg text-gray-500 dark:text-gray-400">
{{ .Params.summary }}
</p>
{{- end }}
<div class="hidden lg:block">
{{ partialCached "md-dropdown.html" "-" "-" }}
</div>
-15
View File
@@ -1,15 +0,0 @@
{{- range . -}}
{{- $lang := index hugo.Data.languages . -}}
{{- with $lang }}
<span class="chip">
<img
class="py-1"
height="18"
width="18"
title="{{ .title }}"
src="{{ .icon }}"
/>
<span>{{ .title }}</span>
</span>
{{- end -}}
{{- end -}}
-9
View File
@@ -1,9 +0,0 @@
{{- range . -}}
{{- $tag := index hugo.Data.tags . -}}
{{- with $tag }}
<span class="chip">
<span class="icon-svg icon-sm pb-0.5">{{ partialCached "icon" "tag" "tag" }}</span>
{{ .title }}
</span>
{{- end -}}
{{- end -}}
-58
View File
@@ -1,58 +0,0 @@
{{/* - Multi-page guide: render a progress bar - */}}
<div class="my-4 flex flex-col items-start text-sm">
{{ $totalPages := len .CurrentSection.Pages }}
{{/* - initialize the page store
$stepper_seen controls the color of the item in the stepper
green: "completed" - index is lower than current page
blue: current page
gray: next in section
for the section page, they're all gray
default to true if kind = section
(make all entries gray)
-
*/}}
{{ page.Store.Set "stepper_seen" .IsSection }}
{{/* - Loop over the pages in this guide - */}}
{{ range $i, $e := .CurrentSection.Pages }}
{{ $isLast := eq (add $i 1) $totalPages }}
<div class="flex">
<div class="flex flex-col items-center">
{{/* - Render the page's index digit (1,2,3,4 etc) - */}}
<a
href="{{ .Permalink }}"
class="{{ if (page.Store.Get "stepper_seen") }}
bg-gray-400 dark:bg-gray-500
{{ else if (eq . page) }}
{{ .Store.Set "stepper_seen" true }} bg-blue-400 dark:bg-blue-800
{{ else }}
bg-green-400 dark:bg-green-dark-400
{{ end }} flex h-8 w-8 items-center justify-center rounded-full text-white no-underline"
>
{{ add $i 1 }}
</a>
{{/* - Render the vertical border - */}}
{{ if not $isLast }}
<div
class="{{ if (page.Store.Get "stepper_seen") }}
border-gray-400 dark:border-gray-400
{{ else if (eq . page) }}
border-blue-400 dark:border-blue-400
{{ else }}
border-green-400 dark:border-green-400
{{ end }} h-6 border-l-2"
></div>
{{ end }}
</div>
{{/* - Render the page's title - */}}
<div class="ml-2 flex h-8 items-center self-start">
<a href="{{ .Permalink }}">
{{ .LinkTitle }}
</a>
</div>
</div>
{{ end }}
</div>
-39
View File
@@ -1,39 +0,0 @@
{{- $guide := cond (eq .CurrentSection .FirstSection) . .CurrentSection -}}
<div class="flex flex-col gap-4 px-4 pt-2">
<div class="font-semibold">
<a href="{{ $guide.Permalink }}">{{ $guide.Title }}</a>
</div>
<div>{{ $guide.Summary }}</div>
<div class="space-y-4">
<div class="flex flex-wrap gap-2">
{{- with $guide.Params.languages }}
{{ partial "guide-languages.html" . }}
{{- end }}
{{- with $guide.Params.tags }}
{{ partial "guide-tags.html" . }}
{{- end }}
</div>
{{- with $guide.Params.time }}
<div class="flex gap-2 text-gray-400 dark:text-gray-400">
<span class="icon-svg"
>{{ partialCached "icon" "clock" "clock" }}</span
>
<span>{{ . }}</span>
</div>
{{- end -}}
</div>
{{- if gt (len $guide.Pages) 0 }}
{{- partial "guides-stepper.html" . }}
{{- end }}
{{- with $guide.Params.resource_links }}
<div class="space-y-2">
<p>Resources:</p>
<ul class="ml-4 space-y-2">
{{- range . }}
<li><a href="{{ .url }}" class="link">{{ .title }}</a></li>
{{- end }}
</ul>
</div>
{{- end }}
<a href="/guides/" class="link mt-2">&laquo; Back to all guides</a>
</div>
+2 -6
View File
@@ -30,7 +30,7 @@
}
}
})"
class="bg-background-toc dark:bg-background-toc fixed top-0 z-40 hidden h-screen w-full flex-none overflow-x-hidden overflow-y-auto md:sticky md:top-16 md:z-auto md:block md:h-[calc(100vh-64px)] md:w-[320px]"
class="bg-background-toc dark:bg-background-toc fixed top-0 z-40 hidden h-screen w-full flex-none overflow-x-hidden overflow-y-auto{{ if ne .Type "guides" }} md:sticky md:top-16 md:z-auto md:block md:h-[calc(100vh-64px)] md:w-[320px]{{ end }}"
:class="{ 'hidden': ! $store.showSidebar }"
>
<!-- Gray backdrop on small screens -->
@@ -53,11 +53,7 @@
<!-- Actual Sidebar Content -->
{{ block "left" . }}
{{ partial "sidebar/mainnav.html" . }}
{{ if eq .Type "guides" }}
{{ partial "sidebar/guides.html" . }}
{{ else }}
{{ partial "sidebar/sections.html" . }}
{{ end }}
{{ partial "sidebar/sections.html" . }}
{{ end }}
</div>
</div>
+207 -262
View File
@@ -1,273 +1,218 @@
{{ define "left" }}
{{- partial "sidebar/mainnav.html" . }}
<div class="navbar-font flex flex-col gap-2 p-4 text-sm">
<p>Filter guides by tag or programming language.</p>
<p></p>
<div
class="space-y-4"
x-data="{
filters: { tags: [], languages: [] },
toggleFilter(grp, tag) {
this.filters[grp].includes(tag)
? this.filters[grp] = this.filters[grp].filter(el => el != tag)
: this.filters[grp].push(tag);
// Update URL
const url = new URL(window.location.href);
if (this.filters[grp].length > 0) {
url.searchParams.set(grp, this.filters[grp].join('~'));
} else {
url.searchParams.delete(grp);
}
window.history.replaceState({}, '', url);
this.$dispatch('guide-filter', { filters: this.filters });
},
init() {
const url = new URL(window.location.href);
const tags = url.searchParams.get('tags')
const langs = url.searchParams.get('languages')
if (tags != null) {
this.filters['tags'] = tags.split('~');
}
if (langs != null) {
this.filters['languages'] = langs.split('~');
}
}
}"
@guide-filter.window="filters = $event.detail.filters;"
>
<div class="pl-2"><strong>Tags</strong></div>
<fieldset class="flex flex-col gap-2">
{{- range $name, $data := hugo.Data.tags }}
{{- if where $.Pages "Params.tags" "intersect" (slice $name) }}
{{- $id := anchorize (fmt.Printf "tag-%s" $name) }}
<div class="flex gap-2 pl-2">
<input
value="{{ $name }}"
type="checkbox"
id="{{ $id }}"
@change="toggleFilter('tags', '{{ $name }}')"
:checked="filters['tags'].includes('{{ $name }}')"
/>
<label class="select-none" for="{{ $id }}"
>{{ $data.title }}</label
>
</div>
{{- end }}
{{ end }}
</fieldset>
<div class="pl-2"><strong>Languages</strong></div>
<fieldset class="flex flex-wrap gap-2 pl-2">
{{- range $name, $data := hugo.Data.languages }}
{{- if where $.Pages "Params.languages" "intersect" (slice $name) }}
{{- $id := anchorize (fmt.Printf "lang-%s" $name) }}
<button
class="border-divider-light dark:border-divider-dark flex gap-1 rounded-full border bg-white px-2 py-1 dark:bg-gray-800"
:class="{ 'ring-3-2 ring-3-blue-light-400 dark:ring-3-blue-dark-400': filters['languages'].includes('{{ $name }}') }"
@click="toggleFilter('languages', '{{ $name }}')"
>
<img
height="18"
width="18"
title="{{ $data.title }}"
src="{{ $data.icon }}"
/>
<span>{{ $data.title }}</span>
</button>
{{- end }}
{{ end }}
</fieldset>
</div>
</div>
{{ end }}
{{ define "main" }}
<div class="flex w-full gap-8">
<article class="prose dark:prose-invert max-w-none min-w-0">
{{- partial "breadcrumbs.html" . }}
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1>
{{ .Content }}
<div
class="not-prose min-h-screen"
x-data="{
filters: { tags: [], languages: [] },
hidden: [],
total: {{ len .Pages }},
{{- $tagOrder := slice "languages" "ai" "testing" "cicd" "security" "databases" "deployment" "admin" "labs" }}
noFilters() {
return Object.values(this.filters).every(arr=> Array.isArray(arr) && arr.length === 0);
},
isVisible(el) {
return !this.hidden.includes(el.id);
},
updateVisible() {
const hiddenSet = new Set();
// show if no filters have been selected
if (this.noFilters()) {
this.hidden = [];
return;
};
const guideContainer = this.$refs['guide-container'];
const guides = guideContainer.children
// Loop over the filters object
for (const [key, value] of Object.entries(this.filters)) {
if (!value || value.length === 0) continue;
for (const g of guides) {
// Get the dataset for the current guide (e.g., languages or tags)
const terms = JSON.parse(g.dataset[key]);
// Check if any of the filter values exist in the terms
const containsSome = terms.some(term => this.filters[key].includes(term));
// If none of the terms match the filter, mark the guide as hidden
if (!containsSome) {
hiddenSet.add(g.id)
}
}
}
this.hidden = Array.from(hiddenSet)
},
init() {
const url = new URL(window.location.href);
const tags = url.searchParams.get('tags')
const langs = url.searchParams.get('languages')
if (tags != null) {
this.filters['tags'] = tags.split('~');
}
if (langs != null) {
this.filters['languages'] = langs.split('~');
}
this.updateVisible();
}
}"
x-cloak
@guide-filter.window="filters = $event.detail.filters; updateVisible(); $nextTick(() => { window.scrollTo({ top: 0 }) })"
>
<div x-show="noFilters()">
<h2>Featured guides</h2>
<div
class="not-prose grid grid-cols-1 gap-8 py-4 lg:grid-cols-2 xl:grid-cols-3"
>
{{- $featured := where .Pages "Params.featured" true }}
{{- with $featured }}
{{- range . }}
<div class="flex h-full flex-col">
<a class="hover:underline" href="{{ .Permalink }}">
{{- $img := resources.Get (.Params.image | default "/images/thumbnail.webp") }}
<img
class="h-64 w-full rounded-sm object-cover shadow"
src="{{ $img.Permalink }}"
/>
<p class="my-4 text-xl leading-snug">{{ .Title }}</p>
</a>
<p class="flex-grow text-sm">{{ .Summary }}</p>
<div class="mt-4">
{{ template "guide-metadata" . }}
</div>
</div>
{{- end }}
{{- end }}
</div>
<hr class="text-divider-light dark:text-divider-dark" />
</div>
<h2 x-show="noFilters()" id="all-guides" class="scroll-mt-36">
All guides
</h2>
<div x-show="!noFilters()" class="flex flex-col gap-2 pb-8">
<div class="flex items-center gap-2">
<span class="icon-svg icon-sm mb-1"
>{{ partialCached "icon" "funnel" "funnel" }}</span
>
<p>
Filtered results: showing
<span x-text="total - hidden.length"></span> out of
<span x-text="total"></span> guides.
</p>
</div>
<div class="flex items-center gap-2 pl-4">
{{- range $name, $data := hugo.Data.tags }}
<div x-show="filters.tags.includes('{{ $name }}')">
{{ template "termchip" $data.title }}
</div>
{{- end }}
{{- range $name, $data := hugo.Data.languages }}
<div
x-show="filters.languages.includes('{{ $name }}')"
class="border-divider-light dark:border-divider-dark inline-flex items-center gap-1 rounded-full border bg-gray-100 px-2 text-sm text-gray-200 select-none dark:bg-gray-800 dark:text-gray-300"
>
<img
class="py-1"
height="18"
width="18"
title="{{ $data.title }}"
src="{{ $data.icon }}"
/>
<span>{{ $data.title }}</span>
</div>
{{- end }}
</div>
</div>
<div x-ref="guide-container">
{{- range .Pages }}
<div
id="guide-{{ math.Counter }}"
data-languages="{{ jsonify (.Params.languages | default slice) }}"
data-tags="{{ jsonify (.Params.tags | default slice) }}"
x-show="isVisible($el);"
class="border-divider-light dark:border-divider-dark flex flex-col justify-between border-b p-4 hover:bg-gray-100 hover:dark:bg-gray-800"
>
<div class="flex flex-col justify-between xl:flex-row">
<a
href="{{ .Permalink }}"
class="mb-2 truncate text-lg hover:underline xl:mb-0"
>{{ .Title }}</a
>
{{ template "guide-metadata" . }}
</div>
</div>
{{- end }}
</div>
</div>
</article>
</div>
{{ end }}
{{- define "guide-metadata" }}
<div
class="flex items-center justify-between gap-8 text-sm text-gray-400 dark:text-gray-300"
class="not-prose mx-auto flex min-h-[calc(100dvh-7rem)] max-w-7xl flex-col"
x-data="{
query: '',
tagFilter: '',
words() { return this.query.trim().toLowerCase().split(/\s+/).filter(Boolean) },
textFiltering() { return this.query.trim().length > 0 },
filtering() { return this.textFiltering() || this.tagFilter !== '' },
matchText(text) { return this.words().every(w => text.includes(w)) },
rowVisible(el) { return !this.textFiltering() || this.matchText(el.dataset.search) },
sectionVisible(el) {
if (this.tagFilter) return el.dataset.tag === this.tagFilter;
if (this.textFiltering()) return Array.from(el.querySelectorAll('[data-guide]')).some(r => this.matchText(r.dataset.search));
return true;
},
resultCount() {
if (this.tagFilter) return document.querySelectorAll('section[data-tag=' + this.tagFilter + '] [data-guide]').length;
return Array.from(document.querySelectorAll('[data-guide]')).filter(r => this.matchText(r.dataset.search)).length;
},
selectTag(tag) { this.tagFilter = this.tagFilter === tag ? '' : tag; this.query = ''; window.scrollTo({ top: 0, behavior: 'smooth' }); },
clear() { this.query = ''; this.tagFilter = ''; }
}"
>
<div class="flex flex-wrap gap-2">
{{- with .Params.languages }}
{{ partial "guide-languages.html" . }}
{{- end }}
{{- with .Params.tags }}
{{ partial "guide-tags.html" . }}
{{- partial "breadcrumbs.html" . }}
<div class="mt-4">
<h1
data-pagefind-weight="10"
class="scroll-mt-36 text-5xl font-bold tracking-tight"
>
Guides
</h1>
{{- with .Description }}
<p class="mt-3 text-lg text-gray-500 dark:text-gray-400">{{ . }}</p>
{{- end }}
</div>
{{- with .Params.time }}
<div class="flex flex-shrink gap-2 whitespace-nowrap">
<span class="icon-svg"
>{{ partialCached "icon" "clock" "clock" }}</span
>
<span>{{ . }}</span>
</div>
{{- end }}
</div>
{{- end }}
{{- define "termchip" }}
<span class="chip">
<span class="icon-svg icon-sm pb-0.5">
{{ partialCached "icon" "tag" "tag" }}
</span>
{{ . }}
</span>
{{- end }}
<!-- Text filter -->
<div class="relative mt-8 mb-10 max-w-xl">
<span
class="icon-svg icon-sm pointer-events-none absolute top-1/2 left-3.5 -translate-y-1/2 text-gray-400 dark:text-gray-500"
>
{{ partialCached "icon" "magnifying-glass" "magnifying-glass" }}
</span>
<input
type="search"
x-model="query"
@input="tagFilter = ''"
@keydown.escape="clear()"
aria-label="Filter guides"
placeholder="Filter guides by name, topic, or tag…"
class="w-full rounded-xl border border-gray-300 bg-white py-2.5 pr-10 pl-11 text-sm text-gray-900 shadow-sm transition placeholder:text-gray-400 focus:border-blue-400 focus:ring-2 focus:ring-blue-400/40 focus:outline-none dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:placeholder:text-gray-500"
/>
<button
x-show="query"
x-cloak
@click="clear()"
aria-label="Clear filter"
class="icon-svg icon-sm absolute top-1/2 right-2.5 -translate-y-1/2 rounded-md p-1 text-gray-400 transition hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-800 dark:hover:text-gray-200"
>
{{ partialCached "icon" "x-mark" "x-mark" }}
</button>
</div>
<div class="flex flex-1 gap-16 xl:gap-24">
<!-- Sticky topic filter -->
<nav class="sticky top-20 hidden w-52 flex-none flex-col self-start text-gray-500 xl:flex dark:text-gray-400">
<p class="mb-3 text-xs font-semibold tracking-widest text-gray-400 uppercase dark:text-gray-500">
Browse
</p>
<button
type="button"
@click="clear()"
class="flex items-center justify-between py-1.5 text-left text-sm transition-colors"
:class="!filtering() ? 'text-black dark:text-white font-medium' : 'text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'"
>
<span class="flex items-center gap-2.5">
<span>All guides</span>
</span>
<span class="text-xs tabular-nums text-gray-300 dark:text-gray-600">{{ len .RegularPagesRecursive }}</span>
</button>
{{- range $i, $tag := $tagOrder }}
{{- $tagData := index hugo.Data.tags $tag }}
{{- $pages := where $.RegularPagesRecursive "Params.tags" "intersect" (slice $tag) }}
{{- if $pages }}
<button
type="button"
@click="selectTag('{{ $tag }}')"
class="flex items-center justify-between py-1.5 text-left text-sm transition-colors"
:class="tagFilter === '{{ $tag }}' ? 'text-black dark:text-white font-medium' : 'text-gray-500 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-100'"
>
<span class="flex items-center gap-2.5">
<span>{{ $tagData.title }}</span>
</span>
<span class="text-xs tabular-nums text-gray-300 dark:text-gray-600">{{ len $pages }}</span>
</button>
{{- end }}
{{- end }}
</nav>
<!-- Guide list -->
<div
class="min-w-0 flex-1"
:class="{ 'guides-flat': filtering() }"
>
<!-- Featured: curated highlights, shown only in the default view -->
{{- $featured := where $.RegularPagesRecursive "Params.featured" true }}
{{- with $featured }}
<div x-show="!filtering()" class="mb-12">
<p class="mb-4 flex items-center gap-1.5 text-xs font-semibold tracking-widest text-gray-400 uppercase dark:text-gray-500">
<span class="icon-svg icon-sm text-blue-500">{{ partialCached "icon" "star" "star" }}</span>
Featured
</p>
<div class="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
{{- range .ByWeight }}
<a
href="{{ .Permalink }}"
class="group flex flex-col gap-1.5 rounded-lg border border-gray-200 p-4 transition-colors hover:border-gray-300 dark:border-gray-800 dark:hover:border-gray-700"
>
<span class="font-medium leading-snug text-gray-900 transition-colors group-hover:text-blue-600 dark:text-gray-100 dark:group-hover:text-blue-400">{{ .Title }}</span>
<span class="line-clamp-2 text-sm leading-relaxed text-gray-500 dark:text-gray-400">{{ .Summary }}</span>
</a>
{{- end }}
</div>
</div>
{{- end }}
<!-- Filtering meta bar -->
<div
x-show="filtering()"
x-cloak
class="mb-8 flex items-center justify-between border-b border-gray-200 pb-4 dark:border-gray-800"
>
<p class="text-sm text-gray-500 dark:text-gray-400">
<span class="font-semibold text-gray-900 dark:text-gray-100" x-text="resultCount()"></span>
of {{ len .RegularPagesRecursive }} guides
</p>
<button
@click="clear()"
class="text-sm font-medium text-blue-600 transition hover:underline dark:text-blue-400"
>
Clear filter
</button>
</div>
{{- range $i, $tag := $tagOrder }}
{{- $tagData := index hugo.Data.tags $tag }}
{{- $pages := where $.RegularPagesRecursive "Params.tags" "intersect" (slice $tag) }}
{{- if $pages }}
<section
id="{{ $tag }}"
data-tag="{{ $tag }}"
x-show="sectionVisible($el)"
class="scroll-mt-16 border-t border-gray-200 py-12 first:border-t-0 first:pt-0 dark:border-gray-800"
>
<div class="mb-6" x-show="!filtering()">
<p class="mb-1 text-xs font-semibold tracking-widest text-gray-400 uppercase dark:text-gray-500">
{{- printf "%02d" (add $i 1) -}}
</p>
<h2 class="text-2xl font-bold">{{ $tagData.title }}</h2>
{{- with $tagData.description }}
<p class="mt-1 text-gray-500 dark:text-gray-400">{{ . }}</p>
{{- end }}
</div>
<div class="divide-y divide-gray-200 dark:divide-gray-800">
{{- range $pages }}
{{- $tagTitles := slice }}
{{- range .Params.tags }}{{ $tagTitles = $tagTitles | append (index hugo.Data.tags .).title }}{{ end }}
{{- $search := lower (printf "%s %s %s %s" .Title .Summary (delimit .Params.tags " ") (delimit $tagTitles " ")) }}
{{- $search = $search | replaceRE "\\s+" " " }}
<div
data-guide
data-search="{{ $search }}"
x-show="rowVisible($el)"
class="grid grid-cols-[5fr_6fr] items-start gap-6 py-4"
>
<a
href="{{ .Permalink }}"
class="font-medium leading-snug text-gray-900 hover:underline dark:text-gray-100"
>{{ .Title }}</a>
<span class="text-sm leading-relaxed text-gray-500 dark:text-gray-400">{{ .Summary }}</span>
</div>
{{- end }}
</div>
</section>
{{- end }}
{{- end }}
<!-- No matches -->
<div
x-show="filtering() && resultCount() === 0"
x-cloak
class="flex flex-col items-center justify-center gap-3 py-24 text-center"
>
<span class="icon-svg icon-lg text-gray-300 dark:text-gray-600">
{{ partialCached "icon" "magnifying-glass" "magnifying-glass" }}
</span>
<p class="text-gray-500 dark:text-gray-400">
No guides match “<span class="font-medium text-gray-700 dark:text-gray-200" x-text="query"></span>”.
</p>
<button
@click="clear()"
class="text-sm font-medium text-blue-600 transition hover:underline dark:text-blue-400"
>
Clear filter
</button>
</div>
</div>
</div>
</div>
{{ end }}
+14
View File
@@ -0,0 +1,14 @@
{{ define "left" }}
{{- partial "sidebar/mainnav.html" . }}
{{ end }}
{{ define "main" }}
<div class="mx-auto flex w-full max-w-7xl justify-center gap-12">
<article class="prose dark:prose-invert min-w-0 max-w-[92ch]">
{{ partial "content-default.html" . }}
</article>
<div class="-mt-8 hidden w-72 flex-none lg:block">
{{ partial "aside.html" . }}
</div>
</div>
{{ end }}
-1
View File
@@ -1 +0,0 @@
{{- template "alias.html" (dict "Permalink" .Params.target) -}}