You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
76 lines
3.0 KiB
76 lines
3.0 KiB
import { resolve } from "path"
|
|
import { app } from "@/global"
|
|
import consolidate from "consolidate"
|
|
import send from "../Send"
|
|
import getPaths from "get-paths"
|
|
// import pretty from "pretty"
|
|
import { logger } from "@/logger"
|
|
import SiteConfigService from "services/SiteConfigService.js"
|
|
import assign from "lodash/assign"
|
|
import config from "config/index.js"
|
|
|
|
export default viewsMiddleware
|
|
|
|
function viewsMiddleware(path, { engineSource = consolidate, extension = "html", options = {}, map } = {}) {
|
|
const siteConfigService = new SiteConfigService()
|
|
|
|
return async function views(ctx, next) {
|
|
if (ctx.render) return await next()
|
|
|
|
// 将 render 注入到 context 和 response 对象中
|
|
ctx.response.render = ctx.render = function (relPath, locals = {}, renderOptions) {
|
|
renderOptions = assign({ includeSite: true, includeUser: false }, renderOptions || {})
|
|
return getPaths(path, relPath, extension).then(async paths => {
|
|
const suffix = paths.ext
|
|
const site = await siteConfigService.getAll()
|
|
const otherData = {
|
|
currentPath: ctx.path,
|
|
$config: config,
|
|
isLogin: !!ctx.state && !!ctx.state.user,
|
|
}
|
|
if (renderOptions.includeSite) {
|
|
otherData.$site = site
|
|
}
|
|
if (renderOptions.includeUser && ctx.state && ctx.state.user) {
|
|
otherData.$user = ctx.state.user
|
|
}
|
|
const state = assign({}, otherData, locals, options, ctx.state || {})
|
|
// deep copy partials
|
|
state.partials = assign({}, options.partials || {})
|
|
// logger.debug("render `%s` with %j", paths.rel, state)
|
|
ctx.type = "text/html"
|
|
|
|
// 如果是 html 文件,不编译直接 send 静态文件
|
|
if (isHtml(suffix) && !map) {
|
|
return send(ctx, paths.rel, {
|
|
root: path,
|
|
})
|
|
} else {
|
|
const engineName = map && map[suffix] ? map[suffix] : suffix
|
|
|
|
// 使用 engineSource 配置的渲染引擎 render
|
|
const render = engineSource[engineName]
|
|
|
|
if (!engineName || !render) return Promise.reject(new Error(`Engine not found for the ".${suffix}" file extension`))
|
|
|
|
return render(resolve(path, paths.rel), state).then(html => {
|
|
// since pug has deprecated `pretty` option
|
|
// we'll use the `pretty` package in the meanwhile
|
|
// if (locals.pretty) {
|
|
// debug("using `pretty` package to beautify HTML")
|
|
// html = pretty(html)
|
|
// }
|
|
ctx.body = html
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// 中间件执行结束
|
|
return await next()
|
|
}
|
|
}
|
|
|
|
function isHtml(ext) {
|
|
return ext === "html"
|
|
}
|
|
|