class AliasBehavior < Behavior::Base register "Alias" description %{ Causes a page to be an alias to another page. The source is given in the "source" page part as a slug path (not the URL). However, the page will search it's own children before searching it's source's children. This is to allow pages to override portions of it's destination (CSS files, for example). } def find_page_by_url(url, live = true, clean = true) url = clean_url(url) if clean # Find source source = @page.part 'source' source = find_page_by_path source.content.strip return super unless source if page_url == url && (not live or @page.published?) return source else # Find my children @page.children.each do |child| if (url =~ Regexp.compile('^' + Regexp.quote(child.url))) and (not child.virtual?) found = child.behavior.find_page_by_url(url, live, clean) return found if found end end # Modify URL to source's URL url.sub!(Regexp.compile('^' + Regexp.quote(page_url)), source.url) # Find source's children source.children.each do |child| if (url =~ Regexp.compile('^' + Regexp.quote(child.url))) and (not child.virtual?) found = child.behavior.find_page_by_url(url, live, clean) return found if found end end # I couldn't find anything. return nil end end private def find_page_by_path(path) return nil unless path # No path, abort! path.gsub! %r{//+}, '/' # Remove dup /s path.gsub! %{[^/]+/..}, '' # remote path/.. return nil if path == '' # No path, abort! # Catch root case if path.sub! %r{^/}, '' page = Page.find_by_parent_id nil else # Begin relative to parent if possible page = @page.parent page = @page unless page end path.split('/').each do |slug| case slug when '..' page = page.parent when '.' next else page = page.children.find_by_slug slug end break if page.nil? # We ran out of pages somewhere end page end end