Skip to content

Commit 077f6b9

Browse files
committed
convert sitemap to ts
1 parent db5b942 commit 077f6b9

4 files changed

Lines changed: 131 additions & 106 deletions

File tree

src/sitemap/SitemapGenerator.js

Lines changed: 0 additions & 43 deletions
This file was deleted.

src/sitemap/SitemapGenerator.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import xml from 'xml';
2+
import type { Post } from '../data/Posts';
3+
4+
export interface SitemapItem {
5+
url: [
6+
{ loc: string },
7+
{ lastmod: string | number },
8+
{ changefreq: string },
9+
{ priority: number }
10+
];
11+
}
12+
13+
export class SitemapGenerator {
14+
private xmlAttribute = {
15+
_attr: {
16+
xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9',
17+
},
18+
};
19+
20+
private encoding = '<?xml version="1.0" encoding="UTF-8" ?>';
21+
22+
private host: string;
23+
24+
constructor({ host }: { host: string }) {
25+
this.host = host;
26+
}
27+
28+
private generateSitemapItem(page: Post): SitemapItem {
29+
const lastmod = page.published_at
30+
? (typeof page.published_at === 'string' ? page.published_at : new Date(page.published_at).toISOString())
31+
: new Date().toISOString();
32+
33+
return {
34+
url: [
35+
{ loc: this.host + page.path },
36+
{ lastmod },
37+
{ changefreq: 'monthly' },
38+
{ priority: 0.5 },
39+
],
40+
};
41+
}
42+
43+
private generateUrlSet(pages: Post[]) {
44+
const items = pages.map((page) => this.generateSitemapItem(page));
45+
return [this.xmlAttribute, ...items];
46+
}
47+
48+
public generateSitemap(pages: Post[]): string {
49+
const sitemap = {
50+
urlset: this.generateUrlSet(pages),
51+
};
52+
53+
return this.encoding + xml(sitemap);
54+
}
55+
}

src/sitemap/sitemap.js

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/sitemap/sitemap.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import path from 'path';
2+
import { fileURLToPath } from 'url';
3+
import { lstatSync, readdirSync, readFileSync, writeFileSync } from 'fs';
4+
import FrontMatter from 'front-matter';
5+
6+
import { SitemapGenerator } from './SitemapGenerator';
7+
import type { Post } from '../data/Posts';
8+
9+
const __filename = fileURLToPath(import.meta.url);
10+
const __dirname = path.dirname(__filename);
11+
12+
const blogRoot = path.join(__dirname, '../../blog/');
13+
const sitemapXmlPath = path.join(__dirname, '../../public/sitemap.xml');
14+
const sitemapJsonPath = path.join(__dirname, '../../public/sitemap.json');
15+
16+
const sitemap: Post[] = [];
17+
18+
function isArticle(filePath: string): boolean {
19+
return (
20+
lstatSync(path.join(blogRoot, filePath)).isFile() &&
21+
!filePath.toString().includes('.json')
22+
);
23+
}
24+
25+
function getArticlesList(): string[] {
26+
return readdirSync(blogRoot, { recursive: true }).filter((item) =>
27+
isArticle(item as string)
28+
) as string[];
29+
}
30+
31+
function generateSitemapXml(posts: Post[]): string {
32+
return new SitemapGenerator({
33+
host: 'https://andrepg.github.io/',
34+
}).generateSitemap(posts);
35+
}
36+
37+
function report(message: string): void {
38+
console.log(message);
39+
}
40+
41+
function addArticleToSitemap(item: string): void {
42+
const content = readFileSync(path.join(blogRoot, item), 'utf8').toString();
43+
const fm = FrontMatter<Post>(content);
44+
45+
sitemap.push({
46+
path: item.replace('.md', ''),
47+
...fm.attributes,
48+
});
49+
50+
report(`\tFile processed -> ${item}`);
51+
}
52+
53+
function main(): void {
54+
report(`Building blog sitemap for ${blogRoot}`);
55+
const articleList = getArticlesList();
56+
57+
report(
58+
`\t${articleList.length} articles found.\nCollecting front-matter properties.`
59+
);
60+
articleList.forEach(addArticleToSitemap);
61+
62+
report('Generating JSON sitemap');
63+
writeFileSync(sitemapJsonPath, JSON.stringify(sitemap, null, 2), {
64+
encoding: 'utf-8',
65+
});
66+
67+
report('Generating XML sitemap');
68+
const xmlContent = generateSitemapXml(sitemap);
69+
writeFileSync(sitemapXmlPath, xmlContent, { encoding: 'utf-8' });
70+
71+
report(`Sitemap file generated at ${sitemapXmlPath} and ${sitemapJsonPath}`);
72+
}
73+
74+
console.time('sitemap-build');
75+
main();
76+
console.timeEnd('sitemap-build');

0 commit comments

Comments
 (0)