pages_core 3.4.3 → 3.5.1

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 (215) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -15
  3. data/Rakefile +1 -1
  4. data/app/assets/javascripts/pages/admin.es6.jsx +19 -0
  5. data/app/assets/javascripts/pages/admin/components.es6.jsx +1 -0
  6. data/app/assets/javascripts/pages/admin/components/page_tree.es6.jsx +330 -0
  7. data/app/assets/javascripts/pages/admin/components/page_tree_actions.es6.jsx +8 -0
  8. data/app/assets/javascripts/pages/admin/components/page_tree_node.es6.jsx +374 -0
  9. data/app/assets/javascripts/pages/admin/components/page_tree_store.es6.jsx +161 -0
  10. data/app/assets/javascripts/pages/admin/features/content_tabs.es6.jsx +63 -0
  11. data/app/assets/javascripts/pages/admin/features/edit_page.es6.jsx +141 -0
  12. data/app/assets/javascripts/pages/admin/features/editable_image.es6.jsx +145 -0
  13. data/app/assets/javascripts/pages/admin/features/modal.es6.jsx +90 -0
  14. data/app/assets/javascripts/pages/admin/features/page_images.es6.jsx +338 -0
  15. data/app/assets/javascripts/pages/admin/features/rich_text.es6.jsx +124 -0
  16. data/app/assets/javascripts/pages/admin/features/tag_editor.es6.jsx +160 -0
  17. data/app/assets/javascripts/pages/admin/lib/ajax_extensions.es6.jsx +21 -0
  18. data/app/assets/javascripts/pages/admin/lib/center_on_screen.es6.jsx +22 -0
  19. data/app/assets/javascripts/pages/admin/lib/tree.es6.jsx +294 -0
  20. data/app/assets/javascripts/pages/login_form.es6.jsx +21 -0
  21. data/app/assets/stylesheets/pages/admin.scss +148 -0
  22. data/app/assets/stylesheets/pages/admin/components/buttons.scss +5 -0
  23. data/app/assets/stylesheets/pages/admin/{editable_image.css.erb → components/editable_image.scss} +7 -8
  24. data/app/assets/stylesheets/pages/admin/components/forms.scss +71 -0
  25. data/app/assets/stylesheets/pages/admin/components/header.scss +169 -0
  26. data/app/assets/stylesheets/pages/admin/{images.css.scss.erb → components/images.scss} +6 -11
  27. data/app/assets/stylesheets/pages/admin/components/layout.scss +44 -0
  28. data/app/assets/stylesheets/pages/admin/components/links.scss +43 -0
  29. data/app/assets/stylesheets/pages/admin/components/list_table.scss +58 -0
  30. data/app/assets/stylesheets/pages/admin/{login.css.scss.erb → components/login.scss} +1 -1
  31. data/app/assets/stylesheets/pages/admin/{modal.css.erb → components/modal.scss} +3 -2
  32. data/app/assets/stylesheets/pages/admin/components/page_tree.scss +173 -0
  33. data/app/assets/stylesheets/pages/admin/{pagination.css.scss → components/pagination.scss} +13 -4
  34. data/app/assets/stylesheets/pages/admin/components/sidebar.scss +25 -0
  35. data/app/assets/stylesheets/pages/admin/{tag_editor.css.scss.erb → components/tag_editor.scss} +6 -0
  36. data/app/assets/stylesheets/pages/admin/components/textarea.scss +76 -0
  37. data/app/assets/stylesheets/pages/admin/controllers/pages.scss +196 -0
  38. data/app/assets/stylesheets/pages/admin/controllers/{users.css.erb → users.scss} +0 -0
  39. data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +21 -0
  40. data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +7 -0
  41. data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +7 -0
  42. data/app/assets/stylesheets/pages/admin/{print.css.erb → print.scss} +0 -0
  43. data/app/assets/stylesheets/pages/admin/vars.scss +8 -0
  44. data/app/controllers/admin/invites_controller.rb +10 -6
  45. data/app/controllers/admin/page_files_controller.rb +6 -8
  46. data/app/controllers/admin/page_images_controller.rb +14 -19
  47. data/app/controllers/admin/pages_controller.rb +44 -97
  48. data/app/controllers/admin/password_resets_controller.rb +7 -2
  49. data/app/controllers/concerns/pages_core/add_comments_controller.rb +67 -0
  50. data/app/controllers/concerns/pages_core/admin/news_page_controller.rb +58 -0
  51. data/app/controllers/concerns/pages_core/authentication.rb +1 -1
  52. data/app/controllers/concerns/pages_core/exception_handler.rb +44 -21
  53. data/app/controllers/concerns/pages_core/policies_helper.rb +10 -6
  54. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +43 -0
  55. data/app/controllers/concerns/pages_core/process_titler.rb +2 -2
  56. data/app/controllers/concerns/pages_core/rss_controller.rb +25 -0
  57. data/app/controllers/concerns/pages_core/search_pages_controller.rb +40 -0
  58. data/app/controllers/errors_controller.rb +14 -2
  59. data/app/controllers/pages_core/admin_controller.rb +7 -5
  60. data/app/controllers/pages_core/frontend/page_files_controller.rb +5 -7
  61. data/app/controllers/pages_core/frontend/pages_controller.rb +41 -219
  62. data/app/controllers/pages_core/frontend_controller.rb +8 -2
  63. data/app/controllers/pages_core/sitemaps_controller.rb +5 -4
  64. data/app/formatters/pages_core/html_formatter.rb +33 -23
  65. data/app/helpers/admin/menu_helper.rb +12 -9
  66. data/app/helpers/admin/pages_helper.rb +40 -28
  67. data/app/helpers/pages_core/admin/admin_helper.rb +58 -56
  68. data/app/helpers/pages_core/admin/labelled_field_helper.rb +6 -7
  69. data/app/helpers/pages_core/admin/tag_editor_helper.rb +11 -9
  70. data/app/helpers/pages_core/application_helper.rb +13 -26
  71. data/app/helpers/pages_core/form_builder.rb +71 -134
  72. data/app/helpers/pages_core/head_tags_helper.rb +26 -168
  73. data/app/helpers/pages_core/images_helper.rb +3 -3
  74. data/app/helpers/pages_core/meta_tags_helper.rb +96 -0
  75. data/app/helpers/pages_core/open_graph_tags_helper.rb +51 -0
  76. data/app/helpers/pages_core/page_path_helper.rb +40 -0
  77. data/app/mailers/admin_mailer.rb +14 -14
  78. data/app/models/autopublisher.rb +2 -2
  79. data/app/models/category.rb +8 -8
  80. data/app/models/concerns/pages_core/has_roles.rb +2 -2
  81. data/app/models/concerns/pages_core/humanizable_param.rb +5 -5
  82. data/app/models/concerns/pages_core/page_model/autopublishable.rb +25 -0
  83. data/app/models/concerns/pages_core/page_model/commentable.rb +29 -0
  84. data/app/models/concerns/pages_core/page_model/images.rb +50 -0
  85. data/app/models/concerns/pages_core/page_model/localizable.rb +29 -0
  86. data/app/models/concerns/pages_core/page_model/pathable.rb +115 -0
  87. data/app/models/concerns/pages_core/page_model/redirectable.rb +36 -0
  88. data/app/models/concerns/pages_core/page_model/searchable.rb +41 -0
  89. data/app/models/concerns/pages_core/page_model/sortable.rb +54 -0
  90. data/app/models/concerns/pages_core/page_model/status.rb +50 -0
  91. data/app/models/concerns/pages_core/page_model/templateable.rb +82 -0
  92. data/app/models/concerns/pages_core/page_model/tree.rb +108 -0
  93. data/app/models/page.rb +30 -212
  94. data/app/models/page_builder.rb +4 -6
  95. data/app/models/page_category.rb +7 -0
  96. data/app/models/page_comment.rb +1 -1
  97. data/app/models/page_file.rb +4 -6
  98. data/app/models/page_image.rb +6 -7
  99. data/app/models/page_path.rb +46 -0
  100. data/app/models/password_reset_token.rb +5 -5
  101. data/app/models/role.rb +1 -1
  102. data/app/models/tag.rb +14 -16
  103. data/app/models/tagging.rb +2 -1
  104. data/app/models/user.rb +6 -7
  105. data/app/policies/page_policy.rb +8 -4
  106. data/app/policies/user_policy.rb +1 -1
  107. data/app/serializers/page_tree_serializer.rb +15 -0
  108. data/app/views/admin/invites/new.html.erb +2 -1
  109. data/app/views/admin/invites/show.html.erb +3 -4
  110. data/app/views/admin/pages/_edit_comments.html.erb +22 -6
  111. data/app/views/admin/pages/_edit_content.html.erb +4 -2
  112. data/app/views/admin/pages/_edit_images.html.erb +86 -75
  113. data/app/views/admin/pages/_edit_metadata.html.erb +22 -0
  114. data/app/views/admin/pages/_edit_options.html.erb +23 -15
  115. data/app/views/admin/pages/_pagelisting.html.erb +6 -6
  116. data/app/views/admin/pages/edit.html.erb +11 -6
  117. data/app/views/admin/pages/index.html.erb +12 -53
  118. data/app/views/admin/pages/new.html.erb +3 -3
  119. data/app/views/admin/pages/news.html.erb +1 -1
  120. data/app/views/admin_mailer/invite.text.erb +1 -1
  121. data/app/views/admin_mailer/password_reset.text.erb +1 -1
  122. data/app/views/errors/422.html.erb +7 -0
  123. data/app/views/errors/500_critical.html.erb +1 -1
  124. data/app/views/layouts/admin.html.erb +36 -32
  125. data/app/views/layouts/admin/_header.html.erb +2 -2
  126. data/config/locales/en.yml +38 -1
  127. data/config/routes.rb +40 -23
  128. data/db/migrate/20111219033112_create_pages_tables.rb +25 -29
  129. data/db/migrate/20121010055412_drop_removed_tables.rb +3 -3
  130. data/db/migrate/20130823133208_update_page_redirect_to.rb +0 -13
  131. data/db/migrate/20140203183900_create_roles.rb +5 -2
  132. data/db/migrate/20140920231700_convert_images_to_dis.rb +4 -2
  133. data/db/migrate/20150401131300_localize_images.rb +7 -8
  134. data/db/migrate/20151002174800_create_page_paths.rb +10 -0
  135. data/db/migrate/20151021103400_drop_binaries_table.rb +7 -0
  136. data/db/migrate/20151204151000_remove_page_content_order.rb +5 -0
  137. data/db/migrate/20160330220900_rename_pages_categories.rb +6 -0
  138. data/db/migrate/20160405202700_change_localization_limit.rb +9 -0
  139. data/lib/pages_core.rb +22 -27
  140. data/lib/pages_core/admin_menu_item.rb +16 -3
  141. data/lib/pages_core/archive_finder.rb +40 -13
  142. data/lib/pages_core/cache_sweeper.rb +72 -45
  143. data/lib/pages_core/configuration.rb +2 -2
  144. data/lib/pages_core/configuration/base.rb +4 -8
  145. data/lib/pages_core/configuration/pages.rb +6 -3
  146. data/lib/pages_core/engine.rb +23 -1
  147. data/lib/pages_core/extensions.rb +2 -2
  148. data/lib/pages_core/file_embedder.rb +40 -0
  149. data/lib/pages_core/page_path_constraint.rb +23 -0
  150. data/lib/pages_core/pages_plugin.rb +11 -0
  151. data/lib/pages_core/paginates.rb +3 -3
  152. data/lib/pages_core/plugin.rb +14 -8
  153. data/lib/pages_core/templates.rb +6 -6
  154. data/lib/pages_core/templates/block_configuration.rb +1 -1
  155. data/lib/pages_core/templates/configuration.rb +23 -24
  156. data/lib/pages_core/templates/configuration_handler.rb +1 -1
  157. data/lib/pages_core/templates/configuration_proxy.rb +7 -11
  158. data/lib/pages_core/templates/template_configuration.rb +55 -61
  159. data/lib/pages_core/version.rb +1 -1
  160. data/lib/rails/generators/pages_core/install/install_generator.rb +22 -48
  161. data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +1 -1
  162. data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +6 -3
  163. data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +4 -1
  164. data/lib/rails/generators/pages_core/rspec/templates/factories.rb +1 -1
  165. data/lib/tasks/pages.rake +4 -4
  166. data/lib/tasks/pages/page_paths.rake +12 -0
  167. data/template.rb +2 -2
  168. data/vendor/assets/javascripts/reflux.min.js +1 -0
  169. metadata +173 -85
  170. data/app/assets/images/pages/admin/description-bg.gif +0 -0
  171. data/app/assets/images/pages/admin/drag-handle.gif +0 -0
  172. data/app/assets/images/pages/admin/flash-error-bg.gif +0 -0
  173. data/app/assets/images/pages/admin/formelement-bg.gif +0 -0
  174. data/app/assets/images/pages/admin/header-tab-current-bg.gif +0 -0
  175. data/app/assets/images/pages/admin/list-table-td-bg.gif +0 -0
  176. data/app/assets/images/pages/admin/sidebar-bg.gif +0 -0
  177. data/app/assets/images/pages/admin/textarea_controls.gif +0 -0
  178. data/app/assets/javascripts/pages/admin.js.coffee +0 -54
  179. data/app/assets/javascripts/pages/admin/controllers/base.js.coffee +0 -4
  180. data/app/assets/javascripts/pages/admin/controllers/pages_controller.js.coffee +0 -139
  181. data/app/assets/javascripts/pages/admin/controllers/users_controller.js.coffee +0 -9
  182. data/app/assets/javascripts/pages/admin/features/content_tabs.js.coffee +0 -47
  183. data/app/assets/javascripts/pages/admin/features/editable_image.js.coffee.erb +0 -122
  184. data/app/assets/javascripts/pages/admin/features/modal.js.coffee +0 -66
  185. data/app/assets/javascripts/pages/admin/features/page_images.js +0 -329
  186. data/app/assets/javascripts/pages/admin/features/rich_text.js.coffee +0 -40
  187. data/app/assets/javascripts/pages/admin/features/tag_editor.js +0 -159
  188. data/app/assets/javascripts/pages/admin/lib/ajax_extensions.js.coffee +0 -17
  189. data/app/assets/javascripts/pages/admin/lib/center_on_screen.js.coffee +0 -21
  190. data/app/assets/javascripts/pages/admin/lib/jrichtextarea.js +0 -57
  191. data/app/assets/javascripts/pages/login_form.js.coffee +0 -17
  192. data/app/assets/stylesheets/pages/admin.css.erb +0 -404
  193. data/app/assets/stylesheets/pages/admin/buttons.css.erb +0 -5
  194. data/app/assets/stylesheets/pages/admin/controllers/artists.css.erb +0 -94
  195. data/app/assets/stylesheets/pages/admin/controllers/files.css.erb +0 -58
  196. data/app/assets/stylesheets/pages/admin/controllers/pages.css.scss.erb +0 -178
  197. data/app/assets/stylesheets/pages/admin/forms.css.scss.erb +0 -73
  198. data/app/assets/stylesheets/pages/admin/header.css.erb +0 -129
  199. data/app/assets/stylesheets/pages/admin/links.css.erb +0 -34
  200. data/app/assets/stylesheets/pages/admin/list_table.css.erb +0 -56
  201. data/app/assets/stylesheets/pages/admin/sidebar.css.erb +0 -39
  202. data/app/assets/stylesheets/pages/admin/sortable_images.css.erb +0 -18
  203. data/app/assets/stylesheets/pages/admin/textarea.css.erb +0 -55
  204. data/app/models/concerns/pages_core/page_tree.rb +0 -85
  205. data/app/models/concerns/pages_core/searchable_page.rb +0 -33
  206. data/app/models/concerns/pages_core/templateable.rb +0 -85
  207. data/app/models/localization.rb +0 -27
  208. data/db/migrate/20140515130100_remove_sphinx_deltas.rb +0 -15
  209. data/lib/pages_core/localizable.rb +0 -49
  210. data/lib/pages_core/localizable/active_record_extension.rb +0 -41
  211. data/lib/pages_core/localizable/class_methods.rb +0 -51
  212. data/lib/pages_core/localizable/configuration.rb +0 -50
  213. data/lib/pages_core/localizable/instance_methods.rb +0 -130
  214. data/lib/pages_core/localizable/localizer.rb +0 -72
  215. data/lib/pages_core/localizable/scope_extension.rb +0 -22
data/app/models/page.rb CHANGED
@@ -2,72 +2,41 @@
2
2
 
3
3
  class Page < ActiveRecord::Base
4
4
  include PagesCore::HumanizableParam
5
- include PagesCore::PageTree
6
- include PagesCore::SearchablePage
7
5
  include PagesCore::Sweepable
8
6
  include PagesCore::Taggable
9
- include PagesCore::Templateable
10
7
 
11
- belongs_to :author, class_name: "User", foreign_key: :user_id
12
-
13
- has_and_belongs_to_many :categories, join_table: "pages_categories"
14
-
15
- belongs_to_image :image
16
- belongs_to_image :meta_image, class_name: "Image"
8
+ include PagesCore::PageModel::Autopublishable
9
+ include PagesCore::PageModel::Commentable
10
+ include PagesCore::PageModel::Images
11
+ include PagesCore::PageModel::Localizable
12
+ include PagesCore::PageModel::Pathable
13
+ include PagesCore::PageModel::Redirectable
14
+ include PagesCore::PageModel::Searchable
15
+ include PagesCore::PageModel::Sortable
16
+ include PagesCore::PageModel::Status
17
+ include PagesCore::PageModel::Tree
18
+ include PagesCore::PageModel::Templateable
17
19
 
18
- has_many :page_images, -> { order("position") }
19
-
20
- has_many :images,
21
- -> { where("`page_images`.`primary` = ?", false).order("position") },
22
- through: :page_images
20
+ belongs_to :author, class_name: "User", foreign_key: :user_id
23
21
 
24
- has_many :comments,
25
- class_name: "PageComment",
26
- dependent: :destroy
22
+ has_many :page_categories, dependent: :destroy
23
+ has_many :categories, through: :page_categories
27
24
 
28
25
  has_many :page_files,
29
26
  -> { order("position ASC") },
30
27
  class_name: "PageFile",
31
28
  dependent: :destroy
32
29
 
33
- acts_as_list scope: :parent_page
34
-
35
- localizable do
36
- attribute :name
37
- attribute :body
38
- attribute :excerpt
39
- attribute :headline
40
- attribute :boxout
41
-
42
- attribute :meta_description
43
- attribute :open_graph_title
44
- attribute :open_graph_description
45
-
46
- dictionary -> { PagesCore::Templates::TemplateConfiguration.all_blocks }
47
- end
48
-
49
- validates_format_of :redirect_to,
50
- with: %r{\A(/|https?://)},
51
- allow_nil: true,
52
- allow_blank: true
53
-
54
- validates_format_of :unique_name,
55
- with: /\A[\w\d_\-]+\z/,
30
+ validates(:unique_name,
31
+ format: { with: /\A[\w\d_\-]+\z/,
56
32
  allow_nil: true,
57
- allow_blank: true
58
-
59
- validates_uniqueness_of :unique_name, allow_nil: true, allow_blank: true
33
+ allow_blank: true },
34
+ uniqueness: { allow_nil: true, allow_blank: true })
60
35
 
61
36
  validates :template, presence: true
62
- validates :content_order, presence: true
63
37
  validates :published_at, presence: true
64
38
 
65
39
  before_validation :published_at
66
- before_validation :set_autopublish
67
- before_validation :set_content_order
68
- after_save :ensure_page_images_contains_primary_image
69
- after_save :queue_autopublisher
70
- after_save ThinkingSphinx::RealTime.callback_for(:page)
71
40
 
72
41
  scope :by_date, -> { order("published_at DESC") }
73
42
  scope :published, -> { where(status: 2, autopublish: false) }
@@ -85,69 +54,19 @@ class Page < ActiveRecord::Base
85
54
  conditions = (options[:include_hidden]) ? "status IN (2,3)" : "status = 2"
86
55
  Page.where(feed_enabled: true).where(conditions).localized(locale)
87
56
  end
88
-
89
- def status_labels
90
- {
91
- 0 => "Draft",
92
- 1 => "Reviewed",
93
- 2 => "Published",
94
- 3 => "Hidden",
95
- 4 => "Deleted"
96
- }
97
- end
98
-
99
- def order_by_tags(tags)
100
- joins(
101
- "LEFT JOIN taggings ON taggings.taggable_id = pages.id AND " \
102
- "taggable_type = \"Page\"",
103
- "LEFT JOIN tags ON tags.id = taggings.tag_id AND tags.id IN (" +
104
- tags.map(&:id).join(",") +
105
- ")"
106
- )
107
- .group("pages.id, localizations.id")
108
- .reorder("COUNT(tags.id) DESC, position ASC")
109
- end
110
- end
111
-
112
- def comments_closed_after_time?
113
- if PagesCore.config.close_comments_after.nil?
114
- false
115
- else
116
- (Time.now - published_at) > PagesCore.config.close_comments_after
117
- end
118
- end
119
-
120
- def comments_allowed?
121
- if self.comments_closed_after_time?
122
- false
123
- else
124
- self[:comments_allowed]
125
- end
126
- end
127
-
128
- def extended?
129
- excerpt? && body?
130
57
  end
131
58
 
132
59
  def empty?
133
60
  !body? && !excerpt?
134
61
  end
135
- alias_method :blank?, :empty?
62
+ alias blank? empty?
136
63
 
137
64
  def excerpt_or_body
138
65
  excerpt? ? excerpt : body
139
66
  end
140
67
 
141
- def image
142
- super.try { |i| i.localize(locale) }
143
- end
144
-
145
- def images
146
- super.in_locale(locale)
147
- end
148
-
149
- def page_images
150
- super.in_locale(locale)
68
+ def extended?
69
+ excerpt? && body?
151
70
  end
152
71
 
153
72
  def files
@@ -158,124 +77,23 @@ class Page < ActiveRecord::Base
158
77
  headline? ? headline : name
159
78
  end
160
79
 
161
- # Does this page have an image?
162
- def image?
163
- self.image_id?
164
- end
165
-
166
- # Get subpages
167
- def pages(_options = nil)
168
- if self.locale?
169
- subpages.published.localized(locale)
170
- else
171
- subpages.published
80
+ def move(parent:, position:)
81
+ Page.transaction do
82
+ update(parent: parent) unless self.parent == parent
83
+ insert_at(position)
172
84
  end
173
85
  end
174
86
 
175
- def subpages
176
- children.order(pinned_content_order)
177
- end
178
-
179
- # Return the status of the page as a string
180
- def status_label
181
- self.class.status_labels[status]
182
- end
183
-
184
- def flag_as_deleted!
185
- update(status: 4)
186
- end
187
-
188
87
  # Get publication date, which defaults to the creation date
189
88
  def published_at
190
- if self.created_at?
191
- self[:published_at] ||= created_at
192
- else
193
- self[:published_at] ||= Time.now
194
- end
195
- end
196
-
197
- # Returns boolean true if page has a valid redirect
198
- def redirects?
199
- self.redirect_to?
200
- end
201
-
202
- def redirect_path(params = {})
203
- path = redirect_to.dup
204
- if path.start_with? "/"
205
- params.each do |key, value|
206
- unless value.is_a?(String) || value.is_a?(Symbol)
207
- fail "redirect_url param must be a string or a symbol"
208
- end
209
- path.gsub!("/:#{key}", "/#{value}")
210
- end
211
- end
212
- path
213
- end
214
-
215
- # Returns true if this page's children is reorderable
216
- def reorderable_children?
217
- !self.content_order? || content_order =~ /position/
218
- end
219
-
220
- # Returns true if this page is reorderable
221
- def reorderable?
222
- !parent || !parent.content_order? || parent.content_order =~ /position/
223
- end
224
-
225
- def draft?
226
- status == 0
227
- end
228
-
229
- def reviewed?
230
- status == 1
231
- end
232
-
233
- def published?
234
- status == 2 && !autopublish?
235
- end
236
-
237
- def hidden?
238
- status == 3
239
- end
240
-
241
- def deleted?
242
- status == 4
89
+ self[:published_at] ||= if created_at?
90
+ created_at
91
+ else
92
+ Time.now.utc
93
+ end
243
94
  end
244
95
 
245
96
  def to_param
246
97
  humanized_param(name)
247
98
  end
248
-
249
- def content_order
250
- self[:content_order] || "position"
251
- end
252
-
253
- private
254
-
255
- def ensure_page_images_contains_primary_image
256
- return if !image_id? || !image_id_changed?
257
- page_image = page_images.where(image_id: image_id).first
258
- if page_image
259
- page_image.update(primary: true)
260
- else
261
- page_images.create(image_id: image_id, primary: true)
262
- end
263
- end
264
-
265
- def pinned_content_order
266
- self.news_page? ? "pages.pinned DESC, #{content_order}" : content_order
267
- end
268
-
269
- def set_autopublish
270
- self.autopublish = published_at? && published_at > Time.now
271
- true
272
- end
273
-
274
- def set_content_order
275
- self[:content_order] ||= "position"
276
- end
277
-
278
- def queue_autopublisher
279
- Autopublisher.queue! if self.autopublish?
280
- end
281
99
  end
@@ -30,16 +30,14 @@ class PageBuilder
30
30
  @parent = parent
31
31
  end
32
32
 
33
- def page(name, options={}, &block)
33
+ def page(name, options = {}, &block)
34
34
  page = Page.create(
35
- { name: name }
36
- .merge(default_options)
37
- .merge(options)
35
+ { name: name }.merge(default_options).merge(options)
38
36
  )
39
37
  if block_given?
40
38
  self.class
41
- .new(user, locale: locale, parent: page)
42
- .run(&block)
39
+ .new(user, locale: locale, parent: page)
40
+ .run(&block)
43
41
  end
44
42
  page
45
43
  end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ class PageCategory < ActiveRecord::Base
4
+ belongs_to :page
5
+ belongs_to :category
6
+ validates :page_id, :category_id, presence: true
7
+ end
@@ -7,7 +7,7 @@ class PageComment < ActiveRecord::Base
7
7
  attr_accessor :invalid_captcha
8
8
 
9
9
  def valid_captcha?
10
- (invalid_captcha) ? false : true
10
+ invalid_captcha ? false : true
11
11
  end
12
12
 
13
13
  after_create do |page_comment|
@@ -56,19 +56,17 @@ class PageFile < ActiveRecord::Base
56
56
 
57
57
  def to_param
58
58
  if filename_extension?
59
- "#{id}.#{filename_extension}"
59
+ "#{id}-#{content_hash}.#{filename_extension}"
60
60
  else
61
- "#{id}"
61
+ "#{id}-#{content_hash}"
62
62
  end
63
63
  end
64
64
 
65
- def published
66
- page.published
67
- end
65
+ delegate :published, to: :page
68
66
 
69
67
  private
70
68
 
71
69
  def set_name_from_filename
72
- self.name = File.basename(filename, ".*") if self.filename? && !self.name?
70
+ self.name = File.basename(filename, ".*") if filename? && !name?
73
71
  end
74
72
  end
@@ -4,12 +4,12 @@ class PageImage < ActiveRecord::Base
4
4
  belongs_to :page
5
5
  belongs_to_image :image
6
6
 
7
- validates_presence_of :page_id
7
+ validates :page_id, presence: true
8
8
 
9
9
  accepts_nested_attributes_for :image
10
10
  validates_associated :image
11
11
 
12
- acts_as_list scope: :page
12
+ acts_as_list scope: [:page, :primary]
13
13
 
14
14
  localizable
15
15
 
@@ -21,15 +21,14 @@ class PageImage < ActiveRecord::Base
21
21
 
22
22
  after_save do |page_image|
23
23
  if page_image.primary_changed?
24
-
25
24
  # Make sure only one PageImage can be the primary,
26
25
  # then update image_id on the page.
27
26
  if page_image.primary?
28
27
  PageImage.where
29
28
  page_image.page
30
- .page_images
31
- .where("id != ?", page_image.id)
32
- .update_all(primary: false)
29
+ .page_images
30
+ .where("id != ?", page_image.id)
31
+ .update_all(primary: false)
33
32
  page_image.page.update(image_id: page_image.image_id)
34
33
 
35
34
  # Clear image_id on the page if primary is toggled off
@@ -45,7 +44,7 @@ class PageImage < ActiveRecord::Base
45
44
 
46
45
  class << self
47
46
  def cleanup!
48
- all.each do |page_image|
47
+ all.find_each do |page_image|
49
48
  page_image.destroy unless page_image.image
50
49
  end
51
50
  end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ class PagePath < ActiveRecord::Base
4
+ class PageNotSavedError < StandardError; end
5
+ class NoPathError < StandardError; end
6
+ class NoLocaleError < StandardError; end
7
+
8
+ belongs_to :page
9
+ validates :locale, presence: true
10
+ validates :path, presence: true, uniqueness: { scope: :locale }
11
+
12
+ class << self
13
+ def build(page)
14
+ page.locales.each do |locale|
15
+ localized = page.localize(locale)
16
+ localized.ensure_path_segment
17
+ associate(localized) if !localized.deleted? && localized.full_path?
18
+ end
19
+ page.children.each { |p| build(p) }
20
+ end
21
+
22
+ def build_all
23
+ Page.roots.each do |p|
24
+ build(p)
25
+ end
26
+ end
27
+
28
+ def get(locale, path)
29
+ find_by(locale: locale, path: path)
30
+ end
31
+
32
+ def associate(page, locale: nil, path: nil)
33
+ locale ||= page.locale
34
+ path ||= page.full_path
35
+ raise PageNotSavedError unless page.id?
36
+ raise NoLocaleError unless locale
37
+ raise NoPathError unless path
38
+ existing = get(locale, path)
39
+
40
+ return create(locale: locale, path: path, page: page) unless existing
41
+
42
+ existing.update(page: page) unless existing.page_id == page.id
43
+ existing
44
+ end
45
+ end
46
+ end