nxus / templater

The template manager for Nxus applications
1 stars 0 forks source link

Documentation: practices for reusable templates #21

Open loppear opened 7 years ago

loppear commented 7 years ago

Goals

  1. Users are not required to provide a template implementation in order to use a module (provide a default base implementation)
  2. Users can override templates to provide their own implementation (use default() when registering)
  3. Users have access to the default implementation (via render()) when wrapping/overriding. (register the base name as well)
  4. Users are able to override reasonably granular parts of the template rather than all-or-nothing (decompose with render())
  5. Template namespace is reasonably structured to make it clear where to find templates and provide granular override (register reuse-specific names based on module/model)

    Approach

For reusable modules to provide a base template implementation

  1. name the template with the module name prefix e.g. users-login
  2. register the template with default() and within the 'page' wrapper, e.g. templater.default().template('path/users-login.ejs', 'page')
  3. decompose the template where reasonable into render calls to partial templates e.g. render('users-login-form-fields') calls so that the partial templates can be overridden rather than overriding the whole thing.

Additionally, for modules that provide default functionality that may be used repeatedly (per model, say), we typically construct a specific name and register the default implementation under that name - this template doesn't exist but can be implemented by an end-user:

  1. templater.default().template('path/web-controller-list.ejs', 'page', 'yourmodule-yourmodel-list')

Good practice here is to also register the template once at the base name, web-controller-list, so that an actual implementation of yourmodule-yourmodel-list can render('web-controller-list') to simply wrap the base implementation (and/or any specific overridden template implementations).

Questions

  1. Is overriding the primary module's template names (in their namespace) better than a naming convention that looks for e.g. appname-module-template before falling back to module-template?
  2. Should include be discouraged or only for reusable modules [Luke: I think include is fine in end-use templates, rather than needing to add all templates into the registered namespace]
ScottMaxson commented 7 years ago

Clarifying question: in point#3 "decompose the template..." I was thinking this was done with include calls in the parent EJS template. How is the render('...') example you give here different?

loppear commented 7 years ago

@ScottMaxson render is our preferred alternative for include that lets other modules / end-user replacement of the template (it's a template name rather than a relative path).

mjreich commented 7 years ago

👍 let's definitely add into the docs as well.