grippy-doozer 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 (72) hide show
  1. data/.document +5 -0
  2. data/.gitignore +5 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +57 -0
  5. data/Rakefile +59 -0
  6. data/VERSION +1 -0
  7. data/bin/doozer +8 -0
  8. data/doozer.gemspec +114 -0
  9. data/lib/doozer/README.rb +40 -0
  10. data/lib/doozer/active_support/array.rb +14 -0
  11. data/lib/doozer/active_support/class.rb +221 -0
  12. data/lib/doozer/active_support/date_time.rb +23 -0
  13. data/lib/doozer/active_support/object.rb +43 -0
  14. data/lib/doozer/active_support/time.rb +32 -0
  15. data/lib/doozer/app.rb +265 -0
  16. data/lib/doozer/configs.rb +131 -0
  17. data/lib/doozer/controller.rb +335 -0
  18. data/lib/doozer/extend.rb +10 -0
  19. data/lib/doozer/initializer.rb +95 -0
  20. data/lib/doozer/lib.rb +32 -0
  21. data/lib/doozer/logger.rb +11 -0
  22. data/lib/doozer/orm/active_record.rb +19 -0
  23. data/lib/doozer/orm/data_mapper.rb +19 -0
  24. data/lib/doozer/orm/sequel.rb +18 -0
  25. data/lib/doozer/partial.rb +99 -0
  26. data/lib/doozer/plugins/paginate/init.rb +2 -0
  27. data/lib/doozer/plugins/paginate/lib/paginate/collection.rb +60 -0
  28. data/lib/doozer/plugins/paginate/lib/paginate/finder.rb +116 -0
  29. data/lib/doozer/plugins/paginate/lib/paginate/view_helpers.rb +37 -0
  30. data/lib/doozer/plugins/paginate/lib/paginate.rb +32 -0
  31. data/lib/doozer/rackup/server.ru +37 -0
  32. data/lib/doozer/rackup/test.rb +19 -0
  33. data/lib/doozer/redirect.rb +12 -0
  34. data/lib/doozer/route.rb +264 -0
  35. data/lib/doozer/scripts/cluster.rb +132 -0
  36. data/lib/doozer/scripts/migrate.rb +108 -0
  37. data/lib/doozer/scripts/task.rb +60 -0
  38. data/lib/doozer/scripts/test.rb +23 -0
  39. data/lib/doozer/version.rb +8 -0
  40. data/lib/doozer/view_helpers.rb +163 -0
  41. data/lib/doozer/watcher.rb +375 -0
  42. data/lib/doozer.rb +30 -0
  43. data/lib/generator/generator.rb +547 -0
  44. data/templates/skeleton/Rakefile +3 -0
  45. data/templates/skeleton/app/controllers/application_controller.rb +2 -0
  46. data/templates/skeleton/app/controllers/index_controller.rb +7 -0
  47. data/templates/skeleton/app/helpers/application_helper.rb +17 -0
  48. data/templates/skeleton/app/views/global/_header.html.erb +7 -0
  49. data/templates/skeleton/app/views/global/_navigation.html.erb +6 -0
  50. data/templates/skeleton/app/views/index/index.html.erb +108 -0
  51. data/templates/skeleton/app/views/layouts/default.html.erb +23 -0
  52. data/templates/skeleton/config/app.yml +31 -0
  53. data/templates/skeleton/config/database.yml +25 -0
  54. data/templates/skeleton/config/environment.rb +13 -0
  55. data/templates/skeleton/config/rack.rb +30 -0
  56. data/templates/skeleton/config/routes.rb +69 -0
  57. data/templates/skeleton/script/cluster +5 -0
  58. data/templates/skeleton/script/migrate +5 -0
  59. data/templates/skeleton/script/task +5 -0
  60. data/templates/skeleton/script/test +4 -0
  61. data/templates/skeleton/static/404.html +16 -0
  62. data/templates/skeleton/static/500.html +16 -0
  63. data/templates/skeleton/static/css/style.css +32 -0
  64. data/templates/skeleton/static/favicon.ico +0 -0
  65. data/templates/skeleton/static/js/application.js +1 -0
  66. data/templates/skeleton/static/js/jquery-1.3.min.js +19 -0
  67. data/templates/skeleton/static/robots.txt +5 -0
  68. data/templates/skeleton/test/fixtures/setup.rb +6 -0
  69. data/templates/skeleton/test/setup.rb +33 -0
  70. data/test/doozer_test.rb +7 -0
  71. data/test/test_helper.rb +10 -0
  72. metadata +126 -0
@@ -0,0 +1,60 @@
1
+ module Paginate
2
+
3
+ class InvalidPage < ArgumentError
4
+ def initialize(page, page_num)
5
+ super "#{page.inspect} given as value, which translates to '#{page_num}' as page number"
6
+ end
7
+ end
8
+
9
+ class Collection < Array
10
+ attr_reader :current_page, :per_page, :total_entries, :total_pages
11
+
12
+ def initialize(page, per_page, total = nil)
13
+ @current_page = page.to_i
14
+ raise InvalidPage.new(page, @current_page) if @current_page < 1
15
+ @per_page = per_page.to_i
16
+ raise ArgumentError, "`per_page` setting cannot be less than 1 (#{@per_page} given)" if @per_page < 1
17
+
18
+ self.total_entries = total if total
19
+ end
20
+
21
+ def self.create(page, per_page, total = nil)
22
+ pager = new(page, per_page, total)
23
+ yield pager
24
+ pager
25
+ end
26
+
27
+ def out_of_bounds?
28
+ current_page > total_pages
29
+ end
30
+
31
+ def offset
32
+ (current_page - 1) * per_page
33
+ end
34
+
35
+ def previous_page
36
+ current_page > 1 ? (current_page - 1) : nil
37
+ end
38
+
39
+ def next_page
40
+ current_page < total_pages ? (current_page + 1) : nil
41
+ end
42
+
43
+ def total_entries=(number)
44
+ @total_entries = number.to_i
45
+ @total_pages = (@total_entries / per_page.to_f).ceil
46
+ end
47
+
48
+ def replace(array)
49
+ result = super
50
+
51
+ # The collection is shorter then page limit? Rejoice, because
52
+ # then we know that we are on the last page!
53
+ if total_entries.nil? and length < per_page and (current_page == 1 or length > 0)
54
+ self.total_entries = offset + length
55
+ end
56
+
57
+ result
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,116 @@
1
+ module Paginate
2
+ module Finder
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ class << base
7
+ # alias_method_chain :method_missing, :paginate
8
+ # # alias_method_chain :find_every, :paginate
9
+ define_method(:per_page) { 30 } unless respond_to?(:per_page)
10
+ end
11
+ end
12
+
13
+ module ClassMethods
14
+
15
+ def paginate(*args)
16
+ options = args.pop
17
+ page, per_page, total_entries = paginate_parse_options(options)
18
+
19
+ finder = (options[:finder] || 'find').to_s
20
+
21
+ if finder == 'find'
22
+ # an array of IDs may have been given:
23
+ total_entries ||= (Array === args.first and args.first.size)
24
+ # :all is implicit
25
+ args.unshift(:all) if args.empty?
26
+ end
27
+
28
+ Paginate::Collection.create(page, per_page, total_entries) do |pager|
29
+ count_options = options.except :page, :per_page, :total_entries, :finder
30
+ find_options = count_options.except(:count).update(:offset => pager.offset, :limit => pager.per_page)
31
+
32
+ args << find_options
33
+ # @options_from_last_find = nil
34
+ pager.replace(send(finder, *args) { |*a| yield(*a) if block_given? })
35
+
36
+ # magic counting for user convenience:
37
+ pager.total_entries = paginate_count(count_options, args, finder) unless pager.total_entries
38
+ end
39
+
40
+
41
+ end
42
+
43
+ def paginate_parse_options(options)
44
+ raise ArgumentError, 'parameter hash expected' unless options.respond_to? :symbolize_keys
45
+ options = options.symbolize_keys
46
+ raise ArgumentError, ':page parameter required' unless options.key? :page
47
+
48
+ if options[:count] and options[:total_entries]
49
+ raise ArgumentError, ':count and :total_entries are mutually exclusive'
50
+ end
51
+
52
+ page = options[:page] || 1
53
+ per_page = options[:per_page] || self.per_page
54
+ total = options[:total_entries]
55
+ [page, per_page, total]
56
+ end
57
+
58
+ # Does the not-so-trivial job of finding out the total number of entries
59
+ # in the database. It relies on the ActiveRecord +count+ method.
60
+ def paginate_count(options, args, finder)
61
+ excludees = [:count, :order, :limit, :offset, :readonly]
62
+ excludees << :from unless ActiveRecord::Calculations::CALCULATIONS_OPTIONS.include?(:from)
63
+
64
+ # we may be in a model or an association proxy
65
+ klass = (@owner and @reflection) ? @reflection.klass : self
66
+
67
+ # Use :select from scope if it isn't already present.
68
+ options[:select] = scope(:find, :select) unless options[:select]
69
+
70
+ if options[:select] and options[:select] =~ /^\s*DISTINCT\b/i
71
+ # Remove quoting and check for table_name.*-like statement.
72
+ if options[:select].gsub('`', '') =~ /\w+\.\*/
73
+ options[:select] = "DISTINCT #{klass.table_name}.#{klass.primary_key}"
74
+ end
75
+ else
76
+ excludees << :select # only exclude the select param if it doesn't begin with DISTINCT
77
+ end
78
+
79
+ # count expects (almost) the same options as find
80
+ count_options = options.except *excludees
81
+
82
+ # merge the hash found in :count
83
+ # this allows you to specify :select, :order, or anything else just for the count query
84
+ count_options.update options[:count] if options[:count]
85
+
86
+ # forget about includes if they are irrelevant (Rails 2.1)
87
+ # if count_options[:include] and
88
+ # klass.private_methods.include_method?(:references_eager_loaded_tables?) and
89
+ # !klass.send(:references_eager_loaded_tables?, count_options)
90
+ # count_options.delete :include
91
+ # end
92
+
93
+ # we may have to scope ...
94
+ counter = Proc.new { count(count_options) }
95
+
96
+ count = if finder.index('find_') == 0 and klass.respond_to?(scoper = finder.sub('find', 'with'))
97
+ # scope_out adds a 'with_finder' method which acts like with_scope, if it's present
98
+ # then execute the count with the scoping provided by the with_finder
99
+ send(scoper, &counter)
100
+ # elsif finder =~ /^find_(all_by|by)_([_a-zA-Z]\w*)$/
101
+ # # extract conditions from calls like "paginate_by_foo_and_bar"
102
+ # attribute_names = $2.split('_and_')
103
+ # conditions = construct_attributes_from_arguments(attribute_names, args)
104
+ # with_scope(:find => { :conditions => conditions }, &counter)
105
+ else
106
+ counter.call
107
+ end
108
+
109
+ count.respond_to?(:length) ? count.length : count
110
+ end
111
+
112
+
113
+ end # ClassMethods
114
+
115
+ end
116
+ end
@@ -0,0 +1,37 @@
1
+ module Paginate
2
+ module ViewHelpers
3
+ # default options that can be overridden on the global level
4
+ @@pagination_options = {
5
+ :class => 'pagination',
6
+ :previous_label => '&laquo; Previous',
7
+ :next_label => 'Next &raquo;',
8
+ :inner_window => 4, # links around the current page
9
+ :outer_window => 1, # links around beginning and end
10
+ :separator => ' ', # single space is friendly to spiders and non-graphic browsers
11
+ :param_name => :page,
12
+ :params => {},
13
+ :page_links => true,
14
+ :container => true,
15
+ :debug => false
16
+ }
17
+ mattr_reader :pagination_options
18
+
19
+ def paginate(collection, options={})
20
+ #Collection => :current_page, :per_page, :total_entries, :total_pages
21
+ opt = @@pagination_options
22
+ opt.update(options)
23
+ out=[]
24
+ if opt[:debug]
25
+ out.push("current_page:#{collection.current_page} / ")
26
+ out.push("per_page:#{collection.per_page} / ")
27
+ out.push("total_entries:#{collection.total_entries} / ")
28
+ out.push("total_pages:#{collection.total_pages} <br />")
29
+ end
30
+ out.push("<div class=\"pagination_container\">") if opt[:container]
31
+ out.push(link(opt[:previous_label], {:page=>collection.previous_page}.update(opt[:params]), {:class=>opt[:class]}) ) if collection.previous_page
32
+ out.push(link(opt[:next_label], {:page=>collection.next_page}.update(opt[:params]), {:class=>opt[:class]}) ) if collection.next_page
33
+ out.push("</div>") if opt[:container]
34
+ return out.join(opt[:separator])
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,32 @@
1
+ # = Doozer Paginate
2
+ # This code was lifted (i mean...ported) from the WillPaginate gem for ActiveRecord with a few modifications.
3
+ #
4
+ # Not supported by this plugin but in WillPAginate:
5
+ # * Page numbers between 'Previous' and 'Next' links
6
+ # * NamedScopes
7
+ #
8
+ # See http://wiki.github.com/mislav/will_paginate for more details on useage and license.
9
+ require "#{PAGINATE_PLUGIN_ROOT}/paginate/collection"
10
+ module Paginate
11
+ class << self
12
+ def enable_activerecord
13
+ return if ActiveRecord::Base.respond_to? :paginate
14
+ require "#{PAGINATE_PLUGIN_ROOT}/paginate/finder"
15
+ ActiveRecord::Base.send :include, Paginate::Finder
16
+ end
17
+ def enable_view_helpers
18
+ # return if Doozer::Initializer.respond_to? :paginate
19
+ require "#{PAGINATE_PLUGIN_ROOT}/paginate/view_helpers"
20
+ Doozer::Controller.send :include, Paginate::ViewHelpers
21
+ Doozer::Partial.send :include, Paginate::ViewHelpers
22
+ end
23
+ end
24
+ end
25
+
26
+ # Enable ActiveRecord if it's defined
27
+ Paginate.enable_activerecord if defined? ActiveRecord
28
+
29
+ # Load the View Helpers if Doozer::Initializer is loaded
30
+ Doozer::Initializer.before_rackup do | config |
31
+ Paginate.enable_view_helpers
32
+ end if defined? Doozer::Initializer
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'doozer'
4
+
5
+ #--load initializers
6
+ # require 'doozer/initializer'
7
+
8
+ #--boot it up
9
+ Doozer::Initializer.boot(env)
10
+
11
+ #--hookup the logger for production only since the base rackup builder doesn't load it. this avoids double logging in development
12
+ use Rack::CommonLogger, Doozer::Configs.logger if Doozer::Configs.rack_env == :deployment
13
+
14
+ #--map root to doozer
15
+ map "/" do
16
+ # use Rack::ShowExceptions
17
+ if Doozer::Configs.rack_env != :deployment
18
+ use Rack::Reloader, secs=1
19
+ end
20
+
21
+ use Rack::Static, {:urls => Doozer::Configs.app["static_urls"], :root => "#{Dir.pwd}/#{Doozer::Configs.app["static_root"]}"} if Doozer::Configs.app
22
+
23
+ use Rack::Session::Cookie, :key => 'rack.session',
24
+ :domain => '',
25
+ :path => '/',
26
+ :expire_after => 2592000
27
+
28
+ run Doozer::App.new(args=options)
29
+ end
30
+
31
+ #--stack additional rack apps
32
+ begin
33
+ require "#{Dir.pwd}/config/rack"
34
+ stack()
35
+ rescue => e
36
+ Doozer::Configs.logger.error(e)
37
+ end
@@ -0,0 +1,19 @@
1
+ """
2
+ script to bootstrap the doozer/rackup/server.ru in test mode
3
+ since rackup doesn't call Rackup::Builder in test (in rackup this is 'none') mode
4
+
5
+ """
6
+ config = 'doozer/rackup/server.ru'
7
+ env = :test
8
+ cfgfile = File.read(config)
9
+ if cfgfile[/^#\\(.*)/]
10
+ opts.parse! $1.split(/\s+/)
11
+ end
12
+ ru=[]
13
+ ru.push("options = {:Port => 5000, :Host => '127.0.0.1', :AccessLog => []}")
14
+ ru.push("app = Rack::Builder.new do")
15
+ ru.push("use Rack::CommonLogger")
16
+ ru.push(cfgfile)
17
+ ru.push("end.to_app")
18
+ ru.push("Rack::Handler::Mongrel.run app, :Port => 5000")
19
+ app = eval "Rack::Builder.new {( " + ru.join("\n") + "\n )}.to_app", nil, config
@@ -0,0 +1,12 @@
1
+ module Doozer
2
+ class Redirect < Exception
3
+ attr_accessor :url
4
+ attr_reader :status
5
+
6
+ def initialize(url, opts={})
7
+ super "redirect"
8
+ @url=(url=="") ? "/" : url
9
+ @status = (opts[:status]) ? opts[:status] : nil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,264 @@
1
+ require 'doozer/app'
2
+
3
+ module Doozer
4
+ module Routing
5
+ class Routes
6
+ @@parts=[] # stored as [route.name, route.path]
7
+ @@dict={} # route hash
8
+ @@cache={} # lookup for matches
9
+ @@magics=[] # hold raw magic routes before processing
10
+ @@inner_apps={} # holds the app dedicated to processing this path
11
+
12
+ def self.draw(&block)
13
+ # p "draw routes"
14
+ instance_eval(&block) if block_given?
15
+
16
+ # init magic routes :conrtoller/:action or just /:action with predefined :controller
17
+ # Routes.init_magic_routes
18
+
19
+ # sort routes here
20
+ @@parts.sort! do |a, b| a[1].length <=> b[1].length end
21
+ @@parts.reverse!
22
+ p "Routes drawn and sorted..."
23
+ # @@parts.each { | i | p i[1] }
24
+ end
25
+ def self.add(name=nil, path=nil, args=nil)
26
+ # p name
27
+ # p path
28
+ # p args.inspect
29
+ if not name.nil? and not path.nil? and not args.nil?
30
+ args = Routes::init_formats(args)
31
+ formats = args[:formats]
32
+ # p formats.inspect
33
+ for format in formats
34
+ args.delete(:formats)
35
+ if name != :magic
36
+ parts = [name, path, args]
37
+ # p parts.inspect
38
+ args[:format] = format
39
+ route = Doozer::Routing::Route.new(parts)
40
+ # p route.inspect
41
+ @@parts.push([route.name, route.path])
42
+ @@dict[route.name] = route
43
+ else
44
+ p "magic routes init turned off"
45
+ # Routes.magic(parts)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def self.init_formats(args)
52
+ formats = args[:formats]
53
+ formats = [] if formats.nil?
54
+ formats.push(:html) if not formats.include?(:html)
55
+ args[:formats] = formats
56
+ return args
57
+ end
58
+
59
+ def self.get_by_name(name)
60
+ # p @@dict.inspect
61
+ return @@dict[name]
62
+ end
63
+
64
+ def self.match(path)
65
+ # p path
66
+ # p @@cache.inspect
67
+ # return @@dict[@@cache[path]] if @@cache[path]
68
+ for part in @@parts
69
+ route = @@dict[part[0]]
70
+ # p route.inspect
71
+ if route.match(path)
72
+ # Routes.cache_request_path(route, path)
73
+ return route
74
+ end
75
+ end
76
+ return nil
77
+ end
78
+
79
+ def self.cache_request_path(route,path)
80
+ # p "route cache request path"
81
+ @@cache[path] = route.name
82
+ end
83
+
84
+ def self.magic(route)
85
+ @@magics.push(route)
86
+ end
87
+
88
+ def self.init_magic_routes
89
+ @@controllers={}
90
+ controller_files = Dir.glob(File.join(File.dirname(__FILE__),'../app/controllers/*_controller.rb'))
91
+
92
+ if controller_files.length > 0
93
+ i=0
94
+ for f in controller_files
95
+ break if i==0 and f.index('application_controller.rb')
96
+ if f.index('application_controller.rb')
97
+ controller_files.insert(0, controller_files.delete(f))
98
+ break
99
+ end
100
+ i+=1
101
+ end
102
+ end
103
+
104
+ controller_files.each {|f|
105
+ require f
106
+ key = f.split("controllers/")[1].split("_controller.rb")[0]
107
+ if key.index("_")
108
+ value = key.split('_').each{ | k | k.capitalize! }.join('')
109
+ else
110
+ value = key.capitalize
111
+ end
112
+ @@controllers[key.to_sym] = "#{value}Controller"
113
+ # p "cache controller: #{key.to_sym}"
114
+ }
115
+ # p @@controllers.inspect
116
+ # grab all controllers
117
+ routes = []
118
+ dup_lu = {}
119
+ obj = Doozer::Controller
120
+ obj.public_instance_methods.each { | name | dup_lu[name]=''}
121
+ # p dup_lu.inspect
122
+
123
+ @@magics.each { | route |
124
+ path = route[1]
125
+ if path.index(':controller') and path.index(':action')
126
+ ## loop all controller and then loop all #methods
127
+ @@controllers.each{ |key,value |
128
+ klass = Object.const_get(value)
129
+ methods = klass.public_instance_methods()
130
+ methods.push('index')
131
+ methods.uniq! # filter duplicate indexes
132
+ methods.each { | val |
133
+ if dup_lu[val].nil?
134
+ controller= route[2][:controller] || key.to_s
135
+ action = route[2][:action] || val
136
+ # p "#{controller}##{action}"
137
+ name = "#{controller}_#{action}".to_sym
138
+ new_path = path.gsub(/:controller/, controller).gsub(/:action/,action)
139
+ new_path = new_path.gsub(/\/index/) if new_path.endswith('/index')
140
+ new_path = "/#{new_path}" if not new_path =~ /^\//
141
+ add([name, new_path, {:controller=>controller, :action=>action, :status=>200, :formats=>route[2][:formats]}])
142
+ end
143
+ }
144
+ }
145
+ elsif path.index(':action') and not route[2][:controller].nil?
146
+ ## loop all methods on this controller
147
+ #p "load route controller:" + @@controllers[route[2][:controller].to_sym].inspect
148
+ controller= route[2][:controller]
149
+
150
+ klass = Object.const_get(@@controllers[controller.to_sym])
151
+ methods = klass.public_instance_methods()
152
+ methods.push('index')
153
+ methods.uniq! # filter duplicate indexes
154
+ methods.each { | val |
155
+ if dup_lu[val].nil?
156
+ action = val
157
+ # p "#{controller}##{action}"
158
+ name = "#{controller}_#{action}".to_sym
159
+ new_path = path.gsub(/:action/,action)
160
+ new_path = new_path.gsub(/\/index/,'') if new_path =~ /\/index/
161
+ new_path = "/#{new_path}" if not new_path =~ /^\//
162
+
163
+ # p [name, new_path, {:controller=>controller, :action=>action, :status=>200}].inspect
164
+ add([name, new_path, {:controller=>controller, :action=>action, :status=>200, :formats=>route[2][:formats]}])
165
+ end
166
+ }
167
+ end
168
+ }
169
+
170
+ ## make sure to route index to '/'
171
+ ## loop route/methods pairs
172
+ # save new path for action controller
173
+ end
174
+ end
175
+
176
+ class Route
177
+ attr_accessor :name, :path, :controller, :action,
178
+ :layout, :status, :content_type, :tokens,
179
+ :grouping, :app, :format, :view, :view_path
180
+ def initialize(route)
181
+ #p "Doozer::Route#new: #{route}"
182
+ args = route[2]
183
+ @controller = args[:controller]
184
+ @action = args[:action]
185
+ @layout = (args[:layout]) ? args[:layout] : 'default'
186
+ @status = (args[:status]) ? args[:status] : 200
187
+ @app=args[:app]
188
+ @format = (args[:format]) ? args[:format] : :html
189
+ #@content_type = (args[:content_type]) ? args[:content_type] : 'text/html'
190
+ case @format
191
+ when :js
192
+ content_type = 'text/javascript'
193
+ when :xml
194
+ content_type = 'text/xml'
195
+ when :json
196
+ content_type = 'application/json'
197
+ when :rss
198
+ content_type = 'application/rss+xml'
199
+ when :atom
200
+ content_type = 'application/atom+xml'
201
+ else
202
+ content_type = 'text/html'
203
+ end
204
+ @content_type = content_type
205
+ @tokens = []
206
+ path = route[1]
207
+ path = '/' if path == ''
208
+ @path = (@format == :html) ? path : "#{path}.#{format}"
209
+ @name = (@format == :html) ? route[0] : "#{route[0]}_#{format.to_s}".to_sym
210
+ @layout = :none if @format != :html and @layout == 'default'
211
+
212
+ @view = "#{@action}_#{@format.to_s}"
213
+ @view_path = "#{@controller}/#{@action}.#{@format.to_s}.erb"
214
+ regify()
215
+ end
216
+
217
+ def regify
218
+ if (@path.index('/'))
219
+ grouping = []
220
+ url = @path.split('/')
221
+ for part in url
222
+ if /^:/.match(part)
223
+ token = part.gsub(/:/,'')
224
+ # part = '(?P<'+token+'>.)'
225
+ # part = '(\.*)'
226
+ # part = '(\w*)'
227
+ part = '([a-zA-Z0-9,-.%]*)' # this picks up all allowable route tokens (a-zA-Z0-9,-.%)
228
+ @tokens.push(token)
229
+ end
230
+ grouping.push(part)
231
+ end
232
+ out = "^#{grouping.join('/')}"
233
+ @grouping = Regexp.compile(out)
234
+ else
235
+ #handle default index route
236
+ @grouping = Regexp.compile("/")
237
+ end
238
+ end
239
+
240
+ def match(path)
241
+ # p "#{path} vs #{@path}"
242
+ # p path =~ @grouping
243
+ #short-circut for root
244
+ return false if path == '/' and @path != '/' #handles root condition
245
+ pass=(path =~ @grouping) == 0 ? true : false
246
+ # p @tokens.inspect if pass
247
+ if @tokens.empty?; pass=false if @path != path; end #handles root condition '/'
248
+ pass=false if path.split('/').length != @path.split('/').length #handles the root condition /:token
249
+ return pass
250
+ end
251
+
252
+ def extra_params(path)
253
+ hashish = {}
254
+ params = @grouping.match(path)
255
+ i = 1
256
+ for token in @tokens
257
+ hashish[token.to_sym] = params[i]
258
+ i += 1
259
+ end
260
+ return hashish
261
+ end
262
+ end
263
+ end
264
+ end