site: rework guides filters and tags taxonomy

- Rework the filtering system for guides to drop the use of the
  "products", "subjects", and "levels" taxonomies in favor of "tags" and
  "languages"
- This change means that the existing taxonomy functionality integrates
  better with the guides filtering, and there are fewer parameters to
  keep in mind when adding metadata to a guide
  - Only two taxonomies instead of three
  - Only one of those taxonomies are guides-specific (languages)
  - The other taxonomy (tags) works for all content
- Updates how tags and tag pages are rendered in general

Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com>
This commit is contained in:
David Karlsson 2024-10-24 18:09:27 +02:00
parent 60bf7c8406
commit 56e58ae5bf
84 changed files with 329 additions and 318 deletions

View File

@ -1,6 +1,6 @@
--- ---
title: Guides title: Docker guides
keywords: Docker guides linkTitle: Guides
description: Explore the Docker guides description: Explore the Docker guides
params: params:
icon: developer_guide icon: developer_guide

View File

@ -3,9 +3,10 @@ title: Set up your company for success with Docker
linkTitle: Admin set up linkTitle: Admin set up
summary: Get the most out of Docker by streamlining workflows, standardizing development environments, and ensuring smooth deployments across your company. summary: Get the most out of Docker by streamlining workflows, standardizing development environments, and ensuring smooth deployments across your company.
description: Learn how to onboard your company and take advantage of all of the Docker products and features. description: Learn how to onboard your company and take advantage of all of the Docker products and features.
levels: [intermediate] tags: [admin]
params: params:
featured: true featured: true
time: 20 minutes
image: image:
resource_links: resource_links:
- title: Overview of Administration in Docker - title: Overview of Administration in Docker

View File

@ -5,9 +5,8 @@ description: >
Learn how to manage simple and complex build configurations with Buildx Bake. Learn how to manage simple and complex build configurations with Buildx Bake.
summary: > summary: >
Learn to automate Docker builds and testing with declarative configurations using Buildx Bake. Learn to automate Docker builds and testing with declarative configurations using Buildx Bake.
tags: [devops]
languages: [go] languages: [go]
subjects: [devops]
levels: [advanced]
params: params:
time: 30 minutes time: 30 minutes
featured: true featured: true

View File

@ -5,7 +5,6 @@ title: Bun language-specific guide
summary: | summary: |
Learn how to containerize JavaScript applications with the Bun runtime. Learn how to containerize JavaScript applications with the Bun runtime.
linkTitle: Bun linkTitle: Bun
levels: [beginner]
languages: [js] languages: [js]
params: params:
time: 10 minutes time: 10 minutes

View File

@ -5,7 +5,7 @@ summary: |
Containers don't have to be just for your app. Learn how to run your app's dependent services and other debugging tools to enhance your development environment. Containers don't have to be just for your app. Learn how to run your app's dependent services and other debugging tools to enhance your development environment.
description: | description: |
Use containers in your local development loop to develop and test faster… even if your main app isn't running in containers. Use containers in your local development loop to develop and test faster… even if your main app isn't running in containers.
levels: [beginner] tags: [app-dev]
params: params:
image: images/learning-paths/container-supported-development.png image: images/learning-paths/container-supported-development.png
time: 20 minutes time: 20 minutes

View File

@ -11,7 +11,6 @@ aliases:
- /language/cpp/ - /language/cpp/
- /guides/language/cpp/ - /guides/language/cpp/
languages: [cpp] languages: [cpp]
levels: [beginner]
params: params:
time: 10 minutes time: 10 minutes
--- ---

View File

@ -4,8 +4,7 @@ keywords: database, mysql
title: Use containerized databases title: Use containerized databases
summary: | summary: |
Learn how to effectively run and manage databases as containers. Learn how to effectively run and manage databases as containers.
levels: [beginner] tags: [databases]
subjects: [databases]
aliases: aliases:
- /guides/use-case/databases/ - /guides/use-case/databases/
params: params:

View File

@ -7,8 +7,7 @@ description: |
summary: | summary: |
Build applications up to 39x faster using cloud-based resources, shared team Build applications up to 39x faster using cloud-based resources, shared team
cache, and native multi-architecture support. cache, and native multi-architecture support.
levels: [beginner] tags: [product-demo]
products: [dbc]
aliases: aliases:
- /learning-paths/docker-build-cloud/ - /learning-paths/docker-build-cloud/
params: params:

View File

@ -5,8 +5,7 @@ summary: |
Simplify the process of defining, configuring, and running multi-container Simplify the process of defining, configuring, and running multi-container
Docker applications. Docker applications.
description: Learn how to use Docker Compose to define and run multi-container Docker applications. description: Learn how to use Docker Compose to define and run multi-container Docker applications.
levels: [beginner] tags: [product-demo]
products: [compose]
aliases: aliases:
- /learning-paths/docker-compose/ - /learning-paths/docker-compose/
params: params:

View File

@ -8,8 +8,7 @@ description: |
Learn how to use Docker Scout to enhance container security by automating Learn how to use Docker Scout to enhance container security by automating
vulnerability detection and remediation, ensuring compliance, and protecting vulnerability detection and remediation, ensuring compliance, and protecting
your development workflow. your development workflow.
levels: [Beginner] tags: [product-demo]
products: [scout]
aliases: aliases:
- /learning-paths/docker-scout/ - /learning-paths/docker-scout/
params: params:

View File

@ -9,7 +9,6 @@ aliases:
- /language/dotnet/ - /language/dotnet/
- /guides/language/dotnet/ - /guides/language/dotnet/
languages: [c-sharp] languages: [c-sharp]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
toc_min: 1 toc_min: 1

View File

@ -5,8 +5,7 @@ keywords: python, generative ai, genai, llm, neo4j, ollama, langchain
summary: | summary: |
Learn how to build a PDF bot for parsing PDF documents and generating Learn how to build a PDF bot for parsing PDF documents and generating
responses using Docker and generative AI. responses using Docker and generative AI.
levels: [beginner] tags: [ai]
subjects: [ai]
aliases: aliases:
- /guides/use-case/genai-pdf-bot/ - /guides/use-case/genai-pdf-bot/
params: params:

View File

@ -6,8 +6,7 @@ keywords: python, generative ai, genai, llm, whisper, pinecone, openai, whisper
summary: | summary: |
Learn how to build and deploy a generative AI video analysis and Learn how to build and deploy a generative AI video analysis and
transcription bot using Docker. transcription bot using Docker.
subjects: [ai] tags: [ai]
levels: [beginner]
aliases: aliases:
- /guides/use-case/genai-video-bot/ - /guides/use-case/genai-video-bot/
params: params:

View File

@ -11,7 +11,6 @@ aliases:
- /language/golang/ - /language/golang/
- /guides/language/golang/ - /guides/language/golang/
languages: [go] languages: [go]
levels: [beginner]
params: params:
time: 30 minutes time: 30 minutes
--- ---

View File

@ -11,7 +11,6 @@ aliases:
- /language/java/ - /language/java/
- /guides/language/java/ - /guides/language/java/
languages: [java] languages: [java]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -5,9 +5,8 @@ title: Data science with JupyterLab
toc_max: 2 toc_max: 2
summary: | summary: |
Use Docker to run Jupyter notebooks. Use Docker to run Jupyter notebooks.
tags: [data-science]
languages: [python] languages: [python]
levels: [beginner]
subjects: [data-science]
aliases: aliases:
- /guides/use-case/jupyter/ - /guides/use-case/jupyter/
params: params:

View File

@ -5,9 +5,8 @@ title: Developing event-driven applications with Kafka and Docker
linktitle: Event-driven apps with Kafka linktitle: Event-driven apps with Kafka
summary: | summary: |
This guide explains how to run Apache Kafka in Docker containers. This guide explains how to run Apache Kafka in Docker containers.
subjects: [distributed-systems] tags: [distributed-systems]
languages: [js] languages: [js]
levels: [intermediate]
aliases: aliases:
- /guides/use-case/kafka/ - /guides/use-case/kafka/
params: params:

View File

@ -7,8 +7,7 @@ aliases:
- /guides/deployment-orchestration/kube-deploy/ - /guides/deployment-orchestration/kube-deploy/
summary: | summary: |
Learn how to deploy and orchestrate Docker containers using Kubernetes. Learn how to deploy and orchestrate Docker containers using Kubernetes.
subjects: [deploy] tags: [deploy]
levels: [beginner]
params: params:
time: 10 minutes time: 10 minutes
--- ---

View File

@ -6,8 +6,7 @@ description: Learn how to build and run a language translation application using
summary: | summary: |
This guide demonstrates how to use Docker to deploy language translation This guide demonstrates how to use Docker to deploy language translation
models for NLP tasks. models for NLP tasks.
levels: [beginner] tags: [ai]
subjects: [ai]
languages: [python] languages: [python]
aliases: aliases:
- /guides/use-case/nlp/language-translation/ - /guides/use-case/nlp/language-translation/

View File

@ -6,9 +6,8 @@ linktitle: AWS development with LocalStack
summary: | summary: |
This guide explains how to use Docker to run LocalStack, a local AWS cloud This guide explains how to use Docker to run LocalStack, a local AWS cloud
stack emulator. stack emulator.
subjects: [cloud-services] tags: [cloud-services]
languages: [js] languages: [js]
levels: [intermediate]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -6,9 +6,8 @@ description: Learn how to build and run a named entity recognition application u
summary: | summary: |
This guide explains how to containerize named entity recognition (NER) models This guide explains how to containerize named entity recognition (NER) models
using Docker. using Docker.
subjects: [ai] tags: [ai]
languages: [python] languages: [python]
levels: [beginner]
aliases: aliases:
- /guides/use-case/nlp/named-entity-recognition/ - /guides/use-case/nlp/named-entity-recognition/
params: params:

View File

@ -11,7 +11,6 @@ aliases:
- /language/nodejs/ - /language/nodejs/
- /guides/language/nodejs/ - /guides/language/nodejs/
languages: [js] languages: [js]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -7,8 +7,7 @@ aliases:
- /guides/deployment-orchestration/orchestration/ - /guides/deployment-orchestration/orchestration/
summary: | summary: |
Explore the essentials of container orchestration with Docker. Explore the essentials of container orchestration with Docker.
subjects: [deploy] tags: [deploy]
levels: [beginner]
params: params:
time: 10 minutes time: 10 minutes
--- ---

View File

@ -11,7 +11,6 @@ aliases:
- /language/php/ - /language/php/
- /guides/language/php/ - /guides/language/php/
languages: [php] languages: [php]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -4,8 +4,7 @@ linktitle: Pre-seeding database
description: &desc Pre-seeding database with schema and data at startup for development environment description: &desc Pre-seeding database with schema and data at startup for development environment
keywords: Pre-seeding, database, postgres, container-supported development keywords: Pre-seeding, database, postgres, container-supported development
summary: *desc summary: *desc
levels: [intermediate] tags: [app-dev, databases]
subjects: [databases]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -11,7 +11,6 @@ aliases:
- /language/python/ - /language/python/
- /guides/language/python/ - /guides/language/python/
languages: [python] languages: [python]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -11,7 +11,6 @@ aliases:
- /languages/r/ - /languages/r/
- /guides/languages/r/ - /guides/languages/r/
languages: [r] languages: [r]
levels: [beginner]
params: params:
time: 10 minutes time: 10 minutes
--- ---

View File

@ -6,8 +6,7 @@ linkTitle: RAG Ollama application
summary: | summary: |
This guide demonstrates how to use Docker to deploy Retrieval-Augmented This guide demonstrates how to use Docker to deploy Retrieval-Augmented
Generation (RAG) models with Ollama. Generation (RAG) models with Ollama.
subjects: [ai] tags: [ai]
levels: [beginner]
aliases: aliases:
- /guides/use-case/rag-ollama/ - /guides/use-case/rag-ollama/
params: params:

View File

@ -12,7 +12,6 @@ aliases:
- /language/ruby/ - /language/ruby/
- /guides/language/ruby/ - /guides/language/ruby/
languages: [ruby] languages: [ruby]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -11,7 +11,6 @@ aliases:
- /language/rust/ - /language/rust/
- /guides/language/rust/ - /guides/language/rust/
languages: [rust] languages: [rust]
levels: [beginner]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -6,9 +6,8 @@ description: Learn how to build and run a sentiment analysis application using P
summary: | summary: |
This guide demonstrates how to containerize sentiment analysis models using This guide demonstrates how to containerize sentiment analysis models using
Docker. Docker.
subjects: [ai] tags: [ai]
languages: [python] languages: [python]
levels: [beginner]
aliases: aliases:
- /guides/use-case/nlp/sentiment-analysis/ - /guides/use-case/nlp/sentiment-analysis/
params: params:

View File

@ -8,8 +8,7 @@ aliases:
- /guides/deployment-orchestration/swarm-deploy/ - /guides/deployment-orchestration/swarm-deploy/
summary: | summary: |
Discover how to deploy and manage Docker containers using Docker Swarm. Discover how to deploy and manage Docker containers using Docker Swarm.
subjects: [deploy] tags: [deploy]
levels: [beginner]
params: params:
time: 10 minutes time: 10 minutes
--- ---

View File

@ -4,9 +4,8 @@ keywords: tensorflow.js, machine learning, ml, mediapipe, blazeface, face detect
title: Face detection with TensorFlow.js title: Face detection with TensorFlow.js
summary: | summary: |
This guide explains how to run TensorFlow.js in Docker containers. This guide explains how to run TensorFlow.js in Docker containers.
subjects: [ai] tags: [ai]
languages: [js] languages: [js]
levels: [beginner]
aliases: aliases:
- /guides/use-case/tensorflowjs/ - /guides/use-case/tensorflowjs/
params: params:

View File

@ -6,8 +6,7 @@ summary: |
Automate, scale, and optimize testing workflows with Testcontainers Cloud Automate, scale, and optimize testing workflows with Testcontainers Cloud
description: | description: |
Testcontainers Cloud by Docker streamlines integration testing by offloading container management to the cloud. It enables faster, consistent tests for containerized services like databases, improving performance and scalability in CI/CD pipelines without straining local or CI resources. Ideal for developers needing efficient, reliable testing environments. Testcontainers Cloud by Docker streamlines integration testing by offloading container management to the cloud. It enables faster, consistent tests for containerized services like databases, improving performance and scalability in CI/CD pipelines without straining local or CI resources. Ideal for developers needing efficient, reliable testing environments.
levels: [Beginner] tags: [product-demo]
products: [testcontainers]
params: params:
featured: true featured: true
image: images/learning-paths/testcontainers-cloud-learning-path.png image: images/learning-paths/testcontainers-cloud-learning-path.png

View File

@ -6,9 +6,8 @@ description: Learn how to build and run a text recognition application using Pyt
summary: | summary: |
This guide details how to containerize text classification models using This guide details how to containerize text classification models using
Docker. Docker.
subjects: [ai] tags: [ai]
languages: [python] languages: [python]
levels: [beginner]
aliases: aliases:
- /guides/use-case/nlp/text-classification/ - /guides/use-case/nlp/text-classification/
params: params:

View File

@ -5,9 +5,8 @@ keywords: nlp, natural language processing, text summarization, python, bert ext
description: Learn how to build and run a text summarization application using Python, Bert Extractive Summarizer, and Docker. description: Learn how to build and run a text summarization application using Python, Bert Extractive Summarizer, and Docker.
summary: | summary: |
This guide shows how to containerize text summarization models with Docker. This guide shows how to containerize text summarization models with Docker.
subjects: [ai] tags: [ai]
languages: [python] languages: [python]
levels: [beginner]
aliases: aliases:
- /guides/use-case/nlp/text-summarization/ - /guides/use-case/nlp/text-summarization/
params: params:

View File

@ -4,8 +4,7 @@ description: &desc Use Traefik to easily route traffic between multiple containe
keywords: traefik, container-supported development keywords: traefik, container-supported development
linktitle: HTTP routing with Traefik linktitle: HTTP routing with Traefik
summary: *desc summary: *desc
levels: [intermediate] tags: [networking]
subjects: [networking]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -4,8 +4,8 @@ description: &desc Mocking API services in development and testing with WireMock
keywords: WireMock, container-supported development keywords: WireMock, container-supported development
linktitle: Mocking API services with WireMock linktitle: Mocking API services with WireMock
summary: *desc summary: *desc
levels: [intermediate] tags: [app-dev, distributed-systems]
subjects: [distributed-systems] languages: [js]
params: params:
time: 20 minutes time: 20 minutes
--- ---

View File

@ -3,3 +3,4 @@ cascade:
build: build:
render: never render: never
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: C# title: C#
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/csharp/csharp-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: C++ title: C++
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cplusplus/cplusplus-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: Go title: Go
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/go/go-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: Java title: Java
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/java/java-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: JavaScript title: JavaScript
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: PHP title: PHP
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/php/php-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: Python title: Python
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: R title: R
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/r/r-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: Ruby title: Ruby
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/ruby/ruby-original.svg
--- ---

View File

@ -1,3 +1,5 @@
--- ---
title: Rust title: Rust
params:
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/rust/rust-original.svg
--- ---

View File

@ -1,5 +0,0 @@
---
cascade:
build:
render: never
---

View File

@ -1,5 +0,0 @@
---
cascade:
build:
render: never
---

View File

@ -1,3 +0,0 @@
---
title: Docker Compose
---

View File

@ -1,3 +0,0 @@
---
title: Docker Build Cloud
---

View File

@ -1,3 +0,0 @@
---
title: Docker Scout
---

View File

@ -1,5 +0,0 @@
---
cascade:
build:
render: never
---

View File

@ -0,0 +1,3 @@
---
title: Administration
---

View File

@ -0,0 +1,3 @@
---
title: App development
---

View File

@ -1,6 +1,5 @@
--- ---
title: Best practices title: Best practices
icon: star
description: Optimal patterns for Docker description: Optimal patterns for Docker
--- ---

View File

@ -1,6 +1,5 @@
--- ---
title: FAQ title: FAQ
icon: quiz
description: Frequently asked questions description: Frequently asked questions
--- ---

View File

@ -0,0 +1,3 @@
---
title: Product demo
---

View File

@ -1,6 +1,5 @@
--- ---
title: Secrets title: Secrets
icon: password
description: Use sensitive information in containers securely description: Use sensitive information in containers securely
--- ---

View File

@ -1,6 +1,5 @@
--- ---
title: Troubleshooting title: Troubleshooting
icon: troubleshoot
description: Fix common issues description: Fix common issues
--- ---

View File

@ -9,11 +9,7 @@ ignoreLogs:
taxonomies: taxonomies:
tag: tags tag: tags
# filters for guides:
language: languages language: languages
subject: subjects
level: levels
product: products
permalinks: permalinks:
page: page:

View File

@ -41,6 +41,7 @@
"Docker-Compose", "Docker-Compose",
"Docker-Desktop", "Docker-Desktop",
"Docker-Hub", "Docker-Hub",
"Docker-Scout-Dashboard",
"Download", "Download",
"Editor-or-IDE", "Editor-or-IDE",
"Entra-ID", "Entra-ID",
@ -86,6 +87,7 @@
"Node", "Node",
"Non-compliant", "Non-compliant",
"Okta", "Okta",
"Okta-SAML",
"Old-Dockerfile", "Old-Dockerfile",
"PHP", "PHP",
"PowerShell", "PowerShell",
@ -192,7 +194,6 @@
"chroma", "chroma",
"col-start-2", "col-start-2",
"containerd-image-store", "containerd-image-store",
"cursor-not-allowed",
"cursor-pointer", "cursor-pointer",
"dark:bg-amber-dark", "dark:bg-amber-dark",
"dark:bg-amber-dark-200", "dark:bg-amber-dark-200",
@ -231,8 +232,8 @@
"dark:hover:bg-gray-dark-200", "dark:hover:bg-gray-dark-200",
"dark:hover:bg-gray-dark-500", "dark:hover:bg-gray-dark-500",
"dark:hover:text-blue-dark", "dark:hover:text-blue-dark",
"dark:hover:text-white",
"dark:prose-invert", "dark:prose-invert",
"dark:ring-blue-dark-400",
"dark:ring-gray-dark-400", "dark:ring-gray-dark-400",
"dark:syntax-dark", "dark:syntax-dark",
"dark:text-amber-dark", "dark:text-amber-dark",
@ -292,7 +293,6 @@
"grid-cols-1", "grid-cols-1",
"group", "group",
"group-hover:block'", "group-hover:block'",
"group-hover:underline",
"h-16", "h-16",
"h-2", "h-2",
"h-32", "h-32",
@ -311,7 +311,6 @@
"hover:bg-gray-light-100", "hover:bg-gray-light-100",
"hover:bg-gray-light-200", "hover:bg-gray-light-200",
"hover:bg-gray-light-300", "hover:bg-gray-light-300",
"hover:bg-white",
"hover:bg-white/20", "hover:bg-white/20",
"hover:border-gray-light-200", "hover:border-gray-light-200",
"hover:border-white/20", "hover:border-white/20",
@ -321,7 +320,6 @@
"hover:dark:text-blue-dark", "hover:dark:text-blue-dark",
"hover:drop-shadow-lg", "hover:drop-shadow-lg",
"hover:opacity-90", "hover:opacity-90",
"hover:text-black",
"hover:text-blue-light", "hover:text-blue-light",
"hover:text-white", "hover:text-white",
"hover:underline", "hover:underline",
@ -329,6 +327,7 @@
"icon-sm", "icon-sm",
"icon-svg", "icon-svg",
"inline", "inline",
"inline-flex",
"inset-0", "inset-0",
"invertible", "invertible",
"italic", "italic",
@ -352,7 +351,6 @@
"lg:no-underline", "lg:no-underline",
"lg:pb-2", "lg:pb-2",
"lg:scale-100", "lg:scale-100",
"lg:text-base",
"link", "link",
"lntable", "lntable",
"lntd", "lntd",
@ -368,6 +366,7 @@
"max-w-full", "max-w-full",
"max-w-none", "max-w-none",
"max-w-xl", "max-w-xl",
"mb-1",
"mb-2", "mb-2",
"mb-4", "mb-4",
"mb-8", "mb-8",
@ -399,7 +398,6 @@
"mt-4", "mt-4",
"mx-auto", "mx-auto",
"my-0", "my-0",
"my-2",
"my-4", "my-4",
"my-6", "my-6",
"no-underline", "no-underline",
@ -427,6 +425,7 @@
"pb-1", "pb-1",
"pb-2", "pb-2",
"pb-4", "pb-4",
"pb-8",
"pl-1", "pl-1",
"pl-2", "pl-2",
"pl-3", "pl-3",
@ -440,7 +439,6 @@
"pt-4", "pt-4",
"px-1", "px-1",
"px-2", "px-2",
"px-3",
"px-4", "px-4",
"px-6", "px-6",
"py-1", "py-1",
@ -452,7 +450,9 @@
"right-0", "right-0",
"right-3", "right-3",
"right-8", "right-8",
"ring-2",
"ring-[1.5px]", "ring-[1.5px]",
"ring-blue-light-400",
"ring-gray-light-200", "ring-gray-light-200",
"rotate-45", "rotate-45",
"rounded", "rounded",
@ -519,9 +519,7 @@
"top-full", "top-full",
"transition", "transition",
"truncate", "truncate",
"underline",
"underline-offset-2", "underline-offset-2",
"underline-offset-8",
"w-2", "w-2",
"w-8", "w-8",
"w-[1200px]", "w-[1200px]",

View File

@ -1,165 +1,221 @@
{{ define "left" }} {{ define "left" }}
{{ partial "sidebar/mainnav.html" . }} {{- partial "sidebar/mainnav.html" . }}
<div class="p-4 flex flex-col gap-4 text-sm"> <div class="p-4 flex flex-col gap-2 text-sm">
<div> <p>Filter guides by tag or programming language.<p>
<span class="icon-svg">{{ partialCached "icon" "filter_alt" "filter_alt" }}</span> <div class="space-y-4" x-data="{
<span>Filters</span> filters: { tags: [], languages: [] },
</div> toggleFilter(grp, tag) {
<div class="space-y-4" this.filters[grp].includes(tag)
x-data="{ ? this.filters[grp] = this.filters[grp].filter(el => el != tag)
selected: { products: [], subjects: [], languages: [], levels: [], }, : this.filters[grp].push(tag);
toggleFilter(taxonomy, term) {
this.selected[taxonomy].includes(term)
? this.selected[taxonomy] = this.selected[taxonomy].filter(el => el != term)
: this.selected[taxonomy].push(term);
// Update URL // Update URL
const url = new URL(window.location.href); const url = new URL(window.location.href);
if (this.selected[taxonomy].length > 0) { if (this.filters[grp].length > 0) {
url.searchParams.set(taxonomy, this.selected[taxonomy].join('~')); url.searchParams.set(grp, this.filters[grp].join('~'));
} else { } else {
url.searchParams.delete(taxonomy); url.searchParams.delete(grp);
} }
window.history.replaceState({}, '', url); window.history.replaceState({}, '', url);
this.$dispatch('guide-filter', { filters: this.selected }); this.$dispatch('guide-filter', { filters: this.filters });
}, },
init() { init() {
const url = new URL(window.location.href); const url = new URL(window.location.href);
for (const [key, value] of url.searchParams.entries()) { const tags = url.searchParams.get('tags')
if (value) { const langs = url.searchParams.get('languages')
this.selected[key] = value.split('~'); if (tags != null) {
} this.filters['tags'] = tags.split('~');
}
if (langs != null) {
this.filters['languages'] = langs.split('~');
} }
} }
}"> }" @guide-filter.window="filters = $event.detail.filters;">
{{ template "taxofilters" site.Taxonomies.products }} <div class="pl-2"><strong>Tags</strong></div>
{{ template "taxofilters" site.Taxonomies.subjects }} <fieldset class="flex flex-col gap-2">
{{ template "taxofilters" site.Taxonomies.levels }} {{- range $name, $taxonomy := where site.Taxonomies.tags ".Page.Type" "guides" }}
{{ template "taxofilters" site.Taxonomies.languages }} {{- $id := anchorize (fmt.Printf "tag-%s" $name) }}
<div class="pl-2 flex gap-2">
<input value="{{ $name }}" type="checkbox" id="{{ $id }}" @change="toggleFilter('tags', '{{ $name }}')"
:checked="filters['tags'].includes('{{ $name }}')">
<label class="select-none" for="{{ $id }}">{{ .Page.LinkTitle }}</label>
</div>
{{ end }}
</fieldset>
<div class="pl-2"><strong>Languages</strong></div>
<fieldset class="pl-2 flex flex-wrap gap-2">
{{- range $name, $taxonomy := where site.Taxonomies.languages ".Page.Type" "guides" }}
{{- $id := anchorize (fmt.Printf "lang-%s" $name) }}
<button
class="px-2 py-1 rounded-full flex gap-1 bg-white dark:bg-gray-dark-300 border border-divider-light dark:border-divider-dark"
:class="{ 'ring-2 ring-blue-light-400 dark:ring-blue-dark-400': filters['languages'].includes('{{ $name }}') }"
@click="toggleFilter('languages', '{{ $name }}')">
<img height="18" width="18" title="{{ .Page.LinkTitle }}" src="{{ .Page.Params.icon }}">
<span>{{ .Page.LinkTitle }}</span>
</button>
{{ end }}
</fieldset>
</div> </div>
</div> </div>
{{ end }} {{ end }}
{{ define "taxofilters" }}
{{- $taxonomy := .Page.Data.Plural }}
<fieldset class="flex flex-col gap-2">
<div>{{ humanize $taxonomy }}</div>
{{- range . }}
{{- $term := .Page.Data.Term }}
<div class="pl-2 flex gap-2">
{{- $id := anchorize (fmt.Printf "%s-%s" $taxonomy $term) }}
<input value="{{$term}}" type="checkbox" id="{{ $id }}"
@change="toggleFilter('{{$taxonomy}}','{{$term}}')"
:checked="selected['{{$taxonomy}}'].includes('{{$term}}')">
<label class="select-none" for="{{ $id }}">{{ .Page.LinkTitle }}</label>
</div>
{{ end }}
</fieldset>
{{ end }}
{{ define "main" }} {{ define "main" }}
<div class="flex gap-8 w-full"> <div class="flex gap-8 w-full">
<article class="prose min-w-0 max-w-none dark:prose-invert"> <article class="prose min-w-0 max-w-none dark:prose-invert">
{{- partial "breadcrumbs.html" . }} {{- partial "breadcrumbs.html" . }}
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1> <h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1>
{{ .Content }} {{ .Content }}
<h2>Featured</h2> <div class="not-prose min-h-screen" x-data="{
<div class="not-prose py-4 grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8"> filters: { tags: [], languages: [] },
{{- $featured := where .Pages "Params.featured" true }} hidden: [],
{{- with $featured }} total: {{ len .Pages }},
{{- range . }}
<div class="flex flex-col h-full">
<a class="hover:underline" href="{{ .Permalink }}">
{{- $img := resources.Get (.Params.image | default "/images/thumbnail.webp") }}
{{- $img = $img.Process "resize 600x" }}
<img class="h-48 w-full object-cover rounded shadow" src="{{ $img.Permalink }}">
<p class="text-xl leading-snug my-4">{{ .Title }}</p>
</a>
<p class="flex-grow text-sm">{{ .Summary }}</p>
<div class="mt-4">
{{ template "guide-metadata" . }}
</div>
</div>
{{- end }}
{{- end }}
</div>
</ul>
<hr class="text-divider-light dark:text-divider-dark">
{{- $taxonomies := slice "products" "subjects" "levels" "languages" }}
<div class="not-prose min-h-screen"
x-data="{
filters: { {{ delimit (apply $taxonomies "fmt.Printf" "%s: []," "." ) "" }} },
noFilters() { noFilters() {
return Object.values(this.filters).every(arr=> Array.isArray(arr) && arr.length === 0); return Object.values(this.filters).every(arr=> Array.isArray(arr) && arr.length === 0);
}, },
showItem(taxonomies) { isVisible(el) {
if (this.noFilters()) return true; return !this.hidden.includes(el.id);
let match = false; },
for (const taxonomy in this.filters) { updateVisible() {
const selectedTerms = this.filters[taxonomy]; const hiddenSet = new Set();
if (selectedTerms.length > 0) { // show if no filters have been selected
const itemTerms = taxonomies[taxonomy] || []; if (this.noFilters()) return;
// Check if all selected terms are included in the item's terms const guideContainer = this.$refs['guide-container'];
const hasAnyTerms = selectedTerms.some(term => itemTerms.includes(term)); const guides = guideContainer.children
if (hasAnyTerms) {
match = true; // Loop over the filters object
break; 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)
} }
} }
} }
return match;
this.hidden = Array.from(hiddenSet)
}, },
init() { init() {
const url = new URL(window.location.href); const url = new URL(window.location.href);
for (const [key, value] of url.searchParams.entries()) { const tags = url.searchParams.get('tags')
if (value) { const langs = url.searchParams.get('languages')
this.filters[key] = value.split('~'); if (tags != null) {
} this.filters['tags'] = tags.split('~');
} }
if (langs != null) {
this.filters['languages'] = langs.split('~');
}
this.updateVisible();
} }
}" }" x-cloak
x-cloak @guide-filter.window="filters = $event.detail.filters; updateVisible(); $nextTick(() => { window.scrollTo({ top: 0 }) })">
@guide-filter.window="filters = $event.detail.filters; document.getElementById('all-guides').scrollIntoView({ behavior: 'smooth' })"> <div x-show="noFilters()">
<h2 id="all-guides" class="scroll-mt-36">All guides</h2> <h2>Featured guides</h2>
{{- range .Pages }} <div class="not-prose py-4 grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
{{- $opts := dict "page" . "taxonomies" $taxonomies }} {{- $featured := where .Pages "Params.featured" true }}
{{- $filters := partial "utils/filter-terms.html" $opts }} {{- with $featured }}
<a href="{{ .Permalink }}" x-show="showItem({{ jsonify $filters }});" x-transition {{- range . }}
class="group flex flex-col justify-between p-4 border-b <div class="flex flex-col h-full">
border-divider-light hover:bg-white <a class="hover:underline" href="{{ .Permalink }}">
hover:dark:bg-gray-dark-200 dark:border-divider-dark {{- $img := resources.Get (.Params.image | default "/images/thumbnail.webp") }}
drop-shadow transition"> {{- $img = $img.Process "resize 600x" }}
<div class="flex flex-col xl:flex-row justify-between"> <img class="h-48 w-full object-cover rounded shadow" src="{{ $img.Permalink }}">
<div class="text-lg group-hover:underline mb-2 xl:mb-0 truncate">{{ .Title }}</div> <p class="text-xl leading-snug my-4">{{ .Title }}</p>
{{ template "guide-metadata" . }} </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="pb-8 flex flex-col gap-2">
<div class="flex gap-2 items-center">
<span class="mb-1 icon-svg icon-sm">{{ partialCached "icon" "filter_alt" "filter_alt" }}</span>
<p>Filtered results: showing <span x-text="total - hidden.length"></span> out of <span x-text="total"></span> guides.</p>
</div>
<div class="pl-4 flex gap-2 items-center">
{{- range $name, $taxonomy := site.Taxonomies.tags }}
<div x-show="filters.tags.includes('{{$name}}')">{{ template "termchip" $taxonomy.Page.LinkTitle }}</div>
{{- end }}
{{- range $name, $taxonomy := site.Taxonomies.languages }}
<div x-show="filters.languages.includes('{{$name}}')"
class="text-sm inline-flex gap-1 items-center rounded-full border
border-divider-light dark:border-divider-dark bg-gray-light-100
px-2 text-gray-light-800 dark:bg-gray-dark-200
dark:text-gray-dark-800 select-none">
<img class="py-1" height="18" width="18" title="{{ .Page.LinkTitle }}" src="{{ .Page.Params.icon }}">
<span>{{ .Page.LinkTitle }}</span>
</div> </div>
</a> {{- end }}
{{- 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="flex flex-col justify-between p-4 border-b border-divider-light
hover:bg-gray-light-100 hover:dark:bg-gray-dark-200
dark:border-divider-dark">
<div class="flex flex-col xl:flex-row justify-between">
<a href="{{ .Permalink }}" class="text-lg hover:underline mb-2 xl:mb-0 truncate">{{ .Title }}</a>
{{ template "guide-metadata" . }}
</div>
</div>
{{- end }}
</div>
</div>
</article> </article>
</div> </div>
{{ end }} {{ end }}
{{- define "guide-metadata" }} {{- define "guide-metadata" }}
<div class="flex gap-8 items-center text-sm justify-between text-gray-light dark:text-gray-dark"> <div class="text-sm flex gap-8 items-center justify-between text-gray-light dark:text-gray-dark">
<div class="flex flex-wrap md:flex-nowrap gap-2"> <div class="flex flex-wrap md:flex-nowrap gap-2">
{{- $taxoterms := .GetTerms "languages" }} {{- $langs := .GetTerms "languages" }}
{{- $taxoterms = $taxoterms | append (.GetTerms "levels") }} {{ partial "languages" $langs }}
{{- $taxoterms = $taxoterms | append (.GetTerms "subjects") }} {{- $tags := .GetTerms "tags" }}
{{- range $taxoterms }} {{- range $tags }}
<span class="rounded whitespace-nowrap bg-gray-light-200 dark:bg-gray-dark-300 px-2">{{- .Page.LinkTitle }}</span> {{ template "termchip" .Page.LinkTitle }}
{{- end }} {{- end }}
</div> </div>
{{- with .Params.time }} {{- with .Params.time }}
<div class="flex whitespace-nowrap flex-shrink gap-2"> <div class="flex whitespace-nowrap flex-shrink gap-2">
<span class="icon-svg">{{ partialCached "icon" "schedule" "schedule" }}</span> <span class="icon-svg">{{ partialCached "icon" "schedule" "schedule" }}</span>
<span>{{ . }}</span> <span>{{ . }}</span>
</div> </div>
{{- end }} {{- end }}
</div> </div>
{{- end }} {{- end }}
{{- define "termchip" }}
<span class="whitespace-nowrap inline-flex text-sm min-w-0 items-center rounded-full
border border-divider-light dark:border-divider-dark
bg-gray-light-100 px-2 text-gray-light-800 dark:bg-gray-dark-200
dark:text-gray-dark-800 select-none">
<span class="icon-svg icon-sm pb-0.5">
{{ partialCached "icon" "tag" "tag" }}
</span>
{{ . }}
</span>
{{- end }}

View File

@ -2,6 +2,13 @@
<article class="prose min-w-0 flex-[2_2_0%] max-w-4xl dark:prose-invert"> <article class="prose min-w-0 flex-[2_2_0%] max-w-4xl dark:prose-invert">
{{ partial "breadcrumbs.html" . }} {{ partial "breadcrumbs.html" . }}
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1> <h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1>
{{- if ne .Type "guides" }}
{{ with .GetTerms "tags" }}
<div class="not-prose">
{{- partial "tags.html" . }}
</div>
{{- end }}
{{- end }}
<div class="block lg:hidden"> <div class="block lg:hidden">
{{ partialCached "pagemeta.html" . . }} {{ partialCached "pagemeta.html" . . }}
<hr /> <hr />

View File

@ -1,8 +1,8 @@
{{- $svg := resources.Get (fmt.Printf "icons/%s-fill.svg" .) }} {{- $svg := resources.Get (fmt.Printf "icons/%s-fill.svg" .) }}
{{- if not $svg }} {{- if not $svg }}
{{- errorf "Failed to get icon: %s" . }} {{- errorf "Failed to get icon: %v\n\n" . }}
{{ end }} {{ end }}
{{- if not $svg.Content }} {{- if not $svg.Content }}
{{- errorf "Failed to get icon: %s" . }} {{- errorf "Failed to get icon: %v\n\n" . }}
{{- end }} {{- end }}
{{- safe.HTML $svg.Content -}} {{- safe.HTML $svg.Content -}}

View File

@ -0,0 +1,21 @@
{{- /*
List of languages (taxonomy) chips with images
Context: page.Pages
*/
-}}
{{- range . -}}
{{- if eq .File nil }}
{{- errorf "[languages] Undefined language: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }}
{{- end }}
{{- if not .Page.Params.icon }}
{{- errorf "[languages] language is missing an icon: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }}
{{- end }}
<span class="text-sm inline-flex gap-1 items-center rounded-full border
border-divider-light dark:border-divider-dark bg-gray-light-100
px-2 text-gray-light-800 dark:bg-gray-dark-200
dark:text-gray-dark-800 select-none">
<img class="py-1" height="18" width="18" title="{{ .Page.LinkTitle }}" src="{{ .Page.Params.icon }}">
<span>{{ .Page.LinkTitle }}</span>
</span>
{{- end -}}

View File

@ -2,24 +2,13 @@
{{- with .Fragments }} {{- with .Fragments }}
{{- $toc = and (ne page.Params.notoc true) .Headings }} {{- $toc = and (ne page.Params.notoc true) .Headings }}
{{- end }} {{- end }}
{{- $tags := .GetTerms "tags" }} {{- with $toc }}
{{- if or $toc $tags }}
<div data-pagefind-ignore class="not-prose"> <div data-pagefind-ignore class="not-prose">
{{- with $tags }} <div class="text-lg pb-0 lg:pb-2">{{ T "tableOfContents" }}</div>
<div class="flex flex-col gap-2 my-2"> <nav class="toc">
<span class="text-lg">Tags</span> {{ $root := (index page.Fragments.Headings 0).Headings }}
<div class="flex flex-wrap items-center gap-2"> {{- template "walkHeadingFragments" $root }}
{{- partial "tags.html" . -}} </nav>
</div>
</div>
{{- end }}
{{- with $toc }}
<div class="text-lg pb-0 lg:pb-2">{{ T "tableOfContents" }}</div>
<nav class="toc">
{{ $root := (index page.Fragments.Headings 0).Headings }}
{{- template "walkHeadingFragments" $root }}
</nav>
{{- end }}
</div> </div>
{{- end }} {{- end }}

View File

@ -9,18 +9,15 @@
<a href="{{ $root.Permalink }}">{{ $root.Title }}</a> <a href="{{ $root.Permalink }}">{{ $root.Title }}</a>
</div> </div>
<div>{{ $root.Summary }}</div> <div>{{ $root.Summary }}</div>
<div class="space-y-2"> <div class="space-y-4">
{{- with ($root.GetTerms "levels") }} <div class="flex flex-wrap gap-2">
<div class="flex gap-2 text-gray-light dark:text-gray-dark"> {{- with ($root.GetTerms "languages") }}
<span class="icon-svg">{{ partialCached "icon" "school" "school" }}</span> {{ partial "languages.html" . }}
<span> {{- end }}
{{- range $i, $e := . -}} {{- with ($root.GetTerms "tags") }}
{{- if $i -}},{{ end -}} {{ partial "tags.html" . }}
{{- .Page.Title -}} {{- end }}
{{- end -}} </div>
</span>
</div>
{{- end -}}
{{- with ($root.Params.time) }} {{- with ($root.Params.time) }}
<div class="flex gap-2 text-gray-light dark:text-gray-dark"> <div class="flex gap-2 text-gray-light dark:text-gray-dark">
<span class="icon-svg" <span class="icon-svg"

View File

@ -1,10 +1,13 @@
<!-- Main navigation for the sidebar --> <!-- Main navigation for the sidebar -->
<div class="py-2 px-4" x-data="{ expanded: false }"> <div class="py-2 px-4" x-data="{ expanded: false }">
<div class="flex w-full items-center justify-between"> <div class="flex w-full items-center justify-between">
<!-- Current section: use menu, fall back to current page --> <!-- Current section: use menu, fall back to current section or page -->
{{- $curr := page }} {{- $curr := .FirstSection }}
{{- if eq $curr site.Home }}
{{- $curr = . }}
{{- end }}
{{- range site.Menus.main }} {{- range site.Menus.main }}
{{- if .Page.IsAncestor page }} {{- if or (.Page.IsAncestor page) (eq .Page page) }}
{{- $curr = .Page }} {{- $curr = .Page }}
{{- end }} {{- end }}
{{- end }} {{- end }}

View File

@ -1,11 +1,10 @@
<ul> <ul class="md:text-sm">
{{- range site.Taxonomies.tags }} {{- range site.Taxonomies.tags }}
<li class="pl-4 hover:text-blue-light hover:dark:text-blue-dark <li class="pl-4 hover:text-blue-light hover:dark:text-blue-dark
{{ if eq .Page page }} bg-gray-light-200 dark:bg-gray-dark-200{{ end }}"> {{ if eq .Page page }} bg-gray-light-200 dark:bg-gray-dark-200{{ end }}">
<a class="py-2 w-full truncate block" <a class="py-2 w-full truncate block"
href="{{ .Page.Permalink }}" href="{{ .Page.Permalink }}"
title="{{ .Page.LinkTitle }}"> title="{{ .Page.LinkTitle }}">
<span class="icon-svg">{{- partialCached "icon.html" .Page.Params.icon .Page.Params.icon -}}</span>
{{ .Page.LinkTitle }} {{ .Page.LinkTitle }}
</a> </a>
</li> </li>

View File

@ -1,13 +1,20 @@
{{- /* {{- /*
List of tag "chips" as links List of tag "chips" as links
Context: page.Pages Context: page.Pages
*/ -}} */
-}}
{{- range . -}} {{- range . -}}
{{- if eq .File nil }} {{- if eq .File nil }}
{{- errorf "[tags] Undefined tag: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }} {{- errorf "[tags] Undefined tag: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }}
{{- end }} {{- end }}
<a class="flex items-center gap-2 lg:text-base px-2 rounded text-gray-light-800 bg-gray-light-200 dark:bg-gray-dark-300 dark:text-gray-dark-800" href="{{ .Permalink }}"> <a class="text-sm inline-flex items-center rounded-full border
<div class="icon-svg icon-sm pb-0.5">{{ partialCached "icon" .Params.icon .Params.icon }}</div> border-divider-light dark:border-divider-dark bg-gray-light-100 px-2
<div>{{ .LinkTitle }}</div> text-gray-light-800 dark:bg-gray-dark-200 dark:text-gray-dark-800
select-none"
href="{{ .Permalink }}">
<span class="icon-svg icon-sm pb-0.5">
{{ partialCached "icon" "tag" "tag" }}
</span>
<span>{{ .LinkTitle }}</span>
</a> </a>
{{- end -}} {{- end -}}

View File

@ -1,11 +0,0 @@
{{- $currentPage := .page }}
{{- $taxonomies := .taxonomies }}
{{- $scratch := collections.NewScratch }}
{{- range $taxo := $taxonomies }}
{{- $terms := slice }}
{{- range ($currentPage.GetTerms $taxo) }}
{{- $terms = $terms | append .Page.Data.Term }}
{{- end }}
{{ $scratch.SetInMap "filters" $taxo $terms }}
{{- end }}
{{- return ($scratch.Get "filters") }}

View File

@ -6,19 +6,18 @@
{{ define "main" }} {{ define "main" }}
<article class="prose max-w-none dark:prose-invert"> <article class="prose max-w-none dark:prose-invert">
{{ partial "breadcrumbs.html" . }} {{ partial "breadcrumbs.html" . }}
<h1 class="scroll-mt-36">{{ .Title }}</h1> <h1 class="scroll-mt-36 flex items-center">
<span class="icon-svg icon-lg pb-2">{{ partialCached "icon" "tag" "tag" }}</span>
<span>{{ .Title }}</span>
</h1>
{{ .Content }} {{ .Content }}
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3"> <ul>
{{ range site.Taxonomies.tags }} {{ range site.Taxonomies.tags }}
{{ partial "components/card.html" <li>
(dict <a href="{{ .Page.Permalink }}">{{ .Page.Title }}</a>
"link" .Page.Permalink ({{ (len .Pages) }} {{ cond (gt (len .Pages) 1) "pages" "page" }})
"title" .Page.Title </li>
"description" .Page.Description
"icon" .Page.Params.icon
)
}}
{{ end }} {{ end }}
</div> </ul>
</article> </article>
{{ end }} {{ end }}

View File

@ -1,44 +1,25 @@
{{ define "left" }} {{ define "left" }}
{{ partial "sidebar/mainnav.html" . }}
{{ partial "sidebar/tags.html" . }} {{ partial "sidebar/tags.html" . }}
{{ end }} {{ end }}
{{ define "main" }} {{ define "main" }}
<article class="prose max-w-none dark:prose-invert"> <article class="prose max-w-none dark:prose-invert">
{{ partial "breadcrumbs.html" . }} {{ partial "breadcrumbs.html" . }}
<h1 class="scroll-mt-36 flex gap-4 items-center"> <h1 class="scroll-mt-36 flex items-center">
<span class="bg-gray-light-200 dark:bg-gray-dark-300 rounded-full px-3 icon-svg icon-lg pb-2">{{ partialCached "icon" .Params.icon .Params.icon }}</span> <span class="icon-svg icon-lg pb-2">{{ partialCached "icon" "tag" "tag" }}</span>
</span>{{ .Title }}</span> </span>{{ .Title }}</span>
</h1> </h1>
{{ .Content }} {{ .Content }}
<div class="not-prose flex justify-between items-center"> {{- range .Pages.GroupBy "Type" }}
<span class="text-gray-light dark:text-gray-dark">Pages with this tag:</span> <h2>{{ (site.GetPage .Key).LinkTitle }}</h2>
{{ partial "pagination.html" . }} <ul>
</div> {{ range .Pages }}
<table style="display: table"> <li>
<thead> <a href="{{ .Permalink }}">{{ .Title }}</a>
<tr> </li>
<th width="50%">Title</th> {{- end }}
<th width="50%">Section</th> </ul>
</tr> {{- end }}
</thead>
<tbody>
{{ range .Paginator.Pages }}
<tr>
<td>
<a href="{{ .Permalink }}" class="link">
{{ .Title }}
</a>
</td>
<td>
<span class="text-gray-light dark:text-gray-dark">
{{- range .Ancestors.Reverse }}
{{ .Title }} /
{{- end }}
</span>
</td>
</tr>
{{ end }}
</tbody>
</table>
</article> </article>
{{ end }} {{ end }}