ice 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,10 +1,13 @@
1
1
  #Ice Ice Baby!!!
2
2
 
3
- The Ice system for CoffeeScript/Javascript templating allows people to serve Javascript templates thanks to [The Ruby Racer](http://github.com/cowboyd/therubyracer), a gem letting you use Google's V8 Javascript engine. These templates are then compiled and served to the browser.
3
+ The Ice system for templating allows people to serve Coffescript templates from Rails applications. The advantage of this approach is that it is easy to serve these templates from a secure sandbox. Therefore, your users can upload templates that are evaluated and served, but exist securely.
4
4
 
5
- One of the key advantages of this approach is that the templates execute in their own sandbox. This is the approach taken by [Liquid](http://github.com/tobi/liquid) and some of the other template systems.
5
+ This is the approach taken by [Liquid](http://github.com/tobi/liquid) and some other template systems. The advantage of using Ice for this is that you have a rich language at your disposal, as well as being able to provide your own functions that can be exposed to your users.
6
6
 
7
- The template parser we currently use is Eco (written by [Sam Stephenson](https://github.com/sstephenson/eco)). This allows you to use Coffeescript with HTML in an ERB-ish fashion.
7
+ Ice builds upon two excellent Gems:
8
+
9
+ * [The Ruby Racer](http://github.com/cowboyd/therubyracer) (written by Charles Lowell). This gem lets you use Google's V8 Javascript engine.
10
+ * [Eco](https://github.com/sstephenson/ruby-eco) (written by Sam Stephenson). This gem allows you to use Coffeescript with HTML in an ERB-ish fashion.
8
11
 
9
12
  You can then write Eco templates like:
10
13
 
@@ -12,14 +15,16 @@ You can then write Eco templates like:
12
15
  <tr><th>Name</th><th>Email</th></tr>
13
16
  <% for user in @users %>
14
17
  <tr>
15
- <td><%= user.name %></td><td><%= @mailTo(user.email) %></td>
18
+ <td><%= user.name %></td><td><%= mailTo(user.email) %></td>
16
19
  </tr>
17
20
  <% end %>
18
21
  </table>
19
22
 
20
23
  Eco-formatted files may also exist in your filesystem, provided they have a .eco extension. Also, the templates may be compiled on demand with the method:
21
24
 
22
- Ice::EcoTemplate.convert(template_text, vars = {})
25
+ Ice::EcoTemplate.convert(template_text, variables)
26
+
27
+ The variables are whatever environment you want to pass in to the application.
23
28
 
24
29
  ## Installation
25
30
 
@@ -33,13 +38,13 @@ Every object is revealed to the templates via its to_ice method. This helps san
33
38
 
34
39
  Instances of some classes like String and Numeric just return themselves as the result of to_ice. Hashes and Arrays run to_ice recursively on their members.
35
40
 
36
- If you want an object to map to a different representation, simply define a to_ice object that returns whatever object you want to represent it within the eco template. These objects are referred to as "Cubes", and are equivalent to "Drops" for those used to the Liquid template.
41
+ If you want an object to map to a different representation, simply define a to_ice object that returns whatever object you want to represent it within the Eco template. These objects are referred to as "Cubes", and are equivalent to "Drops" for those used to Liquid.
37
42
 
38
43
  ## ActiveModel and to_ice
39
44
 
40
45
  To make life easy, since most complex objects passed to the templates will be classes including ActiveModel::Serializable, the default to_ice behaviour of these classes is to pass itself in to a class with the same name, but followed by the word "Cube".
41
46
 
42
- Therefore calling to_ice on instance of a User class will invoke
47
+ Therefore calling to_ice on an instance of a User class will invoke
43
48
 
44
49
  UserCube.new self
45
50
 
@@ -70,15 +75,22 @@ Note that the results of all associations and revealed functions are also saniti
70
75
 
71
76
  ## Partials
72
77
 
73
- Partials may now be written in Eco, and included in Erb (and other) templates.
78
+ Partials may now be written in Eco, and included in ERB (and other) templates.
79
+
80
+
81
+ ## Helpers
82
+
83
+ Two global arrays exist named `IceJavascriptHelpers` and `IceCoffeescriptHelpers`. If you add to those arrays strings of Javascript or Coffeescript, those strings will be included in your views. These string are also compiled in the case of Coffeescript.
84
+
85
+ This is slightly hackish, so expect this approach to shortly be replaced with a better one. But it is a decent way to add helpers to your Eco file.
74
86
 
75
87
  ## NavBar
76
88
 
77
- To make it easier to generate links, we added a `@navBar` helper.
89
+ To make it easier to generate links, we added a `navBar` helper.
78
90
 
79
- <%- @navBar (bar) => %>
80
- <%- bar.linkTo("Bar", "/foo") %>
81
- <%- bar.linkTo("http://ludicast.com") %>
91
+ <%= navBar (bar) => %>
92
+ <%= bar.linkTo("Bar", "/foo") %>
93
+ <%= bar.linkTo("http://ludicast.com") %>
82
94
  <% end %>
83
95
 
84
96
  This then generates the following html
@@ -88,10 +100,10 @@ This then generates the following html
88
100
  <li><a href="http://ludicast.com">http://ludicast.com</a></li>
89
101
  </ul>
90
102
 
91
- The `@navBar` helper also takes options so if the above was instead instantiated with:
103
+ The `navBar` helper also takes options so if the above was instead instantiated with:
92
104
 
93
- <% @opts = nav_prefix:'<div>', nav_postfix: '</div>', link_prefix: '<span>', link_postfix: '</span>' %>
94
- <%- @navBar @opts, (bar)=> %>
105
+ <% opts = nav_prefix:'<div>', nav_postfix: '</div>', link_prefix: '<span>', link_postfix: '</span>' %>
106
+ <%= navBar opts, (bar)=> %>
95
107
 
96
108
  it would generate
97
109
 
@@ -100,27 +112,31 @@ it would generate
100
112
  <span><a href="http://ludicast.com">http://ludicast.com</a></span>
101
113
  </div>
102
114
 
103
- Also, if you want to make a site-wide change to the default NavBar settings, all you need to do is add these options to the NavBarConfig class (in Ruby) like
115
+ Also, if you want to make a site-wide change to the default NavBar settings, all you need to do is add these options to the NavBarConfig class like
104
116
 
105
- NavBarConfig[:nav_prefix] = "<div>"
106
- NavBarConfig[:nav_postfix] = "</div>"
107
- NavBarConfig[:link_prefix] = "<span>"
108
- NavBarConfig[:link_postfix] = "</span>"
117
+ coffeescript = <<-COFFEESCRIPT
118
+ NavBarConfig =
119
+ navPrefix: "<div>",
120
+ navPostFix: "</div>",
121
+ linkPrefix: "<span>",
122
+ linkPostFix: "</span>"
123
+ COFFEESCRIPT
124
+ IceCoffeescriptHelpers << coffeescript
109
125
 
110
- Then all links will generate with these options, unless overridden in the values passed it to `@navBar`.
126
+ Then all links will generate with these options, unless overridden in the values passed in to `navBar`.
111
127
 
112
128
  ## Routes
113
129
 
114
- Assuming that all your cubes are models that you are exposing to your app, we add to your eco templates routing helpers for every class inheriting from BaseCube. Therefore, if you have a cube class named `NoteDrop`, you will have the following helper methods available:
130
+ Assuming that all your cubes are models that you are exposing to your app, we add to your Eco templates routing helpers for every class inheriting from BaseCube. Therefore, if you have a cube class named `NoteCube`, you will have the following helper methods available:
115
131
 
116
- @newNotePath
117
- @notesPath
118
- @notePath(@note)
119
- @editNotePath(@note)
132
+ newNotePath
133
+ notesPath
134
+ notePath(@note)
135
+ editNotePath(@note)
120
136
 
121
137
  which are converted to the appropriate paths.
122
138
 
123
- Note that some people might claim that it is insecure to expose your resources like this, but that probably should be dealt with on a case-by-case basis.
139
+ Note that some people might claim that it is insecure to expose your resources like this, but that probably should be dealt with on a case-by-case basis. Besides, the fact that you are exposing these resources as cubes means that you are, well, already exposing these resources.
124
140
 
125
141
  ## Note on Patches/Pull Requests
126
142
 
@@ -132,7 +148,6 @@ Note that some people might claim that it is insecure to expose your resources l
132
148
 
133
149
  ## Todo
134
150
 
135
- * Allow Coffeescript (or Javascript) helpers to be read from an additional file.
136
151
  * Add in form builders (from clots project)
137
152
  * Haml support
138
153
  * Use [Moneta](http://github.com/wycats/moneta) for caching autogenerated javascript files.
data/lib/ice.rb CHANGED
@@ -9,7 +9,7 @@ require 'rails'
9
9
 
10
10
  require 'ice/eco_template/handler'
11
11
 
12
- NavBarConfig = {}
13
-
12
+ IceJavascriptHelpers = []
13
+ IceCoffeescriptHelpers = []
14
14
 
15
15
  ActionView::Template.register_template_handler :eco, Ice::EcoTemplate::Handler
@@ -1,17 +1,26 @@
1
- require "ice/eco_template/context"
1
+ require "ice/eco_template/generated_helpers"
2
2
  require 'eco'
3
3
  require 'v8'
4
4
 
5
5
  module Ice
6
6
  module EcoTemplate
7
+
7
8
  def self.convert_template(template_text, vars = {})
8
- env = Context.new vars
9
9
  context = V8::Context.new
10
- context.eval(Eco::Source.combined_contents)
10
+ context.eval(open "#{File.dirname(__FILE__)}/../../../js/lib/path-helper.js")
11
+
12
+ IceJavascriptHelpers.each do |helper|
13
+ context.eval(helper)
14
+ end
15
+ IceCoffeescriptHelpers.each do |helper|
16
+ context.eval CoffeeScript.compile(helper, :bare => true)
17
+ end
11
18
 
19
+ context.eval CoffeeScript.compile(GeneratedHelpers.get_routes, :bare => true)
20
+ context.eval(Eco::Source.combined_contents)
12
21
  template = context["eco"]["compile"].call(template_text)
13
- # Render the template
14
- template.call(env)
22
+
23
+ template.call(vars.to_ice)
15
24
  end
16
25
  end
17
26
  end
@@ -0,0 +1,31 @@
1
+ module Ice
2
+ module EcoTemplate
3
+ module GeneratedHelpers
4
+ def self.get_routes
5
+ coffeescript = ""
6
+ Ice::BaseCube.subclasses.map(&:name).each do |cube_model_name|
7
+ model_name = cube_model_name.sub(/Cube/, "")
8
+ name = model_name[0].downcase + model_name[1..-1]
9
+
10
+ coffeescript << <<-COFFEESCRIPT
11
+
12
+ edit#{model_name}Path = (object)->
13
+ "/#{name.tableize}/" + object.id + "/edit"
14
+
15
+ new#{model_name}Path = ()->
16
+ "/#{name.tableize}/new"
17
+
18
+ #{name}Path = (object)->
19
+ "/#{name.tableize}/" + object.id
20
+
21
+ #{name.pluralize}Path = ()->
22
+ "/#{name.tableize}"
23
+
24
+ COFFEESCRIPT
25
+ end
26
+ coffeescript
27
+ end
28
+
29
+ end
30
+ end
31
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: ice
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.4.0
5
+ version: 0.4.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Nate Kidwell
@@ -49,7 +49,7 @@ files:
49
49
  - lib/ice/cube_helpers.rb
50
50
  - lib/ice/cubeable.rb
51
51
  - lib/ice/eco_template/base.rb
52
- - lib/ice/eco_template/context.rb
52
+ - lib/ice/eco_template/generated_helpers.rb
53
53
  - lib/ice/eco_template/handler.rb
54
54
  - lib/ice/railtie.rb
55
55
  - lib/ice.rb
@@ -1,76 +0,0 @@
1
- module Ice
2
- module EcoTemplate
3
- class Context < Hash
4
-
5
- def initialize(hash)
6
- add_routes
7
- add_links
8
- add_nav_bar
9
- hash.each_pair do |key, value|
10
- self[key] = value.to_ice
11
- end
12
- end
13
-
14
- private
15
-
16
- def add_routes
17
- Ice::BaseCube.subclasses.map(&:name).each do |cube_model_name|
18
- model_name = cube_model_name.sub(/Cube/, "")
19
- name = model_name[0].downcase + model_name[1..-1]
20
-
21
- self["edit" + model_name + "Path"]= lambda do |object|
22
- "/#{name.tableize}/#{object.id}/edit"
23
- end
24
-
25
- self["new" + model_name + "Path"]= lambda do
26
- "/#{name.tableize}/new"
27
- end
28
-
29
- self[name + "Path"]= lambda do |object|
30
- "/#{name.tableize}/#{object.id}"
31
- end
32
-
33
- self[name.pluralize + "Path"]= lambda do
34
- "/#{name.tableize}"
35
- end
36
-
37
- end
38
- end
39
-
40
- def add_links
41
- self["linkTo"] = lambda do |label, link|
42
- if (!link)
43
- link = label
44
- end
45
- %{<a href="#{link}">#{label}</a>}
46
- end
47
- end
48
-
49
- def try_config(opts, var, config_class)
50
- opts.first.try(var) ||
51
- config_class.try(:[], var)
52
- end
53
-
54
- def try_nav_config(opts, sym)
55
- try_config opts, sym, NavBarConfig
56
- end
57
-
58
- def add_nav_bar
59
-
60
-
61
- self["navBar"] = lambda do |*opts, yield_func|
62
- nav_prefix = try_nav_config(opts, :nav_prefix) || '<ul class="linkBar">'
63
- nav_postfix = try_nav_config(opts, :nav_postfix) || '</ul>'
64
- link_prefix = try_nav_config(opts, :link_prefix) || '<li>'
65
- link_postfix = try_nav_config(opts, :link_postfix) || '</li>'
66
- ctx = {}
67
- ctx['linkTo'] = lambda do |label, link = nil|
68
- "#{link_prefix}#{self["linkTo"].call label, link}#{link_postfix}"
69
- end
70
- body = yield_func.call(ctx)
71
- %{#{nav_prefix}#{body}#{nav_postfix}}
72
- end
73
- end
74
- end
75
- end
76
- end