mack 0.0.7.0 → 0.1.0

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 (24) hide show
  1. data/CHANGELOG +8 -0
  2. data/bin/templates/config/app_config/default.yml.template +2 -2
  3. data/bin/templates/config/database.yml.template +1 -1
  4. data/lib/core_extensions/hash.rb +30 -0
  5. data/lib/core_extensions/string.rb +10 -0
  6. data/lib/generators/scaffold_generator/scaffold_generator.rb +72 -0
  7. data/lib/generators/scaffold_generator/templates/activerecord/app/models/model.rb.template +2 -0
  8. data/lib/generators/scaffold_generator/templates/data_mapper/app/controllers/controller.rb.template +50 -0
  9. data/lib/generators/scaffold_generator/templates/data_mapper/app/models/model.rb.template +2 -0
  10. data/lib/generators/scaffold_generator/templates/generic/app/controllers/controller.rb.template +50 -0
  11. data/lib/generators/scaffold_generator/templates/generic/app/views/edit.html.erb.template +13 -0
  12. data/lib/generators/scaffold_generator/templates/generic/app/views/index.html.erb.template +20 -0
  13. data/lib/generators/scaffold_generator/templates/generic/app/views/new.html.erb.template +12 -0
  14. data/lib/generators/scaffold_generator/templates/generic/app/views/show.html.erb.template +7 -0
  15. data/lib/generators/scaffold_generator/templates/no_orm/app/controllers/controller.rb.template +38 -0
  16. data/lib/initialization/initializer.rb +1 -1
  17. data/lib/initialization/initializers/orm_support.rb +3 -3
  18. data/lib/mack.rb +8 -2
  19. data/lib/routing/route_map.rb +2 -2
  20. data/lib/sea_level/helpers/view_helpers/orm_helpers.rb +20 -5
  21. data/lib/test_extensions/test_helpers.rb +2 -14
  22. data/lib/utils/inflections.rb +62 -0
  23. data/lib/utils/inflector.rb +129 -0
  24. metadata +14 -2
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ ===0.1.0
2
+ * Added an inflections system. The default inflections are from Jeremy McAnally's great Rails plugin, acts_as_good_speeler. Thanks Jeremy! http://www.jeremymcanally.com/
3
+ * Added a to_params method to Hash to help with testing.
4
+ * Added rake generate:scaffold task.
5
+
6
+ ===0.0.7.0
7
+ * Fixed [#18488] Recommend moving files under lib/
8
+
1
9
  ===0.0.6.2
2
10
  * gem: thin 0.7.0
3
11
  * gem: cachetastic 1.3.1
@@ -2,6 +2,6 @@ whiny_config_missing: false
2
2
 
3
3
  mack::session_id: _<%= app.downcase %>_session_id
4
4
 
5
- # mack::log_level: error
5
+ # log::level: error
6
6
 
7
- <%= options.orm ? "mack::orm: #{options.orm}" : "" %>
7
+ <%= options.orm ? "orm: #{options.orm}" : "" %>
@@ -14,7 +14,7 @@ test:
14
14
 
15
15
  production:
16
16
  adapter: mysql
17
- database: <%= app.downcase %>_development
17
+ database: <%= app.downcase %>_production
18
18
  host: localhost
19
19
  username: root
20
20
  password:
@@ -6,4 +6,34 @@ class Hash
6
6
  self
7
7
  end
8
8
 
9
+ # Converts a hash to query string parameters.
10
+ # An optional boolean escapes the values if true, which is the default.
11
+ def to_params(escape = true)
12
+ params = ''
13
+ stack = []
14
+
15
+ each do |k, v|
16
+ if v.is_a?(Hash)
17
+ stack << [k,v]
18
+ else
19
+ v = Rack::Utils.escape(v) if escape
20
+ params << "#{k}=#{v}&"
21
+ end
22
+ end
23
+
24
+ stack.each do |parent, hash|
25
+ hash.each do |k, v|
26
+ if v.is_a?(Hash)
27
+ stack << ["#{parent}[#{k}]", v]
28
+ else
29
+ v = Rack::Utils.escape(v) if escape
30
+ params << "#{parent}[#{k}]=#{v}&"
31
+ end
32
+ end
33
+ end
34
+
35
+ params.chop! # trailing &
36
+ params
37
+ end
38
+
9
39
  end
@@ -25,4 +25,14 @@ class String
25
25
  self == ""
26
26
  end
27
27
 
28
+ # Maps to Mack::Utils::Inflector.instance.pluralize
29
+ def plural
30
+ Mack::Utils::Inflector.instance.pluralize(self)
31
+ end
32
+
33
+ # Maps to Mack::Utils::Inflector.instance.singularize
34
+ def singular
35
+ Mack::Utils::Inflector.instance.singularize(self)
36
+ end
37
+
28
38
  end
@@ -0,0 +1,72 @@
1
+ # Generates scaffold for Mack applications.
2
+ #
3
+ # Example:
4
+ # rake generate:scaffold name=post
5
+ # This will generate the following in your mack application:
6
+ # vendor/plugins/my_cool_plugin
7
+ # vendor/plugins/my_cool_plugin/init.rb
8
+ # vendor/plugins/my_cool_plugin/lib
9
+ # vendor/plugins/my_cool_plugin/lib/my_cool_plugin.rb
10
+ class ScaffoldGenerator < Mack::Generator::Base
11
+
12
+ require_param :name
13
+
14
+ def generate
15
+ @name_singular = param(:name).singular
16
+ @name_plural = param(:name).plural
17
+ @name_singular_camel = @name_singular.camelcase
18
+ @name_plural_camel = @name_plural.camelcase
19
+
20
+ # update routes.rb
21
+ routes = File.join(MACK_CONFIG, "routes.rb")
22
+ rf = File.open(routes).read
23
+ unless rf.match(".resource :#{@name_plural}")
24
+ puts "Updating routes.rb"
25
+ nrf = ""
26
+ rf.each do |line|
27
+ if line.match("Mack::Routes.build")
28
+ x = line.match(/\|(.+)\|/).captures
29
+ line << "\n #{x}.resource :#{@name_plural} # Added by rake generate:scaffold name=#{param(:name)}\n"
30
+ end
31
+ nrf << line
32
+ end
33
+ File.open(routes, "w") do |f|
34
+ f.puts nrf
35
+ end
36
+ end
37
+
38
+ app_cont_dir = File.join(MACK_APP, "controllers")
39
+ directory(app_cont_dir)
40
+
41
+ app_model_dir = File.join(MACK_APP, "models")
42
+ directory(app_model_dir)
43
+
44
+ app_views_dir = File.join(MACK_APP, "views", @name_plural)
45
+ directory(app_views_dir)
46
+
47
+ temp_dir = File.join(File.dirname(__FILE__), "templates")
48
+
49
+ case app_config.orm
50
+ when "activerecord"
51
+ template(File.join(temp_dir, "generic", "app", "controllers", "controller.rb.template"), File.join(app_cont_dir, "#{@name_plural}_controller.rb"), :force => param(:force))
52
+ template(File.join(temp_dir, "activerecord", "app", "models", "model.rb.template"), File.join(app_model_dir, "#{@name_singular}.rb"), :force => param(:force))
53
+
54
+ template(File.join(temp_dir, "generic", "app", "views", "index.html.erb.template"), File.join(app_views_dir, "index.html.erb"), :force => param(:force))
55
+ template(File.join(temp_dir, "generic", "app", "views", "edit.html.erb.template"), File.join(app_views_dir, "edit.html.erb"), :force => param(:force))
56
+ template(File.join(temp_dir, "generic", "app", "views", "new.html.erb.template"), File.join(app_views_dir, "new.html.erb"), :force => param(:force))
57
+ template(File.join(temp_dir, "generic", "app", "views", "show.html.erb.template"), File.join(app_views_dir, "show.html.erb"), :force => param(:force))
58
+ when "data_mapper"
59
+ template(File.join(temp_dir, "data_mapper", "app", "controllers", "controller.rb.template"), File.join(app_cont_dir, "#{@name_plural}_controller.rb"), :force => param(:force))
60
+ template(File.join(temp_dir, "data_mapper", "app", "models", "model.rb.template"), File.join(app_model_dir, "#{@name_singular}.rb"), :force => param(:force))
61
+
62
+ template(File.join(temp_dir, "generic", "app", "views", "index.html.erb.template"), File.join(app_views_dir, "index.html.erb"), :force => param(:force))
63
+ template(File.join(temp_dir, "generic", "app", "views", "edit.html.erb.template"), File.join(app_views_dir, "edit.html.erb"), :force => param(:force))
64
+ template(File.join(temp_dir, "generic", "app", "views", "new.html.erb.template"), File.join(app_views_dir, "new.html.erb"), :force => param(:force))
65
+ template(File.join(temp_dir, "generic", "app", "views", "show.html.erb.template"), File.join(app_views_dir, "show.html.erb"), :force => param(:force))
66
+ else
67
+ template(File.join(temp_dir, "no_orm", "app", "controllers", "controller.rb.template"), File.join(app_cont_dir, "#{@name_plural}_controller.rb"), :force => param(:force))
68
+ end
69
+
70
+ end
71
+
72
+ end
@@ -0,0 +1,2 @@
1
+ class <%= @name_singular_camel %> < ActiveRecord::Base
2
+ end
@@ -0,0 +1,50 @@
1
+ class <%= @name_plural_camel %>Controller < Mack::Controller::Base
2
+
3
+ # GET /<%= @name_plural %>
4
+ def index
5
+ @<%= @name_plural %> = <%= @name_singular_camel %>.find(:all)
6
+ end
7
+
8
+ # GET /<%= @name_plural %>/1
9
+ def show
10
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
11
+ end
12
+
13
+ # GET /<%= @name_plural %>/new
14
+ def new
15
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new
16
+ end
17
+
18
+ # GET /<%= @name_plural %>/1/edit
19
+ def edit
20
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
21
+ end
22
+
23
+ # POST /<%= @name_plural %>
24
+ def create
25
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new(params(:<%= @name_singular %>))
26
+ if @<%= @name_singular %>.save
27
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
28
+ else
29
+ render(:action => "new")
30
+ end
31
+ end
32
+
33
+ # PUT /<%= @name_plural %>/1
34
+ def update
35
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
36
+ if @<%= @name_singular %>.update_attributes(params(:<%= @name_singular %>))
37
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>.id))
38
+ else
39
+ render(:action => "edit")
40
+ end
41
+ end
42
+
43
+ # DELETE /<%= @name_plural %>/1
44
+ def delete
45
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
46
+ @<%= @name_singular %>.destroy!
47
+ redirect_to(<%= @name_plural %>_index_url)
48
+ end
49
+
50
+ end
@@ -0,0 +1,2 @@
1
+ class <%= @name_singular_camel %> < DataMapper::Base
2
+ end
@@ -0,0 +1,50 @@
1
+ class <%= @name_plural_camel %>Controller < Mack::Controller::Base
2
+
3
+ # GET /<%= @name_plural %>
4
+ def index
5
+ @<%= @name_plural %> = <%= @name_singular_camel %>.find(:all)
6
+ end
7
+
8
+ # GET /<%= @name_plural %>/1
9
+ def show
10
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
11
+ end
12
+
13
+ # GET /<%= @name_plural %>/new
14
+ def new
15
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new
16
+ end
17
+
18
+ # GET /<%= @name_plural %>/1/edit
19
+ def edit
20
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
21
+ end
22
+
23
+ # POST /<%= @name_plural %>
24
+ def create
25
+ @<%= @name_singular %> = <%= @name_singular_camel %>.new(params(:<%= @name_singular %>))
26
+ if @<%= @name_singular %>.save
27
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>))
28
+ else
29
+ render(:action => "new")
30
+ end
31
+ end
32
+
33
+ # PUT /<%= @name_plural %>/1
34
+ def update
35
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
36
+ if @<%= @name_singular %>.update_attributes(params(:<%= @name_singular %>))
37
+ redirect_to(<%= @name_plural %>_show_url(:id => @<%= @name_singular %>))
38
+ else
39
+ render(:action => "edit")
40
+ end
41
+ end
42
+
43
+ # DELETE /<%= @name_plural %>/1
44
+ def delete
45
+ @<%= @name_singular %> = <%= @name_singular_camel %>.find(params(:id))
46
+ @<%= @name_singular %>.destroy
47
+ redirect_to(<%= @name_plural %>_index_url)
48
+ end
49
+
50
+ end
@@ -0,0 +1,13 @@
1
+ <h1>Edit <%= @name_singular %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <form action="<%%= <%= @name_singular %>s_update_url(:id => @<%= @name_singular %>.id) %>" class="edit_<%= @name_singular %>" id="edit_<%= @name_singular %>" method="<%= @name_singular %>">
6
+ <input type="hidden" name="_method" value="put">
7
+
8
+ <p>
9
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Create" />
10
+ </p>
11
+ </form>
12
+
13
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,20 @@
1
+ <h1>Listing <%= @name_plural %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>&nbsp;</th>
6
+ </tr>
7
+
8
+ <%% for <%= @name_singular %> in @<%= @name_plural %> %>
9
+ <tr>
10
+ <td>&nbsp;</td>
11
+ <td><%%= link_to("Show", <%= @name_plural %>_show_url(:id => <%= @name_singular %>.id)) %></td>
12
+ <td><%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => <%= @name_singular %>.id)) %></td>
13
+ <td><%%= link_to("Delete", <%= @name_plural %>_delete_url(:id => <%= @name_singular %>.id), :method => :delete, :confirm => "Are you sure?") %></td>
14
+ </tr>
15
+ <%% end %>
16
+ </table>
17
+
18
+ <br />
19
+
20
+ <%%= link_to("New <%= @name_singular_camel %>", <%= @name_plural %>_new_url) %>
@@ -0,0 +1,12 @@
1
+ <h1>New <%= @name_singular %></h1>
2
+
3
+ <%%= error_messages_for :<%= @name_singular %> %>
4
+
5
+ <form action="<%%= <%= @name_singular %>s_create_url %>" class="new_<%= @name_singular %>" id="new_<%= @name_singular %>" method="<%= @name_singular %>">
6
+
7
+ <p>
8
+ <input id="<%= @name_singular %>_submit" name="commit" type="submit" value="Create" />
9
+ </p>
10
+ </form>
11
+
12
+ <%%= link_to("Back", <%= @name_singular %>s_index_url) %>
@@ -0,0 +1,7 @@
1
+ <p>
2
+ <%%= @<%= @name_singular %>.inspect %>
3
+ </p>
4
+
5
+
6
+ <%%= link_to("Edit", <%= @name_plural %>_edit_url(:id => @<%= @name_singular %>.id)) %> |
7
+ <%%= link_to("Back", <%= @name_plural %>_index_url) %>
@@ -0,0 +1,38 @@
1
+ class <%= @name_plural_camel %>Controller < Mack::Controller::Base
2
+
3
+ # GET /<%= @name_plural %>
4
+ def index
5
+ "<%= @name_plural_camel %>#index"
6
+ end
7
+
8
+ # POST /<%= @name_plural %>
9
+ def create
10
+ "<%= @name_plural_camel %>#create"
11
+ end
12
+
13
+ # GET /<%= @name_plural %>/new
14
+ def new
15
+ "<%= @name_plural_camel %>#new"
16
+ end
17
+
18
+ # GET /<%= @name_plural %>/1
19
+ def show
20
+ "<%= @name_plural_camel %>#show id: #{params(:id)}"
21
+ end
22
+
23
+ # GET /<%= @name_plural %>/1/edit
24
+ def edit
25
+ "<%= @name_plural_camel %>#edit id: #{params(:id)}"
26
+ end
27
+
28
+ # PUT /<%= @name_plural %>/1
29
+ def update
30
+ "<%= @name_plural_camel %>#update id: #{params(:id)}"
31
+ end
32
+
33
+ # DELETE /<%= @name_plural %>/1
34
+ def delete
35
+ "<%= @name_plural_camel %>#delete"
36
+ end
37
+
38
+ end
@@ -40,7 +40,7 @@ unless Object.const_defined?("MACK_INITIALIZED")
40
40
  fl = File.join(File.dirname(__FILE__), "..")
41
41
 
42
42
  # Require all the necessary files to make Mack actually work!
43
- ["errors", "core_extensions", "utils", "test_extensions", "routing", "sea_level", "tasks", "initialization/server"].each do |dir|
43
+ ["errors", "core_extensions", "utils", "test_extensions", "routing", "sea_level", "tasks", "initialization/server", "generators"].each do |dir|
44
44
  dir_globs = Dir.glob(File.join(fl, dir, "**/*.rb"))
45
45
  dir_globs.each do |d|
46
46
  require d
@@ -4,9 +4,9 @@
4
4
  eval("def using_#{orm}?; false; end")
5
5
  end
6
6
 
7
- unless app_config.mack.orm.nil?
7
+ unless app_config.orm.nil?
8
8
  dbs = YAML::load(ERB.new(IO.read(File.join(MACK_CONFIG, "database.yml"))).result)
9
- case app_config.mack.orm
9
+ case app_config.orm
10
10
  when 'activerecord'
11
11
  require 'activerecord'
12
12
  ActiveRecord::Base.establish_connection(dbs[MACK_ENV])
@@ -16,7 +16,7 @@ unless app_config.mack.orm.nil?
16
16
  DataMapper::Database.setup(dbs[MACK_ENV])
17
17
  eval("def using_data_mapper?; true; end")
18
18
  else
19
- MACK_DEFAULT_LOGGER.warn("Attempted to configure an unknown ORM: #{app_config.mack.orm}")
19
+ MACK_DEFAULT_LOGGER.warn("Attempted to configure an unknown ORM: #{app_config.orm}")
20
20
  end
21
21
  else
22
22
  MACK_DEFAULT_LOGGER.warn("No ORM has been configured!")
data/lib/mack.rb CHANGED
@@ -55,15 +55,21 @@ module Mack
55
55
  # Setup the request, response, cookies, session, etc...
56
56
  # yield up, and then clean things up afterwards.
57
57
  def setup(env)
58
+ exception = nil
58
59
  log_request do
59
60
  @request = Mack::Request.new(env)
60
61
  @response = Mack::Response.new
61
62
  @cookies = Mack::CookieJar.new(self.request, self.response)
62
63
  session do
63
- yield
64
+ begin
65
+ yield
66
+ rescue Exception => e
67
+ exception = e
68
+ end
64
69
  end
65
- self.response.finish
70
+ return self.response.finish unless exception
66
71
  end
72
+ raise exception if exception
67
73
  end
68
74
 
69
75
  def session
@@ -60,7 +60,7 @@ module Mack
60
60
  # # '/users/:id/:edit # => {:controller => 'users', :action => :edit, :method => :get}
61
61
  # # # => users_edit_url
62
62
  # # # => users_edit_full_url
63
- # # '/users/:id/update # => {:controller => 'users', :action => :update, :method => :post}
63
+ # # '/users/:id # => {:controller => 'users', :action => :update, :method => :put}
64
64
  # # # => users_update_url
65
65
  # # # => users_update_full_url
66
66
  # # '/users/:id # => {:controller => 'users', :action => :delete, :method => :delete}
@@ -158,7 +158,7 @@ module Mack
158
158
  connect_with_named_route("#{controller}_new", "/#{controller}/new", {:controller => controller, :action => :new, :method => :get})
159
159
  connect_with_named_route("#{controller}_show", "/#{controller}/:id", {:controller => controller, :action => :show, :method => :get})
160
160
  connect_with_named_route("#{controller}_edit", "/#{controller}/:id/edit", {:controller => controller, :action => :edit, :method => :get})
161
- connect_with_named_route("#{controller}_update", "/#{controller}/:id/update", {:controller => controller, :action => :update, :method => :post})
161
+ connect_with_named_route("#{controller}_update", "/#{controller}/:id", {:controller => controller, :action => :update, :method => :put})
162
162
  connect_with_named_route("#{controller}_delete", "/#{controller}/:id", {:controller => controller, :action => :delete, :method => :delete})
163
163
  end
164
164
 
@@ -38,13 +38,28 @@ module Mack
38
38
  object = instance_variable_get("@#{name}")
39
39
  if object
40
40
  object.errors.each do |key, value|
41
- if value.match(/^\^/)
42
- app_errors << value[1..value.length]
41
+ key = key.to_s
42
+ if value.is_a?(Array)
43
+ value.each do |v|
44
+ if v.match(/^\^/)
45
+ app_errors << v[1..v.length]
46
+ else
47
+ if key.class == String and key == "base"
48
+ app_errors << "#{v}"
49
+ else
50
+ app_errors << "#{object.business_display_name} #{key.underscore.split('_').join(' ')} #{v}"
51
+ end
52
+ end
53
+ end
43
54
  else
44
- if key.class == String and key == "base"
45
- app_errors << "#{value}"
55
+ if value.match(/^\^/)
56
+ app_errors << value[1..value.length]
46
57
  else
47
- app_errors << "#{object.business_display_name} #{key.underscore.split('_').join(' ').humanize} #{value}"
58
+ if key.class == String and key == "base"
59
+ app_errors << "#{value}"
60
+ else
61
+ app_errors << "#{object.business_display_name} #{key.underscore.split('_').join(' ')} #{value}"
62
+ end
48
63
  end
49
64
  end
50
65
  end
@@ -11,24 +11,12 @@ module Mack
11
11
 
12
12
  # Performs a 'put' request for the specified uri.
13
13
  def put(uri, options = {})
14
- build_response(request.put(uri, options))
14
+ build_response(request.put(uri, :input => options.to_params))
15
15
  end
16
16
 
17
17
  # Performs a 'post' request for the specified uri.
18
18
  def post(uri, options = {})
19
- opts = {}
20
- options.each_pair do |k,v|
21
- if v.is_a?(String)
22
- opts[k] = Rack::Utils.escape(v)
23
- elsif v.is_a?(Hash)
24
- v.each_pair do |sk, sv|
25
- opts["#{k}[#{sk}]"] = Rack::Utils.escape(sv)
26
- end
27
- else
28
- opts[k] = v
29
- end
30
- end
31
- build_response(request.post(uri, :input => opts.join("%s=%s", "&")))
19
+ build_response(request.post(uri, :input => options.to_params))
32
20
  end
33
21
 
34
22
  # Performs a 'delete' request for the specified uri.
@@ -0,0 +1,62 @@
1
+ require File.join(File.dirname(__FILE__), "inflector")
2
+ # Default inflections. This is taken from Jeremy McAnally's great Rails plugin, acts_as_good_speeler. Thanks Jeremy! http://www.jeremymcanally.com/
3
+ Mack::Utils::Inflector.inflections do |inflect|
4
+ inflect.plural(/$/, 's')
5
+ inflect.plural(/s$/i, 's')
6
+ inflect.plural(/(bu)s$/i, '\1ses')
7
+ inflect.plural(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)us$/i, '\1i')
8
+ inflect.plural(/(ax|test)is$/i, '\1es')
9
+ inflect.plural(/(alias|status)$/i, '\1es')
10
+ inflect.plural(/(buffal|tomat|torped)o$/i, '\1oes')
11
+ inflect.plural(/([dti])um$/i, '\1a')
12
+ inflect.plural(/sis$/i, 'ses')
13
+ inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
14
+ inflect.plural(/(hive)$/i, '\1s')
15
+ inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
16
+ inflect.plural(/(x|ch|ss|sh)$/i, '\1es')
17
+ inflect.plural(/(matr|append|vert|ind)ix|ex$/i, '\1ices')
18
+ inflect.plural(/([m|l])ouse$/i, '\1ice')
19
+ inflect.plural(/^(ox)$/i, '\1en')
20
+ inflect.plural(/(quiz)$/i, '\1zes')
21
+ inflect.plural(/(phenomen|criteri)on$/i, '\1a')
22
+ inflect.plural(/^(?!(.*hu|.*ger|.*sha))(.*)(wom|m)an$/i, '\2\3en')
23
+ inflect.plural(/(curricul|bacteri|medi)um$/i, '\1a')
24
+ inflect.plural(/(nebul|formul|vit|vertebr|alg|alumn)a$/i, '\1ae')
25
+
26
+ inflect.singular(/s$/i, '')
27
+ inflect.singular(/(n)ews$/i, '\1ews')
28
+ inflect.singular(/([dti])a$/i, '\1um')
29
+ inflect.singular(/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i, '\1\2sis')
30
+ inflect.singular(/(^analy|cri|empha)ses$/i, '\1sis')
31
+ inflect.singular(/([^f])ves$/i, '\1fe')
32
+ inflect.singular(/(hive)s$/i, '\1')
33
+ inflect.singular(/(tive)s$/i, '\1')
34
+ inflect.singular(/(bus)es$/i, '\1')
35
+ inflect.singular(/(o)es$/i, '\1')
36
+ inflect.singular(/(shoe)s$/i, '\1')
37
+ inflect.singular(/(test|ax)es$/i, '\1is')
38
+ inflect.singular(/(stimul|hippopotam|octop|vir|syllab|foc|alumn|fung|radi)i$/i, '\1us')
39
+ inflect.singular(/(alias|status)es$/i, '\1')
40
+ inflect.singular(/^(ox)en$/i, '\1')
41
+ inflect.singular(/(vert|ind)ices$/i, '\1ex')
42
+ inflect.singular(/(matr|append)ices$/i, '\1ix')
43
+ inflect.singular(/(quiz)zes$/i, '\1')
44
+ inflect.singular(/(phenomen|criteri)a$/i, '\1on')
45
+ inflect.singular(/(.*)(wo|m)en$/i, '\1\2an')
46
+ inflect.singular(/(medi|curricul|bacteri)a$/i, '\1um')
47
+ inflect.singular(/(nebula|formula|vita|vertebra|alga|alumna)e$/i, '\1')
48
+ inflect.singular(/^(.*)ookies$/, '\1ookie')
49
+ inflect.singular(/(.*)ss$/, '\1ss')
50
+ inflect.singular(/(.*)ies$/, '\1y')
51
+
52
+ inflect.irregular('person', 'people')
53
+ inflect.irregular('child', 'children')
54
+ inflect.irregular('sex', 'sexes')
55
+ inflect.irregular('move', 'moves')
56
+ inflect.irregular('tooth', 'teeth')
57
+ inflect.irregular('die', 'dice')
58
+ inflect.irregular('talisman', 'talismans')
59
+ inflect.irregular('penis', 'penises')
60
+
61
+ inflect.uncountable(%w(pokemon pokémon equipment information rice money species series fish sheep deer offspring))
62
+ end
@@ -0,0 +1,129 @@
1
+ require 'singleton'
2
+ module Mack
3
+ module Utils
4
+ # This class is used to deal with inflection strings. This means taken a string and make it plural, or singular, etc...
5
+ # Inflection rules can be added very easy, and are checked from the bottom up. This means that the last rule is the first
6
+ # rule to be matched. The exception to this, kind of, is 'irregular' and 'uncountable' rules. The 'uncountable' rules are
7
+ # always checked first, then the 'irregular' rules, and finally either the 'singular' or 'plural' rules, depending on what
8
+ # you're trying to do. Within each of these sets of rules, the last rule in is the first rule matched.
9
+ #
10
+ # Example:
11
+ # Mack::Utils::Inflector.inflections do |inflect|
12
+ # inflect.plural(/$/, 's')
13
+ # inflect.plural(/^(ox)$/i, '\1en')
14
+ # inflect.plural(/(phenomen|criteri)on$/i, '\1a')
15
+ #
16
+ # inflect.singular(/s$/i, '')
17
+ # inflect.singular(/(n)ews$/i, '\1ews')
18
+ # inflect.singular(/^(.*)ookies$/, '\1ookie')
19
+ #
20
+ # inflect.irregular('person', 'people')
21
+ # inflect.irregular('child', 'children')
22
+ #
23
+ # inflect.uncountable(%w(fish sheep deer offspring))
24
+ # end
25
+ class Inflector
26
+ include Singleton
27
+
28
+ def initialize # :nodoc:
29
+ @plural_rules = []
30
+ @singular_rules = []
31
+ @irregular_rules = []
32
+ @uncountable_rules = []
33
+ end
34
+
35
+ # Adds a plural rule to the system.
36
+ #
37
+ # Example:
38
+ # Mack::Utils::Inflector.inflections do |inflect|
39
+ # inflect.plural(/$/, 's')
40
+ # inflect.plural(/^(ox)$/i, '\1en')
41
+ # inflect.plural(/(phenomen|criteri)on$/i, '\1a')
42
+ # end
43
+ def plural(rule, replacement)
44
+ @plural_rules << {:rule => rule, :replacement => replacement}
45
+ end
46
+
47
+ # Adds a singular rule to the system.
48
+ #
49
+ # Example:
50
+ # Mack::Utils::Inflector.inflections do |inflect|
51
+ # inflect.singular(/s$/i, '')
52
+ # inflect.singular(/(n)ews$/i, '\1ews')
53
+ # inflect.singular(/^(.*)ookies$/, '\1ookie')
54
+ # end
55
+ def singular(rule, replacement)
56
+ @singular_rules << {:rule => rule, :replacement => replacement}
57
+ end
58
+
59
+ # Adds a irregular rule to the system.
60
+ #
61
+ # Example:
62
+ # Mack::Utils::Inflector.inflections do |inflect|
63
+ # inflect.irregular('person', 'people')
64
+ # inflect.irregular('child', 'children')
65
+ # end
66
+ def irregular(rule, replacement)
67
+ @irregular_rules << {:rule => rule, :replacement => replacement}
68
+ # do the reverse so you get:
69
+ # person => people
70
+ # people => person
71
+ @irregular_rules << {:rule => replacement, :replacement => rule}
72
+ end
73
+
74
+ # Adds a uncountable word, or words, to the system.
75
+ #
76
+ # Example:
77
+ # Mack::Utils::Inflector.inflections do |inflect|
78
+ # inflect.uncountable(%w(fish sheep deer offspring))
79
+ # end
80
+ def uncountable(*args)
81
+ [args].flatten.each do |word|
82
+ @uncountable_rules << word.downcase
83
+ end
84
+ end
85
+
86
+ # Returns the singular version of the word, if possible.
87
+ #
88
+ # Examples:
89
+ # Mack::Utils::Inflector.instance.singularize("armies") # => "army"
90
+ # Mack::Utils::Inflector.instance.singularize("people") # => "person"
91
+ # Mack::Utils::Inflector.instance.singularize("boats") # => "boat"
92
+ def singularize(word)
93
+ do_work(word, @singular_rules)
94
+ end
95
+
96
+ # Returns the singular version of the word, if possible.
97
+ #
98
+ # Examples:
99
+ # Mack::Utils::Inflector.instance.pluralize("army") # => "armies"
100
+ # Mack::Utils::Inflector.instance.pluralize("person") # => "people"
101
+ # Mack::Utils::Inflector.instance.pluralize("boat") # => "boats"
102
+ def pluralize(word)
103
+ do_work(word, @plural_rules)
104
+ end
105
+
106
+ private
107
+ def do_work(word, specific_rules)
108
+ return word if @uncountable_rules.include?(word.downcase)
109
+ w = word.dup
110
+ [specific_rules, @irregular_rules].flatten.reverse.each do |rule_hash|
111
+ return w if w.gsub!(rule_hash[:rule], rule_hash[:replacement])
112
+ end
113
+ # if all else fails, return the word:
114
+ return word
115
+ end
116
+
117
+ public
118
+ class << self
119
+
120
+ # Yields up Mack::Utils::Inflector.instance
121
+ def inflections
122
+ yield Mack::Utils::Inflector.instance
123
+ end
124
+
125
+ end
126
+
127
+ end # Inflection
128
+ end # Utils
129
+ end # Mack
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - markbates
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-03-03 00:00:00 -05:00
12
+ date: 2008-03-04 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -103,6 +103,16 @@ files:
103
103
  - lib/generators/plugin_generator/plugin_generator.rb
104
104
  - lib/generators/plugin_generator/templates/init.rb.template
105
105
  - lib/generators/plugin_generator/templates/lib/plugin.rb.template
106
+ - lib/generators/scaffold_generator/scaffold_generator.rb
107
+ - lib/generators/scaffold_generator/templates/activerecord/app/models/model.rb.template
108
+ - lib/generators/scaffold_generator/templates/data_mapper/app/controllers/controller.rb.template
109
+ - lib/generators/scaffold_generator/templates/data_mapper/app/models/model.rb.template
110
+ - lib/generators/scaffold_generator/templates/generic/app/controllers/controller.rb.template
111
+ - lib/generators/scaffold_generator/templates/generic/app/views/edit.html.erb.template
112
+ - lib/generators/scaffold_generator/templates/generic/app/views/index.html.erb.template
113
+ - lib/generators/scaffold_generator/templates/generic/app/views/new.html.erb.template
114
+ - lib/generators/scaffold_generator/templates/generic/app/views/show.html.erb.template
115
+ - lib/generators/scaffold_generator/templates/no_orm/app/controllers/controller.rb.template
106
116
  - lib/initialization/configuration.rb
107
117
  - lib/initialization/console.rb
108
118
  - lib/initialization/initializer.rb
@@ -133,6 +143,8 @@ files:
133
143
  - lib/test_extensions/test_assertions.rb
134
144
  - lib/test_extensions/test_helpers.rb
135
145
  - lib/utils/html.rb
146
+ - lib/utils/inflections.rb
147
+ - lib/utils/inflector.rb
136
148
  - lib/utils/server.rb
137
149
  - CHANGELOG
138
150
  has_rdoc: true