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,335 @@
1
+ # load gems
2
+ %w(rack erb).each { |dep| require dep }
3
+
4
+ # load doozer modules
5
+ # %w(doozer/lib doozer/extend doozer/logger doozer/view_helpers doozer/route doozer/partial).each { |dep| require dep }
6
+
7
+ # autoload all models
8
+ # Dir.glob(File.join(File.dirname(__FILE__),'../app/models/*.rb')).each {|f| require f }
9
+
10
+ module Doozer
11
+
12
+ # This is the main Controller class which is inherited by application controllers.
13
+ #
14
+ # Controllers have access to all ViewHelpers.
15
+ class Controller
16
+
17
+ # @route variable containing the route instance
18
+ attr_accessor :route
19
+ # @env variable passed from the Rack request
20
+ attr_accessor :env
21
+ # @request variable. See Rack request for additional methods. http://rack.rubyforge.org/doc/Rack/Request.html
22
+ attr_accessor :request
23
+ # @params variable which is a symbolized hash of all querystring values
24
+ attr_accessor :params
25
+ # @flash variable containing a hash of strings which are persisted in the flash cookie across the response, next request/response and then removed.
26
+ attr_accessor :flash
27
+ # @session variable containing a hash of strings which are persisted in the session cookie until the browser session expires.
28
+ attr_accessor :session
29
+ # @view variable containing a hash of string which are read from layouts.
30
+ attr_accessor :view
31
+ # @bust_key variable which is appended to img sources and script sources via view_helpers in development mode
32
+ attr_accessor :bust_key
33
+ # @format variable which is a symbol
34
+ attr_accessor :format
35
+ # @port variable holing the port number of the appserver handling the request
36
+ attr_accessor :port
37
+ # @render_args variable containing a hash of values to use while rendering the request
38
+ attr_accessor :render_args
39
+
40
+ include Doozer::Util::Logger
41
+ include Doozer::ViewHelpers
42
+
43
+ self.class_inheritable_accessor :after_initialize_exclude, :before_filter_exclude, :after_filter_exclude, :require_view_helpers
44
+
45
+ # Array of actions to exclude from calling after_initialize.
46
+ #
47
+ # Example: self.after_initialize_exclude=[:action_1, :action_2]
48
+ self.after_initialize_exclude=[]
49
+
50
+ # Array of actions to exclude from calling before_filter.
51
+ #
52
+ # Example: self.before_filter_exclude=[:action_1, :action_2]
53
+ self.before_filter_exclude=[]
54
+
55
+ # Array of actions to exclude from calling after_filter.
56
+ #
57
+ # Example: self.after_filter_exclude=[:action_1, :action_2]
58
+ self.after_filter_exclude=[]
59
+
60
+ # Array of actions to exclude from calling require_view.
61
+ #
62
+ # Example: self.require_view_helpers=[:application, :helper_1]
63
+ self.require_view_helpers=[]
64
+
65
+ # When a Controller is intialized it expects the following args:
66
+ #
67
+ # args={
68
+ # :route=>route matched against the request path,
69
+ # :extra_params=>the route tokens parameterized as a hash,
70
+ # :port=>the port of the appserver responding to the request
71
+ # }
72
+ #
73
+ # * :extra_params are turned into instance variables so you can access them directly from controller methods and views. In order to keep a small footprint these aren't passed into partial classes.
74
+ #
75
+ # Example: A route of /admin/post/:id and a request path of /admin/post/8 automatically exposes an instance variable of @id with a value of 8 in your controller.
76
+ #
77
+ # * query params are accessible via @params hash and are parameterized via Rack.
78
+
79
+ def initialize(args={})
80
+ @route = args[:route]; @env = args[:env]
81
+ @format = @route.format
82
+ @port = args[:port]
83
+
84
+ #init request from env
85
+ @request = Rack::Request.new(@env)
86
+
87
+ #holds all variables for template binding
88
+ @view={}; @view[:meta]={}
89
+
90
+ #store flash
91
+ @flash={}; flash_from_cookie()
92
+
93
+ #store session
94
+ @session={}; session_from_cookie()
95
+
96
+ #symbolize params
97
+ @params={}; @request.params.each { |key, value| @params[key.to_sym] = value}
98
+
99
+ #set bust key
100
+ @bust_key = (rand(1000) * 1024)
101
+
102
+ # set up default render_args
103
+ @render_args = {:layout=>nil, :view=>nil, :text=>nil}
104
+ render_args_init()
105
+
106
+ #turn extra params into instance variables...
107
+ args[:extra_params].each { |key, value| self.instance_variable_set("@#{key}".to_sym, value)}
108
+ logger.info(" Params: #{@request.params.inspect}") if not @request.params.nil?
109
+ logger.info(" Extra params: #{args[:extra_params].inspect}") if not args[:extra_params].nil?
110
+ end
111
+
112
+ # Renders an action with any of the following overridable parameters:
113
+ #
114
+ # args={
115
+ # :view=>Symbol, String or ERB,
116
+ # :layout=>Symbol,
117
+ # :text=>'this is the text to render'
118
+ # }
119
+ #
120
+ # :view - All actions default to a view of views/controller_name/action_name.format.erb which is originated from the route properties.
121
+ #
122
+ # To override this from controller actions, you can pass any of the following:
123
+ #
124
+ # * :view=>:view_name
125
+ #
126
+ # This assumes the view is in the same controller as the present action.
127
+ #
128
+ # * :view=>'controller_name/action_name'
129
+ #
130
+ # This renders a view from a the provided controller and action and with the format specified in the route.
131
+ #
132
+ # * :view=>ERB.new('<%=var%> is nice')
133
+ #
134
+ # :layout - All actions default to a layout of views/layouts/default.format.erb
135
+ #
136
+ # To override this from controller actions, you can pass any of the following:
137
+ #
138
+ # * :layout=>:layout_name_format or :none (don't display a layout at all)
139
+ #
140
+ # There is no need to specify the format for :html formats.
141
+ #
142
+ # Example: :layout=>:some_layout (where format equals :html) or :some_layout_json (where format equals :json)
143
+ #
144
+ # :text - Overrides all view rendering options and displays an ERB template with the provided text string.
145
+ #
146
+ # A layout is rendered unless its overriden or the route was declared without one.
147
+ #
148
+ # To override this from controller actions, you can pass any of the following:
149
+ def render(args={})
150
+ change_layout(args[:layout]) if args[:layout]
151
+ change_view(args[:view]) if args[:view]
152
+ change_view(ERB.new(args[:text])) if args[:text]
153
+
154
+ end
155
+
156
+ # This method is called from the appserver controller handler.
157
+ def render_result
158
+ layout = @render_args[:layout]
159
+ view = @render_args[:view]
160
+ if layout.kind_of? Symbol # this handles the layout(:none)
161
+ view.result(binding)
162
+ else
163
+ @view[:timestamp] = "<!-- server: #{@port} / rendered: #{Time.now()} / env: #{rack_env} -->"
164
+ @view[:body] = view.result(binding)
165
+ # layout = @layout if layout.nil? # this handles the layout(:some_other_layout) case for formats
166
+ layout.result(binding)
167
+ end
168
+ end
169
+
170
+ # A method to render a partial from a controller. Expects a file name and optional local variables. See Partial for more details.
171
+ #
172
+ # By default, the @request variable is appended to locals and available in the partial view.
173
+ def partial(file=nil, locals={})
174
+ # self.instance_variables.each { | k |
175
+ # locals[k.gsub(/@/,'').to_s] = eval(k)
176
+ # }
177
+ # p locals.inspect
178
+ locals[:request] = @request
179
+ Doozer::Partial.partial(file, locals, route=@route)
180
+ end
181
+
182
+ # Redirect the response object to the tokenized route url with optional query string values
183
+ #
184
+ # The route is passed through the ViewHelpers.url method. See url() for examples.
185
+ def redirect_to(route={}, opts={})
186
+ path = url(route)
187
+ # p "Redirect to: #{path}"
188
+ raise Doozer::Redirect.new(path, opts)
189
+ end
190
+
191
+ # Sequel ORM db connection
192
+ def db
193
+ Doozer::Configs.db_conn
194
+ end
195
+
196
+ # Compile flash keys as name=value array which are stored in the flash cookie. The flash variables are only persisted for one response.
197
+ def flash_to_cookie
198
+ #loop over all flash messages and return as name/value array
199
+ out=[]; @flash.each { |key, value| out.push("#{key}=#{CGI::escape(value.to_s)}") }
200
+ return out
201
+ end
202
+
203
+ # Read all the flash cookies and store them in the @flash instance variable
204
+ def flash_from_cookie
205
+ #split name/value pairs and merge with flash
206
+ if @request.cookies
207
+ if @request.cookies["flash"]
208
+ pairs=@request.cookies["flash"].split('&')
209
+ pairs.each{|pair|
210
+ pair = pair.split('=')
211
+ @flash[pair[0].to_sym]=CGI::unescape(pair[1])
212
+ }
213
+ end
214
+ end
215
+ end
216
+
217
+ # Compile session keys as name=value array which are eventually stored as cookies.
218
+ def session_to_cookie
219
+ #loop over all flash messages and return as name/value array
220
+ out=[]; @session.each { |key, value| out.push("#{key}=#{CGI::escape(value.to_s)}") }
221
+ return out
222
+ end
223
+
224
+ # Read all the session cookies and store them in the @session instance variable
225
+ def session_from_cookie
226
+ #split name/value pairs and merge with flash
227
+ if @request.cookies
228
+ if @request.cookies["session"]
229
+ pairs=@request.cookies["session"].split('&')
230
+ pairs.each{|pair|
231
+ pair = pair.split('=')
232
+ @session[pair[0].to_sym]=CGI::unescape(pair[1])
233
+ }
234
+ end
235
+ end
236
+ end
237
+
238
+ # Method for setting metatags via Controllers.
239
+ #
240
+ # Pass an options hash to meta and all the keys are turned into metatags with the corresponding values.
241
+ #
242
+ # Example: meta({:description=>'The awesome metatag description is awesome', :keywords=>'awesome, blog, of awesomeness'})
243
+ def meta(opt={})
244
+ @view[:meta]=opt
245
+ end
246
+
247
+ # DEPRECATED: use render() instead
248
+ def layout(sym)
249
+ raise "Deprecated: Controller#layout; Use render({:layout=>:symbol}) instead"
250
+ end
251
+
252
+ # Controller hook called after controller#initialize call.
253
+ #
254
+ # By default, this method automatically checks if the authtoken is present for post requests. It throws an error if it's missing or has been tampered with.
255
+ def after_initialize
256
+ # test if request == post and if so if authtoken is present and valid
257
+ if @request.post?
258
+ token=@params[:_authtoken]
259
+ if token
260
+ raise "Doozer Authtoken Tampered With!" if not authtoken_matches?(token)
261
+ else
262
+ raise "Doozer Authtoken Missing! By default, post requests require an authtoken. You can override this by adding the action to the after_initialize_exclude list." if not authtoken_matches?(token)
263
+ end
264
+ end
265
+ end
266
+
267
+ # Controller hook called before controller#method call
268
+ def before_filter; end
269
+
270
+ # Controller hook called after controller#method call
271
+ def after_filter; end
272
+
273
+ # Include additional view helpers declared for the class.
274
+ #
275
+ # This method automatically appends '_helper' to each required helper symbol
276
+ def self.include_view_helpers
277
+ # importing view helpers into controller
278
+ self.require_view_helpers.each { | sym |
279
+ self.include_view_helper("#{sym.to_s}_helper")
280
+ }
281
+ end
282
+
283
+ # Include the app/helpers file_name. Expects helper as a string.
284
+ #
285
+ # You must pass the full file name if you use this method.
286
+ #
287
+ # Example: self.include_view_helper('application_helper')
288
+ def self.include_view_helper(helper)
289
+ # importing view helpers into controller
290
+ include Object.const_get(Doozer::Lib.classify("#{helper}"))
291
+ end
292
+
293
+ private
294
+ def render_args_init
295
+ if not [301, 302].include?(@route.status)
296
+ # view = (@format == :html) ? "#{@route.name.to_s}_html".to_sym : @route.
297
+ view = @route.view.to_sym
298
+ layout = (@route.layout.kind_of? String) ? @route.layout.to_sym : @route.layout
299
+ render({
300
+ :view=>view,
301
+ :layout=>layout
302
+ })
303
+ end
304
+ end
305
+
306
+ def change_layout(sym)
307
+ if sym == :none
308
+ layout=sym
309
+ else
310
+ #this needs to look up the layout and reset layout to this erb template
311
+ lay = Doozer::App.layouts[sym]
312
+ raise "Can't find layout for #{sym}" if lay.nil?
313
+ layout = lay
314
+ end
315
+ @render_args[:layout] = layout
316
+ end
317
+
318
+ def change_view(args)
319
+ if args.kind_of? Symbol
320
+ # implies we're using the same controller as the current controller with a view name of :view_name
321
+ view = Doozer::App.views[@route.controller.to_sym][args]
322
+ elsif args.kind_of? String
323
+ # implies
324
+ controller = (args.index('/')) ? args.split('/')[0].to_sym : @route.controller.to_sym
325
+ action = (args.index('/')) ? args.split('/')[1] : args
326
+ action = "#{action}_#{@format.to_s}".to_sym
327
+ view = Doozer::App.views[controller][action]
328
+ elsif args.kind_of? ERB
329
+ view = args
330
+ end
331
+ view = ERB.new("Missing view for controller#action") if view.nil?
332
+ @render_args[:view] = view
333
+ end
334
+ end
335
+ end
@@ -0,0 +1,10 @@
1
+ #
2
+ # Load some of the rails active_support/core_ext class extensions which are used by Doozer.
3
+ # All of these are automtically loaded if active_record is used but we need to provide them incase
4
+ #
5
+ require 'doozer/active_support/array'
6
+ require 'doozer/active_support/object'
7
+ require 'doozer/active_support/class'
8
+ require 'doozer/active_support/time'
9
+ require 'doozer/active_support/date_time'
10
+
@@ -0,0 +1,95 @@
1
+ module Doozer
2
+
3
+ # This is the main class which facilitates booting Doozer components and hooks.
4
+ #
5
+ # Calling boot initializes Doozer in the following order:
6
+ # 1. Doozer::Configs
7
+ # 2. require ORM
8
+ # 3. require root/config/environment.rb
9
+ # 4. call after_orm_init
10
+ # 5. require Doozer::App
11
+ # 6. call before_rackup_init
12
+ class Initializer
13
+ @@after_orm = []
14
+ @@before_rackup = []
15
+
16
+ # env - :development, :deployment, or :test
17
+ def self.boot(env)
18
+ #--load configs
19
+ require 'doozer/configs'
20
+ Doozer::Configs.load(env)
21
+
22
+ #--load orm
23
+ Doozer::Initializer.orm
24
+
25
+ #--load environment hooks
26
+ Doozer::Initializer.environment
27
+
28
+ #--call the after_orm_init features
29
+ Doozer::Initializer.after_orm_init
30
+
31
+ #--load app
32
+ require 'doozer/app'
33
+
34
+ #--call the before_rackup_init features
35
+ Doozer::Initializer.before_rackup_init
36
+ end
37
+
38
+ # Checks to see if an ORM gem (active_record, data_mapper, or sequel) is specified in database.yml and loads it.
39
+ def self.orm
40
+ begin
41
+ # load orm layer (if required)
42
+ if not Doozer::Configs.orm.nil? and not Doozer::Configs.db.nil?
43
+ require "doozer/orm/#{Doozer::Configs.orm}"
44
+ Doozer::ORM.load
45
+ end
46
+ rescue => e
47
+ Doozer::Configs.logger.error(e)
48
+ end
49
+ end
50
+
51
+ # Requires the root/config/environment.rb hooks.
52
+ #
53
+ # This is where you can place your code to initialize additional plugins for models, extend ruby, or whatever else yor app requires.
54
+ #
55
+ #=== Example environment.rb
56
+ # Time::DATE_FORMATS[:month_and_year] = "%B %Y"
57
+ #
58
+ # Doozer::Initializer.after_orm do | config |
59
+ # p "Extending some ORM, yo!"
60
+ # end
61
+ #
62
+ # Doozer::Initializer.before_rackup do | config |
63
+ # p "Before rackup, horray for rackup!"
64
+ # end
65
+ def self.environment
66
+ begin
67
+ require "#{Dir.pwd}/config/environment"
68
+ rescue => e
69
+ Doozer::Configs.logger.error(e)
70
+ end
71
+ end
72
+
73
+ # Primary hook for extending/overriding ORM. Code block is pushed onto an array which allows for multiple hooks throughtout different files.
74
+ #
75
+ # &block - code to execute after ORM is intialized
76
+ def self.after_orm(&block)
77
+ @@after_orm.push(block) if block_given?
78
+ end
79
+
80
+ # Primary hook for adding/overriding Doozer::ViewHelpers methods. Code block is pushed onto an array which allows for multiple hooks throughtout different files.
81
+ #
82
+ # &block - code to execute after prior to Doozer.App.new being intialized.
83
+ def self.before_rackup(&block)
84
+ @@before_rackup.push(block) if block_given?
85
+ end
86
+
87
+ private
88
+ def self.after_orm_init
89
+ @@after_orm.each{ | block | instance_eval(&block)}
90
+ end
91
+ def self.before_rackup_init
92
+ @@before_rackup.each{ | block | instance_eval(&block)}
93
+ end
94
+ end
95
+ end
data/lib/doozer/lib.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Doozer
2
+ class Lib
3
+
4
+ #Return a ClassName as string from an underscored string.
5
+ # example: input "example_class" > "ExampleClass"
6
+ def self.classify(klass)
7
+ if klass.index('_')
8
+ klass = klass.split('_')
9
+ parts = []
10
+ klass = klass.each { | part |
11
+ parts.push(part.capitalize)
12
+ }
13
+ klass = parts.join('')
14
+ else
15
+ klass.capitalize!
16
+ end
17
+ end
18
+
19
+ #Returns a one-level deep folder/file structure and preservers underscores for filename.
20
+ # example: input "folder_some_file_name" > "folder/some_file_name"
21
+ def self.pathify_first(s)
22
+ if s.index('_')
23
+ parts = s.split('_')
24
+ folder = parts[0]
25
+ file = parts.slice(1, parts.length).join('_')
26
+ s = "#{folder}/#{file}"
27
+ end
28
+ s
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ module Doozer
2
+ module Util
3
+ module Logger
4
+
5
+ def logger
6
+ Doozer::Configs.logger
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'active_record'
2
+ module Doozer
3
+ module ORM
4
+ def self.load
5
+ db_config = Doozer::Configs.db()
6
+ # ActiveRecord::Base.allow_concurrency = true
7
+ ActiveRecord::Base.establish_connection(
8
+ :adapter => db_config["adapter"],
9
+ :host => db_config["host"],
10
+ :username => db_config["username"],
11
+ :password => db_config["password"],
12
+ :database => db_config["database"]
13
+ )
14
+ p "ORM: #{Doozer::Configs.orm()} initialized..."
15
+ p "ORM: logging initialized"
16
+ ActiveRecord::Base.logger = Doozer::Configs.logger
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'dm-core'
2
+ module Doozer
3
+
4
+ # See for more info => http://datamapper.org/doku.php?id=getting_started_with_datamapper
5
+ module ORM
6
+ def self.load
7
+ db_config = Doozer::Configs.db()
8
+ DataMapper.setup(:default, {
9
+ :adapter => db_config["adapter"],
10
+ :database => db_config["database"],
11
+ :username => db_config["username"],
12
+ :password => db_config["password"],
13
+ :host => db_config["host"]
14
+ })
15
+ p "ORM: #{Doozer::Configs.orm()} initialized..."
16
+ DataMapper::Logger.new(STDOUT, :debug)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ require 'sequel'
2
+ module Doozer
3
+ module ORM
4
+
5
+ # See for details => http://sequel.rubyforge.org/rdoc/index.html
6
+ def self.load
7
+ db_config = Doozer::Configs.db()
8
+ Doozer::Configs.db_conn = Sequel.connect({
9
+ :adapter => db_config["adapter"],
10
+ :database => db_config["database"],
11
+ :username => db_config["username"],
12
+ :password => db_config["password"],
13
+ :host => db_config["host"]
14
+ })
15
+ p "ORM: #{Doozer::Configs.orm} initialized..."
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,99 @@
1
+ require "erb"
2
+ require "doozer/lib"
3
+ require "doozer/view_helpers"
4
+
5
+ module Doozer
6
+
7
+ # This class facilitates loading and rendering of partials.
8
+ #
9
+ # A partial is an ERB template which starts with an underscore. They behave the same as action view ERB template with the only difference of not having access to Controller instance variables.
10
+ #
11
+ # An example partial: app/views/controller_name/_partial.html.erb
12
+ #
13
+ # By default, the Doozer scaffold creates an app/views/global folder which can be used to place global partials like headers, footers, etc.
14
+ #
15
+ # Partials have access to Doozer::ViewHelpers.
16
+ #
17
+ # All view helpers in app/helpers are automatically included in the Partial class during app initialize.
18
+ #
19
+ # A partial can render another partial and so on and so on.
20
+ class Partial
21
+ attr_accessor :erb, :route
22
+
23
+ include ERB::Util
24
+ include Doozer::Util::Logger
25
+ include Doozer::ViewHelpers
26
+
27
+ APP_PATH = Dir.pwd
28
+ @@partials={}
29
+
30
+ def initialize(erb, locals, route)
31
+ @erb = erb
32
+ @route = route
33
+ if locals.kind_of? Hash
34
+ locals.each_pair {|key, value|
35
+ #p "#{key}:#{value}"
36
+ self.instance_variable_set("@#{key}".to_sym, value) # :@a, value
37
+ }
38
+ end
39
+ end
40
+
41
+ def bind
42
+ @erb.result(binding)
43
+ end
44
+
45
+ # This class method lazily loads and caches the erb templates of the requested partials
46
+ def self.partial(file=nil, locals={}, route=route)
47
+ #p "Class method: Doozer::Partial#partial"
48
+ if file.index("/").nil?
49
+ name = "#{route.controller}/_#{file}"
50
+ else
51
+ name = "#{file.gsub(/\//,'/_')}"
52
+ end
53
+ load_partial(name) if @@partials[name].nil?
54
+ erb = @@partials[name]
55
+ if erb
56
+ partial = Doozer::Partial.new(erb, locals, route)
57
+ partial.bind()
58
+ else
59
+ p "no partial exists for #{file}"
60
+ end
61
+ end
62
+
63
+ # Renders and returns a partial template with the given file_name and local variables.
64
+ #
65
+ # * file - expects a string. By default, if you don't pass a controller, it's assumed the lookup location is the current route.controller path in the views folder.
66
+ # You must omit the underscore when passing the file_name.
67
+ # A partial is automatically assumed to be html format. It shouldn't matter if you display an html partial inside a view with a different format.
68
+ #
69
+ # * locals - All local key/values are instantiated as instance variables acessable from the partial template. The controller.request variable is appended to locals and is also accessable as an instance variable from the partial template.
70
+ def partial(file=nil, locals={})
71
+ locals[:request] = @request if not @request.nil?
72
+ Doozer::Partial.partial(file, locals, route=@route)
73
+ end
74
+
75
+ # Load and cache partial ERB template with the given file_name.
76
+ def self.load_partial(name)
77
+ file = File.join(APP_PATH,"/app/views/#{name}.html.erb")
78
+ results = []
79
+ begin
80
+ File.new(file, "r").each { |line| results << line }
81
+ # TODO: throw error if doesn't exist
82
+ @@partials[name] = ERB.new(results.join(""))
83
+ rescue
84
+ p "sorry couldn't load partial #{name} (#{file})"
85
+ end
86
+ end
87
+
88
+ # Class methods for clearing all cached partials. Mainly a dispatcher for the file watcher to pick up new changes without having to restart the appserver in development mode.
89
+ def self.clear_loaded_partials
90
+ @@partials = {}
91
+ end
92
+
93
+ # Class method for including a view helper.
94
+ def self.include_view_helper(helper)
95
+ m = Doozer::Lib.classify(helper)
96
+ include Object.const_get(m)
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,2 @@
1
+ PAGINATE_PLUGIN_ROOT = File.join(File.dirname(__FILE__), 'lib')
2
+ require "#{PAGINATE_PLUGIN_ROOT}/paginate"