panda_cms 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/Rakefile +0 -1
  4. data/app/assets/builds/panda_cms.css +2415 -1
  5. data/app/assets/config/panda_cms_manifest.js +2 -0
  6. data/app/assets/stylesheets/panda_cms/application.tailwind.css +3 -27
  7. data/app/builders/panda_cms/form_builder.rb +1 -1
  8. data/app/components/panda_cms/admin/button_component.rb +6 -3
  9. data/app/components/panda_cms/admin/flash_message_component.rb +1 -1
  10. data/app/components/panda_cms/admin/tag_component.rb +1 -1
  11. data/app/components/panda_cms/code_component.rb +60 -0
  12. data/app/components/panda_cms/page_menu_component.html.erb +12 -16
  13. data/app/components/panda_cms/page_menu_component.rb +23 -10
  14. data/app/components/panda_cms/rich_text_component.html.erb +6 -38
  15. data/app/components/panda_cms/rich_text_component.rb +24 -7
  16. data/app/components/panda_cms/text_component.rb +25 -22
  17. data/app/controllers/panda_cms/admin/dashboard_controller.rb +14 -6
  18. data/app/controllers/panda_cms/admin/menus_controller.rb +1 -54
  19. data/app/controllers/panda_cms/admin/pages_controller.rb +2 -1
  20. data/app/controllers/panda_cms/admin/sessions_controller.rb +13 -6
  21. data/app/controllers/panda_cms/application_controller.rb +1 -1
  22. data/app/controllers/panda_cms/pages_controller.rb +1 -1
  23. data/app/controllers/panda_cms/posts_controller.rb +1 -1
  24. data/app/helpers/panda_cms/application_helper.rb +9 -9
  25. data/app/javascript/panda_cms/@hotwired--stimulus.js +4 -0
  26. data/app/javascript/panda_cms/@hotwired--turbo.js +160 -0
  27. data/app/javascript/panda_cms/@rails--actioncable--src.js +4 -0
  28. data/app/javascript/panda_cms/application_panda_cms.js +4 -0
  29. data/app/javascript/panda_cms/controllers/dashboard_controller.js +7 -0
  30. data/app/javascript/panda_cms/controllers/index.js +42 -0
  31. data/app/javascript/panda_cms/controllers/slug_controller.js +48 -0
  32. data/app/javascript/panda_cms/panda_cms_editable.js +248 -0
  33. data/app/javascript/panda_cms/tailwindcss-stimulus-components.js +4 -0
  34. data/app/lib/panda_cms/demo_site_generator.rb +1 -1
  35. data/app/lib/panda_cms/slug.rb +1 -1
  36. data/app/models/panda_cms/block.rb +2 -2
  37. data/app/models/panda_cms/page.rb +9 -3
  38. data/app/models/panda_cms/post.rb +1 -1
  39. data/app/models/panda_cms/template.rb +4 -2
  40. data/app/models/panda_cms/user.rb +9 -1
  41. data/app/views/panda_cms/admin/dashboard/show.html.erb +11 -9
  42. data/app/views/panda_cms/admin/forms/new.html.erb +6 -7
  43. data/app/views/panda_cms/admin/menus/index.html.erb +0 -2
  44. data/app/views/panda_cms/admin/pages/edit.html.erb +18 -16
  45. data/app/views/panda_cms/admin/pages/new.html.erb +6 -7
  46. data/app/views/panda_cms/admin/posts/_form.html.erb +4 -4
  47. data/app/views/panda_cms/admin/sessions/new.html.erb +1 -2
  48. data/app/views/panda_cms/admin/shared/_sidebar.html.erb +12 -16
  49. data/app/views/panda_cms/shared/_header.html.erb +14 -14
  50. data/app/views/panda_cms/shared/_importmap.html.erb +22 -0
  51. data/config/importmap.rb +11 -10
  52. data/config/initializers/panda_cms.rb +57 -55
  53. data/config/routes.rb +9 -9
  54. data/config/tailwind.config.js +1 -0
  55. data/db/migrate/20240205223709_create_panda_cms_pages.rb +6 -4
  56. data/lib/generators/panda_cms/install_generator.rb +3 -0
  57. data/lib/panda_cms/engine.rb +27 -22
  58. data/lib/panda_cms/version.rb +1 -1
  59. data/lib/panda_cms.rb +58 -10
  60. data/lib/tasks/panda_cms.rake +41 -57
  61. data/public/panda-cms-assets/rich_text_editor.css +568 -0
  62. metadata +216 -278
  63. data/app/javascript/base.js +0 -37
  64. data/app/javascript/controllers/menu_controller.js +0 -19
  65. data/app/javascript/controllers/text_controller.js +0 -78
  66. data/app/javascript/controllers/text_field_update_controller.js +0 -51
  67. data/app/javascript/vendor/stimulus-components-rails-nested-form.js +0 -2
  68. data/app/javascript/vendor/tailwindcss-stimulus-components.js +0 -2
  69. data/app/views/panda_cms/admin/menus/_form.html.erb +0 -21
  70. data/app/views/panda_cms/admin/menus/_menu_item_fields.html.erb +0 -7
  71. data/app/views/panda_cms/admin/menus/edit.html.erb +0 -58
  72. data/app/views/panda_cms/admin/menus/new.html.erb +0 -5
  73. data/public/panda-cms-assets/javascripts/base.js +0 -37
  74. data/public/panda-cms-assets/javascripts/controllers/menu_controller.js +0 -19
  75. data/public/panda-cms-assets/javascripts/controllers/text_field_update_controller.js +0 -23
  76. data/public/panda-cms-assets/javascripts/embed/editable.js +0 -358
  77. data/public/panda-cms-assets/javascripts/embed/rich_text.css +0 -1294
  78. data/public/panda-cms-assets/javascripts/vendor/stimulus-components-rails-nested-form.js +0 -2
  79. data/public/panda-cms-assets/javascripts/vendor/stimulus-loading.js +0 -113
  80. data/public/panda-cms-assets/javascripts/vendor/tailwindcss-stimulus-components.js +0 -2
  81. /data/db/migrate/{20240804110225_add_status_to_panda_cms_pages.rb → 20240315125411_add_status_to_panda_cms_pages.rb} +0 -0
@@ -1 +1,3 @@
1
1
  //= link_tree ../builds/ .css
2
+ //= link_directory ../../javascript/panda_cms .js
3
+ //= link_directory ../../javascript/panda_cms/controllers .js
@@ -13,9 +13,9 @@
13
13
 
14
14
  --color-highlight: 208 64 20; /* #D04014 */
15
15
 
16
- --color-active: 188 230 163; /* #BCE6A3 */
16
+ --color-active: 0 135 85; /* #008755 */
17
17
  --color-warning: 250 207 142; /* #FACF8E */
18
- --color-inactive: 211 229 249; /* #D3E5F9 */
18
+ --color-inactive: 216 247 245; /* #d6e4f7 */
19
19
  --color-error: 245 129 129; /* #F58181 */
20
20
  }
21
21
 
@@ -29,6 +29,7 @@
29
29
 
30
30
  --color-active: 166 211 129; /* #A6D381 */
31
31
  --color-warning: 244 190 102; /* #F4BE66 */
32
+ --color-inactive: 216 247 245; /* #d6e4f7 */
32
33
  --color-error: 208 64 20; /* #D04014 */
33
34
  }
34
35
 
@@ -39,37 +40,12 @@
39
40
  }
40
41
  }
41
42
 
42
- .ql-editor {
43
- border: none !important;
44
- /* font-size: 1.3rem !important; */
45
- padding: 0 !important;
46
- margin: 0;
47
-
48
- margin-top: -1rem;
49
-
50
- &:active, &:focus {
51
- border: none;
52
- outline: none;
53
- }
54
-
55
- h1, h2, h3, p {
56
- margin-bottom: 20px !important;
57
- font-size: 130% !important;
58
- }
59
-
60
- li {
61
- font-size: 130% !important;
62
- }
63
- }
64
-
65
43
  @import "actiontext.css";
66
44
 
67
45
  /*
68
46
  * Provides a drop-in pointer for the default Trix stylesheet that will format the toolbar and
69
47
  * the trix-editor content (whether displayed or under editing). Feel free to incorporate this
70
48
  * inclusion directly in any other asset bundle and remove this file.
71
- *
72
- *= require trix
73
49
  */
74
50
 
75
51
  /*
@@ -12,7 +12,7 @@ module PandaCms
12
12
  label(attribute) + meta_text(options) +
13
13
  content_tag(:div, class: "flex flex-grow") do
14
14
  content_tag(:span, class: "inline-flex items-center px-3 text-base border border-r-none rounded-s-md whitespace-nowrap break-keep") { options.dig(:data, :prefix) } +
15
- super(attribute, options.reverse_merge(class: input_styles_prefix + " rounded-l-none border-l-none"))
15
+ super(attribute, options.reverse_merge(class: input_styles_prefix + " input-prefix rounded-l-none border-l-none"))
16
16
  end
17
17
  end
18
18
  else
@@ -5,13 +5,14 @@ module PandaCms
5
5
  class ButtonComponent < ViewComponent::Base
6
6
  attr_accessor :text, :action, :link, :icon, :size, :data
7
7
 
8
- def initialize(text: "Button", action: nil, data: {}, link: "#", icon: nil, size: :regular)
8
+ def initialize(text: "Button", action: nil, data: {}, link: "#", icon: nil, size: :regular, id: nil)
9
9
  @text = text
10
10
  @action = action
11
11
  @data = data
12
12
  @link = link
13
13
  @icon = icon
14
14
  @size = size
15
+ @id = id
15
16
  end
16
17
 
17
18
  def call
@@ -33,15 +34,17 @@ module PandaCms
33
34
  classes += case @action
34
35
  when :save, :create
35
36
  "text-white bg-active"
37
+ when :save_inactive
38
+ "text-white bg-inactive"
36
39
  when :secondary
37
- "text-highlight border border-highlight bg-white hover:bg-sky-100 focus-visible:outline-highlight "
40
+ "text-dark border-2 border-dark bg-transparent hover:bg-light transition-all "
38
41
  when :delete, :destroy, :danger
39
42
  "text-error border border-error bg-red-100 hover:bg-red-200 hover:text-error focus-visible:outline-red-300 "
40
43
  else
41
44
  "text-dark border-2 border-dark bg-transparent hover:bg-light transition-all "
42
45
  end
43
46
 
44
- content_tag :a, href: @link, class: classes, data: @data do
47
+ content_tag :a, href: @link, class: classes, data: @data, id: @id do
45
48
  @text
46
49
  end
47
50
  end
@@ -19,7 +19,7 @@ module PandaCms
19
19
  when :warning
20
20
  "text-warning"
21
21
  when :info, :notice
22
- "text-highlight"
22
+ "text-active"
23
23
  else
24
24
  "text-mid"
25
25
  end
@@ -15,7 +15,7 @@ module PandaCms
15
15
 
16
16
  classes += case @status
17
17
  when :active
18
- "text-black ring-black/30 bg-active border-0 "
18
+ "text-white ring-black/30 bg-active border-0 "
19
19
  when :draft
20
20
  "text-black ring-black/30 bg-warning "
21
21
  when :inactive, :hidden
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PandaCms
4
+ # Text component
5
+ # @param key [Symbol] The key to use for the text component
6
+ # @param text [String] The text to display
7
+ # @param editable [Boolean] If the text is editable or not (defaults to true)
8
+ # @param options [Hash] The options to pass to the content_tag
9
+ class CodeComponent < ViewComponent::Base
10
+ KIND = "code"
11
+
12
+ def initialize(key: :text_component, text: "", editable: true, **options)
13
+ @key = key
14
+ @text = text
15
+ @options = options || {}
16
+ @options[:id] ||= "code-#{key.to_s.dasherize}"
17
+ @editable = editable
18
+ end
19
+
20
+ def call
21
+ # TODO: For the non-editable version, grab this from a cache or similar?
22
+ block = PandaCms::Block.find_by(kind: KIND, key: @key, panda_cms_template_id: Current.page.panda_cms_template_id)
23
+
24
+ if block.nil?
25
+ raise PandaCms::MissingBlockError("Block with key #{@key} not found") unless Rails.env.production?
26
+ return false
27
+ end
28
+
29
+ block_content = block.block_contents.find_by(panda_cms_page_id: Current.page.id)
30
+ code_content = block_content&.content.to_s
31
+
32
+ if component_is_editable?
33
+ @options[:contenteditable] = "plaintext-only"
34
+ @options[:data] = {
35
+ "editable-kind": "html",
36
+ "editable-page-id": Current.page.id,
37
+ "editable-block-content-id": block_content&.id
38
+ }
39
+ @options[:class] = "block bg-yellow-50 font-mono p-2 border-2 border-yellow-700"
40
+ @options[:style] = "white-space: pre-wrap;"
41
+
42
+ @options[:id] = "editor-#{block_content&.id}"
43
+ # TODO: Switch between the HTML and the preview?
44
+ content_tag(:div, code_content, @options, true)
45
+ else
46
+ code_content.html_safe
47
+ end
48
+ end
49
+
50
+ def component_is_editable?
51
+ # TODO: Permissions
52
+ @editable && is_embedded? && Current.user&.admin
53
+ end
54
+
55
+ def is_embedded?
56
+ # TODO: Check security on this - embed_id should match something?
57
+ request.params.dig(:embed_id).present?
58
+ end
59
+ end
60
+ end
@@ -1,22 +1,18 @@
1
- <% inactive_nav_styles = "border-gray-200 text-slate-600 " %>
2
- <% active_nav_styles = "bg-gray-100 text-blue-900 border-blue-900 " %>
3
- <nav class="pl-8 font-sans font-sm">
4
- <ul role="list" class="">
1
+ <nav class="<%= styles[:container] %>">
2
+ <ul role="list" class="p-0 m-0">
5
3
  <li>
6
- <a href="<%= menu_item.page.path %>" class="border-l-2 hover:bg-gray-50 group px-3 py-2.5 text-lg leading-6 font-semibold <%= menu_item.page == PandaCms::Current.page ? active_nav_styles : inactive_nav_styles %>">
4
+ <a href="<%= menu_item.page.path %>" class="<%= menu_item.page == PandaCms::Current.page ? styles[:current_page_active] : styles[:current_page_inactive] %>">
7
5
  <%= menu_item.text %>
8
6
  </a>
9
7
  </li>
10
- <div>
11
- <ul class="mt-1">
12
- <% PandaCms::MenuItem.each_with_level(menu_item.descendants) do |submenu_item, level| %>
13
- <li data-level="<%= level %>" data-page-id="<%= submenu_item.page.id %>" <% if level > 1 && !PandaCms::Current.page.id.in?(submenu_item.page.self_and_ancestors.ids + submenu_item.page.siblings.ids) %> class="hidden"<% end %>>
14
- <a href="<%= submenu_item.page.path %>" class="<%= helpers.menu_indent(submenu_item) %> border-l-2 hover:bg-gray-50 block px-3 py-2.5 text-base leading-6 font-regular <%= submenu_item.page == PandaCms::Current.page ? active_nav_styles : inactive_nav_styles %>">
15
- <%= submenu_item.page.title %>
16
- </a>
17
- </li>
18
- <% end %>
19
- </ul>
20
- </div>
8
+ <ul>
9
+ <% PandaCms::MenuItem.includes(:page).each_with_level(menu_item.descendants) do |submenu_item, level| %>
10
+ <% next if PandaCms::Current.page == menu_item.page && level > 1 # If we're on the "top" menu item, only show its direct ancestors %>
11
+ <% next if submenu_item.page.depth > PandaCms::Current.page.depth && !PandaCms::Current.page.in?(submenu_item.page.ancestors) %>
12
+ <li data-level="<%= level %>" data-page-id="<%= submenu_item.page.id %>" class="<%= submenu_item.page == PandaCms::Current.page ? @styles[:active] : @styles[:inactive] %>">
13
+ <a href="<%= submenu_item.page.path %>" class="<%= helpers.menu_indent(submenu_item, indent_with: @styles[:indent_with]) %>"><%= submenu_item.page.title %></a>
14
+ </li>
15
+ <% end %>
16
+ </ul>
21
17
  </ul>
22
18
  </nav>
@@ -2,20 +2,33 @@
2
2
 
3
3
  module PandaCms
4
4
  class PageMenuComponent < ViewComponent::Base
5
+ attr_accessor :page
5
6
  attr_accessor :menu_item
6
- attr_accessor :children
7
+ attr_accessor :styles
7
8
 
8
- def initialize(page:, start_depth:)
9
- start_page = if page.depth == start_depth
10
- page
11
- else
12
- page.ancestors.find { |anc| anc.depth == start_depth }
13
- end
9
+ def initialize(page:, start_depth:, styles: {})
10
+ @page = page
11
+
12
+ unless @page.nil?
13
+ start_page = if @page.depth == start_depth
14
+ @page
15
+ else
16
+ @page.ancestors.find { |anc| anc.depth == start_depth }
17
+ end
18
+
19
+ menu = start_page&.page_menu
20
+ return if menu.nil?
14
21
 
15
- menu = PandaCms::Menu.find_by(kind: "auto", start_page: start_page)
16
- @menu_item = menu.menu_items.order(:lft)&.first unless menu.nil?
22
+ @menu_item = menu.menu_items.order(:lft)&.first
23
+
24
+ # Set some default styles for sanity
25
+ @styles = styles
26
+ @styles[:indent_with] ||= "pl-2"
27
+ end
28
+ end
17
29
 
18
- @children = menu_item&.descendants unless menu_item.nil?
30
+ def render?
31
+ @page&.path != "/" && @menu_item.present?
19
32
  end
20
33
  end
21
34
  end
@@ -1,38 +1,6 @@
1
- <%= content_tag(:div, @content, @options) %>
2
-
3
- <script type="text/javascript">
4
- document.addEventListener("pandaCmsRichTextEditorLoaded", function() {
5
- console.debug("[Panda CMS] Called event listener: pandaCmsRichTextEditorLoaded for <%= @options[:id] %>");
6
-
7
- // Allowing per-element toolbar configuration, if needed
8
- let quillOptions = {
9
- modules: {
10
- toolbar: [
11
- [{ header: [1, 2, 3, false] }],
12
- ["bold", "italic", "underline"],
13
- [{ list: "ordered" }, { list: "bullet" }],
14
- [{ script: "sub" }, { script: "super" }],
15
- [{ color: [] }, { background: [] }],
16
- [{ align: [] }],
17
- ["link", "image", "video", "code-block", "clean"],
18
- ],
19
- magicUrl: true,
20
- imageCompressor: {
21
- quality: 0.9,
22
- maxWidth: 2000,
23
- maxHeight: 2000,
24
- imageType: "image/png",
25
- keepImageTypes: ["image/jpeg", "image/jpg", "image/png"],
26
- },
27
- },
28
- theme: "snow",
29
- };
30
-
31
- let quillVar = "<%= @options[:id] %>";
32
- console.debug(`[Panda CMS] Enabling Quill editor: ${quillVar}`);
33
- console.debug(`[Panda CMS] Quill options for ${quillVar}: `, quillOptions);
34
-
35
- Quill.register("modules/imageCompressor", imageCompressor);
36
- quillVar = new Quill("#" + quillVar, quillOptions);
37
- });
38
- </script>
1
+ <% if @editable %>
2
+ <input id="trix_<%= @options[:id] %>" value="<%= @content %>" type="hidden" name="trix_<%= @options[:id] %>" data-editor-block-content-id="<%= @options[:data][:block_content_id] %>" data-editor-type="<%= @options[:data][:mode] %>">
3
+ <trix-editor input="trix_<%= @options[:id] %>" class="panda-cms-content"></trix-editor>
4
+ <% else %>
5
+ <div class="panda-cms-content"><%= @content %></div>
6
+ <% end %>
@@ -9,6 +9,10 @@ module PandaCms
9
9
  class RichTextComponent < ViewComponent::Base
10
10
  KIND = "rich_text"
11
11
 
12
+ attr_accessor :editable
13
+ attr_accessor :content
14
+ attr_accessor :options
15
+
12
16
  def initialize(key: :text_component, text: "Lorem ipsum...", editable: true, **options)
13
17
  @key = key
14
18
  @text = text
@@ -18,20 +22,33 @@ module PandaCms
18
22
 
19
23
  # Check if the element is editable and set up the content
20
24
  def before_render
21
- @editable &&= params[:embed_id].present? && params[:embed_id] == Current.page.id && Current.user&.admin?
22
-
25
+ @editable &&= params[:embed_id].present? && params[:embed_id] == Current.page.id && Current.user.admin?
23
26
  block = PandaCms::Block.find_by(kind: "rich_text", key: @key, panda_cms_template_id: Current.page.panda_cms_template_id)
24
27
  block_content = block.block_contents.find_by(panda_cms_page_id: Current.page.id)
25
- @content = block_content.content.html_safe
26
- @options[:id] = "editor_rich_text_#{block_content&.id&.tr("-", "_")}"
27
- @options[:class] ||= ""
28
- @options[:class] += " content-rich-text"
28
+ @content = block_content.content
29
+
30
+ @options[:id] = "editor_rich_text_#{block_content.id.tr("-", "_")}"
29
31
 
30
32
  if @editable
31
33
  @options[:data] = {
32
- block_content_id: block_content&.id
34
+ block_content_id: block_content&.id,
35
+ mode: "rich-text"
33
36
  }
37
+ else
38
+ @content = @content.html_safe
34
39
  end
40
+ rescue => e
41
+ if Rails.env.production?
42
+ Sentry.capture_exception(e) if defined?(Sentry)
43
+ else
44
+ raise e
45
+ end
46
+ false
47
+ end
48
+
49
+ # Only render the component if there is some content set, or if the component is editable
50
+ def render?
51
+ @content.present? || @editable
35
52
  end
36
53
  end
37
54
  end
@@ -21,17 +21,37 @@ module PandaCms
21
21
  end
22
22
 
23
23
  def call
24
- # TODO: For the non-editable version, grab this from a cache or similar?
24
+ content_tag(:span, @content, @options, false) # Don't escape the content
25
+ rescue
26
+ if !Rails.env.production? || is_defined?(Sentry)
27
+ raise PandaCms::MissingBlockError("Block with key #{@key} not found")
28
+ else
29
+ false
30
+ end
31
+ end
32
+
33
+ #
34
+ # Prepares content for display
35
+ #
36
+ # @usage Do not use this when rendering editable content
37
+ def prepare_content_for_display(content)
38
+ # Replace \n characters with <br> tags
39
+ content.gsub("\n", "<br>")
40
+ end
41
+
42
+ # Check if the element is editable
43
+ # TODO: Check user permissions
44
+ def before_render
45
+ @editable &&= params[:embed_id].present? && params[:embed_id] == Current.page.id
46
+
25
47
  block = PandaCms::Block.find_by(kind: KIND, key: @key, panda_cms_template_id: Current.page.panda_cms_template_id)
26
48
 
27
49
  if block.nil?
28
- raise PandaCms::MissingBlockError("Block with key #{@key} not found") unless Rails.env.production?
29
50
  return false
30
51
  end
31
52
 
32
53
  block_content = block.block_contents.find_by(panda_cms_page_id: Current.page.id)
33
54
  plain_text = block_content&.content.to_s
34
-
35
55
  if @editable
36
56
  @options[:contenteditable] = "plaintext-only"
37
57
  @options[:data] = {
@@ -41,27 +61,10 @@ module PandaCms
41
61
  }
42
62
 
43
63
  @options[:id] = "editor-#{block_content&.id}"
44
- content = plain_text
64
+ @content = plain_text
45
65
  else
46
- content = prepare_content_for_display(plain_text)
66
+ @content = prepare_content_for_display(plain_text)
47
67
  end
48
-
49
- content_tag(:span, content, @options, false) # Don't escape the content
50
- end
51
-
52
- #
53
- # Prepares content for display
54
- #
55
- # @usage Do not use this when rendering editable content
56
- def prepare_content_for_display(content)
57
- # Replace \n characters with <br> tags
58
- content.gsub("\n", "<br>")
59
- end
60
-
61
- # Check if the element is editable
62
- # TODO: Check user permissions
63
- def before_render
64
- @editable &&= params[:embed_id].present? && params[:embed_id] == Current.page.id
65
68
  end
66
69
  end
67
70
  end
@@ -14,17 +14,25 @@ module PandaCms
14
14
  private
15
15
 
16
16
  def set_initial_breadcrumb
17
- add_breadcrumb "Dashboard", PandaCms.admin_path
17
+ add_breadcrumb "Dashboard", PandaCms.route_namespace
18
18
  end
19
19
 
20
20
  def domain_expiry
21
21
  return "" if request.domain == "localhost"
22
22
 
23
- whois_record = Whois.whois(request.domain)
24
- if (parser = whois_record&.parser)
25
- " (expiry date: #{parser.expires_on&.strftime("%d %b %Y")})"
26
- else
27
- " (error parsing WHOIS data)"
23
+ begin
24
+ whois_record = Whois.whois(request.domain)
25
+ if (parser = whois_record&.parser)
26
+ " (expiry date: #{parser.expires_on&.strftime("%d %b %Y")})"
27
+ else
28
+ " (error parsing WHOIS data)"
29
+ end
30
+ rescue => e
31
+ if defined?(Sentry)
32
+ Sentry.capture_exception(e)
33
+ end
34
+
35
+ ""
28
36
  end
29
37
  end
30
38
  end
@@ -3,8 +3,7 @@
3
3
  module PandaCms
4
4
  module Admin
5
5
  class MenusController < ApplicationController
6
- before_action :set_initial_breadcrumb, only: %i[index new edit create update]
7
- before_action :set_paper_trail_whodunnit, only: %i[create update]
6
+ before_action :set_initial_breadcrumb, only: %i[index]
8
7
  before_action :authenticate_admin_user!
9
8
 
10
9
  # Lists all menus which can be managed by the administrator
@@ -15,47 +14,6 @@ module PandaCms
15
14
  render :index, locals: {menus: menus}
16
15
  end
17
16
 
18
- # Loads the menu editor
19
- # @type GET
20
- def edit
21
- add_breadcrumb menu.name, edit_admin_menu_path(menu)
22
- end
23
-
24
- # GET /admin/menus/new
25
- # @type GET
26
- def new
27
- @menu = PandaCms::Menu.new
28
- @menu.menu_items.new
29
- set_new_menu_breadcrumb
30
- end
31
-
32
- # POST /admin/menus
33
- def create
34
- @menu = PandaCms::Menu.new(menu_params)
35
-
36
- if @menu.save
37
- redirect_to admin_menus_path, notice: "Menu was successfully created."
38
- else
39
- flash[:error] = @menu.errors.full_messages.join(", ")
40
- set_new_menu_breadcrumb
41
- render :new, status: :unprocessable_entity
42
- end
43
- end
44
-
45
- # @type PATCH/PUT
46
- # @return
47
- def update
48
- if menu.update!(menu_params)
49
- redirect_to edit_admin_menu_path(menu),
50
- status: :see_other,
51
- flash: {success: "This menu was successfully updated!"}
52
- else
53
- add_breadcrumb menu.name, edit_admin_menu_path(menu)
54
- flash[:error] = "There was an error updating the menu."
55
- render :edit, status: :unprocessable_entity
56
- end
57
- end
58
-
59
17
  private
60
18
 
61
19
  def menu
@@ -65,17 +23,6 @@ module PandaCms
65
23
  def set_initial_breadcrumb
66
24
  add_breadcrumb "Menus", admin_menus_path
67
25
  end
68
-
69
- def set_new_menu_breadcrumb
70
- add_breadcrumb "Add New Menu", new_admin_menu_path
71
- end
72
-
73
- # Only allow a list of trusted parameters through.
74
- # @type private
75
- # @return ActionController::StrongParameters
76
- def menu_params
77
- params.require(:menu).permit(:name, menu_items_attributes: %i[id text external_url sort_order panda_cms_page_id _destroy])
78
- end
79
26
  end
80
27
  end
81
28
  end
@@ -26,6 +26,7 @@ module PandaCms
26
26
  # @type GET
27
27
  def edit
28
28
  add_breadcrumb page.title, edit_admin_page_path(page)
29
+
29
30
  render :edit, locals: {page: page, template: page.template}
30
31
  end
31
32
 
@@ -64,7 +65,7 @@ module PandaCms
64
65
  @page ||= if params[:id]
65
66
  PandaCms::Page.find(params[:id])
66
67
  else
67
- PandaCms::Page.new(template: PandaCms::Template.most_used)
68
+ PandaCms::Page.new(template: PandaCms::Template.default)
68
69
  end
69
70
  end
70
71
 
@@ -6,14 +6,14 @@ module PandaCms
6
6
  layout "panda_cms/public"
7
7
 
8
8
  def new
9
- @providers = PandaCms.authentication.select { |_, v| v[:enabled] && !v[:hidden] }.keys
9
+ @providers = PandaCms.config.authentication.select { |_, v| v[:enabled] && !v[:hidden] }.keys
10
10
  end
11
11
 
12
12
  def create
13
13
  user_info = request.env.dig("omniauth.auth", "info")
14
14
  provider = params[:provider].to_sym
15
15
 
16
- unless PandaCms.authentication.dig(provider, :enabled)
16
+ unless PandaCms.config.authentication.dig(provider, :enabled)
17
17
  Rails.logger.error "Authentication provider '#{provider}' is not enabled"
18
18
  redirect_to admin_login_path, flash: {error: t("panda_cms.admin.sessions.create.error")}
19
19
  return
@@ -21,8 +21,8 @@ module PandaCms
21
21
 
22
22
  user = PandaCms::User.find_by(email: user_info["email"])
23
23
 
24
- if !user && PandaCms.authentication.dig(provider, :create_account_on_first_login)
25
- create_as_admin = PandaCms.authentication.dig(provider, :create_as_admin)
24
+ if !user && PandaCms.config.authentication.dig(provider, :create_account_on_first_login)
25
+ create_as_admin = PandaCms.config.authentication.dig(provider, :create_as_admin)
26
26
 
27
27
  # Always create the first user as admin, regardless of what our settings look like
28
28
  # else we can't ever really login. :)
@@ -47,9 +47,16 @@ module PandaCms
47
47
  end
48
48
  end
49
49
 
50
- if user.nil? || !user.admin?
50
+ if user.nil?
51
+ # User can't be found with this email address
52
+ Rails.logger.error "User does not exist: #{user_info["email"]}"
53
+ redirect_to admin_login_path, flash: {error: t("panda_cms.admin.sessions.create.error")}
54
+ return
55
+ end
56
+
57
+ if !user.admin?
51
58
  # User can't be found with this email address or can't login
52
- Rails.logger.info "User #{user.id} attempted admin login, is not admin." if user && !user.admin
59
+ Rails.logger.error "User ID #{user.id} attempted admin login, is not admin." if user && !user.admin
53
60
  redirect_to admin_login_path, flash: {error: t("panda_cms.admin.sessions.create.error")}
54
61
  return
55
62
  end
@@ -32,7 +32,7 @@ module PandaCms
32
32
  PandaCms::Current.page = nil
33
33
  PandaCms::Current.user ||= User.find_by(id: session[:user_id]) if session[:user_id]
34
34
 
35
- PandaCms.url ||= PandaCms::Current.root
35
+ PandaCms.config.url ||= PandaCms::Current.root
36
36
  end
37
37
 
38
38
  def authenticate_user!
@@ -8,7 +8,7 @@ module PandaCms
8
8
  end
9
9
 
10
10
  def show
11
- if PandaCms.require_login_to_view && !user_signed_in?
11
+ if PandaCms.config.require_login_to_view && !user_signed_in?
12
12
  redirect_to panda_cms_maintenance_path and return
13
13
  end
14
14
 
@@ -1,7 +1,7 @@
1
1
  module PandaCms
2
2
  class PostsController < ApplicationController
3
3
  def show
4
- @posts_index_page = PandaCms::Page.find_by(path: "/#{PandaCms.posts[:prefix]}")
4
+ @posts_index_page = PandaCms::Page.find_by(path: "/#{PandaCms.config.posts[:prefix]}")
5
5
  @post = PandaCms::Post.find_by(slug: "/#{params[:slug]}")
6
6
  @title = @post.title
7
7