Skip to content

Commit f28cac5

Browse files
authored
Merge pull request #94 from webdoc-labs/feature/deploy
Feature: Generate sitemaps
2 parents 698dd76 + ab23fac commit f28cac5

File tree

10 files changed

+118
-8
lines changed

10 files changed

+118
-8
lines changed

example/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@
2323
},
2424
"scripts": {
2525
"unit-test": "",
26-
"build": "webdoc --tutorials ./tutorials --site-root example-documentation",
26+
"build": "webdoc --tutorials ./tutorials --site-root example-documentation --site-domain https://webdoc-labs.github.io",
2727
"build-next": "cd .. && webdoc && cd example",
2828
"build-pixi-api": "cd ../../pixi-api && webdoc --site-root docs && cd ../webdoc/example",
29-
"build-pixi-api-prod": "cd ../../pixi-api && webdoc --site-root pixi-api && cd ../webdoc/example"
29+
"build-pixi-api-prod": "cd ../../pixi-api && webdoc --site-root pixi-api && cd ../webdoc/example",
30+
"build-pixi-api-gcp": "cd ../../pixi-api && webdoc && cd ../webdoc/example"
3031
},
3132
"bugs": {
3233
"url": "https://github.com/SukantPal/webdoc/issues"

packages/webdoc-cli/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ npm install --save-dev @webdoc/cli
1414

1515
### Command-line arguments
1616

17+
* `--site-domain <path>`: (optional) The domain of the website where you'll publish the documentation is used to
18+
generate the `sitemap.xml`. This is useful if you want to integrate with [Algolia and use its crawler](https://www.algolia.com/products/crawler/). You must include the protocol for this to work currently, e.g. `http://pixijs.webdoclabs.com`.
1719
* `--site-root <path>`: If using absolute links in a template, this will set the basepath. The basepath should the directory in which the documentation is being stored relative to where the server is running. The site root is "/" by default - which means that you'll need to serve the documentation directory as top-level. Note that @webdoc/default-template uses absolute links.
1820
* `-c <config-path>`: This sets the path of the configuration file webdoc uses.
1921

packages/webdoc-cli/src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ type ConfigSchema = {
3131
template?: string,
3232
},
3333
template: {
34+
siteDomain?: string,
3435
siteRoot: string,
3536
mainPage?: {
3637
title?: string

packages/webdoc-cli/src/index.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ async function main(argv: yargs.Argv) {
6666
if (argv.siteRoot) {
6767
config.template.siteRoot = argv.siteRoot;
6868
}
69+
if (argv.siteDomain) {
70+
config.template.siteDomain = argv.siteDomain;
71+
}
6972
if (config.template.siteRoot[0] === "/") {
7073
config.template.siteRoot = config.template.siteRoot.slice(1);
7174
}
@@ -137,7 +140,11 @@ async function main(argv: yargs.Argv) {
137140
};
138141

139142
if (template.publish && typeof template.publish === "function") {
140-
template.publish(publishOptions);
143+
const resolve = template.publish(publishOptions);
144+
145+
if (resolve) {
146+
await resolve;
147+
}
141148
} else {
142149
console.error("[Config]: ", `${getTemplate(config)} not found.`);
143150
}
@@ -146,7 +153,9 @@ async function main(argv: yargs.Argv) {
146153
}
147154

148155
const argv = yargs.scriptName("@webdoc/cli")
149-
.usage("$0 -c <configFile> -u <tutorialDir> --verbose --site-root <siteRoot>")
156+
.usage("$0 -c <configFile> -u <tutorialDir> --verbose " +
157+
"--site-root <siteRoot> " +
158+
"--site-domain <siteDomain>")
150159
.default("config", path.join(process.cwd(), "webdoc.conf.json"), "webdoc config file")
151160
.alias("c", "config")
152161
.alias("u", "tutorials")

packages/webdoc-default-template/publish.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const {traverse} = require("@webdoc/model");
77
const {
88
FlushToFile,
99
RelationsPlugin,
10+
Sitemap,
1011
TemplateRenderer,
1112
TemplatePipeline,
1213
TemplateTagsResolver,
@@ -45,7 +46,7 @@ const PRETTIFIER_SCRIPT_FILES = [
4546

4647
let idToDoc/*: Map<string, Doc> */;
4748

48-
exports.publish = (options /*: PublishOptions */) => {
49+
exports.publish = async function publish(options /*: PublishOptions */) {
4950
const config = options.config;
5051

5152
linker.siteRoot = config.template.siteRoot;
@@ -65,9 +66,17 @@ exports.publish = (options /*: PublishOptions */) => {
6566
.installPlugin("signature", signaturePlugin)
6667
.installPlugin("categoryFilter", categoryFilterPlugin)
6768
.installPlugin("relations", RelationsPlugin);
68-
const pipeline = new TemplatePipeline(renderer)
69-
.pipe(new TemplateTagsResolver())
70-
.pipe(new FlushToFile({skipNullFile: false}));
69+
70+
const pipeline = new TemplatePipeline(renderer).pipe(new TemplateTagsResolver());
71+
72+
if (config.template.siteDomain) {
73+
pipeline.pipe(new Sitemap(
74+
outDir,
75+
config.template.siteDomain,
76+
config.template.siteRoot));
77+
}
78+
79+
pipeline.pipe(new FlushToFile({skipNullFile: false}));
7180

7281
renderer.getPlugin("relations").buildRelations();
7382

@@ -87,6 +96,8 @@ exports.publish = (options /*: PublishOptions */) => {
8796
outMainPage(path.join(outDir, indexRelative), pipeline, options.config);
8897
outIndexes(outDir, pipeline, options.config, crawlData.index);
8998
outReference(outDir, pipeline, options.config, docTree);
99+
100+
pipeline.close();
90101
};
91102

92103
// Copy the contents of ./static to the output directory

packages/webdoc-template-library/src/TemplatePipeline.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ export interface TemplatePipelineElement<T> {
2626
* Clones the element, less any pipeline-related state.
2727
*/
2828
clone(): TemplatePipelineElement<T>;
29+
30+
/**
31+
* Flush and close the pipeline's state.
32+
*/
33+
close(): void;
2934
}
3035

3136
/**
@@ -68,6 +73,15 @@ export class TemplatePipeline {
6873
return output;
6974
}
7075

76+
/**
77+
* Close the template pipeline. Pipes can flush files at this stage.
78+
*/
79+
close() {
80+
for (const pe of this.elements) {
81+
pe.close();
82+
}
83+
}
84+
7185
/**
7286
* Adds the pipeline-element to run after the last pipeline element.
7387
*

packages/webdoc-template-library/src/pipeline-elements/FlushToFile.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,6 @@ export class FlushToFile implements TemplatePipelineElement<FlushData> {
5555
skipNullFile: this.skipNullFile,
5656
});
5757
}
58+
59+
close() {}
5860
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// @flow
2+
3+
import * as fse from "fs-extra";
4+
import type {TemplatePipeline, TemplatePipelineElement} from "../TemplatePipeline";
5+
import path from "path";
6+
7+
type SitemapData = {
8+
outputFile: string;
9+
};
10+
11+
export class Sitemap implements TemplatePipelineElement<SitemapData> {
12+
urls: string[] = [];
13+
dir: string;
14+
domain: string;
15+
root: string;
16+
17+
/**
18+
* @param {string} dir - Directory to save sitemap.xml
19+
* @param {string} domain - The site domain with protocol
20+
* @param {string} root - the siteroot
21+
*/
22+
constructor(dir: string, domain: string, root: string) {
23+
this.dir = dir;
24+
this.domain = domain;
25+
this.root = root;
26+
27+
if (this.domain.charAt(this.domain.length - 1) !== "/") {
28+
this.domain += "/";
29+
}
30+
}
31+
32+
attachTo(pipeline: TemplatePipeline) {
33+
// noop
34+
}
35+
36+
run(input: string, pipelineData: SitemapData = {}) {
37+
if (pipelineData.outputFile) {
38+
this.urls.push(pipelineData.outputFile);
39+
}
40+
}
41+
42+
close() {
43+
/* eslint-disable max-len */
44+
const xml =
45+
`<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
46+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
47+
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
48+
${this.urls.map((url) =>
49+
` <url>
50+
<loc>${this.domain + path.join(this.root, path.relative(this.dir, url))}</loc>
51+
</url>`).join("\n")}
52+
</urlset>`;
53+
/* eslint-enable max-len */
54+
55+
fse.outputFile(path.join(this.dir, "sitemap.xml"), xml, (err) => {
56+
if (err) throw err;
57+
});
58+
}
59+
60+
clone() {
61+
const clone = new Sitemap(this.dir, this.domain, this.root);
62+
63+
clone.urls = [...this.urls];
64+
65+
return clone;
66+
}
67+
}

packages/webdoc-template-library/src/pipeline-elements/TemplateTagsResolver.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ export class TemplateTagsResolver implements TemplatePipelineElement<{}> {
9494
linkClass: this.linkClass,
9595
});
9696
}
97+
98+
close() {}
9799
}
98100

99101
// Helper function to check if link content is just a URL
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export {FlushToFile} from "./FlushToFile";
2+
export {Sitemap} from "./Sitemap";
23
export {TemplateTagsResolver} from "./TemplateTagsResolver";

0 commit comments

Comments
 (0)