0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-03-24 23:21:57 -05:00

feat(sitemap): add xslURL to enable styling (#11485)

* feat(sitemap): add xslURL to enable styling

* Add test

* Update .changeset/proud-horses-cry.md

---------

Co-authored-by: bluwy <bjornlu.dev@gmail.com>
Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
This commit is contained in:
Sondre Aasemoen 2024-10-03 10:01:42 +02:00 committed by GitHub
parent 42037f33e6
commit fbe1bc51d8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 36 additions and 7 deletions

View file

@ -0,0 +1,5 @@
---
'@astrojs/sitemap': minor
---
Adds new `xslURL` option to enable styling of sitemaps

View file

@ -88,7 +88,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
const { filter, customPages, serialize, entryLimit } = opts;
let finalSiteUrl = new URL(config.base, config.site);
const finalSiteUrl = new URL(config.base, config.site);
const shouldIgnoreStatus = isStatusCodePage(Object.keys(opts.i18n?.locales ?? {}));
let pageUrls = pages
.filter((p) => !shouldIgnoreStatus(p.pathname))
@ -100,7 +100,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
return new URL(fullPath, finalSiteUrl).href;
});
let routeUrls = routes.reduce<string[]>((urls, r) => {
const routeUrls = routes.reduce<string[]>((urls, r) => {
// Only expose pages, not endpoints or redirects
if (r.type !== 'page') return urls;
@ -116,7 +116,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
if (fullPath.endsWith('/')) fullPath += r.generate(r.pathname).substring(1);
else fullPath += r.generate(r.pathname);
let newUrl = new URL(fullPath, finalSiteUrl).href;
const newUrl = new URL(fullPath, finalSiteUrl).href;
if (config.trailingSlash === 'never') {
urls.push(newUrl);
@ -168,6 +168,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
}
}
const destDir = fileURLToPath(dir);
const xslURL = opts.xslURL ? new URL(opts.xslURL, finalSiteUrl).href : undefined;
await writeSitemap(
{
hostname: finalSiteUrl.href,
@ -175,6 +176,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
publicBasePath: config.base,
sourceData: urlData,
limit: entryLimit,
xslURL: xslURL,
},
config,
);

View file

@ -9,6 +9,7 @@ export const SitemapOptionsSchema = z
filter: z.function().args(z.string()).returns(z.boolean()).optional(),
customPages: z.string().url().array().optional(),
canonicalURL: z.string().url().optional(),
xslURL: z.string().optional(),
i18n: z
.object({

View file

@ -17,6 +17,7 @@ type WriteSitemapConfig = {
destinationDir: string;
publicBasePath?: string;
limit?: number;
xslURL?: string;
};
// adapted from sitemap.js/sitemap-simple
@ -28,6 +29,7 @@ export async function writeSitemap(
destinationDir,
limit = 50000,
publicBasePath = './',
xslURL: xslUrl,
}: WriteSitemapConfig,
astroConfig: AstroConfig,
) {
@ -38,6 +40,7 @@ export async function writeSitemap(
getSitemapStream: (i) => {
const sitemapStream = new SitemapStream({
hostname,
xslUrl,
});
const path = `./sitemap-${i}.xml`;
const writePath = resolve(destinationDir, path);
@ -63,7 +66,7 @@ export async function writeSitemap(
},
});
let src = Readable.from(sourceData);
const src = Readable.from(sourceData);
const indexPath = resolve(destinationDir, `./sitemap-index.xml`);
return promisify(pipeline)(src, sitemapAndIndexStream, createWriteStream(indexPath));
}

View file

@ -3,7 +3,7 @@ import { before, describe, it } from 'node:test';
import { sitemap } from './fixtures/static/deps.mjs';
import { loadFixture, readXML } from './test-utils.js';
describe('Filter support', () => {
describe('Config', () => {
/** @type {import('./test-utils.js').Fixture} */
let fixture;
@ -14,17 +14,26 @@ describe('Filter support', () => {
integrations: [
sitemap({
filter: (page) => page === 'http://example.com/one/',
xslURL: '/sitemap.xsl',
}),
],
});
await fixture.build();
});
it('Just one page is added', async () => {
it('filter: Just one page is added', async () => {
const data = await readXML(fixture.readFile('/sitemap-0.xml'));
const urls = data.urlset.url;
assert.equal(urls.length, 1);
});
it('xslURL: Includes xml-stylsheet', async () => {
const xml = await fixture.readFile('/sitemap-0.xml');
assert.ok(
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
xml,
);
});
});
describe('SSR', () => {
@ -34,16 +43,25 @@ describe('Filter support', () => {
integrations: [
sitemap({
filter: (page) => page === 'http://example.com/one/',
xslURL: '/sitemap.xsl',
}),
],
});
await fixture.build();
});
it('Just one page is added', async () => {
it('filter: Just one page is added', async () => {
const data = await readXML(fixture.readFile('/client/sitemap-0.xml'));
const urls = data.urlset.url;
assert.equal(urls.length, 1);
});
it('xslURL: Includes xml-stylsheet', async () => {
const xml = await fixture.readFile('/client/sitemap-0.xml');
assert.ok(
xml.includes('<?xml-stylesheet type="text/xsl" href="http://example.com/sitemap.xsl"?>'),
xml,
);
});
});
});