pages_core 3.15.3 → 3.15.5
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/app/assets/builds/pages_core/admin-dist.js +1 -1
- data/app/assets/builds/pages_core/admin-dist.js.map +4 -4
- data/app/assets/builds/pages_core/admin.css +378 -253
- data/app/assets/builds/pages_core/mailer.css +41 -6
- data/app/assets/builds/pages_core_fonts/121b837e.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/216e5c23.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/3017b52f.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/489746b9.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/49775483.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/49c9e472.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/4a119645.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/5d56d7a8.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/61ea75a6.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/62cbb778.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/647d26c.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/67764053.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/6bb0fd00.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/6c0194a2.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/71423409.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/7584e61d.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/77bcfa1c.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/7aca0cc5.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/9a09533f.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/a51f5bc8.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/a80b2975.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/a891f617.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/ad6083f3.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/b29a61ff.woff2 +0 -0
- data/app/assets/builds/{fonts/6569749d.ttf → pages_core_fonts/b30b0656.ttf} +0 -0
- data/app/assets/builds/pages_core_fonts/b3a5f48c.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/bc73ee06.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/c38c6d45.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/c5ce0b1f.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/c8d53904.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/ce13c169.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/d43bd0d5.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/e1c7d368.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/e1e8175d.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/e318f796.woff2 +0 -0
- data/app/assets/builds/{fonts/ee32bc60.ttf → pages_core_fonts/e7acb7d9.ttf} +0 -0
- data/app/assets/builds/pages_core_fonts/ee5514c6.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/f4e495e2.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/f736ec65.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/f741c7ba.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/f7767345.woff2 +0 -0
- data/app/assets/builds/pages_core_fonts/fe9eb751.woff2 +0 -0
- data/app/assets/stylesheets/pages_core/admin/components/forms.css +2 -2
- data/app/assets/stylesheets/pages_core/admin/components/header.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/controllers/pages.css +1 -1
- data/app/assets/stylesheets/pages_core/admin/global/fonts.css +38 -38
- data/app/controllers/{pages_core → admin}/admin_controller.rb +1 -3
- data/app/controllers/attachments_controller.rb +40 -0
- data/app/controllers/concerns/pages_core/document_title_controller.rb +16 -0
- data/app/controllers/concerns/pages_core/page_parameters.rb +1 -1
- data/app/controllers/concerns/pages_core/pages/preview_controller.rb +49 -0
- data/app/controllers/concerns/pages_core/pages/rss_controller.rb +43 -0
- data/app/controllers/errors_controller.rb +2 -0
- data/app/controllers/images_controller.rb +13 -0
- data/app/controllers/pages_core/frontend/pages_controller.rb +3 -4
- data/app/controllers/pages_core/frontend_controller.rb +6 -1
- data/app/controllers/pages_core/sitemaps_controller.rb +21 -52
- data/app/helpers/pages_core/admin/image_uploads_helper.rb +1 -1
- data/app/helpers/pages_core/application_helper.rb +0 -3
- data/app/helpers/pages_core/attachments_helper.rb +0 -10
- data/app/helpers/pages_core/feed_tags_helper.rb +31 -0
- data/app/helpers/pages_core/frontend_helper.rb +3 -0
- data/app/helpers/pages_core/head_tags_helper.rb +80 -70
- data/app/helpers/pages_core/page_path_helper.rb +1 -12
- data/app/javascript/components/Attachments/Attachment.tsx +3 -3
- data/app/javascript/components/Attachments/AttachmentEditor.tsx +5 -5
- data/app/javascript/components/Attachments/Deleted.tsx +28 -0
- data/app/javascript/components/Attachments/List.tsx +11 -24
- data/app/javascript/components/Attachments/Placeholder.tsx +0 -2
- data/app/javascript/components/Attachments.tsx +2 -3
- data/app/javascript/components/DateRangeSelect.tsx +13 -10
- data/app/javascript/components/DateTimeSelect.tsx +11 -11
- data/app/javascript/components/EditableImage.tsx +3 -3
- data/app/javascript/components/FileUploadButton.tsx +3 -3
- data/app/javascript/components/ImageCropper/FocalPoint.tsx +10 -14
- data/app/javascript/components/ImageCropper/Image.tsx +19 -25
- data/app/javascript/components/ImageCropper/Toolbar.tsx +27 -26
- data/app/javascript/components/ImageCropper/useContainerSize.ts +25 -0
- data/app/javascript/components/ImageCropper/useCrop.ts +28 -13
- data/app/javascript/components/ImageCropper/useImageCropperContext.ts +13 -0
- data/app/javascript/components/ImageCropper.tsx +24 -83
- data/app/javascript/components/ImageEditor/Form.tsx +25 -28
- data/app/javascript/components/ImageEditor/useImageEditor.ts +63 -0
- data/app/javascript/components/ImageEditor/useImageEditorContext.ts +14 -0
- data/app/javascript/components/ImageEditor.tsx +28 -42
- data/app/javascript/components/ImageGrid/Deleted.tsx +28 -0
- data/app/javascript/components/ImageGrid/DragElement.tsx +5 -5
- data/app/javascript/components/ImageGrid/FilePlaceholder.tsx +0 -2
- data/app/javascript/components/ImageGrid/Grid.tsx +15 -24
- data/app/javascript/components/ImageGrid/GridImage.tsx +4 -4
- data/app/javascript/components/ImageGrid/Placeholder.tsx +2 -4
- data/app/javascript/components/ImageGrid.tsx +2 -4
- data/app/javascript/components/ImageUploader.tsx +5 -5
- data/app/javascript/components/LabelledField.tsx +6 -6
- data/app/javascript/components/Modal.tsx +16 -13
- data/app/javascript/components/PageForm/Block.tsx +3 -3
- data/app/javascript/components/PageForm/Content.tsx +11 -15
- data/app/javascript/components/PageForm/Dates.tsx +3 -11
- data/app/javascript/components/PageForm/Files.tsx +2 -4
- data/app/javascript/components/PageForm/Form.tsx +3 -9
- data/app/javascript/components/PageForm/Images.tsx +2 -4
- data/app/javascript/components/PageForm/LocaleLinks.tsx +4 -11
- data/app/javascript/components/PageForm/Metadata.tsx +8 -13
- data/app/javascript/components/PageForm/Options.tsx +28 -11
- data/app/javascript/components/PageForm/PageDescription.tsx +7 -14
- data/app/javascript/components/PageForm/PathSegment.tsx +5 -10
- data/app/javascript/components/PageForm/TabPanel.tsx +3 -6
- data/app/javascript/components/PageForm/Tabs.tsx +2 -4
- data/app/javascript/components/PageForm/UnconfiguredContent.tsx +7 -12
- data/app/javascript/components/PageForm/pageParams.ts +3 -2
- data/app/javascript/components/PageForm/usePage.ts +1 -46
- data/app/javascript/components/PageForm/usePageFormContext.ts +8 -0
- data/app/javascript/components/PageForm/useTabs.ts +1 -1
- data/app/javascript/components/PageForm/utils.ts +49 -0
- data/app/javascript/components/PageForm.tsx +52 -48
- data/app/javascript/components/PageImages.tsx +1 -3
- data/app/javascript/components/PageTree/Button.tsx +25 -0
- data/app/javascript/components/PageTree/CollapseArrow.tsx +34 -0
- data/app/javascript/components/PageTree/CollapsedLabel.tsx +21 -0
- data/app/javascript/components/PageTree/EditPageName.tsx +68 -0
- data/app/javascript/components/PageTree/Node.tsx +143 -413
- data/app/javascript/components/PageTree/PageName.tsx +6 -4
- data/app/javascript/components/PageTree/StatusLabel.tsx +10 -0
- data/app/javascript/components/PageTree/tree.ts +268 -0
- data/app/javascript/components/PageTree/usePageTree.ts +268 -0
- data/app/javascript/components/PageTree/usePageTreeContext.ts +13 -0
- data/app/javascript/components/PageTree.tsx +194 -214
- data/app/javascript/components/{RichTextToolbarButton.tsx → RichTextArea/ToolbarButton.tsx} +3 -5
- data/app/javascript/components/RichTextArea/actions.ts +106 -0
- data/app/javascript/components/RichTextArea/useMaybeControlledValue.ts +14 -0
- data/app/javascript/components/RichTextArea.tsx +91 -209
- data/app/javascript/components/TagEditor/AddTagForm.tsx +2 -2
- data/app/javascript/components/TagEditor/Editor.tsx +3 -5
- data/app/javascript/components/TagEditor/Tag.tsx +3 -5
- data/app/javascript/components/TagEditor/useTags.ts +7 -4
- data/app/javascript/components/TagEditor.tsx +2 -4
- data/app/javascript/components/Toast.tsx +5 -5
- data/app/javascript/components/drag/draggedOrder.ts +6 -6
- data/app/javascript/components/drag/useDragCollection.ts +21 -25
- data/app/javascript/components/drag/useDragUploader.ts +20 -18
- data/app/javascript/components/drag/useDraggable.ts +3 -3
- data/app/javascript/features/RichText.tsx +0 -1
- data/app/javascript/features/contentTabs.ts +2 -2
- data/app/javascript/stores/useModalStore.ts +1 -1
- data/app/javascript/stores/useToastStore.ts +2 -2
- data/app/javascript/types/Attachments.ts +11 -11
- data/app/javascript/types/Crop.ts +16 -12
- data/app/javascript/types/Drag.ts +21 -23
- data/app/javascript/types/Images.ts +8 -8
- data/app/javascript/types/PageEditor.ts +11 -4
- data/app/javascript/types/Pages.ts +22 -27
- data/app/javascript/types/Tags.ts +5 -6
- data/app/javascript/types/Template.ts +4 -4
- data/app/javascript/types.ts +2 -2
- data/app/models/attachment.rb +5 -9
- data/app/models/autopublisher.rb +1 -1
- data/app/models/concerns/pages_core/page_model/redirectable.rb +1 -2
- data/app/models/concerns/pages_core/page_model/searchable.rb +1 -1
- data/app/models/concerns/pages_core/page_model/status.rb +2 -4
- data/app/models/concerns/pages_core/searchable_document.rb +2 -4
- data/app/models/image.rb +0 -15
- data/app/models/page_builder.rb +4 -6
- data/app/resources/admin/page_resource.rb +2 -2
- data/app/resources/export/page_resource.rb +1 -1
- data/app/services/pages_core/invite_service.rb +1 -2
- data/app/views/layouts/admin.html.erb +1 -0
- data/app/views/pages_core/sitemaps/index.xml.builder +10 -0
- data/config/routes.rb +4 -3
- data/db/migrate/20240917142300_add_skip_index_to_pages.rb +7 -0
- data/lib/pages_core/engine.rb +15 -17
- data/lib/pages_core/sitemap.rb +58 -0
- data/lib/pages_core/templates/configuration_proxy.rb +3 -3
- data/lib/pages_core.rb +7 -4
- data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +2 -2
- data/lib/rails/generators/pages_core/frontend/templates/application.html.erb +13 -5
- data/lib/rails/generators/pages_core/frontend/templates/postcss.config.js +2 -6
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/components/base.css +3 -1
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/config.css +2 -3
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/animation.css +1 -1
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/colors.css +6 -5
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/fonts.css +1 -1
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/grid.css +9 -6
- data/lib/rails/generators/pages_core/frontend/templates/stylesheets/global/typography.css +42 -26
- data/lib/rails/generators/pages_core/install/templates/application_controller.rb +0 -6
- data/lib/rails/generators/pages_core/rspec/templates/rails_helper.rb +1 -1
- metadata +81 -49
- data/app/assets/builds/fonts/7b7db107.woff2 +0 -0
- data/app/assets/builds/fonts/921961e9.woff2 +0 -0
- data/app/controller_dummies/admin/admin_controller.rb +0 -6
- data/app/controller_dummies/application_controller.rb +0 -6
- data/app/controller_dummies/attachments_controller.rb +0 -4
- data/app/controller_dummies/frontend_controller.rb +0 -4
- data/app/controller_dummies/images_controller.rb +0 -4
- data/app/controller_dummies/page_files_controller.rb +0 -4
- data/app/controller_dummies/pages_controller.rb +0 -4
- data/app/controller_dummies/sitemaps_controller.rb +0 -4
- data/app/controllers/concerns/pages_core/preview_pages_controller.rb +0 -47
- data/app/controllers/concerns/pages_core/rss_controller.rb +0 -41
- data/app/controllers/pages_core/attachments_controller.rb +0 -42
- data/app/controllers/pages_core/frontend/page_files_controller.rb +0 -25
- data/app/controllers/pages_core/images_controller.rb +0 -15
- data/app/helpers/pages_core/meta_tags_helper.rb +0 -96
- data/app/helpers/pages_core/open_graph_tags_helper.rb +0 -49
- data/app/javascript/components/PageTree/Draggable.tsx +0 -338
- data/app/javascript/lib/Tree.ts +0 -305
- data/app/javascript/types/Trees.ts +0 -19
- data/app/views/sitemaps/show.xml.builder +0 -11
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PagesCore
|
4
|
+
module Pages
|
5
|
+
module RssController
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def all_feed_items
|
11
|
+
feeds = Page.enabled_feeds(locale, include_hidden: true)
|
12
|
+
Page.where(parent_page_id: feeds)
|
13
|
+
.order("published_at DESC")
|
14
|
+
.published
|
15
|
+
.localized(locale)
|
16
|
+
end
|
17
|
+
|
18
|
+
def per_page_rss_param(default = 20, max = 1000)
|
19
|
+
return default unless params[:per_page].is_a?(String)
|
20
|
+
|
21
|
+
params[:per_page].to_i.clamp(1, max)
|
22
|
+
end
|
23
|
+
|
24
|
+
def render_page_rss(page, pagination_page = 1)
|
25
|
+
if page.feed_enabled?
|
26
|
+
render_rss(page.pages.paginate(per_page: per_page_rss_param,
|
27
|
+
page: pagination_page)
|
28
|
+
.includes(:image, :author),
|
29
|
+
title: page.name)
|
30
|
+
else
|
31
|
+
render_error 404
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_rss(items, title: nil)
|
36
|
+
@title = PagesCore.config.site_name
|
37
|
+
@title += ": #{title}" if title
|
38
|
+
@items = items
|
39
|
+
render template: "feeds/pages", layout: false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -5,10 +5,9 @@ module PagesCore
|
|
5
5
|
class PagesController < ::FrontendController
|
6
6
|
include PagesCore::FrontendHelper
|
7
7
|
include PagesCore::Templates::ControllerActions
|
8
|
-
include PagesCore::HeadTagsHelper
|
9
8
|
|
10
|
-
include PagesCore::
|
11
|
-
include PagesCore::RssController
|
9
|
+
include PagesCore::Pages::PreviewController
|
10
|
+
include PagesCore::Pages::RssController
|
12
11
|
|
13
12
|
before_action :load_root_pages
|
14
13
|
before_action :find_page_by_path, only: [:show]
|
@@ -75,7 +74,7 @@ module PagesCore
|
|
75
74
|
def render_page
|
76
75
|
return if redirect_page(@page)
|
77
76
|
|
78
|
-
|
77
|
+
if document_title.blank?
|
79
78
|
document_title(@page.meta_title? ? @page.meta_title : @page.name)
|
80
79
|
end
|
81
80
|
|
@@ -3,6 +3,7 @@
|
|
3
3
|
# Abstract controller for all frontend controllers.
|
4
4
|
module PagesCore
|
5
5
|
class FrontendController < ::ApplicationController
|
6
|
+
include PagesCore::DocumentTitleController
|
6
7
|
include ApplicationHelper
|
7
8
|
|
8
9
|
before_action :set_i18n_locale
|
@@ -23,7 +24,11 @@ module PagesCore
|
|
23
24
|
private
|
24
25
|
|
25
26
|
def page_param
|
26
|
-
params[:page].is_a?(String)
|
27
|
+
if params[:page].is_a?(String)
|
28
|
+
[Integer(params[:page], exception: false), 1].compact.max
|
29
|
+
else
|
30
|
+
1
|
31
|
+
end
|
27
32
|
end
|
28
33
|
|
29
34
|
def set_i18n_locale
|
@@ -1,32 +1,32 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module PagesCore
|
4
|
-
class SitemapsController <
|
4
|
+
class SitemapsController < ApplicationController
|
5
5
|
include PagesCore::PagePathHelper
|
6
|
-
static_cache :
|
6
|
+
static_cache :index, :pages
|
7
7
|
|
8
|
-
def
|
9
|
-
@
|
8
|
+
def index
|
9
|
+
@sitemaps = PagesCore::Sitemap.sitemaps.flat_map do |entry|
|
10
|
+
if entry.is_a?(Proc)
|
11
|
+
locales.map { |l| instance_exec(l, &entry) }
|
12
|
+
else
|
13
|
+
entry
|
14
|
+
end
|
15
|
+
end.compact_blank.uniq
|
10
16
|
end
|
11
17
|
|
12
|
-
|
18
|
+
def pages
|
19
|
+
render_sitemap do |map|
|
20
|
+
Page.published.where.not(skip_index: true)
|
21
|
+
.localized(content_locale).find_each do |page|
|
22
|
+
next if page.redirects?
|
13
23
|
|
14
|
-
|
15
|
-
|
16
|
-
timestamp.strftime("%Y-%m-%d")
|
17
|
-
else
|
18
|
-
timestamp.strftime("%Y-%m-%dT%H:%M:%S#{timestamp.formatted_offset}")
|
24
|
+
map.add(page_url(page.locale, page), lastmod: page.updated_at)
|
25
|
+
end
|
19
26
|
end
|
20
27
|
end
|
21
28
|
|
22
|
-
|
23
|
-
{ loc: record_url(record),
|
24
|
-
lastmod: format_time(record.updated_at) }
|
25
|
-
end
|
26
|
-
|
27
|
-
def formatted_entries
|
28
|
-
records.map { |r| format_record(r) }
|
29
|
-
end
|
29
|
+
private
|
30
30
|
|
31
31
|
def locales
|
32
32
|
if PagesCore.config.locales
|
@@ -36,41 +36,10 @@ module PagesCore
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def pages
|
44
|
-
([Page.root.try(:localize, I18n.default_locale)] +
|
45
|
-
locales.flat_map do |locale|
|
46
|
-
Page.published.localized(locale).includes(:parent)
|
47
|
-
end).compact
|
48
|
-
end
|
49
|
-
|
50
|
-
def page_record_url(record)
|
51
|
-
if record == root_page && record.locale == I18n.default_locale
|
52
|
-
root_url
|
53
|
-
else
|
54
|
-
page_url(record.locale, record)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def record_url(record)
|
59
|
-
if record.is_a?(Page)
|
60
|
-
page_record_url(record)
|
61
|
-
elsif localized?(record)
|
62
|
-
polymorphic_url(record, locale: record.locale)
|
63
|
-
else
|
64
|
-
polymorphic_url(record)
|
39
|
+
def render_sitemap(&)
|
40
|
+
respond_to do |format|
|
41
|
+
format.xml { render xml: PagesCore::Sitemap.new(&).to_xml }
|
65
42
|
end
|
66
43
|
end
|
67
|
-
|
68
|
-
def records
|
69
|
-
pages
|
70
|
-
end
|
71
|
-
|
72
|
-
def root_page
|
73
|
-
@root_page ||= Page.root
|
74
|
-
end
|
75
44
|
end
|
76
45
|
end
|
@@ -31,7 +31,7 @@ module PagesCore
|
|
31
31
|
return {} unless image
|
32
32
|
|
33
33
|
{ src: dynamic_image_path(image, size: "#{width * 2}x"),
|
34
|
-
image: ::Admin::ImageResource.new(image).
|
34
|
+
image: ::Admin::ImageResource.new(image).to_h }
|
35
35
|
end
|
36
36
|
|
37
37
|
def editable_image_options(image, width: 250, caption: false, locale: nil)
|
@@ -5,10 +5,7 @@
|
|
5
5
|
module PagesCore
|
6
6
|
module ApplicationHelper
|
7
7
|
include PagesCore::AttachmentsHelper
|
8
|
-
include PagesCore::HeadTagsHelper
|
9
8
|
include PagesCore::ImagesHelper
|
10
|
-
include PagesCore::MetaTagsHelper
|
11
|
-
include PagesCore::OpenGraphTagsHelper
|
12
9
|
include PagesCore::PagePathHelper
|
13
10
|
|
14
11
|
def page_link(page, options = {})
|
@@ -10,16 +10,6 @@ module PagesCore
|
|
10
10
|
super(*attachment_params(args))
|
11
11
|
end
|
12
12
|
|
13
|
-
def page_file_path(*args)
|
14
|
-
ActiveSupport::Deprecation.warn(
|
15
|
-
"#page_file_path is deprecated, use #attachment_path"
|
16
|
-
)
|
17
|
-
page_file = args.detect { |a| a.is_a?(PageFile) }
|
18
|
-
return attachment_path(page_file.attachment) if page_file
|
19
|
-
|
20
|
-
super
|
21
|
-
end
|
22
|
-
|
23
13
|
private
|
24
14
|
|
25
15
|
def attachment_params(args)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module PagesCore
|
4
|
+
module FeedTagsHelper
|
5
|
+
# Generates links for all RSS feeds. Specify
|
6
|
+
# :include_hidden to also include hidden pages.
|
7
|
+
#
|
8
|
+
# feed_tags
|
9
|
+
# feed_tags include_hidden: true
|
10
|
+
#
|
11
|
+
def feed_tags(options = {})
|
12
|
+
feeds = Page.enabled_feeds(content_locale, options)
|
13
|
+
return unless feeds.any?
|
14
|
+
|
15
|
+
feed_tags = [
|
16
|
+
rss_link_tag(PagesCore.config(:site_name),
|
17
|
+
pages_url(content_locale, format: :rss))
|
18
|
+
] + feeds.map do |page|
|
19
|
+
rss_link_tag("#{PagesCore.config(:site_name)}: #{page.name}",
|
20
|
+
page_url(content_locale, page, format: :rss))
|
21
|
+
end
|
22
|
+
safe_join(feed_tags, "\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def rss_link_tag(title, href)
|
28
|
+
tag.link(rel: "alternate", type: "application/rss+xml", title:, href:)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,95 +2,105 @@
|
|
2
2
|
|
3
3
|
module PagesCore
|
4
4
|
module HeadTagsHelper
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
#
|
9
|
-
def document_title(*args)
|
10
|
-
if args.any?
|
11
|
-
@document_title = args.first
|
12
|
-
else
|
13
|
-
safe_join([@document_title, PagesCore.config(:site_name)].compact.uniq,
|
14
|
-
" - ")
|
15
|
-
end
|
5
|
+
def document_title_tag(separator: " - ")
|
6
|
+
parts = [document_title, PagesCore.config.site_name]
|
7
|
+
tag.title(parts.compact_blank.uniq.join(separator))
|
16
8
|
end
|
17
9
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
10
|
+
def head_tag(&)
|
11
|
+
PagesCore.deprecator.warn(
|
12
|
+
"head_tag helper is deprecated and will be removed"
|
13
|
+
)
|
22
14
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def feed_tags(options = {})
|
30
|
-
feeds = Page.enabled_feeds(content_locale, options)
|
31
|
-
return unless feeds.any?
|
32
|
-
|
33
|
-
feed_tags = [
|
34
|
-
rss_link_tag(PagesCore.config(:site_name),
|
35
|
-
pages_url(content_locale, format: :rss))
|
36
|
-
] + feeds.map do |page|
|
37
|
-
rss_link_tag("#{PagesCore.config(:site_name)}: #{page.name}",
|
38
|
-
page_url(content_locale, page, format: :rss))
|
15
|
+
tag.head do
|
16
|
+
safe_join([document_title_tag,
|
17
|
+
pages_meta_tags(instance_variable_get(:@page)),
|
18
|
+
([csrf_meta_tags, csp_meta_tag] unless static_cached?),
|
19
|
+
(block_given? ? capture(&) : nil)].flatten.compact_blank,
|
20
|
+
"\n")
|
39
21
|
end
|
40
|
-
safe_join(feed_tags, "\n")
|
41
22
|
end
|
42
23
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
#
|
47
|
-
# <%= head_tag do %>
|
48
|
-
# <%= stylesheet_link_tag "application" %>
|
49
|
-
# <%= javascript_include_tag "application" %>
|
50
|
-
# <%= feed_tags %>
|
51
|
-
# <% end %>
|
52
|
-
#
|
53
|
-
def head_tag(&)
|
54
|
-
# The block output must be captured first
|
55
|
-
block_output = block_given? ? capture(&) : nil
|
24
|
+
def meta_image_url(image, size: "1200x")
|
25
|
+
return if image.blank?
|
26
|
+
return image unless image.is_a?(Image)
|
56
27
|
|
57
|
-
|
28
|
+
dynamic_image_url(image, size:, only_path: false)
|
58
29
|
end
|
59
30
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
title:,
|
68
|
-
href:)
|
31
|
+
def pages_meta_tags(page = nil)
|
32
|
+
safe_join(
|
33
|
+
[(tag.meta(name: "robots", content: "noindex") if page&.skip_index?),
|
34
|
+
meta_description_tag(meta_description(page)),
|
35
|
+
meta_image_tag(meta_image(page)),
|
36
|
+
open_graph_tags(page)].compact_blank, "\n"
|
37
|
+
)
|
69
38
|
end
|
70
39
|
|
71
40
|
private
|
72
41
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
(tag.link(rel: "image_src", href: meta_image) if meta_image?),
|
79
|
-
open_graph_tags,
|
80
|
-
(csrf_meta_tags unless static_cached?),
|
81
|
-
block_output].compact_blank
|
42
|
+
def meta_description(record = nil)
|
43
|
+
description = content_for(:meta_description)
|
44
|
+
description ||= record.meta_description if record.try(&:meta_description?)
|
45
|
+
description ||= record.excerpt if record.try(&:excerpt?)
|
46
|
+
strip_tags(description)&.strip
|
82
47
|
end
|
83
48
|
|
84
|
-
def meta_description_tag
|
85
|
-
return
|
49
|
+
def meta_description_tag(content)
|
50
|
+
return if content.blank?
|
86
51
|
|
87
|
-
tag.meta(name: "description", content:
|
52
|
+
tag.meta(name: "description", content:)
|
88
53
|
end
|
89
54
|
|
90
|
-
def
|
91
|
-
|
55
|
+
def meta_image(record = nil)
|
56
|
+
meta_image_url(
|
57
|
+
content_for(:meta_image) ||
|
58
|
+
record.try(:meta_image) || record.try(:image)
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def meta_image_tag(href)
|
63
|
+
return if href.blank?
|
92
64
|
|
93
|
-
tag.
|
65
|
+
tag.link(rel: "image_src", href:)
|
66
|
+
end
|
67
|
+
|
68
|
+
def open_graph_description(record = nil)
|
69
|
+
if content_for?(:open_graph_description)
|
70
|
+
content_for(:open_graph_description)
|
71
|
+
elsif record.try(:open_graph_description?)
|
72
|
+
record.open_graph_description
|
73
|
+
else
|
74
|
+
meta_description(record)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def open_graph_properties(record = nil)
|
79
|
+
{ type: "website",
|
80
|
+
site_name: PagesCore.config(:site_name),
|
81
|
+
title: open_graph_title(record),
|
82
|
+
image: meta_image(record),
|
83
|
+
description: open_graph_description(record)&.strip,
|
84
|
+
url: request.url }
|
85
|
+
end
|
86
|
+
|
87
|
+
def open_graph_tags(record = nil)
|
88
|
+
safe_join(
|
89
|
+
open_graph_properties(record)
|
90
|
+
.compact
|
91
|
+
.map { |name, content| tag.meta(property: "og:#{name}", content:) },
|
92
|
+
"\n"
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def open_graph_title(record = nil)
|
97
|
+
if content_for?(:open_graph_title)
|
98
|
+
content_for(:open_graph_title)
|
99
|
+
elsif record.try(:open_graph_title?)
|
100
|
+
record.open_graph_title
|
101
|
+
else
|
102
|
+
document_title
|
103
|
+
end
|
94
104
|
end
|
95
105
|
end
|
96
106
|
end
|
@@ -13,9 +13,7 @@ module PagesCore
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
def page_url(
|
17
|
-
locale, page = page_url_locale_and_page(page_or_locale, page, opts)
|
18
|
-
|
16
|
+
def page_url(locale, page, opts = {})
|
19
17
|
page.localize(locale) do |p|
|
20
18
|
if p.redirects? && html_format?(opts)
|
21
19
|
page_redirect_url(locale, p)
|
@@ -48,15 +46,6 @@ module PagesCore
|
|
48
46
|
path.split("/").map { |s| CGI.escape(s) }.join("/")
|
49
47
|
end
|
50
48
|
|
51
|
-
def page_url_locale_and_page(page_or_locale, page, opts)
|
52
|
-
return [page_or_locale, page] if page
|
53
|
-
|
54
|
-
ActiveSupport::Deprecation.warn(
|
55
|
-
"Calling page_url without locale is deprecated"
|
56
|
-
)
|
57
|
-
[opts[:locale] || content_locale, page_or_locale]
|
58
|
-
end
|
59
|
-
|
60
49
|
def paginated_section(opts)
|
61
50
|
return "" unless opts[:page]
|
62
51
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import { MouseEvent } from "react";
|
2
2
|
import copyToClipboard from "../../lib/copyToClipboard";
|
3
3
|
import AttachmentEditor from "./AttachmentEditor";
|
4
4
|
import useModalStore from "../../stores/useModalStore";
|
@@ -9,7 +9,7 @@ import { Locale } from "../../types";
|
|
9
9
|
|
10
10
|
import { useDraggable } from "../drag";
|
11
11
|
|
12
|
-
|
12
|
+
type Props = {
|
13
13
|
attributeName: string;
|
14
14
|
placeholder: boolean;
|
15
15
|
draggable: Drag.Draggable<Attachments.Record>;
|
@@ -23,7 +23,7 @@ interface Props {
|
|
23
23
|
evt: MouseEvent,
|
24
24
|
draggable: Drag.Draggable<Attachments.Record>
|
25
25
|
) => void;
|
26
|
-
}
|
26
|
+
};
|
27
27
|
|
28
28
|
export default function Attachment(props: Props) {
|
29
29
|
const { attributeName, draggable, locales, locale } = props;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import { ChangeEvent, MouseEvent, useState } from "react";
|
2
2
|
import copyToClipboard, { copySupported } from "../../lib/copyToClipboard";
|
3
3
|
import useModalStore from "../../stores/useModalStore";
|
4
4
|
import useToastStore from "../../stores/useToastStore";
|
@@ -6,12 +6,12 @@ import { putJson } from "../../lib/request";
|
|
6
6
|
import * as Attachments from "../../types/Attachments";
|
7
7
|
import { Locale } from "../../types";
|
8
8
|
|
9
|
-
|
9
|
+
type Props = {
|
10
10
|
attachment: Attachments.Resource;
|
11
11
|
locale: string;
|
12
12
|
locales: { [index: string]: Locale };
|
13
13
|
onUpdate: (attachment: Partial<Attachments.Resource>) => void;
|
14
|
-
}
|
14
|
+
};
|
15
15
|
|
16
16
|
export default function AttachmentEditor(props: Props) {
|
17
17
|
const { attachment, locales } = props;
|
@@ -40,13 +40,13 @@ export default function AttachmentEditor(props: Props) {
|
|
40
40
|
notice("Embed code copied to clipboard");
|
41
41
|
};
|
42
42
|
|
43
|
-
const save = (evt: MouseEvent) => {
|
43
|
+
const save = async (evt: MouseEvent) => {
|
44
44
|
evt.preventDefault();
|
45
45
|
evt.stopPropagation();
|
46
46
|
|
47
47
|
const data = { ...localizations };
|
48
48
|
|
49
|
-
|
49
|
+
await putJson(`/admin/attachments/${attachment.id}`, { attachment: data });
|
50
50
|
|
51
51
|
if (props.onUpdate) {
|
52
52
|
props.onUpdate(data);
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import * as Attachments from "../../types/Attachments";
|
2
|
+
|
3
|
+
type Props = {
|
4
|
+
attributeName: (record: Attachments.Record) => string;
|
5
|
+
deleted: Attachments.Record[];
|
6
|
+
};
|
7
|
+
|
8
|
+
export default function Deleted({ attributeName, deleted }: Props) {
|
9
|
+
return (
|
10
|
+
<div className="deleted">
|
11
|
+
{deleted.map((r) => (
|
12
|
+
<span className="deleted-attachment" key={r.id}>
|
13
|
+
<input name={`${attributeName(r)}[id]`} type="hidden" value={r.id} />
|
14
|
+
<input
|
15
|
+
name={`${attributeName(r)}[attachment_id]`}
|
16
|
+
type="hidden"
|
17
|
+
value={(r.attachment && r.attachment.id) || ""}
|
18
|
+
/>
|
19
|
+
<input
|
20
|
+
name={`${attributeName(r)}[_destroy]`}
|
21
|
+
type="hidden"
|
22
|
+
value="true"
|
23
|
+
/>
|
24
|
+
</span>
|
25
|
+
))}
|
26
|
+
</div>
|
27
|
+
);
|
28
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import React from "react";
|
2
1
|
import Attachment from "./Attachment";
|
2
|
+
import Deleted from "./Deleted";
|
3
3
|
import Placeholder from "./Placeholder";
|
4
4
|
import FileUploadButton from "../FileUploadButton";
|
5
5
|
import { post } from "../../lib/request";
|
@@ -8,9 +8,9 @@ import * as Drag from "../../types/Drag";
|
|
8
8
|
|
9
9
|
import { createDraggable, draggedOrder, useDragUploader } from "../drag";
|
10
10
|
|
11
|
-
|
11
|
+
type Props = Attachments.Options & {
|
12
12
|
state: Attachments.State;
|
13
|
-
}
|
13
|
+
};
|
14
14
|
|
15
15
|
function filenameToName(str: string): string {
|
16
16
|
return str.replace(/\.[\w\d]+$/, "").replace(/_/g, " ");
|
@@ -24,7 +24,7 @@ export default function List(props: Props) {
|
|
24
24
|
const name = {};
|
25
25
|
locales.forEach((l) => (name[l] = file.name));
|
26
26
|
|
27
|
-
const draggable = createDraggable({
|
27
|
+
const draggable = createDraggable<Attachments.Record>({
|
28
28
|
attachment: { filename: file.name, name: name },
|
29
29
|
uploading: true
|
30
30
|
});
|
@@ -58,7 +58,10 @@ export default function List(props: Props) {
|
|
58
58
|
});
|
59
59
|
};
|
60
60
|
|
61
|
-
const dragEnd = (
|
61
|
+
const dragEnd = (
|
62
|
+
dragState: Drag.State<Attachments.Record>,
|
63
|
+
files: File[]
|
64
|
+
) => {
|
62
65
|
collection.dispatch({
|
63
66
|
type: "reorder",
|
64
67
|
payload: draggedOrder(collection, dragState)
|
@@ -69,7 +72,7 @@ export default function List(props: Props) {
|
|
69
72
|
});
|
70
73
|
};
|
71
74
|
|
72
|
-
const [dragState, dragStart, listeners] = useDragUploader
|
75
|
+
const [dragState, dragStart, listeners] = useDragUploader(
|
73
76
|
[collection],
|
74
77
|
dragEnd
|
75
78
|
);
|
@@ -110,7 +113,7 @@ export default function List(props: Props) {
|
|
110
113
|
}
|
111
114
|
};
|
112
115
|
|
113
|
-
const attachment = (draggable: Drag.
|
116
|
+
const attachment = (draggable: Drag.DraggableOrFiles<Attachments.Record>) => {
|
114
117
|
const { dragging } = dragState;
|
115
118
|
|
116
119
|
if (draggable === "Files") {
|
@@ -144,23 +147,7 @@ export default function List(props: Props) {
|
|
144
147
|
return (
|
145
148
|
<div className={classes.join(" ")} ref={collection.ref} {...listeners}>
|
146
149
|
<div className="files">{dragOrder.map((d) => attachment(d))}</div>
|
147
|
-
<
|
148
|
-
{deleted.map((r) => (
|
149
|
-
<span className="deleted-attachment" key={r.id}>
|
150
|
-
<input name={`${attrName(r)}[id]`} type="hidden" value={r.id} />
|
151
|
-
<input
|
152
|
-
name={`${attrName(r)}[attachment_id]`}
|
153
|
-
type="hidden"
|
154
|
-
value={(r.attachment && r.attachment.id) || ""}
|
155
|
-
/>
|
156
|
-
<input
|
157
|
-
name={`${attrName(r)}[_destroy]`}
|
158
|
-
type="hidden"
|
159
|
-
value="true"
|
160
|
-
/>
|
161
|
-
</span>
|
162
|
-
))}
|
163
|
-
</div>
|
150
|
+
<Deleted attributeName={attrName} deleted={deleted} />
|
164
151
|
<div className="drop-target">
|
165
152
|
<FileUploadButton
|
166
153
|
multiple={true}
|