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" }