Add mongoid-tree to Item

This commit is contained in:
Christophe Vilayphiou 2012-05-11 16:16:09 +08:00
parent fd52d00187
commit 6a443f0976
13 changed files with 60 additions and 95 deletions

View File

@ -16,6 +16,7 @@ gem 'kaminari', :git => 'git://github.com/amatsuda/kaminari.git'
gem 'mini_magick' gem 'mini_magick'
gem 'mongoid' gem 'mongoid'
gem 'mongoid-tree', :require => 'mongoid/tree'
gem "mongo_session_store-rails3" gem "mongo_session_store-rails3"
gem 'nokogiri' gem 'nokogiri'
gem 'radius' gem 'radius'

View File

@ -118,6 +118,8 @@ GEM
activemodel (~> 3.1) activemodel (~> 3.1)
mongo (~> 1.3) mongo (~> 1.3)
tzinfo (~> 0.3.22) tzinfo (~> 0.3.22)
mongoid-tree (0.7.0)
mongoid (~> 2.0)
multi_json (1.1.0) multi_json (1.1.0)
nokogiri (1.5.2) nokogiri (1.5.2)
nokogiri (1.5.2-x86-mingw32) nokogiri (1.5.2-x86-mingw32)
@ -277,6 +279,7 @@ DEPENDENCIES
mini_magick mini_magick
mongo_session_store-rails3 mongo_session_store-rails3
mongoid mongoid
mongoid-tree
nokogiri nokogiri
radius radius
rails (>= 3.1.0, < 3.2.0) rails (>= 3.1.0, < 3.2.0)

View File

@ -15,7 +15,7 @@ class PagesController < ApplicationController
def show def show
#begin #begin
@item = Item.first(:conditions => {:full_name => params[:page_name]}) @item = Item.first(:conditions => {:path => params[:page_name]})
if @item && @item.is_published && (@item.enabled_for.nil? ? true : @item.enabled_for.include?(I18n.locale.to_s)) if @item && @item.is_published && (@item.enabled_for.nil? ? true : @item.enabled_for.include?(I18n.locale.to_s))
case @item._type case @item._type
when 'Page' when 'Page'
@ -33,16 +33,16 @@ class PagesController < ApplicationController
def index_from_link def index_from_link
if params[:page] if params[:page]
redirect_to "/#{@item.full_name}?page=#{params[:page]}&category_id=#{params[:category_id]}&tag_id=#{params[:tag_id]}" redirect_to "/#{@item.path}?page=#{params[:page]}&category_id=#{params[:category_id]}&tag_id=#{params[:tag_id]}"
else else
redirect_to "/#{@item.full_name}?category_id=#{params[:category_id]}&tag_id=#{params[:tag_id]}" redirect_to "/#{@item.path}?category_id=#{params[:category_id]}&tag_id=#{params[:tag_id]}"
end end
end end
def show_from_link def show_from_link
# debugger # debugger
# a=1 # a=1
redirect_to "/#{@item.full_name}?id=#{params[:id]}&preview=#{params[:preview]}" redirect_to "/#{@item.path}?id=#{params[:id]}&preview=#{params[:preview]}"
end end
def load_orbit_bar def load_orbit_bar

View File

@ -8,9 +8,9 @@ module Admin::ItemHelper
dest = admin_page_path(node) dest = admin_page_path(node)
when 'Link' when 'Link'
dest = admin_link_path(node) dest = admin_link_path(node)
no_nested = 'no-nest'
end end
# ret << "<ol>" unless node.parent.nil? ret << "<li id='#{node.id}' class='#{no_nested}'>"
ret << "<li id='#{node.id}'>"
ret << "<div class='with_action'>" ret << "<div class='with_action'>"
ret << (link_to node.i18n_variable[I18n.locale], dest) ret << (link_to node.i18n_variable[I18n.locale], dest)
ret << "<div class='quick-edit hide'>" ret << "<div class='quick-edit hide'>"
@ -22,14 +22,13 @@ module Admin::ItemHelper
ret << "</div>" ret << "</div>"
ret << render_children(node) ret << render_children(node)
ret << "</li>" ret << "</li>"
# ret << "</ol>" unless node.parent.nil?
end end
ret.html_safe ret.html_safe
end end
def render_children(parent) def render_children(parent)
children = parent.ordered_children children = parent.children
if !children.entries.blank? if !parent.children.entries.blank?
ret = '' ret = ''
ret << "<ol class='#{'sortable' if parent.parent.nil?}'>" ret << "<ol class='#{'sortable' if parent.parent.nil?}'>"
children.each do |child| children.each do |child|
@ -43,15 +42,3 @@ module Admin::ItemHelper
end end
end end
# <ol class="sortable">
# <li><div>Some content</div></li>
# <li><div>Some content</div>
# <ol>
# <li><div>Some sub-item content</div></li>
# <li><div>Some sub-item content</div></li>
# </ol>
# </li>
# <li><div>Some content</div></li>
# </ol>

View File

@ -114,7 +114,7 @@ module ApplicationHelper
def page_title(page) def page_title(page)
res = "<title>" res = "<title>"
page_title = page.title ? page.title[I18n.locale] : page.i18n_variable[I18n.locale] page_title = page.title ? page.title[I18n.locale] : page.i18n_variable[I18n.locale]
if page.is_home? && @site.title if page.root? && @site.title
res << @site.title[I18n.locale] res << @site.title[I18n.locale]
elsif @site.title && @site.title_always_on elsif @site.title && @site.title_always_on
res << @site.title[I18n.locale] + ' - ' + page_title res << @site.title[I18n.locale] + ' - ' + page_title

View File

@ -2,59 +2,31 @@ class Item
include Mongoid::Document include Mongoid::Document
include Mongoid::Timestamps include Mongoid::Timestamps
include Mongoid::Tree
include Mongoid::Tree::Ordering
field :name, :index => true field :name
field :full_name, :index => true field :path
field :position, :type => Integer field :is_published, :type => Boolean, :default => false
field :is_published, :type => Boolean, :default => false, :index => true
field :enabled_for, :type => Array, :default => nil field :enabled_for, :type => Array, :default => nil
field :menu_enabled_for, :type => Array, :default => nil field :menu_enabled_for, :type => Array, :default => nil
validates_format_of :name, :with => /^[0-9a-zA-Z\-_]+$/ validates_format_of :name, :with => /^[0-9a-zA-Z\-_]+$/
validates :name, :exclusion => { :in => LIST[:forbidden_item_names] } validates :name, :exclusion => { :in => LIST[:forbidden_item_names] }
validates_uniqueness_of :name, :scope => :parent_id validates_uniqueness_of :name, :scope => :parent_id
validates_presence_of :name, :full_name, :position validates_presence_of :name
validates_associated :parent, :children
after_rearrange :rebuild_path
belongs_to :parent, :class_name => "Item"
has_one :i18n_variable, :as => :language_value, :autosave => true, :dependent => :destroy has_one :i18n_variable, :as => :language_value, :autosave => true, :dependent => :destroy
has_many :children, :class_name => "Item", :as => 'parent'
before_validation :setup_default_value
def self.find_by_name(item_name) def self.find_by_name(item_name)
Item.first(:conditions => { :name => item_name, :is_published => true }) Item.first(:conditions => { :name => item_name, :is_published => true })
end end
# Get an array of ancestors def visible_children
def ancestors objects = self.children
node, nodes = self, []
nodes << node = node.parent while !node.parent.blank? rescue nil
nodes.reverse
end
# Get an array of ancestor's id
def ancestor_ids
node, nodes = self, []
while !node.parent.blank? do
node = node.parent rescue nil
nodes << node.id if node
end
# nodes << node = node.parent while !node.parent.blank? rescue nil
nodes.reverse
end
# Build the url from the array of ancestors
def url
urls = ancestors.map{ |a| a.name } << self.name
urls.join("/")
end
def ordered_children
self.children.asc(:position)
end
def ordered_and_visible_children
objects = ordered_children
a = [] a = []
if objects if objects
objects.each do |object| objects.each do |object|
@ -66,18 +38,8 @@ class Item
protected protected
def setup_default_value def rebuild_path
# Set the position value within the parent scope self.path = (self.ancestors_and_self - [Item.root]).collect{|x| x.name unless x.root?}.join('/')
if self.position.blank?
max_page = Item.where(:parent_id => self.parent_id).count
self.position = (max_page)? max_page + 1 : 1
end
# Build the full_name from the ancestors array
full_node = self.ancestors.map{ |a| a.name }.push( self.name )
# Remove root node if not root
full_node.shift if full_node.size >= 2
self.full_name = full_node.join("/")
end end
# Enable the validation for parent_id # Enable the validation for parent_id

View File

@ -16,10 +16,6 @@ class Page < Item
# embeds_many :custom_images, :class_name => 'Image', as: :design_image # embeds_many :custom_images, :class_name => 'Image', as: :design_image
def is_home?
self.parent ? false : true
end
def title def title
@title ||= I18nVariable.first(:conditions => {:key => 'title', :language_value_id => self.id, :language_value_type => self.class}) rescue nil @title ||= I18nVariable.first(:conditions => {:key => 'title', :language_value_id => self.id, :language_value_type => self.class}) rescue nil
end end

View File

@ -19,9 +19,6 @@
stop: function(event, ui) { stop: function(event, ui) {
$.post("<%= admin_update_position_path %>", { id: ui.item.attr('id'), parent_id: ui.item.parent().closest('li').attr('id'), position: ui.item.index() } ); $.post("<%= admin_update_position_path %>", { id: ui.item.attr('id'), parent_id: ui.item.parent().closest('li').attr('id'), position: ui.item.index() } );
// console.log("parent: " + ui.item.parent().closest('li').attr('id'));
// console.log("id: " + ui.item.attr('id'));
// console.log("position: " + ui.item.index());
} }
}); });
}); });

View File

@ -14,7 +14,7 @@ module ParserBackEnd
# }.join(' | ') # }.join(' | ')
# end # end
# c.define_tag 'link' do |tag| # c.define_tag 'link' do |tag|
# item = Item.first(:conditions => { :full_name => tag.attr['name'] }) # item = Item.first(:conditions => { :path => tag.attr['name'] })
# ret = '' # ret = ''
# ret << "<a href='" # ret << "<a href='"
# ret << eval("admin_#{item._type.downcase}_path(item.id)") # ret << eval("admin_#{item._type.downcase}_path(item.id)")

View File

@ -3,7 +3,7 @@ module ParserCommon
def menu_level(page, current_page, current, menu, edit = false) def menu_level(page, current_page, current, menu, edit = false)
res = '' res = ''
if page.ordered_and_visible_children.size > 0 if page.visible_children.size > 0
res << "<ul class='" res << "<ul class='"
res << menu.values["class_#{current}"] rescue nil res << menu.values["class_#{current}"] rescue nil
res << "'>" res << "'>"
@ -12,7 +12,7 @@ module ParserCommon
if menu.values['home'] && current == 1 if menu.values['home'] && current == 1
res << menu_li(page, current_page, current, menu, i, edit) res << menu_li(page, current_page, current, menu, i, edit)
end end
page.ordered_and_visible_children.each do |child| page.visible_children.each do |child|
res << menu_li(child, current_page, current, menu, i, edit) res << menu_li(child, current_page, current, menu, i, edit)
i += 1 if i i += 1 if i
end end
@ -25,13 +25,13 @@ module ParserCommon
res = "<li class='" res = "<li class='"
res << menu.values["li_class_#{current}"] rescue nil res << menu.values["li_class_#{current}"] rescue nil
res << "_#{i}" if i res << "_#{i}" if i
res << " active" if (current_page.id.eql?(page.id) || current_page.ancestor_ids.include?(page.id)) res << " active" if (current_page.id.eql?(page.id) || current_page.descendant_of?(page))
res << "'>" res << "'>"
res << "<a href='/#{edit ? admin_page_path(page.id) : page.full_name}'><span>#{page.i18n_variable[I18n.locale]}</span></a>" res << "<a href='/#{edit ? admin_page_path(page.id) : page.path}'><span>#{page.i18n_variable[I18n.locale]}</span></a>"
if page.ordered_and_visible_children.size > 0 && current <= menu.levels if page.visible_children.size > 0 && current <= menu.levels
res << "<span class='dot'></span>" res << "<span class='dot'></span>"
res << menu_level(page, current_page, current + 1, menu, edit) res << menu_level(page, current_page, current + 1, menu, edit)
end unless (page.is_home? rescue nil) end unless (page.root? rescue nil)
res << "</li>" res << "</li>"
end end
@ -113,13 +113,13 @@ module ParserCommon
body.css('sub_menu').each do |sub_menu| body.css('sub_menu').each do |sub_menu|
menu_page = Page.find(sub_menu['id']) rescue nil menu_page = Page.find(sub_menu['id']) rescue nil
res = '' res = ''
if menu_page && menu_page.ordered_and_visible_children.size > 0 if menu_page && menu_page.visible_children.size > 0
res << "<div class='category_list'>" res << "<div class='category_list'>"
res << "<h3 class='h3'>#{menu_page.i18n_variable[I18n.locale]}</h3>" res << "<h3 class='h3'>#{menu_page.i18n_variable[I18n.locale]}</h3>"
res << "<ul class='list'>" res << "<ul class='list'>"
menu_page.ordered_and_visible_children.each do |child| menu_page.visible_children.each do |child|
res << "<li class='#{page.id.eql?(child.id) ? 'active' : nil}'>" res << "<li class='#{page.id.eql?(child.id) ? 'active' : nil}'>"
res << "<a href='/#{edit ? admin_page_path(child.id) : child.full_name}'>#{child.i18n_variable[I18n.locale]}</a>" res << "<a href='/#{edit ? admin_page_path(child.id) : child.path}'>#{child.i18n_variable[I18n.locale]}</a>"
res << "</li>" res << "</li>"
end end
res << "</ul>" res << "</ul>"

View File

@ -11,7 +11,7 @@ module ParserFrontEnd
# }.join(' | ') # }.join(' | ')
# end # end
# c.define_tag 'link' do |tag| # c.define_tag 'link' do |tag|
# item = Item.first(:conditions => { :full_name => tag.attr['name'] }) # item = Item.first(:conditions => { :path => tag.attr['name'] })
# ret = '' # ret = ''
# ret << "<a href='#{tag.attr['name']}'>" # ret << "<a href='#{tag.attr['name']}'>"
# ret << item.i18n_variable[I18n.locale] # ret << item.i18n_variable[I18n.locale]

19
lib/tasks/items.rake Normal file
View File

@ -0,0 +1,19 @@
# encoding: utf-8
namespace :items do
task :tree_changes => :environment do
Item.all.each do |item|
item.position -= 1
item.parent_ids = ancestors(item)
item.rename(:full_name, :path)
item.save
end
end
def ancestors(item)
node, nodes = item, []
nodes << node = node.parent while !node.parent.blank? rescue nil
nodes.reverse
end
end

View File

@ -1,7 +1,7 @@
<tr id="<%= dom_id page_context %>" class="with_action"> <tr id="<%= dom_id page_context %>" class="with_action">
<td> <td>
<%= page_context.page.full_name %> <%= page_context.page.path %>
<div class="quick-edit"> <div class="quick-edit">
<ul class="nav nav-pills hide"> <ul class="nav nav-pills hide">
<li><%= link_to t('page_context.edit'), edit_panel_page_content_back_end_page_context_path(page_context) %></li> <li><%= link_to t('page_context.edit'), edit_panel_page_content_back_end_page_context_path(page_context) %></li>