Skip to content

Instantly share code, notes, and snippets.

@lukesutton
Created December 11, 2008 05:16
Show Gist options
  • Select an option

  • Save lukesutton/34616 to your computer and use it in GitHub Desktop.

Select an option

Save lukesutton/34616 to your computer and use it in GitHub Desktop.
# Example usage within Gluttonberg
# Page.localized_tree("australia_english", :depth => (0..1))
def self.localized_tree(locale_name, page_opts = {})
# Find all matching pages
pages = Page.all({:order => [:position.asc]}.merge!(page_opts))
if pages.empty?
pages
else
# Find the localizations that belong to the pages passed in. This is done
# by collecting the page ids and using an IN condition in the query.
page_ids = pages.collect {|p| p.id}
l_opts = {:page_id => page_ids, :locale_name => locale_name}
localizations = PageLocalization.all(l_opts).inject({}) do |memo, localization|
memo[localization.page_id] = localization
memo
end
# Sort everything ready to build a tree, and set the current localization
# for each.
children = Hash.new {|h, k| h[k] = []}
top_level = []
pages.each do |page|
# Sort them into top level and child pages
if page.parent_id
children[page.parent_id] << page
else
top_level << page
end
# Associate the localization
page.current_localization = localizations[page.id]
end
# Now to start off the recursive method which sorts the pages into a tree
sort_pages([], top_level, children)
end
end
private
Node = Stuct.new(:page, :children)
def sort_pages(collection, pages, children)
pages.inject(collection) do |memo, page|
memo << Node.new(page, sort_pages([], children.delete(page.id), children))
end
end
# Example usage
# for node in pages
# puts node.page.name
# end
property :depth, Integer, :writer => :private
before :save, :set_depth
def set_depth
if attribute_dirty?(:parent_id)
new_depth = (parent_id ? parent.depth + 1 : 0)
attribute_set(:depth, new_depth)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment