GithubHelp home page GithubHelp logo

emilioforrer / haml_coffee_assets Goto Github PK

View Code? Open in Web Editor NEW
439.0 20.0 142.0 493 KB

Haml Coffee templates in the Rails asset pipeline or as Sprockets engine.

Home Page: https://rubygems.org/gems/haml_coffee_assets

License: MIT License

Ruby 40.55% JavaScript 56.16% CoffeeScript 3.29%

haml_coffee_assets's Introduction

Haml Coffee Assets Build Status

Haml Coffee Assets compiles Haml Coffee templates in the Rails 3.1 asset pipeline, so you can use them as JavaScript templates in your JavaScript heavy Rails application. Server-side rendering of templates is also possible, allowing you to share the same template files for Rails and JavaScript templates. It also works as a pure Sprockets engine without Rails.

Tested on MRI Ruby 1.9.3, 2.0.0 and the latest version of JRuby.

Features

  • Seamless integration of Haml-Coffee into the Rails asset pipeline or as standalone Sprockets engine.
  • Manifold options to configure Haml Coffee Assets to your needs.
  • AMD support.
  • Server-side rendering of templates in Rails.

Haml Coffee

Haml Coffee allows you to write inline CoffeeScript in your HAML JavaScript templates:

#cart
  %h2 Cart
  - if @cart.length is 0
    %p.empty Your cart is empty
  - else
    %ul
      - for item in @cart
        %li
          .item
            = item.name
            %a{ :href => "/cart/item/remove/#{ item.id }" } Remove Item

You can try Haml Coffee online by visiting Haml Coffee Online and have a look the AMD example Rails app.

Installation

The simplest way to install Haml Coffee Assets is to use Bundler. Add haml_coffee_assets and execjs to your Gemfile:

group :assets do
  gem 'haml_coffee_assets'
  gem 'execjs'
end

(note that Rails 4.0 removed the assets group from Gemfile and so you don't need that line) and require the hamlcoffee.js in your app/assets/javascripts/templates/context.js.coffee:

#= require hamlcoffee

If you're using AMD support then you do not need to include the above helper, since it will be automatically included.

This provides the default escaping and the global context functions. Read more about it in the configuration section below.

Please have a look at the CHANGELOG when upgrading to a newer Haml Coffee Assets version.

If you want to use Haml Coffee with Sinatra, please have a look at the Haml Coffee Sinatra demo application.

Usage

Haml Coffee Assets allows two different ways of generating your JavaScript templates, but the Haml Coffee template generation is preferred, since it provides more configuration options and a smoother experience.

Haml Coffee template generation

  • Extension: .hamlc

If you omit the .jst and give your templates only a .hamlc extension, then Haml Coffee Assets will handle the JavaScript template generation. With this approach you can easily define your own namespace with a simple configuration and you can use the template name filter.

You can place all your Haml Coffee templates in the app/assets/javascripts/templates directory and include all templates from your app/assets/javascripts/application.js.coffee:

#= require_tree ./templates

Because Haml Coffee Assets provides a default template name filter, the templates/ prefix will be automatically removed.

Sprocket JST processor template generation

  • Extension: .jst.hamlc

When you give your templates the extension .jst.hamlc, Haml Coffee Assets will only generate the template function, which then in turn will be further processed by the Sprocket JST processor. Because Haml Coffee Assets will not generate the template, you can't use the AMD support, template name filter and the JST namespace definition is more cumbersome compared to the Haml Coffee template generation.

With this approach you should place all your Haml Coffee templates in the app/assets/templates directory and include all templates from your app/assets/javascripts/application.js.coffee:

#= require_tree ../templates

If you would place your templates into app/assets/javascripts/templates, then all your JST template names would begin with templates/, which may be not what you want.

Server-side rendering in Rails

Haml Coffee Assets registers the .hamlc extension with Action View, so that Rails templates can be written in Haml Coffee. Rails will see templates placed in app/assets/javascripts/templates (though this path can be changed if you store your templates in another directory), and the same template files can be rendered via Rails or via JavaScript on the client. Server-side rendering is only available when using the global placement and not with the AMD placement.

Given a Haml Coffee template at app/assets/javascripts/templates/books/_book.hamlc:

%dl
  %dt Name
  %dd= @name
  %dt Author
  %dd= @author

And a Haml Coffee context at app/assets/javascripts/templates/context.js:

//= require hamlcoffee

To render on server in books#index:

= render "book", :name => "A Tale of Two Cities", :author => "Charles Dickens"

To render and render the same file on the client using the asset pipeline:

#= require hamlcoffee
#= require templates/books/_book

JST["books/book"](name: "A Tale of Two Cities", author: "Charles Dickens")

Note that the template is required as books/_book because it refers to the actual file, but the template name on the client is simply books/book. If you require all templates at once with #= require_tree ./templates, you won't need to remember this distinction.

Configuration

Please note that all configuration examples will use the paths of the Haml Coffee template generation and not the Sprocket JST processor template generation.

Sprockets will cache your templates after compiling and will only recompile them when the content of the template has changed, thus if you change to your configuration, the new settings will not be applied to templates already compiled. You can clear the Sprockets cache with:

rake assets:clean

For Rails, you can set the configuration options in your environment by accessing config.hamlcoffee, whereas if you just use the plain Sprockets engine you can access the configuration with HamlCoffeeAssets.config. All the following examples use the Rails way.

Please note: When you put Haml Coffee Assets into the :assets group within your Gemfile and precompile the assets (the default Rails behaviour), then Haml Coffee Assets is not loaded in production and you can't set any configuration at config.hamlcoffee in both config/application.rb and config/environments/production.rb.

You can simply add a condition around the configuration:

if defined? ::HamlCoffeeAssets
 config.hamlcoffee.awesome = true
end

or move your configuration to config/environments/development.rb (and config/environments/test.rb, depending on your JavaScript testing setup).

Document format

By default all Haml Coffee templates are rendered to a HTML5 document. You can choose between the following output formats:

  • html5
  • html4
  • xhtml

If you prefer another HTML format than HTML5, you can set it in your config/application.rb:

config.hamlcoffee.format = 'xhtml'

Template placement

By default all Haml Coffee templates are placed under the configured template namespace. You can choose between the following placements:

  • global
  • amd

By setting the placement option to amd, each template will be wrapped within a define function, enabling the usage of a module loader.

config.hamlcoffee.placement = 'amd'

Please note, the placement option is only applicable if you use the .hamlc extension and let Haml Coffee Assets handle the JST generation. The global hamlcoffee helpers must be loaded normally before making use of any templates due to the current template design.

Global template dependencies

Haml Coffee Assets allows you to globally define the module dependencies for all templates. By default, the Haml Coffee Assets helper is included, but you can add your own:

config.hamlcoffee.dependencies = { '_' => 'underscore', :hc => 'hamlcoffee_amd' }

If you do not include the hamlcoffee_amd module as hc in the list, then the helper methods will be included in each template, increasing its size. It's recommended to always have the hamlcoffee module included.

Template namespace

By default all Haml Coffee templates are registered under the JST namespace. A template app/assets/javascripts/templates/header.hamlc with the given content:

%header
  %h2= @title

will be accessible in your browser as JST['header']. You can now render the precompiled template and pass the data to be rendered:

JST['header']({ title: 'Hello Haml Coffee' })

If you prefer another namespace, you can set it in your config/application.rb:

config.hamlcoffee.namespace = 'window.HAML'

You can even set a deep nested namespace like window.templates.HAML and Haml Coffee will handle creation all the way down.

You can't use this configuration if you give your templates a .jst.hamlc extension, because the Sprockets JST processor handles the template generation. In this case you have to subclass the JST processor:

class MyJstProcessor < Sprockets::JstProcessor
  def prepare
    @namespace = 'MyApp.Tpl'
  end
end

Foo::Application.assets.register_engine '.jst', MyJstProcessor

And you must make sure MyApp exists before any template is loaded.

Template name

The name under which the template can be addressed in the namespace depends not only from the filename, but also on the directory name by default.

The following examples assumes a configured namespace window.JST and the asset template directory app/assets/javascripts/templates:

  • app/assets/javascripts/templates/login.hamlc will become JST['login']
  • app/assets/javascripts/templates/users/new.hamlc will become JST['users/new']
  • app/assets/javascripts/templates/shared/form/address.hamlc will become JST['shared/form/address']

Template name filter

If you wish to put the templates in a different location, you may want to change the name_filter config.

config.hamlcoffee.name_filter = lambda { |n| n.sub /^templates\//, '' }

By default, name_filter strips the leading templates/ directory off of the name and also a leading _ from the template name. Please note, name_filter is only applicable if you use the .hamlc extension and let Haml Coffee Assets handle the JST generation. If you use the .jst.hamlc extension, then Sprockets JST processor will name things accordingly (e.g., with templates/ intact in this case).

The template name filter is not used with AMD loader.

Basename

If you don't want to have your directory names under which your template is located to be contained in the JST name, you can configure Haml Coffee in your config/application.rb to strip off the path to the file name and only use the basename as JST name:

config.hamlcoffee.basename = true

With this setting enabled the following naming rule applies:

  • app/assets/javascripts/templates/login.hamlc will become JST['login']
  • app/assets/javascripts/templates/users/new.hamlc will become JST['new']
  • app/assets/javascripts/templates/shared/form/address.hamlc will become JST['address']

This setting has only an effect when you're using Haml Coffee to generate the JST and not when using the Sprockets JST processor.

Escaping

All generated output by running CoffeeScript in your template is being escaped, but you can disable escaping of either the attributes or the generated Html.

Attribute escaping

You can toggle attribute escaping in your config/application.rb:

config.hamlcoffee.escapeAttributes = false

HTML escaping

You can toggle HTML escaping in your config/application.rb:

config.hamlcoffee.escapeHtml = false

Clean values

Every value that is returned from inline CoffeeScript will be cleaned by default. The included implementation converts null and undefined to an empty string. You can disable value cleaning in your config/application.rb:

config.hamlcoffee.cleanValue = false

Uglify generated HTML

By default all generated HTML is indented to have a nice reading experience. If you like to ignore indention to have a better rendering performance, you can enable the uglify option in your config/application.rb:

config.hamlcoffee.uglify = true

Global context

Haml Coffee Assets allows you to configure a global context function that gets merged into the local template context for each template. You can simply override HAML.globals and return the global context data:

HAML.globals = ->
  {
    isAuthenticated: App.isAuthenticated()
    isAdmin: App.currentUser.hasRole('admin')
  }

Now you can use the properties from the global context in every template:

.not-found-error
  %h1 Page not found
  - if @isAuthenticated
    %p Please visit the home page.
  - else
    %p Please log into your account.

When rendering on the server, haml_coffee_assets will expect the global context to be overriden with the global_context_asset. Located by default at templates/context.

You can configure the path to this asset in your config/application.rb:

config.hamlcoffee.global_context_asset = 'templates/context'

If you like to use your own implementation, simply configure your context function in your config/application.rb:

config.hamlcoffee.context = 'App.globalTemplateContext'

or disable the global context completely:

config.hamlcoffee.context = false

Your custom context function must take the local context as parameter and returns the merged context data. The following example uses the Haml Coffee Assets extend function to merge the global context data with the passed local context data:

App.globalTemplateContext = (locals) -> HAML.extend({}, {
    authenticated: App.isAuthenticated()
}, locals)

Please have a look at the wiki for further examples on how to use the global context.

Customize the tag lists

Haml Coffee contains two list of HTML tags that you can customize. In general you're fine with the defaults, but if you need to extend the list, you can instruct Haml Coffee Assets to do so.

Whitespace sensitive tag list

  • Tags: textarea, pre

Some HTML tags are whitespace sensitive, which means that whitespace used for proper indention results in a wrong display of the tag. In order to avoid this, the content is preserved by converting the newlines to a HTML entity. You can set your own list of whitespace sensitive tags in your config/application.rb:

config.hamlcoffee.preserveTags = 'pre,textarea,abbr'

This list is also taken into account for the HAML.preserveAndFind helper function that is provided and its shortcut notation ~.

Auto-closing tag list

Tags: meta, img, link, br, hr, input, area, param, col, base

The auto-closing tag list will contains the tags that will be self-closes if they have no content. You can set the list of self closing tags in your config/application.rb:

config.hamlcoffee.autoclose = 'meta,img,link,br,hr,input,area,param,col,base'

Custom helper functions

Haml Coffee Assets provides a set of custom functions for Haml Coffee, so that the templates doesn't have to be self contained and can make use of the global functions. In general you don't have to customize them further, but if you need to, you can set custom functions for:

  • config.hamlcoffee.customHtmlEscape
  • config.hamlcoffee.customCleanValue
  • config.hamlcoffee.customPreserve
  • config.hamlcoffee.customFindAndPreserve
  • config.hamlcoffee.customSurround
  • config.hamlcoffee.customSucceed
  • config.hamlcoffee.customPrecede

You can see the default implementation and the Haml Coffee documentation for more information about each helper function.

Templates path

Rails will look for templates in app/assets/javascripts/templates when rendering on the server side. If you store your templates in another directory, you can change this location:

config.hamlcoffee.templates_path = "custom/template/path"

Partial rendering

With Haml Coffee Assets you can render partials when using plain JST approach and also with AMD support.

JST partial rendering

With the traditional JST approach, all the templates are globally accessible in your defined namespace, which is JST by default. This allows you to render a template within another template like:

%h1 Comments for this article
- for comment in @article.comments
  != JST['articles/comment'](comment)

AMD partial rendering

Haml Coffee parses the template source code for require statements and adds them to the template module dependencies. This allows you to require other templates like this:

- require 'module'
- require 'deep/nested/other'

Now your dependencies are available in the template, allowing you to render it with:

!= module()
!= other()

Please note that only the basename ot the template is used as module variable name.

Of course you can also directly require and render a template like:

!= require("another/other")()

Please have a look at the AMD example Rails app for a working example.

Author

Developed by Michael Kessler, FlinkFinger.

If you like Haml Coffee Assets, you can watch the repository at GitHub and follow @netzpirat on Twitter for project updates.

Development

Pull requests are very welcome! Please try to follow these simple rules if applicable:

  • Please create a topic branch for every separate change you make.
  • Make sure your patches are well tested. All specs must pass.
  • Update the Yard documentation.
  • Update the README.
  • Update the CHANGELOG for noteworthy changes.
  • Please do not change the version number.

For questions please join #haml on irc.freenode.net

Open Commit Bit

Guard has an open commit bit policy: Anyone with an accepted pull request gets added as a repository collaborator. Please try to follow these simple rules:

  • Commit directly onto the master branch only for typos, improvements to the readme and documentation (please add [ci skip] to the commit message).
  • Create a feature branch and open a pull-request early for any new features to get feedback.
  • Make sure you adhere to the general pull request rules above.

Contributors

See the CHANGELOG and the GitHub list of contributors.

Acknowledgement

  • Jeremy Ashkenas for CoffeeScript, that little language that compiles into JavaScript.
  • The people at 9elements who started haml-coffee, an elegant JavaScript template solution.

License

(The MIT License)

Copyright (c) 2011-2013 Michael Kessler

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

haml_coffee_assets's People

Contributors

camertron avatar damrbaby avatar dersascha avatar dhiemstra avatar emilioforrer avatar fixme avatar jayzes avatar jfirebaugh avatar jimmycuadra avatar jingoro avatar jipiboily avatar joliss avatar joshed-io avatar kiskoza avatar ktham avatar manjunath-nm89 avatar mathieujobin avatar mrchess avatar netzpirat avatar ngtk avatar nivoc avatar panterch avatar paulyoung avatar phenchaw avatar thedeeno avatar thekidcoder avatar toomanybees avatar vlmonk avatar whitequark avatar zhrivodkin 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

haml_coffee_assets's Issues

Adding class on condition

Should something like this work?
%ul.avatars{:class => ("all-shown" if @allShown?) }

I tried a few combinations but couldn't get a class to be added conditionally.

Class attribute interpolation

> test1 = '
  - for i in [1..5]
    %i{:class => "prefix-#{i}"}'

> HamlCoffeeAssets::HamlCoffee.compile 'test1', test1, false
=> "(function(context) {\n  return (function() {\n    var $o, i;\n    $o = [];\n    for (i = 1; i <= 5; i++) {\n      $o.push(\"<i class='prefix-\" + i + \"'></i>\");\n    }\n    return $o.join(\"\\n\").replace(/\\s(\\w+)='true'/mg, ' $1').replace(/\\s(\\w+)='false'/mg, '');\n  }).call(HAML.context(context));\n});"

> test2 = '
  - for i in [1..5]
    %i.other{:class => "prefix-#{i}"}'

HamlCoffeeAssets::HamlCoffee.compile 'test2', test2, false
=> "(function(context) {\n  return (function() {\n    var $o, i;\n    $o = [];\n    for (i = 1; i <= 5; i++) {\n      $o.push(\"<i class='\" + (['other', i].sort().join(' ')) + \"'></i>\");\n    }\n    return $o.join(\"\\n\").replace(/\\s(\\w+)='true'/mg, ' $1').replace(/\\s(\\w+)='false'/mg, '');\n  }).call(HAML.context(context));\n});"

In first case we are getting expected class=("prefix" + i), but in the second case prefix is omitted: class=(['other', i].sort().join(' '))

null values show up as text

I just switched from using .jst.eco for my Backbone templates to using hamlc. I love it so far, soo much cleaner. While updating my templates I am bumping into one issue though, I can't seem to get a null value to parse nothing.

In my Backbone Model I do:

defaults:
  email: null
  first_name: null
  last_name: null
  company: null

This line in eco shows the company when there is one, and shows nothing when there isn't:

<div class="field">
  <label for="company"> company:</label>
  <input type="text" name="company" id="company" value=<%= @company %> >
</div>

While the new hamlc shows the actual text null inside the input field when no company is provided:

.field
  %label{ for: 'company' } company:
  %input{ type: 'text', name: 'company', id: 'company', value: @company }

Any ideas?

rake assets:precompile not processing .hamlc

When I run "bundle exec rake RAILS_ENV=production assets:precompile", hamlc templates are not compiled. They are just put as is in the /assets directory.

On-the-fly compilation (like in development mode) works perfectly though.

Did I miss something ?

I18n is not defined Source File

Hi netzpirat,

I tried to use I18n in hamlc file likes below.

%span= I18n.t('text.test')

And It gave me a message below.

Error: I18n is not defined Source File.

  • haml_coffee_assets (0.6.0)

P.S. Could I use render , form_for in haml_coffee_assets?

Empty "name" attribute

Hello,

I encountered an error in your gem. My hamlc template contains a line:

%input{name: 'name', type: 'text' }

The error is that html output for the line is:

<input name="" type="text">

So, if an input has name "name", the gem generates html tag with an empty name attribute.

Thank you in advance.

Failing to quote object literal keys causes an 'unmatched OUTDENT' error

The following should be valid haml/coffeescript, but causes an unmatched OUTDENT error:

%input{ type: 'text', name: 'padded_number', value: myFunction(@number, length: 3 ) }

However, it only breaks in the context of haml. This compiles without error:

= myFunction(@number, length: 3)

These other syntaxes don't work:

%input{ type: 'text', name: 'padded_number', value: myFunction(@number, { length: 3 }) }
%input{ type: 'text', name: 'padded_number', value: myFunction(@number, 'length': 3 ) }
%input{ type: 'text', name: 'padded_number', value: myFunction(@number, { 'length': 3 } ) }

The only syntaxes that work require the key to be quoted, and separated from the colon by a space. Curly braces are optional:

%input{ type: 'text', name: 'padded_number', value: myFunction(@number, { 'length' : 3 } ) }
%input{ type: 'text', name: 'padded_number', value: myFunction(@number, 'length' : 3 ) }

Uncaught TypeError: Cannot call method 'context' of undefined

Stuck on this for a couple of hours, not sure what to do with this error in js:

this.JST["login_btn"] = (function(context) {
    return (function() {
      var $o;

      $o = [];

      $o.push("<div id='login_btn'></div>");

  return $o.join("\n").replace(/\s(\w+)='�true'/mg, ' $1').replace(/\s(\w+)='�false'/mg, '');

}).call(window.HAML.context(context));

I have the repo here: https://github.com/WaleyChen/vekii_2.0.
Could you take a look?

Thank you,
Waley

Attribute parsing partially broken

Not really want to hunt the reason down, so here is the broken template:

%label.g-label{:for => 'input-transfer-template-repeat-number'} Время:
%input#input-transfer-template-repeat-number.g-field{:type => 'text', :name => 'transfer_template[repeat_number]', :placeholder => 'например, 14:50'}

It fails with ActionView::Template::Error Error: Parse error on line 5: Unexpected 'STRING'

Looks like it's because of the UTF-8 in placeholder attr.

Sprockets::FileNotFound error

When I run rails project in production mode on local machine and open /assets/application-286367ee0c04b437bb18d2ede3e221cf.js I see the following error -

throw Error("Sprockets::FileNotFound: couldn't find file 'hamlcoffee'\n  (in /project/app/assets/javascripts/application.js:21)")

21 line -

//= require hamlcoffee

I open gem source code

gem open haml_coffee_assets

and hamlcoffee.js.coffee.erb file in the right place.

What is interesting, in development mode or on heroku this error does not occur. I can't even imagine why this error happens. @netzpirat, please help figure out.

undefined method `hamlcoffee' in Rails production

Hi,

I'm trying to run my Rails 3.2.2 app in production env. Trying to start up the Rails instance results in

/Users/nicholas/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.2.2/lib/rails/railtie/configuration.rb:85:in `method_missing': undefined method `hamlcoffee' for #<Rails::Application::Configuration:0x007fd98badfc98> (NoMethodError)
    from /Users/nicholas/code/src/clients/commandfusion/Integrator-Portal/config/application.rb:66:in `<class:Application>'

This is issuing from some config I'm setting up in application.rb.:

    #haml_coffee_assets config
    config.hamlcoffee.escapeHtml = false
    config.hamlcoffee.escapeAttributes = false
    config.hamlcoffee.cleanValue = false

Just wondering if you've come across this before? I'm using the latest version of your gem, 0.8.4. Running the app in the dev or test environments is fine.

Haml_coffee_assets has been a pleasure to use so far, thanks for providing it.

Cheers,
Nicholas

CoffeScript interpolation does not work

Similar to haml syntax following code:

%span.add-on.stats-vote-impact
  #{2 + 2}%

Should be parsed as

%span.add-on.stats-vote-impact
  = "#{2 + 2}%"

But it throws exception :

ExecJS::ProgramError in Video_channel/polls#show

Showing /var/proj/rp-dev1/app/views/layouts/video_channel.html.haml where line #10 raised:

Unable to parse tag from #{2 + 2}%: TypeError: Cannot call method 'replace' of undefined
(in /var/proj/rp-dev1/app/assets/javascripts/templates/polls/statistics.jst.hamlc)

Can I use this gem with backbone-rails gem ?

I just add two gems in my Gemfile and create one template to test and.. it doesn't work
Gemfile

ExecJS::ProgramError in Main#index

Showing C:/preject/app/views/layouts/application.html.haml where line #6 raised:

TypeError: Object doesn't support this property or method
(in C:/preject/app/assets/javascripts/backbone/templates/profile/index.jst.hamlc)

In index.jst.hamlc just:
.qwe test123

Using rails helpers in .hamlc templates

Hi

I am trying to use rails helpers in my .hamlc templates (e.g. image_tag, route helpers), but they are not processed. Instead, they are getting sent to the client as javascript methods to be called when rendering the template.

What do I need to do to use rails helpers in my haml templates?

readme examples

With my install, the Readme examples don't work as written. Should we update the readme ?

%header
  %h2= title

Should be:

%header
  %h2= @title

and also,

JST["template"].render(...)

should be

JST["template"](...)

(without render())

Does not proccess haml?

When I run this in my sprockets pipeline, the output javascript is as follows:

// test.jst.hamlc
(function() {
  this.JST || (this.JST = {});
  this.JST["backbone/templates/test"] = #cart
    %h2= I18n.t('js.cart.title')
    - if @cart.length == 0
      %p.empty= I18n.t('js.cart.empty')
    - else
      %ul
        - for item in @cart
          %li
            .item
              = item.name;
}).call(this);

It seems like it isn't even detecting/processing haml to html. Any thoughts on this or how to debug why it doesn't work?

Note: I am using Sprockets outside of the Rails asset pipeline (using a Sprockets standalone)

name_filter doesn't seem to work

I keep my templates in the backbone tree (app/assets/javascripts/backbone/templates) rather than in the root of javascript assets (app/assets/javascripts/templates), so I created an initializer with this one line:

HamlCoffeeAssets::HamlCoffeeTemplate.name_filter = lambda { |n| n.sub /^backbone\/templates\//, '' }

When I bind to pry, I can see that the lambda is created properly. I can even call it passing a block and it seems to work properly (i.e. returning "template.hamlc" ratther than "backbone/templates/template.hamlc").

Yet I still have to call JST['backbone/templates/tempalte']() in order to get the template.

I use Rails 3.1.1
This is my Gemfile:

source 'http://rubygems.org'

gem 'aws-sdk'
gem 'cancan'
gem 'devise', '1.5.3'
gem 'friendly_id'
gem 'haml-rails'
gem 'jquery-rails'
gem 'json'
gem 'mysql2'
gem 'paperclip', '~> 2.7.0'
gem 'rails', '3.1.3'
gem 'rails-backbone'
gem 'simple_form'
# gem 'therubyracer'

# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'coffee-rails', '~> 3.1.0'
  gem 'execjs'
  gem 'haml_coffee_assets'
  gem 'sass-rails', '~> 3.1.0'
  gem 'uglifier'
  gem 'zurb-foundation'
end

group :development, :test do
  gem 'capybara', '~> 1.1.2'
  gem 'cucumber-rails', '~> 1.2.1'
  gem 'database_cleaner'
  gem 'factory_girl_rails', '1.4.0'
  gem 'minitest', '~> 2.10.0'
  gem 'mongrel'
  gem 'pry'
  gem 'rspec-rails', '2.7.0'
end

and this is my application.coffee:

#/= require jquery
#/= require jquery_ujs
#/= require foundation
#/= require underscore
#/= require hamlcoffee
#/= require_tree ./backbone/templates
#/= require backbone
#/= require backbone_rails_sync
#/= require backbone_datalink
#/= require_tree ./backbone

%textarea issue

%textarea
   =  @title 

compiles to

function (context) {
    var fn;
    fn = function(context) {
      var c, e, o;
      o = [];
      e = HAML.escape;
      c = HAML.cleanValue;
      o.push("<textarea>undefined</textarea>");
      return o.join("\n");
    };
    return fn.call(HAML.context(context));
  }

This only happens with textareas... any idea what's happening ?

doesn't support quoted symbols

.whatever { data: { :'some-thing' => 'foo' } }

Parses as

      $o.push("<div class='whatever'>{ data: { :'some-thing' => 'foo' } }</div>");

As far as I can tell, it's not possible to use dashes in any way. strings don't work on the left hand side either.

Make it possible to put templates in a different directory

The latest Sprockets is giving me errors when I try to put my templates directory directly in app/assets.

Uncaught Error: Sprockets::FileOutsidePaths: /Users/dorje/work/cms/app/assets/templates/about.hamlc isn't in paths: /Users/dorje/work/cms/app/assets/images, /Users/dorje/work/cms/app/assets/javascripts, /Users/dorje/work/cms/app/assets/stylesheets, /Users/dorje/work/cms/vendor/assets/images, /Users/dorje/work/cms/vendor/assets/javascripts, /Users/dorje/work/cms/vendor/assets/stylesheets, /Users/dorje/.rvm/gems/ruby-1.9.2-p290/gems/haml_coffee_assets-0.4.0/vendor/assets/javascripts, /Users/dorje/.rvm/gems/ruby-1.9.2-p290/gems/rails-backbone-0.5.5/vendor/assets/javascripts, /Users/dorje/.rvm/gems/ruby-1.9.2-p290/gems/jquery-rails-1.0.19/vendor/assets/javascripts

It also gives me much cognitive dissonance not to put my templates with the rest of my JS application.

Is there a way I can configure the app to view a certain directory as the base dir? I've been reading through all kinds of Tilt stuff but I can't quite figure out what this scope.logical_path stuff is about.

Assets not well pre-compiled since 0.8.0

Hi Michael!

Thanks for haml_coffee_assets, however we had a big issue last week when we first try to deploy our Universal Real-Time Statistics Demo page with haml_coffee_assets 0.8.2. It seemed that the assets where not well pre-compiled (there was a dummy JS error, nothing more), we couldn't find really the cause of it, the only thing that I did find is that by reverting to 0.7.1, everything was working again (so it fails with 0.8.2, 0.8.1 and 0.8.0).

So I think there might be an issue in these commits, maybe in this line, I can't see any other significant changes...

Thanks for the help!

assets:precompile fail in production

Hi I've been trying to deploy but it keeps on failing on assets precompile.

can't modify immutable index
haml_coffee_assets-1.4.1/lib/haml_coffee_assets/rails/engine.rb:19:in `block in class:Engine'

I'm using 1.4.1 with sprockets 2.1.3 and rail ties 3.2.7

not escaping HTML

Hi, in my configuration I have:

config.hamlcoffee.escapeHtml = false
config.hamlcoffee.escapeAttributes = false
config.hamlcoffee.uglify = true

But whenever I pass HTML into JST it is escaped anyway, e.g.:

JST['template']({title: "<p>asd</p>"})

Will return

<header>
  <h2>&lt;p&gt;asd&lt;/p&gt;</h2>
</header>

There doesn't seem to be anything unusal about my Gemifle setup, I'm using Rails 3.2 on Ruby 1.9.3, with haml and coffee everywhere.

Single quotes in attribute values are converted to double quotes

In the following template, the single quote in the title attribute is converted into a double quote:

%a{ href: '#', title: "This shouldn't be a double quote" } But it is

This produces the following HTML:

<a href='#' title="This shouldn&quot;t be a double quote">But it is</a>

As a result, the title is displayed at:

This shouldn"t be a double quote

Instead of converting ' to &quot;, it should be converted to &#39; or &apos;.

Empty lines aren't supported

Empty lines broke the template:

#cart
  %h2= I18n.t('js.cart.title')

  - if @cart.length == 0
    %p.empty= I18n.t('js.cart.empty')

  - else
    %ul
      - for item in @cart
        %li
          .item
            = item.name
            %a{ :href => "/cart/item/remove/#{ item.id }" }
              = I18n.t('js.cart.item.remove')

HAML HTML comments parse error

I got parse error when using HTML comments in HAMLC code with { or }
for example

/  %a{:href=>''}

But Coffee code comment work ok in this case

-# %a{:href=>''}

Guard for config?

maybe I'm missing something, but it seems like config.hamlcoffee.whatever would throw in environments that don't include the :assets group. Is there a good way to guard against this?

Did brackets' behavior changed?

Not sure if it's a bug, but some existing code got broken.

> test1 = "%label{:for => 'gods_sake'} It fails (whyyyyy?)"
> HamlCoffeeAssets::HamlCoffee.compile 'test1', test1, false
ExecJS::ProgramError: Error: unclosed ( on line 4
from /home/alerticus/.rvm/gems/ruby-1.9.3-p125/gems/execjs-1.3.1/lib/execjs/external_runtime.rb:68:in `extract_result'

# but it works as expected with the linebreak and indentation

> test2 = "%label{:for => 'gods_sake'}\n  It fails (whyyyyy?)"
> HamlCoffeeAssets::HamlCoffee.compile 'test2', test2, false
=> "(function(context) {\n  return (function() {\n    var $o;\n    $o = [];\n    $o.push(\"<label for='gods_sake'>\\n  It fails (whyyyyy?)\\n</label>\");\n    return $o.join(\"\\n\").replace(/\\s(\\w+)='true'/mg, ' $1').replace(/\\s(\\w+)='false'/mg, '');\n  }).call(HAML.context(context));\n});"

bundle exec rake RAILS_ENV=development assets:precompile failed.

Hello,
Thanks for nice gem.
It looks really cool.
But I can't use it sadly. :(
I'm developing on Windows.
I suppose it cause execjs can't find proper Javascript Runtime.
Then I uninstalled execjs gem.
And installed nodejs, reinstalled execjs gem again.
But it still not work.
How can I fix this problem?
('jst.ejs' work fine)


bundle exec rake RAILS_ENV=development assets:precompile
D:/ruby/bin/ruby.exe D://ruby/lib/ruby/gems/1.9.1/bin/rake assets:precompile:all RAILS_ENV=development RAILS_GROUPS=assets
rake aborted!
TypeError: Object doesn't support this property or method
(in D:/testapp/app/assets/javascripts/app/views/posts/index.jst.hamlc)

Tasks: TOP => assets:precompile:primary
(See full trace by running task with --trace)
rake aborted!
Command failed with status (1): [D:/ruby/bin/ruby.exe D:/ruby...]

Tasks: TOP => assets:precompile
(See full trace by running task with --trace)

Access other assets (images) from a template?

Is there a way to access images or other assets from within a template? In a normal Rails view using Haml you would just do something like:

= image_tag(asset_path("images/rails.png"), :alt => "Rails!")

And it will link you to the cache-buster version of the file: rails-abcd1234efab.png (I think also just image_tag("rails.png") might do the same thing but I'm unsure)

Is there a method that will automatically do that for me here, or should I name a file index.jst.hamlc.erb if I need to include other asset pipeline files and add this:

%img{:src => "<%= asset_path("images/rails.png") %>", :alt => "Rails!")

That feels a little cumbersome...but if there's no other solution it might work (Haven't actually tested it yet).

CoffeScript =>

When using "=>" context feature of CoffeScript it prepends the

var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };

to properly handle it in JS. This prefix appears before your function(context) { wrapper. Which leads to

this.JST["..."] = var __bind = function(fn, me){ ret

which is a syntax error.

hamlc can't be rendered at all?

Hi, I think this is very useful, however there is a problem.

I'm using backbone.js with rails 3.2.2, I created a simple file named hello2.hamlc located at '\app\assets\javascripts\backbone\templates\organizations\hello2.hamlc',

content is simple as below:

%h1 Hello2 HAML

%h1 Listing organizations
%table
  %tr
    %th Name
    %th Parent
    %th Organization type
    %th
    %th
    %th

when I browse to the url which requires the hamlc file, I got an error
ExecJS::ProgramError in Organizations#index

so I debugged into haml_coffee, and found an exception raises as below. I have no idea what's going on, could you help me? thanks very much!

C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.8.4/lib/haml_coffee_ass
ets/haml_coffee.rb:122
self.configuration ||= Configuration.new
(rdb:1) pp configuration
#<HamlCoffeeAssets::HamlCoffee::Configuration:0x231e4f0
 @basename=false,
 @cleanValue=true,
 @context="HAML.context",
 @customCleanValue="HAML.cleanValue",
 @customFindAndPreserve="HAML.findAndPreserve",
 @customHtmlEscape="HAML.escape",
 @customPrecede="HAML.precede",
 @customPreserve="HAML.surround",
 @customSucceed="HAML.succeed",
 @customSurround="window.HAML.surround",
 @escapeAttributes=true,
 @escapeHtml=true,
 @format="html5",
 @namespace="window.JST",
 @preserveTags="textarea,pre",
 @selfCloseTags="meta,img,link,br,hr,input,area,param,col,base",
 @uglify=false>
(rdb:1) p name
"backbone/templates/organizations/hello2"
(rdb:1) p source
"\n%h1 Hello2 HAML\n\n%h1 Listing organizations\n%table\n  %tr\n    %th Name\n
  %th Parent\n    %th Organization type\n    %th\n    %th\n    %th\n"
(rdb:1) p jst
true
(rdb:1) s
C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.8.4/lib/haml_coffee_ass
ets/haml_coffee.rb:123
runtime.call('HamlCoffeeAssets.compile', name, source, jst,
(rdb:1) s
C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.8.4/lib/haml_coffee_ass
ets/haml_coffee.rb:140
@runtime ||= ExecJS.compile(source)
(rdb:1) n
C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.8.4/lib/haml_coffee_ass
ets/haml_coffee.rb:148
coffeescript + ';' + haml_coffee + ';' + haml_coffee_assets
(rdb:1) p coffeescript + ';' + haml_coffee + ';' + haml_coffee_assets
SyntaxError Exception: C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.
8.4/lib/haml_coffee_assets/haml_coffee.rb:148: unterminated string meets end of
file
(rdb:1) n
C:/Ruby192/lib/ruby/gems/1.9.1/gems/haml_coffee_assets-0.8.4/lib/haml_coffee_ass
ets/haml_coffee.rb:172
(rdb:1) n
C:/Ruby192/lib/ruby/gems/1.9.1/gems/execjs-1.3.0/lib/execjs/module.rb:27
runtime.compile(source)
(rdb:1) n
C:/Ruby192/lib/ruby/gems/1.9.1/gems/execjs-1.3.0/lib/execjs/external_runtime.rb:
32
eval "#{identifier}.apply(this, #{MultiJson.encode(args)})"
(rdb:1) p "#{identifier}.apply(this, #{MultiJson.encode(args)})"
"HamlCoffeeAssets.compile.apply(this, [\"backbone/templates/organizations/hello2
\",\"\\n%h1 Hello2 HAML\\n\\n%h1 Listing organizations\\n%table\\n  %tr\\n    %t
h Name\\n    %th Parent\\n    %th Organization type\\n    %th\\n    %th\\n    %t
h\\n\",true,\"window.JST\",\"html5\",false,false,true,true,true,\"HAML.escape\",
\"HAML.cleanValue\",\"HAML.surround\",\"HAML.findAndPreserve\",\"window.HAML.sur
round\",\"HAML.succeed\",\"HAML.precede\",\"textarea,pre\",\"meta,img,link,br,hr
,input,area,param,col,base\",\"HAML.context\"])"
(rdb:1) n
C:/Ruby192/lib/ruby/gems/1.9.1/gems/sprockets-2.1.2/lib/sprockets/context.rb:179

annotate_exception! e
(rdb:1)

Not compiling under Rails 3.1.1 or 3.1.3

I have the require to hamlcoffee and require_tree to the assets/templates directory in my application.js.coffee. The gem is required in the assets block of my Gemfile.

My .jst.hamlc files don't get compiled. Instead when loading the application in a browser, I get the following error in the console

clients.htmlc.js GET http://localhost:3000/assets/clients.htmlc.js?body=1 404 (Not Found)

Moreover, there is no JST object available to the Javascript code.

Strange results for whitespace removal on 1.9

Ruby 1.9.3-p194 and haml_coffee_assets 0.9.0:

Example 1:

%blockquote<
  %div
    Foo!

Expected:

<blockquote><div>
  Foo!
</div></blockquote>

Actual:

<blockquote>Â’
<div>
Foo!
</div>
‘</blockquote>

Example 2:

%img
%img>
%img

Expected:

<img><img><img>

Actual:

<img>
‘<img>
<img>

These examples are from the Haml Reference.

Weird behavior when using space before the : of an attribute

I noticed some strange behaviors when using a space between an attribute and its :.

/ Works well.
%span.value{ 'foo': 'foo', 'bar': 'bar', baz: 'baz' } Foo
/ <span class="value" foo="foo" bar="bar" baz="baz">Foo</span>

/ Throws error. ExecJS::ProgramError: Unable to parse tag.
/ %span.value{ 'foo' : 'foo', 'bar' : 'bar', baz: 'baz' } Foo
/ It only throw error when the space is after the first attribute !?


/ Works weird: no error despite the space but fucked HTML.
%span.value{ 'foo': 'foo', 'bar' : 'bar', baz: 'baz' } Foo
/ <span class="value" foo="foo&quot;, &quot;bar&quot; :&quot;bar" baz="baz">Foo</span>

/ Less strange in data attribute: the attribute is just not displayed:
%span.value{ data: { 'foo' : 'foo', 'bar': 'bar' } } Foo
/ <span class="value" data-bar="bar">Foo</span>

So I stick with foo: 'foo' or 'foo-foo': 'foo' for keys.
But I thought it was important to point that bugs out as they can drive you crazy.

Setting name_filter still requires me to use the original path for templates

I'm trying to get the gem setup for development. I followed the current README:

  1. Placed the gem in the assets group in the Gemfile
  2. Add the name_filter configuration in application.rb, around a if defined? ::HamlCoffeeAssets if block: n.sub /^backbone\/templates\//, ''
  3. Required the hamlcoffee js file

But when I type JST in the javascript console, I see the old path of my templates: backbone/templates/path/to/template. Howcome it doesn't seem to register?

If you need more information I'd be happy to give it.

Template undefined in JST after being added earlier

Here is a .hamlc template I am having trouble with:

%td= new Date(@transaction.get('posted_at')).toString('M/d/yyyy')
%td= @transaction.escape('description')
%td= @transaction.debit()
%td= @transaction.credit()
%td= @transaction.running_balance()

This compiles down to the final javascript template thus:

(function() {
  this.JST || (this.JST = {});
  this.JST["transactions/show"] = (function() {
    var _ref;
    if ((_ref = window.JST) == null) {
      window.JST = {};
    }
    window.JST['transactions/show'] = function(context) {
      var fn;
      fn = function(context) {
        var c, e, o;
        o = [];
        e = HAML.escape;
        c = HAML.cleanValue;
        o.push("<td>" + (e(c(new Date(this.transaction.get('posted_at')).toString('M/d/yyyy')))) + "</td>");
        o.push("<td>" + (e(c(this.transaction.escape('description')))) + "</td>");
        o.push("<td>" + (e(c(this.transaction.debit()))) + "</td>");
        o.push("<td>" + (e(c(this.transaction.credit()))) + "</td>");
        o.push("<td>" + (e(c(this.transaction.running_balance()))) + "</td>");
        return o.join("\n");
      };
      return fn.call(HAML.context(context));
    };
  }).call(this);;
}).call(this);

I noticed that the template is null/undefined when I try to use it in my backbone view, so I started tracing back to see where it was getting set figuring I had the order of imports wrong or something. The interesting thing that I found was that the above javascript was getting called before my view code looked for the template and it was also adding the template to window.JST! When I put a breakpoint before the line that reads "}).call(this);;" (basically stopping just before the call to .call(this)) and check the value of window.JST['transactions/show'] it is the function as expected. If I step on more line however window.JST['transactions/show'] is now undefined.

This is my first hamlc template (I've been using ECO), so it's very likely I'm just doing something wrong, but I haven't been able to figure it out and any help would be greatly appreciated.

Interpolation followed by an & causes an ExecJS::ProgramError

Hi there,

New to haml_coffee_assets so please forgive me if I'm doing something dumb.

The following interpolation with a .hamlc file causes an error:

%a{ href: "/people?name=#{@name}&page=4" }

Error is:

Uncaught Error: ExecJS::ProgramError: missing ', starting on line $LINE_NUMBER

Changing the href to omit the ampersand after the interpolation prevents the error, as does using + to concatenate strings:

%a{ href: "/people?name=#{@name}page=4" }

%a{ href: "/people?name=" + @name + "&page=4" }

Seems like an ampersand directly after the interpolation is the cause of the error, but I'm not sure exactly why.

Cheers :)

Edit: I'm using haml_coffee_assets 0.9.4.

Make it JST compliant

Currently it generates the full JST template trying to shorten the names.
I did similar thing in my pakunok gem for hamljs. Did it even smarter when ot was producing the plain function names for subdirectories.

But after some discussions and considerations decided to stick to rails conventions
This resulted in a separate gem (ruby-haml-js).

It might look like a good idea to automatically attach the template to JST.
But this is not how it is supposed to be.

Regression in 1.1.1 with two attributes and #{} in first

This input doesn't seem to work anymore in 1.1.1:

%div(foo="#{func('foo')}" bar="bar")

Diff between 1.1.0 and 1.1.1 output:

--- regression_1.1.0.js 2012-07-04 12:13:02.000000000 +0200
+++ regression_1.1.1.js 2012-07-04 12:14:31.000000000 +0200
@@ -2,11 +2,11 @@
   this.JST || (this.JST = {});
   this.JST["regression"] = (function(context) {
     return (function() {
-      var $o;
+      var $o, bar;

       $o = [];

-      $o.push("<div foo='" + (func('foo')) + "' bar='bar'></div>");
+      $o.push(("<div foo='" + (func('foo')))(bar = "bar'></div>"));

       return $o.join("\n").replace(/\s(\w+)='�true'/mg, ' $1').replace(/\s(\w+)='�false'/mg, '');

not fully haml compatible

The following haml works in a haml template but not in a hamlc template:

%div <div class="strong"><p>Hello world!</p></div>

The exeception thrown is Error: Parse error on line 2: Unexpected 'IDENTIFIER'.

It'd be great to support it so that for example some rails view helpers can be used:

%span Here's the link: <%=content_tag("a", "Test", href: "http://www.example.com", target: "_blank")%>

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.