summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/application_controller.rb34
-rw-r--r--app/controllers/pages_controller.rb4
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/helpers/blog_helper.rb4
-rw-r--r--app/helpers/navigation_helper.rb37
-rw-r--r--app/views/layouts/_topnav.html.haml8
-rw-r--r--app/views/layouts/application.html.haml2
-rw-r--r--config/initializers/libraries.rb9
-rw-r--r--lib/config.rb9
-rw-r--r--lib/menu.rb133
-rw-r--r--lib/site.rb93
-rw-r--r--lib/site_configuration.rb50
-rw-r--r--lib/site_mount_point.rb59
-rw-r--r--lib/static_page.rb149
-rw-r--r--lib/static_page_array.rb32
-rw-r--r--site.rb11
16 files changed, 473 insertions, 169 deletions
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index da6cf3e..b2c5762 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -3,6 +3,10 @@ class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale, :initialize_pages
+ class << self
+ attr_accessor :current_site # a class instance variable
+ end
+
if Rails.env.production?
rescue_from Exception, :with => :render_500
rescue_from ActionController::RoutingError, :with => :render_404
@@ -81,25 +85,31 @@ class ApplicationController < ActionController::Base
helper_method :page_body
##
- ## INITIALIZATION
+ ## SITE
##
#
- # run every time in development mode, run once in production mode
+ # if we ever make this code support multiple sites, this should depend on the request's domain
#
- def initialize_pages
- run_once(:initialize_pages, :unless => Rails.env.development?) do
- StaticPage.load(PAGE_DIRECTORY)
- Menu.load(PAGE_DIRECTORY + '/menu.txt')
- end
+ def site
+ self.class.current_site ||= Site.new
end
+ helper_method :site
- def run_once(name, options={})
- key_name = "run_once_#{name}"
- if !Thread.current[key_name] || options[:unless]
- yield
+ def initialize_pages
+ if Rails.env.development?
+ site.load_pages
+ else
+ site.reload_pages_if_needed
end
- Thread.current[key_name] = true
end
+ #def run_once(name, options={})
+ # key_name = "run_once_#{name}"
+ # if !Thread.current[key_name] || options[:unless]
+ # yield
+ # end
+ # Thread.current[key_name] = true
+ #end
+
end
diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb
index d4fa09a..36c733b 100644
--- a/app/controllers/pages_controller.rb
+++ b/app/controllers/pages_controller.rb
@@ -7,7 +7,7 @@ class PagesController < ApplicationController
rescue_from PageNotFound, :with => :render_404
def show
- @page = StaticPage.find(params[:page])
+ @page = site.find_pages(params[:page])
if @page
respond_to do |format|
format.atom { render_atom_feed(@page) }
@@ -21,7 +21,7 @@ class PagesController < ApplicationController
protected
def choose_layout
- if @page && @page.props.layout
+ if @page && @page.props && @page.props.layout
@page.props.layout
else
'application'
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index b5bb657..2933bd1 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -33,7 +33,7 @@ module ApplicationHelper
if name.starts_with?('#') || name.starts_with?('http')
path = name
else
- page = StaticPage.find(name)
+ page = site.find_page(name)
if page
label ||= page.title
path = page_path(page)
@@ -69,7 +69,11 @@ module ApplicationHelper
def page_title
if @page
- @page.props.title || @page.title
+ if @page.props
+ @page.props.title || @page.title
+ else
+ @page.title
+ end
else
""
end
diff --git a/app/helpers/blog_helper.rb b/app/helpers/blog_helper.rb
index 42e6f9c..2fc6b85 100644
--- a/app/helpers/blog_helper.rb
+++ b/app/helpers/blog_helper.rb
@@ -1,9 +1,9 @@
module BlogHelper
def recent_blog_summaries(path)
- root = StaticPage.find(path)
+ root = site.find_page(path)
if root
- pages = root.all_children.order_by(:posted_at, :direction => :desc).limit(PAGINATION_SIZE)
+ pages = root.all_children.order_by(:posted_at, :direction => :desc).limit(site.pagination_size)
haml do
pages.each do |page|
haml render(:partial => 'layouts/blog/summary', :locals => {:page => page})
diff --git a/app/helpers/navigation_helper.rb b/app/helpers/navigation_helper.rb
index 8582391..a43eecd 100644
--- a/app/helpers/navigation_helper.rb
+++ b/app/helpers/navigation_helper.rb
@@ -1,18 +1,21 @@
module NavigationHelper
def has_side_column?
- second_level_children_count = Menu.menu.submenu(current_page_path.first).try(:size)
+ if root_page?
+ return false
+ end
+ second_level_children_count = site.menu.submenu(current_page_path.first).try(:size)
if second_level_children_count.nil?
false
else
- second_level_children_count > 1
+ second_level_children_count >= 1
end
end
def top_level_navigation_links
haml do
first = 'first'
- Menu.menu.each do |item|
+ site.menu.each do |item|
active = current_page_path.first == item.name ? 'active' : ''
haml 'li.tab', :class => first do
haml 'a.tab', I18n.t('pages.' + item.name), :href => menu_item_path(item), :class => active
@@ -23,7 +26,7 @@ module NavigationHelper
end
def side_column_navigation_links
- if menu = Menu.menu.submenu(current_page_path.first)
+ if menu = site.menu.submenu(current_page_path.first)
haml do
haml 'ul.nav.nav-tabs.nav-stacked' do
display_menu(menu, 1)
@@ -33,7 +36,7 @@ module NavigationHelper
end
def act_as(page)
- page = StaticPage.find(page)
+ page = site.find_page(page)
@current_page_path = page.path
render_page(page)
end
@@ -54,7 +57,17 @@ module NavigationHelper
end
def path_active(page_path, menu_item)
- array_starts_with(page_path, menu_item.path) ? 'active' : ''
+ active = ''
+ if menu_item.path == page_path
+ active = 'active'
+ elsif menu_item.path_prefix_of?(page_path)
+ if menu_item.leaf_for_path?(page_path)
+ active = 'active'
+ else
+ active = 'semi-active'
+ end
+ end
+ active
end
def current_page_path
@@ -70,15 +83,11 @@ module NavigationHelper
end
#
- # returns true if first part of array_long contains array_short
+ # the usage of 'home' as the default root page is hardcoded right now in the routes.
+ # this should be changed in the future.
#
- def array_starts_with(array_long, array_short)
- array_short.length.times do |i|
- if array_short[i] != array_long[i]
- return false
- end
- end
- return true
+ def root_page?
+ @page && @page.path == ['home']
end
end
diff --git a/app/views/layouts/_topnav.html.haml b/app/views/layouts/_topnav.html.haml
deleted file mode 100644
index d0d553e..0000000
--- a/app/views/layouts/_topnav.html.haml
+++ /dev/null
@@ -1,8 +0,0 @@
-%ul#topnav
- = top_level_navigation_links
- %li.tab.first
- %a.tab{:href => '#'} Home
- %li.tab
- %a.tab.active{:href => '#'} Technology
- %li.tab
- %a.tab About Us \ No newline at end of file
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index fe0888a..3d28f38 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,7 +1,7 @@
!!! 5
%html{:dir=>'ltr'}
%head
- %title #{SITE_TITLE} - #{page_title}
+ %title #{site.title} - #{page_title}
= stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "application"
= csrf_meta_tags
diff --git a/config/initializers/libraries.rb b/config/initializers/libraries.rb
index f018ff9..ae0b4f0 100644
--- a/config/initializers/libraries.rb
+++ b/config/initializers/libraries.rb
@@ -1,5 +1,6 @@
-require 'config'
-require 'static_page'
-require 'menu'
-require 'http_accept_language'
+#require 'site_configuration'
+#require 'site'
+#require 'static_page'
+#require 'menu'
+#require 'http_accept_language'
require 'core_extensions' \ No newline at end of file
diff --git a/lib/config.rb b/lib/config.rb
deleted file mode 100644
index a579631..0000000
--- a/lib/config.rb
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Here go any application configuration
-#
-
-SITE_TITLE = "LEAP"
-
-PAGE_DIRECTORY = File.expand_path('../../app/views/pages', __FILE__)
-
-PAGINATION_SIZE = 20
diff --git a/lib/menu.rb b/lib/menu.rb
index 71690a4..c156e07 100644
--- a/lib/menu.rb
+++ b/lib/menu.rb
@@ -1,47 +1,45 @@
-class Menu < Array
- attr_accessor :parent
+#
+# A navigation menu class
+#
- #
- # class methods
- #
+class Menu
+ attr_accessor :parent
+ attr_accessor :children
+ attr_accessor :name
#
- # load the menu.txt file, recursively, and build the in-memory menu array
+ # load the menu.txt file and build the in-memory menu array
#
- def self.load(menu_file_path)
- @menu = Menu.new
+ def load(menu_file_path)
File.open(menu_file_path) do |file|
- append_menu_item(@menu, file)
+ parse_menu(file)
end
end
- def self.menu
- @menu || Menu.new
+ def initialize(name, parent=nil)
+ self.name = name
+ self.parent = parent
+ self.children = []
end
- def self.create(elements=[], parent=nil)
- menu = Menu[elements]
- menu.parent = parent
- return menu
- end
+ ##
+ ## public methods
+ ##
#
- # public methods
+ # returns the menu under the item that matches item_name.
#
-
def submenu(item_name=nil)
if item_name
- submenu = detect {|item| item[0] == item_name} || Menu.new
+ self.children.detect {|child| child.name == item_name} || Menu.new
else
- submenu = self
+ self.children
end
- return submenu[1..-1] # strip of first element
- end
-
- def name
- first
end
+ #
+ # returns path from root to this leaf as an array
+ #
def path
@path ||= begin
if parent == nil
@@ -52,27 +50,86 @@ class Menu < Array
end
end
+ def each(&block)
+ children.each(&block)
+ end
+
+ def size
+ children.size
+ end
+
+ #
+ # returns true if menu's path starts with +path_prefix+
+ #
+ def path_starts_with?(path_prefix)
+ array_starts_with?(path, path_prefix)
+ end
+
+ def path_prefix_of?(full_path)
+ array_starts_with?(full_path, path)
+ end
+
+ #
+ # returns true if this menu item is the terminus menu item for path.
+ # (meaning that there are no children that match more path segments)
+ #
+ def leaf_for_path?(path)
+ return false unless path_prefix_of?(path)
+ next_path_segment = (path - self.path).first
+ return false if next_path_segment.nil?
+ return !children.detect {|i| i.name == next_path_segment}
+ end
+
+ def inspect(indent=0)
+ lines = []
+ lines << ' '*indent + '- ' + self.name
+ self.children.each do |child|
+ lines << child.inspect(indent+1)
+ end
+ lines.join("\n")
+ end
+
+ #
+ # private & protected methods
+ #
+
+ protected
+
+ def add_child(name)
+ self.children << Menu.new(name, self)
+ end
+
private
- def self.append_menu_item(menu, file)
- begin
+ def array_starts_with?(big_array, small_array)
+ small_array.length.times do |i|
+ if small_array[i] != big_array[i]
+ return false
+ end
+ end
+ return true
+ end
+
+
+ def parse_menu(file)
+ while true
item = file.readline
- rescue EOFError
- # do nothing
- else
- if item !~ /^\s*#/
+ if item.strip.chars.any? && item !~ /^\s*#/
depth = item.scan(" ").size
- sub_menu = sub_menu_for_depth(menu, depth)
- sub_menu << Menu.create(item.strip, sub_menu)
+ last_menu_at_depth(depth).add_child(item.strip)
end
- append_menu_item(menu, file)
end
+ rescue EOFError
+ # done loading
end
- def self.sub_menu_for_depth(menu, depth)
- sub_menu = menu
- depth.times { sub_menu = sub_menu[-1] }
- sub_menu
+ #
+ # returns the last list of children at the specified depth
+ #
+ def last_menu_at_depth(depth)
+ menu = self
+ depth.times { menu = menu.children.last }
+ menu
end
end \ No newline at end of file
diff --git a/lib/site.rb b/lib/site.rb
new file mode 100644
index 0000000..a3e8ac3
--- /dev/null
+++ b/lib/site.rb
@@ -0,0 +1,93 @@
+
+class Site
+ extend Forwardable
+
+ attr_accessor :pages
+ attr_accessor :page_list
+ attr_accessor :root
+ attr_accessor :menu
+
+ def_delegators :@config, :title, :pagination_size
+
+ def initialize
+ @config = SiteConfiguration.load("#{Rails.root}/site.rb")
+ end
+
+ def load_pages
+ @root = nil
+ @pages = {}
+ @page_list = StaticPageArray.new
+ @menu = Menu.new('root')
+ @config.mount_points.each do |mp|
+ add_mount_point(mp)
+ mp.reset_timestamp
+ end
+ end
+
+ def reload_pages_if_needed
+ if @pages.nil? || @config.pages_changed?
+ puts "Reloading pages ................."
+ load_pages
+ end
+ end
+
+ #def menu
+ # @menu ||= Menu.new
+ #end
+
+ def find_pages(filter)
+ StaticPage.find(self, filter)
+ end
+
+ def find_page(filter)
+ find_pages(filter)
+ end
+
+ def all_pages
+ @page_list
+ end
+
+ private
+
+ def add_mount_point(mp)
+ # create base_page
+ base_page = begin
+ if mp.path == '/'
+ @root = StaticPage.new(nil, 'root', mp.directory)
+ else
+ name = File.basename(mp.path)
+ page = StaticPage.new(find_parent(mp.path), name, File.join(mp.directory, name))
+ add_page(page)
+ page
+ end
+ end
+ base_page.mount_point = mp
+
+ # load menu and locals
+ menu.load(mp.menu_file) if mp.menu_file
+ I18n.load_path += Dir[File.join(mp.locales_dir, '/*.{rb,yml,yaml}')] if mp.locales_dir
+
+ # add the full directory tree
+ base_page.scan do |page|
+ add_page(page)
+ end
+ end
+
+ def add_page(page)
+ @pages[page.name] = page
+ @pages[page.path.join('/')] = page
+ @page_list << page
+ end
+
+ def find_parent(path)
+ so_far = []
+ path.split('/').compact.each do |path_segment|
+ so_far << path_segment
+ if page = @pages[so_far.join('/')]
+ return page
+ end
+ end
+ return @root
+ end
+
+end
diff --git a/lib/site_configuration.rb b/lib/site_configuration.rb
new file mode 100644
index 0000000..62ad854
--- /dev/null
+++ b/lib/site_configuration.rb
@@ -0,0 +1,50 @@
+#
+# A class for a site's configuration.
+# Site configuration file is eval'ed in the context of an instance of SiteConfiguration
+#
+
+require 'pathname'
+
+class SiteConfiguration
+
+ attr_accessor :title
+ attr_accessor :pagination_size
+ attr_accessor :mount_points
+ attr_reader :file_path
+
+ ##
+ ## CLASS METHODS
+ ##
+
+ def self.load(config_file)
+ SiteConfiguration.new(config_file)
+ end
+
+ ##
+ ## INSTANCE METHODS
+ ##
+
+ #
+ # accepts a file_path to a configuration file.
+ #
+ def initialize(file_path)
+ @file_path = file_path
+ @site_title = "untitled"
+ @pagination_size = 20
+ @mount_points = []
+ self.eval
+ end
+
+ def pages(directory_source, options={})
+ @mount_points << SiteMountPoint.new(self, directory_source, options)
+ end
+
+ def pages_changed?
+ @mount_points.detect {|mp| mp.changed?}
+ end
+
+ def eval
+ self.instance_eval(File.read(@file_path), @file_path)
+ end
+
+end
diff --git a/lib/site_mount_point.rb b/lib/site_mount_point.rb
new file mode 100644
index 0000000..0b8224a
--- /dev/null
+++ b/lib/site_mount_point.rb
@@ -0,0 +1,59 @@
+#
+# A site can have many 'mount points' -- places in the site tree where different directories are inserted.
+#
+# At a minimum, every site needs a mount point for '/'
+#
+class SiteMountPoint
+
+ attr_accessor :directory
+ attr_accessor :relative_directory
+ attr_accessor :path
+ attr_accessor :options
+ attr_accessor :menu_file
+ attr_accessor :locales_dir
+ attr_accessor :timestamp
+
+ def initialize(site_config, directory_source, options={})
+ if directory_source.starts_with?('/')
+ @directory = directory_source
+ else
+ @directory = File.expand_path(directory_source, File.dirname(site_config.file_path))
+ end
+
+ @path = options[:path]
+ @relative_directory = relative_dir_path(@directory)
+ @menu_file = file_path('menu.txt')
+ @locales_dir = file_path('locales')
+ @options = options
+ reset_timestamp
+ end
+
+ def changed?
+ File.mtime(@directory) > @timestamp
+ end
+
+ def reset_timestamp
+ @timestamp = File.mtime(@directory)
+ end
+
+ private
+
+ def file_path(file)
+ path = File.join(@directory, file)
+ if File.exists?(path)
+ path
+ else
+ nil
+ end
+ end
+
+ #
+ # returns path relative to app/views
+ #
+ def relative_dir_path(directory)
+ if Rails.root
+ Pathname.new(directory).relative_path_from(Pathname.new(Rails.root + 'app/views')).to_s
+ end
+ end
+
+end \ No newline at end of file
diff --git a/lib/static_page.rb b/lib/static_page.rb
index 1c5336e..eb32319 100644
--- a/lib/static_page.rb
+++ b/lib/static_page.rb
@@ -1,72 +1,50 @@
+#
+# class StaticPage
+#
+# represents a static website page.
+#
+#
+
require 'property_set'
require 'i18n'
require 'pathname'
class StaticPage
-
- class PageArray < Array
- def limit(num)
- PageArray.new(self[0..(num-1)])
- end
- def order_by(attr, options={})
- locale = options[:locale] || I18n.locale
- direction = options[:direction] || :asc
- array = sort do |a,b|
- if direction == :desc
- a, b = b, a
- end
- a_prop = a.props.locale(locale).send(attr)
- b_prop = b.props.locale(locale).send(attr)
- if a_prop.nil? && b_prop.nil?
- 0
- elsif a_prop.nil?
- 1
- elsif b_prop.nil?
- -1
- else
- a_prop <=> b_prop
- end
- end
- array.delete_if do |page|
- page.props.locale(locale).send(attr).nil?
- end
- return PageArray.new.replace array
- end
- end
-
- attr_accessor :path, :children, :name, :props, :parent
+ attr_accessor :path, :children, :name, :file_path, :props, :parent, :mount_point
##
## CLASS METHODS
##
- def self.find(filter)
+ def self.find(site, filter)
if filter =~ /\//
path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
- page = @@pages[path.join('/')]
+ page = site.pages[path.join('/')]
if page
return page
else
- return @@pages[path.last]
+ return site.pages[path.last]
end
else
- @@pages[filter]
+ site.pages[filter]
end
end
- def self.all
- @@pages_array
- end
-
- def self.load(directory)
- @@pages = {}
- @@page_array = PageArray.new
- @@root_directory = directory
- @@relative_root_directory = relative_to_rails_view_root(directory)
- scan_directory(directory) do |page|
- @@pages[page.name] ||= page
- @@pages[page.path.join('/')] = page
- @@page_array << page
+ #
+ # loads a directory, creating StaticPages from the directory structure
+ #
+ def scan(&block)
+ Dir.chdir(file_path) do
+ Dir.glob("*").each do |child_name|
+ if File.directory?(child_name)
+ child = StaticPage.new(self, child_name)
+ yield child
+ child.scan(&block)
+ elsif is_simple_page?(child_name)
+ child = StaticPage.new(self, file_without_suffix(child_name))
+ yield child
+ end
+ end
end
end
@@ -74,17 +52,26 @@ class StaticPage
## INSTANCE METHODS
##
- def initialize(parent, name)
+ def initialize(parent, name, file_path=nil)
@children = []
@name = name
if parent
@parent = parent
+ @mount_point = @parent.mount_point
@parent.add_child(self)
@path = [@parent.path, @name].flatten.compact
- @props = load_properties(file_path)
else
@path = []
end
+ if file_path
+ @file_path = file_path
+ elsif @parent && @parent.file_path
+ @file_path = File.join(@parent.file_path, @name)
+ else
+ raise 'file path must be specified or in parent'
+ end
+ @simple_page = !File.directory?(@file_path)
+ @props = load_properties
end
def add_child(page)
@@ -92,21 +79,25 @@ class StaticPage
end
def all_children
- PageArray.new(child_tree.flatten.compact)
+ StaticPageArray.new(child_tree.flatten.compact)
end
#
# e.g. /home/user/dev/leap-public-site/app/views/pages/about-us/contact
#
- def file_path
- "#{@@root_directory}/#{@path.join('/')}"
- end
+ #def file_path
+ # "#{@mount_point.directory}/#{@path.join('/')}"
+ #end
#
# e.g. pages/about-us/contact/en
#
def template_path(locale=I18n.locale)
- "#{@@relative_root_directory}/#{@path.join('/')}/#{locale}"
+ if @simple_page
+ "#{@mount_point.relative_directory}/#{@path.join('/')}"
+ else
+ "#{@mount_point.relative_directory}/#{@path.join('/')}/#{locale}"
+ end
end
def inspect
@@ -133,32 +124,19 @@ class StaticPage
private
- def self.scan_directory(directory, parent=nil, &block)
- parent ||= StaticPage.new(nil, 'root')
- Dir.chdir directory do
- Dir.glob("*").each do |child_dir|
- next unless File.directory?(child_dir)
- page = StaticPage.new(parent, child_dir)
- yield page
- scan_directory(child_dir, page, &block)
- end
- end
- end
+ #def self.relative_to_rails_view_root(absolute_path)
+ # if Rails.root
+ # absolute = Pathname.new(absolute_path)
+ # rails_view_root = Pathname.new(Rails.root + 'app/views')
+ # absolute.relative_path_from(rails_view_root).to_s
+ # end
+ #end
- def self.relative_to_rails_view_root(absolute_path)
- if Rails.root
- absolute = Pathname.new(absolute_path)
- rails_view_root = Pathname.new(Rails.root + 'app/views')
- absolute.relative_path_from(rails_view_root).to_s
- end
- end
-
- def load_properties(file_path)
+ def load_properties
props = PropertySet.new(self)
Dir.glob(file_path + '/*.haml') do |content_file_path|
locale = File.basename(content_file_path).sub(File.extname(content_file_path),'')
#variable_header = ""
- #p content_file_path
#File.open(content_file_path) do |f|
# while (line = f.gets) =~ /^- @/
# variable_header << line
@@ -169,6 +147,23 @@ class StaticPage
return props
end
+ SUFFIXES = '(haml|md)'
+
+ #
+ # returns true if the name of a file could be a 'simple' static page
+ # with only one translation.
+ #
+ # rules:
+ # * we include files that end in appriopriate suffixes
+ # * we exclude file names that are locales.
+ #
+ def is_simple_page?(name)
+ name =~ /\.#{SUFFIXES}$/ && name !~ /^(#{AVAILABLE_LANGUAGES.join('|')})\.#{SUFFIXES}$/
+ end
+
+ def file_without_suffix(name)
+ name.sub(/^(.*?)\.#{SUFFIXES}$/, "\\1")
+ end
end
diff --git a/lib/static_page_array.rb b/lib/static_page_array.rb
new file mode 100644
index 0000000..33b11e0
--- /dev/null
+++ b/lib/static_page_array.rb
@@ -0,0 +1,32 @@
+#
+# Array of StaticPages
+#
+class StaticPageArray < Array
+ def limit(num)
+ StaticPageArray.new(self[0..(num-1)])
+ end
+ def order_by(attr, options={})
+ locale = options[:locale] || I18n.locale
+ direction = options[:direction] || :asc
+ array = sort do |a,b|
+ if direction == :desc
+ a, b = b, a
+ end
+ a_prop = a.props.locale(locale).send(attr)
+ b_prop = b.props.locale(locale).send(attr)
+ if a_prop.nil? && b_prop.nil?
+ 0
+ elsif a_prop.nil?
+ 1
+ elsif b_prop.nil?
+ -1
+ else
+ a_prop <=> b_prop
+ end
+ end
+ array.delete_if do |page|
+ page.props.locale(locale).send(attr).nil?
+ end
+ return StaticPageArray.new.replace array
+ end
+end \ No newline at end of file
diff --git a/site.rb b/site.rb
new file mode 100644
index 0000000..f503604
--- /dev/null
+++ b/site.rb
@@ -0,0 +1,11 @@
+#
+# site configuration
+#
+
+pages 'pages', :path => '/'
+
+pages '../leap_doc', :path => '/docs'
+
+@title = "LEAP"
+
+@pagination_size = 20