app/models/alchemy/page/page_natures.rb
# frozen_string_literal: true
module Alchemy
class Page < BaseRecord
module PageNatures
extend ActiveSupport::Concern
# Determines if this page has a public version and this version is public.
#
# @see PageVersion#public?
# @returns Boolean
def public?
language.public? && !!public_version&.public?
end
def expiration_time
public_until ? public_until - Time.current : nil
end
def rootpage?
!new_record? && parent_id.blank?
end
def folded?(user_id)
return unless Alchemy.user_class < ActiveRecord::Base
folded_pages.where(user_id: user_id, folded: true).any?
end
# Returns an Array of Alchemy roles which are able to edit this template
#
# # config/alchemy/page_layouts.yml
# - name: contact
# editable_by:
# - freelancer
# - admin
#
# @returns Array
#
def has_limited_editors?
definition["editable_by"].present?
end
def editor_roles
return unless has_limited_editors?
definition["editable_by"]
end
# True if page locked_at timestamp and locked_by id are set
def locked?
locked_by? && locked_at?
end
# Returns a Hash describing the status of the Page.
#
def status
{
public: public?,
locked: locked?,
restricted: restricted?
}
end
# Returns the long translated status message for given status type.
#
# @param [Symbol] status_type
#
def status_message(status_type)
Alchemy.t(status[status_type].to_s, scope: "page_states.#{status_type}")
end
# Returns the sort translated status title for given status type.
#
# @param [Symbol] status_type
#
def status_title(status_type)
Alchemy.t(status[status_type].to_s, scope: "page_status_titles.#{status_type}")
end
# Returns the self#page_layout definition from config/alchemy/page_layouts.yml file.
def definition
definition = PageLayout.get(page_layout)
if definition.nil?
log_warning "Page definition for `#{page_layout}` not found. Please check `page_layouts.yml` file."
return {}
end
definition
end
# Returns translated name of the pages page_layout value.
# Page layout names are defined inside the config/alchemy/page_layouts.yml file.
# Translate the name in your config/locales language yml file.
def layout_display_name
Alchemy.t(page_layout, scope: "page_layout_names")
end
# Returns the name for the layout partial
#
def layout_partial_name
page_layout.parameterize.underscore
end
# Returns the version string that's taken for Rails' recycable cache key.
#
def cache_version
last_modified_at&.to_s
end
# Returns the timestamp that the page was last modified at, regardless of through
# publishing or editing page, or through a change of related objects through ingredients.
# Respects the public version not changing if editing a preview.
#
# In preview mode, it will take the draft version's updated_at timestamp.
# In public mode, it will take the public version's updated_at timestamp.
#
def last_modified_at
relevant_page_version = (Current.preview_page == self) ? draft_version : public_version
relevant_page_version&.updated_at
end
# Returns true if the page cache control headers should be set.
#
# == Disable Alchemy's page caching globally
#
# # config/alchemy/config.yml
# ...
# cache_pages: false
#
# == Disable caching on page layout level
#
# # config/alchemy/page_layouts.yml
# - name: contact
# cache: false
#
# == Note:
#
# This only sets the cache control headers and skips rendering of the page body,
# if the cache is fresh.
# This does not disable the fragment caching in the views.
# So if you don't want a page and it's elements to be cached,
# then be sure to not use <% cache element %> in the views.
#
# @returns Boolean
#
def cache_page?
return false unless caching_enabled?
page_layout = PageLayout.get(self.page_layout)
page_layout["cache"] != false && page_layout["searchresults"] != true
end
private
def caching_enabled?
Alchemy::Config.get(:cache_pages) &&
Rails.application.config.action_controller.perform_caching
end
end
end
end