diff --git a/changelog b/changelog index 89673887b..7947fd9a1 100644 --- a/changelog +++ b/changelog @@ -2,4 +2,5 @@ 移除了 ctx.app (请使用 ctx.root) 移除了 ctx.options (请使用 ctx.root.config) serializer: 移除 showDisplayName 参数 -移除了 loader.addScript, loader.addon 函数 \ No newline at end of file +移除了 loader.addScript, loader.addon 函数 +移除了 Hydro.module.render (请使用 ctx.server.registerRenderer) \ No newline at end of file diff --git a/framework/framework/base.ts b/framework/framework/base.ts index 052d61781..32b076aad 100644 --- a/framework/framework/base.ts +++ b/framework/framework/base.ts @@ -77,10 +77,7 @@ export default (logger, xff, xhost) => async (ctx: KoaContext, next: Next) => { } response.type = 'application/json'; } else if (response.template) { - const s = response.template.split('.'); - let templateName = `${s[0]}.${args.domainId}.${s[1]}`; - if (!global.Hydro.ui.template[templateName]) templateName = response.template; - response.body = await handler.renderHTML(templateName, response.body || {}); + response.body = await handler.renderHTML(response.template, response.body || {}); response.type = 'text/html'; } } diff --git a/framework/framework/server.ts b/framework/framework/server.ts index 9f06935a8..09897f36b 100644 --- a/framework/framework/server.ts +++ b/framework/framework/server.ts @@ -68,6 +68,7 @@ export interface HydroResponse { attachment: (name: string, stream?: any) => void; addHeader: (name: string, value: string) => void; } +export type RendererFunction = (name: string, context: Record) => string | Promise; type HydroContext = { request: HydroRequest; response: HydroResponse; @@ -163,8 +164,7 @@ export class HandlerCommon { renderHTML(templateName: string, args: Record) { const type = templateName.split('.')[1]; - const engine = global.Hydro.module.render[type] - || (() => JSON.stringify(args, serializer(false, this))); + const engine = this.ctx.server.renderers[type] || (() => JSON.stringify(args, serializer(false, this))); return engine(templateName, { handler: this, UserContext: this.user, @@ -316,6 +316,7 @@ export class WebService extends Service { private wsLayers = []; private captureAllRoutes = {}; + renderers: Record = {}; server = koa; router = router; HandlerCommon = HandlerCommon; @@ -657,6 +658,14 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`); HandlerCommon.prototype[val] = MixinClass[val]; } } + + public registerRenderer(name: string, func: RendererFunction) { + if (this.renderers[name]) logger.warn('Renderer %s already exists.', name); + this.renderers[name] = func; + this[Context.current]?.on('dispose', () => { + delete this.renderers[name]; + }); + } } declare module 'cordis' { diff --git a/packages/hydrooj/src/interface.ts b/packages/hydrooj/src/interface.ts index aab11e8f3..45e0d3bfc 100644 --- a/packages/hydrooj/src/interface.ts +++ b/packages/hydrooj/src/interface.ts @@ -802,7 +802,6 @@ export interface ModuleInterfaces { callback: (this: Handler, args: Record) => Promise; }; hash: (password: string, salt: string, user: User) => boolean | string | Promise; - render: (name: string, state: any) => string | Promise; } export interface HydroGlobal { diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 7fcb5aae1..7657b8445 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -78,6 +78,12 @@ export class Handler extends HandlerOriginal { constructor(_, ctx: Context) { super(_, ctx); this.ctx = ctx.extend({ domain: this.domain }); + this.renderHTML = ((orig) => function (name: string, args: Record) { + const s = name.split('.'); + let templateName = `${s[0]}.${args.domainId}.${s[1]}`; + if (!global.Hydro.ui.template[templateName]) templateName = name; + return orig(templateName, args); + })(this.renderHTML).bind(this); } async onerror(error: HydroError) { diff --git a/packages/ui-default/backendlib/template.ts b/packages/ui-default/backendlib/template.ts index 768ec2b40..aea026729 100644 --- a/packages/ui-default/backendlib/template.ts +++ b/packages/ui-default/backendlib/template.ts @@ -181,8 +181,9 @@ const render = (name: string, state: any) => new Promise((resolve, rejec }); }); +export const inject = ['server']; export async function apply(ctx: Context) { - ctx.provideModule('render', 'html', render); - ctx.provideModule('render', 'yaml', render); - ctx.provideModule('render', 'md', render); + ctx.server.registerRenderer('html', render); + ctx.server.registerRenderer('yaml', render); + ctx.server.registerRenderer('md', render); }