hobo 0.5.3

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 (125) hide show
  1. data/LICENSE.txt +22 -0
  2. data/README.txt +18 -0
  3. data/bin/hobo +81 -0
  4. data/hobo_files/plugin/CHANGES.txt +963 -0
  5. data/hobo_files/plugin/LICENSE.txt +22 -0
  6. data/hobo_files/plugin/README +4 -0
  7. data/hobo_files/plugin/Rakefile +11 -0
  8. data/hobo_files/plugin/generators/hobo/hobo_generator.rb +37 -0
  9. data/hobo_files/plugin/generators/hobo/templates/application.dryml +2 -0
  10. data/hobo_files/plugin/generators/hobo/templates/guest.rb +31 -0
  11. data/hobo_files/plugin/generators/hobo_front_controller/USAGE +11 -0
  12. data/hobo_files/plugin/generators/hobo_front_controller/hobo_front_controller_generator.rb +90 -0
  13. data/hobo_files/plugin/generators/hobo_front_controller/templates/controller.rb +51 -0
  14. data/hobo_files/plugin/generators/hobo_front_controller/templates/functional_test.rb +18 -0
  15. data/hobo_files/plugin/generators/hobo_front_controller/templates/helper.rb +2 -0
  16. data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +43 -0
  17. data/hobo_files/plugin/generators/hobo_front_controller/templates/login.dryml +44 -0
  18. data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +18 -0
  19. data/hobo_files/plugin/generators/hobo_front_controller/templates/signup.dryml +45 -0
  20. data/hobo_files/plugin/generators/hobo_model/USAGE +26 -0
  21. data/hobo_files/plugin/generators/hobo_model/hobo_model_generator.rb +38 -0
  22. data/hobo_files/plugin/generators/hobo_model/templates/fixtures.yml +11 -0
  23. data/hobo_files/plugin/generators/hobo_model/templates/migration.rb +13 -0
  24. data/hobo_files/plugin/generators/hobo_model/templates/model.rb +24 -0
  25. data/hobo_files/plugin/generators/hobo_model/templates/unit_test.rb +10 -0
  26. data/hobo_files/plugin/generators/hobo_model_controller/USAGE +30 -0
  27. data/hobo_files/plugin/generators/hobo_model_controller/hobo_model_controller_generator.rb +43 -0
  28. data/hobo_files/plugin/generators/hobo_model_controller/templates/controller.rb +5 -0
  29. data/hobo_files/plugin/generators/hobo_model_controller/templates/functional_test.rb +18 -0
  30. data/hobo_files/plugin/generators/hobo_model_controller/templates/helper.rb +2 -0
  31. data/hobo_files/plugin/generators/hobo_model_controller/templates/view.rhtml +2 -0
  32. data/hobo_files/plugin/generators/hobo_rapid/hobo_rapid_generator.rb +51 -0
  33. data/hobo_files/plugin/generators/hobo_rapid/templates/hobo_rapid.js +436 -0
  34. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/default_mapping.rb +11 -0
  35. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/banner.gif +0 -0
  36. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_bodytop.gif +0 -0
  37. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_01.gif +0 -0
  38. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_02.gif +0 -0
  39. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_03.gif +0 -0
  40. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_corner_04.gif +0 -0
  41. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_bottom.gif +0 -0
  42. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_left.gif +0 -0
  43. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_right.gif +0 -0
  44. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg_shadow_top.gif +0 -0
  45. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_blue.gif +0 -0
  46. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_dblue.gif +0 -0
  47. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_green.gif +0 -0
  48. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_purple.gif +0 -0
  49. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header_red.gif +0 -0
  50. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/logo.gif +0 -0
  51. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/spinner.gif +0 -0
  52. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_dblue.gif +0 -0
  53. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_green.gif +0 -0
  54. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_purple.gif +0 -0
  55. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt_list_img_red.gif +0 -0
  56. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_01.gif +0 -0
  57. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_02.gif +0 -0
  58. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_03.gif +0 -0
  59. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_corner_04.gif +0 -0
  60. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_bottom.gif +0 -0
  61. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_left.gif +0 -0
  62. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_right.gif +0 -0
  63. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window_shadow_top.gif +0 -0
  64. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +390 -0
  65. data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +104 -0
  66. data/hobo_files/plugin/generators/hobo_user_model/USAGE +26 -0
  67. data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +38 -0
  68. data/hobo_files/plugin/generators/hobo_user_model/templates/fixtures.yml +11 -0
  69. data/hobo_files/plugin/generators/hobo_user_model/templates/migration.rb +15 -0
  70. data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +58 -0
  71. data/hobo_files/plugin/generators/hobo_user_model/templates/unit_test.rb +10 -0
  72. data/hobo_files/plugin/init.rb +44 -0
  73. data/hobo_files/plugin/lib/action_view_extensions/base.rb +14 -0
  74. data/hobo_files/plugin/lib/active_record/has_many_association.rb +54 -0
  75. data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +22 -0
  76. data/hobo_files/plugin/lib/active_record/table_definition.rb +34 -0
  77. data/hobo_files/plugin/lib/extensions.rb +245 -0
  78. data/hobo_files/plugin/lib/extensions/test_case.rb +130 -0
  79. data/hobo_files/plugin/lib/hobo.rb +353 -0
  80. data/hobo_files/plugin/lib/hobo/HtmlString +3 -0
  81. data/hobo_files/plugin/lib/hobo/authenticated_user.rb +106 -0
  82. data/hobo_files/plugin/lib/hobo/authentication_support.rb +108 -0
  83. data/hobo_files/plugin/lib/hobo/composite_model.rb +66 -0
  84. data/hobo_files/plugin/lib/hobo/controller.rb +134 -0
  85. data/hobo_files/plugin/lib/hobo/controller_helpers.rb +135 -0
  86. data/hobo_files/plugin/lib/hobo/core.rb +475 -0
  87. data/hobo_files/plugin/lib/hobo/define_tags.rb +56 -0
  88. data/hobo_files/plugin/lib/hobo/dryml.rb +161 -0
  89. data/hobo_files/plugin/lib/hobo/dryml/dryml_builder.rb +126 -0
  90. data/hobo_files/plugin/lib/hobo/dryml/tag_module.rb +9 -0
  91. data/hobo_files/plugin/lib/hobo/dryml/taglib.rb +57 -0
  92. data/hobo_files/plugin/lib/hobo/dryml/template.rb +586 -0
  93. data/hobo_files/plugin/lib/hobo/dryml/template_environment.rb +302 -0
  94. data/hobo_files/plugin/lib/hobo/dryml/template_handler.rb +19 -0
  95. data/hobo_files/plugin/lib/hobo/generator.rb +25 -0
  96. data/hobo_files/plugin/lib/hobo/html_string.rb +3 -0
  97. data/hobo_files/plugin/lib/hobo/lazy_hash.rb +28 -0
  98. data/hobo_files/plugin/lib/hobo/mapping_tags.rb +262 -0
  99. data/hobo_files/plugin/lib/hobo/markdown_string.rb +7 -0
  100. data/hobo_files/plugin/lib/hobo/model.rb +391 -0
  101. data/hobo_files/plugin/lib/hobo/model_controller.rb +676 -0
  102. data/hobo_files/plugin/lib/hobo/model_queries.rb +92 -0
  103. data/hobo_files/plugin/lib/hobo/model_support.rb +44 -0
  104. data/hobo_files/plugin/lib/hobo/password_string.rb +3 -0
  105. data/hobo_files/plugin/lib/hobo/predicate_dispatch.rb +78 -0
  106. data/hobo_files/plugin/lib/hobo/proc_binding.rb +32 -0
  107. data/hobo_files/plugin/lib/hobo/rapid.rb +447 -0
  108. data/hobo_files/plugin/lib/hobo/static_tags +92 -0
  109. data/hobo_files/plugin/lib/hobo/text.rb +3 -0
  110. data/hobo_files/plugin/lib/hobo/textile_string.rb +13 -0
  111. data/hobo_files/plugin/lib/hobo/undefined.rb +41 -0
  112. data/hobo_files/plugin/lib/hobo/undefined_access_error.rb +5 -0
  113. data/hobo_files/plugin/lib/hobo/where_fragment.rb +23 -0
  114. data/hobo_files/plugin/lib/rexml.rb +345 -0
  115. data/hobo_files/plugin/tags/core.dryml +6 -0
  116. data/hobo_files/plugin/tags/rapid.dryml +177 -0
  117. data/hobo_files/plugin/tags/rapid_editing.dryml +168 -0
  118. data/hobo_files/plugin/tags/rapid_navigation.dryml +95 -0
  119. data/hobo_files/plugin/tags/rapid_pages.dryml +175 -0
  120. data/hobo_files/plugin/tasks/environments.rake +19 -0
  121. data/hobo_files/plugin/tasks/hobo_tasks.rake +4 -0
  122. data/hobo_files/plugin/test/hobo_dryml_template_test.rb +7 -0
  123. data/hobo_files/plugin/test/hobo_test.rb +7 -0
  124. data/hobo_files/plugin/uninstall.rb +1 -0
  125. metadata +206 -0
@@ -0,0 +1,3 @@
1
+ class Hobo::HtmlString
2
+
3
+ end
@@ -0,0 +1,106 @@
1
+ require 'digest/sha1'
2
+
3
+ module Hobo
4
+
5
+ module AuthenticatedUser
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+
10
+ base.class_eval do
11
+ # Virtual attribute for the unencrypted password
12
+ attr_accessor :password
13
+
14
+ validates_presence_of :password, :if => :password_required?
15
+ validates_presence_of :password_confirmation, :if => :password_required?
16
+ validates_confirmation_of :password, :if => :password_required?
17
+
18
+ before_save :encrypt_password
19
+
20
+ never_show :salt, :crypted_password, :remember_token, :remember_token_expires_at
21
+
22
+ set_field_type :password => :password, :password_confirmation => :password
23
+
24
+ password_validations
25
+ end
26
+ end
27
+
28
+ module ClassMethods
29
+
30
+ def password_validations
31
+ validates_length_of :password, :within => 4..40, :if => :password_required?
32
+ end
33
+
34
+ def set_login_attr(attr)
35
+ @login_attr = attr = attr.to_sym
36
+ alias_attribute(:login, attr) unless attr == :login
37
+
38
+ if block_given?
39
+ yield
40
+ else
41
+ validates_presence_of attr
42
+ validates_length_of attr, :within => 3..100
43
+ validates_uniqueness_of attr, :case_sensitive => false
44
+ end
45
+ end
46
+
47
+ # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
48
+ def authenticate(login, password)
49
+ u = find(:first, :conditions => ["#{@login_attr} = ?", login]) # need to get the salt
50
+
51
+ if u && u.authenticated?(password)
52
+ u.last_login_at = Time.now and u.save if u.respond_to?(:last_login_at)
53
+ u
54
+ else
55
+ nil
56
+ end
57
+ end
58
+
59
+ # Encrypts some data with the salt.
60
+ def encrypt(password, salt)
61
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
62
+ end
63
+
64
+ end
65
+
66
+ # Encrypts the password with the user salt
67
+ def encrypt(password)
68
+ self.class.encrypt(password, salt)
69
+ end
70
+
71
+ def authenticated?(password)
72
+ crypted_password == encrypt(password)
73
+ end
74
+
75
+ def remember_token?
76
+ remember_token_expires_at && Time.now.utc < remember_token_expires_at
77
+ end
78
+
79
+ # These create and unset the fields required for remembering users between browser closes
80
+ def remember_me
81
+ self.remember_token_expires_at = 2.weeks.from_now.utc
82
+ self.remember_token = encrypt("#{login}--#{remember_token_expires_at}")
83
+ save(false)
84
+ end
85
+
86
+ def forget_me
87
+ self.remember_token_expires_at = nil
88
+ self.remember_token = nil
89
+ save(false)
90
+ end
91
+
92
+ protected
93
+ # before filter
94
+ def encrypt_password
95
+ return if password.blank?
96
+ self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
97
+ self.crypted_password = encrypt(password)
98
+ end
99
+
100
+ def password_required?
101
+ (crypted_password.blank? && password != nil) || !password.blank?
102
+ end
103
+
104
+ end
105
+
106
+ end
@@ -0,0 +1,108 @@
1
+ module Hobo
2
+
3
+ module AuthenticationSupport
4
+
5
+ # Filter method to enforce a login requirement.
6
+ def logged_in?
7
+ not current_user.guest?
8
+ end
9
+
10
+ # Check if the user is authorized.
11
+ #
12
+ # Override this method in your controllers if you want to restrict access
13
+ # to only a few actions or if you want to check if the user
14
+ # has the correct rights.
15
+ #
16
+ # Example:
17
+ #
18
+ # # only allow nonbobs
19
+ # def authorize?
20
+ # current_user.login != "bob"
21
+ # end
22
+ def authorized?
23
+ true
24
+ end
25
+
26
+ #
27
+ # To require logins for all actions, use this in your controllers:
28
+ #
29
+ # before_filter :login_required
30
+ #
31
+ # To require logins for specific actions, use this in your controllers:
32
+ #
33
+ # before_filter :login_required, :only => [ :edit, :update ]
34
+ #
35
+ # To skip this in a subclassed controller:
36
+ #
37
+ # skip_before_filter :login_required
38
+ #
39
+ def login_required
40
+ if current_user.guest?
41
+ username, passwd = get_auth_data
42
+ self.current_user = Hobo.user_model.authenticate(username, passwd) || :false if username && passwd
43
+ end
44
+ logged_in? && authorized? ? true : access_denied
45
+ end
46
+
47
+ # Redirect as appropriate when an access request fails.
48
+ #
49
+ # The default action is to redirect to the login screen.
50
+ #
51
+ # Override this method in your controllers if you want to have special
52
+ # behavior in case the user is not authorized
53
+ # to access the requested action. For example, a popup window might
54
+ # simply close itself.
55
+ def access_denied
56
+ respond_to do |accepts|
57
+ accepts.html do
58
+ store_location
59
+ redirect_to login_url
60
+ end
61
+ accepts.xml do
62
+ headers["Status"] = "Unauthorized"
63
+ headers["WWW-Authenticate"] = %(Basic realm="Web Password")
64
+ render :text => "Could't authenticate you", :status => '401 Unauthorized'
65
+ end
66
+ end
67
+ false
68
+ end
69
+
70
+ # Store the URI of the current request in the session.
71
+ #
72
+ # We can return to this location by calling #redirect_back_or_default.
73
+ def store_location
74
+ session[:return_to] = request.request_uri
75
+ end
76
+
77
+ # Redirect to the URI stored by the most recent store_location call or
78
+ # to the passed default.
79
+ def redirect_back_or_default(default)
80
+ session[:return_to] ? redirect_to_url(session[:return_to]) : redirect_to(default)
81
+ session[:return_to] = nil
82
+ end
83
+
84
+ # When called with before_filter :login_from_cookie will check for an :auth_token
85
+ # cookie and log the user back in if apropriate
86
+ def login_from_cookie
87
+ return unless cookies[:auth_token] && !logged_in?
88
+ user = Hobo.user_model.find_by_remember_token(cookies[:auth_token])
89
+ if user && user.remember_token?
90
+ user.remember_me
91
+ self.current_user = user
92
+ cookies[:auth_token] = { :value => self.current_user.remember_token ,
93
+ :expires => self.current_user.remember_token_expires_at }
94
+ end
95
+ end
96
+
97
+ private
98
+ @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
99
+ # gets BASIC auth info
100
+ def get_auth_data
101
+ auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h) }
102
+ auth_data = request.env[auth_key].to_s.split unless auth_key.blank?
103
+ return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]
104
+ end
105
+
106
+ end
107
+
108
+ end
@@ -0,0 +1,66 @@
1
+ module Hobo
2
+
3
+ class CompositeModel
4
+
5
+ include ModelSupport
6
+
7
+ class << self
8
+
9
+ def find(id)
10
+ ids = id.split('_')
11
+ new(*ids.map_with_index{|id, i| @models[i].constantize.find(id)})
12
+ end
13
+
14
+ def compose(*models)
15
+ @models = models.omap{to_s.camelize}
16
+ attr_reader *models
17
+ CompositeModel.composites ||= {}
18
+ CompositeModel.composites[@models.sort] = self.name
19
+
20
+ Hobo.register_model(self)
21
+ end
22
+
23
+ attr_accessor :composites
24
+
25
+ attr_reader :models
26
+
27
+ def new_for(objects)
28
+ classes = objects.map{|o| o.class.name}.sort
29
+ composite_class = CompositeModel.composites[classes].constantize rescue
30
+ (raise ArgumentError, "No composite model for #{classes.inspect}")
31
+ composite_class.new(*objects)
32
+ end
33
+
34
+ end
35
+
36
+
37
+ def initialize(*objects)
38
+ objects.each do |obj|
39
+ raise ArgumentError, "invalid objects for composition: #{objects.inspect}" unless
40
+ obj.class.name.in? self.class.models
41
+ instance_variable_set("@#{obj.class.name.underscore}", obj)
42
+ end
43
+ end
44
+
45
+
46
+ def compose_with(object, use=nil)
47
+ self_classes = use ? use.models : self.class.models
48
+ from_self = (self_classes - [object.class.name]).map {|classname| send(classname.underscore)}
49
+ CompositeModel.new_for(from_self + [object])
50
+ end
51
+
52
+
53
+ def typed_id
54
+ "#{self.class.name.underscore}_#{id}"
55
+ end
56
+
57
+
58
+ def id
59
+ objects = self.class.models.map {|m| instance_variable_get("@#{m.underscore}")}
60
+ objects.omap{id}.join("_")
61
+ end
62
+
63
+ end
64
+
65
+ end
66
+
@@ -0,0 +1,134 @@
1
+ module Hobo
2
+
3
+ module Controller
4
+
5
+ include ControllerHelpers
6
+
7
+ include AuthenticationSupport
8
+
9
+ def self.included(base)
10
+ if base.is_a?(Class)
11
+ Hobo::ControllerHelpers.public_instance_methods.each {|m| base.hide_action(m)}
12
+ base.class_eval do
13
+ alias_method_chain :redirect_to, :object_url
14
+ end
15
+ end
16
+ end
17
+
18
+
19
+ protected
20
+
21
+ def redirect_to_with_object_url(destination, view=nil)
22
+ if destination.is_a?(String, Hash, Symbol)
23
+ redirect_to_without_object_url(destination)
24
+ else
25
+ redirect_to_without_object_url(object_url(destination, view))
26
+ end
27
+ end
28
+
29
+ def hobo_ajax_response(this=nil, results={})
30
+ this ||= @this
31
+ part_page = params[:part_page]
32
+ r = params[:render]
33
+ if r
34
+ ajax_update_response(this, part_page, r.values, results)
35
+ true
36
+ else
37
+ false
38
+ end
39
+ end
40
+
41
+
42
+ def ajax_update_response(this, part_page, render_specs, results={})
43
+ before_ajax if respond_to? :before_ajax
44
+ add_variables_to_assigns
45
+ renderer = Hobo::Dryml.page_renderer(@template, [], part_page) if part_page
46
+
47
+ render :update do |page|
48
+ page << "var _update = typeof Hobo == 'undefined' ? Element.update : Hobo.updateElement;"
49
+ for spec in render_specs
50
+ function = spec[:function] || "_update"
51
+
52
+ if spec[:as] or spec[:part]
53
+ obj = if spec[:object] == "this" or spec[:object].blank?
54
+ this
55
+ elsif spec[:object] == "nil"
56
+ nil
57
+ else
58
+ Hobo.object_from_dom_id(spec[:object])
59
+ end
60
+
61
+ if spec[:as]
62
+ part_content = render(:partial => (Hobo::ModelController.find_partial(obj.class, spec[:as])),
63
+ :locals => { :this => obj })
64
+ page.call(function, spec[:id], part_content)
65
+
66
+ elsif spec[:part]
67
+ dom_id = spec[:id] || spec[:part]
68
+ part_content = renderer.call_part(dom_id, spec[:part], obj)
69
+ page.call(function, dom_id, part_content)
70
+ end
71
+
72
+ elsif spec[:result]
73
+ result = results[spec[:result].to_sym]
74
+ page.call(function, spec[:id], result)
75
+
76
+ else
77
+ # spec didn't specify any action :-/
78
+ end
79
+ end
80
+ if renderer
81
+ renderer.part_contexts.each_pair do |dom_id, p|
82
+ part_id, model_id = p
83
+ page.assign "hoboParts.#{dom_id}", [part_id, model_id]
84
+
85
+ # not sure why this isn't happending automatically
86
+ # but it's messing up ARTS, so chuck a newline in
87
+ page << "\n"
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+
94
+ def render_tag(tag, options={})
95
+ add_variables_to_assigns
96
+ render :text => Hobo::Dryml.render_tag(@template, tag, options), :layout => false
97
+ end
98
+
99
+
100
+ def render_tags(objects, tag, options={})
101
+ add_variables_to_assigns
102
+ dryml_renderer = Hobo::Dryml.empty_page_renderer(@template)
103
+ render :text => objects.map {|o| dryml_renderer.send(tag, options.merge(:obj => o))}.join +
104
+ dryml_renderer.part_contexts_js
105
+ end
106
+
107
+
108
+ def site_search(query)
109
+ results = Hobo.find_by_search(query).select {|r| Hobo.can_view?(current_user, r, nil)}
110
+ if results.empty?
111
+ render :text => "<p>Your search returned no matches.</p>"
112
+ else
113
+ render_tags(results, "tag_for_object", :name => "search_result")
114
+ end
115
+ end
116
+
117
+
118
+ # Store the given user in the session.
119
+ def current_user=(new_user)
120
+ session[:user] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id
121
+ @current_user = new_user
122
+ end
123
+
124
+
125
+ def request_no_cache?
126
+ request.env['HTTP_CACHE_CONTROL'] =~ /max-age=\s*0/
127
+ end
128
+
129
+ def not_found
130
+
131
+ end
132
+
133
+ end
134
+ end
@@ -0,0 +1,135 @@
1
+ module Hobo::ControllerHelpers
2
+
3
+ protected
4
+
5
+ def current_user
6
+ # simple one-hit-per-request cache
7
+ @current_user or
8
+ @current_user = if Hobo.user_model and session and id = session[:user]
9
+ Hobo.user_model.find(id)
10
+ else
11
+ Guest.new
12
+ end
13
+ end
14
+
15
+
16
+ def logged_in?
17
+ not current_user.guest?
18
+ end
19
+
20
+
21
+ def urlb
22
+ request.relative_url_root
23
+ end
24
+
25
+
26
+ def controller_for(obj)
27
+ if obj.is_a? Class
28
+ obj.name.underscore.pluralize
29
+ else
30
+ obj.class.name.underscore.pluralize
31
+ end
32
+ end
33
+
34
+
35
+ def object_url(obj, action=nil, *param_hashes)
36
+ action &&= action.to_s
37
+
38
+ controller_name = controller_for(obj)
39
+
40
+ parts = if obj.is_a? Class
41
+ [urlb, controller_name]
42
+
43
+ elsif obj.is_a? Hobo::CompositeModel
44
+ [urlb, controller_name, obj.id]
45
+
46
+ elsif obj.is_a? ActiveRecord::Base
47
+ if obj.new_record?
48
+ [urlb, controller_name]
49
+ else
50
+ raise HoboError.new("invalid object url: new for existing object") if action == "new"
51
+
52
+ klass = obj.class
53
+ id = if klass.id_name?
54
+ obj.id_name(true)
55
+ else
56
+ obj.id
57
+ end
58
+
59
+ [urlb, controller_name, id]
60
+ end
61
+
62
+ elsif obj.is_a? Array # warning - this breaks if we use `case/when Array`
63
+ owner = obj.proxy_owner
64
+ new_model = obj.proxy_reflection.klass
65
+ [object_url(owner), obj.proxy_reflection.name]
66
+
67
+ else
68
+ raise HoboError.new("cannot create url for #{obj.inspect} (#{obj.class})")
69
+ end
70
+ basic = parts.join("/")
71
+
72
+ controller = (controller_name.camelize + "Controller").constantize rescue nil
73
+ url = if action && controller && action.to_sym.in?(controller.web_methods)
74
+ basic + "/#{action}"
75
+ else
76
+ case action
77
+ when "new"
78
+ basic + "/new"
79
+ when "destroy"
80
+ basic + "?_method=DELETE"
81
+ when "update"
82
+ basic + "?_method=PUT"
83
+ when nil
84
+ basic
85
+ else
86
+ basic + ";" + action
87
+ end
88
+ end
89
+ params = make_params(*param_hashes)
90
+ params.blank? ? url : url + "?" + params
91
+ end
92
+
93
+
94
+ def _as_params(name, obj)
95
+ if obj.is_a? Array
96
+ obj.map {|x| _as_params("#{name}[]", x)}.join("&")
97
+ elsif obj.is_a? Hash
98
+ obj.map {|k,v| _as_params("#{name}[#{k}]", v)}.join("&")
99
+ elsif obj.is_a? Hobo::RawJs
100
+ "#{name}=' + #{obj} + '"
101
+ else
102
+ v = if obj.is_a?(ActiveRecord::Base) or obj.is_a?(Array)
103
+ "@" + dom_id(obj)
104
+ else
105
+ obj.to_s.gsub("'"){"\\'"}
106
+ end
107
+ "#{name}=#{v}"
108
+ end
109
+ end
110
+
111
+
112
+ def make_params(*hashes)
113
+ hash = {}
114
+ hashes.each {|h| hash.update(h) if h}
115
+ hash.map {|k,v| _as_params(k, v)}.join("&")
116
+ end
117
+
118
+
119
+ def dom_id(x, attr=nil)
120
+ Hobo.dom_id(x, attr)
121
+ end
122
+
123
+
124
+ # debugging support
125
+
126
+ def debug(*args)
127
+ logger.debug(args.map{|arg| PP.pp(arg, "")}.join("\n"))
128
+ return args.first
129
+ end
130
+
131
+ def abort_with(*args)
132
+ raise args.map{|arg| PP.pp(arg, "")}.join("\n")
133
+ end
134
+
135
+ end