Coder Social home page Coder Social logo

require-handlebars-plugin's Introduction

Require.js Handlebars Plugin

devDependency Status

Requirements

Should work in both the java and node build environments.

Require.js >= 2.1.x (The last tag to work for Require < 2.1 is the 0.3.3 tag)

Usage

Write a template ( path: App/Template/One.hbs ):

<div class="best plugin ever">
  This is my {{ adjective }} template.

  {{! To include a partial: }}
  {{! just provide the path to the partial without the extension }}

  {{> App/Template/CoolPartial }}

  {{! the path can also be relative to the current template: }}
  {{> ./coolPartial }}
</div>

Here's the partial (optional) ( path : App/Template/CoolPartial.hbs )

<div>
  {{! This can obviously have it's own partials, etc, etc }}
  I am a partial
</div>

Installation

Clone this repo* or use bower to add require-handlebars-plugin to your project (typically in you lib/ directory) and make sure you tell requirejs about the new hbs plugin by editing your requirejs.conf.js file (you can also pass a few options):

require.config({
	paths: {
		hbs: 'lib/require-handlebars-plugin/hbs'
	},
	hbs: { // optional
		helpers: true,            // default: true
		templateExtension: 'hbs', // default: 'hbs'
		partialsUrl: ''           // default: ''
	}
});

partialsUrl: base url for loading partials so that you don't have to provide the full path every time you need to load a partial within a template.

Then require your templates like so:

require(['hbs!App/Template/One'], function ( tmplOne ) {
  // Use whatever you would to render the template function
  document.body.innerHTML = tmplOne({adjective: "favorite"});
});

And then the output into your body would be as follows:

<div class="best plugin ever">
  This is my favorite template.

  <div>
    I am a partial
  </div>
</div>

YAY!

* Note that if you clone the require-handlebars-plugin repository into an existing git repository, the existing repo will not include the files within the newly-cloned require-handlebars-plugin repo, because git ignores all subfolders which are git repos of their own. Look into git's submodules feature as a way to solve this issue.

i18n

As of the latest version. This functionality has been removed. Probably use format-js for this.

Helpers

Just put your helpers in templates/helpers/* and they'll automagically get pulled in as long as you write them as modules.

I find that many helpers are good helpers in regular code as well, so the following is a good practice:

define('templates/helpers/roundNumber', ['handlebars'], function ( Handlebars ) {
  function roundNumber ( context, options ) {
    // Simple function for example
    return Math.round( context );
  }
  Handlebars.registerHelper( 'roundNumber', roundNumber );
  return roundNumber;
});

Then in your templates, you can just do:

{{roundNumber Data.ThreeFourths}}

The system will make sure these modules are pulled in automatically from that directory. But if in your app, you need a rounding module (perhaps in a view/datanormalization place), you could do this:

require(['templates/helpers/roundNumber'], function ( roundNumber ) {
  var threeFourths = (3/4);
  alert( roundNumber( threeFourths ));
});

It's just a module that happens to register itself.

You can specify a helper path callback in the config. The callback should be a function that gets a name of a helper as the only argument and returns the full path to be require()-d, e.g., the following callback allows for automatic loading of helper modules written in CoffeeScript (via the require-cs plugin) under a non-standard location:

require({
  hbs : {
    helperPathCallback: function(name) {return 'cs!/helpers/' + name;}
  }
}, ['main'])

Meta Data

Any template that begins with a comment, with only a valid json object in it will be read in as meta data for the template.

I encourage you to list the name of the template and give a description, though these aren't strictly necessary.

Styles

If you want to build stylesheets that are comprised of only styles needed by the templates that your app uses, I encourage you to add a styles property to the meta info:

{{!
{
  "name" : "template1",
  "description" : "A nice template.",
  "styles" : ["templatecss"]
}
}}

This will inject a link tag in dev mode to load in this style dynamically. At build time, a screen.build.css is created. At this time it is just a list of import statements. These can be inlined by many existing tools. Eventually I'd love it to just happen.

De-duping happens automatically, so don't worry if multiple templates require the same styles. The styles are injected in the order that they are read in, so usually from least specific to most specific. This is usually what you want, but know that if you do weird things, it could break.

Introspection

In dev mode a few properties are added to your function (an object in javascript) as a helper with debugging and as a testing plug-point.

Those variables look like the following:

require(['hbs!template/one'], function ( tmplOne ) {
  console.log(
    'Variables referenced in this template: ',                     tmplOne.vars,
    'Partials/templates that this file directly depends on: ',     tmplOne.deps,
    'Helpers that this template directly depends on: ',            tmplOne.helpers,
    'The metadata object at the top of the file (if it exists): ', tmplOne.meta
  );
});

Note: All of these go away after a build, as they just take up space with data that is known at build time, which is the ideal time to get stuff figured out (speed-wise).

Builds

As long as all of your paths match up, this should precompile all of your templates and include them in the build.

You can stub out the hbs plugin in the build using stubModules the same way you would for other plugins that inline the final function. Your helpers and compiled templates still need to load Handlebars though, so you'll need to make sure they load the runtime version of Handlebars included in this repo as hbs/handlebars.runtime.js. You just need to do 2 things for that in your build config:

  1. Make sure hbs.handlebarsPath resolves to hbs/handlebars.runtime.js
  2. Make sure your helpers load the same file

See the example build configuration for a way to do that by setting handlebarsPath to handlebars, having the helpers load handlebars, and setting handlebars to hbs/handlebars.runtime in the paths.config

Before Build

Before Build

After Build

After Build

So many dependencies in the hbs plugin!

I use them for coding happiness. It shouldn't bother you tooooo much, because it all gets built out in production. The hbs.js file essentially gets written to the main.js file as a noop (a few empty definitions), and none of it's dependencies are included into the build. All the dependencies are inside the hbs folder and this folder should be a sibling of the hbs.js file.

Demo

To run the demo, go into the root directory of this project and run the following command.

./build.sh

This requires that node.js is installed. To see these in your browser, I'd suggest serving them quickly with the python simple server. (Linux/OSX assumed here, but there is a java implementation of the require.js build that should work just as well as the node version. I have not tried it though.)

cd ~/require-handlebars-plugin
python -m SimpleHTTPServer

You could also use the node 'serve' module.

npm install serve -g
serve .

Then visit http://127.0.0.1:8000/demo.html for the dev version.

And visit http://127.0.0.1:8000/demo-build.html for the production build version.

You should be able to see all of the templates and individual files in your network panel in dev mode, and just 2 minified files in build mode.

Config

There are several configurable options, which you can set in your require.config:

require.config({
  // ... other require config here

  // hbs config
  hbs: {
    helpers: false,               // When false, won't look for and try to automatically load
                                  // helpers (true by default)

    helperPathCallback:           // Callback to determine the path to look for helpers
      function (name) {           // ('/templates/helpers/'+name by default)
        return 'cs!' + name;
      },

    templateExtension: "html"     // Set the extension automatically appended to templates
                                  // ('hbs' by default)

    handlebarsPath:               // Custom path to handlebars for compiled templates
      'some/path/to/handlebars'   // ('hbs/handlebars' by default). Could simply be 'handlebars'
                                  // as long as it is defined in paths. If you are stubbing out
                                  // the plugin in an optimized build, use this to point to 
                                  // the runtime hbs (see demo/app.build.js)

    compileOptions: {}            // options object which is passed to Handlebars compiler
  }

})

Notes/QA

Partial Collision

This plugin registers every single template as a partial with it's modified module name and no file extension.

App/Template/One.handlebars is registered as App_Template_One

I'd encourage you to not call registerPartials in your code, and just use the automatic module registering, that way you definitely won't hit any collisions. You could also just be careful. We're all adults here.

Templates not loading cross-domain

In dev mode, loading the templates requires that you are on the same domain as your templates. This is standard same origin policy stuff. Once you build, though, it won't matter since there are no additional requests. Usually a few cleverly placed host overrides get you through the dev mode hurdles.

Other Templating Languages

Very little of this is specific to handlebars, but things are just a tiny bit too specific about how everything works to properly generalize this.

If you'd like to implement this for your templating language of choice, you'll need:

  • Has a pre-compile type functionality (unless you don't care about builds)
  • If it has some concept of partials, that you can register them externally
  • It eventually returns a function that takes data context and outputs something you can deal with.
  • For any of the meta-data, you'll need some fancy regex or an AST to walk through.

I'd just turn your template language into a module first (just the old global name, or whatever), then look through the references to Handlebars in hbs.js and see if your templating language does something similar. It's not a terribly complicated process.

License

Most of the code in this is from James Burke and Yehuda Katz in require.js and handlebars.js (respectively). Those projects are under their own license. Any other code added by me is released under the WTFPL license.

require-handlebars-plugin's People

Contributors

achur avatar boccob avatar brettjonesdev avatar chearon avatar chris-rink-veeva avatar dcousineau avatar drola avatar geronimod avatar hippich avatar jomaxx avatar levmar avatar marcusmacinnes avatar millermedeiros avatar mjmedmen avatar nfriedly avatar patrickkettner avatar peol avatar perfusorius avatar pieterv avatar rkstar avatar rmurphey avatar rosstuck avatar salami162 avatar sastan avatar saturate avatar simenb avatar sjhewitt avatar slexaxton avatar stutrek avatar xdamman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

require-handlebars-plugin's Issues

Change project name to Randlebars

NFL Hall of Famer John Randle's amazingly intimidating facepaint is just one reason this plugin should be renamed in his honor:

wat.

In addition, you mentioned that you were interested in a new creative name for this plugin at a recent conference where you spoke. And Randlebars is also short for require-handlebars. So you could use this name if you want. Kinda JKing but also up to you bro, iykwim

demo app optimization failed using r.js 2.0.0

requirejs 2.0 came out, and running optimization on r.js 2.0.0 is now failing on various place in hbs.js and Handlebars.js, was able to fix a couple:

diff --git a/Handlebars.js b/Handlebars.js
index d9a0262..1dd691b 100755
--- a/Handlebars.js
+++ b/Handlebars.js
@@ -1311,7 +1311,7 @@ Handlebars.JavaScriptCompiler = function() {};
},

 invokePartial: function(context) {
  •  params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpers",
    
  •  var params = [this.nameLookup('partials', context, 'partial'), "'" + context + "'", this.popStack(), "helpe
    

    if (this.options.data) {
    params.push("data");

diff --git a/hbs.js b/hbs.js
index b0896f7..976384a 100644
--- a/hbs.js
+++ b/hbs.js
@@ -349,7 +345,7 @@ define([
// I write out my import statements to a file in order to help me build stuff.
// Then I use a tool to inline my import statements afterwards. (you can run r.js on
fs.open(__dirname + buildStyleDirectory + buildCSSFileName, filecode, '0666', functio

  •                          fs.writeSync(id, str, null, encoding='utf8');
    
  •                          fs.writeSync(id, str, null, 'utf8');
                           fs.close(id);
                         });
                         filecode = "a";
    

but could not figure out this last error (it come up when calling "r.js -o demo/app.build.js":

fs.js:331
return binding.write(fd, buffer, offset, length, position);
^
TypeError: Bad argument
at Object.writeSync (fs.js:331:18)
at Object.oncomplete (eval at (/usr/local/lib/node_modules/requirejs/bin/r.js:14967:38))

problem with i18n value in quoted html attribute

I wish to output a i18n value on a button , I tried:

in my template, with corresponding key in en_us.json

"login" : "Login"

but I get output:

Is there way to insert i18n values into quoted HTML attributes?

Using handlebars variables within i18n template strings

Hi,

I'd like to use handlebars variables within the i18n template string;

{ "hello", "Hello {{name}}! Welcome back." }

To make this possible, you'd have to compile the Handlebar template twice, and provide it with the same context.

I made this change to line 387 of the hbs.js file;

- "return t;\n" +
+ "return function (context, options) { var t2 = Handlebars.compile(t(context, options)); return t2(context, options); };\n"

What do you think of this approach, and what is the impact on performance?

regards,
Jorgen

Optimization with requirejs 2.0.1 fails

The requirejs optimization fails while loading 'hbs/underscore':

Error: Parse error using UglifyJS for file: XXX/lib/require-handlebars-plugin/hbs/underscore.js
Unterminated string constant (line: 913, col: 16, pos: 32318)

Error
    at new JS_Parse_Error (XXX/node_modules/requirejs/bin/r.js:9636:22)
    at js_error (XXX/node_modules/requirejs/bin/r.js:9644:15)
    at parse_error (XXX/node_modules/requirejs/bin/r.js:9736:17)
    at with_eof_error (XXX/node_modules/requirejs/bin/r.js:9963:44)
    at read_string (XXX/node_modules/requirejs/bin/r.js:9802:24)
    at Object.next_token [as input] (XXX/node_modules/requirejs/bin/r.js:9976:52)
    at next (XXX/node_modules/requirejs/bin/r.js:10086:37)
    at vardefs (XXX/node_modules/requirejs/bin/r.js:10423:33)
    at var_ (XXX/node_modules/requirejs/bin/r.js:10436:34)
    at prog1 (XXX/node_modules/requirejs/bin/r.js:10671:23)Error: Parse error using UglifyJS for file: XXX/lib/require-handlebars-plugin/hbs/underscore.js
Unterminated string constant (line: 913, col: 16, pos: 32318)

Error
    at new JS_Parse_Error (XXX/node_modules/requirejs/bin/r.js:9636:22)

In module tree:
    hbs

Helpers with only string arguments are not detected

Registering a new helper that only has string arguments is not picked up by recursiveVarSearch, as Handlebars.AST.StringNode does not have a "parts" property. The end result is that the helper is not detected and thus never loaded and the whole script errors out.

I've tried adding a quick fix by checking for String nodes explicitly to the check above it (line 230~)

if ( _(paramsWithoutParts).contains(param.original) || param instanceof Handlebars.AST.StringNode) {
    helpersres.push(statement.id.string);
}

However, this causes it to detect the i18n helper ($) and tries to load /template/helpers/$.js (which has the same format but does not exist) and then the build process fails. Perhaps we could check higher in the function if the helper is $, but I'm a bit new to requirejs and handlebars, so I'm not sure if that's just piling hack on hack.

I'm more than willing to send a PR but could use a bit of guidance here. Am I missing something big here? Thanks in advance.

reserved keywords (eg. class) can't be used in expressions in IE8

the following template cause an error in IE 8 which is very hard to track:

<div class="foo {{#if class}}{{class}}{{/if}}">{{bar}}</div>

while this one works fine:

<div class="foo {{#if className}}{{className}}{{/if}}">{{bar}}</div>

error is caused by the load.fromText() -> req.exec() method but I'm not sure who is responsible for it (if it's a Handlebars issue or just caused because of the way the plugin works), didn't had time to try it out yet.

package.json for volo

It could well be worth adding a package.json that allows installing with volo.

With the below adjustment (and a bit of luck / testing), the following volo command:

volo add SlexAxton/require-handlebars-plugin hbs

should install the global "Handlebars.js" along with a "hbs.js" wrapper file pointing to "hbs/hbs.js" and a "hbs" folder containing this repo.

package.json

{
  //name, description, version, etc. then:

  "main": "hbs",
  "volo": {
    "type": "directory",
    "dependencies": {
      "Handlebars": "https://raw.github.com/SlexAxton/require-handlebars-plugin/master/Handlebars.js"
    }
  },
  "scripts": {
    "install": "volo add"
  }
}

Apologies if I've got something wrong there, happy to look into this further if I have.

Underscores in template filenames

Is there a reason why partial includes have to use underscores to denote a folder delimitation? It means we can't use underscores in partial filenames.

If there is no reason for this would you be interested in a pull request to change the behaviour?

Work with Ember

Hi, there,

The Handlebars.js seems not compatible with Ember (1.0.pre.2). This is the error I got,

Uncaught Error: assertion failed: Ember Handlebars requires Handlebars 1.0.beta.5 or greater.

I am wondering if this is related to the Handlebars.js is actually a AMD wrapper around the actually Handlebars code.

Helpers without parameters are not loaded automatically

I've defined a helper like this:

define(['Handlebars'], function(Handlebars) {
  var isLoggedIn = function(number) {
    return true;
  };
  Handlebars.registerHelper('isLoggedIn', isLoggedIn);
  return isLoggedIn;
});

When I want to use this in a template without providing parameters, like this: {{isLoggedIn}} the helper will not be loaded. If I provide a dummy parameter like {{isLoggedIn somethingHere}} it is automatically loaded and the helper works.

Access i18n JSON file from javascript

In certain instances, it is valuable to access the i18n dictionary in javascript (e.g. dynamically creating graphs with localized tooltips).

This is possible using the text plugin, but is at best inefficient (as you are loading the same file from the server twice, and calling JSON.parse each time you load it).

Is there a better way to access it, and if not, where is the entry point so I can patch/pull request?

Reference Error: window is not defined

When Trying to use this plugin in app.build.js with requirejs I'm getting a build error to do with window is not defined when the hbs plugin is loaded.

All of the scripts work fine for when loading in each separate file, but when I try to build it all together I get that error and I'm unable to use the hbs plugin because of this.

Something is wrong with your fs.write code on line 363

There's something wrong with your code on line 363:

fs.writeSync(id, str, null, encoding='utf8');

Those are (kind of) the arguments for fs.writeFileSync, not fs.writeSync.

According to the docs:
http://nodejs.org/api/fs.html#fs_fs_writesync_fd_buffer_offset_length_position
fs.writeSync(fd, buffer, offset, length, position)

http://nodejs.org/api/fs.html#fs_fs_writefilesync_filename_data_encoding
fs.writeFileSync(filename, data, [encoding])

You have that extra "null" argument in place of the encoding.

I changed it match the API, but now I'm not actually sure what this code is supposed to do. It created a file named 3 (the id returned by openSync) and in that file was the following:

@import url(two.css);

This is confusing to me for a few reasons.

First, there is an argument called buildCSSFileName, which leads me to believe that all the css for all the templates would be compacted into one file named that and placed into the buildStyleDirectory. By saying @import url(two.css) it looks like it expects all the individual css files to remain. Is this the case?

Two, the id returned by openSync is always the same (3), so it just overwrites the file over and over again.

If I had to guess, I'd say your intention was to write a series of @import statements into the buildCSSFileName file, and then your templates would load that css file.

The problem is, even if I hard code the template.css file to look like this

@import url(one.css);
@import url(two.css);

When I open the html page in the browser, it's still not loading the css correctly.

So, I'm curious about what this piece of code is supposed to do and how it's supposed to do it. I'd like to help if I can but I don't know for sure what the intent here is.

if template has the same name as module it will fail to load

sometimes I have templates with the same name as the module itself and stored at the same folder..

// foo/bar.js
define(['hbs!./bar'], function(template){
  // never load since "bar" will timeout
});

this will work:

// foo/bar.js
define(['hbs!./bar-template'], function(template){
  // loads template
});

The `tmpl.vars` output is janky.

It seems to find the right dependencies, but displays them incorrectly.

base..base..something.somethingelse

I can tell the logic for finding the variables is correct. The logic for creating all permutations of the string is obviously messed up a bit.

ReferenceError: depth is not defined

I'm struggling to get my project optimized, at the moment, fixing one thing after the other. At the moment, I'm stuck at a file where a handlebars template is loaded using this plugin.

I get the following error;

$ node js/dev/r.js -o app.build.js

Tracing dependencies for: main
ReferenceError: depth is not defined
In module tree:
    main
      js/relations/someRouter
        js/relations/someListView

at Object.compileProgram (eval at <anonymous> (E:\blahproject\src\main\webapp\assets\js\dev\r.js:14965:38))

The list view depends on a listview.html template, in which I selectively removed some stuff until it passed on to the next. As it (seems to) turn out, the problem occurs when iterating over a collection, i.e:

 {{#items}}
   <p>content</p>
 {{/items}}

or, alternatively:

 {{#each items}}
   <p>content</p>
 {{/each}}

Removing this iterator makes the optimizer move on to the next file, and stop there when it encounters one of those iterators. I've looked (briefly) into the Handlebars.js file (supplied with this plugin), and there is a mention of a 'depth' here and there, but I'm no Handlebars expert, so I haven't found much useful there.

I'm guessing there's weirdness in the used version of Handlebars or something. I should try an earlier version, see if that works.

Edit: same issue when using handlebars-1.0.0.beta.4, but an error "ReferenceError: compilerWords is not defined" in beta 3. This is just replacing the HAndlebars version btw, not the matching hbs.js file.

Edit 2: I cloned the demo project and attempted to reproduce, but was unsuccessful; the iterator works just fine there, both with test data filled in (hardcoded) and left undefined (although the data itself is ignored by the optimizer, I'm sure. It should, at least).

Edit 3: Copy/pasted the r.js file found in the demo application and now it seems to work. I believe I used the r.js file from RequireJS's site before; it might be a good idea to give your fork of that one a unique name to avoid convusion.

any way to remove the i18n precompile?

I'm not using the i18n stuff and I'm getting errors since it can't find the file template/i18n/en_us.json.

any easy way to remove this feature?

it would be awesome if the plugin used the configs from require.config() for this kind of setting.

Context for partial view

Hi! Is there exist some way to pass params to a context view ?

Something like this:
{{> Path_to_partial "context"}}

or

{{partial "Path/To/Partial" {data:true} }}

Templates load successfully, then try to load again with a .js extension

This might be related to #70

I'm working on an existing project that already used handlebars templates with some custom code to wire everything up, and trying to convert it to use require.js instead of just concatenating everything.

I'm seeing it correctly load my three top-level templates, then it tries to re-load my first top-level template with a .js extension (but not the other two), then it loads both of the partials that had been called by the second and third top-level templates, then it reloads those partials with a .js extension.

So it seems like anything that calls a partial works correctly, while anything that doesn't call a partial tries to re-load with a .js extension after loading successfully.

And then it gets the error Uncaught Error: Load timeout for modules: hbs!modules/targetedinvite/progress_bar_unnormalized2,hbs!modules/targetedinvite/friend_tagging_dialog_unnormalized3,hbs!modules/targetedinvite/inline_unnormalized4,hbs!modules/targetedinvite/progress_bar,hbs!modules/targetedinvite/friend_tagging_dialog,hbs!modules/targetedinvite/inline,hbs!templates/feed-story-preview,hbs!modules/targetedinvite/inline-content

I traced the .js loading back to the parentRequire([name], function) call here: https://github.com/SlexAxton/require-handlebars-plugin/blob/master/hbs.js#L425

              if ( !config.isBuild ) {
                require( deps, function (){
                  load.fromText(text);

                  //Give result to load. Need to wait until the module
                  //is fully parse, which will happen after this
                  //execution.
                  parentRequire([name], function (value) {
                    load(value);
                  });
                });
              }

But I'm not sure what needs to be changed to fix this.

If it helps, is what my require.config looks like:

require.config({
    hbs: {
        disableI18n: true,
        templateExtension: "handlebars"
    },
    paths: {
        "hbs": "lib/require-handlebars-plugin/hbs",
        "handlebars": "lib/require-handlebars-plugin/Handlebars",
        "json2": "lib/require-handlebars-plugin/hbs/json2",
        "i18nprecompile":  "lib/require-handlebars-plugin/hbs/i18nprecompile"
    }
});

and I'm happy to provide more info if you'd like.

Optimizing doesn't work

The demo provided in the repo doesn't seem to work. Here's the exact commands I'm running:

git clone https://github.com/SlexAxton/require-handlebars-plugin.git require-handlebars-plugin
npm install [email protected] -g
cd require-handlebars-plugin/demo
r.js.cmd -o app.build.js

Error:

fs.js:429
return binding.write(fd, buffer, offset, length, position);
^
TypeError: Bad argument
at Object.fs.writeSync (fs.js:429:18)
at define.load.filecode (eval at (C:\Users\dherman\AppData\Roaming\npm\node_modules\requirejs\bin\r.js:14973:38))
at Object.oncomplete (fs.js:297:15)

Allow use of format in i18n

js format works as follows:

"{0} started following {1}".format("achur", "require-handlebars-plugin")

outputs

"achur started following require-handlebars-plugin"

It would be awesome if we could do something like

{{$ "following-format" "achur" "require-handlebars-plugin"}}

which would localize the string with the two parameters.

Build error

Upgrading to version 0.4.0 of the plugin causes my build to fail with a file not found error. It is looking for a .js file instead of a .hbs. It works fine in the browser still. I am using requirejs v2.1.1

Using handlebars.runtime instead of the full version after pre-compiling

I'm playing with precompiling using node.js and the whole process worked like a champ, only issue I got is after all templates/helpers/partials are compiled, it would be great to include a lighter version of hadnlebars (runtime) in the final js file, is it possible ?

ps. I tried to manually switch out the handlebar part in final js and seems it's working, it's just now I need an automatic approach to make it happen in the build system.

Jeremy.

Problems with drop in Underscore replacement Lodash

I'm getting this errorUncaught TypeError: Object message,message has no method 'chain' hbs.js:284

My require config

requirejs.config({
  deps : ['main'],
  locale: 'en_us',
  hbs: {
    templateExtension: 'hbs',
    disableI18n: true,
    disableHelpers: true
  },
  paths: {
    'jquery': 'js/libs/jquery.min',
    'backbone': 'js/libs/backbone-min',
    'hbs': 'js/libs/hbs',
    'handlebars': 'js/libs/Handlebars',
    'underscore': 'js/libs/lodash.min',
    //'underscore': 'js/libs/underscore-min',
    'i18nprecompile': 'js/libs/i18nprecompile',
    'json2': 'js/libs/json2'
  }
});

If anyone wants to try it out... just clone this repo and replace underscore with Lodash.
Btw... everything works just fine with underscore.
Is anyone else experiencing problems with Lodash or has anyone else figured it out??

i18n doesn't work inside else block

en_us.json:

{
  "example" : "example string"
}

template.hbs:

<div>
{{#if condition}}
  Something here
{{else}}
  {{$ "example"}}
{{/if}}
</div>

This will fail with Uncaught Error: Could not find property '$', since it is missed by precompiling the i18n.

It might be good to, just in case, register the $ helper on Handlebars, to fill from the i18n dictionary (though obviously in an ideal world, precompilation would work in all cases).

Handlebars runtime

This may be more of a question than an issue.

Why doesn't the build compile in the runtime version of Handlebars instead of the entire thing?

DevStyleDirectory not working

setting devStyleDirectory does nothing.

line 333 uses the base config url to determine a style if not built through node instead of using the devstyledirectory.

Error with json parse method

Hello,

I'm getting an error when trying to optimise using r.js (both the default one on the require site and the one on this github project).

If I just run the project without optimising, the hbs loads fine and I can use the templates as normal. But when I run the optimizer I get the error below:

TypeError: Object # has no method 'parse'
In module tree:
main
app
libs/artist/artist
hbs
hbs/json2

TypeError: Object # has no method 'parse'
In module tree:
main
app
libs/artist/artist
hbs
hbs/json2

at eval at <anonymous> (C:\workspaces\Teardowns\Teardown App\r.js:14973:38)

Dependencies are included in an r.js build

I was under the impression from the readme that the dependencies located in the hbs folder would not be included with a build produced from the r.js optimizer, but they do end up in my build. This inflates the file size way beyond what it needs to be.

I am using RequireJS 2.0.2 and r.js 2.0.2.

Problem with loading handlebar template with require js

Hi,
I was using require.js text plugin to pull in html templates in my backbone app, the template engine I used is the one that comes with underscore/backbone, and things were working fine. I wanted to switch to handlebars template engine while continue using require js for module management, so I downloaded this plugin, but I am having tourble getting it to work.

I am on Fedora, using require-2.1.2. I downloaded require-handlebars-plugin-master. I put Handlebars.js and hbs.js in my js/lib directory and i18nprecompile.js and json2.js in lib/hbs directory. Handlebars.js in this plugin seems a little different than the one on handlebars site, in that it looks to be AMD enabled so I asume I don't need the shim.

In my index.html I have:
<script src="./static/js/lib/require-2.1.2.js" data-main="static/js/main"></script>

Here is my main.js

baseUrl: "./static/js/",
paths: {
jquery: 'lib/jquery-1.8.3.min',
underscore: 'lib/underscore-1.4.3.min',
backbone: 'lib/backbone-0.9.2.min',
text: 'lib/text-2.0.3',

    Handlebars: 'lib/Handlebars',
    hbs : 'lib/hbs',        
    handlebars : "lib/Handlebars",
    i18nprecompile : "lib/hbs/i18nprecompile",
    json2 : "lib/hbs/json2",

    bootstrap : 'lib/bootstrap'
},

shim: {
    underscore: {
        exports: "_"
    },
    bootstrap: {
        deps: ['jquery']
    },
    backbone: {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
    }
  }
  ......

And in my view, I have

define(function(require) {
var $ = require('jquery'),
_ = require('underscore'),
Backbone = require('backbone'),
Handlebars = require('handlebars'),
hbs = require('hbs'),
ClusterRowTemplate = require('hbs!app/mywork/templates/MyRowTemplate.hbs');
//ClusterRowTemplate = require('text!app/mywork/templates/MyRowTemplate.html');

  var row = Backbone.View.extend({
    //template: _.template(MyRowTemplate),
    template: Handlebars.compile(MyRowTemplate),
   ....

The first issue I have is that in require config, I have to list both Handlebars and handlebars

Handlebars: 'lib/Handlebars',
handlebars : "lib/Handlebars",

Otherwise, browser loads static/js/lib/Handlebars.js successfully, but then it tries to load static/js/Handlebars.js which will fail.

So I added both in require config, then I get the error of
Uncaught Error: Load timeout for modules: hbs!app/mywork/templates/MyRowTemplate.hbs_unnormalized2,Handlebars

Although I can see Handlebars.js and hbs.js got pulled down.

Is there anything I mis-configured? Any help is greately appreciated.

Load Templates from URL during optimization

Hey, first thanks for the great plugin.

It works great in development, but I a have small problem with the r.js optimization and I wasn't able to fix it. My Templates are only accessible via http eg. http://www.server.de/js/templates/item.hbs

So during the optimization the it tries to use node fs which of course doesn't work. I also tried the request node lib to get the tempaltes from the url but somehow the callback did not fire.

Can you help me out or point me in the right direction?

Thanks
Steffen

Duplicate Failed @hbs Includes

I've been using (and loving) the require-handlebars-plugin since I first heard you mention it at jQueryConf. However, I've run in to a problem with the latest version: when I use it, all of my templates get loaded normally:

GET /assets/js/search/templates/queryListRow.handlebars 200 ok

but then the same template file tries to load (and fails) at an invalid address:

"NetworkError: 404 NOT FOUND - /assets/js/search/templates/[email protected]"

Now, I have a "template" path that maps to "ext/require/hbs', and my hbs config has a templateExtension of "handlebars", so that came from a define["template!search/templates/queryListRow'] call ... but I'm not sure how any of that would matter.

I've tried changing customNameExtension = "@hbs", to customNameExtension = "hbs", in hbs.js (as that was the only place I could find "@hbs"), but that didn't seem to help. Any thoughts on what I might be doing wrong?

plugin uses global require config in stead of loading context.

The hbs plugin uses the 'require' function without specifying it as a dependency. As a result the global require config is used in stead of the require config of the loading context.

FIX:

define([
'require', 'handlebars', ...
], function (
require, Handlebars, ...
) {
...

By specifying 'require' as a dependency, teh correct context is passed.

Helpers inside each

I have template with {{#each}} and helper call inside it. getExternalDeps function recognizes this helper as variable and doesn't include necessary helper in build.
Is it possible to call helper inside each loop?

My code is similar to example at handlebarsjs.com. Simplified version:

{{#each results}}
  {{generateFullName}}
{{/each}}

generateFullName is helper.

Update Handlebars to RC1

Would it be possible to bump the version on handlebars to the latest version?

It would be awesome if there were a separate .patch file that we could manually apply to the latest handlebars source to generate new hbs-specific handlebars versions more easily. :)

Config for partial lookup directory.

Could you add a config for the partial lookup base directory?

Also is there a reason for using _ instead of /?

It would look a lot nicer using / to me, but if I use it it's replaced with ., any hint to change that in my local version?

Thanks.

lots of 'unnormalized' template files failing to load

Using the 4.0 version with RequireJS 2.1.1 I'm getting this error:

Error: Load timeout for modules: hbs!template/LoginForm_unnormalized2,hbs!template/SetInitialPassword_unnormalized3,hbs!template/SetInitialPassword_Expired_unnormalized4,hbs!template/Header_unnormalized5,hbs!template/Footer_unnormalized6,hbs!template/accounts/Accounts_unnormalized7,hbs!template/accounts/AccountTenantPerms_unnormalized8,hbs!template/accounts/AddAccountForm_unnormalized9,...

This is the related parts of requirejs config

paths: {
 ...
    hbs: "../assets/js/libs/hbs",
    Handlebars: "../assets/js/libs/Handlebars",

    //requirejs handlebars plugin dependencies:
    handlebars : "../assets/js/libs/Handlebars",
    underscore : "../assets/js/libs/hbs/underscore",
    i18nprecompile : "../assets/js/libs/hbs/i18nprecompile",
    json2 : "../assets/js/libs/hbs/json2",

 ...
},

//this stuff from demo project:

optimizeCss: "standard",
inlineText: true,
// hbs config
pragmasOnSave: {
    //removes Handlebars.Parser code (used to compile template strings) set
    //it to `false` if you need to parse template strings even after build
    excludeHbsParser : true,
    // kills the entire plugin set once it's built.
    excludeHbs: true,
    // removes i18n precompiler, handlebars and json2
    excludeAfterBuild: true
},
hbs: {
    disableI18n: false,
    // This disables the i18n helper and
    // doesn't require the json i18n files (e.g. en_us.json)
    // (false by default)
    disableHelpers: false,
    // When true, won't look for and try to automatically load
    // helpers (false by default)
    // Callback to determine the path to look for helpers:
    helperPathCallback: function (name) { // ('/template/helpers/'+name by default)
        return 'cs!' + name;
    },
    partialPath: '/template/',
    templateExtension: "hbs" // Set the extension automatically appended to templates
},

template loading as null

Trying to use this plugin in an already configured app, so I had to adjust some of the paths. After finally getting them to resolve, I found that the template was null. Looking at the included script, it appears that it may be including it as a partial instead of a full template. Am I doing anything obviously wrong in my configuration that would make this so?

Is there some obvious way to tell it to be a normal template? Looked through the docs and it didn't seem clear.

https://gist.github.com/2262214

_ is not a function when using non-amd version of underscore

I understand that with non-amd version of underscore, _ is no longer a global object and the error makes sense. How-ever, i am using require 2.0's shim config as follows and was hoping that this would work. Could you please help in determining what i am doing wrong. By the way Backbone works with non-amd versions of underscore

shim: {
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'hbs': {
deps: ['underscore']
}
}

Failure on empty template

For an empty template I get: 'Cannot read property 'type' of undefined' from line:

if ( statement.type === "comment" ) {

It might be a good idea to put a statement verification step, e.g.,

if ( statement && statement.type === "comment" ) {

Loading templates from relative paths

I get an error when I use relative paths to load templates with the same name as a JavaScript module. The template itself actually loads fine though it just does some more stuff afterwards which throws this.

Uncaught Error: Load timeout for modules: hbs!../src/SelectBox_unnormalized2,hbs!../src/SelectBox

I can fix this by changing the name of the template or using absolute paths. Thought this problem should probably be mentioned in the docs.

RequireJS 2.1 support

Seems like require-handlebars is a bit broken after the new RequireJS 2.1 update. I keep getting 404 on for example: /templates/[email protected] in the network tab, seems to be an issue with customNameExtension = "@hbs" etc.

Maybe do an thorough check on hbs.js etc to make sure it works? RequireJS 2.1 is an larger update than normal.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.