Skip to content

Commit

Permalink
xsl
Browse files Browse the repository at this point in the history
  • Loading branch information
derduher committed Mar 9, 2020
1 parent 512931a commit 41bf270
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 17 deletions.
23 changes: 17 additions & 6 deletions lib/sitemap-index-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { IndexItem, SitemapItemLoose, ErrorLevel } from './types';
import { UndefinedTargetFolder } from './errors';
import { chunk } from './utils';
import { SitemapStream } from './sitemap-stream';
import { SitemapStream, stylesheetInclude } from './sitemap-stream';
import { element, otag, ctag } from './sitemap-xml';

export enum IndexTagNames {
Expand All @@ -21,22 +21,27 @@ export enum IndexTagNames {
}

const statPromise = promisify(stat);
const preamble =
'<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
const xmlDec = '<?xml version="1.0" encoding="UTF-8"?>';

const sitemapIndexTagStart =
'<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
const closetag = '</sitemapindex>';

export interface SitemapIndexStreamOptions extends TransformOptions {
level?: ErrorLevel;
xslUrl?: string;
}
const defaultStreamOpts: SitemapIndexStreamOptions = {};
export class SitemapIndexStream extends Transform {
level: ErrorLevel;
xslUrl?: string;
private hasHeadOutput: boolean;
constructor(opts = defaultStreamOpts) {
opts.objectMode = true;
super(opts);
this.hasHeadOutput = false;
this.level = opts.level ?? ErrorLevel.WARN;
this.xslUrl = opts.xslUrl;
}

_transform(
Expand All @@ -46,7 +51,11 @@ export class SitemapIndexStream extends Transform {
): void {
if (!this.hasHeadOutput) {
this.hasHeadOutput = true;
this.push(preamble);
let stylesheet = '';
if (this.xslUrl) {
stylesheet = stylesheetInclude(this.xslUrl);
}
this.push(xmlDec + stylesheet + sitemapIndexTagStart);
}
this.push(otag(IndexTagNames.sitemap));
if (typeof item === 'string') {
Expand Down Expand Up @@ -90,15 +99,17 @@ export async function createSitemapsAndIndex({
sitemapName = 'sitemap',
sitemapSize = 50000,
gzip = true,
xslUrl,
}: {
urls: (string | SitemapItemLoose)[];
targetFolder: string;
hostname?: string;
sitemapName?: string;
sitemapSize?: number;
gzip?: boolean;
xslUrl?: string;
}): Promise<boolean> {
const indexStream = new SitemapIndexStream();
const indexStream = new SitemapIndexStream({ xslUrl });

try {
const stats = await statPromise(targetFolder);
Expand All @@ -121,7 +132,7 @@ export async function createSitemapsAndIndex({
indexStream.write(new URL(filename, hostname).toString());

const ws = createWriteStream(targetFolder + '/' + filename);
const sms = new SitemapStream({ hostname });
const sms = new SitemapStream({ hostname, xslUrl });
let pipe: Writable;
if (gzip) {
pipe = sms.pipe(createGzip()).pipe(ws);
Expand Down
36 changes: 25 additions & 11 deletions lib/sitemap-stream.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { URL } from 'url';
import {
Transform,
TransformOptions,
Expand All @@ -8,8 +9,16 @@ import {
import { SitemapItemLoose, ErrorLevel } from './types';
import { validateSMIOptions, normalizeURL } from './utils';
import { SitemapItemStream } from './sitemap-item-stream';
const preamble =
'<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';

const xmlDec = '<?xml version="1.0" encoding="UTF-8"?>';
export const stylesheetInclude = (url: string): string => {
// Throws if url is invalid
new URL(url);

return `<?xml-stylesheet type="text/xsl" href="${url}"?>`;
};
const urlsetTagStart =
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"';

export interface NSArgs {
news: boolean;
Expand All @@ -18,14 +27,16 @@ export interface NSArgs {
image: boolean;
custom?: string[];
}
const getURLSetNs: (opts: NSArgs) => string = ({
news,
video,
image,
xhtml,
custom,
}) => {
let ns = preamble;
const getURLSetNs: (opts: NSArgs, xslURL?: string) => string = (
{ news, video, image, xhtml, custom },
xslURL
) => {
let ns = xmlDec;
if (xslURL) {
ns += stylesheetInclude(xslURL);
}

ns += urlsetTagStart;

if (news) {
ns += ' xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"';
Expand Down Expand Up @@ -56,6 +67,7 @@ export interface SitemapStreamOptions extends TransformOptions {
level?: ErrorLevel;
lastmodDateOnly?: boolean;
xmlns?: NSArgs;
xslUrl?: string;
errorHandler?: (error: Error, level: ErrorLevel) => void;
}
const defaultXMLNS: NSArgs = {
Expand All @@ -79,6 +91,7 @@ export class SitemapStream extends Transform {
level: ErrorLevel;
hasHeadOutput: boolean;
xmlNS: NSArgs;
xslUrl?: string;
private smiStream: SitemapItemStream;
lastmodDateOnly: boolean;
constructor(opts = defaultStreamOpts) {
Expand All @@ -91,6 +104,7 @@ export class SitemapStream extends Transform {
this.smiStream.on('data', data => this.push(data));
this.lastmodDateOnly = opts.lastmodDateOnly || false;
this.xmlNS = opts.xmlns || defaultXMLNS;
this.xslUrl = opts.xslUrl;
}

_transform(
Expand All @@ -100,7 +114,7 @@ export class SitemapStream extends Transform {
): void {
if (!this.hasHeadOutput) {
this.hasHeadOutput = true;
this.push(getURLSetNs(this.xmlNS));
this.push(getURLSetNs(this.xmlNS, this.xslUrl));
}
this.smiStream.write(
validateSMIOptions(
Expand Down

0 comments on commit 41bf270

Please sign in to comment.