Permalink
Browse files

init commit

  • Loading branch information...
0 parents commit 1389354987f3f8bd84273813dc9684af1b65db02 @nicksweet committed Jul 21, 2012
Showing with 454 additions and 0 deletions.
  1. BIN .DS_Store
  2. +1 −0 .npmignore
  3. +125 −0 README.md
  4. +40 −0 lib/exe.coffee
  5. +88 −0 lib/templr.coffee
  6. +15 −0 package.json
  7. +60 −0 src/exe.js
  8. +125 −0 src/templr.js
Binary file not shown.
@@ -0,0 +1 @@
+.git*
@@ -0,0 +1,125 @@
+templr
+======
+
+Templr Compiles html files containing special `<tpl>` tags to javascript strings for use as client side templates. Templr also supports recursive imports of other html files with the special `<import>` tag. The stringifyed html is compressed by removing comments and unnecessary white space by default.
+
+Templr is handy if you do a lot of client side view rendering and are sick of having one giant html file and using a bunch of `<script type="text/template">` tags to write your client side templates. Templr assumes that your app is being bundeled up for the client using something like browserify, so the tpls object containing your stringifyed html templates is assigned to module.exports by default. If you'd rather just run the compiled template script directly in the browser and assign the tpls object to `window`, just use the `-b, --browser` flag.
+
+
+example
+=======
+
+Lets say you have the following html files:
+
+templates_a.html which contains:
+``` html
+<import updir/templates_b>
+
+<tpl name="file-a-tpl-a">
+ <div>
+ <h1>Hello form tpl A of file templates_a.html!</h1>
+ </div>
+</tpl>
+<tpl name="file-a-tpl-b">
+ <div>
+ <h1>hello from tpl B of file templates_a.html!</h1>
+ </div>
+</tpl>
+```
+
+updir/templates_b.html which contains:
+``` html
+<tpl name="file-b-tpl-a">
+ <div>
+ <h1>Hello form tpl A of file templates_b.html!</h1>
+ </div>
+</tpl>
+```
+
+and main.html which contains:
+``` html
+<import templates_a>
+
+<tpl name="main-a">
+ <div>
+ <a class="a" id="a" href="/url">Hello from tpl A of the root html file</a>
+ </div>
+</tpl>
+<tpl name="main-b">
+ <div>
+ <h1>Hello from tpl B of the root html file</h1>
+ </div>
+</tpl>
+```
+
+Now, to compile all the templates from your main html file --along with any templates from any imported files-- to a tpls object in to results.js just run `templr main.html -o results.js`. results.js will contain:
+
+``` js
+var tpls = {};
+
+tpls.main-a="<div><a class=\"a\"id=\"a\"href=\"/url\">Hello from tpl A of the root html file</a></div>";tpls.main-b="<div><h1>Hello from tpl B of the root html file</h1></div>";tpls.file-a-tpl-a="<div><h1>Hello form tpl A of file templates_a.html!</h1></div>";tpls.file-a-tpl-b="<div><h1>hello from tpl B of file templates_a.html!</h1></div>";tpls.file-b-tpl-a="<div><h1>Hello form tpl A of file templates_b.html!</h1></div>";
+
+module.exports = tpls;
+```
+
+Or to compile without compression, and target the browser run `templr main.html -nc -b -o results.js`. results.js will contain:
+
+``` js
+var tpls = {};
+
+
+tpls.main-a="
+ <div>
+ <a class=\"a\" id=\"a\" href=\"/url\">Hello from tpl A of the root html file</a>
+ </div>
+";
+
+tpls.main-b="
+ <div>
+ <h1>Hello from tpl B of the root html file</h1>
+ </div>
+";
+
+tpls.file-a-tpl-a="
+ <div>
+ <h1>Hello form tpl A of file templates_a.html!</h1>
+ </div>
+";
+
+tpls.file-a-tpl-b="
+ <div>
+ <h1>hello from tpl B of file templates_a.html!</h1>
+ </div>
+";
+tpls.file-b-tpl-a="
+ <div>
+ <h1>Hello form tpl A of file templates_b.html!</h1>
+ </div>
+";
+
+window.tpls = tpls;
+```
+
+usage
+=====
+
+````
+Usage: templr [root.html] {OPTIONS}
+
+Options:
+ --outfile, -o Write the the resulting javascript tpl object to the outfile given.
+ If unspecified, templr will write a js file in the same dir, with the same name as the entry html file
+ --watch, -w Watch the entry html file, aswell as all files in the import heirarchy for changes, recompiling on change.
+ --no-compress, -nc Compile to output file without removing comments and unnecessary white space.
+ --browser, -b Assign the tpl object in resulting js file to the window object for use in the browser.
+ If unspecified, the resulting tpl object will be assigned to module.exports.
+ --help, -h Show this message
+
+````
+
+install
+=======
+
+```
+npm install templr -g
+```
@@ -0,0 +1,40 @@
+Templr = require '../src/templr'
+args = process.argv
+
+help = """
+Usage: templr [root.html] [OPTIONS]
+
+Options:
+ --outfile, -o Write the the resulting javascript tpl object to the outfile given.
+ If unspecified, templr will write a js file in the same dir, with the same name as the entry html file
+ --watch, -w Watch the entry html file, aswell as all files in the import heirarchy for changes, recompiling on change.
+ --no-compress, -nc Compile to output file without removing comments and unnecessary white space.
+ --browser, -b Assign the tpl object in resulting js file to the window object for use in the browser.
+ If unspecified, the resulting tpl object will be assigned to module.exports.
+ --help, -h Show this message
+"""
+
+options =
+ watch: false
+ compress: true
+ src: if args[2] and not args[2].match(/^-/) then args[2] else './'
+ show_help: false
+
+for arg, index in args
+ #console.log arg
+ switch arg
+ when '-w', '--watch' then options.watch = true
+ when '-nc', '--no-compress' then options.compress = false
+ when '-b', '--browser' then options.browser = true
+ when '-o', '--out' then options.out_filename = args[index + 1]
+ when '-s', '--src' then options.src = args[index + 1]
+ when '-h', '--help' then options.show_help = true
+
+if options.show_help
+ console.log help
+else
+ templr = new Templr(options)
+ if options.watch is true
+ templr.watch()
+ else
+ templr.compile()
@@ -0,0 +1,88 @@
+fs = require 'fs'
+path = require 'path'
+
+class Templr
+ constructor: (option_args) ->
+ @files = {}
+ @compiling = false
+ @options =
+ watch: false
+ compress: true
+ src: './'
+
+ if option_args
+ for k,v of option_args
+ @options[k] = v
+
+ if path.extname(@options.src) is '.html'
+ if not @options.out_filename
+ file_dir = if path.dirname(@options.src) is '.' then '' else path.dirname(@options.src)
+ filename = path.basename(@options.src, '.html')
+ @options.out_filename = "#{file_dir}#{filename}.js"
+ @files[@options.src] = true
+
+ @get_imports(@options.src)
+ else if not path.extname(@options.src)
+ if not @options.out_filename
+ @options.out_filename = 'tpls.js'
+ files = fs.readdirSync @options.src
+ for file in files
+ if path.extname(file) is '.html'
+ file_path = "#{@options.src}#{file}"
+ @files[file_path] = true
+ else
+ console.log 'Templr can only compile .html files'
+ process.exit(1)
+
+ get_imports: (root) ->
+ src_file = fs.readFileSync root, 'utf8'
+ import_tags = src_file.match(/<import\s[\w\/.]{1,35}\s?>/g)
+ if import_tags
+ for tag in import_tags
+ import_file_name = tag.replace(/(<import\s)([\w\/.]{1,35})(\s?>)/, '$2')
+ import_file_name = "#{import_file_name}.html" if not path.extname(import_file_name)
+ @files[import_file_name] = true
+ @get_imports(import_file_name)
+
+ compile_file: (tpl) ->
+ tpls = tpl.replace(/<import\s[\w\/.]{1,35}\s?>/g, '').split(/<tpl /g)
+ compiled_tpls = ''
+ for tpl in tpls
+ cmpld_tpl = tpl
+ .replace(/"/gm, '\\"')
+ .replace(/^name=\\"/, 'tpls.')
+ .replace(/\\"\s?>\s?/, '="\n')
+ .replace(/<\/tpl>/, '";\n')
+ if @options.compress
+ cmpld_tpl = cmpld_tpl
+ .replace(/(\r\n|\n|\r)/gm, '')
+ .replace(/>\s+</g, '><')
+ .replace(/\s+/g, ' ')
+ .replace(/<!--(.*?)-->/g, '')
+ .replace(/([\w]{1,30}=\\"[\w]{1,30}\\")(\s)(.)/gm, '$1$3')
+ .replace(/(\s)(\/>)/g, '$2')
+ .replace(/(\=")(\s)(<)/g, '$1$3')
+ compiled_tpls += cmpld_tpl
+ return compiled_tpls
+
+ compile: ->
+ if not @compiling
+ @compiling = true
+ compiled_tpl = "var tpls = {};\n"
+ for file of @files
+ tpl = fs.readFileSync file, 'utf8'
+ compiled_tpl += @compile_file(tpl)
+ if @options.browser
+ compiled_tpl += '\nwindow.tpls = tpls;'
+ else
+ compiled_tpl += '\nmodule.exports = tpls;'
+ fs.writeFile "#{@options.out_filename}", compiled_tpl
+ console.log compiled_tpl
+ @compiling = false
+ watch: ->
+ @compile()
+ for file of @files
+ fs.watch file, =>
+ @compile()
+
+module.exports = Templr
@@ -0,0 +1,15 @@
+{
+ "name": "templr",
+ "version": "0.0.1",
+ "description": "Compile html files with containing special <tpl> tags to javascript strings for use as client side templates.",
+ "author": {
+ "name": "Nick Sweet",
+ "email": "nick@igloo.io"
+ },
+ "main": "src/templr.js",
+ "bin": {
+ "templr": "src/exe.js"
+ },
+ "dependencies":{
+ }
+}
@@ -0,0 +1,60 @@
+#!/usr/bin/env node
+
+// Generated by CoffeeScript 1.3.3
+(function() {
+ var Templr, arg, args, help, index, options, templr, _i, _len;
+
+ Templr = require('../src/templr');
+
+ args = process.argv;
+
+ help = "Usage: templr [root.html] [OPTIONS]\n\nOptions:\n --outfile, -o Write the the resulting javascript tpl object to the outfile given.\n If unspecified, templr will write a js file in the same dir, with the same name as the entry html file\n --watch, -w Watch the entry html file, aswell as all files in the import heirarchy for changes, recompiling on change.\n --no-compress, -nc Compile to output file without removing comments and unnecessary white space.\n --browser, -b Assign the tpl object in resulting js file to the window object for use in the browser.\n If unspecified, the resulting tpl object will be assigned to module.exports.\n --help, -h Show this message ";
+
+ options = {
+ watch: false,
+ compress: true,
+ src: args[2] && !args[2].match(/^-/) ? args[2] : './',
+ show_help: false
+ };
+
+ for (index = _i = 0, _len = args.length; _i < _len; index = ++_i) {
+ arg = args[index];
+ switch (arg) {
+ case '-w':
+ case '--watch':
+ options.watch = true;
+ break;
+ case '-nc':
+ case '--no-compress':
+ options.compress = false;
+ break;
+ case '-b':
+ case '--browser':
+ options.browser = true;
+ break;
+ case '-o':
+ case '--out':
+ options.out_filename = args[index + 1];
+ break;
+ case '-s':
+ case '--src':
+ options.src = args[index + 1];
+ break;
+ case '-h':
+ case '--help':
+ options.show_help = true;
+ }
+ }
+
+ if (options.show_help) {
+ console.log(help);
+ } else {
+ templr = new Templr(options);
+ if (options.watch === true) {
+ templr.watch();
+ } else {
+ templr.compile();
+ }
+ }
+
+}).call(this);
Oops, something went wrong.

0 comments on commit 1389354

Please sign in to comment.