Permalink
Browse files

Basic blog support

  • Loading branch information...
octref committed Jun 24, 2018
1 parent 62af972 commit 81fe2db8b64a5648c7ea13cbc1abcfb988a93ff9
Showing with 86 additions and 33 deletions.
  1. +0 βˆ’11 lib/app/app.js
  2. +36 βˆ’3 lib/build.js
  3. +7 βˆ’0 lib/markdown/imgWrapper.js
  4. +3 βˆ’8 lib/markdown/index.js
  5. +0 βˆ’1 lib/markdown/lineNumbers.js
  6. +1 βˆ’1 lib/markdown/link.js
  7. +1 βˆ’2 lib/markdown/preWrapper.js
  8. +28 βˆ’6 lib/prepare/codegen.js
  9. +10 βˆ’1 lib/prepare/index.js
@@ -69,17 +69,6 @@ export function createApp () {
}
})
// redirect /foo to /foo/
router.beforeEach((to, from, next) => {
if (!/(\/|\.html)$/.test(to.path)) {
next(Object.assign({}, to, {
path: to.path + '/'
}))
} else {
next()
}
})
const options = {}
themeEnhanceApp({ Vue, options, router, siteData })
@@ -53,7 +53,7 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
// create server renderer using built manifests
const renderer = createBundleRenderer(serverBundle, {
clientManifest,
// clientManifest,
runInNewContext: false,
inject: false,
shouldPrefetch: options.siteConfig.shouldPrefetch || (() => true),
@@ -89,6 +89,12 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
})
}
// write rss
const rssPath = path.resolve(outDir, 'feed.xml')
const rssContent = renderRss(options)
await fs.writeFile(rssPath, rssContent)
// DONE.
const relativeDir = path.relative(process.cwd(), outDir)
logger.success(`\n${chalk.green('Success!')} Generated static files in ${chalk.cyan(relativeDir)}.\n`)
@@ -158,8 +164,13 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
console.error(logger.error(chalk.red(`Error rendering ${pagePath}:`), false))
throw e
}
const filename = decodeURIComponent(pagePath.replace(/\/$/, '/index.html').replace(/^\//, ''))
const filePath = path.resolve(outDir, filename)
let outPath = pagePath
if (!pagePath.endsWith('/') && !pagePath.endsWith('.html')) {
outPath += '.html'
}
const filename = decodeURIComponent(outPath.replace(/\/$/, '/index.html').replace(/^\//, ''))
filePath = path.resolve(outDir, filename)
await fs.ensureDir(path.dirname(filePath))
await fs.writeFile(filePath, html)
}
@@ -193,3 +204,25 @@ module.exports = async function build (sourceDir, cliOptions = {}) {
await fs.writeFile(appChunkPath, styleChunkContent + appChunkContent)
}
}
function renderRss (options) {
const sortedRssItems = options.rssItems.sort((a, b) => a > b).reverse()
return `<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>${options.siteConfig.title}</title>
<link>http://blog.matsu.io</link>
${sortedRssItems.map(renderRssItem).join('')}
</channel>
</rss>
`
}
function renderRssItem (rssItem) {
return `
<item>
<title>${rssItem.title}</title>
<link>http://blog.matsu.io${rssItem.path}</link>
<pubDate>${rssItem.date}</pubDate>
</item>
`
}
@@ -0,0 +1,7 @@
module.exports = md => {
const defaultRenderer = md.renderer.rules.image
md.renderer.rules.image = (tokens, idx, options, env, self) => {
return `<figure>${defaultRenderer(tokens, idx, options, env, self)}</figure>`
}
}
@@ -1,10 +1,9 @@
const highlight = require('./highlight')
const highlightLines = require('./highlightLines')
const preWrapper = require('./preWrapper')
const preWrapper = require('./preWrapper.js')
const imgWrapper = require('./imgWrapper.js')
const lineNumbers = require('./lineNumbers')
const component = require('./component')
const hoistScriptStyle = require('./hoist')
const convertRouterLink = require('./link')
const containers = require('./containers')
const snippet = require('./snippet')
const emoji = require('markdown-it-emoji')
@@ -24,13 +23,9 @@ module.exports = ({ markdown = {}} = {}) => {
})
// custom plugins
.use(component)
.use(highlightLines)
.use(preWrapper)
.use(imgWrapper)
.use(snippet)
.use(convertRouterLink, Object.assign({
target: '_blank',
rel: 'noopener noreferrer'
}, markdown.externalLinks))
.use(hoistScriptStyle)
.use(containers)
@@ -19,7 +19,6 @@ module.exports = md => {
const finalCode = rawCode
.replace('<!--beforeend-->', `${lineNumbersWrapperCode}<!--beforeend-->`)
.replace('extra-class', 'line-numbers-mode')
return finalCode
}
@@ -75,7 +75,7 @@ module.exports = (md, externalAttrs) => {
if (hasOpenExternalLink) {
hasOpenExternalLink = false
// add OutBoundLink to the beforeend of this link if it opens in _blank.
return '<OutboundLink/>' + self.renderToken(tokens, idx, options)
return self.renderToken(tokens, idx, options)
}
return self.renderToken(tokens, idx, options)
}
@@ -13,7 +13,6 @@ module.exports = md => {
const [tokens, idx] = args
const token = tokens[idx]
const rawCode = fence(...args)
return `<!--beforebegin--><div class="language-${token.info.trim()} extra-class">` +
`<!--afterbegin-->${rawCode}<!--beforeend--></div><!--afterend-->`
return `<!--beforebegin--><!--afterbegin-->${rawCode}<!--beforeend--><!--afterend-->`
}
}
@@ -6,13 +6,20 @@ exports.genRoutesFile = async function ({
sourceDir,
pageFiles
}) {
function genRoute ({ path: pagePath, key: componentName }, index) {
const rssItems = []
function genRoute ({ path: pagePath, key: componentName, frontmatter }, index) {
const file = pageFiles[index]
const filePath = path.resolve(sourceDir, file)
let cleanPagePath = pagePath.replace(/.html/g, '')
if (cleanPagePath !== '/' && cleanPagePath.endsWith('/')) {
cleanPagePath = cleanPagePath.slice(0, -1)
}
let code = `
{
name: ${JSON.stringify(componentName)},
path: ${JSON.stringify(pagePath)},
path: ${JSON.stringify(cleanPagePath)},
component: ThemeLayout,
beforeEnter: (to, from, next) => {
import(${JSON.stringify(filePath)}).then(comp => {
@@ -22,20 +29,28 @@ exports.genRoutesFile = async function ({
}
}`
if (!frontmatter.top_page) {
rssItems.push({
title: frontmatter.title,
path: cleanPagePath,
date: frontmatter.date
})
}
const dncodedPath = decodeURIComponent(pagePath)
if (dncodedPath !== pagePath) {
code += `,
{
path: ${JSON.stringify(dncodedPath)},
redirect: ${JSON.stringify(pagePath)}
redirect: ${JSON.stringify(cleanPagePath)}
}`
}
if (/\/$/.test(pagePath)) {
code += `,
{
path: ${JSON.stringify(pagePath + 'index.html')},
redirect: ${JSON.stringify(pagePath)}
redirect: ${JSON.stringify(cleanPagePath)}
}`
}
@@ -48,15 +63,22 @@ exports.genRoutesFile = async function ({
component: ThemeNotFound
}`
return (
const generatedRoutes = pages.map(genRoute)
const routesCode = (
`import ThemeLayout from '@themeLayout'\n` +
`import ThemeNotFound from '@themeNotFound'\n` +
`import { injectMixins } from '@app/util'\n` +
`import rootMixins from '@app/root-mixins'\n\n` +
`injectMixins(ThemeLayout, rootMixins)\n` +
`injectMixins(ThemeNotFound, rootMixins)\n\n` +
`export const routes = [${pages.map(genRoute).join(',')}${notFoundRoute}\n]`
`export const routes = [${generatedRoutes.join(',')}${notFoundRoute}\n]`
)
return {
routesCode,
rssItems
}
}
exports.genComponentRegistrationFile = async function ({ sourceDir }) {
@@ -9,15 +9,24 @@ module.exports = async function prepare (sourceDir) {
const options = await resolveOptions(sourceDir)
// 2. generate routes & user components registration code
const routesCode = await genRoutesFile(options)
const { routesCode, rssItems } = await genRoutesFile(options)
const componentCode = await genComponentRegistrationFile(options)
options.rssItems = rssItems
await writeTemp('routes.js', [
componentCode,
routesCode
].join('\n'))
// 3. generate siteData
options.siteData.pages.forEach(p => {
if (p.path) {
p.path = p.path.replace(/.html$/g, '')
}
if (p.path !== '/' && p.path.endsWith('/')) {
p.path = p.path.slice(0, -1)
}
})
const dataCode = `export const siteData = ${JSON.stringify(options.siteData, null, 2)}`
await writeTemp('siteData.js', dataCode)

0 comments on commit 81fe2db

Please sign in to comment.