Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/changelog-1.11.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ All changes included in 1.11:
- ([#15004](https://github.com/quarto-dev/quarto-cli/issues/15004)): Fix notebook preview pages and notebook sources missing from the output directory when a website with embedded notebooks is rendered from a directory other than the project directory.
- ([#15022](https://github.com/quarto-dev/quarto-cli/issues/15022)): Fix rendering a listing with a `feed` failing on Windows with `os error 123` when a listing item's `image` or the feed `image` is a web URL. The image URL is used as is in the feed and no local size lookup is attempted. (author: @Masad791)
- ([#15032](https://github.com/quarto-dev/quarto-cli/pull/15032)): Fix the listing feed `image` missing its height and width when a website is rendered from a directory other than the project directory, or when the image path starts with `/`.
- ([#15039](https://github.com/quarto-dev/quarto-cli/issues/15039)): Fix the open graph and twitter card image of website pages in subdirectories pointing to a missing file when the image comes from a relative `website: image:`, `open-graph: image:` or `twitter-card: image:` under `website:`, and the listing feed image pointing to a missing file when it comes from the `image` of a listing page in a subdirectory. A project relative image path starting with `/` no longer gives a doubled `/` in these URLs when `site-url` ends with `/`.
- ([#15044](https://github.com/quarto-dev/quarto-cli/issues/15044)): Fix a YAML file listed next to a folder in a listing's `contents` being left out, or another file being used, when a website is rendered from a directory other than the listing page's directory.
- ([#15050](https://github.com/quarto-dev/quarto-cli/pull/15050)): Support JPEG images when adding image height and width to the listing feed `image`, feed item media, and `og:image` and `twitter:image` metadata. Image files are now detected by content rather than file extension, so an uppercase `.PNG` is measured too.

Expand Down
9 changes: 7 additions & 2 deletions src/project/types/website/listing/website-listing-feed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Copyright (C) 2020-2022 Posit Software, PBC
*/

import { join, relative } from "../../../../deno_ral/path.ts";
import { dirname, join, relative } from "../../../../deno_ral/path.ts";
import { warning } from "../../../../deno_ral/log.ts";
import { Document } from "deno_dom/deno-dom-wasm-noinit.ts";

Expand All @@ -16,6 +16,7 @@ import { quartoConfig } from "../../../../core/quarto.ts";
import { resourcePath } from "../../../../core/resources.ts";
import { ProjectContext } from "../../../types.ts";
import { kImage } from "../website-constants.ts";
import { projectRelativeHref } from "../website-shared.ts";
import {
websiteBaseurl,
websiteDescription,
Expand Down Expand Up @@ -167,7 +168,11 @@ export async function createFeed(
};

// Add any image metadata
const image = options.image || format.metadata[kImage] as string ||
// The page image is relative to the listing document, the others to the project
const pageImage = format.metadata[kImage] as string | undefined;
const image = options.image ||
(pageImage &&
projectRelativeHref(pageImage, dirname(relative(project.dir, source)))) ||
websiteImage(project.config)?.src;
if (image) {
feed.image = {
Expand Down
18 changes: 2 additions & 16 deletions src/project/types/website/listing/website-listing-read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ import {
kListingPageFieldTitle,
kListingPageFieldWordCount,
} from "../../../../config/constants.ts";
import { isAbsoluteRef } from "../../../../core/http.ts";
import { projectRelativeHref } from "../website-shared.ts";
import { isYamlPath, readYaml } from "../../../../core/yaml.ts";
import { parseAuthor } from "../../../../core/author.ts";
import { parsePandocDate, resolveDate } from "../../../../core/date.ts";
Expand Down Expand Up @@ -1148,9 +1148,7 @@ async function listItemFromFile(

const imageRaw = documentMeta?.image as string | boolean;
const image = imageRaw !== undefined && typeof imageRaw === "string"
? pathWithForwardSlashes(
listingItemHref(imageRaw, dirname(projectRelativePath)),
)
? projectRelativeHref(imageRaw, dirname(projectRelativePath))
: undefined;

const imageAlt = documentMeta?.[kImageAlt] as string | undefined;
Expand Down Expand Up @@ -1430,18 +1428,6 @@ function fileModifiedDate(input: string) {
}
}

function listingItemHref(path: string, projectRelativePath: string) {
if (isAbsoluteRef(path) || path.startsWith("/")) {
// This is a project relative or absolute href, just
// leave it alone
return path;
} else {
// This is a document relative path, need to fix it up
// to be project relative
return join("/", projectRelativePath, path);
}
}

function expandGlob(
source: string,
project: ProjectContext,
Expand Down
41 changes: 30 additions & 11 deletions src/project/types/website/website-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
kTwitterSite,
kWebsite,
} from "./website-constants.ts";
import { computePageTitle } from "./website-shared.ts";
import { computePageTitle, projectRelativeHref } from "./website-shared.ts";
import {
createMarkdownPipeline,
MarkdownPipeline,
Expand Down Expand Up @@ -181,7 +181,14 @@ export function metadataHtmlPostProcessor(
// find a preview image if one is not provided
if (metadata[kImage] === undefined && format.metadata[kImage] !== false) {
const pagePreviewImg = findPreviewImg(doc);
const previewImg = pagePreviewImg || websiteImage(project.config);
let previewImg = pagePreviewImg;
if (!previewImg) {
// The site image is written in _quarto.yml, so it is project relative
const siteImg = websiteImage(project.config);
previewImg = siteImg && siteMeta?.[kSiteUrl] !== undefined
? { ...siteImg, src: projectRelativeHref(siteImg.src, ".") }
: siteImg;
}
metadata[kImage] = previewImg ? previewImg.src : undefined;
metadata[kImageAlt] = previewImg ? previewImg.alt : undefined;
if (pagePreviewImg && provider.key === kOpenGraph) {
Expand Down Expand Up @@ -383,20 +390,32 @@ function mergedSiteAndDocumentData(
? format.metadata[key]
: false;

if (typeof siteMetadata === "object" && format.metadata[kImage]) {
const siteMeta = siteMetadata as Metadata;
siteMeta[kImage] = format.metadata[kImage];
// Work on a copy: the site metadata is shared by every page
let siteObject: Metadata | undefined;
if (typeof siteMetadata === "object") {
siteObject = { ...(siteMetadata as Metadata) };
if (format.metadata[kImage]) {
siteObject[kImage] = format.metadata[kImage];
} else if (
typeof siteObject[kImage] === "string" &&
siteData[kSiteUrl] !== undefined
) {
// The site image is written in _quarto.yml, so it is project relative
siteObject[kImage] = projectRelativeHref(
siteObject[kImage] as string,
".",
);
}
}
if (
typeof siteMetadata === "object" &&
typeof docMetadata === "object"
) {
if (siteObject && typeof docMetadata === "object") {
return mergeConfigs(
siteMetadata,
siteObject,
docMetadata,
) as Metadata;
} else if (docMetadata !== false) {
return docMetadata as boolean | Metadata;
} else if (siteObject) {
return siteObject;
} else if (siteMetadata !== false) {
return siteMetadata as boolean | Metadata;
} else {
Expand Down Expand Up @@ -424,7 +443,7 @@ function imageMetadata(
// read the image size
return {
path: image,
href: `${baseUrl}${image}`,
href: joinUrl(baseUrl, image),
height: size?.height,
width: size?.width,
};
Expand Down
13 changes: 13 additions & 0 deletions src/project/types/website/website-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { join } from "../../../deno_ral/path.ts";
import * as ld from "../../../core/lodash.ts";

import { dirAndStem, pathWithForwardSlashes } from "../../../core/path.ts";
import { isAbsoluteRef } from "../../../core/http.ts";

import {
NavigationItemObject,
Expand Down Expand Up @@ -114,6 +115,18 @@ export function computePageTitle(
}
}

// Gives a project relative href (leading `/`) for a path written in a document
// in `documentDir` (project relative). Paths that already start with `/` are
// kept, URLs are returned as is.
export function projectRelativeHref(href: string, documentDir: string) {
if (isAbsoluteRef(href)) {
return href;
}
return pathWithForwardSlashes(
href.startsWith("/") ? href : join("/", documentDir, href),
);
}

export function inputFileHref(href: string) {
const [hrefDir, hrefStem] = dirAndStem(href);
const htmlHref = "/" + join(hrefDir, `${hrefStem}.html`);
Expand Down
14 changes: 7 additions & 7 deletions src/resources/editor/tools/vs-code.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10145,7 +10145,7 @@ var require_yaml_intelligence_resources = __commonJS({
},
image: {
path: {
description: "Default site thumbnail image for `twitter` /`open-graph`\n"
description: "Default site thumbnail image for `twitter` /`open-graph`, relative to the project directory.\n"
}
},
"image-alt": {
Expand Down Expand Up @@ -10814,7 +10814,7 @@ var require_yaml_intelligence_resources = __commonJS({
path: {
description: {
short: "The path to an image for this feed.",
long: "The path to an image for this feed. If not specified, the image for the page the listing \nappears on will be used, otherwise an image will be used if specified for the site \nin the Quarto project.\n"
long: "The path to an image for this feed. If not specified, the image for the page the listing \nappears on will be used, otherwise an image will be used if specified for the site \nin the Quarto project. A relative path set in the listing page front matter is relative to the project directory.\n"
}
}
},
Expand Down Expand Up @@ -22351,7 +22351,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Provide a \u2018back to top\u2019 navigation button",
"Whether to show navigation breadcrumbs for pages more than 1 level\ndeep",
"Shared page footer",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>, relative to the project directory.",
"Default site thumbnail image alt text for <code>twitter</code>\n/<code>open-graph</code>",
"Publish open graph metadata",
"Publish twitter card metadata",
Expand Down Expand Up @@ -22518,7 +22518,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Provide a \u2018back to top\u2019 navigation button",
"Whether to show navigation breadcrumbs for pages more than 1 level\ndeep",
"Shared page footer",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>, relative to the project directory.",
"Default site thumbnail image alt text for <code>twitter</code>\n/<code>open-graph</code>",
"Publish open graph metadata",
"Publish twitter card metadata",
Expand Down Expand Up @@ -22627,7 +22627,7 @@ var require_yaml_intelligence_resources = __commonJS({
},
{
short: "The path to an image for this feed.",
long: "The path to an image for this feed. If not specified, the image for\nthe page the listing appears on will be used, otherwise an image will be\nused if specified for the site in the Quarto project."
long: "The path to an image for this feed. If not specified, the image for\nthe page the listing appears on will be used, otherwise an image will be\nused if specified for the site in the Quarto project. A relative path\nset in the listing page front matter is relative to the project\ndirectory."
},
{
short: "The description of this feed.",
Expand Down Expand Up @@ -24965,7 +24965,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Provide a \u2018back to top\u2019 navigation button",
"Whether to show navigation breadcrumbs for pages more than 1 level\ndeep",
"Shared page footer",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>, relative to the project directory.",
"Default site thumbnail image alt text for <code>twitter</code>\n/<code>open-graph</code>",
"Publish open graph metadata",
"Publish twitter card metadata",
Expand Down Expand Up @@ -25318,7 +25318,7 @@ var require_yaml_intelligence_resources = __commonJS({
"Provide a \u2018back to top\u2019 navigation button",
"Whether to show navigation breadcrumbs for pages more than 1 level\ndeep",
"Shared page footer",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>",
"Default site thumbnail image for <code>twitter</code>\n/<code>open-graph</code>, relative to the project directory.",
"Default site thumbnail image alt text for <code>twitter</code>\n/<code>open-graph</code>",
"Publish open graph metadata",
"Publish twitter card metadata",
Expand Down

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions src/resources/editor/tools/yaml/web-worker.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading