mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 17:38:19 +08:00
framework: add multiple renderers support
This commit is contained in:
2 files changed
+29
-10
No files matched your search
@@ -73,7 +73,6 @@ export interface HydroResponse {
|
|||||||
attachment: (name: string, stream?: any) => void;
|
attachment: (name: string, stream?: any) => void;
|
||||||
addHeader: (name: string, value: string) => void;
|
addHeader: (name: string, value: string) => void;
|
||||||
}
|
}
|
||||||
export type RendererFunction = (name: string, context: Record<string, any>) => string | Promise<string>;
|
|
||||||
type HydroContext = {
|
type HydroContext = {
|
||||||
request: HydroRequest;
|
request: HydroRequest;
|
||||||
response: HydroResponse;
|
response: HydroResponse;
|
||||||
@@ -90,6 +89,21 @@ export type KoaContext = Koa.Context & {
|
|||||||
holdFiles: (string | File)[];
|
holdFiles: (string | File)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TextRenderer = {
|
||||||
|
output: 'html' | 'json' | 'text';
|
||||||
|
render: (name: string, args: Record<string, any>, context: Record<string, any>) => string | Promise<string>;
|
||||||
|
};
|
||||||
|
export type BinaryRenderer = {
|
||||||
|
output: 'binary';
|
||||||
|
render: (name: string, args: Record<string, any>, context: Record<string, any>) => Buffer | Promise<Buffer>;
|
||||||
|
};
|
||||||
|
export type Renderer = (BinaryRenderer | TextRenderer) & {
|
||||||
|
name: string;
|
||||||
|
accept: readonly string[];
|
||||||
|
priority: number;
|
||||||
|
asFallback: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const logger = new Logger('server');
|
const logger = new Logger('server');
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
export const koa = new Koa<Koa.DefaultState, KoaContext>({
|
export const koa = new Koa<Koa.DefaultState, KoaContext>({
|
||||||
@@ -170,14 +184,14 @@ export class HandlerCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderHTML(templateName: string, args: Record<string, any>) {
|
renderHTML(templateName: string, args: Record<string, any>) {
|
||||||
const type = templateName.split('.')[1];
|
const renderers = Object.values(this.ctx.server.renderers).filter((r) => r.accept.includes(templateName) || r.asFallback);
|
||||||
const engine = this.ctx.server.renderers[type] || (() => JSON.stringify(args, serializer(false, this)));
|
const topPrio = renderers.sort((a, b) => b.priority - a.priority)[0];
|
||||||
return engine(templateName, {
|
const engine = topPrio?.render || (() => JSON.stringify(args, serializer(false, this)));
|
||||||
|
return engine(templateName, args, {
|
||||||
handler: this,
|
handler: this,
|
||||||
UserContext: this.user,
|
UserContext: this.user,
|
||||||
url: this.url,
|
url: this.url,
|
||||||
_: this.translate,
|
_: this.translate,
|
||||||
...args,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,7 +352,7 @@ export class WebService extends Service {
|
|||||||
private wsLayers = [];
|
private wsLayers = [];
|
||||||
private captureAllRoutes = Object.create(null);
|
private captureAllRoutes = Object.create(null);
|
||||||
|
|
||||||
renderers: Record<string, RendererFunction> = Object.create(null);
|
renderers: Record<string, Renderer> = Object.create(null);
|
||||||
server = koa;
|
server = koa;
|
||||||
router = router;
|
router = router;
|
||||||
HandlerCommon = HandlerCommon;
|
HandlerCommon = HandlerCommon;
|
||||||
@@ -730,7 +744,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public registerRenderer(name: string, func: RendererFunction) {
|
public registerRenderer(name: string, func: Renderer) {
|
||||||
if (this.renderers[name]) logger.warn('Renderer %s already exists.', name);
|
if (this.renderers[name]) logger.warn('Renderer %s already exists.', name);
|
||||||
this.ctx.effect(() => {
|
this.ctx.effect(() => {
|
||||||
this.renderers[name] = func;
|
this.renderers[name] = func;
|
||||||
|
|||||||
@@ -199,7 +199,12 @@ const render = (name: string, state: any) => new Promise<string>((resolve, rejec
|
|||||||
|
|
||||||
export const inject = ['server'];
|
export const inject = ['server'];
|
||||||
export async function apply(ctx: Context) {
|
export async function apply(ctx: Context) {
|
||||||
ctx.server.registerRenderer('html', render);
|
ctx.server.registerRenderer('ui-default', {
|
||||||
ctx.server.registerRenderer('yaml', render);
|
name: 'ui-default',
|
||||||
ctx.server.registerRenderer('md', render);
|
output: 'html',
|
||||||
|
accept: [],
|
||||||
|
asFallback: true,
|
||||||
|
priority: 1,
|
||||||
|
render: (name, args, context) => render(name, { ...context, ...args }),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user