diff --git a/news/changelog-1.7.md b/news/changelog-1.7.md index b4a259c006d..a4f29af34e9 100644 --- a/news/changelog-1.7.md +++ b/news/changelog-1.7.md @@ -17,6 +17,10 @@ All changes included in 1.7: - ([#11701](https://github.com/quarto-dev/quarto-cli/issues/11701)): Wrap HTML emitted by EJS templates in `{=html}` blocks to avoid memory blowup issues with Pandoc's parser. +## Blog projects + +- ([#11745](https://github.com/quarto-dev/quarto-cli/issues/11745)): Fix categories links under post title in post with url encoded path (e.g. with space or other special characters). + ## Book projects - ([#11520](https://github.com/quarto-dev/quarto-cli/issues/11520)): Book's cover image now escapes lightbox treatment, which was incorrectly applied to it when `lightbox: true` was set in the book's configuration. diff --git a/src/resources/formats/html/quarto.js b/src/resources/formats/html/quarto.js index f49812ebcbc..a71a420fce5 100644 --- a/src/resources/formats/html/quarto.js +++ b/src/resources/formats/html/quarto.js @@ -238,9 +238,10 @@ window.document.addEventListener("DOMContentLoaded", function (_event) { for (const listingPath of listingPaths) { const pathWithoutLeadingSlash = listingPath.listing.substring(1); for (const item of listingPath.items) { + const encodedItem = encodeURI(item); if ( - item === currentPagePath || - item === currentPagePath + "index.html" + encodedItem === currentPagePath || + encodedItem === currentPagePath + "index.html" ) { // Resolve this path against the offset to be sure // we already are using the correct path to the listing diff --git a/tests/docs/playwright/blog/simple-blog/posts/post with space/image.jpg b/tests/docs/playwright/blog/simple-blog/posts/post with space/image.jpg new file mode 100644 index 00000000000..5d5ad1f4d2e Binary files /dev/null and b/tests/docs/playwright/blog/simple-blog/posts/post with space/image.jpg differ diff --git a/tests/docs/playwright/blog/simple-blog/posts/post with space/index.qmd b/tests/docs/playwright/blog/simple-blog/posts/post with space/index.qmd new file mode 100644 index 00000000000..006bd1211fe --- /dev/null +++ b/tests/docs/playwright/blog/simple-blog/posts/post with space/index.qmd @@ -0,0 +1,13 @@ +--- +title: "testing post with space" +author: "Harlow Malloc" +date: "2024-12-28" +categories: [news, code, analysis] +image: "image.jpg" +--- + +This is a post folder name with space + +```{r} +1 + 1 +``` diff --git a/tests/docs/playwright/blog/simple-blog/posts2/post with space/image.jpg b/tests/docs/playwright/blog/simple-blog/posts2/post with space/image.jpg new file mode 100644 index 00000000000..5d5ad1f4d2e Binary files /dev/null and b/tests/docs/playwright/blog/simple-blog/posts2/post with space/image.jpg differ diff --git a/tests/docs/playwright/blog/simple-blog/posts2/post with space/index.qmd b/tests/docs/playwright/blog/simple-blog/posts2/post with space/index.qmd new file mode 100644 index 00000000000..006bd1211fe --- /dev/null +++ b/tests/docs/playwright/blog/simple-blog/posts2/post with space/index.qmd @@ -0,0 +1,13 @@ +--- +title: "testing post with space" +author: "Harlow Malloc" +date: "2024-12-28" +categories: [news, code, analysis] +image: "image.jpg" +--- + +This is a post folder name with space + +```{r} +1 + 1 +``` diff --git a/tests/docs/playwright/blog/simple-blog/posts3/post with space/image.jpg b/tests/docs/playwright/blog/simple-blog/posts3/post with space/image.jpg new file mode 100644 index 00000000000..5d5ad1f4d2e Binary files /dev/null and b/tests/docs/playwright/blog/simple-blog/posts3/post with space/image.jpg differ diff --git a/tests/docs/playwright/blog/simple-blog/posts3/post with space/index.qmd b/tests/docs/playwright/blog/simple-blog/posts3/post with space/index.qmd new file mode 100644 index 00000000000..006bd1211fe --- /dev/null +++ b/tests/docs/playwright/blog/simple-blog/posts3/post with space/index.qmd @@ -0,0 +1,13 @@ +--- +title: "testing post with space" +author: "Harlow Malloc" +date: "2024-12-28" +categories: [news, code, analysis] +image: "image.jpg" +--- + +This is a post folder name with space + +```{r} +1 + 1 +``` diff --git a/tests/integration/playwright/tests/blog-simple-blog.spec.ts b/tests/integration/playwright/tests/blog-simple-blog.spec.ts index 01981c6e0b8..ed6151acc5b 100644 --- a/tests/integration/playwright/tests/blog-simple-blog.spec.ts +++ b/tests/integration/playwright/tests/blog-simple-blog.spec.ts @@ -28,40 +28,41 @@ Object.entries(testPages).forEach(([postDir, pageName]) => { await expect(page.getByRole('link', { name: 'Welcome To My Blog' })).toBeHidden(); }); - const checkCategoryLink = async (page: Page, category: string, pageName: string) => { + const checkCategoryLink = async (page: Page, category: string, pageName: string, postTitle: string) => { await page.getByText(category, { exact: true }).click(); await expect(page).toHaveURL(getUrl(`blog/simple-blog/_site/${pageName}#category=${encodeURIComponent(category)}`)); await expect(page.locator(`div.category[data-category="${btoa(encodeURIComponent(category))}"]`)).toHaveClass(/active/); + await expect(page.getByRole('link', { name: postTitle })).toBeVisible(); }; test(`All Categories links are clickable ${postDir} pages`, async ({ page }) => { // Checking link is working await page.goto(`./blog/simple-blog/_site/${postDir}/welcome/`); - await checkCategoryLink(page, 'news', pageName); + await checkCategoryLink(page, 'news', pageName, 'Welcome To My Blog'); // Including for special characters await page.getByRole('link', { name: 'Welcome To My Blog' }).click(); - await checkCategoryLink(page, 'euros (€)', pageName); + await checkCategoryLink(page, 'euros (€)', pageName, 'Welcome To My Blog'); await page.getByRole('link', { name: 'Welcome To My Blog' }).click(); - await checkCategoryLink(page, '免疫', pageName); + await checkCategoryLink(page, '免疫', pageName, 'Welcome To My Blog'); await page.goto(`./blog/simple-blog/_site/${postDir}/post-with-code/`); - await checkCategoryLink(page, "apos'trophe", pageName); + await checkCategoryLink(page, "apos'trophe", pageName, 'Post With Code'); // special check for when a page is not loaded from non root path await page.goto(`./blog/simple-blog/_site/${postDir}/welcome/#img-lst`); - await checkCategoryLink(page, 'news', pageName); + await checkCategoryLink(page, 'news', pageName, 'Welcome To My Blog'); + // special check for post with space in page name + await page.goto(`./blog/simple-blog/_site/${postDir}/post with space/`); + await checkCategoryLink(page, 'news', pageName, 'testing post with space'); }); if (pageName !== 'table.html') { test(`Categories link on listing page works for ${pageName}`, async ({ page }) => { await page.goto(`./blog/simple-blog/_site/${pageName}`); - await checkCategoryLink(page, 'apos\'trophe', pageName); - await expect(page.getByRole('link', { name: 'Post With Code' })).toBeVisible(); + await checkCategoryLink(page, 'apos\'trophe', pageName, 'Post With Code'); await page.goto(`./blog/simple-blog/_site/${pageName}`); - await checkCategoryLink(page, 'euros (€)', pageName); - await expect(page.getByRole('link', { name: 'Welcome To My Blog' })).toBeVisible(); + await checkCategoryLink(page, 'euros (€)', pageName, 'Welcome To My Blog'); await page.goto(`./blog/simple-blog/_site/${pageName}`); - await checkCategoryLink(page, '免疫', pageName); - await expect(page.getByRole('link', { name: 'Welcome To My Blog' })).toBeVisible(); + await checkCategoryLink(page, '免疫', pageName, 'Welcome To My Blog'); }); } });