Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to run ruby in haml in javascript definition?

Tags:

ruby

haml

  • how can I run ruby code inside javascript in haml?
  • if I use var = #{message} in my example I get undefined local variable or method message
  • when I move - message = 'it works' above :javascript everything works fine

I want to run iteration .each inside :javascript. See the last code sample for what I need in final javascript code. Where I need to loop few ruby variables (or one hash of hashes of hashes?) to get this. Data (='basics') can have few elemenets. It can have children with few elements etc.

SO this haml code

%html
  %head
    :javascript
      $(document).ready(function() {
        - message = 'it works'
            var = message

        });
%body
    - message2 = 'hi'
    = message2
    %div{:id =>"jstree"}

gives me this html code

<html>
  <head>
    <script type='text/javascript'>
      //<![CDATA[
        $(document).ready(function() {
            - message = 'hi'
            var = message

        });
      //]]>
    </script>
  </head>
  <body>
    hi
    <div id='jstree'></div>
  </body>
</html>

The final javascript code I want to produce using haml is the javascript variable

var data = [{
       data: "basics",
       attr: {},
        children: [
         {data: "login", attr: {run: "run"},
           children: [                   
           {data: "login", attr: {}}
          ]
         } ,
         {data: "Academic Year", attr: {run: "run"},
          children: [                   
           {data: "login", attr: {}},
           {data: "Academic Year", attr: {filter: "mini", SOF: "yes"}}
          ]

         }
        ]
      }];
like image 774
Radek Avatar asked May 03 '11 02:05

Radek


2 Answers

First, let's review what you seem to know:

  1. Ruby requires you to define local variables before you use them.
  2. You can run Ruby code on lines outside of a filter using - ....
  3. You use #{...} markup to interpolate Ruby code inside a filter.

You say you want to run each, but presumably you want output from this; since the result of #{...} is turned into a string and put in your code, what you really want (probably) is map:

%html
  %head
    :javascript
      var foo = [];
      #{
        limit = rand(4)+3
        array = (0..limit).to_a
        array.map{ |i| "foo[#{i}] = #{rand(12)};" }.join ' '
      }
      console.log(foo.length);
    %body

Running the above code gives this output:

<html>
  <head>
    <script type='text/javascript'>
      //<![CDATA[
        var foo = [];
        foo[0] = 2; foo[1] = 0; foo[2] = 11; foo[3] = 8; foo[4] = 0; foo[5] = 1;
      //]]>
    </script>
    <body></body>
  </head>
</html>

As you can see, the big #{...} block (which may span multiple lines) runs arbitrary Ruby code. The result of the last expression (in this case the map{...}.join) is converted to a string and placed in the output.

like image 199
Phrogz Avatar answered Oct 31 '22 19:10

Phrogz


The haml documentation for filters states that you can interpolate Ruby code using #{}

- flavor = "raspberry"
#content
  :textile
    I *really* prefer _#{h flavor}_ jam.
like image 44
Jeff Perrin Avatar answered Oct 31 '22 21:10

Jeff Perrin