app/models/alchemy/page/page_layouts.rb
# frozen_string_literal: true
module Alchemy
class Page < BaseRecord
# Module concerning page layouts
#
module PageLayouts
extend ActiveSupport::Concern
module ClassMethods
# Register a custom page layouts repository
#
# The default repository is Alchemy::PageLayout
#
def layouts_repository=(klass)
@_layouts_repository = klass
end
# Returns page layouts ready for Rails' select form helper.
#
def layouts_for_select(language_id, layoutpages: false)
@map_array = []
mapped_layouts_for_select(selectable_layouts(language_id, layoutpages: layoutpages))
end
# Returns all layouts that can be used for creating a new page.
#
# It removes all layouts from available layouts that are unique and already taken and that are marked as hide.
#
# @param [Fixnum]
# language_id of current used Language.
# @param [Boolean] (false)
# Pass true to only select layouts for global/layout pages.
#
def selectable_layouts(language_id, layoutpages: false)
@language_id = language_id
layouts_repository.all.select do |layout|
if layoutpages
layout["layoutpage"] && layout_available?(layout)
else
!layout["layoutpage"] && layout_available?(layout)
end
end
end
# Translates name for given layout
#
# === Translation example
#
# en:
# alchemy:
# page_layout_names:
# products_overview: Products Overview
#
# @param [String]
# The layout name
#
def human_layout_name(layout)
Alchemy.t(layout, scope: "page_layout_names", default: layout.to_s.humanize)
end
private
def layouts_repository
@_layouts_repository ||= PageLayout
end
# Maps given layouts for Rails select form helper.
#
def mapped_layouts_for_select(layouts)
layouts.each do |layout|
@map_array << [human_layout_name(layout["name"]), layout["name"]]
end
@map_array
end
# Returns true if the given layout is unique and not already taken or it should be hidden.
#
def layout_available?(layout)
!layout["hide"] && !already_taken?(layout) && available_on_site?(layout)
end
# Returns true if this layout is unique and already taken by another page.
#
def already_taken?(layout)
layout["unique"] && page_with_layout_existing?(layout["name"])
end
# Returns true if one page already has the given layout
#
def page_with_layout_existing?(layout)
Alchemy::Page.where(page_layout: layout, language_id: @language_id).pluck(:id).any?
end
# Returns true if given layout is available for current site.
#
# If no site layouts are defined it always returns true.
#
# == Example
#
# # config/alchemy/site_layouts.yml
# - name: default_site
# page_layouts: [default_intro]
#
def available_on_site?(layout)
return false unless Alchemy::Current.site
Alchemy::Current.site.definition.blank? ||
Alchemy::Current.site.definition.fetch("page_layouts", []).include?(layout["name"])
end
end
end
end
end