handlebar

Once you know the basics of Handlebars, the following should be clear. You need to understand the meaning of partials, helpers, and contextForDynamic.

Partials

You have access everywhere to the full list of partials in the partials directory. A partial is specified within a Handlebars file of the same name (not counting the file extension). You can add as many as you like, and create as many subdirectories as you need. But, there are two naming constraints:

  1. The name of each partial must be unique.
  2. Each partial file should have an '.hbs' extension.

This example shows some subdirectories and a number of examples. Many clauses that appear in multiple types of files are used.

Helpers

There are three sources for helpers currently at your disposal in geenee:

  1. geenee provides the full use of the just-handlebars-helpers package. That will probably be enhanced or replaced with handlebars-helpers soon.

    For instance, {{capitalizeFirst 'just wow'}} produces Just wow and {{and value1 value2}} will result in the value1 && value2 (useful for `{{#if}} for instance).

  2. There are a few included helpers:

    • {{safe text}} shows text without escape characters. That is helpful if you are getting unwanted escapes of certain special characters such as quote marks.
    • {{curly true}} produces a left curly brace {, {{curly false}} returns }.
  3. The helpers directory should contain any helpers that you create. Since geenee is written with typescript, your helpers should be in typescript as well, with a .ts extension.

    See this example for some ideas.

Context

Your .hbs templates for standard, static and dynamic files are passed a rich context automatically that is derived from your template's configuration and values in an ns file.

The context varies a bit for each of the three types of files (standard, static and dynamic), as specified below.

Shared Context Elements

names

geenee context includes a names object that contains, minimally, these values for naming an instance for a file:

  • singular: the name starting with uppercase [useful for a component class, for instance]
  • singularLowercase: component [useful for a component instance]
  • plural: a pluralized version of singular
  • pluralLowercase: a pluralized version of singularLowercase

For instance, this line in an .hbs file:

describe('{{names.singular}}', () => {

where a current component is "sample" will produce Sample.

General Info

  • nsInfo: the contents of the ns file for the code base
  • config: the contents of the config for the template
  • general: an object with info that a template can use. There are a few automatically included items:

    1. If there is a package.json for a code base, then general.json will show the contents.

      For instance, {{general.json.name}} will show the name of the file.

    2. The current code directory is general.codeDir.

    Other than that, the template developer must request what you want the code base developer to put into general. Currently, general is not accessed within dynamic context, but it does appear in standard and static contexts.

Static Context

In addition to the shared elements above, a static context contains these elements, specified in the ns file for the instance:

  • slug
  • specs
  • A number of fields about the dynamic hierarchy that can be useful:
    • sources: all units. For each, there is a sourceConst which is recommended as a consistent way to refer programmatically to the unit, and sourceId if the ns file defines it in a backend section.
    • types: all types. For each, there are typeConst and typeId, analogous to sourceConst and sourceId for types.
    • actionTypes. For each there is actionType and actions. Each action has actionConst and actionId.

Dynamic Context

In addition to the shared elements above, a dynamic context contains these elements:

  • nodeTypes, dataTypes, and boilerPlateInfo, derived from the config
  • stackInfo: info about the stack (derived from the ns file)
  • childrenInfo: info about the children in a unit for a given component (again, derived from the ns file)

For instance, in this sample config file you can find a list of dataFunctionTypes that refer to an earlier list of componentTypes. When an ns file (see the sample ns file) for the template uses a dataFunctionType, geenee loads into contextForDynamic an object boilerPlateInfo that includes componentType for any given file.

So your partials can refer to boilerPlateInfo.componentType. For an example, see the next section (Conditional Branching).

As with all Handlebars helpers, you must explicitly specify their parameters and they do not have access to the full geenee contextForDynamic.

Conditional Branching

geenee provides the full use of the just-handlebars-helpers package for the sake of basic conditions. For instance, that permits you to check a value in your contextForDynamic and conditionally branch.

Here is an example of conditional branching from contextForDynamic. One element of the contextForDynamic is boilerPlateInfo, which contains a key componentType. There is some basic branching here based on that value. Another key of boilerPlateInfo is nodeType, which is used in an embedded branch.

fileInfo

The fileInfo object contains two keys, useful for standard geenee file identification when storing and retrieving custom code modifications.

  • unitName: a name for a dynamic unit, or group of files.
  • component: the specific dynamic component or specific file.

This gets inserted at the beginning of a file in an ns__file comment for the sake of geenee. You normally don't have to do anthing with it.