enhance the nav tag + some optimization in the back-office when rendering the pages tree

This commit is contained in:
dinedine 2011-01-02 23:58:06 +01:00
parent c0ac0046c1
commit 210ce3d2d8
9 changed files with 107 additions and 16 deletions

View File

@ -6,7 +6,8 @@ module Admin
respond_to :json, :only => [:update, :sort, :get_path]
def index
@pages = current_site.pages.roots
# @pages = current_site.pages.roots.minimal_attributes
@pages = current_site.all_pages_in_once
end
def new

View File

@ -27,8 +27,68 @@ module Models
alias :descendants :hacked_descendants
end
module ClassMethods
# Warning: used only in read-only
def quick_tree(site)
pages = site.pages.minimal_attributes.order_by([[:depth, :asc], [:position, :asc]]).to_a
puts "pages size = #{pages.size}"
tmp = []
while !pages.empty?
tmp << _quick_tree(pages.delete_at(0), pages)
end
tmp
end
def _quick_tree(current_page, pages)
puts "_build_tree [current_page = #{current_page.title}] / #{pages.size}"
i, children = 0, []
while !pages.empty?
puts "...#{i}"
page = pages[i]
break if page.nil?
if page.parent_id == current_page.id
page = pages.delete_at(i)
children << _quick_tree(page, pages)
else
i += 1
end
end
current_page.instance_eval do
def children=(list); @children = list; end
def children; @children || []; end
end
current_page.children = children
puts "children size for #{current_page.title} = #{current_page.children.size}"
current_page
end
end
module InstanceMethods
def children?
self.class.where(self.parent_id_field => self.id).count
end
def children_with_minimal_attributes
self.class.where(self.parent_id_field => self.id).
order_by(self.tree_order).
minimal_attributes
end
def sort_children!(ids)
ids.each_with_index do |id, position|
child = self.children.detect { |p| p._id == BSON::ObjectId(id) }

View File

@ -40,6 +40,8 @@ class Page
scope :index, :where => { :slug => 'index', :depth => 0 }
scope :not_found, :where => { :slug => '404', :depth => 0 }
scope :published, :where => { :published => true }
scope :fullpath, lambda { |fullpath| { :where => { :fullpath => fullpath } } }
scope :minimal_attributes, :only => %w(title slug fullpath position depth published templatized parent_id created_at updated_at)
## methods ##

View File

@ -40,6 +40,10 @@ class Site
## methods ##
def all_pages_in_once
Page.quick_tree(self)
end
def domains=(array)
array = [] if array.blank?; super(array)
end

View File

@ -1,5 +1,7 @@
%li{ :id => "item-#{page.id}", :class => "#{'not-found' if page.not_found? } #{'templatized' if page.templatized?}"}
- if not page.index? and not page.children.empty?
- with_children = !page.children.empty?
- if not page.index? and with_children
= image_tag 'admin/list/icons/node_closed.png', :class => 'toggler'
%em
%strong= link_to truncate(page.title, :length => 80), edit_admin_page_url(page)
@ -11,6 +13,6 @@
- if not page.index? and not page.not_found?
= link_to image_tag('admin/list/icons/trash.png'), admin_page_url(page), :class => 'remove', :confirm => t('admin.messages.confirm'), :method => :delete
- if not page.children.empty?
- if with_children
%ul{ :id => "folder-#{page._id}", :class => "folder depth-#{(page.depth || 0) + 1}", :data_url => sort_admin_page_url(page), :style => "display: #{cookies["folder-#{page._id}"] || 'block'}" }
= render page.children

View File

@ -5,7 +5,7 @@
.inner
%h2!= t('admin.pages.index.lastest_items')
%ul
- current_site.pages.latest_updated.each do |page|
- current_site.pages.latest_updated.minimal_attributes.each do |page|
%li
= link_to truncate(page.title, :length => 25), edit_admin_page_url(page)
%span= time_ago_in_words(page.updated_at)

View File

@ -8,6 +8,10 @@ x ruby 1.9.2:
x DelayedJob not working
x new version of Aloha-Editor
x locomotive gem: test with staging
- nav tag:
- site | page | parent
- retrieve only important page information from mongodb
- published by default when importing pages
BACKLOG:

View File

@ -19,6 +19,10 @@ module Locomotive
@fullpath ||= @source.fullpath
end
def depth
@source.depth
end
end
end
end

View File

@ -1,20 +1,22 @@
module Locomotive
module Liquid
module Tags
# Display the children pages of the site or the current page. If not precised, nav is applied on the current page.
# Display the children pages of the site, current page or the parent page. If not precised, nav is applied on the current page.
# The html output is based on the ul/li tags.
#
# Usage:
#
# {% nav site %} => <ul class="nav"><li class="on"><a href="/features">Features</a></li></ul>
#
# {% nav site, no_wrapper: true, exclude: 'contact|about', id: 'main-nav' }
#
class Nav < ::Liquid::Tag
Syntax = /(#{::Liquid::Expression}+)?/
def initialize(tag_name, markup, tokens, context)
if markup =~ Syntax
@site_or_page = $1 || 'page'
@source = ($1 || 'page').gsub(/"|'/, '')
@options = {}
markup.scan(::Liquid::TagAttributes) { |key, value| @options[key.to_sym] = value }
@ -29,15 +31,26 @@ module Locomotive
def render(context)
@current_page = context.registers[:page]
source = context.registers[@site_or_page.to_sym]
if source.respond_to?(:name) # site ?
source = source.pages.index.first # start from home page
children = (case @source
when 'site' then context.registers[:site].pages.index.minimal_attributes.first # start from home page
when 'parent' then @current_page.parent || @current_page
when 'page' then @current_page
else
source = source.parent || source
context.registers[:site].pages.fullpath(@source).minimal_attributes.first
end).children_with_minimal_attributes
children_output = []
children.each_with_index do |p, index|
if include_page?(p)
css = ''
css = 'first' if index == 0
css = 'last' if index == children.size - 1
children_output << render_child_link(p, css)
end
end
output = source.children.map { |p| include_page?(p) ? render_child_link(p) : '' }.join("\n")
output = children_output.join("\n")
if @options[:no_wrapper] != 'true'
output = %{<ul id="nav">\n#{output}</ul>}
@ -49,7 +62,7 @@ module Locomotive
private
def include_page?(page)
if page.templatized?
if page.templatized? || !page.published?
false
elsif @options[:exclude]
(page.fullpath =~ @options[:exclude]).nil?
@ -58,14 +71,15 @@ module Locomotive
end
end
def render_child_link(page)
selected = @current_page._id == page._id ? ' on' : ''
def render_child_link(page, css)
# selected = @current_page._id == page._id ? ' on' : ''
selected = @current_page.fullpath =~ /^#{page.fullpath}/ ? ' on' : ''
icon = @options[:icon] ? '<span></span>' : ''
label = %{#{icon if @options[:icon] != 'after' }#{page.title}#{icon if @options[:icon] == 'after' }}
%{
<li id="#{page.slug.dasherize}" class="link#{selected}">
<li id="#{page.slug.dasherize}" class="link#{selected} #{css}">
<a href="/#{page.fullpath}">#{label}</a>
</li>
}.strip