Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] allow template to be function in vue-server-renderer #9324

Merged
merged 9 commits into from Jan 18, 2019
@@ -23,7 +23,7 @@ export type RenderOptions = {
directives?: Object;
isUnaryTag?: Function;
cache?: RenderCache;
template?: string;
template?: string | (content: string, context: any) => string;

This comment has been minimized.

Copy link
@lbogdan

lbogdan Jan 19, 2019

Contributor

Wouldn't (context, content) be a better API, consistent with, for example, vuex actions, which have context as their first argument?

inject?: boolean;
basedir?: string;
shouldPreload?: Function;
@@ -82,14 +82,26 @@ export function createRenderer ({
}, cb)
try {
render(component, write, context, err => {
if (err) {
return cb(err)
}
if (context && context.rendered) {
context.rendered(context)
}
if (template) {
result = templateRenderer.renderSync(result, context)
}
if (err) {
cb(err)
try {
const res = templateRenderer.render(result, context)
if (typeof res !== 'string') {
// function template returning promise
res
.then(html => cb(null, html))
.catch(cb)
} else {
cb(null, res)
}
} catch (e) {
cb(e)
}
} else {
cb(null, result)
}
@@ -119,6 +131,8 @@ export function createRenderer ({
})
}
return renderStream
} else if (typeof template === 'function') {
throw new Error(`function template is only supported in renderToString.`)
} else {
const templateStream = templateRenderer.createStream(context)
renderStream.on('error', err => {
@@ -11,7 +11,7 @@ import type { ParsedTemplate } from './parse-template'
import type { AsyncFileMapper } from './create-async-file-mapper'

type TemplateRendererOptions = {
template: ?string;
template?: string | (content: string, context: any) => string;
inject?: boolean;
clientManifest?: ClientManifest;
shouldPreload?: (file: string, type: string) => boolean;
@@ -42,7 +42,7 @@ type Resource = {
export default class TemplateRenderer {
options: TemplateRendererOptions;
inject: boolean;
parsedTemplate: ParsedTemplate | null;
parsedTemplate: ParsedTemplate | Function | null;
publicPath: string;
clientManifest: ClientManifest;
preloadFiles: Array<Resource>;
@@ -55,8 +55,12 @@ export default class TemplateRenderer {
this.inject = options.inject !== false
// if no template option is provided, the renderer is created
// as a utility object for rendering assets like preload links and scripts.
this.parsedTemplate = options.template
? parseTemplate(options.template)

const { template } = options
this.parsedTemplate = template
? typeof template === 'string'
? parseTemplate(template)
: template
: null

// function used to serialize initial state JSON
@@ -89,12 +93,17 @@ export default class TemplateRenderer {
}

// render synchronously given rendered app content and render context
renderSync (content: string, context: ?Object) {
render (content: string, context: ?Object): string | Promise<string> {
const template = this.parsedTemplate
if (!template) {
throw new Error('renderSync cannot be called without a template.')
throw new Error('render cannot be called without a template.')
}
context = context || {}

if (typeof template === 'function') {
return template(content, context)
}

if (this.inject) {
return (
template.head(context) +
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.