зеркало из https://github.com/docker/docs.git
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:
Родитель
60bf7c8406
Коммит
56e58ae5bf
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
title: Guides
|
||||
keywords: Docker guides
|
||||
title: Docker guides
|
||||
linkTitle: Guides
|
||||
description: Explore the Docker guides
|
||||
params:
|
||||
icon: developer_guide
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
title: Set up your company for success with Docker
|
||||
linkTitle: Admin set up
|
||||
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.
|
||||
levels: [intermediate]
|
||||
description: Learn how to onboard your company and take advantage of all of the Docker products and features.
|
||||
tags: [admin]
|
||||
params:
|
||||
featured: true
|
||||
time: 20 minutes
|
||||
image:
|
||||
resource_links:
|
||||
- title: Overview of Administration in Docker
|
||||
|
@ -66,4 +67,4 @@ By configuring Docker products to suit your company’s needs, you can optimize
|
|||
|
||||
## Tools integration
|
||||
|
||||
Okta, Entra ID SAML 2.0, Azure Connect (OIDC), MDM solutions like Intune
|
||||
Okta, Entra ID SAML 2.0, Azure Connect (OIDC), MDM solutions like Intune
|
||||
|
|
|
@ -5,9 +5,8 @@ description: >
|
|||
Learn how to manage simple and complex build configurations with Buildx Bake.
|
||||
summary: >
|
||||
Learn to automate Docker builds and testing with declarative configurations using Buildx Bake.
|
||||
tags: [devops]
|
||||
languages: [go]
|
||||
subjects: [devops]
|
||||
levels: [advanced]
|
||||
params:
|
||||
time: 30 minutes
|
||||
featured: true
|
||||
|
|
|
@ -5,7 +5,6 @@ title: Bun language-specific guide
|
|||
summary: |
|
||||
Learn how to containerize JavaScript applications with the Bun runtime.
|
||||
linkTitle: Bun
|
||||
levels: [beginner]
|
||||
languages: [js]
|
||||
params:
|
||||
time: 10 minutes
|
||||
|
|
|
@ -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.
|
||||
description: |
|
||||
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:
|
||||
image: images/learning-paths/container-supported-development.png
|
||||
time: 20 minutes
|
||||
|
@ -73,4 +73,4 @@ Once you start using containers in your development environment, it becomes much
|
|||
|
||||
{{< youtube-embed TCZX15aKSu4 >}}
|
||||
|
||||
<div id="lp-survey-anchor"></div>
|
||||
<div id="lp-survey-anchor"></div>
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/cpp/
|
||||
- /guides/language/cpp/
|
||||
languages: [cpp]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 10 minutes
|
||||
---
|
||||
|
|
|
@ -4,8 +4,7 @@ keywords: database, mysql
|
|||
title: Use containerized databases
|
||||
summary: |
|
||||
Learn how to effectively run and manage databases as containers.
|
||||
levels: [beginner]
|
||||
subjects: [databases]
|
||||
tags: [databases]
|
||||
aliases:
|
||||
- /guides/use-case/databases/
|
||||
params:
|
||||
|
|
|
@ -7,8 +7,7 @@ description: |
|
|||
summary: |
|
||||
Build applications up to 39x faster using cloud-based resources, shared team
|
||||
cache, and native multi-architecture support.
|
||||
levels: [beginner]
|
||||
products: [dbc]
|
||||
tags: [product-demo]
|
||||
aliases:
|
||||
- /learning-paths/docker-build-cloud/
|
||||
params:
|
||||
|
|
|
@ -5,8 +5,7 @@ summary: |
|
|||
Simplify the process of defining, configuring, and running multi-container
|
||||
Docker applications.
|
||||
description: Learn how to use Docker Compose to define and run multi-container Docker applications.
|
||||
levels: [beginner]
|
||||
products: [compose]
|
||||
tags: [product-demo]
|
||||
aliases:
|
||||
- /learning-paths/docker-compose/
|
||||
params:
|
||||
|
|
|
@ -8,8 +8,7 @@ description: |
|
|||
Learn how to use Docker Scout to enhance container security by automating
|
||||
vulnerability detection and remediation, ensuring compliance, and protecting
|
||||
your development workflow.
|
||||
levels: [Beginner]
|
||||
products: [scout]
|
||||
tags: [product-demo]
|
||||
aliases:
|
||||
- /learning-paths/docker-scout/
|
||||
params:
|
||||
|
|
|
@ -9,7 +9,6 @@ aliases:
|
|||
- /language/dotnet/
|
||||
- /guides/language/dotnet/
|
||||
languages: [c-sharp]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
toc_min: 1
|
||||
|
|
|
@ -5,8 +5,7 @@ keywords: python, generative ai, genai, llm, neo4j, ollama, langchain
|
|||
summary: |
|
||||
Learn how to build a PDF bot for parsing PDF documents and generating
|
||||
responses using Docker and generative AI.
|
||||
levels: [beginner]
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
aliases:
|
||||
- /guides/use-case/genai-pdf-bot/
|
||||
params:
|
||||
|
|
|
@ -6,8 +6,7 @@ keywords: python, generative ai, genai, llm, whisper, pinecone, openai, whisper
|
|||
summary: |
|
||||
Learn how to build and deploy a generative AI video analysis and
|
||||
transcription bot using Docker.
|
||||
subjects: [ai]
|
||||
levels: [beginner]
|
||||
tags: [ai]
|
||||
aliases:
|
||||
- /guides/use-case/genai-video-bot/
|
||||
params:
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/golang/
|
||||
- /guides/language/golang/
|
||||
languages: [go]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 30 minutes
|
||||
---
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/java/
|
||||
- /guides/language/java/
|
||||
languages: [java]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -5,9 +5,8 @@ title: Data science with JupyterLab
|
|||
toc_max: 2
|
||||
summary: |
|
||||
Use Docker to run Jupyter notebooks.
|
||||
tags: [data-science]
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
subjects: [data-science]
|
||||
aliases:
|
||||
- /guides/use-case/jupyter/
|
||||
params:
|
||||
|
|
|
@ -5,9 +5,8 @@ title: Developing event-driven applications with Kafka and Docker
|
|||
linktitle: Event-driven apps with Kafka
|
||||
summary: |
|
||||
This guide explains how to run Apache Kafka in Docker containers.
|
||||
subjects: [distributed-systems]
|
||||
tags: [distributed-systems]
|
||||
languages: [js]
|
||||
levels: [intermediate]
|
||||
aliases:
|
||||
- /guides/use-case/kafka/
|
||||
params:
|
||||
|
|
|
@ -7,8 +7,7 @@ aliases:
|
|||
- /guides/deployment-orchestration/kube-deploy/
|
||||
summary: |
|
||||
Learn how to deploy and orchestrate Docker containers using Kubernetes.
|
||||
subjects: [deploy]
|
||||
levels: [beginner]
|
||||
tags: [deploy]
|
||||
params:
|
||||
time: 10 minutes
|
||||
---
|
||||
|
|
|
@ -6,8 +6,7 @@ description: Learn how to build and run a language translation application using
|
|||
summary: |
|
||||
This guide demonstrates how to use Docker to deploy language translation
|
||||
models for NLP tasks.
|
||||
levels: [beginner]
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [python]
|
||||
aliases:
|
||||
- /guides/use-case/nlp/language-translation/
|
||||
|
|
|
@ -6,9 +6,8 @@ linktitle: AWS development with LocalStack
|
|||
summary: |
|
||||
This guide explains how to use Docker to run LocalStack, a local AWS cloud
|
||||
stack emulator.
|
||||
subjects: [cloud-services]
|
||||
tags: [cloud-services]
|
||||
languages: [js]
|
||||
levels: [intermediate]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -6,9 +6,8 @@ description: Learn how to build and run a named entity recognition application u
|
|||
summary: |
|
||||
This guide explains how to containerize named entity recognition (NER) models
|
||||
using Docker.
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
aliases:
|
||||
- /guides/use-case/nlp/named-entity-recognition/
|
||||
params:
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/nodejs/
|
||||
- /guides/language/nodejs/
|
||||
languages: [js]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -7,8 +7,7 @@ aliases:
|
|||
- /guides/deployment-orchestration/orchestration/
|
||||
summary: |
|
||||
Explore the essentials of container orchestration with Docker.
|
||||
subjects: [deploy]
|
||||
levels: [beginner]
|
||||
tags: [deploy]
|
||||
params:
|
||||
time: 10 minutes
|
||||
---
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/php/
|
||||
- /guides/language/php/
|
||||
languages: [php]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -4,8 +4,7 @@ linktitle: Pre-seeding database
|
|||
description: &desc Pre-seeding database with schema and data at startup for development environment
|
||||
keywords: Pre-seeding, database, postgres, container-supported development
|
||||
summary: *desc
|
||||
levels: [intermediate]
|
||||
subjects: [databases]
|
||||
tags: [app-dev, databases]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/python/
|
||||
- /guides/language/python/
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /languages/r/
|
||||
- /guides/languages/r/
|
||||
languages: [r]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 10 minutes
|
||||
---
|
||||
|
|
|
@ -6,8 +6,7 @@ linkTitle: RAG Ollama application
|
|||
summary: |
|
||||
This guide demonstrates how to use Docker to deploy Retrieval-Augmented
|
||||
Generation (RAG) models with Ollama.
|
||||
subjects: [ai]
|
||||
levels: [beginner]
|
||||
tags: [ai]
|
||||
aliases:
|
||||
- /guides/use-case/rag-ollama/
|
||||
params:
|
||||
|
|
|
@ -12,7 +12,6 @@ aliases:
|
|||
- /language/ruby/
|
||||
- /guides/language/ruby/
|
||||
languages: [ruby]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -11,7 +11,6 @@ aliases:
|
|||
- /language/rust/
|
||||
- /guides/language/rust/
|
||||
languages: [rust]
|
||||
levels: [beginner]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -6,9 +6,8 @@ description: Learn how to build and run a sentiment analysis application using P
|
|||
summary: |
|
||||
This guide demonstrates how to containerize sentiment analysis models using
|
||||
Docker.
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
aliases:
|
||||
- /guides/use-case/nlp/sentiment-analysis/
|
||||
params:
|
||||
|
|
|
@ -8,8 +8,7 @@ aliases:
|
|||
- /guides/deployment-orchestration/swarm-deploy/
|
||||
summary: |
|
||||
Discover how to deploy and manage Docker containers using Docker Swarm.
|
||||
subjects: [deploy]
|
||||
levels: [beginner]
|
||||
tags: [deploy]
|
||||
params:
|
||||
time: 10 minutes
|
||||
---
|
||||
|
|
|
@ -4,9 +4,8 @@ keywords: tensorflow.js, machine learning, ml, mediapipe, blazeface, face detect
|
|||
title: Face detection with TensorFlow.js
|
||||
summary: |
|
||||
This guide explains how to run TensorFlow.js in Docker containers.
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [js]
|
||||
levels: [beginner]
|
||||
aliases:
|
||||
- /guides/use-case/tensorflowjs/
|
||||
params:
|
||||
|
|
|
@ -6,8 +6,7 @@ summary: |
|
|||
Automate, scale, and optimize testing workflows with Testcontainers Cloud
|
||||
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.
|
||||
levels: [Beginner]
|
||||
products: [testcontainers]
|
||||
tags: [product-demo]
|
||||
params:
|
||||
featured: true
|
||||
image: images/learning-paths/testcontainers-cloud-learning-path.png
|
||||
|
|
|
@ -6,9 +6,8 @@ description: Learn how to build and run a text recognition application using Pyt
|
|||
summary: |
|
||||
This guide details how to containerize text classification models using
|
||||
Docker.
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
aliases:
|
||||
- /guides/use-case/nlp/text-classification/
|
||||
params:
|
||||
|
|
|
@ -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.
|
||||
summary: |
|
||||
This guide shows how to containerize text summarization models with Docker.
|
||||
subjects: [ai]
|
||||
tags: [ai]
|
||||
languages: [python]
|
||||
levels: [beginner]
|
||||
aliases:
|
||||
- /guides/use-case/nlp/text-summarization/
|
||||
params:
|
||||
|
|
|
@ -4,8 +4,7 @@ description: &desc Use Traefik to easily route traffic between multiple containe
|
|||
keywords: traefik, container-supported development
|
||||
linktitle: HTTP routing with Traefik
|
||||
summary: *desc
|
||||
levels: [intermediate]
|
||||
subjects: [networking]
|
||||
tags: [networking]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -4,8 +4,8 @@ description: &desc Mocking API services in development and testing with WireMock
|
|||
keywords: WireMock, container-supported development
|
||||
linktitle: Mocking API services with WireMock
|
||||
summary: *desc
|
||||
levels: [intermediate]
|
||||
subjects: [distributed-systems]
|
||||
tags: [app-dev, distributed-systems]
|
||||
languages: [js]
|
||||
params:
|
||||
time: 20 minutes
|
||||
---
|
||||
|
|
|
@ -3,3 +3,4 @@ cascade:
|
|||
build:
|
||||
render: never
|
||||
---
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: C#
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/csharp/csharp-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: C++
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/cplusplus/cplusplus-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: Go
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/go/go-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: Java
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/java/java-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: JavaScript
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/javascript/javascript-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: PHP
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/php/php-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: Python
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/python/python-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: R
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/r/r-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: Ruby
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/ruby/ruby-original.svg
|
||||
---
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
---
|
||||
title: Rust
|
||||
params:
|
||||
icon: https://cdn.jsdelivr.net/gh/devicons/devicon@latest/icons/rust/rust-original.svg
|
||||
---
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
cascade:
|
||||
build:
|
||||
render: never
|
||||
---
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
cascade:
|
||||
build:
|
||||
render: never
|
||||
---
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
title: Docker Compose
|
||||
---
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
title: Docker Build Cloud
|
||||
---
|
|
@ -1,3 +0,0 @@
|
|||
---
|
||||
title: Docker Scout
|
||||
---
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
cascade:
|
||||
build:
|
||||
render: never
|
||||
---
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
title: Administration
|
||||
---
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
title: App development
|
||||
---
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
title: Best practices
|
||||
icon: star
|
||||
description: Optimal patterns for Docker
|
||||
---
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
title: FAQ
|
||||
icon: quiz
|
||||
description: Frequently asked questions
|
||||
---
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
title: Product demo
|
||||
---
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
title: Secrets
|
||||
icon: password
|
||||
description: Use sensitive information in containers securely
|
||||
---
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
---
|
||||
title: Troubleshooting
|
||||
icon: troubleshoot
|
||||
description: Fix common issues
|
||||
---
|
||||
|
||||
|
|
|
@ -9,11 +9,7 @@ ignoreLogs:
|
|||
|
||||
taxonomies:
|
||||
tag: tags
|
||||
# filters for guides:
|
||||
language: languages
|
||||
subject: subjects
|
||||
level: levels
|
||||
product: products
|
||||
|
||||
permalinks:
|
||||
page:
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
"Docker-Compose",
|
||||
"Docker-Desktop",
|
||||
"Docker-Hub",
|
||||
"Docker-Scout-Dashboard",
|
||||
"Download",
|
||||
"Editor-or-IDE",
|
||||
"Entra-ID",
|
||||
|
@ -86,6 +87,7 @@
|
|||
"Node",
|
||||
"Non-compliant",
|
||||
"Okta",
|
||||
"Okta-SAML",
|
||||
"Old-Dockerfile",
|
||||
"PHP",
|
||||
"PowerShell",
|
||||
|
@ -192,7 +194,6 @@
|
|||
"chroma",
|
||||
"col-start-2",
|
||||
"containerd-image-store",
|
||||
"cursor-not-allowed",
|
||||
"cursor-pointer",
|
||||
"dark:bg-amber-dark",
|
||||
"dark:bg-amber-dark-200",
|
||||
|
@ -231,8 +232,8 @@
|
|||
"dark:hover:bg-gray-dark-200",
|
||||
"dark:hover:bg-gray-dark-500",
|
||||
"dark:hover:text-blue-dark",
|
||||
"dark:hover:text-white",
|
||||
"dark:prose-invert",
|
||||
"dark:ring-blue-dark-400",
|
||||
"dark:ring-gray-dark-400",
|
||||
"dark:syntax-dark",
|
||||
"dark:text-amber-dark",
|
||||
|
@ -292,7 +293,6 @@
|
|||
"grid-cols-1",
|
||||
"group",
|
||||
"group-hover:block'",
|
||||
"group-hover:underline",
|
||||
"h-16",
|
||||
"h-2",
|
||||
"h-32",
|
||||
|
@ -311,7 +311,6 @@
|
|||
"hover:bg-gray-light-100",
|
||||
"hover:bg-gray-light-200",
|
||||
"hover:bg-gray-light-300",
|
||||
"hover:bg-white",
|
||||
"hover:bg-white/20",
|
||||
"hover:border-gray-light-200",
|
||||
"hover:border-white/20",
|
||||
|
@ -321,7 +320,6 @@
|
|||
"hover:dark:text-blue-dark",
|
||||
"hover:drop-shadow-lg",
|
||||
"hover:opacity-90",
|
||||
"hover:text-black",
|
||||
"hover:text-blue-light",
|
||||
"hover:text-white",
|
||||
"hover:underline",
|
||||
|
@ -329,6 +327,7 @@
|
|||
"icon-sm",
|
||||
"icon-svg",
|
||||
"inline",
|
||||
"inline-flex",
|
||||
"inset-0",
|
||||
"invertible",
|
||||
"italic",
|
||||
|
@ -352,7 +351,6 @@
|
|||
"lg:no-underline",
|
||||
"lg:pb-2",
|
||||
"lg:scale-100",
|
||||
"lg:text-base",
|
||||
"link",
|
||||
"lntable",
|
||||
"lntd",
|
||||
|
@ -368,6 +366,7 @@
|
|||
"max-w-full",
|
||||
"max-w-none",
|
||||
"max-w-xl",
|
||||
"mb-1",
|
||||
"mb-2",
|
||||
"mb-4",
|
||||
"mb-8",
|
||||
|
@ -399,7 +398,6 @@
|
|||
"mt-4",
|
||||
"mx-auto",
|
||||
"my-0",
|
||||
"my-2",
|
||||
"my-4",
|
||||
"my-6",
|
||||
"no-underline",
|
||||
|
@ -427,6 +425,7 @@
|
|||
"pb-1",
|
||||
"pb-2",
|
||||
"pb-4",
|
||||
"pb-8",
|
||||
"pl-1",
|
||||
"pl-2",
|
||||
"pl-3",
|
||||
|
@ -440,7 +439,6 @@
|
|||
"pt-4",
|
||||
"px-1",
|
||||
"px-2",
|
||||
"px-3",
|
||||
"px-4",
|
||||
"px-6",
|
||||
"py-1",
|
||||
|
@ -452,7 +450,9 @@
|
|||
"right-0",
|
||||
"right-3",
|
||||
"right-8",
|
||||
"ring-2",
|
||||
"ring-[1.5px]",
|
||||
"ring-blue-light-400",
|
||||
"ring-gray-light-200",
|
||||
"rotate-45",
|
||||
"rounded",
|
||||
|
@ -519,9 +519,7 @@
|
|||
"top-full",
|
||||
"transition",
|
||||
"truncate",
|
||||
"underline",
|
||||
"underline-offset-2",
|
||||
"underline-offset-8",
|
||||
"w-2",
|
||||
"w-8",
|
||||
"w-[1200px]",
|
||||
|
|
|
@ -1,165 +1,221 @@
|
|||
{{ define "left" }}
|
||||
{{ partial "sidebar/mainnav.html" . }}
|
||||
<div class="p-4 flex flex-col gap-4 text-sm">
|
||||
<div>
|
||||
<span class="icon-svg">{{ partialCached "icon" "filter_alt" "filter_alt" }}</span>
|
||||
<span>Filters</span>
|
||||
</div>
|
||||
<div class="space-y-4"
|
||||
x-data="{
|
||||
selected: { products: [], subjects: [], languages: [], levels: [], },
|
||||
toggleFilter(taxonomy, term) {
|
||||
this.selected[taxonomy].includes(term)
|
||||
? this.selected[taxonomy] = this.selected[taxonomy].filter(el => el != term)
|
||||
: this.selected[taxonomy].push(term);
|
||||
{{- partial "sidebar/mainnav.html" . }}
|
||||
<div class="p-4 flex flex-col gap-2 text-sm">
|
||||
<p>Filter guides by tag or programming language.<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.selected[taxonomy].length > 0) {
|
||||
url.searchParams.set(taxonomy, this.selected[taxonomy].join('~'));
|
||||
if (this.filters[grp].length > 0) {
|
||||
url.searchParams.set(grp, this.filters[grp].join('~'));
|
||||
} else {
|
||||
url.searchParams.delete(taxonomy);
|
||||
url.searchParams.delete(grp);
|
||||
}
|
||||
window.history.replaceState({}, '', url);
|
||||
|
||||
this.$dispatch('guide-filter', { filters: this.selected });
|
||||
this.$dispatch('guide-filter', { filters: this.filters });
|
||||
},
|
||||
|
||||
init() {
|
||||
const url = new URL(window.location.href);
|
||||
for (const [key, value] of url.searchParams.entries()) {
|
||||
if (value) {
|
||||
this.selected[key] = value.split('~');
|
||||
}
|
||||
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('~');
|
||||
}
|
||||
}
|
||||
}">
|
||||
{{ template "taxofilters" site.Taxonomies.products }}
|
||||
{{ template "taxofilters" site.Taxonomies.subjects }}
|
||||
{{ template "taxofilters" site.Taxonomies.levels }}
|
||||
{{ template "taxofilters" site.Taxonomies.languages }}
|
||||
}" @guide-filter.window="filters = $event.detail.filters;">
|
||||
<div class="pl-2"><strong>Tags</strong></div>
|
||||
<fieldset class="flex flex-col gap-2">
|
||||
{{- range $name, $taxonomy := where site.Taxonomies.tags ".Page.Type" "guides" }}
|
||||
{{- $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>
|
||||
{{ 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" }}
|
||||
<div class="flex gap-8 w-full">
|
||||
<article class="prose min-w-0 max-w-none dark:prose-invert">
|
||||
{{- partial "breadcrumbs.html" . }}
|
||||
<h1 data-pagefind-weight="10" class="scroll-mt-36">{{ .Title }}</h1>
|
||||
{{ .Content }}
|
||||
<h2>Featured</h2>
|
||||
<div class="not-prose py-4 grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
|
||||
{{- $featured := where .Pages "Params.featured" true }}
|
||||
{{- with $featured }}
|
||||
{{- 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: []," "." ) "" }} },
|
||||
<div class="not-prose min-h-screen" x-data="{
|
||||
filters: { tags: [], languages: [] },
|
||||
hidden: [],
|
||||
total: {{ len .Pages }},
|
||||
|
||||
noFilters() {
|
||||
return Object.values(this.filters).every(arr=> Array.isArray(arr) && arr.length === 0);
|
||||
},
|
||||
|
||||
showItem(taxonomies) {
|
||||
if (this.noFilters()) return true;
|
||||
let match = false;
|
||||
isVisible(el) {
|
||||
return !this.hidden.includes(el.id);
|
||||
},
|
||||
|
||||
for (const taxonomy in this.filters) {
|
||||
const selectedTerms = this.filters[taxonomy];
|
||||
if (selectedTerms.length > 0) {
|
||||
const itemTerms = taxonomies[taxonomy] || [];
|
||||
// Check if all selected terms are included in the item's terms
|
||||
const hasAnyTerms = selectedTerms.some(term => itemTerms.includes(term));
|
||||
if (hasAnyTerms) {
|
||||
match = true;
|
||||
break;
|
||||
updateVisible() {
|
||||
const hiddenSet = new Set();
|
||||
// show if no filters have been selected
|
||||
if (this.noFilters()) 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
return match;
|
||||
|
||||
this.hidden = Array.from(hiddenSet)
|
||||
},
|
||||
|
||||
init() {
|
||||
const url = new URL(window.location.href);
|
||||
for (const [key, value] of url.searchParams.entries()) {
|
||||
if (value) {
|
||||
this.filters[key] = value.split('~');
|
||||
}
|
||||
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; document.getElementById('all-guides').scrollIntoView({ behavior: 'smooth' })">
|
||||
<h2 id="all-guides" class="scroll-mt-36">All guides</h2>
|
||||
{{- range .Pages }}
|
||||
{{- $opts := dict "page" . "taxonomies" $taxonomies }}
|
||||
{{- $filters := partial "utils/filter-terms.html" $opts }}
|
||||
<a href="{{ .Permalink }}" x-show="showItem({{ jsonify $filters }});" x-transition
|
||||
class="group flex flex-col justify-between p-4 border-b
|
||||
border-divider-light hover:bg-white
|
||||
hover:dark:bg-gray-dark-200 dark:border-divider-dark
|
||||
drop-shadow transition">
|
||||
<div class="flex flex-col xl:flex-row justify-between">
|
||||
<div class="text-lg group-hover:underline mb-2 xl:mb-0 truncate">{{ .Title }}</div>
|
||||
{{ template "guide-metadata" . }}
|
||||
}" 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 py-4 grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3 gap-8">
|
||||
{{- $featured := where .Pages "Params.featured" true }}
|
||||
{{- with $featured }}
|
||||
{{- 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>
|
||||
<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>
|
||||
</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>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{- 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">
|
||||
{{- $taxoterms := .GetTerms "languages" }}
|
||||
{{- $taxoterms = $taxoterms | append (.GetTerms "levels") }}
|
||||
{{- $taxoterms = $taxoterms | append (.GetTerms "subjects") }}
|
||||
{{- range $taxoterms }}
|
||||
<span class="rounded whitespace-nowrap bg-gray-light-200 dark:bg-gray-dark-300 px-2">{{- .Page.LinkTitle }}</span>
|
||||
{{- $langs := .GetTerms "languages" }}
|
||||
{{ partial "languages" $langs }}
|
||||
{{- $tags := .GetTerms "tags" }}
|
||||
{{- range $tags }}
|
||||
{{ template "termchip" .Page.LinkTitle }}
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- with .Params.time }}
|
||||
<div class="flex whitespace-nowrap flex-shrink gap-2">
|
||||
<span class="icon-svg">{{ partialCached "icon" "schedule" "schedule" }}</span>
|
||||
<span>{{ . }}</span>
|
||||
</div>
|
||||
<div class="flex whitespace-nowrap flex-shrink gap-2">
|
||||
<span class="icon-svg">{{ partialCached "icon" "schedule" "schedule" }}</span>
|
||||
<span>{{ . }}</span>
|
||||
</div>
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- 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 }}
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
<article class="prose min-w-0 flex-[2_2_0%] max-w-4xl dark:prose-invert">
|
||||
{{ partial "breadcrumbs.html" . }}
|
||||
<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">
|
||||
{{ partialCached "pagemeta.html" . . }}
|
||||
<hr />
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{{- $svg := resources.Get (fmt.Printf "icons/%s-fill.svg" .) }}
|
||||
{{- if not $svg }}
|
||||
{{- errorf "Failed to get icon: %s" . }}
|
||||
{{- errorf "Failed to get icon: %v\n\n" . }}
|
||||
{{ end }}
|
||||
{{- if not $svg.Content }}
|
||||
{{- errorf "Failed to get icon: %s" . }}
|
||||
{{- errorf "Failed to get icon: %v\n\n" . }}
|
||||
{{- end }}
|
||||
{{- safe.HTML $svg.Content -}}
|
||||
|
|
|
@ -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 -}}
|
||||
|
|
@ -2,24 +2,13 @@
|
|||
{{- with .Fragments }}
|
||||
{{- $toc = and (ne page.Params.notoc true) .Headings }}
|
||||
{{- end }}
|
||||
{{- $tags := .GetTerms "tags" }}
|
||||
{{- if or $toc $tags }}
|
||||
{{- with $toc }}
|
||||
<div data-pagefind-ignore class="not-prose">
|
||||
{{- with $tags }}
|
||||
<div class="flex flex-col gap-2 my-2">
|
||||
<span class="text-lg">Tags</span>
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
{{- partial "tags.html" . -}}
|
||||
</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 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>
|
||||
</div>
|
||||
{{- end }}
|
||||
|
||||
|
|
|
@ -9,18 +9,15 @@
|
|||
<a href="{{ $root.Permalink }}">{{ $root.Title }}</a>
|
||||
</div>
|
||||
<div>{{ $root.Summary }}</div>
|
||||
<div class="space-y-2">
|
||||
{{- with ($root.GetTerms "levels") }}
|
||||
<div class="flex gap-2 text-gray-light dark:text-gray-dark">
|
||||
<span class="icon-svg">{{ partialCached "icon" "school" "school" }}</span>
|
||||
<span>
|
||||
{{- range $i, $e := . -}}
|
||||
{{- if $i -}},{{ end -}}
|
||||
{{- .Page.Title -}}
|
||||
{{- end -}}
|
||||
</span>
|
||||
</div>
|
||||
{{- end -}}
|
||||
<div class="space-y-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{{- with ($root.GetTerms "languages") }}
|
||||
{{ partial "languages.html" . }}
|
||||
{{- end }}
|
||||
{{- with ($root.GetTerms "tags") }}
|
||||
{{ partial "tags.html" . }}
|
||||
{{- end }}
|
||||
</div>
|
||||
{{- with ($root.Params.time) }}
|
||||
<div class="flex gap-2 text-gray-light dark:text-gray-dark">
|
||||
<span class="icon-svg"
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<!-- Main navigation for the sidebar -->
|
||||
<div class="py-2 px-4" x-data="{ expanded: false }">
|
||||
<div class="flex w-full items-center justify-between">
|
||||
<!-- Current section: use menu, fall back to current page -->
|
||||
{{- $curr := page }}
|
||||
<!-- Current section: use menu, fall back to current section or page -->
|
||||
{{- $curr := .FirstSection }}
|
||||
{{- if eq $curr site.Home }}
|
||||
{{- $curr = . }}
|
||||
{{- end }}
|
||||
{{- range site.Menus.main }}
|
||||
{{- if .Page.IsAncestor page }}
|
||||
{{- if or (.Page.IsAncestor page) (eq .Page page) }}
|
||||
{{- $curr = .Page }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
<ul>
|
||||
<ul class="md:text-sm">
|
||||
{{- range site.Taxonomies.tags }}
|
||||
<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 }}">
|
||||
<a class="py-2 w-full truncate block"
|
||||
href="{{ .Page.Permalink }}"
|
||||
title="{{ .Page.LinkTitle }}">
|
||||
<span class="icon-svg">{{- partialCached "icon.html" .Page.Params.icon .Page.Params.icon -}}</span>
|
||||
{{ .Page.LinkTitle }}
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
{{- /*
|
||||
List of tag "chips" as links
|
||||
Context: page.Pages
|
||||
*/ -}}
|
||||
*/
|
||||
-}}
|
||||
{{- range . -}}
|
||||
{{- if eq .File nil }}
|
||||
{{- errorf "[tags] Undefined tag: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }}
|
||||
{{- 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 }}">
|
||||
<div class="icon-svg icon-sm pb-0.5">{{ partialCached "icon" .Params.icon .Params.icon }}</div>
|
||||
<div>{{ .LinkTitle }}</div>
|
||||
{{- if eq .File nil }}
|
||||
{{- errorf "[tags] Undefined tag: '%s' in %s" (urlize (strings.ToLower .Title)) page.File.Filename }}
|
||||
{{- end }}
|
||||
<a class="text-sm inline-flex 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"
|
||||
href="{{ .Permalink }}">
|
||||
<span class="icon-svg icon-sm pb-0.5">
|
||||
{{ partialCached "icon" "tag" "tag" }}
|
||||
</span>
|
||||
<span>{{ .LinkTitle }}</span>
|
||||
</a>
|
||||
{{- end -}}
|
||||
|
|
|
@ -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") }}
|
|
@ -6,19 +6,18 @@
|
|||
{{ define "main" }}
|
||||
<article class="prose max-w-none dark:prose-invert">
|
||||
{{ 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 }}
|
||||
<div class="grid grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3">
|
||||
<ul>
|
||||
{{ range site.Taxonomies.tags }}
|
||||
{{ partial "components/card.html"
|
||||
(dict
|
||||
"link" .Page.Permalink
|
||||
"title" .Page.Title
|
||||
"description" .Page.Description
|
||||
"icon" .Page.Params.icon
|
||||
)
|
||||
}}
|
||||
<li>
|
||||
<a href="{{ .Page.Permalink }}">{{ .Page.Title }}</a>
|
||||
({{ (len .Pages) }} {{ cond (gt (len .Pages) 1) "pages" "page" }})
|
||||
</li>
|
||||
{{ end }}
|
||||
</div>
|
||||
</ul>
|
||||
</article>
|
||||
{{ end }}
|
||||
|
|
|
@ -1,44 +1,25 @@
|
|||
{{ define "left" }}
|
||||
{{ partial "sidebar/mainnav.html" . }}
|
||||
{{ partial "sidebar/tags.html" . }}
|
||||
{{ end }}
|
||||
|
||||
{{ define "main" }}
|
||||
<article class="prose max-w-none dark:prose-invert">
|
||||
{{ partial "breadcrumbs.html" . }}
|
||||
<h1 class="scroll-mt-36 flex gap-4 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>
|
||||
<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 }}
|
||||
<div class="not-prose flex justify-between items-center">
|
||||
<span class="text-gray-light dark:text-gray-dark">Pages with this tag:</span>
|
||||
{{ partial "pagination.html" . }}
|
||||
</div>
|
||||
<table style="display: table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="50%">Title</th>
|
||||
<th width="50%">Section</th>
|
||||
</tr>
|
||||
</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>
|
||||
{{- range .Pages.GroupBy "Type" }}
|
||||
<h2>{{ (site.GetPage .Key).LinkTitle }}</h2>
|
||||
<ul>
|
||||
{{ range .Pages }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{- end }}
|
||||
</article>
|
||||
{{ end }}
|
||||
|
|
Загрузка…
Ссылка в новой задаче