- Start support for auto-generated routes using UniversalPath
All checks were successful
continuous-integration/drone/push Build is passing

- Start support for custom view engine props & functions
- Start login template and namespace
This commit is contained in:
2021-06-29 01:44:07 -05:00
parent faa8a31102
commit cf6d14abca
9 changed files with 172 additions and 14 deletions

View File

@@ -17,14 +17,20 @@ export class PugViewEngine extends ViewEngine {
public renderByName(templateName: string, locals: { [p: string]: any }): string | Promise<string> {
let compiled = this.compileCache[templateName]
if ( compiled ) {
return compiled(locals)
return compiled({
...this.getGlobals(),
...locals,
})
}
const filePath = this.resolveName(templateName)
compiled = pug.compileFile(filePath.toLocal, this.getOptions(templateName))
this.compileCache[templateName] = compiled
return compiled(locals)
return compiled({
...this.getGlobals(),
...locals,
})
}
/**
@@ -39,4 +45,8 @@ export class PugViewEngine extends ViewEngine {
globals: [],
}
}
getFileExtension(): string {
return '.pug'
}
}

View File

@@ -2,6 +2,7 @@ import {AppClass} from '../lifecycle/AppClass'
import {Config} from '../service/Config'
import {Container} from '../di'
import {ErrorWithContext, UniversalPath} from '../util'
import {Routing} from '../service/Routing'
/**
* Abstract base class for rendering views via different view engines.
@@ -9,6 +10,8 @@ import {ErrorWithContext, UniversalPath} from '../util'
export abstract class ViewEngine extends AppClass {
protected readonly config: Config
protected readonly routing: Routing
protected readonly debug: boolean
protected readonly namespaces: {[key: string]: UniversalPath} = {}
@@ -16,6 +19,7 @@ export abstract class ViewEngine extends AppClass {
constructor() {
super()
this.config = Container.getContainer().make(Config)
this.routing = Container.getContainer().make(Routing)
this.debug = (this.config.get('server.mode', 'production') === 'development'
|| this.config.get('server.debug', false))
}
@@ -41,6 +45,30 @@ export abstract class ViewEngine extends AppClass {
*/
public abstract renderByName(templateName: string, locals: {[key: string]: any}): string | Promise<string>
/**
* Get the file extension of template files of this engine.
* @example `.pug`
*/
public abstract getFileExtension(): string
/**
* Get the global variables that should be passed to every view rendered.
* @protected
*/
protected getGlobals(): {[key: string]: any} {
return {
app: this.app(),
config: (key: string, fallback?: any) => this.config.get(key, fallback),
asset: (...parts: string[]) => this.routing.getAssetPath(...parts).toRemote,
vendor: (namespace: string, ...parts: string[]) => this.routing.getVendorPath(namespace, ...parts).toRemote,
}
}
/**
* Register a path as a root for rendering views prefixed with the given namespace.
* @param namespace
* @param basePath
*/
public registerNamespace(namespace: string, basePath: UniversalPath): this {
if ( namespace.startsWith('@') ) {
namespace = namespace.substr(1)
@@ -50,6 +78,10 @@ export abstract class ViewEngine extends AppClass {
return this
}
/**
* Given the name of a template, get a UniversalPath pointing to its file.
* @param templateName
*/
public resolveName(templateName: string): UniversalPath {
let path = this.path
if ( templateName.startsWith('@') ) {
@@ -66,13 +98,18 @@ export abstract class ViewEngine extends AppClass {
templateName = parts.join(':')
}
if ( !templateName.endsWith('.pug') ) {
templateName += '.pug'
if ( !templateName.endsWith(this.getFileExtension()) ) {
templateName += this.getFileExtension()
}
return path.concat(...templateName.split(':'))
}
/**
* Given the name of a template, get a UniversalPath to the root of the tree where
* that template resides.
* @param templateName
*/
public resolveBasePath(templateName: string): UniversalPath {
let path = this.path
if ( templateName.startsWith('@') ) {