Skip to content

Commit

Permalink
Remove root page (AlchemyCMS#1817)
Browse files Browse the repository at this point in the history
* Remove Page#systempage?

* Remove Page.root

We do not need a single root page. All pages that share the same language are a nested set.

* Format page_scopes.rb

* Format pages controller spec file

* Add upgrader task to remove root page

* Rubocop -a
  • Loading branch information
tvdeyen authored May 6, 2020
1 parent dc7b25d commit 4b43ce8
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 247 deletions.
6 changes: 2 additions & 4 deletions app/controllers/alchemy/admin/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,11 @@ def flush
private

def copy_of_language_root
page_copy = Page.copy(
Page.copy(
language_root_to_copy_from,
language_id: params[:languages][:new_lang_id],
language_code: @current_language.code,
)
page_copy.move_to_child_of Page.root
page_copy
end

def language_root_to_copy_from
Expand Down Expand Up @@ -363,7 +361,7 @@ def page_needs_lock?
def paste_from_clipboard
if params[:paste_from_clipboard]
source = Page.find(params[:paste_from_clipboard])
parent = Page.find_by(id: params[:page][:parent_id]) || Page.root
parent = Page.find_by(id: params[:page][:parent_id])
Page.copy_and_paste(source, parent, params[:page][:name])
end
end
Expand Down
34 changes: 9 additions & 25 deletions app/models/alchemy/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,32 +114,28 @@ class Page < BaseRecord
has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page

validates_presence_of :language, on: :create, unless: :root
validates_presence_of :page_layout, unless: :systempage?
validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { systempage? || page_layout.blank? }
validates_presence_of :parent_id, if: proc { Page.count > 1 }, unless: -> { layoutpage? }

validates_presence_of :page_layout
validates_format_of :page_layout, with: /\A[a-z0-9_-]+\z/, unless: -> { page_layout.blank? }
validates_presence_of :parent, unless: -> { layoutpage? || language_root? }

before_save :set_language_code,
if: -> { language.present? },
unless: :systempage?
if: -> { language.present? }

before_save :set_restrictions_to_child_pages,
if: :restricted_changed?,
unless: :systempage?
if: :restricted_changed?

before_save :inherit_restricted_status,
if: -> { parent && parent.restricted? },
unless: :systempage?
if: -> { parent && parent.restricted? }

before_save :set_published_at,
if: -> { public_on.present? && published_at.nil? },
unless: :systempage?
if: -> { public_on.present? && published_at.nil? }

before_save :set_fixed_attributes,
if: -> { fixed_attributes.any? }

before_create :set_language,
if: -> { language.nil? },
unless: :systempage?
if: -> { language.nil? }

after_update :create_legacy_url,
if: :should_create_legacy_url?
Expand All @@ -163,18 +159,6 @@ class Page < BaseRecord
# Class methods
#
class << self
# The root page of the page tree
#
# Internal use only. You wouldn't use this page ever.
#
# Automatically created when accessed the first time.
#
def root
super || create!(name: "Root")
end

alias_method :rootpage, :root

# Used to store the current page previewed in the edit page template.
#
def current_preview=(page)
Expand Down
26 changes: 13 additions & 13 deletions app/models/alchemy/page/page_elements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ module Page::PageElements
join_table: ElementToPage.table_name

after_create :generate_elements,
unless: -> { systempage? || autogenerate_elements == false }
unless: -> { autogenerate_elements == false }

after_update :trash_not_allowed_elements!,
if: :has_page_layout_changed?
Expand Down Expand Up @@ -81,11 +81,11 @@ def copy_elements(source, target)
#
def available_element_definitions(only_element_named = nil)
@_element_definitions ||= if only_element_named
definition = Element.definition_by_name(only_element_named)
element_definitions_by_name(definition["nestable_elements"])
else
element_definitions
end
definition = Element.definition_by_name(only_element_named)
element_definitions_by_name(definition["nestable_elements"])
else
element_definitions
end

return [] if @_element_definitions.blank?

Expand All @@ -107,13 +107,13 @@ def available_element_names
#
def available_elements_within_current_scope(parent)
@_available_elements = if parent
parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
available_element_definitions(parent.name).reject do |e|
parents_unique_nested_elements.include? e["name"]
parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
available_element_definitions(parent.name).reject do |e|
parents_unique_nested_elements.include? e["name"]
end
else
available_element_definitions
end
else
available_element_definitions
end
end

# All element definitions defined for page's page layout
Expand Down Expand Up @@ -181,7 +181,7 @@ def feed_elements
#
def richtext_contents_ids
Alchemy::Content.joins(:element)
.where(Element.table_name => {page_id: id, folded: false})
.where(Element.table_name => { page_id: id, folded: false })
.select(&:has_tinymce?)
.collect(&:id)
end
Expand Down
11 changes: 5 additions & 6 deletions app/models/alchemy/page/page_naming.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ module Page::PageNaming
included do
before_validation :set_urlname,
if: :renamed?,
unless: -> { systempage? || name.blank? }
unless: -> { name.blank? }

validates :name,
presence: true
validates :urlname,
uniqueness: {scope: [:language_id, :layoutpage], if: -> { urlname.present? }},
exclusion: {in: RESERVED_URLNAMES},
length: {minimum: 3, if: -> { urlname.present? }}
uniqueness: { scope: [:language_id, :layoutpage], if: -> { urlname.present? } },
exclusion: { in: RESERVED_URLNAMES },
length: { minimum: 3, if: -> { urlname.present? } }

before_save :set_title,
unless: -> { systempage? },
if: -> { title.blank? }

after_update :update_descendants_urlnames,
Expand Down Expand Up @@ -117,7 +116,7 @@ def nested_url_name(value)
# Returns [], if there is no parent, the parent is
# the root page itself, or url_nesting is off.
def ancestor_slugs
return [] if !Config.get(:url_nesting) || parent.nil? || parent.root?
return [] if !Config.get(:url_nesting) || parent.nil?

visible_ancestors.map(&:slug).compact
end
Expand Down
6 changes: 0 additions & 6 deletions app/models/alchemy/page/page_natures.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ def rootpage?
!new_record? && parent_id.blank?
end

def systempage?
return true if Page.count.zero?

rootpage? || (parent_id == Page.root.id && !language_root?)
end

def folded?(user_id)
return unless Alchemy.user_class < ActiveRecord::Base

Expand Down
48 changes: 23 additions & 25 deletions app/models/alchemy/page/page_scopes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ module Page::PageScopes

# All pages locked by given user
#
scope :locked_by, ->(user) {
if user.class.respond_to? :primary_key
locked.where(locked_by: user.send(user.class.primary_key))
end
}
scope :locked_by,
->(user) {
if user.class.respond_to? :primary_key
locked.where(locked_by: user.send(user.class.primary_key))
end
}

# All not locked pages
#
Expand All @@ -45,29 +46,27 @@ module Page::PageScopes

# All pages that are a published language root
#
scope :public_language_roots, -> {
published.language_roots.where(
language_code: Language.published.pluck(:language_code),
)
}
scope :public_language_roots,
-> {
published.language_roots.where(
language_code: Language.published.pluck(:language_code),
)
}

# Last 5 pages that where recently edited by given user
#
scope :all_last_edited_from, ->(user) {
where(updater_id: user.id).order("updated_at DESC").limit(5)
}
scope :all_last_edited_from,
->(user) {
where(updater_id: user.id).order("updated_at DESC").limit(5)
}

# Returns all pages that have the given +language_id+
#
scope :with_language, ->(language_id) {
where(language_id: language_id)
}
scope :with_language, ->(language_id) { where(language_id: language_id) }

# Returns all content pages.
#
scope :contentpages, -> {
where(layoutpage: [false, nil]).where.not(parent_id: nil)
}
scope :contentpages, -> { where(layoutpage: [false, nil]) }

# Returns all public contentpages that are not locked.
#
Expand All @@ -79,19 +78,18 @@ module Page::PageScopes
#
# Used for flushing all pages caches at once.
#
scope :flushable_layoutpages, -> {
not_locked.layoutpages.where.not(parent_id: Page.unscoped.root.id)
}
scope :flushable_layoutpages, -> { not_locked.layoutpages }

# All searchable pages
#
scope :searchables, -> { not_restricted.published.contentpages }

# All pages from +Alchemy::Site.current+
#
scope :from_current_site, -> {
where(Language.table_name => {site_id: Site.current || Site.default}).joins(:language)
}
scope :from_current_site,
-> {
where(Language.table_name => { site_id: Site.current || Site.default }).joins(:language)
}

# All pages for xml sitemap
#
Expand Down
8 changes: 0 additions & 8 deletions app/views/alchemy/admin/pages/_create_language_form.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<% if root = Alchemy::Page.rootpage %>
<div class="panel">
<%= render_message do %>
<p><%= Alchemy.t(:language_does_not_exist) %></p>
Expand Down Expand Up @@ -37,7 +36,6 @@
<%= form.hidden_field :language_id, value: @language.id %>
<%= form.hidden_field :language_code, value: @language.code %>
<%= form.hidden_field :language_root, value: true %>
<%= form.hidden_field :parent_id, value: root.id %>
<%= form.hidden_field :public, value: Alchemy::Language.all.size == 1 %>
<%= form.submit Alchemy.t("create_tree_as_new_language", language: @language.name), autofocus: true %>
<% end %>
Expand All @@ -50,9 +48,3 @@
<%- end -%>

</div>
<% else %>
<%= render_message :error do %>
<h2>Root page not found.</h2>
<p>Please run <code>bin/rake db:seed</code> task.</p>
<% end %>
<% end %>
1 change: 0 additions & 1 deletion lib/alchemy/seeder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def seed_pages

contentpages.each do |page|
create_page(page, {
parent: Alchemy::Page.root,
language: Alchemy::Language.default,
language_root: true,
})
Expand Down
25 changes: 5 additions & 20 deletions lib/alchemy/test_support/factories/page_factory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,28 @@
sequence(:name) { |n| "A Page #{n}" }
page_layout { "standard" }

parent_id do
(Alchemy::Page.find_by(language_root: true) ||
FactoryBot.create(:alchemy_page, :language_root, language: language)).id
parent do
Alchemy::Page.find_by(language_root: true, language: language) ||
FactoryBot.create(:alchemy_page, :language_root, language: language)
end

# This speeds up creating of pages dramatically.
# Pass autogenerate_elements: true to generate elements
autogenerate_elements { false }

trait :root do
name { "Root" }
language { nil }
parent_id { nil }
page_layout { nil }
end

trait :language_root do
name { "Startseite" }
name { language.frontpage_name }
page_layout { language.page_layout }
language_root { true }
public_on { Time.current }
parent_id { Alchemy::Page.root.id }
parent { nil }
end

trait :public do
sequence(:name) { |n| "A Public Page #{n}" }
public_on { Time.current }
end

trait :system do
name { "Systempage" }
parent_id { Alchemy::Page.root.id }
language_root { false }
page_layout { nil }
language { nil }
end

trait :layoutpage do
layoutpage { true }
page_layout { "footer" }
Expand Down
12 changes: 12 additions & 0 deletions lib/alchemy/upgrader/five_point_zero.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ def remove_layout_roots
log "No layout root pages found.", :skip
end
end

def remove_root_page
desc "Remove root page"
root_page = Alchemy::Page.find_by(parent_id: nil, name: "Root")
if root_page
Alchemy::Page.where(parent_id: root_page.id).update_all(parent_id: nil)
root_page.delete
log "Done.", :success
else
log "Root page not found.", :skip
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/tasks/alchemy/upgrade.rake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace :alchemy do
task database: [
"alchemy:upgrade:5.0:install_gutentag_migrations",
"alchemy:upgrade:5.0:remove_layout_roots",
"alchemy:upgrade:5.0:remove_root_page",
"alchemy:install:migrations",
"db:migrate",
"alchemy:db:seed",
Expand Down Expand Up @@ -48,6 +49,11 @@ namespace :alchemy do
task remove_layout_roots: [:environment] do
Alchemy::Upgrader::FivePointZero.remove_layout_roots
end

desc "Remove root page"
task remove_root_page: [:environment] do
Alchemy::Upgrader::FivePointZero.remove_root_page
end
end
end
end
Loading

0 comments on commit 4b43ce8

Please sign in to comment.