58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
|
|
import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces';
|
|
import { create as create_xml } from 'xmlbuilder2';
|
|
import { BuildState } from './state';
|
|
import { write_text } from '../fs';
|
|
import { resolve as path_resolve } from 'path';
|
|
|
|
export async function write_sitemap_if_needed(state: BuildState) {
|
|
if (! state.conf.sitemap) {
|
|
return;
|
|
}
|
|
|
|
const doc = create_xml({ version: '1.0', encoding: 'UTF-8' });
|
|
const urlset = doc.ele('urlset', {
|
|
'xmlns': 'http://www.sitemaps.org/schemas/sitemap/0.9',
|
|
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
'xsi:schemaLocation': 'http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd'
|
|
});
|
|
|
|
for (const entry of state.sitemap) {
|
|
url_elem(urlset, entry.url, entry.lastmod, entry.change_freq, entry.priority);
|
|
}
|
|
|
|
const out_file = state.conf.sitemap.out_file || path_resolve(state.conf.output.root, 'sitemap.xml');
|
|
const xml = doc.toString({
|
|
indent: ' ',
|
|
prettyPrint: true,
|
|
});
|
|
|
|
await write_text(out_file, xml);
|
|
}
|
|
|
|
export interface SitemapEntry {
|
|
url: string;
|
|
lastmod: string;
|
|
change_freq?: ChangeFreq;
|
|
priority?: number;
|
|
}
|
|
|
|
export type ChangeFreq = 'always' | 'hourly' | 'daily' | 'weekly' | 'monthly' | 'yearly' | 'never';
|
|
|
|
function url_elem(urlset: XMLBuilder, loc: string, lastmod: string, change_freq?: ChangeFreq, priority?: number) {
|
|
const url = urlset.ele('url');
|
|
|
|
url.ele('loc').txt(loc);
|
|
url.ele('lastmod').txt(lastmod);
|
|
|
|
if (change_freq) {
|
|
url.ele('changefreq').txt(change_freq);
|
|
}
|
|
|
|
if (priority != null) {
|
|
url.ele('priority').txt(priority.toFixed(1));
|
|
}
|
|
|
|
return url;
|
|
}
|