weeler 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rspec +1 -1
  4. data/.travis.yml +7 -2
  5. data/CHANGELOG.md +149 -1
  6. data/LICENSE.txt +2 -2
  7. data/README.md +83 -1
  8. data/app/.DS_Store +0 -0
  9. data/app/assets/javascripts/weeler/init.js.coffee +13 -2
  10. data/app/assets/javascripts/weeler/lib/notify.js +18 -0
  11. data/app/assets/javascripts/weeler/lib/sortable.js +9 -0
  12. data/app/assets/stylesheets/weeler/init.css.erb +2 -1
  13. data/app/assets/stylesheets/weeler/style.css.scss +22 -0
  14. data/app/controllers/concerns/weeler/section_seo.rb +16 -0
  15. data/app/controllers/weeler/administration_controller.rb +11 -0
  16. data/app/controllers/weeler/application_controller.rb +5 -0
  17. data/app/controllers/weeler/base_controller.rb +16 -12
  18. data/app/controllers/weeler/configuration_controller.rb +9 -0
  19. data/app/controllers/weeler/content_controller.rb +12 -0
  20. data/app/controllers/weeler/home_controller.rb +5 -2
  21. data/app/controllers/weeler/seo_items_controller.rb +24 -0
  22. data/app/controllers/weeler/settings_controller.rb +21 -0
  23. data/app/controllers/weeler/static_sections_controller.rb +19 -0
  24. data/app/controllers/weeler/translations_controller.rb +36 -18
  25. data/app/models/concerns/weeler/seoable.rb +61 -0
  26. data/app/models/concerns/weeler/sluger.rb +32 -0
  27. data/app/models/settings.rb +2 -0
  28. data/app/models/weeler/seo.rb +9 -0
  29. data/app/views/kaminari/{_first_page.html.erb → weeler/_first_page.html.erb} +1 -1
  30. data/app/views/kaminari/{_gap.html.erb → weeler/_gap.html.erb} +1 -1
  31. data/app/views/kaminari/{_last_page.html.erb → weeler/_last_page.html.erb} +1 -1
  32. data/app/views/kaminari/{_next_page.html.erb → weeler/_next_page.html.erb} +1 -1
  33. data/app/views/kaminari/{_page.html.erb → weeler/_page.html.erb} +0 -0
  34. data/app/views/kaminari/{_paginator.html.erb → weeler/_paginator.html.erb} +1 -1
  35. data/app/views/kaminari/{_prev_page.html.erb → weeler/_prev_page.html.erb} +1 -1
  36. data/app/views/layouts/weeler/base.html.haml +22 -0
  37. data/{lib/generators/weeler/templates/views/weeler/example/index.html.erb → app/views/weeler/administration/_filter.html.haml} +0 -0
  38. data/app/views/weeler/administration/_header_row.html.haml +5 -0
  39. data/app/views/weeler/administration/_row.html.haml +5 -0
  40. data/app/views/weeler/administration/_side_navbar.html.haml +8 -0
  41. data/app/views/weeler/administration/index.html.haml +17 -0
  42. data/app/views/weeler/administration/welcome.html.haml +5 -0
  43. data/app/views/weeler/base/_flash.html.haml +3 -0
  44. data/app/views/weeler/base/_footer.html.haml +2 -0
  45. data/app/views/weeler/base/_header_navbar.html.haml +19 -0
  46. data/app/views/weeler/base/_side_navbar.html.haml +2 -0
  47. data/app/views/weeler/configuration/_side_navbar.html.haml +12 -0
  48. data/app/views/weeler/configuration/index.html.haml +3 -0
  49. data/app/views/weeler/content/_error_messages.html.haml +5 -0
  50. data/app/views/weeler/content/_form.html.haml +6 -0
  51. data/app/views/weeler/content/_list.html.haml +23 -0
  52. data/app/views/weeler/content/_object_seo.html.haml +31 -0
  53. data/app/views/weeler/content/_side_navbar.html.haml +17 -0
  54. data/app/views/weeler/content/_sortable_list.html.haml +24 -0
  55. data/app/views/weeler/content/edit.html.haml +2 -0
  56. data/app/views/weeler/content/index.html.haml +10 -0
  57. data/app/views/weeler/content/new.html.haml +2 -0
  58. data/app/views/weeler/content/welcome.html.haml +3 -0
  59. data/app/views/weeler/home/_side_navbar.html.haml +8 -0
  60. data/app/views/weeler/home/about.html.haml +15 -0
  61. data/app/views/weeler/home/index.html.haml +3 -0
  62. data/app/views/weeler/seo_items/edit.html.haml +28 -0
  63. data/app/views/weeler/seo_items/index.html.haml +15 -0
  64. data/app/views/weeler/settings/index.html.haml +19 -0
  65. data/app/views/weeler/static_sections/show.html.haml +26 -0
  66. data/app/views/weeler/translations/_form.html.haml +27 -0
  67. data/app/views/weeler/translations/_translation.html.haml +11 -0
  68. data/app/views/weeler/translations/edit.html.haml +14 -0
  69. data/app/views/weeler/translations/index.html.haml +76 -0
  70. data/app/views/weeler/translations/new.html.haml +13 -0
  71. data/lib/.DS_Store +0 -0
  72. data/lib/generators/weeler/.DS_Store +0 -0
  73. data/lib/generators/weeler/install_generator.rb +30 -26
  74. data/lib/generators/weeler/templates/assets/javascripts/weeler/app/index.js +2 -0
  75. data/lib/generators/weeler/templates/assets/stylesheets/weeler/app/index.css +4 -0
  76. data/lib/generators/weeler/templates/controllers/weeler/application_controller.rb +6 -0
  77. data/lib/generators/weeler/templates/initializers/weeler.rb +30 -2
  78. data/lib/generators/weeler/templates/migrations/create_weeler_seos.rb +14 -0
  79. data/lib/generators/weeler/templates/migrations/create_weeler_settings.rb +17 -0
  80. data/lib/generators/weeler/templates/migrations/translate_weeler_seos.rb +15 -0
  81. data/lib/generators/weeler/templates/views/weeler/.keep +0 -0
  82. data/lib/i18n/backend/weeler.rb +102 -22
  83. data/lib/i18n/backend/weeler/dedupe.rb +31 -0
  84. data/lib/i18n/backend/weeler/exporter.rb +67 -5
  85. data/lib/i18n/backend/weeler/html_checker.rb +41 -0
  86. data/lib/i18n/backend/weeler/importer.rb +30 -13
  87. data/lib/i18n/backend/weeler/translation.rb +12 -7
  88. data/lib/i18n/humanize_missing_translations.rb +1 -0
  89. data/lib/i18n/weeler.rb +8 -2
  90. data/lib/tasks/weeler.rake +8 -0
  91. data/lib/weeler.rb +80 -7
  92. data/lib/weeler/.DS_Store +0 -0
  93. data/lib/weeler/action_controller/acts/restful.rb +185 -0
  94. data/lib/weeler/action_dispatch/routing/mapper.rb +87 -0
  95. data/lib/weeler/action_view/helpers/form_helper.rb +13 -0
  96. data/lib/weeler/action_view/helpers/image_form_helper.rb +84 -0
  97. data/lib/weeler/action_view/helpers/translation_helper.rb +15 -0
  98. data/lib/weeler/deprecator.rb +9 -0
  99. data/lib/weeler/engine.rb +18 -4
  100. data/lib/weeler/version.rb +7 -1
  101. data/rspec.html +426 -147
  102. data/spec/.DS_Store +0 -0
  103. data/spec/controllers/translations_controller_spec.rb +76 -5
  104. data/spec/dummy/app/controllers/weeler/posts_controller.rb +3 -7
  105. data/spec/dummy/app/models/post.rb +17 -0
  106. data/spec/dummy/app/models/translation.rb +2 -0
  107. data/spec/dummy/config/locales/en.yml +4 -1
  108. data/spec/dummy/config/routes.rb +3 -3
  109. data/spec/dummy/db/development.sqlite3 +0 -0
  110. data/spec/dummy/db/migrate/20140123083704_create_weeler_seos.rb +14 -0
  111. data/spec/dummy/db/migrate/20140123083705_create_weeler_settings.rb +17 -0
  112. data/spec/dummy/db/migrate/{20131015144900_create_weeler_translations.rb → 20140123083706_create_weeler_translations.rb} +0 -0
  113. data/spec/dummy/db/migrate/20140123083707_translate_weeler_seos.rb +15 -0
  114. data/spec/dummy/db/migrate/20140718103237_create_posts.rb +12 -0
  115. data/spec/dummy/db/migrate/20140726151210_create_translations.rb +12 -0
  116. data/spec/dummy/db/schema.rb +59 -1
  117. data/spec/dummy/db/test.sqlite3 +0 -0
  118. data/spec/dummy/log/development.log +221 -0
  119. data/spec/factories/dummy_posts.rb +6 -0
  120. data/spec/fixtures/.DS_Store +0 -0
  121. data/spec/routing/routes_spec.rb +4 -4
  122. data/spec/spec_helper.rb +14 -3
  123. data/spec/weeler/action_controller/acts/restful_spec.rb +155 -0
  124. data/spec/weeler/action_view/helpers/form_helper_spec.rb +26 -0
  125. data/spec/weeler/action_view/helpers/translation_helper_spec.rb +16 -0
  126. data/spec/weeler/i18n/backend/weeler/dedupe_spec.rb +21 -0
  127. data/spec/weeler/i18n/backend/weeler/exporter_spec.rb +2 -4
  128. data/spec/weeler/i18n/backend/weeler/importer_spec.rb +5 -2
  129. data/spec/weeler/i18n/backend/weeler_spec.rb +121 -23
  130. data/weeler.gemspec +15 -7
  131. metadata +207 -85
  132. data/.DS_Store +0 -0
  133. data/app/assets/stylesheets/weeler/vendor/bootstrap.css +0 -6086
  134. data/app/views/layouts/weeler/base.html.erb +0 -40
  135. data/app/views/weeler/home/about.html.erb +0 -16
  136. data/app/views/weeler/home/index.html.erb +0 -4
  137. data/app/views/weeler/shared/_flash.html.erb +0 -17
  138. data/app/views/weeler/shared/_footer.html.erb +0 -3
  139. data/app/views/weeler/shared/_header_navbar.html.erb +0 -18
  140. data/app/views/weeler/shared/_side_navbar.html.erb +0 -14
  141. data/app/views/weeler/translations/_form.html.erb +0 -43
  142. data/app/views/weeler/translations/_translation.html.erb +0 -11
  143. data/app/views/weeler/translations/edit.html.erb +0 -19
  144. data/app/views/weeler/translations/index.html.erb +0 -103
  145. data/app/views/weeler/translations/new.html.erb +0 -19
  146. data/lib/generators/weeler/templates/controllers/weeler/example_controller.rb.example +0 -7
  147. data/lib/i18n/backend/weeler/exporter/active_record.rb +0 -37
  148. data/lib/i18n/backend/weeler/exporter/active_record_relation.rb +0 -38
  149. data/lib/i18n/backend/weeler/store_procs.rb +0 -39
  150. data/lib/weeler/route_mapper.rb +0 -41
  151. data/spec/dummy/db/production.sqlite3 +0 -0
  152. data/spec/dummy/log/test.log +0 -88454
@@ -0,0 +1,41 @@
1
+ # This module is intended to be mixed into the Weeler backend to allow
2
+ # checks if translation is html
3
+ #
4
+ # I18n.backend = I18n::Backend::Weeler.new
5
+ # I18n::Backend::Weeler::Translation.send(:include, I18n::Backend::Weeler::HtmlChecker)
6
+ #
7
+ # The HtmlChecker module requires html-scanner
8
+ # was extracted from the original backend.
9
+
10
+ begin
11
+ require 'action_view/vendor/html-scanner'
12
+ rescue LoadError => e
13
+ puts "can't use Html because: #{e.message}"
14
+ end
15
+
16
+ module I18n
17
+ module Backend
18
+ class Weeler
19
+ module HtmlChecker
20
+
21
+ def html?
22
+ if html_safe_translation_key?(self.key) ||
23
+ (self.value.present? && HTML::FullSanitizer.new.sanitize(self.value.to_s).length != self.value.to_s.length)
24
+ return true
25
+ else
26
+ return false
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def html_safe_translation_key?(key)
33
+ key.to_s =~ /(\b|_|\.)html$/
34
+ end
35
+
36
+ Translation.send(:include, HtmlChecker)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -1,3 +1,13 @@
1
+ # Weeler I18n backend import helper module.
2
+ #
3
+ # Loads file translations into datebase.
4
+ # Supports: csv, xls, xlsx or ods
5
+ #
6
+ # if params[:file].present?
7
+ # I18n::Backend::Weeler::Translation.import params[:file]
8
+ # Settings.i18n_updated_at = Time.now
9
+ # end
10
+
1
11
  begin
2
12
  require 'roo'
3
13
  rescue LoadError => e
@@ -9,27 +19,21 @@ module I18n
9
19
  class Weeler
10
20
 
11
21
  module Importer
12
-
13
22
  extend ActiveSupport::Concern
14
23
 
15
24
  module ClassMethods
16
25
 
17
-
18
-
19
- def import path
20
-
21
- xls = Roo::Excelx.new(path, file_warning: :ignore)
22
-
26
+ # Loads file and iterates each sheet and row.
27
+ def import file
28
+ xls = open_spreadsheet file
23
29
  xls.each_with_pagename do |name, sheet|
24
-
30
+
25
31
  # Lookup locales
26
32
  locales = locales_from_xlsx_sheet_row(sheet.row(1))
27
33
 
28
34
  # Lookup values
29
35
  (2..sheet.last_row).each do |row_no|
30
-
31
36
  store_translations_from_xlsx_row(sheet.row(row_no), locales)
32
-
33
37
  end # rows
34
38
 
35
39
  end # sheets
@@ -38,6 +42,18 @@ module I18n
38
42
 
39
43
  private
40
44
 
45
+ # Open csv, xls, xlsx or ods file and read content
46
+ def open_spreadsheet(file)
47
+ case File.extname(file.original_filename)
48
+ when ".csv" then Roo::Csv.new(file.path, file_warning: :ignore)
49
+ when ".xls" then Roo::Excel.new(file.path, file_warning: :ignore)
50
+ when ".xlsx" then Roo::Excelx.new(file.path, file_warning: :ignore)
51
+ when ".ods" then Roo::OpenOffice.new(file.path, file_warning: :ignore)
52
+ else raise "Unknown file type: #{file.original_filename}"
53
+ end
54
+ end
55
+
56
+ # Lookup locales and sequence for loading
41
57
  def locales_from_xlsx_sheet_row row
42
58
  locales = []
43
59
  row.each_with_index do |cell, i|
@@ -48,11 +64,12 @@ module I18n
48
64
  locales
49
65
  end
50
66
 
67
+ # Iterate each cell in row and store translation by locale
51
68
  def store_translations_from_xlsx_row row, locales
52
69
  locale = nil
53
70
  key = nil
54
71
  value = nil
55
-
72
+
56
73
  row.each_with_index do |cell, i|
57
74
  if i == 0
58
75
  key = cell
@@ -63,9 +80,9 @@ module I18n
63
80
  end
64
81
  end
65
82
 
83
+ # Store locale if locale and key present
66
84
  def store_translation_from_xlsx_cell locale, key, cell
67
85
  value = cell.nil? ? '' : cell
68
- # value = cell
69
86
 
70
87
  if locale.present? && key.present?
71
88
  translation = Translation.find_or_initialize_by locale: locale, key: key
@@ -82,4 +99,4 @@ module I18n
82
99
  Translation.send(:include, Importer)
83
100
  end
84
101
  end
85
- end
102
+ end
@@ -54,6 +54,11 @@ module I18n
54
54
  serialize :value
55
55
  serialize :interpolations, Array
56
56
 
57
+ scope :except_key, -> (key) { where("key NOT LIKE ?", "#{key}%") }
58
+
59
+ validates :key, :uniqueness => { :scope => :locale }
60
+ validates :key, presence: true
61
+
57
62
  class << self
58
63
 
59
64
  def locale(locale)
@@ -73,15 +78,15 @@ module I18n
73
78
  where("#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace)
74
79
  end
75
80
 
76
- def available_locales
77
- Translation.select("DISTINCT locale").map { |t| t.locale.to_sym }
78
- end
79
81
 
80
- # This problably works only with PG
81
82
  def groups
82
- # Translation.select("DISTINCT split_part(key, '.', 1), split_part(key, '.', 1) AS key_group").order("key_group").map { |t| t.key_group.to_sym }
83
- groups_records = Translation.select("key").order("key").map{ |t| t.key.split(".")[0] }.uniq{ |t| t}
84
- groups_records.uniq{ |t| t }
83
+ groups_records = Translation.select("key")
84
+
85
+ ::Weeler.excluded_i18n_groups.each do |key|
86
+ groups_records = groups_records.except_key(key)
87
+ end
88
+ groups_records = groups_records.order("key")
89
+ groups_records.map{ |t| t.key.split(".")[0] }.uniq{ |t| t}
85
90
  end
86
91
  end
87
92
 
@@ -1,4 +1,5 @@
1
1
  module I18n
2
+ # Show only last part from key in humanize mode
2
3
  module HumanizeMissingTranslations
3
4
  def call(exception, locale, key, options)
4
5
  if exception.is_a?(I18n::MissingTranslation)
data/lib/i18n/weeler.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  require 'i18n'
2
+
2
3
  require 'i18n/humanize_missing_translations'
4
+ I18n.exception_handler.extend I18n::HumanizeMissingTranslations
5
+
3
6
  require 'i18n/backend/weeler'
7
+ weeler_i18n_backend = I18n::Backend::Weeler.new
8
+ weeler_i18n_backend.i18n_cache = Weeler.i18n_cache
9
+ I18n.backend = I18n::Backend::Chain.new(weeler_i18n_backend, I18n::Backend::Simple.new)
4
10
 
5
- I18n.exception_handler.extend I18n::HumanizeMissingTranslations
6
- I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Weeler.new, I18n::Backend::Simple.new)
11
+ logger = Logger.new(STDOUT)
12
+ logger.info "Weeler i18n backend loaded"
@@ -0,0 +1,8 @@
1
+ namespace :weeler do
2
+ namespace :translations do
3
+ desc "Remove all weeler i18n translation dublicates"
4
+ task dedupe: :environment do
5
+ I18n::Backend::Weeler::Translation.dedupe
6
+ end
7
+ end
8
+ end
data/lib/weeler.rb CHANGED
@@ -1,10 +1,25 @@
1
1
  require "weeler/version"
2
+ require "weeler/deprecator"
3
+
4
+ require 'logger'
2
5
  require "rails"
3
- require "weeler/route_mapper"
6
+
4
7
  require "weeler/engine"
8
+
9
+ # 3rd party
10
+ require "haml"
5
11
  require "kaminari"
12
+ require "globalize"
13
+ require "jquery-ui-rails"
14
+ require "rails-settings-cached"
6
15
 
7
16
  module Weeler
17
+ #
18
+ # => Static sections in content menu bottom
19
+ # => [{about: [{title: :text_field, content: :text_area}]}]
20
+ #
21
+ mattr_accessor :static_sections
22
+ @@static_sections = {}
8
23
 
9
24
  mattr_accessor :create_missing_translations
10
25
  @@create_missing_translations = true
@@ -12,18 +27,76 @@ module Weeler
12
27
  mattr_accessor :use_weeler_i18n
13
28
  @@use_weeler_i18n = true
14
29
 
15
- mattr_accessor :menu_items
16
- @@menu_items = []
17
-
18
30
  mattr_accessor :required_user_method
19
31
  @@required_user_method = nil
20
32
 
33
+ mattr_accessor :logout_path
34
+ @@logout_path = nil
35
+
36
+ # Rafacture this to one menu module
37
+ mattr_accessor :content_menu_items
38
+ @@content_menu_items = []
39
+
40
+ # Rafacture this to one menu module
41
+ mattr_accessor :static_menu_items
42
+ @@static_menu_items = []
43
+
44
+ # Rafacture this to one menu module
45
+ mattr_accessor :administration_menu_items
46
+ @@administration_menu_items = []
47
+
48
+ # Rafacture this to one menu module
49
+ mattr_accessor :configuration_menu_items
50
+ @@configuration_menu_items = []
51
+
52
+ # Rafacture this to one menu module
53
+ mattr_accessor :main_menu_items
54
+ @@main_menu_items = []
55
+
56
+ mattr_accessor :excluded_i18n_groups
57
+ @@excluded_i18n_groups = [:activerecord, :attributes, :helpers, :views, :i18n, :weeler]
58
+
59
+ mattr_accessor :i18n_cache
60
+ @@i18n_cache = ActiveSupport::Cache::MemoryStore.new
61
+
62
+ mattr_accessor :mount_location_namespace
63
+ @@mount_location_namespace = "weeler"
64
+
21
65
  def self.setup
22
- if Weeler.use_weeler_i18n
66
+ yield self
67
+ if Weeler.use_weeler_i18n == true && ActiveRecord::Base.connection.table_exists?('weeler_translations')
23
68
  require "i18n/weeler"
69
+ Weeler.static_sections.each do |key, section|
70
+ Weeler.static_menu_items << {name: key.to_s.capitalize, weeler_path: "static_sections/#{key}"}
71
+ end
24
72
  end
73
+ build_main_menu
74
+ end
25
75
 
26
- yield self
76
+ def self.build_main_menu
77
+ home_menu_item = {name: "Home", weeler_path: ""}
78
+ content_menu_item = {name: "Content", weeler_path: "content"}
79
+ administration_menu_item = {name: "Administration", weeler_path: "administration"}
80
+ configuration_menu_item = {name: "Configuration", weeler_path: "configuration"}
81
+
82
+ Weeler.main_menu_items.delete(home_menu_item)
83
+ Weeler.main_menu_items.delete(content_menu_item)
84
+ Weeler.main_menu_items.delete(administration_menu_item)
85
+ Weeler.main_menu_items.delete(configuration_menu_item)
86
+
87
+
88
+ Weeler.main_menu_items.insert(0, {name: "Home", weeler_path: ""}) unless Weeler.main_menu_items.include?(home_menu_item)
89
+
90
+ if (Weeler.content_menu_items.size > 0 || Weeler.static_menu_items.size > 0) && !Weeler.main_menu_items.include?(content_menu_item)
91
+ Weeler.main_menu_items.insert(1, {name: "Content", weeler_path: "content"})
92
+ end
93
+
94
+ Weeler.main_menu_items.insert(2, administration_menu_item) if Weeler.administration_menu_items.size > 0 && !Weeler.main_menu_items.include?(administration_menu_item)
95
+ Weeler.main_menu_items.push(configuration_menu_item) unless Weeler.main_menu_items.include?(configuration_menu_item)
96
+ Weeler.main_menu_items = Weeler.main_menu_items.compact
27
97
  end
28
- end
29
98
 
99
+ def self.translations
100
+ I18n::Backend::Weeler::Translation if Weeler.use_weeler_i18n == true
101
+ end
102
+ end
data/lib/weeler/.DS_Store CHANGED
Binary file
@@ -0,0 +1,185 @@
1
+ module Weeler
2
+ module ActionController
3
+ module Acts
4
+ module Restful
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ # Weeler action controller method.
9
+ # It creates all restful actions for action controller. Create a controller for your
10
+ # model (e.g. Post) what you want to administrate in weeler. Add method <tt>acts_as_restful Post</tt>
11
+ # and permit params for your resource - option <tt>permit_params</tt>. Also you can paginate - add
12
+ # option <tt>paginate</tt>
13
+ # e.g.
14
+ #
15
+ # class Weeler::PostController < Weeler::ContentController
16
+ # acts_as_restful Post, permit_params: [:title, :body], paginate: 50
17
+ # end
18
+ #
19
+ # It will handle <tt>:index</tt>, <tt>:new</tt>, <tt>:edit</tt>, <tt>:update</tt>,
20
+ # <tt>:destroy</tt>, <tt>:order</tt>, <tt>:activation</tt> and <tt>:remove_image</tt> actions
21
+ #
22
+ # For permiting custom by role or permiting all params (permit!),
23
+ # you must add block <tt>permit_params: -> (params) { params.require(:post).permit! }</tt>
24
+ #
25
+ # You should implement form file with your own active record attributes.
26
+ # To do that, create <tt>_form.html.haml</tt> in <tt>views/weeler/_YOUR_RESOURCE_/_form.html.haml</tt>
27
+ # where <tt>_YOUR_RESOURCE_</tt> is name of your resource.
28
+ #
29
+ # Also you can override all standart restful action view and implement, if you need,
30
+ # <tt>_filter.html.haml</tt>
31
+ #
32
+ def acts_as_restful(active_record_model, options = {})
33
+ before_filter(:load_record, only: [:show, :edit, :update, :destroy, :remove_image])
34
+
35
+ include InstanceMethodsOnActivation
36
+ helper_method :item_humanized_name
37
+
38
+ cattr_accessor :model do
39
+ active_record_model
40
+ end
41
+
42
+ cattr_accessor :permited_params do
43
+ options[:permit_params] if options.include? :permit_params
44
+ end
45
+
46
+ cattr_accessor :paginate do
47
+ options[:paginate] if options.include? :paginate
48
+ end
49
+
50
+ cattr_accessor :order_by do
51
+ options[:order_by] if options.include? :order_by
52
+ end
53
+ end
54
+ end
55
+
56
+ # These methods only activate if 'acts_as_restful' is called
57
+ #
58
+ module InstanceMethodsOnActivation
59
+
60
+ def index
61
+ @paginate = paginate
62
+ @items = load_collection
63
+ @items = @items.page(params[:page]).per(@paginate) if @paginate.present? && @paginate > 0
64
+ end
65
+
66
+ def new
67
+ @item = model.new
68
+ load_translations
69
+ end
70
+
71
+ def show
72
+ render :edit
73
+ end
74
+
75
+ def edit
76
+ load_translations
77
+ end
78
+
79
+ def order
80
+ sort
81
+ end
82
+
83
+ def create
84
+ @item = model.new(items_params)
85
+ if @item.save
86
+ redirect_to({ action: :edit, id: @item.id }, {:notice => "Successfully created item"})
87
+ else
88
+ render :action => 'new'
89
+ end
90
+ end
91
+
92
+ def update
93
+ if @item.update_attributes(items_params)
94
+ redirect_to({ action: :edit, id: @item.id }, {:notice => "Successfully updated item"})
95
+ else
96
+ render :action => 'edit'
97
+ end
98
+ end
99
+
100
+ def destroy
101
+ @item.destroy
102
+ redirect_to({ action: :index}, {:notice => "Successfully destroyed item"})
103
+ end
104
+
105
+ def remove_image
106
+ if @item.image.present?
107
+ @item.image.destroy
108
+ @item.image_file_name = nil
109
+ @item.save
110
+ end
111
+ redirect_to({ action: :edit, id: @item.id}, {:notice => "Image successfully removed"})
112
+ end
113
+
114
+ protected
115
+
116
+ def items_params
117
+ if permited_params.is_a? Proc
118
+ permited_params.call(params)
119
+ elsif permited_params.blank?
120
+ warning_suggestion = params[parameterized_name.to_sym].is_a?(Hash) ? params[parameterized_name.to_sym].keys.map{ |k| k.to_sym } : "permit_params:"
121
+ warn "[UNPERMITED PARAMS] To permiting #{params[parameterized_name.to_sym].inspect} params, add 'permit_params: #{warning_suggestion}' option to 'acts_as_restful'"
122
+ else
123
+ params.require(parameterized_name.to_sym).permit(permited_params)
124
+ end
125
+ end
126
+
127
+ def collection; end
128
+
129
+ def parameterized_name
130
+ "#{model.to_s.underscore.downcase}"
131
+ end
132
+
133
+ def item_humanized_name
134
+ "#{parameterized_name.humanize}"
135
+ end
136
+
137
+ def load_translations
138
+ if @item.respond_to? :translations
139
+ I18n.available_locales.each { |locale| @item.translations.find_or_initialize_by(locale: locale) }
140
+ end
141
+ end
142
+
143
+ private
144
+
145
+ def model
146
+ model
147
+ end
148
+
149
+ def load_collection
150
+ return @load_collection if @load_collection.present?
151
+ if model
152
+ if collection
153
+ @load_collection = collection
154
+ else
155
+ @load_collection = model.all
156
+ if order_by.present?
157
+ @load_collection.order(order_by)
158
+ elsif model.new.has_attribute?(:sequence)
159
+ @load_collection.order(:sequence)
160
+ else
161
+ @load_collection.order(created_at: :desc)
162
+ end
163
+ end
164
+ end
165
+ end
166
+
167
+ def load_record
168
+ @item = model.find(params[:id])
169
+ end
170
+
171
+ def sort
172
+ items_sequence = URI.decode_www_form(params[:orders]).map{ |i| i[1] }
173
+ items_sequence.each_with_index do |sequence_item_id, index|
174
+ item = model.find_by id: sequence_item_id
175
+ item.sequence = index
176
+ item.save!
177
+ end
178
+ render :text => 'all ok'
179
+ end
180
+
181
+ end # Instance methods
182
+ end
183
+ end
184
+ end
185
+ end