Skip to content

Build Time Templating

Sammy Jelin edited this page Dec 30, 2013 · 10 revisions

We use build-time templating to do three things:

  1. Detect the details about the build environment (e.g. was it compiled in debug mode?)
  2. Inject global variables into files, regardless of the file type.
  3. Do basic textual transformations on code.

You can think of it as similar to the C pre-processor's #DEFINE, but with different syntax and usable outside of just the code files. The commands used in our build-time templating are called [macros](http://en.wikipedia.org/wiki/Macro_(computer_science\))

Why make our own engine?

  • We need it to integrate into our build process (build environment variables, etc)
  • It was easy (<250 lines)
  • We wanted syntax which looked similar to normal templating syntax (e.g. {{VAR_NAME}})
  • We wanted to be able to do somewhat complex text transformations (think C-style #DEFINE functions)

List of build environment variables

  • DEBUG - Boolean
  • LOCAL - Boolean. States if the code was intended to be run off the local server
  • NATIVE - Boolean. States if the code was built to be run in a native app or in the browser
  • PLATFORM - String. Describes the platform the code was built for (e.g. web, iOS)
  • SERVER - String. The URL for the server (e.g. http://localhost:8888, http://www.chkex.com)

Syntax

There are two types of macros: constants and functions.

Constants are defined using the syntax:

	{{VAR_NAME}} = value

The constant can then be subsituted into any file using the syntax {{VAR_NAME}}. So, for instance, if you had the following in your macros file:

	{{DOMAIN_NAME}} = http://www.chkex.com

And in your code you wrote:

	alert("You are using {{DOMAIN_NAME}}");

The resulting code would be:

	alert("You are using http://www.chkex.com");

Functions are defined similarly. The following syntax is used:

	{{FUN_NAME}} = (param1, param2, ...) -> replacement

The function is then invoked for build-time substitution using the following syntax {{FUN_NAME: param1, param2, ...}}. So for instance if you had the following in the macros folder:

	{{ERR}} = (msg) -> alert(msg); throw new Error(msg);

And in your code you wrote:

	{{ERR: "BUG!"}}

The resulting code would be:

	alert("BUG!"); throw new Error("BUG!");

IF_ Macros

Sometimes, the above macros are not enough. For those cases, we have the option of the IF_ macros. For instance, suppose you want a button to only appear in debug mode? Then you could write the following:

<body>
    <div>
        ...website stuff...
    </div>
IF_DEBUG
    <a class="debug-button">Start Debugging!</a>
END_IF
</body>

When the code is compiled in debug mode, the button will be included. Otherwise, it will not.

These macros always follow the form of IF_VARNAME or IF_NOT_VARNAME (where "VARNAME" is the name of a variable) on a line all by itself followed by END_IF on a line all by itself. There is no ELSE or ELSE_IF, but you can nest these statements.

Clone this wiki locally