added capacity for pulling static pages from multiple directory source trees.
[leap_website.git] / lib / static_page.rb
1 #
2 # class StaticPage
3 #
4 # represents a static website page.
5 #
6 #
7
8 require 'property_set'
9 require 'i18n'
10 require 'pathname'
11
12 class StaticPage
13   attr_accessor :path, :children, :name, :file_path, :props, :parent, :mount_point
14
15   ##
16   ## CLASS METHODS
17   ##
18
19   def self.find(site, filter)
20     if filter =~ /\//
21       path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
22       page = site.pages[path.join('/')]
23       if page
24         return page
25       else
26         return site.pages[path.last]
27       end
28     else
29       site.pages[filter]
30     end
31   end
32
33   #
34   # loads a directory, creating StaticPages from the directory structure
35   #
36   def scan(&block)
37     Dir.chdir(file_path) do
38       Dir.glob("*").each do |child_name|
39         if File.directory?(child_name)
40           child = StaticPage.new(self, child_name)
41           yield child
42           child.scan(&block)
43         elsif is_simple_page?(child_name)
44           child = StaticPage.new(self, file_without_suffix(child_name))
45           yield child
46         end
47       end
48     end
49   end
50
51   ##
52   ## INSTANCE METHODS
53   ##
54
55   def initialize(parent, name, file_path=nil)
56     @children = []
57     @name = name
58     if parent
59       @parent = parent
60       @mount_point = @parent.mount_point
61       @parent.add_child(self)
62       @path = [@parent.path, @name].flatten.compact
63     else
64       @path = []
65     end
66     if file_path
67       @file_path = file_path
68     elsif @parent && @parent.file_path
69       @file_path = File.join(@parent.file_path, @name)
70     else
71       raise 'file path must be specified or in parent'
72     end
73     @simple_page = !File.directory?(@file_path)
74     @props = load_properties
75   end
76
77   def add_child(page)
78     @children << page
79   end
80
81   def all_children
82     StaticPageArray.new(child_tree.flatten.compact)
83   end
84
85   #
86   # e.g. /home/user/dev/leap-public-site/app/views/pages/about-us/contact
87   #
88   #def file_path
89   #  "#{@mount_point.directory}/#{@path.join('/')}"
90   #end
91
92   #
93   # e.g. pages/about-us/contact/en
94   #
95   def template_path(locale=I18n.locale)
96     if @simple_page
97       "#{@mount_point.relative_directory}/#{@path.join('/')}"
98     else
99       "#{@mount_point.relative_directory}/#{@path.join('/')}/#{locale}"
100     end
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   def id
116     self.name
117   end
118
119   protected
120
121   def child_tree
122     [self, children.collect{|child| child.child_tree}]
123   end
124
125   private
126
127   #def self.relative_to_rails_view_root(absolute_path)
128   #  if Rails.root
129   #    absolute = Pathname.new(absolute_path)
130   #    rails_view_root = Pathname.new(Rails.root + 'app/views')
131   #    absolute.relative_path_from(rails_view_root).to_s
132   #  end
133   #end
134
135   def load_properties
136     props = PropertySet.new(self)
137     Dir.glob(file_path + '/*.haml') do |content_file_path|
138       locale = File.basename(content_file_path).sub(File.extname(content_file_path),'')
139       #variable_header = ""
140       #File.open(content_file_path) do |f|
141       #  while (line = f.gets) =~ /^- @/
142       #    variable_header << line
143       #  end
144       #end
145       props.eval(locale, File.read(content_file_path))
146     end
147     return props
148   end
149
150   SUFFIXES = '(haml|md)'
151
152   #
153   # returns true if the name of a file could be a 'simple' static page
154   # with only one translation.
155   #
156   # rules:
157   # * we include files that end in appriopriate suffixes
158   # * we exclude file names that are locales.
159   #
160   def is_simple_page?(name)
161     name =~ /\.#{SUFFIXES}$/ && name !~ /^(#{AVAILABLE_LANGUAGES.join('|')})\.#{SUFFIXES}$/
162   end
163
164   def file_without_suffix(name)
165     name.sub(/^(.*?)\.#{SUFFIXES}$/, "\\1")
166   end
167 end
168
169