lib/spontaneous/model/page/paths.rb in spontaneous-0.2.0.beta5 vs lib/spontaneous/model/page/paths.rb in spontaneous-0.2.0.beta6
- old
+ new
@@ -11,36 +11,35 @@
def is_default_slug?(slug)
/^page-\d{8}-\d{6}$/ === slug
end
- def create_root(slug)
- create(slug: slug, :__create_hidden_root => true)
+ def create_root(slug, values = {})
+ create(values.merge(slug: slug, :__create_private_root => true))
end
end
# InstanceMethods
- ANCESTOR_SEP = "."
-
- def __create_hidden_root=(state)
- @__is_hidden_root = state
+ def __create_private_root=(state)
+ @__is_private_root = state
end
- def __create_hidden_root?
- @__is_hidden_root || false
+ def __create_private_root?
+ @__is_private_root || false
end
- private :__create_hidden_root=, :__create_hidden_root?
+ private :__create_private_root=, :__create_private_root?
def after_initialize
super
set_generated_slug
end
def before_create
place_in_page_tree
+ set_slug_from_dynamic_value
super
end
def after_insertion
super
@@ -67,64 +66,67 @@
#
# This doesn't happen when the item is created (i.e. #new? => true)
# because otherwise the slug would always take on the title fields
# default value.
def before_save
- unless new?
- if (title = self.fields[title_field])
- set_slug_from_title(title)
- end
+ if !new? && (title = fields[title_field_name])
+ set_slug_from_title(title)
end
fix_generated_slug_conflicts
super
end
+ def set_slug_from_dynamic_value
+ if (title = fields[title_field_name]) && title.prototype.dynamic_default?
+ set_slug_from_title!(title)
+ end
+ end
+
# Syncing the slug with the title is made more difficult because the field
# update mechanism works differently from the more direct, console version.
# This is called by the field updater before re-serializing each modified field.
def before_save_field(field)
- set_slug_from_title(field) if (field.name == title_field)
+ set_slug_from_title(field) if (field.name == title_field_name)
super
end
def set_slug_from_title(title)
if title.modified? and !title.blank? and has_generated_slug?
- self.slug = title.value
+ set_slug_from_title!(title)
end
end
+ def set_slug_from_title!(title)
+ self.slug = title.value
+ end
+
def sync_slug_to_title
self.slug = title.unprocessed_value
end
def has_generated_slug?
self.class.is_default_slug?(slug)
end
- def after_save
- super
- check_for_path_changes
- end
-
def generate_default_slug
self.class.generate_default_slug
end
def is_conflicting_slug?(slug)
- siblings.reject { |s| s.root? }.compact.map(&:slug).include?(slug)
+ siblings(true).reject { |s| s.root? }.compact.map(&:slug).include?(slug)
end
def parent=(parent)
@__parent_changed = true
update_path
super
end
def place_in_page_tree
if parent_id.nil?
- if __create_hidden_root? || content_model.has_root?
- make_hidden_root
+ if __create_private_root? || content_model.has_root?
+ make_private_root
else
make_root
end
else
update_path
@@ -135,53 +137,90 @@
self[:path] = "/"
self[:slug] = ""
self[:ancestor_path] = ""
end
- def make_hidden_root
+ def make_private_root
raise Spontaneous::AnonymousRootException.new if slug.blank?
self[:path] = "##{slug}"
self[:ancestor_path] = ""
end
def ancestor_path
- (self[:ancestor_path] || "").split(ANCESTOR_SEP).map { |id| id.to_i }
+ (self[:ancestor_path] || "").split(Spontaneous::Model::ANCESTOR_SEP).map { |id| id.to_i }
end
- def root?
+ def is_public_root?
path == Spontaneous::SLASH
end
- alias_method :is_root?, :root?
+ alias_method :root?, :is_public_root?
+ alias_method :is_root?, :is_public_root?
+ # Returns the root of the tree this page belongs to, which in the case
+ # of pages in an private tree will not be the same as the site's
+ # root/home page
+ def tree_root
+ content_model::Page.get(visibility_path_ids.first)
+ end
+ def is_private_root?
+ return false unless parent_id.nil?
+ return false if root?
+ path[0] == '#'
+ end
+
+ def in_private_tree?
+ tree_root = self.tree_root
+ return is_private_root? if tree_root.nil?
+ tree_root.is_private_root?
+ end
+
+
def update_path
self.path = calculate_path
if parent
- self[:ancestor_path] = parent.ancestor_path.push(parent.id).join(ANCESTOR_SEP)
+ self[:ancestor_path] = parent.ancestor_path.push(parent.id).join(Spontaneous::Model::ANCESTOR_SEP)
end
end
def calculate_path
- calculate_path_with_slug(self.slug)
+ calculate_path_with_slug(slug)
end
def calculate_path_with_slug(slug)
if parent.nil?
root? ? Spontaneous::SLASH : "##{slug}"
else
File.join(parent.path, slug)
end
end
+ class SlugChange
+ attr_reader :old_value, :new_value
+ def initialize(origin, old_value, new_value)
+ @origin, @old_value, @new_value = origin, old_value, new_value
+ end
+
+ def propagate
+ return if @old_value == @new_value
+ @origin.force_path_changes
+ end
+ end
+
+ included do
+ cascading_change :slug do |origin, old_value, new_value|
+ SlugChange.new(origin, old_value, new_value)
+ end
+ end
+
# slugs can be max 64 characters long
def slug=(s)
if (new_slug = fit_slug_to_length(s, 64)) != slug
- @__slug_changed = slug
- self[:slug] = new_slug
- self.update_path
+ super(new_slug)
+ update_path
end
end
def fit_slug_to_length(s, max_length)
original = s.to_url
@@ -193,31 +232,21 @@
url.join('-')[0...max_length]
end
protected :fit_slug_to_length
- def check_for_path_changes(force = false)
- if @__slug_changed || force
- @__slug_changed = false
- children.each do |child|
- child.propagate_path_changes
- end
- aliases.each do |link|
- link.propagate_path_changes if link.page?
- end
+ def force_path_changes
+ children.each do |child|
+ child.propagate_path_changes
end
+ aliases.each do |link|
+ link.propagate_path_changes if link.page?
+ end
end
- def force_path_changes
- check_for_path_changes(true)
- end
-
def propagate_path_changes
- # this happens in the child pages who shouldn't update their modification dates
- # because updates to paths are handled by modifications held on the origin of the path change
- @__ignore_page_modification = true
- self.update_path
- self.save
+ update_path
+ save
children.each do |child|
child.propagate_path_changes
end
end
end