added capacity for pulling static pages from multiple directory source trees.
authorelijah <elijah@riseup.net>
Wed, 13 Feb 2013 05:33:39 +0000 (21:33 -0800)
committerelijah <elijah@riseup.net>
Wed, 13 Feb 2013 05:33:39 +0000 (21:33 -0800)
16 files changed:
app/controllers/application_controller.rb
app/controllers/pages_controller.rb
app/helpers/application_helper.rb
app/helpers/blog_helper.rb
app/helpers/navigation_helper.rb
app/views/layouts/_topnav.html.haml [deleted file]
app/views/layouts/application.html.haml
config/initializers/libraries.rb
lib/config.rb [deleted file]
lib/menu.rb
lib/site.rb [new file with mode: 0644]
lib/site_configuration.rb [new file with mode: 0644]
lib/site_mount_point.rb [new file with mode: 0644]
lib/static_page.rb
lib/static_page_array.rb [new file with mode: 0644]
site.rb [new file with mode: 0644]

index da6cf3e..b2c5762 100644 (file)
@@ -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
index d4fa09a..36c733b 100644 (file)
@@ -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'
index b5bb657..2933bd1 100644 (file)
@@ -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
index 42e6f9c..2fc6b85 100644 (file)
@@ -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})
index 8582391..a43eecd 100644 (file)
@@ -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 (file)
index d0d553e..0000000
+++ /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
index fe0888a..3d28f38 100644 (file)
@@ -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
index f018ff9..ae0b4f0 100644 (file)
@@ -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 (file)
index a579631..0000000
+++ /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
index 71690a4..c156e07 100644 (file)
@@ -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 (file)
index 0000000..a3e8ac3
--- /dev/null
@@ -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 (file)
index 0000000..62ad854
--- /dev/null
@@ -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 (file)
index 0000000..0b8224a
--- /dev/null
@@ -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
index 1c5336e..eb32319 100644 (file)
@@ -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 (file)
index 0000000..33b11e0
--- /dev/null
@@ -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 (file)
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