214 lines
7.5 KiB
Ruby
214 lines
7.5 KiB
Ruby
|
# module Locomotive
|
||
|
# module Extensions
|
||
|
# module Page
|
||
|
# module Templatized
|
||
|
#
|
||
|
# extend ActiveSupport::Concern
|
||
|
#
|
||
|
# included do
|
||
|
#
|
||
|
# ## fields ##
|
||
|
# field :wildcards, :type => Array
|
||
|
# field :with_wildcards, :type => Boolean, :default => false
|
||
|
# field :fullpath_with_wildcards, :default => false, :localize => true
|
||
|
#
|
||
|
# ## callbacks ##
|
||
|
# before_validation :get_wildcards_from_parent
|
||
|
# before_validation :add_slug_to_wildcards
|
||
|
# before_save :build_fullpath_with_wildcards
|
||
|
# after_save :propagate_wildcards
|
||
|
#
|
||
|
# ## scopes ##
|
||
|
#
|
||
|
# ## virtual attributes ##
|
||
|
# attr_accessor :wildcards_map
|
||
|
#
|
||
|
# end
|
||
|
#
|
||
|
# protected
|
||
|
#
|
||
|
# def get_wildcards_from_parent
|
||
|
# return if self.parent.nil?
|
||
|
#
|
||
|
# if self.parent.with_wildcards?
|
||
|
# self.wildcards = self.parent.wildcards
|
||
|
# self.with_wildcards = true
|
||
|
# elsif !self.with_wildcards?
|
||
|
# self.wildcards = []
|
||
|
# self.with_wildcards = false
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# def add_slug_to_wildcards
|
||
|
# (self.wildcards ||= []) << self.slug if self.will_wildcards?
|
||
|
# end
|
||
|
#
|
||
|
# def build_fullpath_with_wildcards
|
||
|
# if self.index? || self.not_found?
|
||
|
# self.fullpath_with_wildcards = self.slug
|
||
|
# else
|
||
|
# slugs = self.ancestors_and_self.map { |page| page.with_wildcards? ? '*' : page.slug }
|
||
|
# slugs.shift unless slugs.size == 1
|
||
|
# self.fullpath_with_wildcards = File.join slugs.compact
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# def propagate_wildcards
|
||
|
# return unless self.with_wildcards_changed? || (self.with_wildcards? && self.slug_changed?)
|
||
|
#
|
||
|
# parent_identities = { self._id => self }
|
||
|
#
|
||
|
# self.descendants.order_by([[:depth, :asc]]).each do |page|
|
||
|
# _parent = parent_identities[page._id]
|
||
|
# _wildcards = _parent.wildcards + (page.wildcards? ? [page.slug] : [])
|
||
|
# _fullpath_with_wildcards = File.join(_parent.fullpath_with_wildcards, page.wildcards? ? '*' : page.slug)
|
||
|
#
|
||
|
# # TODO: fullpath_with_wildcards is localized !!!!
|
||
|
#
|
||
|
# selector = { 'id' => page._id }
|
||
|
# operations = {
|
||
|
# '$set' => {
|
||
|
# 'wildcards' => _wildcards,
|
||
|
# 'with_wildcards' => true,
|
||
|
# 'fullpath_with_wildcards' => _fullpath_with_wildcards
|
||
|
# }
|
||
|
# }
|
||
|
# self.collection.update selector, operations
|
||
|
#
|
||
|
# parent_identities[page._id] = page
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
# end
|
||
|
# end
|
||
|
# end
|
||
|
# end
|
||
|
#
|
||
|
#
|
||
|
#
|
||
|
# # field :templatized_from_parent, :type => Boolean, :default => false
|
||
|
# # field :target_klass_name
|
||
|
# #
|
||
|
# # ## validations ##
|
||
|
# # validates_presence_of :target_klass_name, :if => :templatized?
|
||
|
# # validate :ensure_target_klass_name_security
|
||
|
# #
|
||
|
# # ## callbacks ##
|
||
|
# # before_validation :get_templatized_from_parent
|
||
|
# # before_validation :set_slug_if_templatized
|
||
|
# # before_validation :ensure_target_klass_name_security
|
||
|
# # after_save :propagate_templatized
|
||
|
# #
|
||
|
# # ## scopes ##
|
||
|
# # scope :templatized, :where => { :templatized => true }
|
||
|
# #
|
||
|
# # ## virtual attributes ##
|
||
|
# # attr_accessor :content_entry
|
||
|
# # end
|
||
|
# #
|
||
|
# # # Returns the class specified by the target_klass_name property
|
||
|
# # #
|
||
|
# # # @example
|
||
|
# # #
|
||
|
# # # page.target_klass_name = 'Locomotive::Entry12345'
|
||
|
# # # page.target_klass = Locomotive::Entry12345
|
||
|
# # #
|
||
|
# # # @return [ Class ] The target class
|
||
|
# # #
|
||
|
# # def target_klass
|
||
|
# # target_klass_name.constantize
|
||
|
# # end
|
||
|
# #
|
||
|
# # # Gives the name which can be used in a liquid template in order
|
||
|
# # # to reference an entry. It uses the slug property if the target klass
|
||
|
# # # is a Locomotive content type or the class name itself for the other classes.
|
||
|
# # #
|
||
|
# # # @example
|
||
|
# # #
|
||
|
# # # page.target_klass_name = 'Locomotive::Entry12345' # related to the content type Articles
|
||
|
# # # page.target_entry_name = 'article'
|
||
|
# # #
|
||
|
# # # page.target_klass_name = 'OurProduct'
|
||
|
# # # page.target_entry_name = 'our_product'
|
||
|
# # #
|
||
|
# # # @return [ String ] The name in lowercase and underscored
|
||
|
# # #
|
||
|
# # def target_entry_name
|
||
|
# # if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||
|
# # @content_type ||= self.site.content_types.find($1)
|
||
|
# # @content_type.slug.singularize
|
||
|
# # else
|
||
|
# # self.target_klass_name.underscore
|
||
|
# # end
|
||
|
# # end
|
||
|
# #
|
||
|
# # # Finds the entry both specified by the target klass and identified by the permalink
|
||
|
# # #
|
||
|
# # # @param [ String ] permalink The permalink of the entry
|
||
|
# # #
|
||
|
# # # @return [ Object ] The document
|
||
|
# # #
|
||
|
# # def fetch_target_entry(permalink)
|
||
|
# # target_klass.find_by_permalink(permalink)
|
||
|
# # end
|
||
|
# #
|
||
|
# # protected
|
||
|
# #
|
||
|
# # def get_templatized_from_parent
|
||
|
# # return if self.parent.nil?
|
||
|
# #
|
||
|
# # if self.parent.templatized?
|
||
|
# # self.templatized = self.templatized_from_parent = true
|
||
|
# # self.target_klass_name = self.parent.target_klass_name
|
||
|
# # elsif !self.templatized?
|
||
|
# # self.templatized = self.templatized_from_parent = false
|
||
|
# # self.target_klass_name = nil
|
||
|
# # end
|
||
|
# # end
|
||
|
# #
|
||
|
# # def set_slug_if_templatized
|
||
|
# # self.slug = 'content_type_template' if self.templatized? && !self.templatized_from_parent?
|
||
|
# # end
|
||
|
# #
|
||
|
# # # Makes sure the target_klass is owned by the site OR
|
||
|
# # # if it belongs to the models allowed by the application
|
||
|
# # # thanks to the models_for_templatization option.
|
||
|
# # #
|
||
|
# # def ensure_target_klass_name_security
|
||
|
# # return if !self.templatized? || self.target_klass_name.blank?
|
||
|
# #
|
||
|
# # if self.target_klass_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
||
|
# # content_type = Locomotive::ContentType.find($1)
|
||
|
# #
|
||
|
# # if content_type.site_id != self.site_id
|
||
|
# # self.errors.add :target_klass_name, :security
|
||
|
# # end
|
||
|
# # elsif !Locomotive.config.models_for_templatization.include?(self.target_klass_name)
|
||
|
# # self.errors.add :target_klass_name, :security
|
||
|
# # end
|
||
|
# # end
|
||
|
# #
|
||
|
# # # Sets the templatized, templatized_from_parent properties of
|
||
|
# # # the children of the current page ONLY IF the templatized
|
||
|
# # # attribute got changed.
|
||
|
# # #
|
||
|
# # def propagate_templatized
|
||
|
# # return unless self.templatized_changed?
|
||
|
# #
|
||
|
# # selector = { 'parent_ids' => { '$in' => [self._id] } }
|
||
|
# # operations = {
|
||
|
# # '$set' => {
|
||
|
# # 'templatized' => self.templatized,
|
||
|
# # 'templatized_from_parent' => self.templatized,
|
||
|
# # 'target_klass_name' => self.target_klass_name
|
||
|
# # }
|
||
|
# # }
|
||
|
# #
|
||
|
# # self.collection.update selector, operations, :multi => true
|
||
|
# # end
|
||
|
# #
|
||
|
# # end
|
||
|
# # end
|
||
|
# # end
|
||
|
# # end
|