1c5336e9134590758615698fad4561c4f6f90652
[leap_website.git] / lib / static_page.rb
1 require '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       return PageArray.new.replace array
34     end
35   end
36
37   attr_accessor :path, :children, :name, :props, :parent
38
39   ##
40   ## CLASS METHODS
41   ##
42
43   def self.find(filter)
44     if filter =~ /\//
45       path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
46       page = @@pages[path.join('/')]
47       if page
48         return page
49       else
50         return @@pages[path.last]
51       end
52     else
53       @@pages[filter]
54     end
55   end
56
57   def self.all
58     @@pages_array
59   end
60
61   def self.load(directory)
62     @@pages = {}
63     @@page_array = PageArray.new
64     @@root_directory = directory
65     @@relative_root_directory = relative_to_rails_view_root(directory)
66     scan_directory(directory) do |page|
67       @@pages[page.name] ||= page
68       @@pages[page.path.join('/')] = page
69       @@page_array << page
70     end
71   end
72
73   ##
74   ## INSTANCE METHODS
75   ##
76
77   def initialize(parent, name)
78     @children = []
79     @name = name
80     if parent
81       @parent = parent
82       @parent.add_child(self)
83       @path = [@parent.path, @name].flatten.compact
84       @props = load_properties(file_path)
85     else
86       @path = []
87     end
88   end
89
90   def add_child(page)
91     @children << page
92   end
93
94   def all_children
95     PageArray.new(child_tree.flatten.compact)
96   end
97
98   #
99   # e.g. /home/user/dev/leap-public-site/app/views/pages/about-us/contact
100   #
101   def file_path
102     "#{@@root_directory}/#{@path.join('/')}"
103   end
104
105   #
106   # e.g. pages/about-us/contact/en
107   #
108   def template_path(locale=I18n.locale)
109     "#{@@relative_root_directory}/#{@path.join('/')}/#{locale}"
110   end
111
112   def inspect
113     "<'#{@path.join('/')}' #{children.inspect}>"
114   end
115
116   def title
117     begin
118       I18n.t!('pages.' + @name, :raise => true)
119     rescue I18n::MissingTranslationData
120       props.title
121     end
122   end
123
124   def id
125     self.name
126   end
127
128   protected
129
130   def child_tree
131     [self, children.collect{|child| child.child_tree}]
132   end
133
134   private
135
136   def self.scan_directory(directory, parent=nil, &block)
137     parent ||= StaticPage.new(nil, 'root')
138     Dir.chdir directory do
139       Dir.glob("*").each do |child_dir|
140         next unless File.directory?(child_dir)
141         page = StaticPage.new(parent, child_dir)
142         yield page
143         scan_directory(child_dir, page, &block)
144       end
145     end
146   end
147
148   def self.relative_to_rails_view_root(absolute_path)
149     if Rails.root
150       absolute = Pathname.new(absolute_path)
151       rails_view_root = Pathname.new(Rails.root + 'app/views')
152       absolute.relative_path_from(rails_view_root).to_s
153     end
154   end
155
156   def load_properties(file_path)
157     props = PropertySet.new(self)
158     Dir.glob(file_path + '/*.haml') do |content_file_path|
159       locale = File.basename(content_file_path).sub(File.extname(content_file_path),'')
160       #variable_header = ""
161       #p content_file_path
162       #File.open(content_file_path) do |f|
163       #  while (line = f.gets) =~ /^- @/
164       #    variable_header << line
165       #  end
166       #end
167       props.eval(locale, File.read(content_file_path))
168     end
169     return props
170   end
171
172 end
173
174