stache 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. data/.document +11 -0
  2. data/.gitignore +40 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +20 -0
  7. data/README.md +65 -0
  8. data/Rakefile +42 -0
  9. data/lib/stache.rb +13 -0
  10. data/lib/stache/asset_helper.rb +16 -0
  11. data/lib/stache/config.rb +31 -0
  12. data/lib/stache/handler.rb +62 -0
  13. data/lib/stache/util.rb +31 -0
  14. data/lib/stache/version.rb +3 -0
  15. data/lib/stache/view.rb +35 -0
  16. data/spec/controllers/stache_controller_spec.rb +23 -0
  17. data/spec/dummy/Rakefile +7 -0
  18. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  19. data/spec/dummy/app/controllers/stache_controller.rb +13 -0
  20. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  21. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  22. data/spec/dummy/app/views/stache/_eaten_by_a.html.mustache +1 -0
  23. data/spec/dummy/app/views/stache/index.html.mustache +1 -0
  24. data/spec/dummy/app/views/stache/with_partials.html.mustache +3 -0
  25. data/spec/dummy/config.ru +4 -0
  26. data/spec/dummy/config/application.rb +44 -0
  27. data/spec/dummy/config/boot.rb +10 -0
  28. data/spec/dummy/config/database.yml +25 -0
  29. data/spec/dummy/config/environment.rb +5 -0
  30. data/spec/dummy/config/environments/development.rb +26 -0
  31. data/spec/dummy/config/environments/production.rb +49 -0
  32. data/spec/dummy/config/environments/test.rb +35 -0
  33. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  34. data/spec/dummy/config/initializers/inflections.rb +10 -0
  35. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  36. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  37. data/spec/dummy/config/initializers/session_store.rb +8 -0
  38. data/spec/dummy/config/initializers/stache.rb +3 -0
  39. data/spec/dummy/config/locales/en.yml +5 -0
  40. data/spec/dummy/config/routes.rb +61 -0
  41. data/spec/dummy/log/development.log +3 -0
  42. data/spec/dummy/log/production.log +0 -0
  43. data/spec/dummy/log/server.log +0 -0
  44. data/spec/dummy/log/test.log +213 -0
  45. data/spec/dummy/public/404.html +26 -0
  46. data/spec/dummy/public/422.html +26 -0
  47. data/spec/dummy/public/500.html +26 -0
  48. data/spec/dummy/public/favicon.ico +0 -0
  49. data/spec/dummy/public/javascripts/application.js +2 -0
  50. data/spec/dummy/public/javascripts/controls.js +965 -0
  51. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  52. data/spec/dummy/public/javascripts/effects.js +1123 -0
  53. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  54. data/spec/dummy/public/javascripts/rails.js +191 -0
  55. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  56. data/spec/dummy/script/rails +6 -0
  57. data/spec/spec_helper.rb +33 -0
  58. data/spec/stache/asset_helper_spec.rb +21 -0
  59. data/spec/stache/config_spec.rb +36 -0
  60. data/spec/stache/handler_spec.rb +29 -0
  61. data/spec/stache/util_spec.rb +17 -0
  62. data/spec/stache/view_spec.rb +9 -0
  63. data/spec/stache_spec.rb +5 -0
  64. data/stache.gemspec +38 -0
  65. metadata +252 -0
data/.document ADDED
@@ -0,0 +1,11 @@
1
+ # .document is used by rdoc and yard to know how to generate documentation
2
+ # for example, it can be used to control how rdoc gets built when you do `gem install foo`
3
+
4
+ README.rdoc
5
+ lib/**/*.rb
6
+ bin/*
7
+
8
+ # Files below this - are treated as 'extra files', and aren't parsed for ruby code
9
+ -
10
+ features/**/*.feature
11
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,40 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ # rcov generated
6
+ coverage
7
+
8
+ # rdoc generated
9
+ rdoc
10
+
11
+ # yard generated
12
+ doc
13
+ .yardoc
14
+
15
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
16
+ #
17
+ # * Create a file at ~/.gitignore
18
+ # * Include files you want ignored
19
+ # * Run: git config --global core.excludesfile ~/.gitignore
20
+ #
21
+ # After doing this, these files will be ignored in all your git projects,
22
+ # saving you from having to 'pollute' every project you touch with them
23
+ #
24
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
25
+ #
26
+ # For MacOS:
27
+ #
28
+ #.DS_Store
29
+ #
30
+ # For TextMate
31
+ #*.tmproj
32
+ #tmtags
33
+ #
34
+ # For emacs:
35
+ #*~
36
+ #\#*
37
+ #.\#*
38
+ #
39
+ # For vim:
40
+ #*.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format nested
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.2-p180@stache_gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in stache.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Matt Wilson / Agora Games, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # stache
2
+
3
+ A Rails 3.x (yes, even Rails *3.1*) compatible Mustache Template Handler, with support for partials and a couple extra niceties to make sharing the raw templates with client-side javascript a little easier.
4
+
5
+ ## Usage
6
+
7
+ gem "stache"
8
+
9
+ Install the gem. If you want to override any of the configuration options (see `stache/config`), toss an initializer in `config/initializers` and:
10
+
11
+ ```ruby
12
+ Stache.config do |c|
13
+ c.template_base_path = "..." # this is probably the one you'll want to change
14
+ # it defaults to app/templates
15
+ end
16
+
17
+ # or if the block style ain't yer thang, just:
18
+ Stache.template_base_path = File.join(Rails.root, "app", "şablon")
19
+ ```
20
+
21
+ 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. On the todo list is the ability to customize this helper a little more :).
22
+
23
+ ## A View Class of your Very Own
24
+
25
+ To facilitate easy integration, 'Stache comes packaged with a fully-functioning subclass of Mustache, called `Stache::View`. It will try to find a more appropriate view class to provide to the template renderer based on the template name, but if one cannot be found it will automatically give ya a `Stache::View` so you can have *something*.
26
+
27
+ Needless to say, it's probably better if your custom View objects are subclasses of `Stache::View`. That way we can all be sure that the handler will render correctly.
28
+
29
+ An example by way of explanation:
30
+
31
+ With a template `app/templates/profiles/index`, Stache will look for a view named `Profiles::Index`, and, if not found, will just use the base `Stache::View`.
32
+
33
+ ## Of Note
34
+
35
+ This is early code, ripped out from an upcoming project. It probably has some rough edges.
36
+
37
+ TODO:
38
+
39
+ * more and better integration tests
40
+ * automated tests across different rails versions
41
+ * other helpers, etc, as desired
42
+
43
+ ## Thanks to
44
+
45
+ This project builds on work done by the following people and projects:
46
+
47
+ * olivernn's [Poirot](https://github.com/olivernn/poirot)
48
+ * goodmike's [mustache_rails3](https://github.com/goodmike/mustache_rails3)
49
+ * nex3's [HAML](https://github.com/nex3/haml)
50
+
51
+ So: thanks a ton to those guys.
52
+
53
+ ## Note on Patches/Pull Requests
54
+
55
+ * Fork the project.
56
+ * Make your feature addition or bug fix.
57
+ * Add tests for it. This is important so I don't break it in a
58
+ future version unintentionally.
59
+ * Commit, do not mess with rakefile, version, or history.
60
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
61
+ * Send me a pull request. Bonus points for topic branches.
62
+
63
+ ## Copyright
64
+
65
+ Copyright (c) 2011 Matt Wilson / Agora Games. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+
3
+ begin
4
+ require 'bundler'
5
+ rescue LoadError
6
+ $stderr.puts "You must install bundler - run `gem install bundler`"
7
+ end
8
+
9
+ begin
10
+ Bundler.setup
11
+ rescue Bundler::BundlerError => e
12
+ $stderr.puts e.message
13
+ $stderr.puts "Run `bundle install` to install missing gems"
14
+ exit e.status_code
15
+ end
16
+ require 'rake'
17
+
18
+ require 'bueller'
19
+ Bueller::Tasks.new
20
+
21
+ require 'rspec/core/rake_task'
22
+ RSpec::Core::RakeTask.new(:examples) do |examples|
23
+ examples.rspec_opts = '-Ispec'
24
+ end
25
+
26
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
27
+ spec.rspec_opts = '-Ispec'
28
+ spec.rcov = true
29
+ end
30
+
31
+ task :default => :examples
32
+
33
+ require 'rake/rdoctask'
34
+ Rake::RDocTask.new do |rdoc|
35
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
36
+
37
+ rdoc.main = 'README.rdoc'
38
+ rdoc.rdoc_dir = 'rdoc'
39
+ rdoc.title = "stache #{version}"
40
+ rdoc.rdoc_files.include('README*')
41
+ rdoc.rdoc_files.include('lib/**/*.rb')
42
+ end
data/lib/stache.rb ADDED
@@ -0,0 +1,13 @@
1
+ require "stache/version"
2
+ require "stache/config"
3
+ require "stache/util"
4
+ require "stache/handler"
5
+ require "stache/asset_helper"
6
+
7
+ module Stache
8
+ extend Config
9
+
10
+ end
11
+
12
+ ActionView::Template.register_template_handler(:mustache, Stache::Handler)
13
+ ActionView::Base.send :include, Stache::AssetHelper
@@ -0,0 +1,16 @@
1
+ module Stache
2
+ module AssetHelper
3
+ # template_include_tag("widgets/basic_text_api_data")
4
+ # template_include_tag("shared/test_thing")
5
+ def template_include_tag(*sources)
6
+ sources.collect do |source|
7
+ exploded = source.split("/")
8
+ file = exploded.pop
9
+ file = file.split(".").first
10
+ template_path = ::Rails.root.join('app/views', *exploded, "_#{file}.html.mustache")
11
+ template = ::File.open(template_path, "rb")
12
+ content_tag(:script, template.read.html_safe, :type => "text/html", :id => "#{file.dasherize.underscore}_template")
13
+ end.join("\n").html_safe
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ module Stache
2
+ # Change these defaults in, say, an initializer.
3
+ #
4
+ # Stache.template_base_path = Rails.root.join('app', 'templates')
5
+ #
6
+ # Or with the block syntax:
7
+ #
8
+ # Stache.configure do |config|
9
+ # config.template_base_path = Rails.root.join('app', 'views', 'shared')
10
+ # end
11
+ module Config
12
+ attr_accessor :template_base_path, :template_extension, :shared_path
13
+
14
+ def configure
15
+ yield self
16
+ end
17
+
18
+
19
+ def template_base_path
20
+ @template_base_path ||= ::Rails.root.join('app', 'templates')
21
+ end
22
+
23
+ def template_extension
24
+ @template_extension ||= 'html.mustache'
25
+ end
26
+
27
+ def shared_path
28
+ @shared_path ||= ::Rails.root.join('app', 'templates', 'shared')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,62 @@
1
+ require 'stache/view'
2
+
3
+ module Stache
4
+ # From HAML, thanks a bunch, guys!
5
+ # In Rails 3.1+, template handlers don't inherit from anything. In <= 3.0, they do.
6
+ # To avoid messy logic figuring this out, we just inherit from whatever the ERB handler does.
7
+ class Handler < Stache::Util.av_template_class(:Handlers)::ERB.superclass
8
+ if Stache::Util.needs_compilable?
9
+ include Stache::Util.av_template_class(:Handlers)::Compilable
10
+ end
11
+
12
+ # Thanks to Mustache::Rails3 for getting us most of the way home here
13
+ def compile(template)
14
+ #
15
+ # get a custom Mustache, or the default Stache::View
16
+ mustache_class = mustache_class_from_template(template)
17
+
18
+ # Return a string that will be eval'd in the context of the ActionView, ugly, but it works.
19
+ <<-MUSTACHE
20
+ mustache = ::#{mustache_class}.new
21
+ mustache.view = self
22
+ mustache.template = '#{template.source.gsub(/'/, "\\\\'")}'
23
+ mustache[:yield] = content_for(:layout)
24
+ mustache.context.update(local_assigns)
25
+ variables = controller.instance_variable_names
26
+ variables -= %w[@template]
27
+
28
+ if controller.respond_to?(:protected_instance_variables)
29
+ variables -= controller.protected_instance_variables
30
+ end
31
+
32
+ variables.each do |name|
33
+ mustache.instance_variable_set(name, controller.instance_variable_get(name))
34
+ end
35
+
36
+ # Declaring an +attr_reader+ for each instance variable in the
37
+ # Stache::View subclass makes them available to your templates.
38
+ mustache.class.class_eval do
39
+ attr_reader *variables.map { |name| name.sub(/^@/, '').to_sym }
40
+ end
41
+
42
+ mustache.render.html_safe
43
+ MUSTACHE
44
+ end
45
+
46
+ # In Rails 3.1+, #call takes the place of #compile
47
+ def self.call(template)
48
+ new.compile(template)
49
+ end
50
+
51
+ # suss out a constant name for the given template
52
+ def mustache_class_from_template(template)
53
+ const_name = ActiveSupport::Inflector.camelize(template.virtual_path.to_s)
54
+ begin
55
+ const_name.constantize
56
+ rescue NameError
57
+ Stache::View
58
+ end
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,31 @@
1
+ module Stache
2
+ # Basically a dumping ground for code that didn't fit anywhere else
3
+ module Util
4
+ # From HAML
5
+ # Returns an ::ActionView::Template* class.
6
+ # In pre-3.0 versions of Rails, most of these classes
7
+ # were of the form `::ActionView::TemplateFoo`,
8
+ # while afterwards they were of the form `::ActionView::Template::Foo`.
9
+ #
10
+ # @param name [#to_s] The name of the class to get.
11
+ # For example, `:Error` will return `::ActionView::TemplateError`
12
+ # or `::ActionView::Template::Error`.
13
+ def self.av_template_class(name)
14
+ if ::ActionView::Template.const_defined?(name)
15
+ ::ActionView::Template.const_get(name)
16
+ else
17
+ ::ActionView.const_get("Template#{name}")
18
+ end
19
+ end
20
+
21
+ def self.needs_compilable?
22
+ (
23
+ (defined?(::ActionView::TemplateHandlers) && defined?(::ActionView::TemplateHandlers::Compilable)) ||
24
+ (defined?(::ActionView::Template) && defined?(::ActionView::Template::Handlers) && defined?(::ActionView::Template::Handlers::Compilable))
25
+ ) &&
26
+ # In Rails 3.1+, we don't need to include Compilable.
27
+ Stache::Util.av_template_class(:Handlers)::ERB.include?( Stache::Util.av_template_class(:Handlers)::Compilable )
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module Stache
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,35 @@
1
+ module Stache
2
+ #
3
+ # A Convienent Base Class for the views. Subclass this for autoloading magic with your templates.
4
+ #
5
+ # e.g. if the handler is loading a template from templates/
6
+ class View < Mustache
7
+ attr_accessor :view, :template
8
+
9
+ def method_missing(method, *args, &block)
10
+ view.send(method, *args, &block)
11
+ end
12
+
13
+ def respond_to?(method, include_private=false)
14
+ super(method, include_private) || view.respond_to?(method, include_private)
15
+ end
16
+
17
+ # Redefine where Stache::View templates locate their partials:
18
+ #
19
+ # (1) in the same directory as the current template file.
20
+ # (2) in the shared templates path (can be configured via Config.shared_path=(value))
21
+ #
22
+ def partial(name)
23
+ partial_name = "_#{name}.#{Stache.template_extension}"
24
+ template_dir = Pathname.new(self.class.template_file).dirname
25
+ partial_path = File.expand_path(File.join(Stache.template_base_path, template_dir, partial_name))
26
+ unless File.file?(partial_path)
27
+ partial_path = "#{Stache.shared_path}/#{partial_name}"
28
+ end
29
+
30
+ # ::Rails.logger.info "LOADING PARTIAL: #{partial_path}"
31
+ File.read(partial_path)
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe StacheController do
4
+ render_views
5
+
6
+ it "can get to index and render a Mustache" do
7
+ get :index
8
+ assert_response 200
9
+
10
+ response.should render_template 'index' # view
11
+ response.body.should =~ /Hello, Matt!/
12
+ end
13
+
14
+ it "correctly renders partials" do
15
+ get :with_partials
16
+ assert_response 200
17
+
18
+ response.body.should =~ /Grue/
19
+ # puts response.body
20
+ end
21
+
22
+
23
+ end
@@ -0,0 +1,7 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+ require 'rake'
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,13 @@
1
+ class StacheController < ApplicationController
2
+
3
+ def index
4
+ @user = params[:user] || "Matt"
5
+ # index.html.mustache
6
+ end
7
+
8
+ def with_partials
9
+ @user = params[:user] || "Matt"
10
+ @thing = "Grue"
11
+ end
12
+
13
+ end