mustache_rails3 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2010 Michael Harrison mh@michaelharrison.ws
4
+ Paul Barry
5
+ Martin Gamsjaeger
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in
15
+ all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ THE SOFTWARE.
@@ -0,0 +1,6 @@
1
+ # Be sure to install mustache gem and include mustache gem in project Gemfile.
2
+
3
+ # Template Handler
4
+ require 'mustache_rails'
5
+ # Generator
6
+ Rails.application.config.generators.template_engine :mustache
@@ -0,0 +1,9 @@
1
+ class Mustache
2
+ module Generators
3
+ module TemplatePath
4
+ def source_root
5
+ @_mustache_source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'mustache', generator_name, 'templates'))
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,39 @@
1
+ require 'generators/mustache'
2
+ require 'rails/generators/named_base'
3
+
4
+ class Mustache
5
+ module Generators
6
+ class ControllerGenerator < ::Rails::Generators::NamedBase
7
+ extend TemplatePath
8
+
9
+ argument :actions, :type => :array, :default => [], :banner => "action action"
10
+
11
+ def create_view_files
12
+ model_path = File.join(class_path, file_name)
13
+
14
+ base_mustache_view_path = File.join("app/views", model_path)
15
+ empty_directory base_mustache_view_path
16
+
17
+ base_mustache_template_path = File.join("app/templates", model_path)
18
+ empty_directory base_mustache_template_path
19
+
20
+ actions.each do |action|
21
+ @action = action
22
+ mustache_view_path = File.join(base_mustache_view_path,
23
+ "#{action}.rb")
24
+ mustache_template_path = File.join(base_mustache_template_path,
25
+ "#{action}.html.mustache")
26
+
27
+ template "view.rb.erb", mustache_view_path
28
+ template "view.html.mustache.erb", mustache_template_path
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ def handler
35
+ :haml
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ class <%= singular_name.camelize %>::<%= @action.camelize %> < Mustache::Rails
2
+
3
+ end
@@ -0,0 +1,14 @@
1
+ require 'generators/mustache'
2
+
3
+ class Mustache
4
+ module Generators
5
+ class InstallGenerator < ::Rails::Generators::Base
6
+ extend TemplatePath
7
+
8
+ def copy_initializer_files
9
+ copy_file "config/initializers/mustache.rb", "config/initializers/mustache.rb"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ # Be sure to install mustache gem and include mustache gem in project Gemfile.
2
+
3
+ # Template Handler
4
+ require 'mustache_rails'
5
+ # Generator
6
+ Rails.application.config.generators.template_engine :mustache
@@ -0,0 +1,38 @@
1
+ require 'generators/mustache'
2
+ require 'rails/generators/erb/scaffold/scaffold_generator'
3
+
4
+ class Mustache
5
+ module Generators
6
+ class ScaffoldGenerator < Erb::Generators::ScaffoldGenerator
7
+ extend TemplatePath
8
+
9
+ # TODO Layout files? snusnu claims his template engine supports layouts:
10
+ # http://github.com/defunkt/mustache/issues/#issue/3/comment/263445
11
+
12
+ def copy_view_files
13
+ views = available_views
14
+ views.delete("index") if options[:singleton]
15
+
16
+ views.each do |view|
17
+ template "#{view}.rb.erb",
18
+ File.join("app/views", controller_file_path, "#{view}.rb")
19
+ template "#{view}.html.mustache.erb",
20
+ File.join("app/templates",
21
+ controller_file_path,
22
+ "#{view}.html.mustache")
23
+ end
24
+ template "_form.html.mustache.erb",
25
+ File.join("app/templates",
26
+ controller_file_path,
27
+ "_form.html.mustache")
28
+ end
29
+
30
+ private
31
+
32
+ def available_views
33
+ %w(index edit show new)
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,4 @@
1
+ <p><% for attribute in attributes -%>
2
+ {{{<%= attribute.name %>_label}}}: {{{<%= attribute.name %>_text_field}}}<br />
3
+ <% end -%></p>
4
+ {{{form_submit}}}
@@ -0,0 +1,10 @@
1
+ <p>Editing <%= singular_name.capitalize %></p>
2
+
3
+ {{{errors_display_div}}}
4
+
5
+ <hr />
6
+ {{{<%= singular_name %>_form_tag}}}
7
+ {{> form }}
8
+ </form>
9
+ <hr />
10
+ <a href="{{show_path}}">Back to record</a>
@@ -0,0 +1,53 @@
1
+ class <%= plural_name.camelize %>::Edit < Mustache::Rails
2
+
3
+ <%# TODO: extract errors_display settings to to module methods -%>
4
+ def errors_display_div
5
+ return "" unless <%= singular_name %>.errors.any?
6
+ content_tag("div", :id=>"errorExplanation", :class=>"errorExplanation") do
7
+ content_tag("h2", error_header) + content_tag("ul") do
8
+ <%= singular_name %>.errors.full_messages.inject("") do |memo,msg|
9
+ memo += content_tag("li", msg)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ def <%= singular_name %>_form_tag
16
+ form_tag(update_path, :class => "<%= singular_name %>_form", :method => :put, :id => "edit_<%= singular_name %>_#{<%= singular_name %>.id}_form")
17
+ end
18
+
19
+ <% for attribute in attributes -%>
20
+ def <%= attribute.name %>_label
21
+ label :<%= singular_name %>, :<%= attribute.name %>
22
+ end
23
+ <%# TODO: Different fields for different attribute types -%>
24
+
25
+ def <%= attribute.name %>_text_field
26
+ text_field(:<%= singular_name %>, :<%= attribute.name %>, :id => "<%= attribute.name %>_text_field")
27
+ end
28
+
29
+ <% end -%>
30
+
31
+ def form_submit
32
+ submit_tag "Update"
33
+ end
34
+
35
+ def show_path
36
+ <%= singular_name %>_path(<%= singular_name %>)
37
+ end
38
+
39
+ def index_path
40
+ <%= plural_name %>_path
41
+ end
42
+
43
+ private
44
+
45
+ def update_path
46
+ <%= singular_name %>_path(<%= singular_name %>)
47
+ end
48
+
49
+ def error_header
50
+ "u r dong it rong"
51
+ end
52
+
53
+ end
@@ -0,0 +1,13 @@
1
+ <p>Listing <%= plural_name.capitalize %></p>
2
+
3
+ {{#listing}}
4
+
5
+ <p>
6
+ <% attributes.collect do |attribute| -%>
7
+ <b><%= attribute.human_name %></b>: {{<%= attribute.name %>}}
8
+ <% end.join(" | ") -%>
9
+ | <a href="{{show_path}}">Details</a></p>
10
+
11
+ {{/listing}}
12
+
13
+ <p><a href="{{new_path}}">New</a></p>
@@ -0,0 +1,18 @@
1
+ class <%= plural_name.camelize %>::Index < Mustache::Rails
2
+
3
+ def new_path
4
+ new_<%= singular_name %>_path()
5
+ end
6
+
7
+ def listing
8
+ <%= plural_name %>.collect do |record|
9
+ {
10
+ <% for attribute in attributes -%>
11
+ :<%= attribute.name %> => record.<%= attribute.name %>,
12
+ <% end -%>
13
+ :show_path => <%= singular_name %>_path(record)
14
+ }
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,11 @@
1
+ <p>New <%= singular_name.capitalize %></p>
2
+
3
+ {{{errors_display_div}}}
4
+
5
+ <hr />
6
+ {{{<%= singular_name %>_form_tag}}}
7
+ {{> form }}
8
+ </form>
9
+ <hr />
10
+
11
+ <a href="{{index_path}}">Back to listing</a>
@@ -0,0 +1,50 @@
1
+ class <%= plural_name.camelize %>::New < Mustache::Rails
2
+
3
+ <%# TODO: extract errors_display settings to to module methods -%>
4
+ def errors_display_div
5
+ return "" unless <%= singular_name %>.errors.any?
6
+ content_tag("div", :id=>"errorExplanation", :class=>"errorExplanation") do
7
+ content_tag("h2", error_header) + content_tag("ul") do
8
+ <%= singular_name %>.errors.full_messages.inject("") do |memo,msg|
9
+ memo += content_tag("li", msg)
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ def <%= singular_name %>_form_tag
16
+ form_tag(create_path, :class => "<%= singular_name %>_form", :id => "edit_<%= singular_name %>_#{<%= singular_name %>.id}_form")
17
+ end
18
+
19
+ <% for attribute in attributes -%>
20
+ def <%= attribute.name %>_label
21
+ label :<%= singular_name %>, :<%= attribute.name %>
22
+ end
23
+ <%# TODO: Different fields for different attribute types -%>
24
+
25
+ def <%= attribute.name %>_text_field
26
+ text_field(:<%= singular_name %>, :<%= attribute.name %>, :id => "<%= attribute.name %>_text_field")
27
+ end
28
+
29
+ <% end -%>
30
+
31
+ def form_submit
32
+ submit_tag "Create"
33
+ end
34
+
35
+
36
+ def index_path
37
+ <%= plural_name %>_path
38
+ end
39
+
40
+ private
41
+
42
+ def create_path
43
+ <%= plural_name %>_path
44
+ end
45
+
46
+ def error_header
47
+ "u r dong it rong"
48
+ end
49
+
50
+ end
@@ -0,0 +1,7 @@
1
+ <p>Displaying <%= singular_name.capitalize %></p>
2
+
3
+ <% for attribute in attributes -%>
4
+ <p><b><%= attribute.human_name %></b>: {{<%= attribute.name %>}}</p>
5
+ <% end -%>
6
+
7
+ <a href="{{edit_path}}">Edit</a> | <a href="{{index_path}}">Back</a>
@@ -0,0 +1,18 @@
1
+ class <%= plural_name.camelize %>::Show < Mustache::Rails
2
+
3
+ <% for attribute in attributes -%>
4
+ def <%= attribute.name %>
5
+ <%= singular_name %>.<%= attribute.name %>
6
+ end
7
+
8
+ <% end -%>
9
+
10
+ def edit_path
11
+ edit_<%= singular_name %>_path(@<%= singular_name %>)
12
+ end
13
+
14
+ def index_path
15
+ <%= plural_name %>_path
16
+ end
17
+
18
+ end
@@ -0,0 +1,123 @@
1
+ require 'action_view'
2
+ require 'active_support'
3
+ require 'mustache'
4
+
5
+ class Mustache
6
+
7
+ # Remember to use {{{yield}}} (3 mustaches) to skip escaping HTML
8
+ # Using {{{tag}}} will skip escaping HTML so if your mustache methods return
9
+ # HTML, be sure to interpolate them using 3 mustaches.
10
+
11
+ class Rails < Mustache
12
+ attr_accessor :view
13
+
14
+ def method_missing(method, *args, &block)
15
+ view.send(method, *args, &block)
16
+ end
17
+
18
+ def respond_to?(method, include_private=false)
19
+ super(method, include_private) || view.respond_to?(method, include_private)
20
+ end
21
+
22
+ # Redefine where Mustache::Rails templates locate their partials:
23
+ #
24
+ # (1) in the same directory as the current template file.
25
+ # (2) in the shared templates path (can be configured via Config.shared_path=(value))
26
+ #
27
+ def partial(name)
28
+ partial_name = "_#{name}.#{Config.template_extension}"
29
+ template_dir = Pathname.new(self.class.template_file).dirname
30
+ partial_path = File.expand_path("#{template_dir}/#{partial_name}")
31
+ unless File.file?(partial_path)
32
+ partial_path = "#{Config.shared_path}/#{partial_name}"
33
+ end
34
+ File.read(partial_path)
35
+ end
36
+
37
+ # You can change these defaults in, say, a Rails initializer or
38
+ # environment.rb, e.g.:
39
+ #
40
+ # Mustache::Rails::Config.template_base_path = Rails.root.join('app', 'templates')
41
+ module Config
42
+ def self.template_base_path
43
+ @template_base_path ||= ::Rails.root.join('app', 'templates')
44
+ end
45
+
46
+ def self.template_base_path=(value)
47
+ @template_base_path = value
48
+ end
49
+
50
+ def self.template_extension
51
+ @template_extension ||= 'html.mustache'
52
+ end
53
+
54
+ def self.template_extension=(value)
55
+ @template_extension = value
56
+ end
57
+
58
+ def self.shared_path
59
+ @shared_path ||= ::Rails.root.join('app', 'templates', 'shared')
60
+ end
61
+
62
+ def self.shared_path=(value)
63
+ @shared_path = value
64
+ end
65
+ end
66
+
67
+ class TemplateHandler < ActionView::Template::Handler
68
+
69
+ include ActionView::Template::Handlers::Compilable
70
+
71
+ self.default_format = :mustache
72
+
73
+ # @return [String] its evaled in the context of the action view
74
+ # hence the hack below
75
+ #
76
+ # @param [ActionView::Template]
77
+ def compile(template)
78
+ mustache_class = mustache_class_from_template(template)
79
+ mustache_class.template_file = mustache_template_file(template)
80
+
81
+ <<-MUSTACHE
82
+ mustache = ::#{mustache_class}.new
83
+ mustache.view = self
84
+ mustache[:yield] = content_for(:layout)
85
+ mustache.context.update(local_assigns)
86
+ variables = controller.instance_variable_names
87
+ variables -= %w[@template]
88
+
89
+ if controller.respond_to?(:protected_instance_variables)
90
+ variables -= controller.protected_instance_variables
91
+ end
92
+
93
+ variables.each do |name|
94
+ mustache.instance_variable_set(name, controller.instance_variable_get(name))
95
+ end
96
+
97
+ # Declaring an +attr_reader+ for each instance variable in the
98
+ # Mustache::Rails subclass makes them available to your templates.
99
+ mustache.class.class_eval do
100
+ attr_reader *variables.map { |name| name.sub(/^@/, '').to_sym }
101
+ end
102
+
103
+ mustache.render
104
+ MUSTACHE
105
+ end
106
+
107
+ private
108
+
109
+ def mustache_class_from_template(template)
110
+ const_name = ActiveSupport::Inflector.camelize(template.virtual_path.to_s)
111
+ defined?(const_name) ? const_name.constantize : Mustache
112
+ end
113
+
114
+ def mustache_template_file(template)
115
+ "#{Config.template_base_path}/#{template.virtual_path}.#{Config.template_extension}"
116
+ end
117
+
118
+ end
119
+ end
120
+ end
121
+
122
+ ::ActiveSupport::Dependencies.load_paths << Rails.root.join("app", "views")
123
+ ::ActionView::Template.register_template_handler(:rb, Mustache::Rails::TemplateHandler)
@@ -0,0 +1,35 @@
1
+ ## Mustache support for Rails 3
2
+
3
+ This generator and template handler for Mustache in Rails 3 is based on the
4
+ work of Paul Barry, Louis T., and Martin Gamsjaeger. I am indebted to them for allowing me to stand on their shoulders.
5
+
6
+ Subclass Mustache::Rails for your view files. Place view files in
7
+ app/views/:controller/:action.rb.
8
+
9
+ Mustache::Rails registers a TemplateHandler for ".rb" files. Templates go in
10
+ app/templates/:controller/:action.format.mustache
11
+
12
+ This is also available as a [rubygem](http://rubygems.org/gems/mustache_rails3).
13
+
14
+ I'm just getting started. This really is a low-numbered prerelease. :-) I have asked for comments on [the mustache project's Rails Support issue ticket](http://github.com/defunkt/mustache/issues/#issue/3/comment/294928). Please leave feedback there, and thanks.
15
+
16
+ ### Instructions
17
+
18
+ A Rails 3 reminder: be sure to add
19
+ gem 'mustache'
20
+ to your project's Gemfile before running any generators or starting the server.
21
+ If you're using the mustache_rails3 gem, be sure to also add
22
+ gem 'mustache_rails3'
23
+
24
+ You can enable the mustache template handler by running
25
+ rails g mustache:install
26
+ in your project directory.
27
+
28
+ ### TODO:
29
+
30
+ * Enable mustache layout usage (uses default application.erb for now)
31
+ * Add controller-retrofit generator to build default mustache views for existing controllers
32
+ * Generate different fields for different attribute types
33
+ * Think about allowing to overwrite layout methods in subclassing views:
34
+ http://github.com/defunkt/mustache/blob/master/lib/mustache/sinatra.rb#L79-82
35
+ http://github.com/defunkt/mustache/blob/master/lib/mustache/sinatra.rb#L96-102
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mustache_rails3
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 2
9
+ version: 0.1.2
10
+ platform: ruby
11
+ authors:
12
+ - Michael Harrison
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-28 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies: []
20
+
21
+ description: Mustache_rails3 is intended to add Rails 3 support to the existing mustache templating system for Ruby. It provides a template handler for Rails 3 and generators. The source code is maintained at http://github.com/goodmike/mustache_rails3, and I welcome comments and forks.
22
+ email: mh@michaelharrison.ws
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - readme.md
31
+ - LICENSE
32
+ - config/initializers/mustache.rb
33
+ - lib/generators/mustache.rb
34
+ - lib/generators/mustache/controller/controller_generator.rb
35
+ - lib/generators/mustache/controller/templates/view.html.mustache.erb
36
+ - lib/generators/mustache/controller/templates/view.rb.erb
37
+ - lib/generators/mustache/install/install_generator.rb
38
+ - lib/generators/mustache/install/templates/config/initializers/mustache.rb
39
+ - lib/generators/mustache/scaffold/scaffold_generator.rb
40
+ - lib/generators/mustache/scaffold/templates/_form.html.mustache.erb
41
+ - lib/generators/mustache/scaffold/templates/edit.html.mustache.erb
42
+ - lib/generators/mustache/scaffold/templates/edit.rb.erb
43
+ - lib/generators/mustache/scaffold/templates/index.html.mustache.erb
44
+ - lib/generators/mustache/scaffold/templates/index.rb.erb
45
+ - lib/generators/mustache/scaffold/templates/new.html.mustache.erb
46
+ - lib/generators/mustache/scaffold/templates/new.rb.erb
47
+ - lib/generators/mustache/scaffold/templates/show.html.mustache.erb
48
+ - lib/generators/mustache/scaffold/templates/show.rb.erb
49
+ - lib/mustache_rails.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/goodmike/mustache_rails3
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ segments:
65
+ - 0
66
+ version: "0"
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.3.7
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: Mustache_rails3 provides a template handler and generators for Rails 3.
82
+ test_files: []
83
+