Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

pull request 'dustc' command line tool merged.

  • Loading branch information...
commit f131f2f79a114933d1402e49c7a5d6f5e1a7a449 1 parent a4d52e0
Jairo de Morais authored
Showing with 338 additions and 1 deletion.
  1. +267 −1 README.md
  2. +70 −0 bin/dustc
  3. +1 −0  package.json
268 README.md
View
@@ -52,4 +52,270 @@ For Linkedin Dustjs
To render compiled templates in the browser:
- <script src="dust-core-0.3.0.min.js"></script>
+ <script src="dust-core-0.4.0.min.js"></script>
+
+To compile a template on the command line, use the dustc command.
+Its syntax is:
+
+ dustc [{-n|--name}=<template_name>] {inputfilename|-} [<outputfilename>]
+
+For example, to compile a template on the command line and have it
+registered under the same name as the source file:
+
+ $ dustc template.html
+
+You can customize the name under which the template is registered:
+
+ $ dustc --name=mytemplate template.html
+
+**Support logic helper @if**
+----------------------------
+
+Dust supports the exists (?) and not exists (^?). Nested exists block easily allow for (exp1 AND exp2 AND exp3), but (exp1 OR exp2 ) is not possible.@if helper comes handy in cases where an OR operation is required.
+
+*Example 1:*
+
+ {@if cond="('{x}'.length || '{y}'.length ) || (2 > 3) && {a}-{b} == 9"}
+ render if
+ {:else}
+ render else
+ {/if}
+
+**Section index for lists of maps stored in the dust context**
+---------------------------------------------------
+
+*Example 2: $idx is the Loop index in dust #loop*
+
+ {#people}
+ <li class="card
+ {@if cond="({$idx} == {$len})"}last{/if}" data-member-id="{id}" id="card-{id}">
+ </li>
+ {/people}
+
+**Section size for lists of maps stored in the dust context**
+----------------------------------------
+
+*Example 3: $len, Loop size in dust #loop*
+
+ {#people}
+ <li class="card {@if cond="({$len} + 1) % 2 == 0"} odd {:else} even {/if} " data-member-id="{id}" id="card\-{id}"> </li>
+ {/people}
+
+*Example 4: Inside lists of primitives,$idx and $len cannot be used, and {@idx} can be used instead*
+
+ JSON : {"skills": ["jasmine", "qunit", "javascript"]}
+ {#skills}
+ <li>
+ <span class='{@idx}
+ {@if cond="{.} == '{skills}'.split(',').length -1"}
+ last
+ {/if}
+ {/idx}'>
+ {.}</span>
+ </li>
+ {/skills}
+
+*Example 5: @if with else*
+
+ {@if cond="'{names}'.split(',').length == 3 "}
+ {@pre.i18n key="yes" text="Yes, there are 3 names"/}
+ {:else}
+ {@pre.i18n key="no" text="No, there are less than 3 names"/}
+ {/if}
+
+Global Aliases
+----------------------
+
+Most often we tend to reuse the same data in the template again and again ... One way to avoid been repetitive is use aliases. So a common question was, how does dust support this ?
+
+Well, in dust there is more than one way neat way to do this.
+
+*Use Inline Partials*
+
+Inline partials never output content themselves, and are always global to the template in which they are defined, so the order of their definition has no significance.
+
+Key points to note : They are global to the template., there is no ordering and can be defined anywhere
+
+*Step 1* create global alias
+
+ {<greeting}Hello, Hola{/greeting}
+
+*Step 2*
+
+ {#names}
+ {.} {+greeting/}
+ {/names}
+
+ {#projects}
+ {.} {+greeting/}
+ {/projects}
+
+
+
+Block Aliases
+----------------------
+Inline parameters appear within the section's opening tag. Parameters are separated by a single space.
+
+ {#profile bar="baz" bing="bong"}
+ {name}, {bar}, {bing}
+ {/profile}
+
+*There are 3 flavors*
+
+ {#test greeting="hello"} // constant hello
+ {greeting}
+ {/test}
+
+ {#test greeting=hello} // looks for a json context hello in the JSON hierarchy
+ {greeting}
+ {/test}
+
+ {#test greeting="{hello}"} // resolves hello when greeting is referenced in the block and it resolves to the first one in the hierarchy
+ {greeting}
+ {/test}
+
+
+Template Inheritance
+----------------------------
+
+Dust by default allows template inheritance with the concept of partials and inline partials
+
+Example 1:
+--------------------
+
+*partial.tl ( this serves as the base template )*
+
+
+ {+greeting} Hola {/greeting}
+ {+world} World {/world}
+
+
+*main_without_override.tl ( this serves as the child template )*
+
+
+ {>partial/}
+
+*output*
+
+When the main_without_override.tl is rendered ...
+
+ Hola
+ World
+
+main_with_override.tl ( this serves as the child template )
+-----------------
+
+ {>partial/}
+ {<greeting}
+ Hello
+ {/greeting}
+
+*output*
+
+
+When the main_with_override.tl is rendered ...
+
+ Hello
+ World
+
+
+*main_with_loops.tl*
+
+
+ {>partial/}
+ {#projects
+ {<greeting}
+ Hello {.name}
+ {/greeting}
+ {/projects}
+ {<world}{/world} {! override to print nothing !}
+
+
+*output*
+
+
+When the main_with_loops.tl is rendered ... ( says projects has three entries with the name field )
+
+ Hello project 1
+ Hello project 2
+ Hello project 3
+
+Example 2
+---------------
+
+*base.tl*
+
+ {+greeting}hello{/greeting}
+ {+world/}
+
+*footer.tl*
+
+ Common footer
+
+*base_end.tl*
+
+
+ {>"footer"/}
+ {+bye} bye {/bye}
+
+
+*main.tl*
+
+ {>"head"/}
+ BODY
+ {>"foot"/}
+
+*head.tl*
+
+ {>"base"/}
+ {<world} World {/world}
+ START
+
+*foot.tl*
+
+ END
+ {>"base"/}
+ {<greeting}bye{/greeting}
+
+*foot_with_no_end.tl*
+
+ END
+ {>"base_end"/}
+ {<bye} {! Do not print bye | }{/bye}
+
+
+
+
+*output ( when I render main.tl with foot.tl )*
+
+hello World START BODY END bye
+
+
+*output ( when I render main.tl with foot_with_no_end.tl )*
+
+hello World START BODY END common footer
+
+
+Composable templates?
+---------------------
+
+ {^xhr}
+ {>base_template/}
+ {:else}
+ {+main/}
+ {/xhr}
+ {<title}
+ Child Title
+ {/title}
+ {<main}
+ Child Content
+ {/main}
+
+
+
+Dynamic Partials
+----------------
+
+The name of the partial can be determined at render time. Primarily useful when a partial is loaded based on the ab-test key.
+
+{>"/path/{abkey}.tl"/}
70 bin/dustc
View
@@ -0,0 +1,70 @@
+#!/usr/bin/env node
+
+var path = require('path'),
+ fs = require('fs'),
+ sys = require('util'),
+ dust = require('../lib/dust'),
+ args = process.argv.slice(1),
+ name = null;
+
+args = args.filter(function (arg) {
+ var match;
+
+ if (match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i)) { arg = match[1] }
+ else { return arg }
+
+ switch (arg) {
+ case 'h':
+ case 'help':
+ sys.puts("usage: dustc [{-n|--name}=<template_name>] {sourcefilename|-} [destination]");
+ process.exit(0);
+ case 'n':
+ case 'name':
+ name = match[2];
+ break;
+ }
+});
+
+var input = args[1];
+var output = args[2];
+if (output) {
+ output = path.resolve(process.cwd(), output);
+}
+
+var fd, template;
+
+if (! input) {
+ sys.puts("dustc: no input files");
+ process.exit(1);
+}
+
+var parseDustFile = function (e, data) {
+ if (e) {
+ sys.puts("dustc: " + e.message);
+ process.exit(1);
+ }
+
+ template = dust.compile(data, name || input);
+ if (output) {
+ fd = fs.openSync(output, "w");
+ fs.writeSync(fd, template, 0, "utf8");
+ } else {
+ sys.print(template);
+ }
+};
+
+if (input != '-') {
+ fs.readFile(input, 'utf-8', parseDustFile);
+} else {
+ process.stdin.resume();
+ process.stdin.setEncoding('utf8');
+
+ var buffer = '';
+ process.stdin.on('data', function(data) {
+ buffer += data;
+ });
+
+ process.stdin.on('end', function() {
+ parseDustFile(false, buffer);
+ });
+}
1  package.json
View
@@ -17,6 +17,7 @@
"test" : "node test/jasmine-test/server/specRunner.js",
"start": "node src/build.js"
},
+ "bin": { "dustc": "./bin/dustc" },
"main": "./lib/dust",
"repository": {
"type": "git",
Please sign in to comment.
Something went wrong with that request. Please try again.