Repository navigation
fix: readable sitemap and a Get started path on the spec home page #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
4b02e57
ebfeb9e
7ab1406
8edcf4c
47f95f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| User-agent: * | ||
| Allow: / | ||
|
|
||
| Sitemap: https://devops-maturity.github.io/sitemap.xml | ||
| Sitemap: https://devops-maturity.github.io/devops-maturity/sitemap.xml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| {{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }} | ||
| {{- /* As with sitemapindex.xml: <loc> has to be absolute, and baseURL is "/", so the host | ||
| comes from canonicalBaseURL rather than from Hugo's own permalinks. The hreflang | ||
| alternates are the ones Hugo's built-in template lists, made absolute the same way. */}} | ||
| {{- $base := site.Params.canonicalBaseURL }} | ||
| <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" | ||
| xmlns:xhtml="http://www.w3.org/1999/xhtml"> | ||
| {{- range where .Pages "Sitemap.Disable" "ne" true }} | ||
| <url> | ||
| <loc>{{ printf "%s%s" $base (strings.TrimPrefix "/" .RelPermalink) }}</loc> | ||
| {{- if not .Lastmod.IsZero }} | ||
| <lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod> | ||
| {{- end }} | ||
| {{- if .IsTranslated }} | ||
| {{- range .AllTranslations }} | ||
| <xhtml:link rel="alternate" hreflang="{{ .Lang }}" href="{{ printf "%s%s" $base (strings.TrimPrefix "/" .RelPermalink) }}"/> | ||
| {{- end }} | ||
| {{- end }} | ||
| </url> | ||
| {{- end }} | ||
| </urlset> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,11 @@ | ||||||||||||||||||||||
| {{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }} | ||||||||||||||||||||||
| {{- /* The sitemap protocol requires an absolute <loc>, and baseURL is "/" so that a deploy | ||||||||||||||||||||||
| preview serves its own assets. Hugo's built-in template would emit "/en/sitemap.xml", | ||||||||||||||||||||||
| which Search Console cannot fetch, so the host is prefixed explicitly here. */}} | ||||||||||||||||||||||
| <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> | ||||||||||||||||||||||
| {{- range . }} | ||||||||||||||||||||||
| <sitemap> | ||||||||||||||||||||||
| <loc>{{ printf "%s%s" .Params.canonicalBaseURL (strings.TrimPrefix "/" .SitemapAbsURL) }}</loc> | ||||||||||||||||||||||
|
Comment on lines
+4
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: sed -n '1,20p' themes/devops-maturity/layouts/_default/sitemapindex.xml
rg -n 'canonicalBaseURL|baseURL|sitemapindex|SitemapAbsURL' config.yaml themes/devops-maturity/layoutsRepository: devops-maturity/spec Length of output: 2191 🌐 Web query:
💡 Result: 🏁 Script executed: printf '%s\n' '--- Hugo/version declarations ---'; rg -n -F --glob '!public/**' --glob '!node_modules/**' -e 'Hugo' -e 'hugo' -e 'module' -e 'baseURL' -e 'canonicalBaseURL' .github Makefile package.json go.mod config.yaml 2>/dev/null || true; printf '%s\n' '--- relevant templates ---'; nl -ba themes/devops-maturity/layouts/_default/sitemapindex.xml; nl -ba themes/devops-maturity/layouts/_default/sitemap.xml; printf '%s\n' '--- multilingual config ---'; nl -ba config.yaml | sed -n '1,35p'Repository: devops-maturity/spec Length of output: 4258 🏁 Script executed: nl -ba .github/workflows/main.yml | sed -n '28,58p'; printf '%s\n' '--- template references to site parameters in sitemap contexts ---'; rg -n -F --glob '*.xml' -e 'site.Params.canonicalBaseURL' -e '.Params.canonicalBaseURL' themes/devops-maturity/layouts; printf '%s\n' '--- available Hugo binary ---'; if command -v hugo >/dev/null 2>&1; then hugo version; else echo 'hugo not installed'; fiRepository: devops-maturity/spec Length of output: 1783 Read the canonical base URL from the site context. Inside Suggested fix- <loc>{{ printf "%s%s" .Params.canonicalBaseURL (strings.TrimPrefix "/" .SitemapAbsURL) }}</loc>
+ <loc>{{ printf "%s%s" site.Params.canonicalBaseURL (strings.TrimPrefix "/" .SitemapAbsURL) }}</loc>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
| </sitemap> | ||||||||||||||||||||||
| {{- end }} | ||||||||||||||||||||||
| </sitemapindex> | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,96 @@ | ||
| <script src="{{ .Site.BaseURL }}js/bundle.js"></script> | ||
| {{- /* | ||
| Copy buttons for the home page snippets (layouts/partials/welcome.html) and | ||
| the GA events that say whether visitors try the tool: | ||
|
|
||
| copy_install the pip command was copied; method: button | select | ||
| click_action the Action step was copied (method: button | select) or a | ||
| link to the Action was followed (method: link) | ||
| click_docs a link into the docs site (/devops-maturity/) was followed | ||
|
|
||
| Link events also carry placement (hero | content | other) and link_url. | ||
| Inline rather than in js/index.js so it needs no bundle rebuild. | ||
| */}} | ||
| <script> | ||
| (function () { | ||
| function send(name, params) { | ||
| if (typeof window.gtag !== 'function') return; | ||
| try { | ||
| window.gtag('event', name, params); | ||
| } catch (e) { | ||
| // Nothing to recover; the event is simply not counted. | ||
| } | ||
| } | ||
|
|
||
| // Each button's own label, kept before any click can swap it for "Copied". | ||
| // Reading textContent on click instead would, on a second click inside the | ||
| // 1.5 s window, save "Copied" as the label to restore. | ||
| Array.prototype.forEach.call(document.querySelectorAll('[data-copy-target]'), function (button) { | ||
| button.setAttribute('data-label', button.textContent); | ||
| }); | ||
|
|
||
| function copyWithSelection(text) { | ||
| var area = document.createElement('textarea'); | ||
| area.value = text; | ||
| area.setAttribute('readonly', ''); | ||
| area.style.position = 'absolute'; | ||
| area.style.left = '-9999px'; | ||
| document.body.appendChild(area); | ||
| area.select(); | ||
| try { document.execCommand('copy'); } finally { document.body.removeChild(area); } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Report success only after the clipboard changes. If Based on learnings, async clipboard helpers must expose failures to their callers rather than swallow them. Also applies to: 48-52 🤖 Prompt for AI AgentsSource: Learnings |
||
| } | ||
|
|
||
| function copyText(text) { | ||
| if (navigator.clipboard && window.isSecureContext) { | ||
| return navigator.clipboard.writeText(text).catch(function () { copyWithSelection(text); }); | ||
| } | ||
| copyWithSelection(text); | ||
| return Promise.resolve(); | ||
| } | ||
|
|
||
| document.addEventListener('click', function (event) { | ||
| if (!event.target.closest) return; | ||
|
|
||
| var button = event.target.closest('[data-copy-target]'); | ||
| if (button) { | ||
| var source = document.getElementById(button.getAttribute('data-copy-target')); | ||
| var box = button.closest('[data-copy-event]'); | ||
| if (!source) return; | ||
| // A double-click is one copy, not two copy events. | ||
| var now = Date.now(); | ||
| if (now - (button.copiedAt || 0) < 1000) return; | ||
| button.copiedAt = now; | ||
| var label = button.getAttribute('data-label') || button.textContent; | ||
| copyText(source.textContent).then(function () { | ||
| button.textContent = button.getAttribute('data-copied') || label; | ||
| clearTimeout(button.restoreTimer); | ||
| button.restoreTimer = setTimeout(function () { button.textContent = label; }, 1500); | ||
| }); | ||
| if (box) send(box.getAttribute('data-copy-event'), { method: 'button' }); | ||
| return; | ||
| } | ||
|
|
||
| var a = event.target.closest('a[href]'); | ||
| if (!a) return; | ||
| var url; | ||
| try { url = new URL(a.getAttribute('href'), location.href); } catch (e) { return; } | ||
| var placement = a.closest('.welcome') ? 'hero' : (a.closest('.markdown-body') ? 'content' : 'other'); | ||
| var params = { placement: placement, link_url: url.href }; | ||
| if (url.hostname === 'devops-maturity.github.io' && url.pathname.indexOf('/devops-maturity/') === 0) { | ||
| send('click_docs', params); | ||
| } else if (url.hostname === 'github.com' && /^\/(devops-maturity\/devops-maturity-action|marketplace\/actions\/devops-maturity)(\/|$)/i.test(url.pathname)) { | ||
| params.method = 'link'; | ||
| send('click_action', params); | ||
| } | ||
| }, true); | ||
|
|
||
| // Selecting the text and copying it by hand counts too. | ||
| document.addEventListener('copy', function () { | ||
| var selection = document.getSelection(); | ||
| var node = selection && selection.anchorNode; | ||
| var element = node && (node.nodeType === 1 ? node : node.parentElement); | ||
| var box = element && element.closest && element.closest('[data-copy-event]'); | ||
| if (box) send(box.getAttribute('data-copy-event'), { method: 'select' }); | ||
|
Comment on lines
+92
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Count selection copies only from snippet code. If a visitor selects and copies a label or note, its anchor is still inside 🤖 Prompt for AI Agents |
||
| }); | ||
| })(); | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| // "Try it" block under the home page hero (layouts/partials/welcome.html): | ||
| // the pip command and the GitHub Action step, each with a copy button. | ||
| @use "./../abstracts/index"; | ||
|
|
||
| // The hero is a fixed 80vh; with the snippets it grows instead of overflowing. | ||
| .welcome .welcome__container--try { | ||
| height: auto; | ||
| min-height: index.$welcome-height; | ||
| padding-top: index.$header-height + index.$gap-lg; | ||
| // the article card below is pulled up by $article-offset-top; clear it | ||
| padding-bottom: -(index.$article-offset-top) + index.$gap-lg; | ||
| } | ||
|
|
||
| .welcome__action--primary { | ||
| background-color: index.$color-neutral-light; | ||
| color: index.$color-primary; | ||
| font-weight: bold; | ||
|
|
||
| &:hover { | ||
| background-color: rgba(index.$color-neutral-light, .85); | ||
| color: index.$color-primary; | ||
| } | ||
| } | ||
|
|
||
| .try { | ||
| display: grid; | ||
| gap: index.$gap-md; | ||
| margin-top: index.$gap-sm; | ||
| max-width: 600px; | ||
|
|
||
| @include index.desktop { | ||
| width: 70%; | ||
| } | ||
|
|
||
| &__item { | ||
| display: flex; | ||
| flex-direction: column; | ||
| gap: index.$gap-sm; | ||
| min-width: 0; | ||
| } | ||
|
|
||
| &__label { | ||
| font-size: 14px; | ||
| font-weight: bold; | ||
| opacity: .9; | ||
| } | ||
|
|
||
| &__snippet { | ||
| position: relative; | ||
| display: flex; | ||
| align-items: flex-start; | ||
| gap: index.$gap-sm; | ||
| padding: 12px 12px 12px 16px; | ||
| border-radius: index.$radius-lg; | ||
| background: rgba(index.$color-neutral-dark, .28); | ||
| color: index.$color-neutral-light; | ||
| } | ||
|
|
||
| &__code { | ||
| flex: 1; | ||
| min-width: 0; | ||
| margin: 0; | ||
| font: 14px/1.6 SFMono-Regular, Menlo, Consolas, monospace; | ||
| // wrap long lines on phones instead of a scrollbar; the copy button | ||
| // copies the text as written | ||
| white-space: pre-wrap; | ||
| overflow-wrap: anywhere; | ||
| background: none; | ||
| color: inherit; | ||
| } | ||
|
|
||
| &__copy { | ||
| flex: none; | ||
| padding: 4px 10px; | ||
| border: 1px solid rgba(index.$color-neutral-light, .6); | ||
| border-radius: 50px; | ||
| background: transparent; | ||
| color: index.$color-neutral-light; | ||
| font: inherit; | ||
| font-size: 13px; | ||
| line-height: 1.5; | ||
| cursor: pointer; | ||
|
|
||
| &:hover, | ||
| &:focus-visible { | ||
| background: index.$color-neutral-light; | ||
| color: index.$color-primary; | ||
| } | ||
| } | ||
|
|
||
| &__note { | ||
| font-size: 14px; | ||
| opacity: .9; | ||
|
|
||
| a { | ||
| color: inherit; | ||
| } | ||
| } | ||
| } |
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Clarify the Action snippet’s required workflow setup.
If a visitor copies only this step into a new job, the workflow has no trigger for
devops-maturity.ymlchanges. The Action’s setup also requires checkout and write permissions to update the badge and open a pull request. State that this is a step for an existing configured workflow, or make the copyable example complete. Apply the same correction to both languages. (github.com)Also applies to: 78-80
🤖 Prompt for AI Agents