Skip to content
This repository has been archived by the owner on Jun 13, 2022. It is now read-only.

Commit

Permalink
feat(core): support sitemap generation
Browse files Browse the repository at this point in the history
  • Loading branch information
giovagnoli committed Dec 9, 2018
1 parent ff37115 commit 965f496
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 0 deletions.
13 changes: 13 additions & 0 deletions packages/@statusfy/core/client/modules/statusfy/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const fs = require('fs')
const defaultsDeep = require('lodash/defaultsDeep')

const { logger, fse, path } = require('@statusfy/common')
const createSitemap = require('../../../lib/content/sitemap')
const createServer = require('../../../server')
const buildContent = require('./build')

Expand Down Expand Up @@ -90,6 +91,18 @@ module.exports = async function Statusfy () {

this.nuxt.hook('generate:done', async generator => {
await copyPublicFiles(statusfyOptions.publicFilesPath, this.options.generate.dir)

/* Sitemap */
const sitemap = await createSitemap(statusfyOptions.siteConfig)
const xmlPath = path.join(this.options.generate.dir, 'sitemap.xml')

// Ensure no sitemap file exists
await fse.remove(xmlPath)
await fse.ensureFile(xmlPath)

await fse.writeFile(xmlPath, sitemap)

logger.success('Generated /sitemap.xml')
})
}

Expand Down
148 changes: 148 additions & 0 deletions packages/@statusfy/core/client/static/sitemap.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:html="http://www.w3.org/TR/REC-html40"
xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
version="2.0">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Sitemap</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
body {
font-family: sans-serif;
font-size: 16px;
color: #242628;
}
a {
color: #000;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
table {
border: none;
border-collapse: collapse;
width: 100%
}
th {
text-align: left;
padding-right: 30px;
font-size: 11px;
}
thead th {
border-bottom: 1px solid #7d878a;
cursor: pointer;
}
td {
font-size:11px;
padding: 5px;
}
tr:nth-child(odd) td {
background-color: rgba(0,0,0,0.04);
}
tr:hover td {
background-color: #e2edf2;
}

#content {
margin: 0 auto;
padding: 2% 5%;
max-width: 800px;
}

.desc {
margin: 18px 3px;
line-height: 1.2em;
}
.desc a {
color: #5ba4e5;
}
</style>
</head>
<body>
<div id="content">
<h1>XML Sitemap</h1>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) &gt; 0">
<table id="sitemap" cellpadding="3">
<thead>
<tr>
<th width="75%">Sitemap</th>
<th width="25%">Last Modified</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
<xsl:variable name="sitemapURL">
<xsl:value-of select="sitemap:loc" />
</xsl:variable>
<tr>
<td>
<a href="{$sitemapURL}">
<xsl:value-of select="sitemap:loc" />
</a>
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:if>
<xsl:if test="count(sitemap:sitemapindex/sitemap:sitemap) &lt; 1">
<p class="desc">
<a href="/sitemaps.xml" class="back-link">← Back to index</a>
</p>
<table id="sitemap" cellpadding="3">
<thead>
<tr>
<th width="70%">
URL (
<xsl:value-of select="count(sitemap:urlset/sitemap:url)" />
total)
</th>
<th title="Priority" width="5%">Prio</th>
<th title="Change Frequency" width="10%">Ch. Freq.</th>
<th title="Last Modification Time" width="15%">Last Modified</th>
</tr>
</thead>
<tbody>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td>
<xsl:variable name="itemURL">
<xsl:value-of select="sitemap:loc" />
</xsl:variable>
<a href="{$itemURL}">
<xsl:value-of select="sitemap:loc" />
</a>
</td>
<td>
<xsl:value-of select="concat(sitemap:priority*100,'%')" />
</td>
<td>
<xsl:value-of select="concat(translate(substring(sitemap:changefreq, 1, 1),concat($lower, $upper),concat($upper, $lower)),substring(sitemap:changefreq, 2))" />
</td>
<td>
<xsl:value-of select="concat(substring(sitemap:lastmod,0,11),concat(' ', substring(sitemap:lastmod,12,5)))" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
<p class="desc">
<a href="/sitemaps.xml" class="back-link">← Back to index</a>
</p>
</xsl:if>
</div>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
56 changes: 56 additions & 0 deletions packages/@statusfy/core/lib/content/sitemap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const sm = require('sitemap')
const createDatabase = require('./database')

module.exports = async function sitemap (siteConfig) {
const database = await createDatabase(siteConfig)

const sitemap = sm.createSitemap({
hostname: siteConfig.baseUrl,
cacheTime: 86400, // 1 day
xslUrl: '/sitemap.xsl'
})

siteConfig.locales.forEach(locale => {
const prefix = locale.code === siteConfig.defaultLocale ? '' : `/${locale.code}`
const fixedPages = ['/', '/history']
const base = {
changefreq: 'daily',
priority: 0.8,
lastmodISO: new Date().toISOString()
}

// Fixed Pages
fixedPages.forEach(route => {
sitemap.add({
...base,
url: `${siteConfig.baseUrl}${prefix}${route}`
})
})

// History Pages
const historyPage1 = database.incidentsHistory(locale.code)
const totalPages = historyPage1.total_pages

for (let page = 2; page <= totalPages; page++) {
sitemap.add({
...base,
url: `${siteConfig.baseUrl}${prefix}/history/${page}`
})
}

// Incidents Pages
const { incidents } = database.incidents(locale.code, 1, -1)

incidents.forEach(incident => {
sitemap.add({
...base,
url: `${siteConfig.baseUrl}${prefix}/incidents/${incident.id}`,
changefreq: 'weekly',
priority: 0.7,
lastmodISO: new Date(incident.modified).toISOString()
})
})
})

return sitemap.toString()
}
1 change: 1 addition & 0 deletions packages/@statusfy/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"nuxt-i18n": "^5.4.0",
"opener": "^1.5.0",
"portfinder": "^1.0.17",
"sitemap": "^2.1.0",
"stylelint": "^9.6.0",
"stylelint-webpack-plugin": "^0.10.5",
"v-tooltip": "^2.0.0-rc.33",
Expand Down
2 changes: 2 additions & 0 deletions packages/@statusfy/core/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const helmet = require('helmet')
const { Nuxt } = require('nuxt')

const language = require('./middlewares/language')
const sitemap = require('./extra/sitemap')
const buildApiRouter = require('./api')

module.exports = async function createApp (siteConfig, nuxtConfig, host, port, apiPrefix = '') {
Expand Down Expand Up @@ -42,6 +43,7 @@ module.exports = async function createApp (siteConfig, nuxtConfig, host, port, a
app.use(require('serve-static')(nuxtConfig.statusfy.publicFilesPath))
}

app.use('/sitemap.xml', sitemap)
app.use(`${apiPrefix}/api/v0`, buildApiRouter(siteConfig))

if (nuxtConfig) {
Expand Down
9 changes: 9 additions & 0 deletions packages/@statusfy/core/server/extra/sitemap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const createSitemap = require('../../lib/content/sitemap')

module.exports = async (req, res, next) => {
const siteConfig = req.app.get('siteConfig')
const sitemap = await createSitemap(siteConfig)

res.header('Content-Type', 'application/xml')
res.send(sitemap.toString())
}
19 changes: 19 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -14261,6 +14261,15 @@ sitemap@^1.13.0:
underscore "^1.7.0"
url-join "^1.1.0"

sitemap@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-2.1.0.tgz#1633cb88c196d755ad94becfb1c1bcacc6d3425a"
integrity sha512-AkfA7RDVCITQo+j5CpXsMJlZ/8ENO2NtgMHYIh+YMvex2Hao/oe3MQgNa03p0aWY6srCfUA1Q02OgiWCAiuccA==
dependencies:
lodash "^4.17.10"
url-join "^4.0.0"
xmlbuilder "^10.0.0"

slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
Expand Down Expand Up @@ -15752,6 +15761,11 @@ url-join@^1.1.0:
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
integrity sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg=

url-join@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.0.tgz#4d3340e807d3773bda9991f8305acdcc2a665d2a"
integrity sha1-TTNA6AfTdzvamZH4MFrNzCpmXSo=

url-loader@^1.0.1, url-loader@^1.1.1, url-loader@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8"
Expand Down Expand Up @@ -16767,6 +16781,11 @@ xml2js@^0.4.5:
sax ">=0.6.0"
xmlbuilder "~9.0.1"

xmlbuilder@^10.0.0:
version "10.1.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-10.1.1.tgz#8cae6688cc9b38d850b7c8d3c0a4161dcaf475b0"
integrity sha512-OyzrcFLL/nb6fMGHbiRDuPup9ljBycsdCypwuyg5AAHvyWzGfChJpCXMG88AGTIMFhGZ9RccFN1e6lhg3hkwKg==

xmlbuilder@~9.0.1:
version "9.0.7"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d"
Expand Down

0 comments on commit 965f496

Please sign in to comment.