diff --git a/CHANGELOG.md b/CHANGELOG.md index 318c23241..cb922a62b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ Go to the `v1` branch to see the changelog of Lume 1. // New import { gl } from "npm:date-fns/locale/gl"; ``` +- Allow to get value from attribute in CSS query of `getDataValue()` function. See `metas` plugin for a clear example. ### Fixed - Pages filtered with `filter_pages` plugin are exported to the sitemap. diff --git a/core/utils/data_values.ts b/core/utils/data_values.ts index 650ad905d..aab93522f 100644 --- a/core/utils/data_values.ts +++ b/core/utils/data_values.ts @@ -24,10 +24,7 @@ export function getDataValue(data: Partial, value?: unknown) { } if (value.startsWith("$")) { - const document = data.page?.document; - const query = value.slice(1); - const element = document?.querySelector(query); - return element?.innerHTML; + return queryCss(value, data.page?.document); } } @@ -37,3 +34,18 @@ export function getDataValue(data: Partial, value?: unknown) { return value; } + +function queryCss(value: string, document?: Document) { + // https://regexr.com/7qnot + const checkForAttrPattern = /^\$(.+)\s+(?:attr\(([\w\-]+)\))$/; + const checkResult = value.match(checkForAttrPattern); + + const hasAttr = checkResult?.[0]; + if (hasAttr) { + const [_, query, name] = checkResult; + return document?.querySelector(query)?.getAttribute(name); + } + + const query = value.slice(1); + return document?.querySelector(query)?.innerHTML; +} diff --git a/tests/core/utils/data_values.test.ts b/tests/core/utils/data_values.test.ts new file mode 100644 index 000000000..9b327141a --- /dev/null +++ b/tests/core/utils/data_values.test.ts @@ -0,0 +1,32 @@ +import { assertStrictEquals as equals } from "../../../deps/assert.ts"; +import { getDataValue } from "../../../core/utils/data_values.ts"; +import { build, getSite } from "../../utils.ts"; +import metas from "../../../plugins/metas.ts"; + +Deno.test("Test getDataValue() function", async (t) => { + const site = getSite({ src: "metas" }); + + site.use(metas()); + site.process([".html"], async (pages) => { + for (const page of pages) { + const { data } = page; + if (!data.cover) continue; + + await t.step( + "Data query: =", + () => equals(getDataValue(data, data.metas.image), data.cover), + ); + + await t.step( + "CSS query: $", + () => + equals( + getDataValue(data, '$meta[property="og:image"] attr(content)'), + new URL(site.url(data.cover), site.url(page.data.url, true)).href, + ), + ); + } + }); + + await build(site); +});