security bingo!
[leap_website.git] / lib / static_page.rb
1 require 'lib/property_set'
2 require 'i18n'
3 require 'pathname'
4
5 class StaticPage
6
7   class PageArray < Array
8     def limit(num)
9       PageArray.new(self[0..(num-1)])
10     end
11     def order_by(attr, options={})
12       locale = options[:locale] || I18n.locale
13       direction = options[:direction] || :asc
14       array = sort do |a,b|
15         if direction == :desc
16           a, b = b, a
17         end
18         a_prop = a.props.locale(locale).send(attr)
19         b_prop = b.props.locale(locale).send(attr)
20         if a_prop.nil? && b_prop.nil?
21           0
22         elsif a_prop.nil?
23           1
24         elsif b_prop.nil?
25           -1
26         else
27           a_prop <=> b_prop
28         end
29       end
30       array.delete_if do |page|
31         page.props.locale(locale).send(attr).nil?
32       end
33     end
34   end
35
36   attr_accessor :path, :children, :name, :props, :parent
37
38   def self.find(filter)
39     if filter =~ /\//
40       path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
41       page = @@pages[path.join('/')]
42       if page
43         return page
44       else
45         return @@pages[path.last]
46       end
47     else
48       @@pages[filter]
49     end
50   end
51
52   def self.all
53     @@pages_array
54   end
55
56   def self.load(directory)
57     @@pages = {}
58     @@page_array = PageArray.new
59     @@root_directory = directory
60     @@relative_root_directory = relative_to_rails_view_root(directory)
61     scan_directory(directory) do |page|
62       @@pages[page.name] ||= page
63       @@pages[page.path.join('/')] = page
64       @@page_array << page
65     end
66   end
67
68   def initialize(parent, name)
69     @children = []
70     @name = name
71     if parent
72       @parent = parent
73       @parent.add_child(self)
74       @path = [@parent.path, @name].flatten.compact
75       @props = load_properties(file_path)
76     else
77       @path = []
78     end
79   end
80
81   def add_child(page)
82     @children << page
83   end
84
85   def all_children
86     PageArray.new(child_tree.flatten.compact)
87   end
88
89   #
90   # e.g. /home/user/dev/leap-public-site/app/views/pages/about-us/contact
91   #
92   def file_path
93     "#{@@root_directory}/#{@path.join('/')}"
94   end
95
96   #
97   # e.g. pages/about-us/contact/en
98   #
99   def template_path(locale=I18n.locale)
100     "#{@@relative_root_directory}/#{@path.join('/')}/#{locale}"
101   end
102
103   def inspect
104     "<'#{@path.join('/')}' #{children.inspect}>"
105   end
106
107   def title
108     begin
109       I18n.t!('pages.' + @name, :raise => true)
110     rescue I18n::MissingTranslationData
111       props.title
112     end
113   end
114
115   protected
116
117   def child_tree
118     [self, children.collect{|child| child.child_tree}]
119   end
120
121   private
122
123   def self.scan_directory(directory, parent=nil, &block)
124     parent ||= StaticPage.new(nil, 'root')
125     Dir.chdir directory do
126       Dir.glob("*").each do |child_dir|
127         next unless File.directory?(child_dir)
128         page = StaticPage.new(parent, child_dir)
129         yield page
130         scan_directory(child_dir, page, &block)
131       end
132     end
133   end
134
135   def self.relative_to_rails_view_root(absolute_path)
136     if Rails.root
137       absolute = Pathname.new(absolute_path)
138       rails_view_root = Pathname.new(Rails.root + 'app/views')
139       absolute.relative_path_from(rails_view_root).to_s
140     end
141   end
142
143   def load_properties(file_path)
144     props = PropertySet.new(self)
145     Dir.glob(file_path + '/*.haml') do |content_file_path|
146       locale = File.basename(content_file_path).sub(File.extname(content_file_path),'')
147       #variable_header = ""
148       #p content_file_path
149       #File.open(content_file_path) do |f|
150       #  while (line = f.gets) =~ /^- @/
151       #    variable_header << line
152       #  end
153       #end
154       props.eval(locale, File.read(content_file_path))
155     end
156     return props
157   end
158
159 end
160
161