c315a138756e408e1b033bf2042f141d84837b01
[leap_website.git] / lib / property_set.rb
1 #
2 # holds the set or properties defined for each static page.
3 # property sets are organized by locale.
4 #
5 # e.g.
6 #
7 # setting the property (in en.haml):
8 #
9 #   - @title = 'hi'
10 #
11 # getting the property
12 #
13 #   page.props.title
14 #
15
16 require 'i18n'
17 require 'time'
18 require 'rubygems'
19 require 'haml'
20 require 'RedCloth'
21
22 class PropertySet
23
24   DEFAULT_LOCALE = 'en'
25
26   #
27   # a simple class to pass through all member variables as attributes.
28   # when the template for a page is evaluated, all the member variabled defined in that template
29   # are loaded as member variables of the AttrObject instance.
30   #
31   class AttrObject
32     def initialize(property_set, locale)
33       @_ps = property_set
34       @_locale = locale
35       #code.gsub!(/^((?!^\-\ \@).)*$/, '')  # remove any lines not starting with '- @'
36       #code.gsub!(/^- /m, '') # remove '-'
37       #instance_eval(code)
38       #instance_variables.grep(/_at$/).each do |time_variable|
39       #  instance_variable_set(time_variable, Time.parse(instance_variable_get(time_variable)))
40       #end
41     end
42     def method_missing(method)
43       get(method)
44     end
45     def textile(str)
46       RedCloth.new(str).to_html
47     end
48     def get(var_name)
49       value = instance_variable_get("@#{var_name}")
50       if value.nil?
51         if @_locale != DEFAULT_LOCALE
52           # try value from default locale
53           @_ps.get_var(var_name)
54         else
55           # try inherited value
56           @_ps.get_inherited_var(var_name, @_locale)
57         end
58       else
59         value
60       end
61     end
62     def set(var_name, value)
63       instance_variable_set("@#{var_name}", value)
64     end
65   end
66
67   def initialize(page=nil)
68     @page = page
69     @locales = {}
70   end
71
72
73   #
74   # maybe something like this in the future:
75   #
76   #contr = PagesController.new()
77   #contr.response = ActionController::Response.new()
78   #scope = ActionView::Base.new(["#{RAILS_ROOT}/app/views/pages","#{RAILS_ROOT}/app/views"], {}, contr)
79   #scope.template_format = 'html'
80   #Haml::Engine.new(value, :format => :html5).render(scope)
81   #
82
83   #
84   # evaluate the template_string, and load the variables defined into an AttrObject.
85   #
86   def eval(locale, template_string)
87     attrs = AttrObject.new(self, locale)
88     body = nil
89     begin
90       body = Haml::Engine.new(template_string, :format => :html5).render(attrs)  # template is evaluated in scope of attrs
91     rescue Exception => exc
92       # eat exceptions
93     end
94     attrs.instance_variable_set('@body', body)
95     attrs.instance_variables.grep(/_at$/).each do |time_variable|
96       attrs.instance_variable_set(time_variable, Time.parse(attrs.instance_variable_get(time_variable)))
97     end
98     @locales[locale] = attrs
99   end
100
101   #
102   # allows property_set.propname shortcut, assumes default locale
103   #
104   def method_missing(method)
105     get_var(method)
106   end
107
108   def locale(l)
109     @locales[l.to_s] || @locales[DEFAULT_LOCALE]
110   end
111
112   def get_var(var_name, locale=I18n.locale)
113     attrs = locale(locale)
114     if attrs
115       attrs.get(var_name)
116     else
117       nil
118     end
119   end
120
121   #
122   # tries to get the value of an inherited variable
123   #
124   def get_inherited_var(var_name, locale=I18n.locale)
125     if @page && @page.parent && @page.parent.props
126       @page.parent.props.get_var(var_name, locale)
127     end
128   end
129 end
130
131 #
132 # a simple little test.
133 #
134 if ARGV.grep('--test').any?
135   text_en = "
136 - @title = 'hi'
137 - @author = 'you'
138 - @created_at = 'Sun Aug 12 18:32:20 PDT 2012'
139 - ignored = 1
140 this is the body"
141
142   text_es = "
143 - @title = 'hola'
144 - @author = 'tu'
145 - @heading = textile 'h1. hi'
146 "
147
148   ps = PropertySet.new
149   ps.eval('en', text_en)
150   ps.eval('es', text_es)
151
152   p ps.title == 'hi'
153   p ps.locale(:es).title == 'hola'
154   p ps.locale(:es).created_at == Time.parse('Sun Aug 12 18:32:20 PDT 2012')
155   p ps.ignored == nil
156   p ps.locale(:es).heading == "<h1>hi</h1>"
157   p ps.body == "this is the body\n"
158 end