summaryrefslogtreecommitdiff
path: root/lib/static_page.rb
blob: 12d49485034c3be4905e052fc92a9d6c5b4c6a79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
require 'lib/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, locale=I18n.locale)
      array = sort do |a,b|
        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
    end
  end

  attr_accessor :path, :children, :name, :props, :parent

  def self.find(filter)
    if filter =~ /\//
      path = filter.split('/').map{|segment| segment.gsub(/[^0-9a-z_-]/, '')}
      page = @@pages[path.join('/')]
      if page
        return page
      else
        return @@pages[path.last]
      end
    else
      @@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
    end
  end

  def initialize(parent, name)
    @children = []
    @name = name
    if parent
      @parent = parent
      @parent.add_child(self)
      @path = [@parent.path, @name].flatten.compact
      @props = load_properties(file_path)
    else
      @path = []
    end
  end

  def add_child(page)
    @children << page
  end

  def all_children
    PageArray.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

  #
  # e.g. pages/about-us/contact/en
  #
  def template_path(locale=I18n.locale)
    "#{@@relative_root_directory}/#{@path.join('/')}/#{locale}"
  end

  def inspect
    "<'#{@path.join('/')}' #{children.inspect}>"
  end

  def title
    begin
      I18n.t!('pages.' + @name, :raise => true)
    rescue I18n::MissingTranslationData
      props.title
    end
  end

  protected

  def child_tree
    [self, children.collect{|child| child.child_tree}]
  end

  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 load_properties(file_path)
    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
      #  end
      #end
      props.eval(locale, File.read(content_file_path))
    end
    return props
  end

end