nitro 0.8.0 → 0.9.3

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 (198) hide show
  1. data/AUTHORS +3 -4
  2. data/ChangeLog +418 -0
  3. data/LICENSE +1 -1
  4. data/README +157 -89
  5. data/RELEASES +50 -0
  6. data/Rakefile +5 -7
  7. data/benchmark/nitro/bench.rb +5 -0
  8. data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
  9. data/benchmark/nitro/static-webrick-n-200.txt +43 -0
  10. data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
  11. data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
  12. data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
  13. data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
  14. data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
  15. data/bin/proto/README +2 -2
  16. data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
  17. data/bin/proto/conf/app.conf.rb +22 -0
  18. data/bin/proto/conf/lhttpd.conf +236 -0
  19. data/bin/proto/ctl +4 -0
  20. data/bin/proto/lib/README +5 -0
  21. data/bin/proto/log/README +3 -0
  22. data/bin/proto/root/fcgi.rb +6 -0
  23. data/bin/proto/root/index.xhtml +65 -7
  24. data/bin/proto/root/m/nitro.png +0 -0
  25. data/examples/blog/README +7 -5
  26. data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
  27. data/examples/blog/conf/app.conf.rb +56 -0
  28. data/examples/blog/conf/lhttpd.conf +236 -0
  29. data/examples/blog/ctl +4 -0
  30. data/examples/blog/lib/blog.rb +11 -136
  31. data/examples/blog/lib/blog/controller.rb +99 -0
  32. data/examples/blog/lib/blog/model.rb +39 -0
  33. data/examples/blog/log/README +3 -0
  34. data/examples/blog/root/comments.xhtml +2 -2
  35. data/examples/blog/root/fcgi.rb +6 -0
  36. data/examples/blog/root/index.xhtml +4 -5
  37. data/examples/blog/root/login.xhtml +2 -2
  38. data/examples/blog/root/style.xsl +9 -9
  39. data/examples/blog/root/view_entry.xhtml +2 -2
  40. data/examples/flash/conf/app.conf.rb +23 -0
  41. data/examples/flash/ctl +4 -0
  42. data/examples/flash/log/README +3 -0
  43. data/examples/flash/root/index.xhtml +0 -9
  44. data/examples/flash/root/show_inline_text.xhtml +10 -5
  45. data/examples/no_xsl_blog/README +12 -0
  46. data/examples/no_xsl_blog/conf/apache.conf +0 -0
  47. data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
  48. data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
  49. data/examples/no_xsl_blog/ctl +4 -0
  50. data/examples/no_xsl_blog/lib/blog.rb +20 -0
  51. data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
  52. data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
  53. data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
  54. data/examples/no_xsl_blog/log/README +3 -0
  55. data/examples/no_xsl_blog/root/comments.xhtml +41 -0
  56. data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
  57. data/examples/no_xsl_blog/root/fcgi.rb +6 -0
  58. data/examples/no_xsl_blog/root/index.xhtml +39 -0
  59. data/examples/no_xsl_blog/root/login.xhtml +21 -0
  60. data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
  61. data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
  62. data/examples/no_xsl_blog/root/m/down.gif +0 -0
  63. data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
  64. data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
  65. data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
  66. data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
  67. data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
  68. data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
  69. data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
  70. data/examples/no_xsl_blog/root/m/obull.gif +0 -0
  71. data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
  72. data/examples/no_xsl_blog/root/m/rss.gif +0 -0
  73. data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
  74. data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
  75. data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
  76. data/examples/no_xsl_blog/root/style.css +301 -0
  77. data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
  78. data/examples/no_xsl_blog/root/view_entry.xml +12 -0
  79. data/examples/og/run.rb +2 -2
  80. data/examples/tiny/README +2 -2
  81. data/examples/tiny/conf/apache.conf +5 -0
  82. data/examples/tiny/conf/app.conf.rb +21 -0
  83. data/examples/tiny/conf/lhttpd.conf +236 -0
  84. data/examples/tiny/ctl +4 -0
  85. data/examples/tiny/log/README +3 -0
  86. data/examples/tiny/root/fcgi.rb +6 -0
  87. data/examples/tiny/root/index.xhtml +7 -4
  88. data/examples/tiny/root/nitro.png +0 -0
  89. data/lib/glue.rb +13 -9
  90. data/lib/glue/array.rb +1 -1
  91. data/lib/glue/cache.rb +1 -1
  92. data/lib/glue/flexob.rb +12 -0
  93. data/lib/glue/hash.rb +1 -1
  94. data/lib/glue/inflector.rb +2 -2
  95. data/lib/glue/logger.rb +4 -8
  96. data/lib/glue/misc.rb +14 -0
  97. data/lib/glue/number.rb +1 -1
  98. data/lib/glue/object.rb +26 -0
  99. data/lib/glue/pool.rb +1 -1
  100. data/lib/glue/property.rb +84 -91
  101. data/lib/glue/string.rb +1 -1
  102. data/lib/glue/time.rb +1 -1
  103. data/lib/glue/validation.rb +1 -1
  104. data/lib/nitro.rb +18 -6
  105. data/lib/nitro/adaptors/cgi.rb +291 -0
  106. data/lib/nitro/adaptors/fastcgi.rb +42 -0
  107. data/lib/nitro/adaptors/runner.rb +123 -0
  108. data/lib/nitro/adaptors/webrick.rb +110 -0
  109. data/lib/nitro/buffering.rb +43 -0
  110. data/lib/nitro/builders/form.rb +1 -1
  111. data/lib/nitro/builders/rss.rb +1 -1
  112. data/{bin → lib/nitro}/cluster.rb +26 -30
  113. data/lib/nitro/context.rb +82 -0
  114. data/lib/nitro/controller.rb +50 -0
  115. data/lib/nitro/cookie.rb +46 -0
  116. data/lib/nitro/dispatcher.rb +105 -0
  117. data/lib/nitro/filters.rb +9 -10
  118. data/lib/nitro/localization.rb +42 -0
  119. data/lib/nitro/mail.rb +11 -14
  120. data/lib/nitro/render.rb +275 -0
  121. data/lib/nitro/request.rb +128 -0
  122. data/lib/nitro/response.rb +38 -0
  123. data/lib/nitro/scaffold.rb +11 -11
  124. data/lib/nitro/session.rb +84 -0
  125. data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
  126. data/lib/nitro/ui/pager.rb +23 -26
  127. data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
  128. data/lib/nitro/uri.rb +1 -1
  129. data/lib/nitro/version.rb +10 -8
  130. data/lib/og.rb +66 -65
  131. data/lib/og/backend.rb +1 -1
  132. data/lib/og/backends/mysql.rb +48 -52
  133. data/lib/og/backends/psql.rb +34 -37
  134. data/lib/og/connection.rb +15 -15
  135. data/lib/og/enchant.rb +16 -9
  136. data/lib/og/meta.rb +127 -54
  137. data/lib/og/mock.rb +18 -18
  138. data/lib/og/version.rb +6 -4
  139. data/lib/parts/content.rb +4 -8
  140. data/test/glue/tc_logger.rb +3 -0
  141. data/test/glue/tc_property.rb +19 -3
  142. data/test/nitro/adaptors/tc_cgi.rb +63 -0
  143. data/test/nitro/adaptors/tc_webrick.rb +15 -0
  144. data/test/nitro/builders/tc_xml.rb +2 -2
  145. data/test/nitro/tc_context.rb +13 -0
  146. data/test/nitro/tc_controller.rb +47 -0
  147. data/test/nitro/tc_dispatcher.rb +64 -0
  148. data/test/nitro/tc_session.rb +20 -0
  149. data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
  150. data/test/root/blog/list.xhtml +6 -0
  151. data/test/tc_og.rb +41 -4
  152. metadata +115 -59
  153. data/bin/proto/app.rb +0 -20
  154. data/bin/proto/config.rb +0 -77
  155. data/examples/blog/app.rb +0 -21
  156. data/examples/blog/config.rb +0 -95
  157. data/examples/blog/env.rb +0 -22
  158. data/examples/flash/README +0 -34
  159. data/examples/flash/app.rb +0 -20
  160. data/examples/flash/config.rb +0 -38
  161. data/examples/flash/lib/flash.rb +0 -40
  162. data/examples/flash/tmp.swf +0 -0
  163. data/examples/tiny/app.rb +0 -19
  164. data/examples/tiny/config.rb +0 -29
  165. data/examples/tiny/root/nitro-small.png +0 -0
  166. data/lib/nitro/application.rb +0 -217
  167. data/lib/nitro/config.rb +0 -128
  168. data/lib/nitro/events.rb +0 -122
  169. data/lib/nitro/html.rb +0 -151
  170. data/lib/nitro/http.rb +0 -102
  171. data/lib/nitro/l10n.rb +0 -30
  172. data/lib/nitro/server.rb +0 -59
  173. data/lib/nitro/server/appserver.rb +0 -67
  174. data/lib/nitro/server/cookie.rb +0 -87
  175. data/lib/nitro/server/dispatcher.rb +0 -62
  176. data/lib/nitro/server/filters.rb +0 -75
  177. data/lib/nitro/server/filters/autologin.rb +0 -51
  178. data/lib/nitro/server/fragment.rb +0 -70
  179. data/lib/nitro/server/handlers.rb +0 -127
  180. data/lib/nitro/server/render.rb +0 -426
  181. data/lib/nitro/server/request.rb +0 -658
  182. data/lib/nitro/server/requestpart.rb +0 -54
  183. data/lib/nitro/server/script.rb +0 -387
  184. data/lib/nitro/server/server.rb +0 -57
  185. data/lib/nitro/server/session.rb +0 -220
  186. data/lib/nitro/server/user.rb +0 -46
  187. data/lib/nitro/server/webrick.rb +0 -180
  188. data/lib/nitro/service.rb +0 -26
  189. data/lib/xsl/ui.xsl +0 -51
  190. data/lib/xsl/xforms.xsl +0 -28
  191. data/test/nitro/server/tc_cookie.rb +0 -34
  192. data/test/nitro/server/tc_filters.rb +0 -38
  193. data/test/nitro/server/tc_request.rb +0 -70
  194. data/test/nitro/server/tc_requestpart.rb +0 -28
  195. data/test/nitro/server/tc_session.rb +0 -34
  196. data/test/nitro/tc_events.rb +0 -44
  197. data/test/nitro/tc_html.rb +0 -79
  198. data/test/nitro/tc_http.rb +0 -18
@@ -0,0 +1,128 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: nitro.rb 167 2004-11-23 14:03:10Z gmosx $
4
+
5
+ module N
6
+
7
+ # Encapsulates a request. This is an abstract request
8
+ # typically extended by sub-classes.
9
+
10
+ module Request
11
+
12
+ # The request input stream.
13
+
14
+ attr_accessor :in
15
+
16
+ # The request headers collection. Also called
17
+ # the request environment (env).
18
+
19
+ attr_accessor :headers
20
+ alias_method :env, :headers
21
+ alias_method :env=, :headers=
22
+ # for compatibility with cgi.rb
23
+ alias_method :env_table, :headers
24
+
25
+ # The parsed query parameters collection.
26
+
27
+ attr_accessor :params
28
+ alias_method :query, :params
29
+
30
+ # The request cookies.
31
+
32
+ attr_accessor :cookies
33
+
34
+ # The request protocol.
35
+
36
+ def protocol
37
+ 443 == port ? 'https://' : 'http://'
38
+ end
39
+
40
+ # Is this an ssl request?
41
+
42
+ def ssl?
43
+ 443 == port
44
+ end
45
+
46
+ # The request uri.
47
+
48
+ def uri
49
+ @headers['REQUEST_URI']
50
+ end
51
+
52
+ # The path is the uri without the query string.
53
+
54
+ def path
55
+ uri ? uri.split('?').first : ''
56
+ end
57
+
58
+ # The request query string.
59
+
60
+ def query_string
61
+ @headers['QUERY_STRING']
62
+ end
63
+
64
+ # The request method.
65
+
66
+ def method
67
+ @headers['REQUEST_METHOD'].downcase.intern
68
+ end
69
+
70
+ # Return the referer. For the initial page in the
71
+ # clickstream there is no referer, set "/" by default.
72
+
73
+ def referer
74
+ return @headers['REFERER'] || '/'
75
+ end
76
+
77
+ # The remote IP address. REMOTE_ADDR is the standard
78
+ # but will fail if the user is behind a proxy.
79
+ # HTTP_CLIENT_IP and/or HTTP_X_FORWARDED_FOR are set by
80
+ # proxies so check for these before falling back to
81
+ # REMOTE_ADDR. HTTP_X_FORWARDED_FOR may be a comma-delimited
82
+ # list in the case of multiple chained proxies; the first
83
+ # is the originating IP.
84
+
85
+ def remote_ip
86
+ return @headers['HTTP_CLIENT_IP'] if @headers.include?('HTTP_CLIENT_IP')
87
+
88
+ if @headers.include?('HTTP_X_FORWARDED_FOR') then
89
+ remote_ips = @headers['HTTP_X_FORWARDED_FOR'].split(',').reject do |ip|
90
+ ip =~ /^unknown$|^(10|172\.16|192\.168)\./i
91
+ end
92
+
93
+ return remote_ips.first.strip unless remote_ips.empty?
94
+ end
95
+
96
+ return @headers['REMOTE_ADDR']
97
+ end
98
+
99
+ # The server port.
100
+
101
+ def port
102
+ @headers['SERVER_PORT'].to_i
103
+ end
104
+
105
+ # The server host name.
106
+
107
+ def host
108
+ @headers['HTTP_HOST']
109
+ end
110
+
111
+ def host_url
112
+ "http://#{host}"
113
+ end
114
+
115
+ # Lookup a query parameter.
116
+
117
+ def [](param)
118
+ @params[param]
119
+ end
120
+
121
+ # Set a query parameter.
122
+
123
+ def []=(param, value)
124
+ @params[param] = value
125
+ end
126
+ end
127
+
128
+ end
@@ -0,0 +1,38 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: nitro.rb 167 2004-11-23 14:03:10Z gmosx $
4
+
5
+ module N
6
+
7
+ # HTTP Response.
8
+
9
+ module Response
10
+
11
+ # The Response status.
12
+
13
+ attr_accessor :status
14
+
15
+ # The Response headers.
16
+
17
+ attr_accessor :response_headers
18
+
19
+ # The Response cookies.
20
+
21
+ attr_accessor :response_cookies
22
+
23
+ def content_type=(ctype)
24
+ @response_headers['Content-Type'] = ctype
25
+ end
26
+
27
+ # Add a cookie to the response. Better use this
28
+ # method to avoid precreating the cookies array
29
+ # for every request.
30
+
31
+ def add_cookie(cookie)
32
+ (@response_cookies ||= []) << cookie
33
+ end
34
+ alias_method :send_cookie, :add_cookie
35
+
36
+ end
37
+
38
+ end
@@ -1,8 +1,6 @@
1
- # code:
2
1
  # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: scaffold.rb 175 2004-11-26 16:11:27Z gmosx $
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: scaffold.rb 248 2005-01-31 13:38:34Z gmosx $
6
4
 
7
5
  require 'glue/inflector'
8
6
 
@@ -10,18 +8,19 @@ module N
10
8
 
11
9
  module Scaffolding
12
10
 
13
- # Ruby is sometimes VERY surprising, the following trick is needed
14
- # to include singleton methods in other classes.
15
- #
11
+ # Ruby is sometimes VERY surprising, the following trick is
12
+ # needed to include singleton methods in other classes.
13
+
16
14
  def self.append_features(base)
17
15
  super
18
16
  base.extend(SingletonMethods)
19
17
  end
20
18
 
21
19
  module SingletonMethods
20
+
22
21
  # Enchant the caller with a number of default methods.
23
22
  # Override the automatically generated methods as needed.
24
- #
23
+
25
24
  def scaffold(klass, options = {})
26
25
 
27
26
  oid = options[:oid] || 'oid'
@@ -54,19 +53,20 @@ module Scaffolding
54
53
  module_eval <<-"end_eval", __FILE__, __LINE__
55
54
 
56
55
  # TODO: add pager support here!
56
+
57
57
  def list#{suffix}
58
58
  @#{list_name} = #{klass}.all('ORDER BY oid')
59
59
  end
60
60
 
61
61
  def view#{suffix}
62
- @#{name} = #{klass}[@params['#{oid}']]
62
+ @#{name} = #{klass}[@context['#{oid}']]
63
63
  end
64
64
 
65
65
  def save#{suffix}
66
66
  end
67
67
 
68
68
  def del#{suffix}
69
- #{klass}.delete(@params['#{oid}'])
69
+ #{klass}.delete(@context['#{oid}'])
70
70
  end
71
71
  alias_method :delete#{suffix}, :del#{suffix}
72
72
 
@@ -77,4 +77,4 @@ module Scaffolding
77
77
 
78
78
  end
79
79
 
80
- end # module
80
+ end
@@ -0,0 +1,84 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ require 'md5'
6
+ require 'webrick'
7
+
8
+ require 'glue/attribute'
9
+
10
+ require 'nitro/cookie'
11
+
12
+ module N
13
+
14
+ # A web application session.
15
+ #
16
+ # State is a neccessary evil but session variables should
17
+ # be avoided as much as possible. Session state is typically
18
+ # distributed to many servers so avoid storing complete
19
+ # objects in session variables, only store oids and small
20
+ # integer/strings.
21
+ #
22
+ # The session should be persistable to survive server
23
+ # shutdowns.
24
+
25
+ class Session < Hash
26
+
27
+ # Session id salt.
28
+
29
+ cattr_accessor :session_id_salt, 'SALT'
30
+
31
+ # The name of the cookie that stores the session id.
32
+
33
+ cattr_accessor :cookie_name, 'nsid'
34
+
35
+ # The sessions
36
+
37
+ cattr_accessor :manager; @@manager = {}
38
+
39
+ # The unique id of this session.
40
+
41
+ attr_reader :session_id
42
+
43
+ def self.lookup(context)
44
+ if cookie = context.cookies[Session.cookie_name]
45
+ session = context.sessions[cookie]
46
+ end
47
+
48
+ unless session
49
+ session = Session.new(context)
50
+ context.add_cookie(Cookie.new(Session.cookie_name, session.session_id))
51
+ context.sessions[session.session_id] = session
52
+ end
53
+
54
+ return session
55
+ end
56
+
57
+ # Create the session for the given context.
58
+
59
+ def initialize(context = nil)
60
+ @session_id = create_id
61
+ end
62
+
63
+ protected
64
+
65
+ # Calculates a unique id.
66
+ #
67
+ # The session id must be unique, a monotonically
68
+ # increasing function like time is appropriate. Random
69
+ # may produce equal ids? add a prefix (SALT) to stop
70
+ # hackers from creating session_ids.
71
+
72
+ def create_id
73
+ now = Time.now
74
+ md5 = Digest::MD5.new
75
+ md5.update(now.to_s)
76
+ md5.update(now.usec.to_s)
77
+ md5.update(rand(0).to_s)
78
+ md5.update(Session.session_id_salt)
79
+ md5.hexdigest
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -1,25 +1,25 @@
1
- # code:
2
- # * George Moschovitis <gm@navel.gr>
3
- #
4
- # (c) 2004 Navel, all rights reserved.
5
- # $Id: shaders.rb 189 2004-12-13 21:38:05Z gmosx $
1
+ #--
2
+ # George Moschovitis <gm@navel.gr>
3
+ # (c) 2004-2005 Navel, all rights reserved.
4
+ # $Id: shaders.rb 202 2005-01-17 10:44:13Z gmosx $
5
+ #++
6
6
 
7
7
  module N
8
8
 
9
- # = Shader
10
- #
11
- # The equivalent of a 3d engine shader. In essence it defines a
12
- # transformation-pipeline that tansforms the .xhtml files to actual
13
- # ruby code ready for evaluation (compilation) by the engine.
9
+ # A shader defines a transformation-pipeline that tansforms
10
+ # the .xhtml files to actual ruby code ready for evaluation
11
+ # (compilation) by the engine.
14
12
  #
15
13
  # Shaders are equivalend to the render-pipeline filters, ie they
16
14
  # share their folded-filter design.
17
15
  #--
18
16
  # TODO: pipeline stage mixin to be reused in filters too.
19
17
  #++
20
- #
18
+
21
19
  class Shader
20
+
22
21
  # the next stage in the Shader pipeline.
22
+
23
23
  attr :next_stage
24
24
 
25
25
  def initialize(next_stage = nil)
@@ -29,20 +29,20 @@ class Shader
29
29
  # Process the text and optionally update the hash.
30
30
  # The hash is a short, unique representation of the input text,
31
31
  # typically used as a caching key.
32
- #
32
+
33
33
  def process(hash, text)
34
34
  process_next(hash, text)
35
35
  end
36
36
 
37
37
  # Set the next stage of the pipeline.
38
- #
38
+
39
39
  def << (next_stage = nil)
40
40
  @next_stage = next_stage
41
41
  return self
42
42
  end
43
43
 
44
44
  # Process the next stage of the pipeline.
45
- #
45
+
46
46
  def process_next(hash, text)
47
47
  if @next_stage
48
48
  return @next_stage.process(hash, text)
@@ -52,12 +52,10 @@ class Shader
52
52
  end
53
53
  end
54
54
 
55
- # = RubyShader
56
- #
57
55
  # Convert the xhtml script to actual Ruby code, ready to be
58
56
  # evaluated.
59
- #
60
- class RubyShader < N::Shader
57
+
58
+ class RubyShader < Shader
61
59
 
62
60
  # Convert the xhtml script to actual Ruby code, ready to be
63
61
  # evaluated.
@@ -66,19 +64,19 @@ class RubyShader < N::Shader
66
64
  # Investigate:
67
65
  # perhaps xl:href should be used to be XLink compatible?
68
66
  #++
69
- #
67
+
70
68
  def process(hash, text)
71
69
  # strip the xml header! (interracts with the following gsub!)
72
70
  text.gsub!(/<\?xml.*\?>/, "")
73
71
 
74
- # statically include sub script files.
72
+ # Statically include sub script files.
75
73
  # The target file is included at compile time.
76
74
  #
77
75
  # gmosx: must be xformed before the <?r pi.
78
76
  #
79
77
  # Example:
80
78
  # <?include xl:href="root/myfile.sx" ?>
81
- #
79
+
82
80
  text.gsub!(/<\?include href="(.*?)"(.*)\?>/) { |match|
83
81
  # gmosx: xmm match matches the whole string.
84
82
  # match = overload_path($1)
@@ -87,23 +85,41 @@ class RubyShader < N::Shader
87
85
 
88
86
  # xform include instructions <include href="xxx" />
89
87
  # must be transformed before the processinc instructions.
88
+ # Useful to include fragments cached on disk
89
+ #
90
+ # gmosx, FIXME: NOT TESTED! test and add caching.
91
+ # add load_statically_included fixes.
92
+
90
93
  text.gsub!(/<include href="(.*?)"(.*)(.?)\/>/) { |match|
94
+ "<?r File.read( '\#\{@dispatcher.root\}/#$1' ?>"
95
+ }
96
+
97
+ # xform render/inject instructions <render href="xxx" />
98
+ # must be transformed before the processinc instructions.
99
+
100
+ text.gsub!(/<inject href="(.*?)"(.*)(.?)\/>/) { |match|
101
+ "<?r render '/#$1' ?>"
102
+ }
103
+
104
+ text.gsub!(/<render href="(.*?)"(.*)(.?)\/>/) { |match|
91
105
  "<?r render '/#$1' ?>"
92
106
  }
93
107
 
94
108
  # remove <root> elements. typically removed by xslt but lets
95
109
  # play it safe.
110
+
96
111
  text.gsub!(/<(\/)?root>/, '')
97
112
 
98
113
  # runtime ruby code.
99
114
 
100
115
  # xform the processing instructions, use <?r as
101
116
  # a marker.
117
+
102
118
  text.gsub!(/\?>/, "\n@out << %^")
103
119
  text.gsub!(/<\?r(\s?)/, "^\n")
104
120
 
105
121
  # xform alternative code tags (very useful in xsl stylesheets)
106
- #
122
+
107
123
  text.gsub!(/<\/ruby>/, "\n@out << %^")
108
124
  text.gsub!(/<ruby>/, "^\n")
109
125
 
@@ -120,7 +136,7 @@ class RubyShader < N::Shader
120
136
  end
121
137
 
122
138
  # Loads and statically includes a file.
123
- #
139
+
124
140
  def load_statically_included(filename)
125
141
  Logger.debug "Statically including '#{filename}'" if $DBG
126
142
 
@@ -134,20 +150,26 @@ class RubyShader < N::Shader
134
150
 
135
151
  end
136
152
 
137
- # = XSLTShader
138
- #
139
153
  # Apply an XSL transformation to the script code.
140
154
  # There is no need to keep post xsl. I can reuse the same xsl
141
155
  # by calling transform again.
142
- #
143
- class XSLTShader < N::Shader
156
+
157
+ class XSLTShader < Shader
158
+
144
159
  # The name
160
+
145
161
  attr :name
162
+
146
163
  # The xslt filename.
164
+
147
165
  attr :xsl_filename
166
+
148
167
  # The xslt transformer.
168
+
149
169
  attr :xslt
170
+
150
171
  # Last modified time of the xslt.
172
+
151
173
  attr :mtime
152
174
 
153
175
  def initialize(xsl_filename, next_stage = nil)
@@ -161,8 +183,8 @@ class XSLTShader < N::Shader
161
183
  @next_stage = next_stage
162
184
  end
163
185
 
164
- # Transform the given text
165
- #
186
+ # Transform the given text.
187
+
166
188
  def process(hash, text)
167
189
  parse_xsl()
168
190
  @xslt.xml = text
@@ -174,7 +196,7 @@ class XSLTShader < N::Shader
174
196
  private
175
197
 
176
198
  # Parse the xsl.
177
- #
199
+
178
200
  def parse_xsl
179
201
  Logger.debug "Parsing xsl '#{@xsl_filename}'" if $DBG
180
202
  @mtime = File.mtime(@xsl_filename)
@@ -183,14 +205,12 @@ class XSLTShader < N::Shader
183
205
 
184
206
  end
185
207
 
186
- # = CompressShader
187
- #
188
208
  # Compress the inline xhtml. Does not touch the ruby code.
189
- #
190
- class CompressShader < N::Shader
209
+
210
+ class CompressShader < Shader
191
211
 
192
212
  # Compress the inline xhtml. Does not touch the ruby code.
193
- #
213
+
194
214
  def process(hash, text)
195
215
  text.gsub!(/\@out \<\< \%\^(.*?)\^/m) do |match|
196
216
  c = $1.gsub(/^(\s*)/m, '').squeeze(" \t").tr("\n", '').tr("\t", ' ')
@@ -202,5 +222,5 @@ class CompressShader < N::Shader
202
222
 
203
223
  end
204
224
 
205
- end # module
225
+ end
206
226