diff --git a/src/project/types/website/website-search.ts b/src/project/types/website/website-search.ts
index af16f5ba3c..89b21c6110 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 e1b259a61c..3652d57fe1 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 d666a0a15d..8eb91e5048 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 663646e453..9ef575dc13 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 6fe40176b5..6aa7c64192 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 06040e4dca..f4370923cd 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 1d95382ed3..0b71fd5579 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) */
>;
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 0000000000..075b2542af
--- /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 0000000000..39c708e6b9
--- /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 0000000000..07c5e7f9d1
--- /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 0000000000..ecdca22127
--- /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 0000000000..2ddf50c7b4
--- /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 b850e4807e..9e6dceed70 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 });
+ }
+ },
+ },
+);