releaf 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +15 -12
  3. data/Rakefile +8 -0
  4. data/app/assets/javascripts/releaf/controllers/base.js +0 -40
  5. data/app/assets/javascripts/releaf/include/field.type_date_or_datetime_or_time.js +43 -0
  6. data/app/assets/javascripts/releaf/include/nested_fields.js +58 -65
  7. data/app/assets/javascripts/releaf/include/sortable.js +19 -17
  8. data/app/assets/stylesheets/releaf/controllers/releaf/content.css.erb +6 -0
  9. data/app/assets/stylesheets/releaf/include/field.css.erb +37 -13
  10. data/app/controllers/releaf/admins_controller.rb +13 -6
  11. data/app/controllers/releaf/base_application_controller.rb +4 -1
  12. data/app/controllers/releaf/base_controller.rb +415 -154
  13. data/app/controllers/releaf/content_controller.rb +62 -45
  14. data/app/controllers/releaf/roles_controller.rb +11 -9
  15. data/app/controllers/releaf/sessions_controller.rb +23 -1
  16. data/app/controllers/releaf/translations_controller.rb +21 -25
  17. data/app/helpers/releaf/admin_helper.rb +0 -20
  18. data/app/models/releaf/admin.rb +9 -0
  19. data/app/models/releaf/blank_node_base.rb +29 -0
  20. data/app/models/releaf/node.rb +6 -5
  21. data/app/models/releaf/node_base.rb +9 -3
  22. data/app/models/releaf/role.rb +9 -2
  23. data/app/views/layouts/releaf/admin.html.haml +12 -6
  24. data/app/views/layouts/releaf/devise.html.haml +32 -0
  25. data/app/views/releaf/aliases/{_edit.body.haml → _edit.body.html.haml} +0 -0
  26. data/app/views/releaf/aliases/{_edit.header.haml → _edit.header.html.haml} +1 -1
  27. data/app/views/releaf/aliases/_index.row.html.haml +5 -0
  28. data/app/views/releaf/aliases/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
  29. data/app/views/releaf/base/_edit.body.html.haml +11 -0
  30. data/app/views/releaf/base/_edit.field.html.haml +23 -0
  31. data/app/views/releaf/base/{_edit.field.type_autocomplete.haml → _edit.field_type_autocomplete.html.haml} +1 -1
  32. data/app/views/releaf/base/{_edit.field.type_checkbox.haml → _edit.field_type_boolean.html.haml} +1 -1
  33. data/app/views/releaf/base/{_edit.field.type_date.haml → _edit.field_type_date.html.haml} +0 -0
  34. data/app/views/releaf/base/{_edit.field.type_datetime.haml → _edit.field_type_datetime.html.haml} +0 -0
  35. data/app/views/releaf/base/{_edit.field.type_delete_nested.haml → _edit.field_type_delete_nested.html.haml} +0 -0
  36. data/app/views/releaf/base/{_edit.field.type_file.haml → _edit.field_type_file.html.haml} +0 -0
  37. data/app/views/releaf/base/_edit.field_type_image.html.haml +12 -0
  38. data/app/views/releaf/base/_edit.field_type_item.html.haml +31 -0
  39. data/app/views/releaf/base/{_edit.field.type_link.haml → _edit.field_type_link.html.haml} +0 -0
  40. data/app/views/releaf/base/_edit.field_type_link_i18n.html.haml +26 -0
  41. data/app/views/releaf/base/{_edit.field.type_password.haml → _edit.field_type_password.html.haml} +0 -0
  42. data/app/views/releaf/base/{_edit.field.type_richtext.haml → _edit.field_type_richtext.html.haml} +0 -0
  43. data/app/views/releaf/base/{_edit.field.type_richtext_i18n.haml → _edit.field_type_richtext_i18n.html.haml} +0 -0
  44. data/app/views/releaf/base/{_edit.field.type_text.haml → _edit.field_type_text.html.haml} +0 -0
  45. data/app/views/releaf/base/{_edit.field.type_text_i18n.haml → _edit.field_type_text_i18n.html.haml} +0 -0
  46. data/app/views/releaf/base/{_edit.field.type_textarea.haml → _edit.field_type_textarea.html.haml} +0 -0
  47. data/app/views/releaf/base/{_edit.field.type_textarea_i18n.haml → _edit.field_type_textarea_i18n.html.haml} +0 -0
  48. data/app/views/releaf/base/{_edit.field.type_time.haml → _edit.field_type_time.html.haml} +0 -0
  49. data/app/views/releaf/base/_edit.fields.association.html.haml +48 -0
  50. data/app/views/releaf/base/_edit.fields.has_many_template.html.haml +15 -0
  51. data/app/views/releaf/base/_edit.fields.html.haml +20 -0
  52. data/app/views/releaf/base/{_edit.footer.haml → _edit.footer.html.haml} +2 -2
  53. data/app/views/releaf/base/_edit.form.html.haml +4 -0
  54. data/app/views/releaf/base/_edit.header.html.haml +3 -0
  55. data/app/views/releaf/base/{_index.body.haml → _index.body.html.haml} +2 -2
  56. data/app/views/releaf/base/_index.cell.html.haml +20 -0
  57. data/app/views/releaf/base/_index.footer.html.haml +28 -0
  58. data/app/views/releaf/base/_index.header.html.haml +4 -0
  59. data/app/views/releaf/base/_index.row.html.haml +6 -0
  60. data/app/views/releaf/base/_index.search.html.haml +5 -0
  61. data/app/views/releaf/base/_index.table.html.haml +24 -0
  62. data/app/views/releaf/base/_secondary_panel.html.haml +10 -0
  63. data/app/views/releaf/base/_show.body.html.haml +3 -0
  64. data/app/views/releaf/base/_show.field.html.haml +20 -0
  65. data/app/views/releaf/base/_show.field_type_date.html.haml +9 -0
  66. data/app/views/releaf/base/_show.field_type_date_time.html.haml +9 -0
  67. data/app/views/releaf/base/_show.field_type_email.html.haml +6 -0
  68. data/app/views/releaf/base/_show.field_type_file.html.haml +7 -0
  69. data/app/views/releaf/base/_show.field_type_image.html.haml +10 -0
  70. data/app/views/releaf/base/_show.field_type_item.html.haml +11 -0
  71. data/app/views/releaf/base/_show.field_type_link.html.haml +14 -0
  72. data/app/views/releaf/base/_show.field_type_password.html.haml +6 -0
  73. data/app/views/releaf/base/_show.field_type_richtext.html.haml +6 -0
  74. data/app/views/releaf/base/_show.field_type_text.html.haml +6 -0
  75. data/app/views/releaf/base/_show.field_type_textarea.html.haml +6 -0
  76. data/app/views/releaf/base/_show.field_type_time.html.haml +9 -0
  77. data/app/views/releaf/base/_show.field_type_url.html.haml +7 -0
  78. data/app/views/releaf/base/_show.fields.association.html.haml +36 -0
  79. data/app/views/releaf/base/_show.fields.has_many_template.html.haml +12 -0
  80. data/app/views/releaf/base/_show.fields.html.haml +17 -0
  81. data/app/views/releaf/base/{_show.footer.haml → _show.footer.html.haml} +6 -4
  82. data/app/views/releaf/base/_show.header.html.haml +3 -0
  83. data/app/views/releaf/base/confirm_destroy.html.haml +17 -0
  84. data/app/views/releaf/base/edit.html.haml +1 -0
  85. data/app/views/releaf/base/index.html.haml +3 -0
  86. data/app/views/releaf/base/new.html.haml +1 -0
  87. data/app/views/releaf/base/show.html.haml +3 -0
  88. data/app/views/releaf/content/{_edit.body.haml → _edit.body.html.haml} +7 -6
  89. data/app/views/releaf/content/_edit.content_fields.html.haml +11 -0
  90. data/app/views/releaf/content/_edit.fields.html.haml +17 -0
  91. data/app/views/releaf/content/{_edit.slug.haml → _edit.slug.html.haml} +0 -0
  92. data/app/views/releaf/content/{_get_content_form.haml → _get_content_form.html.haml} +2 -2
  93. data/app/views/releaf/content/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
  94. data/app/views/releaf/content/{_tree_level.haml → _tree_level.html.haml} +0 -0
  95. data/app/views/releaf/content/{ajax.new.haml → ajax.new.html.haml} +0 -0
  96. data/app/views/releaf/content/{index.haml → index.html.haml} +0 -0
  97. data/app/views/releaf/roles/_edit.field.permissions.html.haml +5 -0
  98. data/app/views/releaf/roles/{_show.field.default.haml → _show.field.default.html.haml} +1 -1
  99. data/app/views/releaf/roles/{_show.field.permissions.haml → _show.field.permissions.html.haml} +2 -2
  100. data/app/views/releaf/translations/{_edit.body.haml → _edit.body.html.haml} +0 -0
  101. data/app/views/releaf/translations/{_edit.header.haml → _edit.header.html.haml} +1 -1
  102. data/app/views/releaf/translations/_index.row.html.haml +5 -0
  103. data/app/views/releaf/translations/{_secondary_panel.haml → _secondary_panel.html.haml} +0 -0
  104. data/lib/generators/releaf/templates/initializers/releaf.rb +0 -39
  105. data/lib/generators/releaf/templates/initializers/releaf_i18n.rb +17 -0
  106. data/lib/generators/releaf/templates/javascripts/3rd_party/jquery.jcarousel.js +1058 -0
  107. data/lib/generators/releaf/templates/javascripts/lib/init_jcarousel.js +40 -0
  108. data/lib/generators/releaf/templates/migrations/create_releaf_roles.rb +1 -0
  109. data/lib/generators/releaf/templates/migrations/create_releaf_tinymce_assets.rb +1 -0
  110. data/lib/generators/releaf/templates/models/admin_ability.rb +1 -1
  111. data/lib/i18n/backend/releaf.rb +5 -4
  112. data/lib/i18n/backend/releaf/translation.rb +5 -0
  113. data/lib/i18n/backend/releaf/translation_data.rb +7 -0
  114. data/lib/i18n/backend/releaf/translation_group.rb +4 -0
  115. data/lib/releaf.rb +4 -0
  116. data/lib/releaf/boolean_at.rb +77 -0
  117. data/lib/releaf/globalize3/fallbacks.rb +19 -0
  118. data/lib/releaf/resources.rb +101 -0
  119. data/lib/releaf/slug.rb +99 -60
  120. data/lib/releaf/version.rb +1 -1
  121. data/spec/spec_helper.rb +6 -0
  122. data/templates/releaf/installer.rb +15 -4
  123. metadata +275 -329
  124. data/app/views/releaf/aliases/_index.row.haml +0 -5
  125. data/app/views/releaf/base/_edit.body.haml +0 -19
  126. data/app/views/releaf/base/_edit.field.haml +0 -96
  127. data/app/views/releaf/base/_edit.field.type_image.haml +0 -14
  128. data/app/views/releaf/base/_edit.field.type_select.haml +0 -11
  129. data/app/views/releaf/base/_edit.form.haml +0 -4
  130. data/app/views/releaf/base/_edit.has_many_associations.haml +0 -45
  131. data/app/views/releaf/base/_edit.header.haml +0 -3
  132. data/app/views/releaf/base/_index.cell.haml +0 -19
  133. data/app/views/releaf/base/_index.footer.haml +0 -22
  134. data/app/views/releaf/base/_index.header.haml +0 -4
  135. data/app/views/releaf/base/_index.row.haml +0 -6
  136. data/app/views/releaf/base/_index.search.haml +0 -5
  137. data/app/views/releaf/base/_index.table.haml +0 -8
  138. data/app/views/releaf/base/_secondary_panel.haml +0 -9
  139. data/app/views/releaf/base/_show.body.haml +0 -7
  140. data/app/views/releaf/base/_show.field.haml +0 -78
  141. data/app/views/releaf/base/_show.field.type_html.haml +0 -1
  142. data/app/views/releaf/base/_show.header.haml +0 -3
  143. data/app/views/releaf/base/confirm_destroy.haml +0 -10
  144. data/app/views/releaf/base/edit.haml +0 -1
  145. data/app/views/releaf/base/index.haml +0 -3
  146. data/app/views/releaf/base/new.haml +0 -1
  147. data/app/views/releaf/base/show.haml +0 -3
  148. data/app/views/releaf/content/_edit.content_fields.haml +0 -19
  149. data/app/views/releaf/content/_show.field.content.haml +0 -11
  150. data/app/views/releaf/roles/_edit.field.admins.haml +0 -0
  151. data/app/views/releaf/roles/_edit.field.permissions.haml +0 -5
  152. data/app/views/releaf/translations/_index.row.haml +0 -5
  153. data/spec/dummy/README.rdoc +0 -261
  154. data/spec/dummy/Rakefile +0 -7
  155. data/spec/dummy/app/assets/images/rails.png +0 -0
  156. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  157. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  158. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  159. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  160. data/spec/dummy/app/models/admin_ability.rb +0 -51
  161. data/spec/dummy/app/models/settings.rb +0 -2
  162. data/spec/dummy/app/views/layouts/application.html.haml +0 -10
  163. data/spec/dummy/config.ru +0 -4
  164. data/spec/dummy/config/application.rb +0 -68
  165. data/spec/dummy/config/boot.rb +0 -6
  166. data/spec/dummy/config/common_fields.yml.example +0 -17
  167. data/spec/dummy/config/database.yml +0 -42
  168. data/spec/dummy/config/environment.rb +0 -5
  169. data/spec/dummy/config/environments/development.rb +0 -37
  170. data/spec/dummy/config/environments/production.rb +0 -67
  171. data/spec/dummy/config/environments/test.rb +0 -37
  172. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  173. data/spec/dummy/config/initializers/devise.rb +0 -232
  174. data/spec/dummy/config/initializers/dragonfly.rb +0 -1
  175. data/spec/dummy/config/initializers/inflections.rb +0 -15
  176. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  177. data/spec/dummy/config/initializers/releaf.rb +0 -59
  178. data/spec/dummy/config/initializers/releaf_i18n.rb +0 -8
  179. data/spec/dummy/config/initializers/releaf_store_current_template.rb +0 -25
  180. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  181. data/spec/dummy/config/initializers/session_store.rb +0 -8
  182. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  183. data/spec/dummy/config/locales/devise.en.yml +0 -58
  184. data/spec/dummy/config/locales/en.yml +0 -5
  185. data/spec/dummy/config/routes.rb +0 -11
  186. data/spec/dummy/db/migrate/20130204164516_create_settings.rb +0 -17
  187. data/spec/dummy/db/migrate/20130204164523_create_releaf_nodes.rb +0 -25
  188. data/spec/dummy/db/migrate/20130204164524_create_releaf_roles.rb +0 -11
  189. data/spec/dummy/db/migrate/20130204164525_create_releaf_translations.rb +0 -31
  190. data/spec/dummy/db/migrate/20130204164526_create_releaf_admins.rb +0 -53
  191. data/spec/dummy/db/schema.rb +0 -112
  192. data/spec/dummy/db/seeds.rb +0 -64
  193. data/spec/dummy/doc/README_FOR_APP +0 -2
  194. data/spec/dummy/log/development.log +0 -74
  195. data/spec/dummy/log/test.log +0 -129
  196. data/spec/dummy/public/404.html +0 -26
  197. data/spec/dummy/public/422.html +0 -26
  198. data/spec/dummy/public/500.html +0 -25
  199. data/spec/dummy/public/favicon.ico +0 -0
  200. data/spec/dummy/script/rails +0 -6
  201. data/spec/dummy/tmp/cache/9C5/660/settings%3Ai18n_updated_at +0 -1
@@ -1,11 +1,11 @@
1
1
  module Releaf
2
2
  class AdminsController < BaseController
3
3
 
4
- def current_object_class
4
+ def resource_class
5
5
  Releaf::Admin
6
6
  end
7
7
 
8
- def columns( view = nil )
8
+ def fields_to_display
9
9
  fields = super - %w[
10
10
  authentication_token
11
11
  confirmation_sent_at
@@ -26,21 +26,28 @@ module Releaf
26
26
  unlock_token
27
27
  ]
28
28
 
29
- if view == 'index'
29
+ if params[:action] == 'index'
30
30
  fields -= ['avatar_uid']
31
31
  end
32
32
 
33
- if %w[new create edit update].include? view
33
+ if %w[new create edit update].include? params[:action]
34
34
  fields += ['password', 'password_confirmation']
35
35
  end
36
36
 
37
37
  return fields
38
38
  end
39
39
 
40
+ def new
41
+ super
42
+ if Releaf::Role.default
43
+ @resource.role = Releaf::Role.default
44
+ end
45
+ end
46
+
40
47
  protected
41
48
 
42
- def admin_params( action )
43
- return [] unless [:create, :update].include? action
49
+ def resource_params
50
+ return [] unless %w[create update].include? params[:action]
44
51
  %w[name surname role_id email password password_confirmation phone avatar retained_avatar]
45
52
  end
46
53
 
@@ -1,6 +1,5 @@
1
1
  module Releaf
2
2
  class BaseApplicationController < ActionController::Base
3
- # include ReleafDeviseHelper
4
3
 
5
4
  before_filter "authenticate_#{ReleafDeviseHelper.devise_admin_model_name}!"
6
5
  # check_authorization :unless => :devise_controller?
@@ -11,5 +10,9 @@ module Releaf
11
10
  @current_ability ||= AdminAbility.new(self.send("current_#{ReleafDeviseHelper.devise_admin_model_name}"))
12
11
  end
13
12
 
13
+ def full_controller_name
14
+ self.class.name.sub(/Controller$/, '').underscore
15
+ end
16
+
14
17
  end
15
18
  end
@@ -1,127 +1,48 @@
1
1
  module Releaf
2
+ class FeatureDisabled < StandardError; end
3
+
2
4
  class BaseController < BaseApplicationController
5
+ helper_method :build_secondary_panel_variables,
6
+ :fields_to_display,
7
+ :resource_class,
8
+ :find_parent_template,
9
+ :has_template?,
10
+ :list_action,
11
+ :render_field_type,
12
+ :render_parent_template,
13
+ :secondary_panel,
14
+ :current_feature,
15
+ :resource_to_text,
16
+ :resource_to_text_method
17
+
3
18
  before_filter do
4
19
  filter_templates
5
20
  set_locale
6
21
  setup
7
22
  end
8
23
 
9
- def setup
10
- @controller = self # this is used later in views
11
- @features = { :create => true, :show => true, :edit => true, :destroy => true}
12
- @panel_layout = true
13
- @continuous_scroll = false
14
- @items_per_page = 40
15
- end
16
-
17
- def secondary_panel
18
- return '' unless @panel_layout
19
- @_secondary_panel ||= render_to_string( :partial => "secondary_panel", :layout => false, :locals => build_secondary_panel_variables)
20
- end
21
-
22
- def build_secondary_panel_variables
23
- menu_item_name = self.class.name.underscore.sub(/_controller$/, '')
24
-
25
- # if this item is defined in main menu, then there will be no altmenu
26
- # defined for it in alt menu, instead this method should be overriden in
27
- # particular controller to return structure needed to render alt menu
28
- return {} if Releaf.main_menu.include? menu_item_name
29
24
 
30
- # if this item was not found in main menu, then we need to find it in one
31
- # of alt menus. This way we'll know which alt menu to render.
32
- base_menus = Releaf.main_menu.reject { |item| item[0] != '*' }
33
- base_menus.each do |base_menu_name|
34
- if view_context.base_menu_items(base_menu_name).include?(menu_item_name)
35
- build_menu = { :menu => {} }
36
-
37
- base_menu = Releaf.base_menu[base_menu_name]
38
-
39
- base_menu.each do |section|
40
- section_name = section[0].to_sym
41
- build_menu[:menu][section_name] = []
42
- section[1].each do |item|
43
- build_menu[:menu][section_name].push({:controller => item.split(/#/, 2).first})
44
- end
45
- end
46
-
47
- return build_menu
48
- end
49
- end
50
-
51
- # coundn't find current controller in base_menu
52
- return {}
53
- end
54
-
55
- def current_object_class
56
- @_current_object_class ||= self.class.name.split('::').last.sub(/\s?Controller$/, '').classify.constantize
57
- end
58
-
59
- def current_object_class_name
60
- current_object_class.name.underscore.tr('/', '_')
61
- end
62
-
63
- def columns view=params[:action]
64
- cols = current_object_class.column_names - %w[id created_at updated_at encrypted_password position]
65
- unless %w[new edit update create].include? view
66
- cols -= %w[password password_confirmation]
67
- end
68
- return cols
69
- end
70
-
71
- def list_action
72
- if !cookies['base_module:list_action'].blank?
73
- feature = cookies['base_module:list_action']
74
- if feature == 'confirm_destroy'
75
- feature = 'destroy'
76
- end
77
- feature = feature.to_sym
78
- if !@features[ feature ].blank?
79
- return cookies['base_module:list_action']
80
- end
81
- end
82
- if !@features[ :show ].blank?
83
- return 'show'
84
- end
85
- return 'edit';
86
- end
87
-
88
- def has_template( name )
89
- lookup_context.template_exists?( name, lookup_context.prefixes, false )
90
- end
91
-
92
- def find_parent_template( name )
93
- lookup_context.find_template( name, lookup_context.prefixes.slice( 1, lookup_context.prefixes.length ), false )
94
- end
95
-
96
- def render_parent_template( name, locals = {} )
97
- template = find_parent_template( name )
98
- if template.blank?
99
- return 'blank'
100
- end
101
- arguments = { :layout => false, :locals => locals, :template => template.virtual_path }
102
- return render_to_string( arguments ).html_safe
103
- end
104
-
105
- def input_type_for( column_type, name )
106
- input_type = 'text'
107
- case column_type
108
- when :boolean
109
- input_type = 'checkbox'
110
- when :text
111
- input_type = 'textarea'
112
- if name.end_with?( '_html' )
113
- input_type = 'richtext'
114
- end
25
+ # Helper that returns current feature
26
+ def current_feature
27
+ case params[:action].to_sym
28
+ when :index
29
+ return :index
30
+ when :new, :create
31
+ return :create
32
+ when :edit, :update
33
+ return :edit
34
+ when :destroy, :confirm_destroy
35
+ return :destroy
36
+ else
37
+ return params[:action].to_sym
115
38
  end
116
- return input_type
117
39
  end
118
40
 
119
- # actions
120
41
 
121
42
  def autocomplete
122
- authorize! :edit, current_object_class
43
+ authorize! :edit, resource_class
123
44
 
124
- c_obj = current_object_class
45
+ c_obj = resource_class
125
46
 
126
47
  if params[:query_field] and params[:q] and params[:field] #and params[:field] =~ /_id\z/ and c_obj.column_names.include?(params[:field]) and c_obj.respond_to?(:reflect_on_association) and c_obj.reflect_on_association(params[:field].sub(/_id\z/, '').to_sym)
127
48
 
@@ -155,13 +76,13 @@ module Releaf
155
76
  matching_items_count = query.count
156
77
  list = query.limit(20)
157
78
 
158
- @items = []
159
- list.each do |item|
160
- @items.push({ :id => item.id, :text => item.to_text })
79
+ @resources = []
80
+ list.each do |resource|
81
+ @resources.push({ :id => resource.id, :text => resource.to_text })
161
82
  end
162
83
 
163
84
  respond_to do |format|
164
- format.json { render :json => {:matching_items_count => matching_items_count, :query => params[:q], :results => @items } }
85
+ format.json { render :json => {:matching_items_count => matching_items_count, :query => params[:q], :results => @resources } }
165
86
  end
166
87
 
167
88
  else
@@ -172,14 +93,20 @@ module Releaf
172
93
  end
173
94
 
174
95
  def index
175
- authorize! :list, current_object_class
176
- if current_object_class.respond_to?( :filter )
177
- @list = current_object_class.filter(:search => params[:search])
96
+ authorize! :list, resource_class
97
+ if resource_class.respond_to? :filter
98
+ @resources = resource_class.filter(:search => params[:search])
178
99
  else
179
- @list = current_object_class
100
+ @resources = resource_class
101
+ end
102
+
103
+ if resource_class.respond_to? :order_by
104
+ @resources = @resources.order_by(valid_order_by)
180
105
  end
181
- @list = @list.page( params[:page] ).per_page( @items_per_page )
182
- if !params[:ajax].blank?
106
+
107
+ @resources = @resources.includes(relations_for_includes).page( params[:page] ).per_page( @resources_per_page )
108
+
109
+ unless params[:ajax].blank?
183
110
  render :layout => false
184
111
  end
185
112
  end
@@ -197,37 +124,34 @@ module Releaf
197
124
  end
198
125
 
199
126
  def new
200
- authorize! :create, current_object_class
201
- @item = current_object_class.new
127
+ authorize! :create, resource_class
128
+ raise FeatureDisabled unless @features[:create]
129
+ @resource = resource_class.new
202
130
  end
203
131
 
204
132
  def show
205
- @item = current_object_class.find(params[:id])
206
- authorize! :show, @item
133
+ @resource = resource_class.includes(relations_for_includes).find(params[:id])
134
+ authorize! :show, @resource
135
+ raise FeatureDisabled unless @features[:show]
207
136
  end
208
137
 
209
138
  def edit
210
- @item = current_object_class.find(params[:id])
211
- authorize! :edit, @item
139
+ @resource = resource_class.includes(relations_for_includes).find(params[:id])
140
+ authorize! :edit, @resource
141
+ raise FeatureDisabled unless @features[:edit]
212
142
  end
213
143
 
214
144
  def create
215
- authorize! :create, current_object_class
216
- @item = current_object_class.new
145
+ authorize! :create, resource_class
146
+ raise FeatureDisabled unless @features[:create]
217
147
 
218
- if self.respond_to?(:"#{current_object_class_name}_params")
219
- variables = params.require( current_object_class_name ).permit( *self.send(:"#{current_object_class_name}_params", :update) )
220
- elsif @item.respond_to? :allowed_params
221
- variables = params.require( current_object_class_name ).permit( *@item.allowed_params(:create) )
222
- else
223
- variables = params.require( current_object_class_name ).permit( *current_object_class.column_names )
224
- end
148
+ @resource = resource_class.new
225
149
 
226
- @item.assign_attributes( variables )
150
+ @resource.assign_attributes required_params.permit(*resource_params)
227
151
 
228
152
  respond_to do |format|
229
- if @item.save
230
- format.html { redirect_to url_for( :action => 'show', :id => @item.id ) }
153
+ if @resource.save
154
+ format.html { redirect_to url_for( :action => @features[:show] ? 'show' : 'index', :id => @resource.id ) }
231
155
  else
232
156
  format.html { render :action => "new" }
233
157
  end
@@ -235,20 +159,13 @@ module Releaf
235
159
  end
236
160
 
237
161
  def update
238
- @item = current_object_class.find(params[:id])
239
- authorize! :edit, @item
240
-
241
- if self.respond_to?(:"#{current_object_class_name}_params")
242
- variables = params.require( current_object_class_name ).permit( *self.send(:"#{current_object_class_name}_params", :update) )
243
- elsif @item.respond_to? :allowed_params
244
- variables = params.require( current_object_class_name ).permit( *@item.allowed_params(:update) )
245
- else
246
- variables = params.require( current_object_class_name ).permit( *current_object_class.column_names )
247
- end
162
+ @resource = resource_class.find(params[:id])
163
+ authorize! :edit, @resource
164
+ raise FeatureDisabled unless @features[:edit]
248
165
 
249
166
  respond_to do |format|
250
- if @item.update_attributes( variables )
251
- format.html { redirect_to url_for( :action => 'show', :id => @item.id ) }
167
+ if @resource.update_attributes( required_params.permit(*resource_params) )
168
+ format.html { redirect_to url_for( :action => @features[:show] ? 'show' : 'index', :id => @resource.id ) }
252
169
  else
253
170
  format.html { render :action => "edit" }
254
171
  end
@@ -256,14 +173,16 @@ module Releaf
256
173
  end
257
174
 
258
175
  def confirm_destroy
259
- @item = current_object_class.find(params[:id])
260
- authorize! :destroy, @item
176
+ @resource = resource_class.find(params[:id])
177
+ authorize! :destroy, @resource
178
+ raise FeatureDisabled unless @features[:destroy]
261
179
  end
262
180
 
263
181
  def destroy
264
- @item = current_object_class.find(params[:id])
265
- authorize! :destroy, @item
266
- @item.destroy
182
+ @resource = resource_class.find(params[:id])
183
+ authorize! :destroy, @resource
184
+ raise FeatureDisabled unless @features[:destroy]
185
+ @resource.destroy
267
186
 
268
187
  respond_to do |format|
269
188
  format.html { redirect_to url_for( :action => 'index' ) }
@@ -271,8 +190,348 @@ module Releaf
271
190
  end
272
191
 
273
192
 
193
+
194
+
195
+
196
+
197
+ # Helper methods ##############################################################################
198
+
199
+
200
+ def list_action
201
+ if !cookies['base_module:list_action'].blank?
202
+ feature = cookies['base_module:list_action']
203
+ if feature == 'confirm_destroy'
204
+ feature = 'destroy'
205
+ end
206
+ feature = feature.to_sym
207
+ if @features[feature]
208
+ return cookies['base_module:list_action']
209
+ end
210
+ end
211
+
212
+ return 'show' if @features[:show]
213
+ return 'edit'
214
+ end
215
+
216
+ # Defines which fields/associations should be rendered.
217
+ #
218
+ # By default renders resource columns except few (check source).
219
+ #
220
+ # You can override this method to make it possible to render pretty complex
221
+ # views which inludes nested fields.
222
+ #
223
+ # To render field you simply need to add it's name to array.
224
+ #
225
+ # belongs_to relations will be automatically rendered (by default) as
226
+ # select field. For belongs_to to be recognized you need to use Integer
227
+ # field that ends with <tt>_id</tt>
228
+ #
229
+ # You can also render has_many associations. For these associations you
230
+ # need to add either association name, or a Hash. Hash keys must match
231
+ # association name, hash value must be array with nested fields to be
232
+ # rendered.
233
+ #
234
+ # NOTE: currently if you add has_many associations name to array, then it
235
+ # will render all fields (except created_at etc.) including <tt>belongs_to
236
+ # :parent</tt>. This is know bug https://github.com/cubesystems/releaf/issues/64
237
+ #
238
+ # @example
239
+ # def fields_to_display
240
+ # case params[:action]
241
+ # when 'edit', 'update', 'create', 'new'
242
+ # return [
243
+ # 'name',
244
+ # 'category_id',
245
+ # 'description',
246
+ # {'offer_card_types' => ['card_type_id', 'name', 'description']},
247
+ # 'show_banner',
248
+ # 'published',
249
+ # 'item_count',
250
+ # {'images' => ['image_uid']},
251
+ # 'partner_id',
252
+ # 'offer_checkout_places' => ['checkout_place_id']
253
+ # ]
254
+ # else
255
+ # return super
256
+ # end
257
+ # end
258
+ #
259
+ # Fields will be rendered in same order as specified in array
260
+ #
261
+ # @return array that represent which fields to render
262
+ def fields_to_display
263
+ cols = resource_class.column_names - %w[id created_at updated_at encrypted_password position]
264
+ unless %w[new edit update create].include? params[:action]
265
+ cols -= %w[password password_confirmation]
266
+ end
267
+ return cols
268
+ end
269
+
270
+
271
+ def secondary_panel
272
+ return '' unless @panel_layout
273
+ @_secondary_panel ||= render_to_string( :partial => "secondary_panel", :layout => false, :locals => build_secondary_panel_variables)
274
+ end
275
+
276
+ def build_secondary_panel_variables
277
+ menu_item_name = self.class.name.underscore.sub(/_controller$/, '')
278
+
279
+ # if this item is defined in main menu, then there will be no altmenu
280
+ # defined for it in alt menu, instead this method should be overriden in
281
+ # particular controller to return structure needed to render alt menu
282
+ return {} if Releaf.main_menu.include? menu_item_name
283
+
284
+ # if this item was not found in main menu, then we need to find it in one
285
+ # of alt menus. This way we'll know which alt menu to render.
286
+ base_menus = Releaf.main_menu.reject { |item| item[0] != '*' }
287
+ base_menus.each do |base_menu_name|
288
+ if view_context.base_menu_items(base_menu_name).include?(menu_item_name)
289
+ build_menu = { :menu => {} }
290
+
291
+ base_menu = Releaf.base_menu[base_menu_name]
292
+
293
+ base_menu.each do |section|
294
+ section_name = section[0].to_sym
295
+ build_menu[:menu][section_name] = []
296
+ section[1].each do |item|
297
+ build_menu[:menu][section_name].push({:controller => item.split(/#/, 2).first})
298
+ end
299
+ end
300
+
301
+ return build_menu
302
+ end
303
+ end
304
+
305
+ # coundn't find current controller in base_menu
306
+ return {}
307
+ end
308
+
309
+ # Tries to return resource class.
310
+ #
311
+ # If it fails to return proper resource class for your controller, or your
312
+ # controllers name has no relation to resource class name, then simply
313
+ # override this method to return class that you want.
314
+ #
315
+ # @return class
316
+ def resource_class
317
+ @resource_class ||= self.class.name.split('::').last.sub(/Controller$/, '').classify.constantize
318
+ end
319
+
320
+
321
+ # Cheheck if there is a template in lookup_context with given name.
322
+ #
323
+ # @return `true` or `false`
324
+ def has_template? name
325
+ lookup_context.template_exists?( name, lookup_context.prefixes, false )
326
+ end
327
+
328
+ def find_parent_template( name )
329
+ lookup_context.find_template( name, lookup_context.prefixes.slice( 1, lookup_context.prefixes.length ), false )
330
+ end
331
+
332
+ def render_parent_template( name, locals = {} )
333
+ template = find_parent_template( name )
334
+ if template.blank?
335
+ return 'blank'
336
+ end
337
+ arguments = { :layout => false, :locals => locals, :template => template.virtual_path }
338
+ return render_to_string( arguments ).html_safe
339
+ end
340
+
341
+ # Helps to determinate which template to render in :show and :edit feature
342
+ # for given objects attribute.
343
+ #
344
+ # @return [field_type, use_i18n]
345
+ #
346
+ # where field_type is a string representing field type
347
+ # and use_i18n is a `true` or `false`. If use_i18n is true, then template
348
+ # with localization features should be used (if exists)
349
+ #
350
+ # This helper is used by views.
351
+ #
352
+ # @todo document rendering conventions
353
+ def render_field_type( obj, attribute_name )
354
+ field_type = nil
355
+ use_i18n = false
356
+ obj_class = obj.class
357
+
358
+ if obj_class.respond_to?(:translations_table_name)
359
+ use_i18n = obj_class.translates.include?(attribute_name.to_sym)
360
+ end
361
+
362
+ column_type = :string
363
+ if attribute_name.to_s =~ /^#{Releaf::Node::COMMON_FIELD_NAME_PREFIX}/
364
+ column_type = obj.common_field_field_type(attribute_name)
365
+ else
366
+ column_type = obj_class.columns_hash[attribute_name.to_s].try(:type) || :string
367
+ end
368
+
369
+ case column_type.to_sym
370
+ when :boolean
371
+ field_type = 'boolean'
372
+
373
+ when :string
374
+ case attribute_name.to_s
375
+ when /(thumbnail|image|photo|picture|avatar|logo|banner|icon)_uid$/
376
+ field_type = 'image'
377
+
378
+ when /_uid$/
379
+ field_type = 'file'
380
+
381
+ when /password/, 'pin'
382
+ field_type = 'password'
383
+
384
+ when /_email$/, 'email'
385
+ field_type = 'email'
386
+
387
+ when /_link$/, 'link'
388
+ field_type = 'link'
389
+
390
+ else
391
+ field_type = 'text'
392
+ end
393
+
394
+ when :integer
395
+ if attribute_name.to_s =~ /_id$/ and obj_class.reflect_on_association( attribute_name[0..-4].to_sym )
396
+ field_type = 'item'
397
+ else
398
+ field_type = 'text'
399
+ end
400
+
401
+ when :text
402
+ case attribute_name.to_s
403
+ when /_(url|homepage)$/, 'homepage', 'url'
404
+ field_type = 'url'
405
+
406
+ when /_link$/, 'url'
407
+ field_type = 'link_or_url'
408
+
409
+ when /_html$/, 'html'
410
+ field_type = 'richtext'
411
+
412
+ else
413
+ field_type = 'textarea'
414
+ end
415
+
416
+ when :datetime
417
+ field_type = 'datetime'
418
+
419
+ when :date
420
+ field_type = 'date'
421
+
422
+ when :time
423
+ field_type = 'time'
424
+
425
+ end
426
+
427
+ return [field_type || 'text', use_i18n]
428
+ end
429
+
430
+ # calls `#to_text` on resource if resource supports it. Otherwise calls
431
+ # fallback method
432
+ def resource_to_text resource, fallback=:to_s
433
+ resource.send resource_to_text_method(resource, fallback)
434
+ end
435
+
436
+ # @return `:to_text` if resource supports `#to_text`, otherwise fallback.
437
+ def resource_to_text_method resource, fallback=:to_s
438
+ if resource.respond_to?(:to_text)
439
+ return :to_text
440
+ else
441
+ Rails.logger.warn "Re:Leaf: #{resource.class.name} doesn't support #to_text method. Please define it"
442
+ return fallback
443
+ end
444
+ end
445
+
446
+ protected
447
+
448
+ def required_params
449
+ params.require(:resource)
450
+ end
451
+
452
+ # Called before each request by before_filter.
453
+ # It sets various instance variables, that are later used in views and # controllers
454
+ #
455
+ # == Defines
456
+ # @fetures::
457
+ # Hash with symbol keys and boolean values. Each key represents action
458
+ # (currently only `:edit`, `:create`, `:show`, `:destroy` are supported). If one
459
+ # of features is disabled, then routing to it will raise <tt>Releaf::FeatureDisabled</tt>
460
+ # error
461
+ #
462
+ # @continuous_scroll::
463
+ # Boolean. If set to `true` will enable continuous scrool in `#index` view
464
+ #
465
+ # @resources_per_page::
466
+ # Integer - sets the number of resources to display on `#index` view
467
+ #
468
+ # To change controller settings `setup` method should be overriden like this
469
+ #
470
+ # @example
471
+ # def setup
472
+ # super
473
+ # @fetures[:show] = false
474
+ # @resources_per_page = 20
475
+ # end
476
+ def setup
477
+ @features = {
478
+ :edit => true,
479
+ :create => true,
480
+ :show => true,
481
+ :destroy => true
482
+ }
483
+ @continuous_scroll = false
484
+ @panel_layout = true
485
+ @resources_per_page = 40
486
+ end
487
+
488
+ # Returns which resource attributes can be updated with mass assignment.
489
+ #
490
+ # The resulting array will be passed to strong_parameters ``permit``
491
+ def resource_params
492
+ return unless %w[create update].include? params[:action]
493
+ resource_class.column_names
494
+ end
495
+
274
496
  private
275
497
 
498
+ def relations_for_includes
499
+ return nil
500
+ # XXX there's a problem with relations that have conditions with proc.
501
+ # If you refer to models attribute in proc, this function will break.
502
+ # As temp workaround we'll simply skip including relations that have conditions for now.
503
+ rels = []
504
+ fields_to_display.each do |field|
505
+ if (field.is_a? String or field.is_a? Symbol) and field =~ /_id$/
506
+ reflection = resource_class.reflect_on_association(field[0..-4].to_sym)
507
+ next if reflection.blank?
508
+ next unless reflection.conditions.blank?
509
+ rels.push field[0..-4]
510
+ elsif field.is_a? Hash
511
+ field.keys.each do |key|
512
+ if key =~ /_id$/
513
+ reflection = resource_class.reflect_on_association(key[0..-4].to_sym)
514
+ next if reflection.blank?
515
+ next unless reflection.conditions.blank?
516
+ rels.push key[0..-4] if resource_class.reflect_on_association(key[0..-4].to_sym)
517
+ else
518
+ reflection = resource_class.reflect_on_association(key.to_sym)
519
+ next if reflection.blank?
520
+ next unless reflection.conditions.blank?
521
+ rels.push key if resource_class.reflect_on_association(key.to_sym)
522
+ end
523
+ end
524
+ end
525
+ end
526
+ return rels
527
+ end
528
+
529
+ def valid_order_by
530
+ return nil if params[:order_by].blank?
531
+ return nil unless resource_class.column_names.include?(params[:order_by].sub(/-reverse$/, ''))
532
+ return resource_class.table_name + '.' + params[:order_by].sub(/-reverse$/, ' DESC')
533
+ end
534
+
276
535
  def set_locale
277
536
  I18n.locale = if params[:locale] && Settings.i18n_locales.include?(params[:locale])
278
537
  params[:locale]
@@ -281,6 +540,8 @@ module Releaf
281
540
  else
282
541
  I18n.default_locale
283
542
  end
543
+
544
+ Releaf::Globalize3::Fallbacks.set
284
545
  end
285
546
 
286
547
  def filter_templates