From 837f861c1b044ba1de83afb33c00b238a2afbd28 Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Fri, 28 Mar 2025 11:40:18 -0400 Subject: [PATCH 1/2] search - control navbar search crumb merging with configuration --- src/project/types/website/website-search.ts | 8 +++++++- src/resources/editor/tools/vs-code.mjs | 13 ++++++++----- src/resources/editor/tools/yaml/web-worker.js | 13 ++++++++----- .../tools/yaml/yaml-intelligence-resources.json | 13 ++++++++----- src/resources/schema/definitions.yml | 4 ++++ src/resources/schema/json-schemas.json | 3 +++ src/resources/types/schema-types.ts | 1 + 7 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/project/types/website/website-search.ts b/src/project/types/website/website-search.ts index af16f5ba3c6..89b21c61108 100644 --- a/src/project/types/website/website-search.ts +++ b/src/project/types/website/website-search.ts @@ -252,7 +252,13 @@ export async function updateSearchIndex( // link that points to this page / sidebar. If so, inject that level // into the crumbs as well. An attempt at improving #7803 and providing // better crumbs - if (crumbs && sidebar) { + // deno-lint-ignore no-explicit-any + const mergeNavBarSearchCrumbs = (outputFile.format.metadata as any) + ?.website?.search?.["merge-navbar-crumbs"]; + if ( + mergeNavBarSearchCrumbs !== false && + crumbs && sidebar + ) { const navItem = navbarItemForSidebar(sidebar, outputFile.format); if (navItem) { if (typeof navItem === "object") { diff --git a/src/resources/editor/tools/vs-code.mjs b/src/resources/editor/tools/vs-code.mjs index e1b259a61c0..3652d57fe17 100644 --- a/src/resources/editor/tools/vs-code.mjs +++ b/src/resources/editor/tools/vs-code.mjs @@ -9574,6 +9574,11 @@ var require_yaml_intelligence_resources = __commonJS({ schema: "boolean", description: "Provide button for copying search link" }, + "merge-navbar-crumbs": { + schema: "boolean", + default: true, + description: "When false, do not merge navbar crumbs into the crumbs in `search.json`." + }, "keyboard-shortcut": { maybeArrayOf: { string: { @@ -22914,8 +22919,6 @@ var require_yaml_intelligence_resources = __commonJS({ "If true, force the presence of the OJS runtime. If\nfalse, force the absence instead. If unset, the OJS runtime\nis included only if OJS cells are present in the document.", "Use the specified file as a style reference in producing a docx,\npptx, or odt file.", "Branding information to use for this document. If a string, the path\nto a brand file. If false, don\u2019t use branding on this document. If an\nobject, an inline brand definition, or an object with light and dark\nbrand paths or definitions.", - "The path to a light brand file or an inline light brand\ndefinition.", - "The path to a dark brand file or an inline dark brand definition.", "Theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", @@ -24248,12 +24251,12 @@ var require_yaml_intelligence_resources = __commonJS({ mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 196120, + _internalId: 194252, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 196112, + _internalId: 194244, type: "enum", enum: [ "png", @@ -24269,7 +24272,7 @@ var require_yaml_intelligence_resources = __commonJS({ exhaustiveCompletions: true }, theme: { - _internalId: 196119, + _internalId: 194251, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/web-worker.js b/src/resources/editor/tools/yaml/web-worker.js index d666a0a15db..8eb91e50487 100644 --- a/src/resources/editor/tools/yaml/web-worker.js +++ b/src/resources/editor/tools/yaml/web-worker.js @@ -9575,6 +9575,11 @@ try { schema: "boolean", description: "Provide button for copying search link" }, + "merge-navbar-crumbs": { + schema: "boolean", + default: true, + description: "When false, do not merge navbar crumbs into the crumbs in `search.json`." + }, "keyboard-shortcut": { maybeArrayOf: { string: { @@ -22915,8 +22920,6 @@ try { "If true, force the presence of the OJS runtime. If\nfalse, force the absence instead. If unset, the OJS runtime\nis included only if OJS cells are present in the document.", "Use the specified file as a style reference in producing a docx,\npptx, or odt file.", "Branding information to use for this document. If a string, the path\nto a brand file. If false, don\u2019t use branding on this document. If an\nobject, an inline brand definition, or an object with light and dark\nbrand paths or definitions.", - "The path to a light brand file or an inline light brand\ndefinition.", - "The path to a dark brand file or an inline dark brand definition.", "Theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", @@ -24249,12 +24252,12 @@ try { mermaid: "%%" }, "handlers/mermaid/schema.yml": { - _internalId: 196120, + _internalId: 194252, type: "object", description: "be an object", properties: { "mermaid-format": { - _internalId: 196112, + _internalId: 194244, type: "enum", enum: [ "png", @@ -24270,7 +24273,7 @@ try { exhaustiveCompletions: true }, theme: { - _internalId: 196119, + _internalId: 194251, type: "anyOf", anyOf: [ { diff --git a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json index 663646e453a..9ef575dc130 100644 --- a/src/resources/editor/tools/yaml/yaml-intelligence-resources.json +++ b/src/resources/editor/tools/yaml/yaml-intelligence-resources.json @@ -2546,6 +2546,11 @@ "schema": "boolean", "description": "Provide button for copying search link" }, + "merge-navbar-crumbs": { + "schema": "boolean", + "default": true, + "description": "When false, do not merge navbar crumbs into the crumbs in `search.json`." + }, "keyboard-shortcut": { "maybeArrayOf": { "string": { @@ -15886,8 +15891,6 @@ "If true, force the presence of the OJS runtime. If\nfalse, force the absence instead. If unset, the OJS runtime\nis included only if OJS cells are present in the document.", "Use the specified file as a style reference in producing a docx,\npptx, or odt file.", "Branding information to use for this document. If a string, the path\nto a brand file. If false, don’t use branding on this document. If an\nobject, an inline brand definition, or an object with light and dark\nbrand paths or definitions.", - "The path to a light brand file or an inline light brand\ndefinition.", - "The path to a dark brand file or an inline dark brand definition.", "Theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", "The light theme name, theme scss file, or a mix of both.", @@ -17220,12 +17223,12 @@ "mermaid": "%%" }, "handlers/mermaid/schema.yml": { - "_internalId": 196120, + "_internalId": 194252, "type": "object", "description": "be an object", "properties": { "mermaid-format": { - "_internalId": 196112, + "_internalId": 194244, "type": "enum", "enum": [ "png", @@ -17241,7 +17244,7 @@ "exhaustiveCompletions": true }, "theme": { - "_internalId": 196119, + "_internalId": 194251, "type": "anyOf", "anyOf": [ { diff --git a/src/resources/schema/definitions.yml b/src/resources/schema/definitions.yml index 6fe40176b5c..6aa7c641924 100644 --- a/src/resources/schema/definitions.yml +++ b/src/resources/schema/definitions.yml @@ -858,6 +858,10 @@ copy-button: schema: boolean description: "Provide button for copying search link" + merge-navbar-crumbs: + schema: boolean + default: true + description: "When false, do not merge navbar crumbs into the crumbs in `search.json`." keyboard-shortcut: maybeArrayOf: string: diff --git a/src/resources/schema/json-schemas.json b/src/resources/schema/json-schemas.json index 06040e4dcaf..f4370923cd2 100644 --- a/src/resources/schema/json-schemas.json +++ b/src/resources/schema/json-schemas.json @@ -935,6 +935,9 @@ "copy-button": { "type": "boolean" }, + "merge-navbar-crumbs": { + "type": "boolean" + }, "keyboard-shortcut": { "anyOf": [ { diff --git a/src/resources/types/schema-types.ts b/src/resources/types/schema-types.ts index 1d95382ed38..0b71fd55794 100644 --- a/src/resources/types/schema-types.ts +++ b/src/resources/types/schema-types.ts @@ -513,6 +513,7 @@ The user’s cookie preferences will automatically control Google Analytics (if search?: boolean | { "collapse-after"?: number; "copy-button"?: boolean; + "merge-navbar-crumbs"?: boolean; "keyboard-shortcut"?: MaybeArrayOf< string /* One or more keys that will act as a shortcut to launch search (single characters) */ >; From df3b8799eb0da359180c5369429efaafa37fb25e Mon Sep 17 00:00:00 2001 From: Carlos Scheidegger Date: Fri, 28 Mar 2025 11:54:43 -0400 Subject: [PATCH 2/2] test for feature --- .../.gitignore | 1 + .../_quarto.yml | 25 +++++++++ .../about.qmd | 5 ++ .../index.qmd | 7 +++ .../styles.css | 1 + tests/smoke/project/project-website.test.ts | 52 ++++++++++++++++--- 6 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 tests/docs/websites/search/merge-navbar-crumbs-configuration/.gitignore create mode 100644 tests/docs/websites/search/merge-navbar-crumbs-configuration/_quarto.yml create mode 100644 tests/docs/websites/search/merge-navbar-crumbs-configuration/about.qmd create mode 100644 tests/docs/websites/search/merge-navbar-crumbs-configuration/index.qmd create mode 100644 tests/docs/websites/search/merge-navbar-crumbs-configuration/styles.css diff --git a/tests/docs/websites/search/merge-navbar-crumbs-configuration/.gitignore b/tests/docs/websites/search/merge-navbar-crumbs-configuration/.gitignore new file mode 100644 index 00000000000..075b2542afb --- /dev/null +++ b/tests/docs/websites/search/merge-navbar-crumbs-configuration/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/tests/docs/websites/search/merge-navbar-crumbs-configuration/_quarto.yml b/tests/docs/websites/search/merge-navbar-crumbs-configuration/_quarto.yml new file mode 100644 index 00000000000..39c708e6b96 --- /dev/null +++ b/tests/docs/websites/search/merge-navbar-crumbs-configuration/_quarto.yml @@ -0,0 +1,25 @@ +project: + type: website + +website: + title: "merge-navbar-crumbs-configuration" + navbar: + left: + - href: index.qmd + text: Home + - about.qmd + sidebar: + - contents: + - section: "Level 1" + contents: + - text: "Level 2" + href: index.qmd + search: + merge-navbar-crumbs: false +format: + html: + theme: + - cosmo + - brand + css: styles.css + toc: true diff --git a/tests/docs/websites/search/merge-navbar-crumbs-configuration/about.qmd b/tests/docs/websites/search/merge-navbar-crumbs-configuration/about.qmd new file mode 100644 index 00000000000..07c5e7f9d13 --- /dev/null +++ b/tests/docs/websites/search/merge-navbar-crumbs-configuration/about.qmd @@ -0,0 +1,5 @@ +--- +title: "About" +--- + +About this site diff --git a/tests/docs/websites/search/merge-navbar-crumbs-configuration/index.qmd b/tests/docs/websites/search/merge-navbar-crumbs-configuration/index.qmd new file mode 100644 index 00000000000..ecdca221270 --- /dev/null +++ b/tests/docs/websites/search/merge-navbar-crumbs-configuration/index.qmd @@ -0,0 +1,7 @@ +--- +title: "merge-navbar-crumbs-configuration" +--- + +This is a Quarto website. + +To learn more about Quarto websites visit . diff --git a/tests/docs/websites/search/merge-navbar-crumbs-configuration/styles.css b/tests/docs/websites/search/merge-navbar-crumbs-configuration/styles.css new file mode 100644 index 00000000000..2ddf50c7b42 --- /dev/null +++ b/tests/docs/websites/search/merge-navbar-crumbs-configuration/styles.css @@ -0,0 +1 @@ +/* css styles */ diff --git a/tests/smoke/project/project-website.test.ts b/tests/smoke/project/project-website.test.ts index b850e4807e7..9e6dceed70a 100644 --- a/tests/smoke/project/project-website.test.ts +++ b/tests/smoke/project/project-website.test.ts @@ -1,15 +1,14 @@ /* -* project-website.test.ts -* -* Copyright (C) 2020-2022 Posit Software, PBC -* -*/ + * project-website.test.ts + * + * Copyright (C) 2020-2022 Posit Software, PBC + */ import { existsSync } from "../../../src/deno_ral/fs.ts"; import { join } from "../../../src/deno_ral/path.ts"; import { Metadata } from "../../../src/config/types.ts"; -import { testQuartoCmd, Verify } from "../../test.ts"; +import { ExecuteOutput, testQuartoCmd, Verify } from "../../test.ts"; import { docs } from "../../utils.ts"; import { directoryEmptyButFor, @@ -22,6 +21,7 @@ import { kProjectWorkingDir, kQuartoProjectFile, } from "./common.ts"; +import { assert } from "testing/asserts"; // A website project testQuartoCmd( @@ -32,7 +32,7 @@ testQuartoCmd( fileExists(join(kProjectWorkingDir, "index.qmd")), verifyYamlFile( kQuartoProjectFile, - ((yaml: unknown) => { + (yaml: unknown) => { // Make sure there is a project yaml section const metadata = yaml as Metadata; if ( @@ -43,7 +43,7 @@ testQuartoCmd( } else { return false; } - }), + }, ), ], { @@ -86,3 +86,39 @@ testQuartoCmd( }, }, ); + +const mergeNavbarCrumbsConfigSite = docs( + "websites/search/merge-navbar-crumbs-configuration", +); +const mergeNavbarCrumbsConfigSiteOutDir = join(mergeNavbarCrumbsConfigSite, outDir); +testQuartoCmd( + "render", + [mergeNavbarCrumbsConfigSite], + [ + { + name: "verify-no-navbar-crumbs-in-searchjson", + verify: async (outputs: ExecuteOutput[]) => { + // Verify that the search.json file does not contain any navbar breadcrumbs + const searchJson = join(mergeNavbarCrumbsConfigSite, "_site", "search.json"); + const searchJsonExists = existsSync(searchJson); + if (!searchJsonExists) { + throw new Error(`File ${searchJson} does not exist`); + } + const searchJsonContent = await Deno.readTextFile(searchJson); + const json = JSON.parse(searchJsonContent); + for (const entry of json) { + if (entry.crumbs) { + assert(entry.crumbs[0] !== "Home"); + } + } + }, + }, + ], + { + teardown: async () => { + if (existsSync(mergeNavbarCrumbsConfigSiteOutDir)) { + await Deno.remove(mergeNavbarCrumbsConfigSiteOutDir, { recursive: true }); + } + }, + }, +);