Examples
Basic example
#!/usr/bin/env node
import {dirname, relative, join} from 'node:path';
import {getPages, allPages, writeFile} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {frontmatter} from '@sphido/frontmatter';
import {markdown} from '@sphido/markdown';
function getHtml({title, content, path, date}) {
return `<!DOCTYPE html>
<html lang="cs" dir="ltr">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<title>${title} | Sphido Example page</title>
</head>
<body class="prose mx-auto my-6">
<header class="border-b text-2xl py-2 mb-4">Sphido Example website</header>
<main>${content}</main>
<footer class="border-t text-sm text-gray-500 pt-1 mt-1 text-right">Created: ${date?.toLocaleDateString()}</footer>
</body>
<!-- Generated with Sphido from ${path} -->
</html>`;
}
// frontmatter loads page.content and reads the YAML block, markdown() renders
// the rest to HTML — it goes last, after every extender that wants markdown
const pages = await getPages({path: 'content'}, frontmatter, markdown());
for (const page of allPages(pages)) {
page.slug = slugify(page.name) + '.html';
page.output = join('public', relative('content', dirname(page.path)), page.slug);
// save HTML file
await writeFile(page.output, getHtml(page));
}
View on GitHub
Extenders
#!/usr/bin/env node
import {dirname, relative, join} from 'node:path';
import {getPages, allPages, writeFile} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {markdown} from '@sphido/markdown';
function metadata(page, dirent) {
if (dirent.isFile()) {
page.slug = slugify(page.name) + '.html';
page.dir = join('public', relative('content', dirname(page.path)));
}
}
function author(page) {
page.author = 'Roman Ožana';
}
const pages = await getPages({path: 'content'},
// callback extender
metadata,
author,
(page) => {
page.date = new Date();
},
// extender package: renders page.content from markdown to HTML
markdown(),
// Object extenders
{
getFooter: function () {
return `<footer class="border-t text-sm text-gray-500 pt-1 mt-1 text-right">Generated from file ${this.path}</footer>`;
},
getTitle: function () {
return this.name + ' | Sphido example website';
},
getHtml: async function () {
return `<!DOCTYPE html>
<html lang="cs" dir="ltr">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<title>${this.getTitle()}</title>
</head>
<body class="prose mx-auto my-6">
<header class="border-b text-2xl py-2 mb-4">Sphido Example website</header>
<main>${this.content}</main>
${this.getFooter()}
</body>
</html>`;
},
save: async function () {
await writeFile(join(this.dir, this.slug), await this.getHtml());
},
},
);
for (const page of allPages(pages)) {
await page.save();
}
View on GitHub
RSS
#!/usr/bin/env node
import {dirname, relative, join} from 'node:path';
import {getPages, allPages, writeFile} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {markdown} from '@sphido/markdown';
import {renderFeed, writeFeed} from '@sphido/feed';
function getHtml({title, content, path, date}) {
return `<!DOCTYPE html>
<html lang="cs" dir="ltr">
<head>
<meta charset="UTF-8">
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<title>${title} | Sphido Example page</title>
</head>
<body class="prose mx-auto my-6"><main>${content}</main></body>
<!-- Generated with Sphido from ${path} -->
</html>`;
}
const items = [];
// markdown() loads each file and renders page.content to HTML
const pages = await getPages({path: 'content'}, markdown());
for (const page of allPages(pages)) {
page.slug = join('/', relative('content', dirname(page.path)), slugify(page.name) + '.html');
page.output = join('public', page.slug);
page.url = new URL(page.slug, 'https://sphido.org/').toString();
page.title = page.content.match(/(?<=<h[12][^>]*?>)([^<>]+?)(?=<\/h[12]>)/i)?.pop();
page.date = new Date();
items.push({title: page.title, url: page.url, date: page.date});
// save HTML file
await writeFile(page.output, getHtml(page));
}
const xml = renderFeed({
title: 'RSS example',
link: 'https://sphido.org/',
description: 'This is my personal feed!',
feedUrl: 'https://sphido.org/rss.xml',
}, items);
await writeFeed('public/rss.xml', xml);
View on GitHub
Generate JSON file
#!/usr/bin/env node
import {dirname, relative, join} from 'node:path';
import {getPages, allPages, writeFile} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {frontmatter} from '@sphido/frontmatter';
import {markdown} from '@sphido/markdown';
const pages = await getPages({path: 'content'}, frontmatter, markdown());
for (const page of allPages(pages)) {
page.slug = slugify(page.name) + '.json';
const output = join('public', relative('content', dirname(page.path)), page.slug);
// save JSON file with the rendered HTML in page.content
await writeFile(output, JSON.stringify(page));
}
View on GitHub
Sitemap
#!/usr/bin/env node
import {dirname, relative, join} from 'node:path';
import {getPages, allPages} from '@sphido/core';
import slugify from '@sindresorhus/slugify';
import {pagesToSitemap, writeSitemap} from '@sphido/sitemap';
const pages = await getPages({path: 'content'});
for (const page of allPages(pages)) {
page.slug = join('/', relative('content', dirname(page.path)), slugify(page.name) + '.html');
page.url = new URL(page.slug, 'https://sphido.org/').toString();
page.priority = page.name === 'index' ? 1 : 0.8;
// you should save pages here...
}
// map pages to sitemap XML (defaults apply to every entry)
const xml = pagesToSitemap(pages, {
baseUrl: 'https://sphido.org/',
defaults: {changefreq: 'daily', lastmod: new Date()},
});
await writeSitemap('public/sitemap.xml', xml);
View on GitHub