nitro 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. data/CHANGELOG +117 -0
  2. data/INSTALL +4 -0
  3. data/README +30 -31
  4. data/Rakefile +2 -2
  5. data/bin/nitro +10 -1
  6. data/bin/{new_app.rb → nitrogen} +12 -22
  7. data/doc/AUTHORS +4 -13
  8. data/doc/RELEASES +98 -0
  9. data/examples/ajax/run.rb +1 -3
  10. data/examples/blog/cache/entriesadmin +1 -1
  11. data/examples/blog/conf/locales/de.yml +4 -0
  12. data/examples/blog/conf/locales/en.yml +4 -0
  13. data/examples/blog/public/fcgi.rb +2 -3
  14. data/examples/blog/run.rb +10 -5
  15. data/examples/blog/src/controller.rb +21 -10
  16. data/examples/blog/src/mailer.rb +1 -1
  17. data/examples/blog/src/views/index.xhtml +2 -2
  18. data/examples/blog/src/xsl/style.xsl +6 -1
  19. data/examples/flash/run.rb +1 -3
  20. data/examples/no_xsl_blog/conf/locales/de.yml +4 -0
  21. data/examples/no_xsl_blog/conf/locales/en.yml +4 -0
  22. data/examples/no_xsl_blog/lib/blog/controller.rb +10 -0
  23. data/examples/no_xsl_blog/lib/blog/template.rb +4 -0
  24. data/examples/no_xsl_blog/public/fcgi.rb +2 -1
  25. data/examples/no_xsl_blog/public/index.xhtml +1 -1
  26. data/examples/no_xsl_blog/run.rb +8 -4
  27. data/examples/tiny/public/deep/dir/hello.xhtml +1 -0
  28. data/examples/tiny/public/fcgi.rb +2 -1
  29. data/examples/tiny/public/index.xhtml +5 -2
  30. data/examples/tiny/run.rb +1 -3
  31. data/examples/wee_style/run.rb +1 -3
  32. data/examples/why_wiki/run.rb +1 -3
  33. data/lib/nitro.rb +5 -2
  34. data/lib/nitro/builders/form.rb +8 -3
  35. data/lib/nitro/caching/stores.rb +3 -3
  36. data/lib/nitro/controller.rb +26 -6
  37. data/lib/nitro/dispatcher.rb +21 -13
  38. data/lib/nitro/environment.rb +23 -0
  39. data/lib/nitro/filters.rb +10 -8
  40. data/lib/nitro/localization.rb +127 -13
  41. data/lib/nitro/part.rb +24 -0
  42. data/lib/nitro/render.rb +19 -15
  43. data/lib/nitro/runner.rb +2 -1
  44. data/lib/nitro/scaffold.rb +69 -17
  45. data/lib/nitro/shaders.rb +54 -83
  46. data/lib/nitro/template.rb +7 -1
  47. data/proto/README +11 -0
  48. data/proto/conf/apache.conf +51 -0
  49. data/proto/conf/lhttpd.conf +107 -0
  50. data/proto/public/error.xhtml +56 -0
  51. data/proto/public/fcgi.rb +5 -0
  52. data/proto/public/index.xhtml +83 -0
  53. data/proto/public/js/ajax.js +63 -0
  54. data/proto/public/media/nitro.png +0 -0
  55. data/proto/run.rb +11 -0
  56. data/test/nitro/tc_controller.rb +1 -4
  57. data/test/nitro/tc_dispatcher.rb +8 -0
  58. data/test/nitro/tc_localization.rb +49 -0
  59. metadata +34 -6
  60. data/bin/new_form.rb +0 -54
@@ -86,11 +86,16 @@ class Controller
86
86
 
87
87
  cattr_accessor :action_metadata, {}
88
88
 
89
+ def initialize(context, base = nil)
90
+ super
91
+ self.class.template_root ||= "#{@context.dispatcher.template_root}#{base}"
92
+ end
93
+
89
94
  # Use the method_missing hook to compile the actions
90
95
  # for this controller.
91
96
 
92
97
  def method_missing(action, *args)
93
- if Rendering.compile_action(self.class, action, @template_root)
98
+ if Rendering.compile_action(self.class, action, self.class.template_root)
94
99
  send(action, *args)
95
100
  else
96
101
  super
@@ -101,11 +106,26 @@ class Controller
101
106
 
102
107
  alias __old_inherited inherited
103
108
 
104
- def inherited(subclass)
105
- subclass.class_eval %{
106
- DEF_FILE = caller[2].split(':')[-2]
107
- }
108
- __old_inherited(subclass)
109
+ #--
110
+ # gmosx, FIXME: the template_root hack is temporary.
111
+ # this should be moved to the render.
112
+ #++
113
+
114
+ def inherited(child)
115
+ child.class_eval %{
116
+ DEF_FILE = caller[2].to_s.strip.gsub( /:[0-9]+$/ , '')
117
+
118
+ @template_root = 'public'
119
+
120
+ def self.template_root
121
+ @template_root
122
+ end
123
+
124
+ def self.template_root=(root)
125
+ @template_root = root
126
+ end
127
+ }
128
+ __old_inherited(child)
109
129
  end
110
130
 
111
131
  # Define metadata for an action. This is a helper
@@ -133,36 +133,44 @@ class Dispatcher
133
133
  end
134
134
 
135
135
  parts = path.split('/')
136
+ parts.shift
136
137
 
137
138
  case parts.size
138
139
  when 0
139
140
  # / -> root.index
140
- # base = @template_root
141
+ base = '/'
141
142
  klass = controller_class_for(:root, context)
142
143
  action = 'index'
143
144
 
144
- when 2
145
- if klass = controller_class_for(parts[1], context)
145
+ when 1
146
+ if klass = controller_class_for(parts[0], context)
146
147
  # controller/ -> controller.index
147
- # base = "#{@template_root}/#{parts[1]}"
148
+ base = "/#{parts[0]}"
148
149
  action = 'index'
149
150
  else
150
151
  # action/ -> root.action
151
- # base = @template_root
152
+ base = '/'
152
153
  klass = controller_class_for(:root, context)
153
- action = parts[1]
154
+ action = parts[0]
154
155
  end
155
156
 
156
- when 3
157
- # controller/action/ -> controller.action
158
- # base = "#{@template_root}/#{parts[1]}"
159
- klass = controller_class_for(parts[1], context)
160
- action = parts[2]
157
+ else
158
+ if klass = controller_class_for(parts[0], context)
159
+ # controller/action -> controller.action
160
+ base = "/#{parts[0]}"
161
+ parts.shift
162
+ action = parts.join('__')
163
+ else
164
+ # action/ -> root.action
165
+ base = '/'
166
+ klass = controller_class_for(:root, context)
167
+ action = parts.join('__')
168
+ end
161
169
  end
162
-
170
+
163
171
  content_type = @apis[:api] || 'text/html'
164
172
 
165
- return klass, "__#{api}__#{action}", content_type
173
+ return klass, "__#{api}__#{action}", content_type, base
166
174
  end
167
175
  alias_method :split_path, :dispatch
168
176
 
@@ -0,0 +1,23 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: environment.rb 340 2005-04-04 08:26:58Z gmosx $
4
+
5
+ # Setup up the proposed environment. You are free
6
+ # to skip this if you dont like it. Just set
7
+ #
8
+ # $NITRO_NO_ENVIRONMENT = true
9
+ #
10
+ # before requiring nitro.
11
+ #--
12
+ # gmosx: this is temporary code.
13
+ #++
14
+
15
+ Dir.chdir(File.dirname($0))
16
+
17
+ # Application code come here.
18
+
19
+ $LOAD_PATH.unshift 'src'
20
+
21
+ # Library code come here.
22
+
23
+ $LOAD_PATH.unshift 'lib'
data/lib/nitro/filters.rb CHANGED
@@ -1,13 +1,14 @@
1
1
  # * George Moschovitis <gm@navel.gr>
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
- # $Id: filters.rb 326 2005-03-28 11:07:17Z gmosx $
3
+ # $Id: filters.rb 335 2005-03-31 14:02:02Z gmosx $
4
4
 
5
5
  module N
6
6
 
7
7
  # Filtering functionality for renders.
8
- # The design and implementation is HEAVILY influenced by Rails.
8
+ # The design and implementation is HEAVILY influenced
9
+ # by Rails.
9
10
  #
10
- # == Examples
11
+ # === Examples
11
12
  #
12
13
  # Filter as class:
13
14
  #
@@ -18,8 +19,9 @@ module N
18
19
  # before
19
20
  # filter
20
21
  # after
22
+ #
21
23
  #--
22
- # TODO: implement inheritable filters.
24
+ # TODO: rethink what happens with module filters.
23
25
  #++
24
26
 
25
27
  module Filtering
@@ -127,9 +129,9 @@ module Filtering
127
129
 
128
130
  alias :after_filter :append_after_filter
129
131
 
130
- # Install an arround Filter. A filter is a class that responds
131
- # to the before and after methods. Both methods are prepended to
132
- # the respective lists.
132
+ # Install an arround Filter. A filter is a class that
133
+ # responds to the before and after methods. Both methods
134
+ # are prepended to the respective lists.
133
135
 
134
136
  def prepend_arround_filter(*args)
135
137
  options = args.pop if args.last.is_a?(Hash)
@@ -200,7 +202,7 @@ module Filtering
200
202
  elsif filter.respond_to?('filter')
201
203
  code << "if #{filter}.filter(self) == false then return false end"
202
204
  else
203
- raise 'Valid filters are either a symbol, a string or a proc/method.'
205
+ raise 'Valid filters are either a Symbol, a String or a Proc/Method.'
204
206
  end
205
207
  end
206
208
 
@@ -2,41 +2,155 @@
2
2
  # (c) 2004-2005 Navel, all rights reserved.
3
3
  # $Id: l10n.rb 185 2004-12-10 13:29:09Z gmosx $
4
4
 
5
+ require 'yaml'
6
+
5
7
  require 'nitro/filters'
8
+ require 'nitro/shaders'
6
9
 
7
10
  module N
8
11
 
9
- # Localization support.
12
+ # Represents a locale.
10
13
  #--
11
- # TODO: use inflector to convert symbols to strings.
14
+ # TODO: initialize translation map from a yaml file.
12
15
  #++
13
16
 
14
- class Localization
17
+ class Locale
15
18
 
16
- # This map gives the correct localization hash
17
- # for the given locale.
19
+ # The localization map.
18
20
 
19
21
  attr_accessor :map
22
+
23
+ def initialize(map)
24
+ parse_hash(map)
25
+ end
26
+
27
+ # Transalte the given key.
28
+ #
29
+ # [+args+]
30
+ # An array of arguments. The first argument
31
+ # is the translation key. If additional arguments
32
+ # are provided they are used for sprintf
33
+ # interpolation.
34
+ #--
35
+ # THINK: Possibly avoid the creation of the
36
+ # array by making the api less elegant.
37
+ #++
38
+
39
+ def translate(*args)
40
+ if xlated = @map[args.shift]
41
+ if xlated.is_a?(String)
42
+ args.empty? ? xlated : sprintf(xlated, *args)
43
+ else
44
+ xlated.call(*args)
45
+ end
46
+ end
47
+ end
48
+ alias_method :[], :translate
20
49
 
21
- def initialize(map = {})
50
+ private
51
+
52
+ def parse_hash(map)
22
53
  @map = map
23
54
  end
24
55
 
25
- # Return the localization hash for the given
26
- # locale.
56
+ def parse_yaml(yaml)
57
+ raise 'Not implemented'
58
+ end
59
+
60
+ end
61
+
62
+ # Localization support.
63
+ #
64
+ # === Example
65
+ #
66
+ # locale_en = {
67
+ # 'See you' => 'See you',
68
+ # :long_paragraph => 'The best new books, up to 30% reduced price',
69
+ # :price => 'Price: %d %s',
70
+ # :proc_price => proc { |value, cur| "Price: #{value} #{cur}" }
71
+ # }
72
+ #
73
+ # locale_de = {
74
+ # 'See you' => 'Auf wieder sehen',
75
+ # :long_paragraph => 'Die besten neuer buecher, bis zu 30% reduziert',
76
+ # ...
77
+ # }
78
+ #
79
+ # Localization.add(:en => locale_en, :de => locale_de)
80
+ #
81
+ # lc = Localization.get
82
+ # lc['See you'] -> See you
83
+ # lc[:price, 100, 'euro'] -> Price: 100 euro
84
+ # lc = Localization.get[:de]
85
+ # lc['See you'] -> Auf wiedersehen
86
+ #
87
+ # To make localization even more easier, a LocalizationFilter
88
+ # and a LocalizationShader are provided.
89
+
90
+ class Localization
91
+
92
+ class << self
93
+
94
+ # A hash of the available locales.
95
+
96
+ attr_accessor :locales
97
+
98
+ def add(map = {})
99
+ for key, locale in map
100
+ if locale.is_a?(String)
101
+ # this is the name of the localization file.
102
+ locale = YAML.load(File.read(locale))
103
+ end
104
+ @locales[key.to_s] = Locale.new(locale)
105
+ end
106
+ end
107
+
108
+ # Return the localization hash for the given
109
+ # locale.
110
+
111
+ def get(locale = :en)
112
+ locale ||= 'en'
113
+ @locales[locale.to_s]
114
+ end
115
+ alias_method :locale, :get
116
+ alias_method :[], :get
27
117
 
28
- def get(locale = 'en')
29
- locale || = 'en'
30
- @map[locale]
31
118
  end
119
+
120
+ @locales = {}
121
+
32
122
  end
33
123
 
34
- # Localization filter
124
+ # Localization filter.
35
125
 
36
126
  module LocalizationFilter
37
127
  def localize
38
- @lc = @context.conf.lc.get(@session[:LC])
128
+ # @lc = @context.conf.localization[@session[:LOCALE]]
129
+ @lc = Localization[@context.session[:LOCALE]]
39
130
  end
40
131
  end
132
+
133
+ # Localization shader.
134
+ #
135
+ # === Examples
136
+ #
137
+ # <h1>[[Welcome]]</h1>
138
+ # <h1>[[:welcome]]</h1>
139
+
140
+ class LocalizationShader < Shader
41
141
 
142
+ def process(hash, text)
143
+ # handle symbols
144
+ text.gsub!(/\[\[\:(.*?)\]\]/, '#{@lc[\1]}')
145
+
146
+ # handle strings
147
+ text.gsub!(/\[\[(.*?)\]\]/, '#{@lc["\1"]}')
148
+
149
+ process_next(hash, text)
150
+ end
151
+
42
152
  end
153
+
154
+ end
155
+
156
+
data/lib/nitro/part.rb ADDED
@@ -0,0 +1,24 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: part.rb 339 2005-04-01 14:02:14Z gmosx $
4
+
5
+ # UNDER CONSTRUCTION, dont use yet!
6
+
7
+ require 'glue/attribute'
8
+
9
+ module N
10
+
11
+ class Part
12
+ cattr_accessor :parts_root, "/home/gmosx/navel/gen/parts"
13
+ end
14
+
15
+ end
16
+
17
+ module Kernel
18
+
19
+ def require_part(name)
20
+ require "#{N::Part.parts_root}/#{name}/part"
21
+ end
22
+
23
+ end
24
+
data/lib/nitro/render.rb CHANGED
@@ -56,17 +56,17 @@ module Rendering
56
56
  # attempt to find a template of the form
57
57
  # template_root/action.xhtml
58
58
 
59
- path = "#{template_root}/#{action}.#{ext}".squeeze('/')
60
-
59
+ path = "#{template_root}/#{action.gsub(/__/, '/')}.#{ext}".squeeze('/')
60
+
61
61
  unless File.exist?(path)
62
62
 
63
63
  # attempt to find a template of the form
64
64
  # template_root/action/index.xhtml
65
65
 
66
- path = "#{template_root}/#{action}/#{Rendering.default_template}.#{ext}".squeeze('/')
67
-
66
+ path = "#{template_root}/#{action.gsub(/__/, '/')}/#{Rendering.default_template}.#{ext}".squeeze('/')
67
+
68
68
  unless File.exist?(path)
69
- # No template founD!
69
+ # No template found!
70
70
  path = nil
71
71
  end
72
72
  end
@@ -89,7 +89,12 @@ module Rendering
89
89
 
90
90
  def self.compile_action(klass, action, template_root)
91
91
  @@sync.synchronize do
92
- dummy, api, action = action.to_s.split('__')
92
+ action = action.to_s.split('__')
93
+ action.shift
94
+ api = action.shift
95
+ action = action.join('__')
96
+
97
+ # dummy, api, action = action.to_s.split('__')
93
98
 
94
99
  # This is not a controller action.
95
100
 
@@ -173,7 +178,7 @@ module Rendering
173
178
  }
174
179
  end
175
180
 
176
- # puts '---', code, '---' if action.to_s == 'index'
181
+ # puts '---', code, '---'
177
182
 
178
183
  klass.class_eval(code)
179
184
  end
@@ -184,6 +189,10 @@ module Rendering
184
189
  end
185
190
 
186
191
  # The rendering mixin.
192
+ #--
193
+ # TODO: handle template_root here instead of the
194
+ # controller.
195
+ #++
187
196
 
188
197
  module Render
189
198
 
@@ -210,20 +219,15 @@ module Render
210
219
  # The name of the currently executing action.
211
220
 
212
221
  attr_accessor :action_name
213
-
214
- # The template root for this render.
215
-
216
- cattr_accessor :template_root
217
222
 
218
223
  # Initialize the render.
219
224
  #
220
225
  # [+context+]
221
226
  # A parent render/controller acts as the context.
222
227
 
223
- def initialize(context)
228
+ def initialize(context, base = nil)
224
229
  @request = @context = context
225
230
  @out = context.out
226
- @template_root = @context.dispatcher.template_root
227
231
  end
228
232
 
229
233
  # Renders the action denoted by path. The path
@@ -233,7 +237,7 @@ module Render
233
237
  def render(path)
234
238
  Logger.debug "Rendering '#{path}'." if $DBG
235
239
 
236
- klass, action, content_type = @context.dispatcher.dispatch(path, @context)
240
+ klass, action, content_type, base = @context.dispatcher.dispatch(path, @context)
237
241
 
238
242
  @context.content_type = content_type
239
243
 
@@ -242,7 +246,7 @@ module Render
242
246
  if self.class == klass
243
247
  self.send(action)
244
248
  else
245
- klass.new(self).send(action)
249
+ klass.new(self, base).send(action)
246
250
  end
247
251
 
248
252
  rescue RenderExit => e