leshill / handlebars_assets

Use handlebars.js templates with the Rails asset pipeline.
MIT License
647 stars 159 forks source link

requirejs-rails & AMD Compatibility #55

Closed pboling closed 7 years ago

pboling commented 11 years ago

requirejs-rails and general AMD Compatibility to handlebars_assets templates

Adds Config options:

leshill commented 11 years ago

Hi @pboling,

Looks great. Good luck as SxSW! I will see about adding tests myself.

Q: How are you now using this?

var template = require('mytemplate');
template(context, options);
pboling commented 11 years ago

@leshill Where did you find that code? I don't recognize it, and don't think I am using it. I'll push up some documentation enhancements with my use case which makes this work.

leshill commented 11 years ago

Hi @pboling,

I just wrote to see if I understood how this was intended to be used? Documentation would help :)

pboling commented 11 years ago

Done! Please review. It's a lot, so perhaps, link to a wiki? :)

pboling commented 11 years ago

Actually that's all setup, not usage. Adding a bit more.

pboling commented 11 years ago

@leshill Don't merge this yet... The instructions I created so far were fine for getting it working in development. More careful attention was needed to make it work in a deployed, minified, single file optimized, environment. I now have that working, and will update the instructions as soon as I can manage it.

leshill commented 11 years ago

HI @pboling,

I am going to want some tests around this too :) Ideally you would do this, it should be pretty easy to copy the existing tests. Otherwise I will get to it this week – I am travelling.

pboling commented 11 years ago

@leshill: Indeed. :) This one is still baking...

pboling commented 11 years ago

In case others are also trying out this code:

In order to get this working in deployed environments as well as local environments I had to use a two-prong approach. The $.environment.config('env_name') comes from a jQuery plugin I wrote to solve problems of environmental differences in JS execution.

I do not understand why the AMD modules won't work locally. I do not understand why window.HandlebarsTemplates.friend won't work in deployed environments.

Here is an example Marionette View, friend.js.coffee:

define [
  # Libraries
  'jquery-adapter', 'underscore', 'backbone', 'marionette',

  # AMD Templates from handlebars_assets
  'templates/friend'
], ($, _, Backbone, Marionette, viewTemplate) ->
  class FriendView extends Marionette.ItemView
    template: if ($.environment.config('env_name') == 'development' && !$.environment.config('foggy'))
      console.log('FriendView is being loaded locally, uncompiled.')
      viewTemplate
    else
      console.log('FriendView is being compiled, or has been compiled.')
      window.HandlebarsTemplates.friend

    initialize: (data) ->
      @data = data
      @render()

    serializeData: =>
      return @data

To setup the jquery.environment plugin my AMD jquery-adapter.js.erb looks like this:

define(['jquery', 'jquery_ujs', 'jquery-environment'], function($){
  <% if Rails.env == 'production' %>
    <% if ENV['FOGGY'] == 'true' %>
      // When Foggy we are actually precompiling assets in dev...
      $.environment({
        env_name:'development',
        fb_app_id: '107618706081450',
        hostname: 'local.acquaintable.com:5000',
        foggy: true
      });
    <% else %>
      // Otherwise we are production
      $.environment({
        env_name:'production',
        fb_app_id: '146489875419238',
        hostname: 'www.acquaintable.com'
      });
    <% end %>
  <% elsif Rails.env == 'staging' %>
    $.environment({
      env_name:'staging',
      fb_app_id: '228882543906582',
      hostname: 'staging.acquaintable.com'
    });
  <% elsif Rails.env == 'development' %>
    $.environment({
      env_name:'development',
      fb_app_id: '107618706081450',
      hostname: 'local.acquaintable.com:5000',
      foggy: false
    });
  <% elsif Rails.env == 'testing' %>
  $.environment({
    env_name:'test',
    fb_app_id: '263033133731571',
    hostname: 'acquaintable-web.dev'
  });
  <% end %>

  console.log('[jquery-environment] env_name', $.environment.config('env_name'));
  console.log('[jquery-environment] fb_app_id', $.environment.config('fb_app_id'));
  console.log('[jquery-environment] hostname', $.environment.config('hostname'));
  console.log('[jquery-environment] foggy', $.environment.config('foggy'));

  return $
});

I also had to wrap the Marionette library in some AMD code. I now have this setup working in deployed and local environments, but I would like to improve upon it.

AlexRiedler commented 11 years ago

Hey @pboling is this still baking, or how should we proceed with this!

pboling commented 11 years ago

It works better than nothing, and doesn't interfere with those not using AMD in any way, and doesn't change defaults. So I think it is worthwhile, but it is also not tested, and not a perfect solution, as I was not able to use the handlebars_assets 'api' (window.HandlebarsTemplates.template_name) to access the templates in development environment, only in Production (see my comment above). I had to load them directly via RequireJS in the other environment and use a switch making my JS environment aware.

So, I guess, as I think AMD is a growing thing, it would be good to include so it can be hacked on more. Alternatively perhaps it could become a tracking branch until it is more mature. Either way it won't affect those not using AMD.

AlexRiedler commented 11 years ago

That is because it removed JST/Namespace registration ... I am tempted to bake that into potentially another option (default to false when AMD enabled).

I have pushed a branch: that incorporates your changes (minus documentation) at https://github.com/leshill/handlebars_assets/tree/experimental-amd-support

It is possible to use with the gem you said, and:

require(['templates/index'], function (compiledTemplateFunction) { ... });

does work, it just is not auto-registered in the Template Namespace (there is an option, but it is not recommended)

require(['templates/index', 'templates/_partial'], function() { ... })

would work if index used that partial, or I have seen people stub a handlebars helper named "partial" that does the AMD loading. (e.g. https://github.com/elving/swag)

I will continue to think about it for the mean time, unless there is demand (aka if you read this and are interested people please :+1: it!)

pboling commented 11 years ago

That all sounds good to me. I am not currently actively working on anything using handlebars_assets, and it'll be awhile before I get back to something like that. :(

I did at one point need to register my partials with require, but I am sure that I am no longer doing that in my code using this branch. Partials just seem to work for me. I may have done something to get it working, but no longer remember.

StevenLangbroek commented 10 years ago

Hey guys,

This has been dead in the water for some time... Is this going to get merged? Please update.

Thanks!

AlexRiedler commented 10 years ago

@StevenLangbroek noted, I will try to get around to it by EOD Saturday (but probably sooner).

StevenLangbroek commented 10 years ago

On a sidenote: I used the https://github.com/acquaintable/handlebars_assets fork, and it's working fine for me so far, still have to test in production-like environment though.

AlexRiedler commented 10 years ago

sorry @StevenLangbroek won't get around to it tonight; did get some work done though towards 0.17 release (which will include amd loading).

AlexRiedler commented 10 years ago

@StevenLangbroek v0.17 released, test it out :+1: It includes AMD support (I have not writing docs for it yet).

StevenLangbroek commented 10 years ago

Hey,

Sorry for taking so long to respond. It is working in basics, but no matter what I do I can't load partials. When I manually load them from console it's working fine though. I'm guessing this has something to do with them no longer being registered under a shared namespace? Is there a way to fix this?

Thanks,