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.
- data/.document +11 -0
- data/.gitignore +40 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +65 -0
- data/Rakefile +42 -0
- data/lib/stache.rb +13 -0
- data/lib/stache/asset_helper.rb +16 -0
- data/lib/stache/config.rb +31 -0
- data/lib/stache/handler.rb +62 -0
- data/lib/stache/util.rb +31 -0
- data/lib/stache/version.rb +3 -0
- data/lib/stache/view.rb +35 -0
- data/spec/controllers/stache_controller_spec.rb +23 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/controllers/stache_controller.rb +13 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/stache/_eaten_by_a.html.mustache +1 -0
- data/spec/dummy/app/views/stache/index.html.mustache +1 -0
- data/spec/dummy/app/views/stache/with_partials.html.mustache +3 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +44 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/stache.rb +3 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +61 -0
- data/spec/dummy/log/development.log +3 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/log/test.log +213 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +191 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/stache/asset_helper_spec.rb +21 -0
- data/spec/stache/config_spec.rb +36 -0
- data/spec/stache/handler_spec.rb +29 -0
- data/spec/stache/util_spec.rb +17 -0
- data/spec/stache/view_spec.rb +9 -0
- data/spec/stache_spec.rb +5 -0
- data/stache.gemspec +38 -0
- 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
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.2-p180@stache_gem
|
data/Gemfile
ADDED
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
|
data/lib/stache/util.rb
ADDED
@@ -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
|
data/lib/stache/view.rb
ADDED
@@ -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
|
data/spec/dummy/Rakefile
ADDED
@@ -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
|