Permalink
Browse files

Added autoloading

  • Loading branch information...
1 parent ba259db commit 40313b959774e1fe9e93777e1e1abee472616a94 @defunkt defunkt committed Oct 27, 2009
Showing with 107 additions and 0 deletions.
  1. +4 −0 HISTORY.md
  2. +9 −0 README.md
  3. +1 −0 examples/namespaced.mustache
  4. +17 −0 examples/namespaced.rb
  5. +53 −0 lib/mustache.rb
  6. +23 −0 test/autoloading_test.rb
View
@@ -5,6 +5,10 @@
* Throw Mustache::ContextMiss when raise_on_context_miss is true and
we encounter a miss.
* The default template extension is now "mustache" (instead of "html").
+* Added the `view_namespace` and `view_path` settings to `Mustache`
+* Added `Mustache.view_class` method which autoloads a class using the
+ new `view_namespace` and `view_path` settings. Should be used by
+ plugin developers.
## 0.3.3 (2009-??-??)
View
@@ -285,6 +285,15 @@ Or set a different template for a single instance:
Whatever works.
+Views
+-----
+
+Mustache supports a bit of magic when it comes to views. If you're
+authoring a plugin or extension for a web framework (Sinatra, Rails,
+etc), check out the `view_namespace` and `view_path` settings on the
+`Mustache` class. They will surely provide needed assistance.
+
+
Helpers
-------
@@ -0,0 +1 @@
+<h1>{{title}}</h1>
@@ -0,0 +1,17 @@
+$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
+require 'mustache'
+
+module TestViews
+ class Namespaced < Mustache
+ self.path = File.dirname(__FILE__)
+
+ def title
+ "Dragon < Tiger"
+ end
+ end
+end
+
+
+if $0 == __FILE__
+ puts TestViews::Namespaced.to_html
+end
View
@@ -56,6 +56,19 @@
# view.template = "Hi, {{person}}!"
# view[:person] = 'Mom'
# view.render # => Hi, mom!
+#
+# * view_namespace
+#
+# To make life easy on those developing Mustache plugins for web frameworks or
+# other libraries, Mustache will attempt to load view classes (i.e. Mustache
+# subclasses) using the `view_class` class method. The `view_namespace` tells
+# Mustache under which constant view classes live. By default it is `Object`.
+#
+# * view_path
+#
+# Similar to `template_path`, the `view_path` option tells Mustache where to look
+# for files containing view classes when using the `view_class` method.
+#
class Mustache
# Helper method for quickly instantiating and rendering a view.
def self.render(*args)
@@ -126,6 +139,46 @@ def self.template=(template)
@template = templateify(template)
end
+ # The constant under which Mustache will look for views. By default it's
+ # `Object`, but it might be nice to set it to something like `Hurl::Views` if
+ # your app's main namespace is `Hurl`.
+ def self.view_namespace
+ @view_namespace || Object
+ end
+
+ def self.view_namespace=(namespace)
+ @view_namespace = namespace
+ end
+
+ # Mustache searches the view path for .rb files to require when asked to find a
+ # view class. Defaults to "."
+ def self.view_path
+ @view_path ||= '.'
+ end
+
+ def self.view_path=(path)
+ @view_path = path
+ end
+
+ # When given a symbol or string representing a class, will try to produce an
+ # appropriate view class.
+ # e.g.
+ # Mustache.view_namespace = Hurl::Views
+ # Mustache.view_class(:Partial) # => Hurl::Views::Partial
+ def self.view_class(name)
+ name = name.to_s
+ file_name = underscore(name)
+
+ if view_namespace.const_defined?(name)
+ view_namespace.const_get(name)
+ elsif File.exists?(file = "#{view_path}/#{file_name}.rb")
+ require "#{file}".chomp('.rb')
+ view_namespace.const_get(name)
+ else
+ Mustache
+ end
+ end
+
# Should an exception be raised when we cannot find a corresponding method
# or key in the current context? By default this is false to emulate ctemplate's
# behavior, but it may be useful to enable when debugging or developing.
@@ -0,0 +1,23 @@
+require 'test/unit'
+
+module TestViews; end
+
+class AutoloadingTest < Test::Unit::TestCase
+ def setup
+ Mustache.view_path = File.dirname(__FILE__) + '/../examples'
+ end
+
+ def test_autoload
+ klass = Mustache.view_class(:Comments)
+ assert_equal Comments, klass
+ end
+
+ def test_namespaced_autoload
+ Mustache.view_namespace = TestViews
+ klass = Mustache.view_class('Namespaced')
+ assert_equal TestViews::Namespaced, klass
+ assert_equal <<-end_render.strip, klass.render
+<h1>Dragon &lt; Tiger</h1>
+end_render
+ end
+end

0 comments on commit 40313b9

Please sign in to comment.