From 808d64c8115ca058665805d02a937f146c375531 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Mon, 10 Nov 2025 08:56:12 +0100 Subject: [PATCH] site: use gordon for ask ai Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- assets/css/style.css | 1 + assets/js/src/alpine.js | 80 ++++- hugo.yaml | 3 + hugo_stats.json | 64 ++++ layouts/_default/baseof.html | 6 +- layouts/index.html | 1 + layouts/partials/gordon-chat.html | 538 ++++++++++++++++++++++++++++++ layouts/partials/head.html | 53 --- layouts/partials/header.html | 5 +- layouts/partials/search-bar.html | 7 +- package-lock.json | 23 ++ package.json | 2 + 12 files changed, 723 insertions(+), 60 deletions(-) create mode 100644 layouts/partials/gordon-chat.html diff --git a/assets/css/style.css b/assets/css/style.css index d8469b419a5f..8315621f425d 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -41,5 +41,6 @@ @import "syntax-dark.css"; @import "syntax-light.css"; @import "components.css"; +@import "highlight-github-dark.css"; @variant dark (&:where(.dark, .dark *)); diff --git a/assets/js/src/alpine.js b/assets/js/src/alpine.js index cdcdfeb93055..0e2f57e0b6d0 100644 --- a/assets/js/src/alpine.js +++ b/assets/js/src/alpine.js @@ -2,12 +2,90 @@ import Alpine from 'alpinejs' import collapse from '@alpinejs/collapse' import persist from '@alpinejs/persist' import focus from '@alpinejs/focus' - +import { marked } from 'marked' +import hljs from 'highlight.js/lib/core' +// Import languages relevant to Docker docs +import bash from 'highlight.js/lib/languages/bash' +import dockerfile from 'highlight.js/lib/languages/dockerfile' +import yaml from 'highlight.js/lib/languages/yaml' +import json from 'highlight.js/lib/languages/json' +import javascript from 'highlight.js/lib/languages/javascript' +import python from 'highlight.js/lib/languages/python' +import go from 'highlight.js/lib/languages/go' + window.Alpine = Alpine Alpine.plugin(collapse) Alpine.plugin(persist) Alpine.plugin(focus) + +// Register highlight.js languages +hljs.registerLanguage('bash', bash) +hljs.registerLanguage('sh', bash) +hljs.registerLanguage('shell', bash) +hljs.registerLanguage('console', bash) +hljs.registerLanguage('dockerfile', dockerfile) +hljs.registerLanguage('yaml', yaml) +hljs.registerLanguage('yml', yaml) +hljs.registerLanguage('json', json) +hljs.registerLanguage('javascript', javascript) +hljs.registerLanguage('js', javascript) +hljs.registerLanguage('python', python) +hljs.registerLanguage('py', python) +hljs.registerLanguage('go', go) +hljs.registerLanguage('golang', go) + +// Add $markdown magic for rendering markdown with syntax highlighting +Alpine.magic('markdown', () => { + return (content) => { + if (!content) return '' + const html = marked(content) + + // Parse and highlight code blocks + const div = document.createElement('div') + div.innerHTML = html + + // Handle code blocks (pre > code) + div.querySelectorAll('pre').forEach((pre) => { + // Add not-prose to prevent Tailwind Typography styling + pre.classList.add('not-prose') + const code = pre.querySelector('code') + if (code) { + // Preserve the original text with newlines + const codeText = code.textContent + + // Clear and set as plain text first to preserve structure + code.textContent = codeText + + // Now apply highlight.js which will work with the text nodes + hljs.highlightElement(code) + } + }) + + // Handle inline code elements (not in pre blocks) + div.querySelectorAll('code:not(pre code)').forEach((code) => { + code.classList.add('not-prose') + }) + + return div.innerHTML + } +}) + +// Stores Alpine.store("showSidebar", false) +Alpine.store('gordon', { + isOpen: Alpine.$persist(false).as('gordon-isOpen'), + query: '', + toggle() { + this.isOpen = !this.isOpen + }, + open(query) { + this.isOpen = true + if (query) this.query = query + }, + close() { + this.isOpen = false + } +}) Alpine.start() diff --git a/hugo.yaml b/hugo.yaml index 956b5ef633d4..304662b32459 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -271,6 +271,9 @@ module: # Mount the icon files to assets so we can access them with resources.Get - source: node_modules/@material-symbols/svg-400/rounded target: assets/icons + # Mount highlight.js theme for Gordon chat syntax highlighting + - source: node_modules/highlight.js/styles/github-dark.css + target: assets/css/highlight-github-dark.css imports: diff --git a/hugo_stats.json b/hugo_stats.json index 2af0050fd096..2f4d5925775f 100644 --- a/hugo_stats.json +++ b/hugo_stats.json @@ -174,6 +174,11 @@ "admonition-tip", "admonition-title", "admonition-warning", + "align-middle", + "align-text-bottom", + "animate-bounce", + "animate-pulse", + "animate-spin", "aspect-video", "bake-action", "bg-amber-500", @@ -181,9 +186,12 @@ "bg-black/100", "bg-black/50", "bg-blue", + "bg-blue-100", "bg-blue-400", + "bg-blue-50", "bg-blue-500", "bg-blue-600", + "bg-current", "bg-gradient-to-br", "bg-gray-100", "bg-gray-400", @@ -195,6 +203,7 @@ "bg-pattern-blue", "bg-pattern-purple", "bg-pattern-verde", + "bg-red-50", "bg-red-500", "bg-violet-500", "bg-white", @@ -214,10 +223,12 @@ "border-l-2", "border-l-magenta-light", "border-none", + "border-red-200", "border-t", "border-transparent", "bottom-0", "breadcrumbs", + "break-words", "build-push-action", "button", "card", @@ -234,6 +245,7 @@ "cls-2", "col-start-2", "containerd-image-store", + "cursor-not-allowed", "cursor-pointer", "dark:bg-amber-400", "dark:bg-background-dark", @@ -242,6 +254,7 @@ "dark:bg-blue-400", "dark:bg-blue-500", "dark:bg-blue-800", + "dark:bg-blue-900", "dark:bg-gray-300", "dark:bg-gray-500", "dark:bg-gray-800", @@ -251,6 +264,7 @@ "dark:bg-green-dark-400", "dark:bg-navbar-bg-dark", "dark:bg-red-400", + "dark:bg-red-900/20", "dark:bg-violet-400", "dark:block", "dark:border-b-blue-600", @@ -260,6 +274,8 @@ "dark:border-gray-700", "dark:border-green-400", "dark:border-l-magenta-dark", + "dark:border-red-800", + "dark:focus:border-blue-400", "dark:focus:ring-3-blue-dark", "dark:from-blue-300", "dark:hidden", @@ -267,6 +283,7 @@ "dark:hover:bg-blue-500", "dark:hover:bg-blue-700", "dark:hover:bg-gray-600", + "dark:hover:bg-gray-700", "dark:hover:bg-gray-900", "dark:hover:text-blue", "dark:outline-gray-800", @@ -275,24 +292,32 @@ "dark:ring-3-gray-dark-400", "dark:syntax-dark", "dark:text-blue", + "dark:text-blue-400", "dark:text-blue-700", "dark:text-divider-dark", "dark:text-gray", + "dark:text-gray-100", "dark:text-gray-200", "dark:text-gray-300", "dark:text-gray-400", "dark:text-gray-500", "dark:text-gray-600", "dark:text-magenta-dark", + "dark:text-red-400", "dark:text-white", "dark:to-blue-400", + "disabled:cursor-not-allowed", + "disabled:opacity-50", "docker/bake-action", "docker/build-push-action", "download-links", "download-links-subcontainer", "drop-shadow", "dropdown-base", + "duration-200", "duration-300", + "ease-in", + "ease-out", "fixed", "flex", "flex-1", @@ -304,8 +329,11 @@ "flex-shrink", "flex-shrink-0", "flex-wrap", + "focus:border-blue-500", "focus:outline-none", + "focus:ring-2", "focus:ring-3-blue-light", + "focus:ring-blue-500/20", "font-bold", "font-medium", "font-normal", @@ -334,6 +362,7 @@ "h-16", "h-2", "h-32", + "h-4", "h-48", "h-5", "h-6", @@ -348,6 +377,7 @@ "highlight", "hover:bg-blue-400", "hover:bg-blue-500", + "hover:bg-blue-700", "hover:bg-gray-100", "hover:bg-gray-200", "hover:bg-gray-50", @@ -358,6 +388,7 @@ "hover:opacity-80", "hover:opacity-90", "hover:text-blue", + "hover:text-white", "hover:underline", "icon-lg", "icon-sm", @@ -375,6 +406,7 @@ "justify-between", "justify-center", "justify-end", + "justify-start", "leading-none", "leading-snug", "leading-tight", @@ -402,8 +434,10 @@ "max-w-4xl", "max-w-56", "max-w-[1920px]", + "max-w-[85%]", "max-w-full", "max-w-none", + "max-w-sm", "mb-1", "mb-1.5", "mb-2", @@ -413,26 +447,38 @@ "md-dropdown", "md:block", "md:border-none", + "md:bottom-2", "md:flex", "md:flex-nowrap", "md:flex-row", "md:grid-cols-2", "md:h-[334px]", + "md:h-[600px]", + "md:h-[calc(100vh-1rem)]", "md:h-[calc(100vh-64px)]", "md:hidden", "md:max-w-[66%]", + "md:right-2", "md:scale-100", "md:sticky", "md:text-base", "md:text-sm", "md:top-16", + "md:top-2", + "md:top-auto", "md:w-[300px]", "md:w-[320px]", + "md:w-[400px]", + "md:w-[500px]", + "md:w-[clamp(400px,30vw,500px)]", + "md:w-[min(500px,30vw)]", + "md:w-[min(900px,90vw)]", "md:z-auto", "min-h-screen", "min-w-0", "min-w-48", "min-w-52", + "ml-0.5", "ml-2", "ml-3", "ml-4", @@ -442,6 +488,7 @@ "mt-2", "mt-20", "mt-4", + "mt-6", "mt-8", "mt-[2px]", "mx-1", @@ -458,6 +505,7 @@ "no-wrap", "not-prose", "object-cover", + "opacity-50", "open-kapa-widget", "openSUSE-and-SLES", "origin-bottom-right", @@ -493,16 +541,19 @@ "pl-5", "pr-2", "prose", + "prose-sm", "pt-2", "pt-4", "px-1", "px-2", "px-3", "px-4", + "px-6", "py-0.5", "py-1", "py-2", "py-20", + "py-3", "py-4", "py-8", "relative", @@ -515,9 +566,12 @@ "ring-3-gray-light-200", "rotate-45", "rounded", + "rounded-b-lg", "rounded-full", + "rounded-lg", "rounded-md", "rounded-sm", + "rounded-t-lg", "scale-50", "scale-75", "scroll-mt-2", @@ -531,6 +585,7 @@ "self-center", "self-start", "shadow", + "shadow-2xl", "shadow-md", "sm:block", "sm:flex-row", @@ -553,7 +608,9 @@ "text-base", "text-black", "text-blue", + "text-blue-600", "text-blue-light", + "text-center", "text-divider-light", "text-gray", "text-gray-200", @@ -563,11 +620,14 @@ "text-gray-600", "text-gray-700", "text-gray-800", + "text-gray-900", "text-left", "text-lg", "text-magenta-light", + "text-red-800", "text-sm", "text-white", + "text-white/80", "text-xl", "text-xs", "to-blue-200", @@ -579,10 +639,14 @@ "topbar-button", "topbar-button-clear", "transition", + "transition-all", "transition-colors", "transition-opacity", "transition-transform", + "translate-x-0", + "translate-x-full", "truncate", + "w-1", "w-2", "w-5", "w-65", diff --git a/layouts/_default/baseof.html b/layouts/_default/baseof.html index 66cdeeff550b..8ddbf7cdcd36 100644 --- a/layouts/_default/baseof.html +++ b/layouts/_default/baseof.html @@ -8,6 +8,7 @@ class="dark:bg-navbar-bg-dark bg-navbar-bg flex flex-col items-center text-base text-black dark:text-white" > {{ partial "header.html" . }} + {{ partial "gordon-chat.html" . }}
{{ partial "header.html" . }} + {{ partial "gordon-chat.html" . }}
+
+ +
+ + +
+ +
+
+ + {{ partialCached "icon" "icons/sparkle.svg" "icons/sparkle.svg" }} + +

Ask AI

+
+
+ + + +
+
+ + +
+ + + + + + + + +
+ + +
+
+ + +
+
+ + +
+ This is a custom LLM for answering questions about Docker. Answers are + based on the documentation. +
+
+
+ + + diff --git a/layouts/partials/head.html b/layouts/partials/head.html index 4c1455512c37..af9892537126 100644 --- a/layouts/partials/head.html +++ b/layouts/partials/head.html @@ -51,59 +51,6 @@ })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); {{ end }} -{{/* kapa.ai widget */}} - - {{/* preload Roboto Flex as it's a critical font: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/preload */}} ` }} {{- $emptyState | safe.HTML }} diff --git a/package-lock.json b/package-lock.json index 4aefc775b6d7..3b7316c8b938 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ "@tailwindcss/cli": "^4.1.6", "@tailwindcss/typography": "^0.5.15", "alpinejs": "^3.14.3", + "highlight.js": "^11.11.1", + "marked": "^17.0.0", "tailwindcss": "^4.1.6" }, "devDependencies": { @@ -976,6 +978,15 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -1367,6 +1378,18 @@ "url": "https://github.com/sponsors/DavidAnson" } }, + "node_modules/marked": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.0.tgz", + "integrity": "sha512-KkDYEWEEiYJw/KC+DVm1zzlpMQSMIu6YRltkcCvwheCp8HWPXCk9JwOmHJKBlGfzcpzcIt6x3sMnTsRm/51oDg==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/micromark": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", diff --git a/package.json b/package.json index de8098b00b20..795ed12561b4 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "@tailwindcss/cli": "^4.1.6", "@tailwindcss/typography": "^0.5.15", "alpinejs": "^3.14.3", + "highlight.js": "^11.11.1", + "marked": "^17.0.0", "tailwindcss": "^4.1.6" }, "devDependencies": {