nitro 0.8.0 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
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,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
4
+ require 'nitro/adaptors/runner'
@@ -0,0 +1,20 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id: blog.rb 223 2005-01-26 17:07:40Z gmosx $
4
+
5
+ # A simple blog to demonstrate the power of Nitro.
6
+
7
+ class Blog
8
+
9
+ # The administrator username.
10
+
11
+ cattr_accessor :username, 'George Moschovitis'
12
+
13
+ # The administrator password.
14
+
15
+ cattr_accessor :password, 'mypassword'
16
+
17
+ end
18
+
19
+ require 'blog/model'
20
+ require 'blog/controller'
@@ -0,0 +1,102 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ require 'nitro/controller'
6
+ require 'nitro/builders/rss'
7
+ require 'nitro/ui/pager'
8
+
9
+ require 'blog/model'
10
+ require 'blog/template'
11
+
12
+ # The controller of the Blog part.
13
+
14
+ class BlogController < N::Controller
15
+ include BlogTemplate
16
+
17
+ before_filter :get_errors
18
+ # after_filter :cache
19
+
20
+ scaffold BlogEntry, :name => 'entry', :index => true
21
+ scaffold Comment
22
+
23
+ def list_entry
24
+ @pager = UI::Pager.new('entries', context, 3)
25
+ @entries = BlogEntry.all("ORDER BY oid DESC #{@pager.sql_limit}")
26
+ @pager.set(BlogEntry.count)
27
+ end
28
+
29
+ def new_entry
30
+ entry = context.fill(BlogEntry.new)
31
+ entry.author = session[:username]
32
+
33
+ unless entry.valid?
34
+ session[:errors] = entry.errors
35
+ puts '***', @context.headers.inspect, @context.referer
36
+ redirect_referer '#new_entry'
37
+ end
38
+
39
+ entry.save!
40
+ end
41
+
42
+ # example of generated view
43
+
44
+ def list_entry__xml
45
+ @out << RssBuilder.render(@entries)
46
+ end
47
+
48
+ def new_comment
49
+ comment = context.fill(Comment.new)
50
+
51
+ unless comment.valid?
52
+ session[:errors] = comment.errors
53
+ redirect_referer '#new_comment'
54
+ end
55
+
56
+ comment.save!
57
+ end
58
+
59
+ # example of generated view
60
+
61
+ def list_comment__xml
62
+ @out << RssBuilder.render(@comments)
63
+ end
64
+
65
+ def login
66
+ if password = context['password']
67
+ if password == Blog.password
68
+ session[:owner] = true
69
+ session[:username] = Blog.username
70
+ redirect '/'
71
+ else
72
+ @error = 'Invalid password'
73
+ end
74
+ end
75
+ end
76
+
77
+ def logout
78
+ session.delete(:owner)
79
+ session.delete(:username)
80
+ end
81
+
82
+ private
83
+
84
+ # A helper prefilter, autocleans session errors.
85
+ # Used as an example.
86
+
87
+ def get_errors
88
+ # gmosx: should better implement top-level filters!
89
+ if errors = session.delete(:errors)
90
+ @errors = errors
91
+ end
92
+ end
93
+
94
+ # Just an example.
95
+
96
+ def cache
97
+ # Call the automatically configured logger.
98
+
99
+ Logger.info "cache (after filter example)"
100
+ end
101
+
102
+ end
@@ -0,0 +1,39 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ require 'parts/content'
6
+
7
+ # The models used in the Blog part.
8
+
9
+ # Forward reference to the Comment definition.
10
+
11
+ class Comment; end
12
+
13
+ # Common properties/methods for the other classes.
14
+ # Since markup is required, automatically handles
15
+ # the markup expanding/compacting for the body.
16
+
17
+ module Common
18
+ include N::BaseContent
19
+ include N::CreateTime
20
+
21
+ prop_accessor :author, String
22
+ validate_value :body
23
+ end
24
+
25
+ # An entry in the Blog.
26
+
27
+ class BlogEntry
28
+ include Common
29
+ has_many :comments, Comment, :linkback => 'entry_oid'
30
+ validate_value :title, :msg => 'Please provide a title'
31
+ end
32
+
33
+ # A comment to the blog entry.
34
+
35
+ class Comment
36
+ include Common
37
+ belongs_to :entry, BlogEntry
38
+ validate_value :author, :msg => 'Please enter your name'
39
+ end
@@ -0,0 +1,134 @@
1
+ # * George Moschovitis <gm@navel.gr>
2
+ # (c) 2004-2005 Navel, all rights reserved.
3
+ # $Id$
4
+
5
+ # A simple templating system. This demonstrates how
6
+ # easily you can replace the XSLT templating system
7
+ # with a custom implementation. Please note, that
8
+ # this templating system is considerably less
9
+ # efficient than XSLT. Moreover, not all features of
10
+ # the XSLT template are ported.
11
+
12
+ module BlogTemplate
13
+
14
+ def s_head
15
+ %{
16
+ <head>
17
+ <title>#{@context.conf.name}</title>
18
+ <meta name="title" content="Blog" />
19
+ <meta name="description" content="Example" />
20
+ <meta name="keywords" content="nitro, example, blog" />
21
+ <meta name="category" content="example" />
22
+ <meta name="robots" content="index, follow" />
23
+ <meta http-equiv="content-type" content="text/html; charset=utf8" />
24
+ <base href="#{@context.host_url}/" />
25
+ <link href="/style.css" rel="stylesheet" type="text/css" media="screen" />
26
+ <link rel="alternate" type="application/rss+xml" title="Latest Entries" href="#{@context.host_url}/xml/list_entry" />
27
+ <link rel="alternate" type="application/rss+xml" title="Latest Comments" href="#{@context.host_url}/xml/list_comment" />
28
+ }
29
+ end
30
+
31
+ def e_head
32
+ %{
33
+ </head>
34
+ }
35
+ end
36
+
37
+ def t_head
38
+ s_head + e_head
39
+ end
40
+
41
+ def t_header
42
+ %{
43
+ <div id="header">
44
+ <h1><a href="/">#{@context.conf.name}</a></h1>
45
+ </div>
46
+ }
47
+ end
48
+
49
+ def t_footer
50
+ %{
51
+ <div id="footer">
52
+ </div>
53
+ }
54
+ end
55
+
56
+ def t_rendering_errors
57
+ if @rendering_errors and (!@rendering_errors.empty?)
58
+ %{
59
+ <div id="rendering-errors">
60
+ <h3>RENDERING ERRORS:</h3>
61
+ #{@rendering_errors.join('<br />')}
62
+ </div>
63
+ }
64
+ end
65
+ end
66
+
67
+ def s_page
68
+ %{
69
+ <html>
70
+ #{t_head}
71
+ <body>
72
+
73
+ <div id="page">
74
+
75
+ #{t_header}
76
+
77
+ <div class="block main">
78
+ }
79
+ end
80
+
81
+ def e_page
82
+ %{
83
+ </div>
84
+
85
+ <div class="block side">
86
+ <h2>About</h2>
87
+ This is a simple blog powered by <a href="http://www.navel.gr/nitro">
88
+ Nitro</a> Web Engine. Have a look at the source code and enjoy
89
+ the power of Ruby.
90
+ <ruby>unless session['owner']</ruby>
91
+ <p><a href="login">Login</a> as owner.</p>
92
+ <ruby>else</ruby>
93
+ <p><a href="logout">Logout</a>.</p>
94
+ <ruby>end</ruby>
95
+
96
+ <h2>Linkage</h2>
97
+ <ul>
98
+ <li><a target="_new" href="http://www.navel.gr">Navel Ltd</a></li>
99
+ <li><a target="_new" href="http://www.navel.gr/nitro">Nitro Web Engine</a></li>
100
+ <li><a target="_new" href="http://www.ruby-lang.org">Ruby</a></li>
101
+ <li><a target="_new" href="http://www.blogger.com">Blogger</a></li>
102
+ <li><a target="_new" href="http://www.w3c.org">W3 Consortium</a></li>
103
+ </ul>
104
+
105
+ <br />
106
+ <ul class="rss">
107
+ <li><a href="xml/list_entry">Latest entries</a></li>
108
+ <li><a href="xml/list_comment">Latest comments</a></li>
109
+ </ul>
110
+
111
+ <br />
112
+ <p>
113
+ powered by:<br />
114
+ <div style="padding: 5px; background: #fff; text-align: center; border: 1px solid #ccc">
115
+ <a href="http://www.navel.gr/nitro"><img src="m/nitro.gif" style="border: none" /></a>
116
+ </div>
117
+ <br />
118
+ skin from <a href="http://www.blogger.com">Blogger.com</a>
119
+ </p>
120
+ </div>
121
+
122
+ <div class="clear">.</div>
123
+
124
+ #{t_footer}
125
+ </div>
126
+
127
+ #{t_rendering_errors}
128
+
129
+ </body>
130
+ </html>
131
+ }
132
+ end
133
+
134
+ end
@@ -0,0 +1,3 @@
1
+ = Logs
2
+
3
+ Various logs come here.
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <root xmlns:x="http://www.navel.gr/xml/shader.xsd">
4
+
5
+ <h2>#{@entry.comments_count} Comments:</h2>
6
+ <?r
7
+ if comments = @entry.comments
8
+ for comment in comments
9
+ ?>
10
+ <div class="comment">
11
+ #{comment.body}
12
+ <div class="footer">
13
+ by #{comment.author} at #{comment.create_time.strftime('%R %p')}
14
+ <?r if session[:owner] ?>
15
+ [<a href="del_comment?oid=#{comment.oid}">del</a>]
16
+ <?r end ?>
17
+ </div>
18
+ </div>
19
+ <?r
20
+ end
21
+ else
22
+ ?>
23
+ no comments.
24
+ <?r end ?>
25
+ <form id="new_comment" action="new_comment" method="post">
26
+ <input type="hidden" name="entry_oid" value="#{@entry.oid}" />
27
+ <p>
28
+ <b>Your name:</b><br />
29
+ <input type="text" name="author" value="#{session[:username]}" />
30
+ <x:error attr="author" />
31
+ <x:error attr="title" />
32
+ </p>
33
+ <p>
34
+ <b>Write your thoughts:</b><br />
35
+ <textarea name="body" style="width: 90%; height: 100px">#{}</textarea>
36
+ <x:error attr="body"><br /></x:error>
37
+ </p>
38
+ <input type="submit" value="Add comment" />
39
+ </form>
40
+
41
+ </root>
@@ -0,0 +1,22 @@
1
+ <?xml version="1.0"?>
2
+
3
+ <div id="comments" xmlns:x="http://www.navel.gr/xml/shader.xsd">
4
+
5
+ <?r errors = session[:errors] ?>
6
+
7
+ <h2>Post new entry:</h2>
8
+
9
+ <form id="new_entry" action="new_entry" method="post">
10
+ <p>
11
+ <b>Title:</b><br />
12
+ <input type="text" name="title" />
13
+ <x:error attr="title" />
14
+ </p>
15
+ <p>
16
+ <b>Body:</b><br />
17
+ <textarea name="body" style="width: 90%; height: 100px">#{}</textarea>
18
+ <x:error attr="body"><br /></x:error>
19
+ </p>
20
+ <input type="submit" value="Post" />
21
+ </form>
22
+ </div>
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'conf', 'app.conf.rb')
4
+ require 'nitro/adaptors/fastcgi'
5
+
6
+ N::FastCGI.start($conf)
@@ -0,0 +1,39 @@
1
+ <?xml version="1.0"?>
2
+
3
+ #{s_page}
4
+
5
+ <?r
6
+ if @entries
7
+ for entry in @entries
8
+ ?>
9
+ <div class="entry">
10
+ <h2 class="date">#{entry.create_time.strftime('%B %e, %G')}</h2>
11
+ <div class="post">
12
+ <h3 class="title">#{entry.title}</h3>
13
+ #{entry.body}
14
+ <div class="footer">
15
+ posted by #{entry.author} at <a href="view_entry?oid=#{entry.oid}">#{entry.create_time.strftime('%R %p')}</a> |
16
+ <a href="view_entry?oid=#{entry.oid}#comments">#{entry.comments_count} comments</a>.
17
+ <?r if session[:owner] ?>
18
+ [<a href="del_entry?oid=#{entry.oid}">del</a>]
19
+ <?r end ?>
20
+ </div>
21
+ </div>
22
+ </div>
23
+ <?r
24
+ end
25
+ else
26
+ ?>
27
+ no entries
28
+ <?r end ?>
29
+
30
+ <div class="pager">
31
+ #{@pager.navigation}
32
+ <div class="clear">.</div>
33
+ </div>
34
+
35
+ <?r if session[:owner] ?>
36
+ <render href="entry_form" />
37
+ <?r end ?>
38
+
39
+ #{e_page}
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0"?>
2
+
3
+ #{s_page}
4
+
5
+ <p>
6
+ Please login as an author by entering the blog password.
7
+ <br />
8
+ The password is: <b>#{Blog.password}</b>.
9
+ </p>
10
+
11
+ <div class="error">#@error</div>
12
+
13
+ <form action="login" method="post">
14
+ <p>
15
+ <b>Password:</b><br />
16
+ <input type="password" name="password" value="#{Blog.password}" />
17
+ </p>
18
+ <input type="submit" value="Login" />
19
+ </form>
20
+
21
+ #{e_page}