mack 0.0.7.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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