Skip to content

Commit

Permalink
Add support for parent and sub page restrictions in page_layout defin…
Browse files Browse the repository at this point in the history
…ition

sub_pages: ['creatable1', 'creatable2'], parent_pages: ['creatable_under1', 'creatable_under2']. If sub_pages==false hide sub page creation button. If only 1 sub_page creatable, autoselect it and remove blank option.
  • Loading branch information
mickenorlen committed Jun 29, 2020
1 parent a43a746 commit 984a619
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 24 deletions.
4 changes: 2 additions & 2 deletions app/controllers/alchemy/admin/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ def info

def new
@page ||= Page.new(layoutpage: params[:layoutpage] == 'true', parent_id: params[:parent_id])
@page_layouts = PageLayout.layouts_for_select(@current_language.id, @page.layoutpage?)
@page_layouts = PageLayout.layouts_for_select(@current_language.id, @page.layoutpage?, @page.parent.page_layout)
@clipboard = get_clipboard('pages')
@clipboard_items = Page.all_from_clipboard_for_select(@clipboard, @current_language.id, @page.layoutpage?)
@clipboard_items = Page.all_from_clipboard_for_select(@clipboard, @current_language.id, @page.layoutpage?, @page.parent.page_layout)
end

def create
Expand Down
8 changes: 4 additions & 4 deletions app/models/alchemy/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,13 @@ def all_from_clipboard(clipboard)
where(id: clipboard.collect { |p| p['id'] })
end

def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
def all_from_clipboard_for_select(clipboard, language_id, layoutpage = false, parent_page_layout = nil)
return [] if clipboard.blank?

clipboard_pages = all_from_clipboard(clipboard)
allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
allowed_page_layout_names = allowed_page_layouts.collect { |p| p['name'] }
clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage, parent_page_layout)
allowed_parent_page_layouts = allowed_page_layouts.collect { |p| p['name'] }
clipboard_pages.select { |cp| allowed_parent_page_layouts.include?(cp.page_layout) }
end

def link_target_options
Expand Down
1 change: 1 addition & 0 deletions app/serializers/alchemy/page_tree_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def page_hash(page, has_children, level, folded)
visible: page.visible?,
restricted: page.restricted?,
page_layout: page.page_layout,
child_pages_allowed: page.definition['child_pages'] != false,
slug: page.slug,
urlname: page.urlname,
level: level,
Expand Down
3 changes: 2 additions & 1 deletion app/views/alchemy/admin/pages/_new_page_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
<%= f.input :page_layout,
collection: @page_layouts,
label: Alchemy.t(:page_type),
include_blank: Alchemy.t('Please choose'),
include_blank: @page_layouts.length == 1 ? nil : Alchemy.t('Please choose'),
required: true,
selected: @page_layouts.length == 1 ? @page_layouts.first : nil,
input_html: {class: 'alchemy_selectbox'} %>
<%= f.input :name %>
<%= f.submit Alchemy.t(:create) %>
Expand Down
26 changes: 15 additions & 11 deletions app/views/alchemy/admin/pages/_page.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,21 @@
{{/if}}
</div>
{{#if permissions.create}}
<div class="button_with_label sitemap_tool">
<%= link_to_dialog(
render_icon(:plus),
alchemy.new_admin_page_path(parent_id: '__ID__').gsub('__ID__', '{{id}}'),
{
title: Alchemy.t(:create_page),
size: '340x165',
overflow: true
}
) -%>
<label class="left"><%= Alchemy.t(:create_page) %></label>
{{#if child_pages_allowed}}
<div class="button_with_label sitemap_tool">
<%= link_to_dialog(
render_icon(:plus),
alchemy.new_admin_page_path(parent_id: '__ID__').gsub('__ID__', '{{id}}'),
{
title: Alchemy.t(:create_page),
size: '340x165',
overflow: true
}
) -%>
<label class="left"><%= Alchemy.t(:create_page) %></label>
{{else}}
<div class="sitemap_tool">
{{/if}}
{{else}}
<div class="sitemap_tool disabled with-hint">
<%= render_icon(:plus) %>
Expand Down
45 changes: 39 additions & 6 deletions lib/alchemy/page_layout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,15 @@ def get_all_by_attributes(attributes)

# Returns page layouts ready for Rails' select form helper.
#
def layouts_for_select(language_id, only_layoutpages = false)
def layouts_for_select(language_id, only_layoutpages = false, parent_page_layout = nil)
@map_array = []
mapped_layouts_for_select(selectable_layouts(language_id, only_layoutpages))
mapped_layouts_for_select(selectable_layouts(language_id, only_layoutpages, parent_page_layout))
end

# Returns page layouts including given layout ready for Rails' select form helper.
#
def layouts_with_own_for_select(page_layout_name, language_id, only_layoutpages = false)
layouts = selectable_layouts(language_id, only_layoutpages)
layouts = selectable_layouts(language_id, only_layoutpages, page_layout_name)
if layouts.detect { |l| l['name'] == page_layout_name }.nil?
@map_array = [[human_layout_name(page_layout_name), page_layout_name]]
else
Expand All @@ -83,9 +83,17 @@ def layouts_with_own_for_select(page_layout_name, language_id, only_layoutpages
# language_id of current used Language.
# @param [Boolean] (false)
# Pass true to only select layouts for global/layout pages.
# @param [String]
# name of current/parent page layout
#
def selectable_layouts(language_id, only_layoutpages = false)
def selectable_layouts(language_id, only_layoutpages = false, parent_page_layout = nil)
@language_id = language_id
# Assign layout as the "parent" for which we will get the selectable "child" page layouts
@parent_layout = parent_page_layout.present? ? all.detect{ |layout| layout['name'] == parent_page_layout } : nil
# Return empty array if child pages are not allowed in parent layout definition
return [] if @parent_layout.present? && @parent_layout['child_pages'] == false

# Select all layouts that will be available for creation under @parent_layout
all.select do |layout|
if only_layoutpages
layout['layoutpage'] && layout_available?(layout)
Expand Down Expand Up @@ -124,10 +132,35 @@ def human_layout_name(layout)

private

# Returns true if the given layout is unique and not already taken or it should be hidden.
# Returns true if the given layout is available as child under @parent_layout
#
def layout_available?(layout)
!layout['hide'] && !already_taken?(layout) && available_on_site?(layout)
layout_available_from_parent?(layout) && layout_available_from_child?(layout) &&
!already_taken?(layout) && available_on_site?(layout)
end

# Returns true if layout is available as child under @parent_layout according to parent definition
#
def layout_available_from_parent?(layout)
return true if !@parent_layout

only = @parent_layout.dig('child_pages', 'only')
except = @parent_layout.dig('child_pages', 'except')

@parent_layout['child_pages'].blank? ||
only &.include?(layout['name']) ||
(except && !except.include?(layout['name']))
end

# Returns true if layout is available as child under @parent_layout according to child definition
#
def layout_available_from_child?(layout)
only = layout.dig('parent_pages', 'only')
except = layout.dig('parent_pages', 'except')

@parent_layout.nil? || layout['parent_pages'].blank? ||
only &.include?(@parent_layout['name']) ||
(except && !except.include?(@parent_layout['name']))
end

# Returns true if this layout is unique and already taken by another page.
Expand Down

0 comments on commit 984a619

Please sign in to comment.