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:
parent
42037f33e6
commit
fbe1bc51d8
5 changed files with 36 additions and 7 deletions
5
.changeset/proud-horses-cry.md
Normal file
5
.changeset/proud-horses-cry.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/sitemap': minor
|
||||
---
|
||||
|
||||
Adds new `xslURL` option to enable styling of sitemaps
|
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Add table
Reference in a new issue