stache 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c4d478dbffc3306efd783fe17d868a8879c0b24
4
- data.tar.gz: ddba634b4929cc0ac1c83ef8f888b13cee625f10
3
+ metadata.gz: 351c235cf203b65a8eacf4a9fcb01b9236eb54e1
4
+ data.tar.gz: 6540207101f87ff30024205a56c8b308e690280e
5
5
  SHA512:
6
- metadata.gz: f1b49b3ddf56014e1bae27183c5b7b393415d4d27e39884a2701bf505f88b1134fdbd31cd9ed0fe1aecb6920e1ccc9cb327a898082d88d904f1afef33daa0089
7
- data.tar.gz: 0747cd7f832dfdaaca2adeeae2fb3316cf52f9bc582a375139523ea2ea2e64982bba6153a340b99011d7fda39a1285a5957ec65940bb75d50e7b8ee5cbdfb745
6
+ metadata.gz: 689692a05dcf7dc95b82adac7cfb37cd1b0d91f618277584115baffa5a543bc7f0af4e456e172826b5c5dae398b1c06e25822876c14de7a77835fad706e8af2f
7
+ data.tar.gz: cfd7331c2b602ac2a777ab3c98f22df598f280a5a25a5b8e7eaef54557b06d7297b07be29134db2a81ba2643125e74cfc31b492a6b37363207f886b443f1e345
data/.gitignore CHANGED
@@ -13,6 +13,7 @@ doc
13
13
  .yardoc
14
14
 
15
15
  spec/dummy/log/
16
+ spec/dummy/tmp/
16
17
 
17
18
  # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
19
  #
data/.rspec CHANGED
@@ -1,2 +1,2 @@
1
1
  --color
2
- --format nested
2
+ --format documentation
@@ -1 +1 @@
1
- ruby-2.0.0
1
+ ruby-2.1.1
@@ -1,4 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - 2.0.0
4
+ - 2.0.0
5
+ - 2.1.1
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.0 (2014-09-05)
4
+
5
+ * Overhaul of Stache::Mustache rendering by [@MarkusHarmsen](https://github.com/MarkusHarmsen) brings caching, and with it, 200-300% rendering performance enhancements. Thanks!
6
+
3
7
  ## 1.0.3 (2014-01-14)
4
8
 
5
9
  * Access RSpec-assigned instance variables in view classes (Thanks [@kianw](https://github.com/kianw))
data/README.md CHANGED
@@ -1,18 +1,16 @@
1
1
  # stache
2
2
 
3
- A Rails 3.x compatible Mustache/Handlebars Template Handler, with support for partials and a couple extra niceties to make sharing the raw templates with client-side javascript a little easier. It's a one-stop shop for your facial-hair-inspired templates.
3
+ A Rails 3.x and Rails 4.x compatible Mustache/Handlebars template handler, with support for partials and a couple extra niceties to make sharing the raw templates with client-side javascript a little easier. It's a one-stop shop for your facial-hair-inspired templates.
4
4
 
5
5
  [![Build Status](https://secure.travis-ci.org/agoragames/stache.png)](http://travis-ci.org/agoragames/stache)
6
6
 
7
- ## 1.0.0
7
+ ## Mustache template caching is in 1.1+
8
8
 
9
- Major overhaul to the mustache side of things. Backwards compatibility *should* be intact. If not, file a bug and it will get taken care of.
9
+ I'm investigating whether or not this is something that can be/needs to be ported to handlebars.
10
10
 
11
- Handlebars can also handle application layouts, and you can use subclasses of Stache::Handlebars::View to define view-specific helpers now.
11
+ ## Rails 4 Support is in 1.0.3+
12
12
 
13
- ## Notice Of Breaking Changes
14
-
15
- Stache 0.9.x adds handlebars support. In the process, the public API has changed *ever-so-slightly*. Specifically, you'll need to require the mustache or handlebars gems on your own, **and** you'll need to tell Stache which one (or both!) you want to use. Add `config.use :mustache` to your initializer.
13
+ If you want Rails 4, you'll have to use 1.0.3.
16
14
 
17
15
  ## Usage
18
16
 
@@ -23,21 +21,34 @@ Install the gem. If you want to override any of the configuration options (see `
23
21
 
24
22
  ```ruby
25
23
  Stache.configure do |c|
26
- c.template_base_path = "..." # this is probably the one you'll want to change
27
- # it defaults to app/templates
24
+ # This is probably the one you'll want to change
25
+ # it defaults to app/templates
26
+ c.template_base_path = "..."
28
27
 
29
- c.wrapper_module_name = "..." # this lets you indicate the name of a module that
30
- # namespaces all your view classes, useful, if you
31
- # have a naming conflict, such as with a mailer
28
+ # This lets you indicate the name of a module that
29
+ # namespaces all your view classes, useful, if you
30
+ # have a naming conflict, such as with a mailer
31
+ c.wrapper_module_name = "..."
32
32
 
33
33
  # N.B. YOU MUST TELL STACHE WHICH TO USE:
34
34
  c.use :mustache
35
35
  # and / or
36
36
  c.use :handlebars
37
+
38
+ # Set it to true if template path should be included in
39
+ # script's id tag as a underscored prefix. It can be
40
+ # overwritten by an id param in `#template_include_tag`.
41
+ c.include_path_in_id = false
42
+
43
+ # Caching (new in 1.1.0, Mustache-only for now)
44
+ # Any ActiveSupport::Cache should work fine.
45
+ # If you enable this in development, you will lose automagical template reloading!
46
+ c.template_cache = ActiveSupport::Cache::MemoryStore.new if Rails.env.production?
37
47
  end
38
48
 
39
49
  # or if the block style ain't yer thang, just:
40
50
  Stache.template_base_path = File.join(Rails.root, "app", "şablon")
51
+ Stache.template_cache = ActiveSupport::Cache::MemoryStore.new if Rails.env.production?
41
52
  ```
42
53
 
43
54
  There is as of right now one provided helper, `template_include_tag`. Give it the name of a partial and it will write it raw to a script block.
@@ -94,8 +105,8 @@ You can subclass `Stache::Handlebars::View` in the same way as mustache above, b
94
105
 
95
106
  ## View Specs
96
107
 
97
- Yes, you can write view specs using RSpec for your Stache templates! You can use RSpec's `assign` method to
98
- assign values to view instance variables, which will then be be available to the Stache view, either as
108
+ Yes, you can write view specs using RSpec for your Stache templates! You can use RSpec's `assign` method to
109
+ assign values to view instance variables, which will then be be available to the Stache view, either as
99
110
  instance variables, or via an accessor. Any instance variables defined in the RSpec example will also be
100
111
  similarly available, so
101
112
 
@@ -144,12 +155,6 @@ View:
144
155
 
145
156
  This is code that was ripped out of a research project. It probably has some rough edges.
146
157
 
147
- TODO:
148
-
149
- * more and better integration tests
150
- * automated tests across different rails versions
151
- * other helpers, etc, as desired
152
-
153
158
  ## Thanks to
154
159
 
155
160
  This project builds on work done by the following people and projects:
@@ -172,8 +177,10 @@ So: thanks a ton to those guys.
172
177
  * [zombor](https://github.com/zombor) contributed an overhaul to the Mustache renderer that puts Mustache classes themselves in control of the render chain, not Rails.
173
178
  * [kategengler](https://github.com/kategengler) contributed a patch to allow folks to specify a namespace for their view objects.
174
179
  * [joker1007](https://github.com/joker1007) contributed a patch making the autoload paths setup more broadly compatible.
180
+ * [kianw](https://github.com/kianw) contributed a patch making RSpec a little easier to use.
181
+ * [MarkusHarmsen](https://github.com/MarkusHarmsen) added Mustache caching, leading to HUGE performance increases. Thanks!
175
182
 
176
- Thanks a ton to all of the contributors as well. This would never have grown beyond a mediocre tool that rendered partials without their help!
183
+ Thanks a ton to all of the contributors, equally. This would never have grown beyond a mediocre tool that rendered partials without their help!
177
184
 
178
185
  ## Note on Patches/Pull Requests
179
186
 
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
8
8
  # spec.ruby_opts = ['-w']
9
9
  end
10
10
 
11
- task :default => :spec
11
+ task default: :spec
12
12
 
13
13
  require 'rdoc/task'
14
14
  RDoc::Task.new do |rdoc|
@@ -14,10 +14,8 @@ module Stache
14
14
  end
15
15
 
16
16
  template = template_finder.call(true) rescue template_finder.call(false)
17
- template_id = source.split("/").last
18
-
19
- options = options.reverse_merge(:type => "text/html", :id => "#{template_id.dasherize.underscore}_template")
20
- content_tag(:script, template.source.html_safe, options)
17
+ template_id = (Stache.include_path_in_id) ? source.gsub("/", '_') : source.to_s.split("/").last
18
+ content_tag(:script, template.source.html_safe, options.reverse_merge(type: 'text/html', id: template_id.dasherize.underscore))
21
19
 
22
20
  end.join("\n").html_safe
23
21
  end
@@ -11,7 +11,7 @@ module Stache
11
11
  # use :mustache # or :handlebars
12
12
  # end
13
13
  module Config
14
- attr_accessor :template_base_path, :shared_path, :wrapper_module_name
14
+ attr_accessor :template_base_path, :shared_path, :wrapper_module_name, :include_path_in_id, :template_cache
15
15
 
16
16
  def configure
17
17
  yield self
@@ -33,6 +33,22 @@ module Stache
33
33
  @wrapper_module_name ||= nil
34
34
  end
35
35
 
36
+ def include_path_in_id
37
+ @include_path_in_id ||= false
38
+ end
39
+
40
+ def include_path_in_id= boolean
41
+ @include_path_in_id = boolean
42
+ end
43
+
44
+ def template_cache
45
+ @template_cache ||= ActiveSupport::Cache::NullStore.new
46
+ end
47
+
48
+ def template_cache= cache
49
+ @template_cache = cache
50
+ end
51
+
36
52
  def use template_engine
37
53
  require "stache/#{template_engine}"
38
54
  end
@@ -34,11 +34,11 @@ module Stache
34
34
  content_for(:layout)
35
35
  end
36
36
 
37
- template = handlebars.compile('#{template.source.gsub(/'/, "\\\\'")}');
37
+ template = handlebars.compile('#{template.source.gsub(/'/, "\\\\'")}')
38
38
  vars = {}
39
39
  partial_renderer = PartialRenderer.new(lookup_context)
40
40
  vars.merge!(@_assigns)
41
- vars.merge!(partial_renderer.instance_variable_get('@locals') || {})
41
+ vars.merge!(local_assigns || {})
42
42
  options = partial_renderer.instance_variable_get('@options')
43
43
  vars.merge!(options[:context] || {}) if options
44
44
 
@@ -46,7 +46,7 @@ module Stache
46
46
  search_path = '#{template.virtual_path}'.split("/")[0..-2]
47
47
  file = (search_path + [name]).join("/")
48
48
  finder = lambda do |partial|
49
- self.lookup_context.find(file, [], partial, [], {:formats => [:html]})
49
+ self.lookup_context.find(file, [], partial, [], {formats: [:html]})
50
50
  end
51
51
  template = finder.call(false) rescue finder.call(true)
52
52
 
@@ -1,5 +1,7 @@
1
1
  require "stache/mustache/handler"
2
2
  require "stache/mustache/layout"
3
+ require "stache/mustache/cached_template"
4
+ require "stache/mustache/faster_context"
3
5
 
4
6
  module Stache
5
7
  module Mustache; end
@@ -0,0 +1,41 @@
1
+ module Stache
2
+ module Mustache
3
+ #
4
+ # Extend the Mustache::Template class to support dumping/loading.
5
+ # This is not possible by the original class since it uses a singleton class.
6
+ #
7
+ class CachedTemplate < ::Mustache::Template
8
+
9
+ #
10
+ # Init with uncompiled "source" and "compiled_source" if given.
11
+ #
12
+ def initialize(source, compiled_source = nil)
13
+ super(source)
14
+ @compiled_source = compiled_source
15
+ end
16
+
17
+ #
18
+ # Compiles the source, but uses the already compiled version if
19
+ # present.
20
+ #
21
+ def compile(src = @source)
22
+ @compiled_source || (@compiled_source = super(src))
23
+ end
24
+
25
+ #
26
+ # Store the template by returning the compiled_source
27
+ #
28
+ def _dump(level)
29
+ compile
30
+ end
31
+
32
+ #
33
+ # Restore object by simply setting the compiled_source
34
+ #
35
+ def self._load(compiled_source)
36
+ new(nil, compiled_source)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ module Stache
2
+ module Mustache
3
+ class FasterContext < ::Mustache::Context
4
+
5
+ def partial(name, indentation = nil)
6
+ # Look for the first Mustache in the stack.
7
+ mustache = mustache_in_stack
8
+
9
+ # Do NOT indent the partial template by the given indentation.
10
+ part = mustache.partial(name)
11
+
12
+ # If we already have a template, to not convert it into a string
13
+ part = part.to_s unless part.is_a?(::Mustache::Template)
14
+
15
+ # Call the Mustache's `partial` method and render the result.
16
+ mustache.render(part, self)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -23,30 +23,22 @@ module Stache
23
23
  # system.
24
24
 
25
25
  template_is_class = template.source.match(/module/) ? true : false
26
+ virtual_path = template.virtual_path.to_s
27
+
28
+ # Caching key
29
+ template_id = "#{template.identifier.to_s}#{template.updated_at.to_i}"
26
30
 
27
31
  # Return a string that will be eval'd in the context of the ActionView, ugly, but it works.
28
32
  <<-MUSTACHE
29
33
  mustache = ::#{mustache_class}.new
30
34
  mustache.view = self
31
35
 
32
- if #{template_is_class}
33
- template_name = "#{template.virtual_path.to_s}"
34
- file = Dir.glob(File.join(::Stache.template_base_path, template_name + "\.*" + mustache.template_extension)).first
35
- template_source = File.read(file)
36
- else
37
- template_source = '#{template.source.gsub(/'/, "\\\\'")}'
38
- end
39
-
40
- mustache.template = template_source
41
- mustache.virtual_path = '#{template.virtual_path.to_s}'
36
+ mustache.virtual_path = '#{virtual_path}'
42
37
  mustache[:yield] = content_for(:layout)
43
38
  mustache.context.update(local_assigns)
44
- variables = controller.instance_variable_names
45
- variables -= %w[@template]
46
-
47
- if controller.respond_to?(:protected_instance_variables)
48
- variables -= controller.protected_instance_variables
49
- end
39
+ variables = controller.instance_variables
40
+ variables.delete(:@template)
41
+ variables -= controller.class.protected_instance_variables.to_a
50
42
 
51
43
  variables.each do |name|
52
44
  mustache.instance_variable_set(name, controller.instance_variable_get(name))
@@ -59,11 +51,31 @@ module Stache
59
51
 
60
52
  # Declaring an +attr_reader+ for each instance variable in the
61
53
  # Stache::Mustache::View subclass makes them available to your templates.
62
- mustache.class.class_eval do
63
- attr_reader *variables.map { |name| name.sub(/^@/, '').to_sym }
54
+ mustache.singleton_class.class_eval do
55
+ attr_reader *variables.map { |name| name.to_s.sub(/^@/, '').to_sym }
56
+ end
57
+
58
+ # Try to get template from cache, otherwise use template source
59
+ template_cached = ::Stache.template_cache.read(:'#{template_id}', :namespace => :templates, :raw => true)
60
+ mustache.template = template_cached || Stache::Mustache::CachedTemplate.new(
61
+ if #{template_is_class}
62
+ template_name = "#{virtual_path}"
63
+ file = Dir.glob(File.join(::Stache.template_base_path, template_name + "\.*" + mustache.template_extension)).first
64
+ File.read(file)
65
+ else
66
+ '#{template.source.gsub(/'/, "\\\\'")}'
67
+ end
68
+ )
69
+
70
+ # Render - this will also compile the template
71
+ compiled = mustache.render.html_safe
72
+
73
+ # Store the now compiled template
74
+ unless template_cached
75
+ ::Stache.template_cache.write(:'#{template_id}', mustache.template, :namespace => :templates, :raw => true)
64
76
  end
65
77
 
66
- mustache.render.html_safe
78
+ compiled
67
79
  MUSTACHE
68
80
  end
69
81
 
@@ -24,7 +24,7 @@ module Stache
24
24
  # stick that rendered template as :yield into the layout template
25
25
  # (which will be combined with the current context)
26
26
  if (!ctx.is_a?(::Mustache::Context))
27
- rendered_template = super(layout_template, :yield => rendered_template)
27
+ rendered_template = super(layout_template, yield: rendered_template)
28
28
  end
29
29
 
30
30
  rendered_template
@@ -5,7 +5,12 @@ module Stache
5
5
  #
6
6
  # A Convienent Base Class for the views. Subclass this for autoloading magic with your templates.
7
7
  class View < ::Mustache
8
- attr_accessor :view, :template, :virtual_path
8
+ attr_accessor :view, :virtual_path
9
+
10
+ def context
11
+ # Use the faster context instead of the original mustache one
12
+ @context ||= FasterContext.new(self)
13
+ end
9
14
 
10
15
  def method_missing(method, *args, &block)
11
16
  view.send(method, *args, &block)
@@ -15,21 +20,36 @@ module Stache
15
20
  super(method, include_private) || view.respond_to?(method, include_private)
16
21
  end
17
22
 
23
+ def virtual_path=(path)
24
+ @virtual_path = path
25
+ #
26
+ # Since the addition to the lookup_context only depends on the virtual_path,
27
+ # do it here instead of inside the partial.
28
+ #
29
+ current_dir = Stache.template_base_path.join(path.split("/")[0..-2].join("/"))
30
+ lookup_context.view_paths << current_dir unless lookup_context.view_paths.include?(current_dir)
31
+ end
32
+
18
33
  # Redefine where Stache::View templates locate their partials
19
34
  def partial(name)
20
- current_dir = Stache.template_base_path.join( self.virtual_path.split("/")[0..-2].join("/") )
21
- lookup_context.view_paths += [current_dir]
22
-
23
- template_finder = lambda do |partial|
24
- if ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR < 2
25
- lookup_context.find(name, [], partial)
26
- else # Rails 3.2 and higher
27
- lookup_context.find(name, [], partial, [], { formats: [:html], handlers: [:mustache] })
28
- end
35
+ cache_key = :"#{virtual_path}/#{name}"
36
+
37
+ # Try to resolve template from cache
38
+ template_cached = ::Stache.template_cache.read(cache_key, :namespace => :partials, :raw => true)
39
+ curr_template = template_cached || Stache::Mustache::CachedTemplate.new(
40
+ begin # Try to resolve the partial template
41
+ template_finder(name, true)
42
+ rescue ActionView::MissingTemplate
43
+ template_finder(name, false)
44
+ end.source
45
+ )
46
+
47
+ # Store the template
48
+ unless template_cached
49
+ ::Stache.template_cache.write(cache_key, curr_template, :namespace => :partials, :raw => true)
29
50
  end
30
51
 
31
- template = template_finder.call(true) rescue template_finder.call(false)
32
- template.source
52
+ curr_template
33
53
  end
34
54
 
35
55
  def helpers
@@ -43,6 +63,16 @@ module Stache
43
63
  end
44
64
  alias :h :helpers
45
65
  end
66
+
67
+ protected
68
+ def template_finder(name, partial)
69
+ if ActionPack::VERSION::MAJOR == 3 && ActionPack::VERSION::MINOR < 2
70
+ lookup_context.find(name, [], partial)
71
+ else # Rails 3.2 and higher
72
+ lookup_context.find(name, [], partial, [], { formats: [:html], handlers: [:mustache] })
73
+ end
74
+ end
75
+
46
76
  end
47
77
  end
48
78
  end
@@ -1,6 +1,6 @@
1
1
  module Stache
2
2
  class Railtie < ::Rails::Railtie
3
- initializer 'stache.autoload', :before => :set_autoload_paths do |app|
3
+ initializer 'stache.autoload', before: :set_autoload_paths do |app|
4
4
  app.config.autoload_paths << (Rails.root + 'app/views').to_s
5
5
  end
6
6
 
@@ -1,3 +1,3 @@
1
1
  module Stache
2
- VERSION = "1.0.3"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -52,7 +52,7 @@ describe StacheController do
52
52
  response.body.should == "Wrap\nThis is wrapped in a layout\n\nEndWrap\n"
53
53
  end
54
54
 
55
- it "can get render a mustache with rails helpers", :type => :stache do
55
+ it "can get render a mustache with rails helpers", type: :stache do
56
56
  get :helper
57
57
  assert_response 200
58
58
 
@@ -81,4 +81,43 @@ describe StacheController do
81
81
  Stache.wrapper_module_name = nil
82
82
  end
83
83
  end
84
+
85
+ describe "cache usage" do
86
+ before do
87
+ Stache.template_cache = ActiveSupport::Cache::MemoryStore.new
88
+ end
89
+
90
+ it "fills the cache" do
91
+ get :index
92
+ get :index # Render a second time
93
+ Stache.template_cache.instance_variable_get(:@data).size.should eq(1) # But should only contain one element
94
+ end
95
+
96
+ it "fills the cache" do
97
+ get :with_partials
98
+ get :with_partials # Render a second time
99
+ Stache.template_cache.instance_variable_get(:@data).size.should eq(2) # But should only contain two elements (one for template, one for the partial)
100
+ end
101
+
102
+ it "uses the cache" do
103
+ get :with_partials
104
+
105
+ # Setup fake template
106
+ template = Stache::Mustache::CachedTemplate.new("foo")
107
+ template.compile
108
+
109
+ # Get first entry and manipulate it to be the fake template
110
+ key = Stache.template_cache.instance_variable_get(:@data).keys.last
111
+ Stache.template_cache.write(key, template, :raw => true)
112
+
113
+ # Now check response if it is the fake template
114
+ get :with_partials
115
+ assert_response 200
116
+ response.body.should == "foo"
117
+ end
118
+
119
+ after do
120
+ Stache.template_cache = ActiveSupport::Cache::NullStore.new
121
+ end
122
+ end
84
123
  end
@@ -5,3 +5,4 @@
5
5
  # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
7
  Dummy::Application.config.secret_token = '63d476c32606ceb52290e05ef316ea4d0fa558de3bc1ea83b4182a7c030a28b2f8b0111b7b3e3cf6bbdf43c03c7dd7f7fad555cfe11c56c2d23276e16873eaa0'
8
+ Dummy::Application.config.secret_key_base = '63d476c32606ceb52290e05ef316ea4d0fa558de3bc1ea83b4182a7c030a28b2f8b0111b7b3e3cf6bbdf43c03c7dd7f7fad555cfe11c56c2d23276e16873eaa0'
@@ -1,6 +1,6 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Dummy::Application.config.session_store :cookie_store, :key => '_dummy_session'
3
+ Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
4
4
 
5
5
  # Use the database for sessions instead of the cookie-based default,
6
6
  # which shouldn't be used to store highly confidential information
@@ -1,27 +1,27 @@
1
1
  Dummy::Application.routes.draw do
2
- get 'stache', :to => 'stache#index', :as => 'stache'
2
+ get 'stache', to: 'stache#index', as: 'stache'
3
3
 
4
- get 'stache/with_layout', :to => 'stache#with_layout'
4
+ get 'stache/with_layout', to: 'stache#with_layout'
5
5
 
6
- get 'stache/helper', :to => 'stache#helper'
6
+ get 'stache/helper', to: 'stache#helper'
7
7
 
8
- get 'stache/with_partials', :to => 'stache#with_partials'
8
+ get 'stache/with_partials', to: 'stache#with_partials'
9
9
 
10
- get 'stache/with_asset_helpers', :to => 'stache#with_asset_helpers'
10
+ get 'stache/with_asset_helpers', to: 'stache#with_asset_helpers'
11
11
 
12
- get 'stache/with_wrapper', :to => 'stache#with_wrapper'
12
+ get 'stache/with_wrapper', to: 'stache#with_wrapper'
13
13
 
14
- get 'stache/no_format_in_extension', :to => 'stache#no_format_in_extension'
14
+ get 'stache/no_format_in_extension', to: 'stache#no_format_in_extension'
15
15
 
16
- get 'stache/no_format_in_extension_with_wrapper', :to => 'stache#no_format_in_extension_with_wrapper'
16
+ get 'stache/no_format_in_extension_with_wrapper', to: 'stache#no_format_in_extension_with_wrapper'
17
17
 
18
- get 'handlebars', :to => 'handlebars#index', :as => 'handlebars'
18
+ get 'handlebars', to: 'handlebars#index', as: 'handlebars'
19
19
 
20
- get 'handlebars/with_partials', :to => 'handlebars#with_partials'
20
+ get 'handlebars/with_partials', to: 'handlebars#with_partials'
21
21
 
22
- get 'handlebars/with_helpers', :to => 'handlebars#with_helpers'
22
+ get 'handlebars/with_helpers', to: 'handlebars#with_helpers'
23
23
 
24
- get 'handlebars/with_missing_data', :to => 'handlebars#with_missing_data'
24
+ get 'handlebars/with_missing_data', to: 'handlebars#with_missing_data'
25
25
 
26
- get 'handlebars/with_wrapper', :to => 'handlebars#with_wrapper'
26
+ get 'handlebars/with_wrapper', to: 'handlebars#with_wrapper'
27
27
  end
@@ -29,5 +29,5 @@ require 'rspec/rails'
29
29
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
30
30
 
31
31
  RSpec.configure do |config|
32
-
32
+ config.infer_spec_type_from_file_location!
33
33
  end
@@ -39,28 +39,78 @@ describe Stache::AssetHelper do
39
39
  it "renders a script tag with the template contents" do
40
40
  helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
41
41
 
42
- helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
42
+ helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
43
+ end
44
+ it "renders a script tag with the template contents for the passed in symbol" do
45
+ helper.lookup_context.should_receive(:find).with(:oh_herro, [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
46
+
47
+ helper.template_include_tag(:oh_herro).should == "<script id=\"oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
48
+ end
49
+ it "renders a script tag with the template contents for the passed in symbols" do
50
+ helper.lookup_context.should_receive(:find).with(:oh_herro, [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
51
+ helper.lookup_context.should_receive(:find).with(:oh_hai, [], true, [], anything).and_return(TemplateStub.new("{{ awyes }}"))
52
+
53
+ helper.template_include_tag(:oh_herro, :oh_hai).should == "<script id=\"oh_herro\" type=\"text/html\">{{ awyeah }}</script>\n<script id=\"oh_hai\" type=\"text/html\">{{ awyes }}</script>"
43
54
  end
44
55
  it "renders a script tag with the template contents and given id" do
45
56
  helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
46
57
 
47
- helper.template_include_tag("widgets/oh_herro", :id => 'oh_herro_tmpl').should == "<script id=\"oh_herro_tmpl\" type=\"text/html\">{{ awyeah }}</script>"
58
+ helper.template_include_tag("widgets/oh_herro", id: 'oh_herro_tmpl').should == "<script id=\"oh_herro_tmpl\" type=\"text/html\">{{ awyeah }}</script>"
48
59
  end
49
60
  it "renders a script tag with the template contents and given options" do
50
61
  helper.lookup_context.should_receive(:find).with('widgets/oh_herro', [], true, [], anything).and_return(TemplateStub.new("{{ awyeah }}"))
51
62
 
52
- helper.template_include_tag("widgets/oh_herro", :data => {:engine => 'mustache'}).
53
- should == "<script data-engine=\"mustache\" id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
63
+ helper.template_include_tag("widgets/oh_herro", data: {engine: 'mustache'}).
64
+ should == "<script data-engine=\"mustache\" id=\"oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
54
65
  end
55
66
  it "will find first by partial and later by non-partial" do
56
67
  helper.lookup_context.should_receive(:find).with('widgets/oh_herro', anything, true, anything, anything).and_raise(StandardError.new("noooooo"))
57
68
  helper.lookup_context.should_receive(:find).with('widgets/oh_herro', anything, false, anything, anything).and_return(TemplateStub.new("{{ awyeah }}"))
58
69
 
59
- helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro_template\" type=\"text/html\">{{ awyeah }}</script>"
70
+ helper.template_include_tag("widgets/oh_herro").should == "<script id=\"oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
60
71
  end
61
72
  it "raises if it cannot find the template" do
62
73
  lambda { helper.template_include_tag("arrrgh") }.should raise_error(ActionView::MissingTemplate)
63
74
  end
75
+
76
+ context "when config.include_path_in_id is set to true" do
77
+ before do
78
+ Stache.include_path_in_id = true
79
+
80
+ helper.lookup_context.should_receive(:find)
81
+ .with(nested_path, [], true, [], anything)
82
+ .and_return(TemplateStub.new("{{ awyeah }}"))
83
+ end
84
+
85
+ after do
86
+ Stache.include_path_in_id = false
87
+ end
88
+
89
+ let(:nested_path) { 'nested/path/to/oh_herro' }
90
+
91
+ it "renders a script tag id with template path included (underscored)" do
92
+ helper.template_include_tag(nested_path)
93
+ .should == "<script id=\"nested_path_to_oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
94
+ end
95
+
96
+ context "when template_base_path is set" do
97
+ before do
98
+ Stache.template_base_path = 'widgets/'
99
+ end
100
+
101
+ it "renders a script tag id without a template path included" do
102
+ helper.template_include_tag(nested_path)
103
+ .should == "<script id=\"nested_path_to_oh_herro\" type=\"text/html\">{{ awyeah }}</script>"
104
+ end
105
+ end
106
+
107
+ context "when id option is set" do
108
+ it "renders a script tag with given id and without a full path" do
109
+ helper.template_include_tag(nested_path, id: 'oh_herro_tmpl')
110
+ .should == "<script id=\"oh_herro_tmpl\" type=\"text/html\">{{ awyeah }}</script>"
111
+ end
112
+ end
113
+ end
64
114
  end
65
115
 
66
116
 
@@ -28,6 +28,15 @@ describe "Stache::Config" do
28
28
  it "sets a default value for wrapper_module_name" do
29
29
  Stache.send(:wrapper_module_name).should be_nil
30
30
  end
31
+
32
+ it "sets up an attribute named include_path_in_id" do
33
+ attr = :include_path_in_id
34
+ should_set_up_attr_accessor_for(attr)
35
+ end
36
+
37
+ it "sets a default value for include_path_in_id" do
38
+ Stache.send(:include_path_in_id).should be false
39
+ end
31
40
  end
32
41
 
33
42
  describe ".configure" do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Stache::Handlebars::Handler do
4
4
  before do
5
- @template = ActionView::Template.new("{{body}}", "hello handlebars", Stache::Handlebars::Handler, { :virtual_path => "hello_world"})
5
+ @template = ActionView::Template.new("{{body}}", "hello handlebars", Stache::Handlebars::Handler, { virtual_path: "hello_world"})
6
6
  @handler = Stache::Handlebars::Handler.new
7
7
  end
8
8
 
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Stache::Mustache::CachedTemplate do
4
+ before do
5
+ @source = "{{hello}} mustache"
6
+ @template = Stache::Mustache::CachedTemplate.new(@source)
7
+ end
8
+
9
+ it "can be dumped when compiled" do
10
+ @template.compile
11
+ dump = Marshal.dump(@template)
12
+ dump.should =~ /ctx\[:hello\]/
13
+ dump.should =~ /mustache/
14
+ end
15
+
16
+ it "can be loaded from valid dump" do
17
+ @template.compile
18
+ obj = Marshal.load(Marshal.dump(@template))
19
+ obj.compile.should eq(@template.compile)
20
+ end
21
+
22
+ it "should ignore source if already compiled" do
23
+ res = @template.compile
24
+ res2 = @template.compile("{{foo}} bar")
25
+ res.should eq(res2)
26
+ end
27
+ end
@@ -3,10 +3,10 @@ require 'spec_helper'
3
3
  describe Stache::Mustache::Handler do
4
4
  # ERBHandler = ActionView::Template::Handlers::ERB.new
5
5
  # def new_template(body = "<%= hello %>", details = {})
6
- # ActionView::Template.new(body, "hello template", ERBHandler, {:virtual_path => "hello"}.merge!(details))
6
+ # ActionView::Template.new(body, "hello template", ERBHandler, {virtual_path: "hello"}.merge!(details))
7
7
  # end
8
8
  before do
9
- @template = ActionView::Template.new("{{body}}", "hello mustache", Stache::Mustache::Handler, { :virtual_path => "hello_world"})
9
+ @template = ActionView::Template.new("{{body}}", "hello mustache", Stache::Mustache::Handler, { virtual_path: "hello_world"})
10
10
  @handler = Stache::Mustache::Handler.new
11
11
  end
12
12
 
@@ -10,8 +10,8 @@ describe Stache::Util do
10
10
  Stache::Util.av_template_class("Foo").should == ActionView::TemplateFoo
11
11
  end
12
12
  end
13
-
13
+
14
14
  describe ".needs_compilable?" do
15
- pending "need to figure out some way to test this across different rails versions..."
15
+ skip "need to figure out some way to test this across different rails versions..."
16
16
  end
17
17
  end
@@ -8,8 +8,8 @@ Gem::Specification.new do |s|
8
8
  s.authors = ['Matt Wilson']
9
9
  s.email = 'mhw@hypomodern.com'
10
10
  s.homepage = 'http://github.com/agoragames/stache'
11
- s.summary = %Q{Configurable Mustache Handler and Helpers for Rails}
12
- s.description = %Q{A rails 3.x compatible template handler, configurable.}
11
+ s.summary = %Q{A Rails 3.x and Rails 4.x compatible Mustache/Handlebars template handler}
12
+ s.description = %Q{A Rails 3.x and Rails 4.x compatible Mustache/Handlebars template handler}
13
13
  s.license = 'MIT'
14
14
  s.extra_rdoc_files = [
15
15
  'LICENSE',
@@ -28,8 +28,8 @@ Gem::Specification.new do |s|
28
28
  s.add_development_dependency 'mustache'
29
29
  s.add_development_dependency 'handlebars', '~>0.4.0'
30
30
  s.add_development_dependency 'rails', '~>4.0.0'
31
- s.add_development_dependency 'rspec'
32
- s.add_development_dependency 'rspec-rails'
31
+ s.add_development_dependency 'rspec', '~>2.99.0'
32
+ s.add_development_dependency 'rspec-rails', '~>2.99.0'
33
33
  s.add_development_dependency 'bundler'
34
34
  s.add_development_dependency 'rake'
35
35
  end
metadata CHANGED
@@ -1,114 +1,114 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stache
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-14 00:00:00.000000000 Z
11
+ date: 2014-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mustache
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: handlebars
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.4.0
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.4.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rails
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 4.0.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 4.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 2.99.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 2.99.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-rails
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '0'
75
+ version: 2.99.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '0'
82
+ version: 2.99.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rake
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
- description: A rails 3.x compatible template handler, configurable.
111
+ description: A Rails 3.x and Rails 4.x compatible Mustache/Handlebars template handler
112
112
  email: mhw@hypomodern.com
113
113
  executables: []
114
114
  extensions: []
@@ -116,12 +116,12 @@ extra_rdoc_files:
116
116
  - LICENSE
117
117
  - README.md
118
118
  files:
119
- - .document
120
- - .gitignore
121
- - .rspec
122
- - .ruby-gemset
123
- - .ruby-version
124
- - .travis.yml
119
+ - ".document"
120
+ - ".gitignore"
121
+ - ".rspec"
122
+ - ".ruby-gemset"
123
+ - ".ruby-version"
124
+ - ".travis.yml"
125
125
  - CHANGELOG.md
126
126
  - Gemfile
127
127
  - LICENSE
@@ -134,6 +134,8 @@ files:
134
134
  - lib/stache/handlebars/handler.rb
135
135
  - lib/stache/handlebars/view.rb
136
136
  - lib/stache/mustache.rb
137
+ - lib/stache/mustache/cached_template.rb
138
+ - lib/stache/mustache/faster_context.rb
137
139
  - lib/stache/mustache/handler.rb
138
140
  - lib/stache/mustache/layout.rb
139
141
  - lib/stache/mustache/view.rb
@@ -214,6 +216,7 @@ files:
214
216
  - spec/stache/handlebars/handlebars_spec.rb
215
217
  - spec/stache/handlebars/profile_autoload.rb
216
218
  - spec/stache/handlebars/view_spec.rb
219
+ - spec/stache/mustache/cached_template_spec.rb
217
220
  - spec/stache/mustache/handler_spec.rb
218
221
  - spec/stache/mustache/profile_autoload.rb
219
222
  - spec/stache/mustache/view_spec.rb
@@ -232,20 +235,20 @@ require_paths:
232
235
  - lib
233
236
  required_ruby_version: !ruby/object:Gem::Requirement
234
237
  requirements:
235
- - - '>='
238
+ - - ">="
236
239
  - !ruby/object:Gem::Version
237
240
  version: '0'
238
241
  required_rubygems_version: !ruby/object:Gem::Requirement
239
242
  requirements:
240
- - - '>='
243
+ - - ">="
241
244
  - !ruby/object:Gem::Version
242
245
  version: 1.3.7
243
246
  requirements: []
244
247
  rubyforge_project:
245
- rubygems_version: 2.2.0
248
+ rubygems_version: 2.2.2
246
249
  signing_key:
247
250
  specification_version: 3
248
- summary: Configurable Mustache Handler and Helpers for Rails
251
+ summary: A Rails 3.x and Rails 4.x compatible Mustache/Handlebars template handler
249
252
  test_files:
250
253
  - spec/controllers/handlebars_controller_spec.rb
251
254
  - spec/controllers/stache_controller_spec.rb
@@ -319,6 +322,7 @@ test_files:
319
322
  - spec/stache/handlebars/handlebars_spec.rb
320
323
  - spec/stache/handlebars/profile_autoload.rb
321
324
  - spec/stache/handlebars/view_spec.rb
325
+ - spec/stache/mustache/cached_template_spec.rb
322
326
  - spec/stache/mustache/handler_spec.rb
323
327
  - spec/stache/mustache/profile_autoload.rb
324
328
  - spec/stache/mustache/view_spec.rb