pageflow 15.8.0 → 16.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +183 -103
  3. data/README.md +0 -1
  4. data/Rakefile +1 -1
  5. data/admins/pageflow/accounts.rb +12 -16
  6. data/admins/pageflow/entry.rb +28 -26
  7. data/admins/pageflow/entry_templates.rb +5 -7
  8. data/admins/pageflow/sites.rb +53 -0
  9. data/app/assets/javascripts/pageflow/admin/entries.js +16 -7
  10. data/app/assets/javascripts/pageflow/dist/ui.js +298 -72
  11. data/app/assets/stylesheets/pageflow/admin/permalink_input.scss +10 -0
  12. data/app/assets/stylesheets/pageflow/editor/drop_down_button.scss +6 -1
  13. data/app/assets/stylesheets/pageflow/editor/file_thumbnails.scss +4 -0
  14. data/app/assets/stylesheets/pageflow/editor/help.scss +3 -3
  15. data/app/assets/stylesheets/pageflow/editor/info_box.scss +7 -0
  16. data/app/assets/stylesheets/pageflow/editor/inputs/file_input.scss +0 -5
  17. data/app/assets/stylesheets/pageflow/ui/forms.scss +1 -1
  18. data/app/controllers/pageflow/chapters_controller.rb +2 -2
  19. data/app/controllers/pageflow/editor/files_controller.rb +1 -1
  20. data/app/controllers/pageflow/entries_controller.rb +12 -2
  21. data/app/controllers/pageflow/feeds_controller.rb +18 -0
  22. data/app/controllers/pageflow/pages_controller.rb +2 -2
  23. data/app/controllers/pageflow/sitemaps_controller.rb +15 -0
  24. data/app/controllers/pageflow/storylines_controller.rb +2 -2
  25. data/app/helpers/pageflow/common_entry_seed_helper.rb +1 -1
  26. data/app/helpers/pageflow/embed_code_helper.rb +1 -1
  27. data/app/helpers/pageflow/entries_helper.rb +16 -15
  28. data/app/helpers/pageflow/feeds_helper.rb +66 -0
  29. data/app/helpers/pageflow/page_types_helper.rb +9 -9
  30. data/app/helpers/pageflow/sites_helper.rb +11 -0
  31. data/app/helpers/pageflow/social_share_helper.rb +2 -2
  32. data/app/inputs/pageflow_permalink_input.rb +15 -3
  33. data/app/models/concerns/pageflow/reusable_file.rb +3 -3
  34. data/app/models/pageflow/account.rb +13 -31
  35. data/app/models/pageflow/audio_file_url_templates.rb +2 -1
  36. data/app/models/pageflow/{cname_theming_request_scope.rb → cname_site_request_scope.rb} +3 -3
  37. data/app/models/pageflow/customized_theme.rb +1 -1
  38. data/app/models/pageflow/draft_entry.rb +1 -1
  39. data/app/models/pageflow/entries_feed.rb +32 -0
  40. data/app/models/pageflow/entry.rb +3 -4
  41. data/app/models/pageflow/entry_at_revision.rb +2 -2
  42. data/app/models/pageflow/entry_duplicate.rb +1 -1
  43. data/app/models/pageflow/entry_template.rb +4 -4
  44. data/app/models/pageflow/home_button.rb +7 -7
  45. data/app/models/pageflow/image_file.rb +14 -3
  46. data/app/models/pageflow/membership.rb +3 -2
  47. data/app/models/pageflow/other_file.rb +5 -0
  48. data/app/models/pageflow/other_file_url_templates.rb +16 -0
  49. data/app/models/pageflow/permalink.rb +3 -3
  50. data/app/models/pageflow/permalink_directory.rb +2 -2
  51. data/app/models/pageflow/published_entry.rb +8 -2
  52. data/app/models/pageflow/revision.rb +4 -0
  53. data/app/models/pageflow/site.rb +67 -0
  54. data/app/models/pageflow/sitemaps.rb +13 -0
  55. data/app/models/pageflow/theme_customization.rb +1 -1
  56. data/app/models/pageflow/used_file.rb +2 -2
  57. data/app/models/pageflow/video_file_url_templates.rb +3 -1
  58. data/app/models/pageflow/widget.rb +9 -1
  59. data/app/policies/pageflow/account_policy.rb +2 -2
  60. data/app/policies/pageflow/entry_policy.rb +2 -2
  61. data/app/policies/pageflow/entry_template_policy.rb +1 -1
  62. data/app/policies/pageflow/{theming_policy.rb → site_policy.rb} +13 -11
  63. data/app/views/admin/accounts/_entry_template_details.html.arb +1 -1
  64. data/app/views/admin/accounts/_form.html.erb +4 -22
  65. data/app/views/admin/accounts/_site_defaults_inline_help.html.erb +5 -0
  66. data/app/views/admin/entries/_form.html.erb +4 -13
  67. data/app/views/admin/entries/_permalink_inputs.html.erb +2 -3
  68. data/app/views/admin/entries/_site_input.html.erb +15 -0
  69. data/app/views/admin/entries/{entry_type_name_input.html.erb → entry_site_and_type_name_input.html.erb} +3 -0
  70. data/app/views/admin/entry_templates/_form.html.erb +5 -5
  71. data/app/views/admin/sites/_attributes_table.html.arb +12 -0
  72. data/app/views/admin/sites/_fields.html.erb +23 -0
  73. data/app/views/admin/sites/_form.html.erb +5 -0
  74. data/app/views/components/pageflow/admin/entries_tab.rb +1 -2
  75. data/app/views/components/pageflow/admin/entry_templates_tab.rb +10 -11
  76. data/app/views/components/pageflow/admin/extensible_attributes_table.rb +8 -2
  77. data/app/views/components/pageflow/admin/features_tab.rb +1 -1
  78. data/app/views/components/pageflow/admin/sites_tab.rb +35 -0
  79. data/app/views/components/pageflow/admin/users_tab.rb +1 -2
  80. data/app/views/pageflow/editor/config/_seeds.json.jbuilder +1 -0
  81. data/app/views/pageflow/editor/entries/seed.json.erb +1 -1
  82. data/app/views/pageflow/editor/sites/_site.json.jbuilder +1 -0
  83. data/app/views/pageflow/entries/stylesheet.css.erb +1 -1
  84. data/app/views/pageflow/feeds/index.atom.builder +20 -0
  85. data/app/views/pageflow/sitemaps/index.xml.builder +9 -0
  86. data/app/views/pageflow/social_share/_entry_meta_tags.html.erb +1 -1
  87. data/app/views/pageflow/social_share/_page_meta_tags.html.erb +1 -1
  88. data/config/initializers/admin_resource_tabs.rb +29 -12
  89. data/config/initializers/features.rb +1 -0
  90. data/config/initializers/paperclip.rb +4 -0
  91. data/config/locales/de.yml +42 -19
  92. data/config/locales/en.yml +45 -17
  93. data/config/routes.rb +3 -0
  94. data/config/spring.rb +1 -1
  95. data/db/migrate/20221215101134_rename_theming_to_site.rb +9 -0
  96. data/db/migrate/20221215120856_associate_entry_templates_with_sites.rb +34 -0
  97. data/db/migrate/20221219203023_add_name_to_sites.rb +5 -0
  98. data/db/migrate/20230103155934_associate_theme_customizations_with_sites.rb +27 -0
  99. data/db/migrate/20230120092923_create_other_files.rb +23 -0
  100. data/db/migrate/20230323115745_add_feeds_enabled_to_sites.rb +5 -0
  101. data/db/migrate/20230323154323_add_sitemap_enabled_to_sites.rb +5 -0
  102. data/db/migrate/20230331103823_add_title_to_sites.rb +5 -0
  103. data/db/migrate/20230405103612_add_custom_feed_url_to_sites.rb +5 -0
  104. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/editor.js +455 -119
  105. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/frontend.js +31 -8
  106. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-client.js +1 -1
  107. data/entry_types/paged/app/assets/javascripts/pageflow_paged/dist/react-server.js +1 -1
  108. data/entry_types/paged/app/controllers/pageflow_paged/editor/entries_controller.rb +0 -2
  109. data/entry_types/paged/app/controllers/pageflow_paged/entries_controller.rb +1 -0
  110. data/entry_types/paged/app/views/pageflow_paged/entries/show.html.erb +1 -0
  111. data/entry_types/paged/config/initializers/features.rb +0 -1
  112. data/entry_types/paged/lib/pageflow_paged/engine.rb +17 -1
  113. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/chapters_controller.rb +2 -2
  114. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/content_elements_controller.rb +3 -4
  115. data/entry_types/scrolled/app/controllers/pageflow_scrolled/editor/sections_controller.rb +13 -6
  116. data/entry_types/scrolled/app/controllers/pageflow_scrolled/entries_controller.rb +2 -0
  117. data/entry_types/scrolled/app/helpers/pageflow_scrolled/cache_helper.rb +11 -0
  118. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/entry_json_seed_helper.rb +42 -0
  119. data/entry_types/scrolled/app/helpers/pageflow_scrolled/editor/seed_html_helper.rb +3 -0
  120. data/entry_types/scrolled/app/helpers/pageflow_scrolled/packs_helper.rb +31 -10
  121. data/entry_types/scrolled/app/helpers/pageflow_scrolled/react_server_side_rendering_helper.rb +9 -1
  122. data/entry_types/scrolled/app/helpers/pageflow_scrolled/themes_helper.rb +3 -1
  123. data/entry_types/scrolled/app/models/pageflow_scrolled/chapter.rb +23 -0
  124. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_head.html.erb +6 -1
  125. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/entries/_seed.json.jbuilder +1 -5
  126. data/entry_types/scrolled/app/views/pageflow_scrolled/editor/sections/_section_with_content_elements.json.jbuilder +10 -0
  127. data/entry_types/scrolled/app/views/pageflow_scrolled/entries/show.html.erb +44 -41
  128. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_consent_vendors.json.jbuilder +16 -0
  129. data/entry_types/scrolled/app/views/pageflow_scrolled/entry_json_seed/_entry.json.jbuilder +8 -5
  130. data/entry_types/scrolled/config/initializers/features.rb +5 -0
  131. data/entry_types/scrolled/config/locales/consent_widget.de.yml +4 -0
  132. data/entry_types/scrolled/config/locales/consent_widget.en.yml +4 -0
  133. data/entry_types/scrolled/config/locales/de.yml +189 -8
  134. data/entry_types/scrolled/config/locales/en.yml +207 -2
  135. data/entry_types/scrolled/config/routes.rb +4 -0
  136. data/entry_types/scrolled/lib/generators/pageflow_scrolled/install/install_generator.rb +97 -5
  137. data/entry_types/scrolled/lib/pageflow_scrolled/additional_seed_data.rb +1 -1
  138. data/entry_types/scrolled/lib/pageflow_scrolled/configuration.rb +96 -0
  139. data/entry_types/scrolled/lib/pageflow_scrolled/content_element_consent_vendors.rb +38 -0
  140. data/entry_types/scrolled/lib/pageflow_scrolled/engine.rb +17 -1
  141. data/entry_types/scrolled/lib/pageflow_scrolled/plugin.rb +24 -0
  142. data/entry_types/scrolled/lib/pageflow_scrolled/react_widget_type.rb +6 -1
  143. data/entry_types/scrolled/lib/pageflow_scrolled/seeds.rb +1 -1
  144. data/entry_types/scrolled/lib/tasks/pageflow_scrolled/storybook.rake +1 -2
  145. data/entry_types/scrolled/package/contentElements-editor.js +307 -22
  146. data/entry_types/scrolled/package/contentElements-frontend.css +1 -1
  147. data/entry_types/scrolled/package/contentElements-frontend.js +690 -71
  148. data/entry_types/scrolled/package/editor.js +616 -220
  149. data/entry_types/scrolled/package/frontend/{EditableInlineText.module-c6672f27.js → EditableInlineText.module-fa9e3aff.js} +1669 -1674
  150. data/entry_types/scrolled/package/frontend/PhonePlatformContext-10a1d600.js +32 -0
  151. data/entry_types/scrolled/package/frontend/ToggleFullscreenCornerButton-727cce0d.js +107 -0
  152. data/entry_types/scrolled/package/frontend/Viewer-169e14ca.js +154 -0
  153. data/entry_types/scrolled/package/frontend/{Viewer-6b05522f.js → Viewer-ee1aa590.js} +32 -161
  154. data/entry_types/scrolled/package/frontend/arrowRight-92a34ccc.js +77 -0
  155. data/entry_types/scrolled/package/frontend/{components-487daafa.js → components-4a09bfa3.js} +185 -45
  156. data/entry_types/scrolled/package/frontend/{PhonePlatformContext-22e65f92.js → i18n-ddd92820.js} +162 -292
  157. data/entry_types/scrolled/package/frontend/index-02378634.js +118 -0
  158. data/entry_types/scrolled/package/frontend/index.css +1 -1
  159. data/entry_types/scrolled/package/frontend/index.js +375 -40
  160. data/entry_types/scrolled/package/frontend/useContentElementEditorState-63045393.js +52 -0
  161. data/entry_types/scrolled/package/package.json +2 -1
  162. data/entry_types/scrolled/package/testHelpers.js +9 -2
  163. data/entry_types/scrolled/package/values/colors.module.css +15 -0
  164. data/entry_types/scrolled/package/widgets/consentBar.css +1 -0
  165. data/entry_types/scrolled/package/widgets/consentBar.js +426 -0
  166. data/entry_types/scrolled/package/widgets/defaultNavigation.css +2 -2
  167. data/entry_types/scrolled/package/widgets/defaultNavigation.js +16 -9
  168. data/lib/generators/pageflow/resque/resque_generator.rb +1 -1
  169. data/lib/pageflow/ability_mixin.rb +21 -13
  170. data/lib/pageflow/active_admin_can_can_fix.rb +2 -2
  171. data/lib/pageflow/admin/attributes_table_rows.rb +1 -1
  172. data/lib/pageflow/admin/form_inputs.rb +1 -1
  173. data/lib/pageflow/admin/tabs.rb +1 -1
  174. data/lib/pageflow/built_in_file_type.rb +7 -0
  175. data/lib/pageflow/configuration/permissions.rb +3 -3
  176. data/lib/pageflow/configuration.rb +38 -17
  177. data/lib/pageflow/engine.rb +60 -39
  178. data/lib/pageflow/entry_export_import/entry_serialization.rb +1 -1
  179. data/lib/pageflow/entry_export_import/revision_serialization.rb +1 -1
  180. data/lib/pageflow/file_type.rb +2 -2
  181. data/lib/pageflow/global_config_api.rb +2 -2
  182. data/lib/pageflow/nested_revision_component.rb +23 -5
  183. data/lib/pageflow/primary_domain_entry_redirect.rb +7 -7
  184. data/lib/pageflow/rails_version.rb +19 -0
  185. data/lib/pageflow/seeds.rb +20 -17
  186. data/lib/pageflow/theme_customizations.rb +10 -10
  187. data/lib/pageflow/version.rb +1 -1
  188. data/lib/pageflow/widget_types.rb +4 -0
  189. data/package/config/webpack5.js +14 -0
  190. data/package/editor.js +148 -37
  191. data/package/frontend.js +26 -2
  192. data/package/testHelpers.js +1 -1
  193. data/package/ui.js +296 -71
  194. data/spec/factories/accounts.rb +5 -2
  195. data/spec/factories/draft_entries.rb +2 -2
  196. data/spec/factories/entries.rb +19 -5
  197. data/spec/factories/entry_templates.rb +1 -1
  198. data/spec/factories/permalink_directory.rb +1 -1
  199. data/spec/factories/published_entries.rb +2 -2
  200. data/spec/factories/sites.rb +12 -0
  201. data/vendor/assets/javascripts/iscroll.js +4 -7
  202. metadata +84 -59
  203. data/app/helpers/pageflow/admin/permalinks_helper.rb +0 -15
  204. data/app/helpers/pageflow/themings_helper.rb +0 -11
  205. data/app/models/pageflow/theming.rb +0 -30
  206. data/app/views/admin/accounts/_theming_defaults_inline_help.html.erb +0 -5
  207. data/app/views/admin/accounts/_theming_details.html.arb +0 -5
  208. data/app/views/pageflow/editor/themings/_theming.json.jbuilder +0 -1
  209. data/entry_types/scrolled/package/frontend/arrowRight-7e3d9dd5.js +0 -42
  210. data/spec/factories/themings.rb +0 -7
  211. /data/app/views/pageflow/entries/{_theming.css.erb → _site.css.erb} +0 -0
@@ -219,7 +219,7 @@ textarea.short {
219
219
  text-decoration: underline;
220
220
  }
221
221
 
222
- .input-hidden_via_binding {
222
+ .hidden_via_binding {
223
223
  display: none;
224
224
  }
225
225
 
@@ -31,7 +31,7 @@ module Pageflow
31
31
 
32
32
  authorize!(:update, chapter)
33
33
  verify_edit_lock!(chapter.entry)
34
- chapter.update_attributes(chapter_params)
34
+ chapter.update(chapter_params)
35
35
 
36
36
  respond_with(chapter)
37
37
  end
@@ -43,7 +43,7 @@ module Pageflow
43
43
  authorize!(:edit_outline, storyline.entry)
44
44
  verify_edit_lock!(storyline.entry)
45
45
  params.require(:ids).each_with_index do |id, index|
46
- entry.chapters.update(id, storyline_id: storyline.id, position: index)
46
+ entry.chapters.find(id).update(storyline_id: storyline.id, position: index)
47
47
  end
48
48
 
49
49
  head :no_content
@@ -72,7 +72,7 @@ module Pageflow
72
72
  file = entry.find_file(file_type.model, params[:id])
73
73
 
74
74
  authorize!(:update, file.to_model)
75
- file.update_attributes!(update_params)
75
+ file.update!(update_params)
76
76
 
77
77
  head(:no_content)
78
78
  end
@@ -6,9 +6,9 @@ module Pageflow
6
6
  include EntryPasswordProtection
7
7
 
8
8
  def index
9
- theming = Theming.for_request(request).with_home_url.first!
9
+ site = Site.for_request(request).with_home_url.first!
10
10
 
11
- redirect_to(theming.home_url)
11
+ redirect_to(site.home_url)
12
12
  end
13
13
 
14
14
  def show
@@ -85,11 +85,21 @@ module Pageflow
85
85
 
86
86
  delegate_to_rack_app!(entry.entry_type.frontend_app) do |_status, headers, _body|
87
87
  allow_iframe_for_embed(headers)
88
+ apply_cache_control(entry, headers)
88
89
  end
89
90
  end
90
91
 
91
92
  def allow_iframe_for_embed(headers)
92
93
  headers.except!('X-Frame-Options') if params[:embed]
93
94
  end
95
+
96
+ def apply_cache_control(entry, headers)
97
+ config = Pageflow.config_for(entry)
98
+
99
+ return if config.public_entry_cache_control_header.blank?
100
+ return if entry.password_protected?
101
+
102
+ headers['Cache-Control'] = config.public_entry_cache_control_header
103
+ end
94
104
  end
95
105
  end
@@ -0,0 +1,18 @@
1
+ module Pageflow
2
+ # @api private
3
+ class FeedsController < Pageflow::ApplicationController
4
+ def index
5
+ site = Site.for_request(request).first!
6
+ return head 404 unless site.feeds_enabled?
7
+
8
+ @feed = EntriesFeed.for(
9
+ site: site,
10
+ locale: params[:locale]
11
+ )
12
+
13
+ respond_to do |format|
14
+ format.atom
15
+ end
16
+ end
17
+ end
18
+ end
@@ -20,7 +20,7 @@ module Pageflow
20
20
 
21
21
  authorize!(:update, page)
22
22
  verify_edit_lock!(page.chapter.entry)
23
- page.update_attributes(page_params)
23
+ page.update(page_params)
24
24
 
25
25
  respond_with(page)
26
26
  end
@@ -32,7 +32,7 @@ module Pageflow
32
32
  authorize!(:edit_outline, entry.to_model)
33
33
  verify_edit_lock!(chapter.entry)
34
34
  params.require(:ids).each_with_index do |id, index|
35
- entry.pages.update(id, :chapter_id => chapter.id, :position => index)
35
+ entry.pages.find(id).update(chapter_id: chapter.id, position: index)
36
36
  end
37
37
 
38
38
  head :no_content
@@ -0,0 +1,15 @@
1
+ module Pageflow
2
+ # @api private
3
+ class SitemapsController < Pageflow::ApplicationController
4
+ def index
5
+ site = Site.for_request(request).first!
6
+ return head 404 unless site.sitemap_enabled?
7
+
8
+ @entries = Sitemaps.entries_for(site: site)
9
+
10
+ respond_to do |format|
11
+ format.xml
12
+ end
13
+ end
14
+ end
15
+ end
@@ -31,7 +31,7 @@ module Pageflow
31
31
 
32
32
  authorize!(:update, storyline)
33
33
  verify_edit_lock!(storyline.entry)
34
- storyline.update_attributes(storyline_params)
34
+ storyline.update(storyline_params)
35
35
 
36
36
  respond_with(storyline)
37
37
  end
@@ -42,7 +42,7 @@ module Pageflow
42
42
  authorize!(:edit_outline, entry.to_model)
43
43
  verify_edit_lock!(entry)
44
44
  params.require(:ids).each_with_index do |id, index|
45
- entry.storylines.update(id, position: index)
45
+ entry.storylines.find(id).update(position: index)
46
46
  end
47
47
 
48
48
  head :no_content
@@ -10,7 +10,7 @@ module Pageflow
10
10
  config = Pageflow.config_for(entry)
11
11
 
12
12
  json.locale entry.locale
13
- json.theming entry.theming.as_json(only: [:privacy_link_url])
13
+ json.site entry.site.as_json(only: [:privacy_link_url])
14
14
  json.enabled_feature_names entry.enabled_feature_names
15
15
  json.page_types PageTypesSeed.new(config).as_json
16
16
 
@@ -24,7 +24,7 @@ module Pageflow
24
24
 
25
25
  def entry_embed_url_options(entry)
26
26
  options = Pageflow.config.entry_embed_url_options
27
- options = options.call(entry.theming) if options.respond_to?(:call)
27
+ options = options.call(entry.site) if options.respond_to?(:call)
28
28
  options
29
29
  end
30
30
  end
@@ -1,7 +1,8 @@
1
1
  module Pageflow
2
2
  module EntriesHelper
3
3
  def pretty_entry_title(entry)
4
- [entry.title, entry.theming.cname_domain.presence].compact.join(' - ')
4
+ [entry.title,
5
+ entry.site.title.presence || entry.site.cname_domain.presence].compact.join(' - ')
5
6
  end
6
7
 
7
8
  def pretty_entry_url(entry, options = {})
@@ -20,21 +21,21 @@ module Pageflow
20
21
  private
21
22
 
22
23
  def with_custom_canonical_url_prefix(entry)
23
- return if entry.theming.canonical_entry_url_prefix.blank?
24
+ return if entry.site.canonical_entry_url_prefix.blank?
24
25
  entry = ensure_entry_with_revision(entry)
25
26
 
26
27
  [
27
- entry.theming.canonical_entry_url_prefix.gsub(':locale', entry.locale),
28
+ entry.site.canonical_entry_url_prefix.gsub(':locale', entry.locale),
28
29
  entry.to_param,
29
- entry.theming.trailing_slash_in_canonical_urls ? '/' : ''
30
+ entry.site.trailing_slash_in_canonical_urls ? '/' : ''
30
31
  ].join
31
32
  end
32
33
 
33
34
  def default(routes, entry, options)
34
35
  params =
35
36
  options
36
- .reverse_merge(trailing_slash: entry.theming.trailing_slash_in_canonical_urls)
37
- .reverse_merge(Pageflow.config.theming_url_options(entry.theming) || {})
37
+ .reverse_merge(trailing_slash: entry.site.trailing_slash_in_canonical_urls)
38
+ .reverse_merge(Pageflow.config.site_url_options(entry.site) || {})
38
39
 
39
40
  if entry.permalink.present?
40
41
  routes.permalink_url(
@@ -57,8 +58,8 @@ module Pageflow
57
58
  end
58
59
 
59
60
  def entry_privacy_link_url(entry)
60
- return unless entry.theming.privacy_link_url.present?
61
- "#{entry.theming.privacy_link_url}?lang=#{entry.locale}"
61
+ return unless entry.site.privacy_link_url.present?
62
+ "#{entry.site.privacy_link_url}?lang=#{entry.locale}"
62
63
  end
63
64
 
64
65
  def entry_file_rights(entry)
@@ -80,23 +81,23 @@ module Pageflow
80
81
  def entry_global_links(entry)
81
82
  links = []
82
83
 
83
- if entry.theming.imprint_link_label.present? && entry.theming.imprint_link_url.present?
84
- links << link_to(raw(entry.theming.imprint_link_label),
85
- entry.theming.imprint_link_url,
84
+ if entry.site.imprint_link_label.present? && entry.site.imprint_link_url.present?
85
+ links << link_to(raw(entry.site.imprint_link_label),
86
+ entry.site.imprint_link_url,
86
87
  target: '_blank',
87
88
  tabindex: 2,
88
89
  class: 'legal')
89
90
  end
90
91
 
91
- if entry.theming.copyright_link_label.present? && entry.theming.copyright_link_url.present?
92
- links << link_to(raw(entry.theming.copyright_link_label),
93
- entry.theming.copyright_link_url,
92
+ if entry.site.copyright_link_label.present? && entry.site.copyright_link_url.present?
93
+ links << link_to(raw(entry.site.copyright_link_label),
94
+ entry.site.copyright_link_url,
94
95
  target: '_blank',
95
96
  tabindex: 2,
96
97
  class: 'copy')
97
98
  end
98
99
 
99
- if entry.theming.privacy_link_url.present?
100
+ if entry.site.privacy_link_url.present?
100
101
  links << link_to(I18n.t('pageflow.public.privacy_notice'),
101
102
  entry_privacy_link_url(entry),
102
103
  target: '_blank',
@@ -0,0 +1,66 @@
1
+ module Pageflow
2
+ # Helpers to render alternate links to atom feeds.
3
+ #
4
+ # @since 16.1
5
+ module FeedsHelper
6
+ # Render alternate links to atom feed of entries in the same site
7
+ # using the same locale.
8
+ def feed_link_tags_for_entry(entry)
9
+ return '' unless entry.site.feeds_enabled?
10
+
11
+ href =
12
+ entry.site.custom_feed_url.presence&.gsub(':locale', entry.locale) ||
13
+ pageflow.feed_url(
14
+ {
15
+ locale: entry.locale,
16
+ format: 'atom'
17
+ }.merge(Pageflow.config.site_url_options(entry.site) || {})
18
+ )
19
+
20
+ tag(:link,
21
+ rel: 'alternate',
22
+ type: 'application/atom+xml',
23
+ title: 'Feed',
24
+ href: href)
25
+ end
26
+
27
+ # @api private
28
+ def feed_entry_content(entry)
29
+ FeedContent.new(self, entry).build
30
+ end
31
+
32
+ # @api private
33
+ FeedContent = Struct.new(:template, :entry) do
34
+ def build
35
+ [image_html, summary_html, link_html].compact.join
36
+ end
37
+
38
+ private
39
+
40
+ def image_html
41
+ return if entry.thumbnail_file.blank?
42
+
43
+ template.content_tag(
44
+ :p,
45
+ template.tag(
46
+ :img,
47
+ src: entry.thumbnail_file.thumbnail_url(:thumbnail_large),
48
+ width: 560, height: 315
49
+ )
50
+ )
51
+ end
52
+
53
+ def summary_html
54
+ template.content_tag(:p, template.raw(entry.summary))
55
+ end
56
+
57
+ def link_html
58
+ template.content_tag(
59
+ :p,
60
+ template.link_to(template.t('pageflow.public.read_more'),
61
+ template.social_share_entry_url(entry))
62
+ )
63
+ end
64
+ end
65
+ end
66
+ end
@@ -17,16 +17,16 @@ module Pageflow
17
17
  def page_type_templates(entry)
18
18
  safe_join(Pageflow.config.page_types.map do |page_type|
19
19
  content_tag(:script,
20
- render_to_string(template: page_type.template_path,
21
- locals: {
22
- configuration: {},
23
- page: Page.new,
24
- entry: entry,
20
+ render(template: page_type.template_path,
21
+ locals: {
22
+ configuration: {},
23
+ page: Page.new,
24
+ entry: entry,
25
25
 
26
- # Required by RevisionFileHelper#find_file_in_entry
27
- :@entry => entry
28
- },
29
- layout: false).to_str,
26
+ # Required by RevisionFileHelper#find_file_in_entry
27
+ :@entry => entry
28
+ },
29
+ layout: false).to_str,
30
30
  type: 'text/html', data: {template: "#{page_type.name}_page"})
31
31
  end)
32
32
  end
@@ -0,0 +1,11 @@
1
+ module Pageflow
2
+ module SitesHelper
3
+ DEFAULT_PUBLIC_ENTRY_OPTIONS = lambda do |site|
4
+ site.cname.present? ? {host: site.cname} : nil
5
+ end
6
+
7
+ def pretty_site_url(site)
8
+ pageflow.public_root_url(Pageflow.config.site_url_options(site))
9
+ end
10
+ end
11
+ end
@@ -32,8 +32,8 @@ module Pageflow
32
32
 
33
33
  title = ["#{entry.title}:"]
34
34
  title << page.title
35
- title << '-' if entry.theming.cname_domain.present?
36
- title << entry.theming.cname_domain
35
+ title << '-' if entry.site.cname_domain.present?
36
+ title << entry.site.cname_domain
37
37
 
38
38
  title.join(' ')
39
39
  end
@@ -27,9 +27,9 @@ class PageflowPermalinkInput
27
27
  end
28
28
 
29
29
  def permalink_inputs_html
30
- return '' if options[:directory_collection].empty?
30
+ return '' if options[:site].permalink_directories.empty?
31
31
 
32
- builder.select(:directory_id, options[:directory_collection]) <<
32
+ builder.select(:directory_id, directory_select_options) <<
33
33
  builder.text_field(:slug, placeholder: options[:slug_placeholder])
34
34
  end
35
35
 
@@ -38,10 +38,22 @@ class PageflowPermalinkInput
38
38
  end
39
39
 
40
40
  def wrapper_html_options
41
- if options[:directory_collection].empty?
41
+ if options[:site].permalink_directories.empty?
42
42
  super.merge(style: 'display: none')
43
+ elsif options[:site].permalink_directories.one?
44
+ result = super
45
+ result.merge(class: "#{result[:class]} no_directories")
43
46
  else
44
47
  super
45
48
  end
46
49
  end
50
+
51
+ def directory_select_options
52
+ template.options_from_collection_for_select(
53
+ options[:site].permalink_directories,
54
+ 'id',
55
+ 'path',
56
+ builder.object.directory_id
57
+ )
58
+ end
47
59
  end
@@ -30,8 +30,8 @@ module Pageflow
30
30
  file_type_of_parent = Pageflow.config.file_types.find_by_model!(parent_class)
31
31
  models_of_nested_file_types = file_type_of_parent.nested_file_types.map(&:model)
32
32
  unless models_of_nested_file_types.include?(self.class)
33
- errors[:base] << 'File type of provided parent file does not permit nesting files of '\
34
- "type #{self.class.name}"
33
+ errors.add(:base, 'File type of provided parent file does not permit nesting files of '\
34
+ "type #{self.class.name}")
35
35
  end
36
36
  end
37
37
  end
@@ -39,7 +39,7 @@ module Pageflow
39
39
  def parent_belongs_to_same_entry
40
40
  if parent_file.present?
41
41
  unless parent_file.using_entries.include?(entry)
42
- errors[:base] << 'Parent file does not belong to same entry as nested file'
42
+ errors.add(:base, 'Parent file does not belong to same entry as nested file')
43
43
  end
44
44
  end
45
45
  end
@@ -9,49 +9,31 @@ module Pageflow
9
9
  has_many :users, through: :memberships, source: :user, class_name: '::User'
10
10
  has_many :entry_memberships, through: :entries, source: :memberships
11
11
 
12
- has_many :themings, dependent: :destroy
13
- has_many :entry_templates, dependent: :destroy
14
- belongs_to :default_theming, :class_name => 'Theming'
12
+ has_many :sites, dependent: :destroy
13
+ belongs_to :default_site, :class_name => 'Site'
15
14
 
16
- validates :default_theming, :presence => true
17
- validates_associated :entry_templates
15
+ validates :default_site, :presence => true
18
16
 
19
- accepts_nested_attributes_for :default_theming, :update_only => true
17
+ accepts_nested_attributes_for :default_site, :update_only => true
20
18
 
21
19
  scope :with_landing_page, -> { where.not(:landing_page_name => '') }
22
20
 
23
- def build_default_theming(*args)
24
- super.tap do |theming|
25
- theming.account = self
21
+ def build_default_site(*args)
22
+ super.tap do |site|
23
+ site.account = self
26
24
  end
27
25
  end
28
26
 
29
- def first_paged_entry_template
30
- EntryTemplate.find_or_initialize_by(account: self, entry_type_name: 'paged')
27
+ def blacklist_for_serialization
28
+ [:features_configuration]
31
29
  end
32
30
 
33
- def existing_and_potential_entry_templates
34
- entry_type_names = Pageflow.config_for(self).entry_types.map(&:name)
35
- existing_entry_templates = EntryTemplate.where(account_id: id).load
36
- allowed_existing_entry_templates =
37
- existing_entry_templates.select do |template|
38
- entry_type_names.include?(template.entry_type_name)
39
- end
40
- free_type_names =
41
- entry_type_names - allowed_existing_entry_templates.map(&:entry_type_name)
42
-
43
- potential_entry_templates = free_type_names.map do |type_name|
44
- EntryTemplate.new(
45
- account_id: id,
46
- entry_type_name: type_name
47
- )
48
- end
49
-
50
- allowed_existing_entry_templates + potential_entry_templates
31
+ def self.ransackable_attributes(_auth_object)
32
+ %w[id name]
51
33
  end
52
34
 
53
- def blacklist_for_serialization
54
- [:features_configuration]
35
+ def self.ransackable_associations(_auth_object)
36
+ []
55
37
  end
56
38
  end
57
39
  end
@@ -2,6 +2,7 @@ module Pageflow
2
2
  class AudioFileUrlTemplates
3
3
  def call
4
4
  {
5
+ original: url_template(:attachment, :original),
5
6
  m4a: url_template(:m4a),
6
7
  mp3: url_template(:mp3),
7
8
  ogg: url_template(:ogg),
@@ -17,7 +18,7 @@ module Pageflow
17
18
 
18
19
  def example_file
19
20
  @example_file ||= AudioFile.new(id: 0,
20
- file_name: ':basename.mp3',
21
+ file_name: ':basename.:extension',
21
22
  peak_data_file_name: 'audio.json')
22
23
  end
23
24
  end
@@ -1,7 +1,7 @@
1
1
  module Pageflow
2
- class CnameThemingRequestScope
3
- def call(themings, request)
4
- themings.where(<<-SQL, host: request.host)
2
+ class CnameSiteRequestScope
3
+ def call(sites, request)
4
+ sites.where(<<-SQL, host: request.host)
5
5
  cname = :host OR
6
6
  FIND_IN_SET(
7
7
  :host,
@@ -14,7 +14,7 @@ module Pageflow
14
14
  entry: entry,
15
15
  theme: theme,
16
16
  theme_customization: Pageflow.theme_customizations.get(
17
- account: entry.account,
17
+ site: entry.site,
18
18
  entry_type_name: entry.type_name
19
19
  )
20
20
  )
@@ -52,7 +52,7 @@ module Pageflow
52
52
  end
53
53
 
54
54
  def update_meta_data!(attributes)
55
- draft.update_attributes!(attributes)
55
+ draft.update!(attributes)
56
56
  end
57
57
 
58
58
  def self.find(id)
@@ -0,0 +1,32 @@
1
+ module Pageflow
2
+ # @api private
3
+ EntriesFeed = Struct.new(:title, :locale, :custom_url, :root_url, :entries) do
4
+ def updated_at
5
+ entries.map(&:published_at).max
6
+ end
7
+
8
+ class << self
9
+ def for(site:, locale:)
10
+ new(
11
+ site.title.presence || site.host,
12
+ locale,
13
+ site.custom_feed_url&.gsub(':locale', locale),
14
+ site.canonical_entry_url_prefix&.gsub(':locale', locale),
15
+ find_entries(site, locale)
16
+ )
17
+ end
18
+
19
+ private
20
+
21
+ def find_entries(site, locale)
22
+ Pageflow::PublishedEntry.wrap_all(
23
+ site
24
+ .entries
25
+ .published_without_password_protection
26
+ .where(pageflow_revisions: {locale: locale})
27
+ .order('first_published_at DESC')
28
+ )
29
+ end
30
+ end
31
+ end
32
+ end
@@ -13,7 +13,7 @@ module Pageflow
13
13
 
14
14
  belongs_to :account, counter_cache: true
15
15
  belongs_to :folder, optional: true
16
- belongs_to :theming
16
+ belongs_to :site
17
17
 
18
18
  has_many :revisions, -> { order('frozen_at DESC') }
19
19
 
@@ -36,7 +36,7 @@ module Pageflow
36
36
 
37
37
  has_secure_password validations: false
38
38
 
39
- validates :account, :theming, :presence => true
39
+ validates :account, :site, :presence => true
40
40
  validates :title, presence: true
41
41
  validate :entry_type_is_available_for_account
42
42
  validate :folder_belongs_to_same_account
@@ -57,8 +57,7 @@ module Pageflow
57
57
  end
58
58
 
59
59
  def entry_template
60
- @entry_template ||= EntryTemplate.find_or_initialize_by(
61
- account_id: account.id,
60
+ @entry_template ||= site.entry_templates.find_or_initialize_by(
62
61
  entry_type_name: type_name
63
62
  )
64
63
  end
@@ -15,7 +15,7 @@ module Pageflow
15
15
 
16
16
  delegate(:id, :slug,
17
17
  :entry_type,
18
- :account, :theming,
18
+ :account, :site,
19
19
  :permalink,
20
20
  :feature_state, :enabled_feature_names,
21
21
  :edit_lock,
@@ -47,7 +47,7 @@ module Pageflow
47
47
  end
48
48
 
49
49
  def home_button
50
- HomeButton.new(revision, theming)
50
+ HomeButton.new(revision, site)
51
51
  end
52
52
 
53
53
  def overview_button
@@ -45,7 +45,7 @@ module Pageflow
45
45
  type_name: original_entry.type_name,
46
46
  title: new_title,
47
47
  account: original_entry.account,
48
- theming: original_entry.theming,
48
+ site: original_entry.site,
49
49
  features_configuration: original_entry.features_configuration,
50
50
 
51
51
  skip_draft_creation: true
@@ -3,15 +3,15 @@ module Pageflow
3
3
  include ThemeReferencer
4
4
  include SerializedConfiguration
5
5
  serialize :default_share_providers, JSON
6
- belongs_to :account
7
- delegate :enabled_feature_names, to: :account
6
+ belongs_to :site
7
+ delegate :enabled_feature_names, to: :site
8
8
  has_many :widgets, as: :subject, dependent: :destroy
9
9
 
10
- validates :account, presence: true
10
+ validates :site, presence: true
11
11
  validates :entry_type_name, presence: true
12
12
  validates :entry_type_name,
13
13
  uniqueness: {
14
- scope: :account
14
+ scope: :site
15
15
  }
16
16
 
17
17
  def entry_type