ramaze 2011.07.25 → 2011.10.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. data/.gitignore +3 -0
  2. data/.mailmap +3 -2
  3. data/.travis.yml +17 -0
  4. data/.yardopts +13 -0
  5. data/README.md +95 -352
  6. data/examples/app/blog/app.rb +25 -64
  7. data/examples/app/blog/config.ru +11 -9
  8. data/examples/app/blog/controller/init.rb +29 -86
  9. data/examples/app/blog/controller/posts.rb +232 -0
  10. data/examples/app/blog/controller/users.rb +160 -0
  11. data/examples/app/blog/layout/default.xhtml +61 -0
  12. data/examples/app/blog/migrations/01_create_schema.rb +50 -0
  13. data/examples/app/blog/model/comment.rb +41 -54
  14. data/examples/app/blog/model/init.rb +41 -13
  15. data/examples/app/blog/model/post.rb +35 -0
  16. data/examples/app/blog/model/user.rb +105 -0
  17. data/examples/app/blog/public/.htaccess +24 -0
  18. data/examples/app/blog/public/css/grid.css +107 -0
  19. data/examples/app/blog/public/css/layout.css +203 -0
  20. data/examples/app/blog/public/css/reset.css +123 -0
  21. data/examples/app/blog/public/css/text.css +109 -0
  22. data/examples/app/blog/public/dispatch.fcgi +11 -0
  23. data/examples/app/blog/public/favicon.ico +0 -0
  24. data/examples/app/blog/public/images/bg.png +0 -0
  25. data/examples/app/blog/start.rb +18 -3
  26. data/examples/app/blog/view/feed.xhtml +23 -0
  27. data/examples/app/blog/view/form.xhtml +11 -0
  28. data/examples/app/blog/view/index.xhtml +44 -0
  29. data/examples/app/blog/view/users/form.xhtml +12 -0
  30. data/examples/app/blog/view/users/index.xhtml +30 -0
  31. data/examples/app/blog/view/users/login.xhtml +8 -0
  32. data/examples/app/blog/view/view.xhtml +68 -0
  33. data/{doc → guide}/AUTHORS +5 -3
  34. data/{doc → guide}/CHANGELOG +428 -0
  35. data/{doc/GPL → guide/GPL_LICENSE} +0 -0
  36. data/{doc/COPYING → guide/RUBY_LICENSE} +3 -6
  37. data/guide/_static/logo.png +0 -0
  38. data/guide/_static/logo.svg +49 -0
  39. data/guide/_static/ramaze_console.png +0 -0
  40. data/guide/css/common.css +20 -0
  41. data/guide/general/cache.md +167 -0
  42. data/guide/general/configuration.md +168 -0
  43. data/guide/general/contributing.md +108 -0
  44. data/guide/general/controllers.md +115 -0
  45. data/guide/general/helpers.md +76 -0
  46. data/guide/general/installation.md +58 -0
  47. data/guide/general/logging.md +99 -0
  48. data/guide/general/middlewares.md +100 -0
  49. data/guide/general/models.md +78 -0
  50. data/guide/general/principles.md +53 -0
  51. data/guide/general/ramaze_command.md +155 -0
  52. data/guide/general/routes.md +81 -0
  53. data/guide/general/sessions.md +140 -0
  54. data/guide/general/special_thanks.md +67 -0
  55. data/guide/general/testing.md +61 -0
  56. data/guide/general/views.md +322 -0
  57. data/guide/tutorials/introduction.md +259 -0
  58. data/lib/proto/config.ru +1 -1
  59. data/lib/proto/public/favicon.ico +0 -0
  60. data/lib/proto/view/index.xhtml +7 -7
  61. data/lib/ramaze.rb +4 -4
  62. data/lib/ramaze/app.rb +11 -11
  63. data/lib/ramaze/app_graph.rb +2 -4
  64. data/lib/ramaze/bin/console.rb +3 -3
  65. data/lib/ramaze/bin/create.rb +2 -2
  66. data/lib/ramaze/bin/restart.rb +4 -4
  67. data/lib/ramaze/bin/runner.rb +5 -5
  68. data/lib/ramaze/bin/start.rb +19 -4
  69. data/lib/ramaze/bin/status.rb +3 -3
  70. data/lib/ramaze/bin/stop.rb +3 -3
  71. data/lib/ramaze/cache.rb +1 -0
  72. data/lib/ramaze/cache/lru.rb +8 -4
  73. data/lib/ramaze/cache/memcache.rb +32 -13
  74. data/lib/ramaze/cache/redis.rb +164 -0
  75. data/lib/ramaze/cache/sequel.rb +43 -28
  76. data/lib/ramaze/controller.rb +1 -2
  77. data/lib/ramaze/dependencies.rb +40 -3
  78. data/lib/ramaze/helper/bench.rb +26 -16
  79. data/lib/ramaze/helper/blue_form.rb +46 -73
  80. data/lib/ramaze/helper/cache.rb +10 -6
  81. data/lib/ramaze/helper/csrf.rb +35 -39
  82. data/lib/ramaze/helper/disqus.rb +5 -4
  83. data/lib/ramaze/helper/email.rb +35 -24
  84. data/lib/ramaze/helper/erector.rb +9 -13
  85. data/lib/ramaze/helper/flash.rb +7 -9
  86. data/lib/ramaze/helper/formatting.rb +194 -179
  87. data/lib/ramaze/helper/gravatar.rb +4 -8
  88. data/lib/ramaze/helper/identity.rb +3 -3
  89. data/lib/ramaze/helper/layout.rb +23 -8
  90. data/lib/ramaze/helper/markaby.rb +1 -1
  91. data/lib/ramaze/helper/paginate.rb +46 -39
  92. data/lib/ramaze/helper/request_accessor.rb +3 -1
  93. data/lib/ramaze/helper/simple_captcha.rb +18 -17
  94. data/lib/ramaze/helper/stack.rb +1 -1
  95. data/lib/ramaze/helper/tagz.rb +4 -2
  96. data/lib/ramaze/helper/upload.rb +523 -0
  97. data/lib/ramaze/helper/user.rb +4 -8
  98. data/lib/ramaze/helper/xhtml.rb +11 -15
  99. data/lib/ramaze/log.rb +9 -6
  100. data/lib/ramaze/log/rotatinginformer.rb +62 -27
  101. data/lib/ramaze/log/syslog.rb +20 -15
  102. data/lib/ramaze/log/xosd.rb +2 -1
  103. data/lib/ramaze/reloader.rb +2 -0
  104. data/lib/ramaze/request.rb +11 -10
  105. data/lib/ramaze/setup.rb +23 -6
  106. data/lib/ramaze/snippets/array/put_within.rb +3 -9
  107. data/lib/ramaze/snippets/binding/locals.rb +5 -10
  108. data/lib/ramaze/snippets/fiber.rb +1 -23
  109. data/lib/ramaze/snippets/kernel/pretty_inspect.rb +3 -6
  110. data/lib/ramaze/snippets/numeric/filesize_format.rb +3 -5
  111. data/lib/ramaze/snippets/numeric/time.rb +3 -7
  112. data/lib/ramaze/snippets/object/__dir__.rb +3 -7
  113. data/lib/ramaze/snippets/object/instance_variable_defined.rb +3 -6
  114. data/lib/ramaze/snippets/object/pretty.rb +3 -7
  115. data/lib/ramaze/snippets/object/scope.rb +7 -9
  116. data/lib/ramaze/snippets/proc/locals.rb +12 -12
  117. data/lib/ramaze/snippets/ramaze/acquire.rb +15 -14
  118. data/lib/ramaze/snippets/ramaze/deprecated.rb +1 -1
  119. data/lib/ramaze/snippets/ramaze/fiber.rb +1 -1
  120. data/lib/ramaze/snippets/ramaze/lru_hash.rb +2 -3
  121. data/lib/ramaze/snippets/ramaze/struct.rb +2 -4
  122. data/lib/ramaze/snippets/string/camel_case.rb +8 -10
  123. data/lib/ramaze/snippets/string/color.rb +3 -4
  124. data/lib/ramaze/snippets/string/end_with.rb +3 -6
  125. data/lib/ramaze/snippets/string/esc.rb +3 -8
  126. data/lib/ramaze/snippets/string/ord.rb +3 -8
  127. data/lib/ramaze/snippets/string/snake_case.rb +6 -9
  128. data/lib/ramaze/snippets/string/start_with.rb +3 -8
  129. data/lib/ramaze/snippets/string/unindent.rb +3 -6
  130. data/lib/ramaze/snippets/thread/into.rb +1 -3
  131. data/lib/ramaze/spec.rb +2 -31
  132. data/lib/ramaze/spec/bacon.rb +18 -2
  133. data/lib/ramaze/version.rb +1 -1
  134. data/lib/ramaze/view.rb +1 -1
  135. data/ramaze.gemspec +1 -1
  136. data/spec/helper.rb +2 -1
  137. data/spec/ramaze/bin/start.rb +16 -20
  138. data/spec/ramaze/cache/localmemcache.rb +4 -7
  139. data/spec/ramaze/cache/memcache.rb +3 -1
  140. data/spec/ramaze/cache/redis.rb +62 -0
  141. data/spec/ramaze/helper/blue_form.rb +33 -4
  142. data/spec/ramaze/helper/layout.rb +40 -7
  143. data/spec/ramaze/helper/upload.rb +149 -0
  144. data/spec/ramaze/helper/uploads/text_1.txt +1 -0
  145. data/spec/ramaze/helper/uploads/text_2.txt +1 -0
  146. data/spec/ramaze/log/growl.rb +4 -6
  147. data/spec/ramaze/log/syslog.rb +6 -0
  148. data/spec/ramaze/view/lokar.rb +5 -0
  149. data/spec/ramaze/view/nagoro.rb +5 -0
  150. data/tasks/authors.rake +1 -1
  151. data/tasks/bacon.rake +14 -5
  152. data/tasks/changelog.rake +1 -1
  153. data/tasks/yard.rake +12 -4
  154. metadata +277 -239
  155. data/doc/LEGAL +0 -26
  156. data/examples/app/blog/README +0 -3
  157. data/examples/app/blog/controller/comment.rb +0 -45
  158. data/examples/app/blog/controller/entry.rb +0 -85
  159. data/examples/app/blog/controller/main.rb +0 -20
  160. data/examples/app/blog/controller/tag.rb +0 -9
  161. data/examples/app/blog/layout/default.nag +0 -31
  162. data/examples/app/blog/model/entry.rb +0 -89
  163. data/examples/app/blog/model/tag.rb +0 -36
  164. data/examples/app/blog/public/css/screen.css +0 -273
  165. data/examples/app/blog/spec/blog.rb +0 -87
  166. data/examples/app/blog/view/comment/form.nag +0 -10
  167. data/examples/app/blog/view/comment/show.nag +0 -16
  168. data/examples/app/blog/view/entry/edit.nag +0 -14
  169. data/examples/app/blog/view/entry/feed.atom.nag +0 -8
  170. data/examples/app/blog/view/entry/feed.rss.nag +0 -7
  171. data/examples/app/blog/view/entry/index.nag +0 -7
  172. data/examples/app/blog/view/entry/new.nag +0 -13
  173. data/examples/app/blog/view/entry/show.nag +0 -36
  174. data/examples/app/blog/view/feed.atom.nag +0 -18
  175. data/examples/app/blog/view/feed.rss.nag +0 -25
  176. data/examples/app/blog/view/index.nag +0 -6
  177. data/examples/app/blog/view/tag/index.nag +0 -5
  178. data/lib/proto/public/ramaze.png +0 -0
  179. data/lib/ramaze/rest.rb +0 -36
  180. data/spec/ramaze/rest.rb +0 -28
  181. data/tasks/rcov.rake +0 -22
@@ -1,71 +1,32 @@
1
+ # This file contains your application, it requires dependencies and necessary
2
+ # parts of the application.
3
+ #
4
+ # It will be required from either `config.ru` or `start.rb`
5
+ #
6
+ # Note that the require 'rubygems' line is only required if you're running a
7
+ # Ruby implementation that's based on 1.8 such as REE or Rubinius (although I'm
8
+ # not sure if the latter actually requires this).
1
9
  require 'rubygems'
2
10
  require 'ramaze'
3
11
 
4
- Ramaze.setup :verbose => true do
5
- gem 'sequel', '3.9.0'
6
- gem 'maruku', '0.6.0'
7
- gem 'sqlite3-ruby', :lib => 'sqlite3'
8
- gem 'nagoro'
12
+ # This block of code automatically downloads and installs all the specified
13
+ # Gems. This is similar to how Bundler and Isolate work but in a much simpler
14
+ # way.
15
+ Ramaze.setup(:verbose => false) do
16
+ gem 'sequel'
17
+ gem 'sqlite3'
18
+ gem 'bcrypt-ruby', :lib => 'bcrypt'
19
+ gem 'rdiscount'
9
20
  end
10
21
 
11
- module Blog
12
- include Ramaze::Optioned
22
+ # Make sure that Ramaze knows where you are. Without this layouts and such
23
+ # wouldn't be rendered. While Ramaze.options.roots includes "." (the current
24
+ # directory) you should not rely on this path as it changes depending from what
25
+ # directory this script was called.
26
+ Ramaze.options.roots = [__DIR__]
13
27
 
14
- options.dsl do
15
- o 'Title of this blog', :title,
16
- 'Ramaze Blog'
28
+ # Initialize controllers and models
29
+ require __DIR__('model/init')
30
+ require __DIR__('controller/init')
17
31
 
18
- o 'Subtitle of the blog', :subtitle,
19
- 'manveru.thoughts.to_html'
20
-
21
- sub :author do
22
- o 'Your name', :name,
23
- 'Michael Fellinger'
24
-
25
- o 'Your email address', :email,
26
- 'm.fellinger@gmail.com'
27
-
28
- o 'URL pointing to you, uses the url of this blog if nil', :url,
29
- 'http://github.com/manveru'
30
- end
31
-
32
- sub :admin do
33
- o "Admin username", :name,
34
- 'manveru'
35
-
36
- o "Admin password", :password,
37
- 'letmein'
38
- end
39
-
40
- sub :sidebar do
41
- o "Elements to display in the sidebar", :elements,
42
- [:bio, :tagcloud, :history, :admin]
43
-
44
- sub :bio do
45
- o 'Describe yourself, you may use html', :text,
46
- "My name is Forrest, Forrest Gump.<br />
47
- I enjoy running, chocolate, talking, and Jenny."
48
- end
49
-
50
- sub :history do
51
- o "How many past entries should be shown in the history", :size,
52
- 20
53
- end
54
- end
55
-
56
- o 'Number of entries shown in entry listings', :list_size,
57
- 10
58
-
59
- o 'How many entries are shown in the feeds', :feed_size,
60
- 100
61
-
62
- o 'Feed UUID', :uuid,
63
- 'ramaze_blog'
64
-
65
- o "Time format used throughout the blog, see `ri Time.strftime`", :time_format,
66
- '%A, %d.%m.%Y at %R'
67
- end
68
- end
69
-
70
- require 'model/init'
71
- require 'controller/init'
32
+ Ramaze::Log.info('Logging in can be done by going to /users/login')
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env rackup
2
2
  #
3
3
  # config.ru for ramaze apps
4
- # use thin >= 1.0.0
5
- # thin start -R config.ru
6
4
  #
7
- # rackup is a useful tool for running Rack applications, which uses the
5
+ # Rackup is a useful tool for running Rack applications, which uses the
8
6
  # Rack::Builder DSL to configure middleware and build up applications easily.
9
7
  #
10
- # rackup automatically figures out the environment it is run in, and runs your
11
- # application as FastCGI, CGI, or standalone with Mongrel or WEBrickall from
8
+ # Rackup automatically figures out the environment it is run in, and runs your
9
+ # application as FastCGI, CGI, or standalone with Mongrel or WEBrick -- all from
12
10
  # the same configuration.
11
+ #
12
+ # Do not set the adapter.handler in here, it will be ignored.
13
+ # You can choose the adapter like `ramaze start -s mongrel` or set it in the
14
+ # 'start.rb' and use `ruby start.rb` instead.
15
+ require ::File.expand_path('../app', __FILE__)
16
+
17
+ Ramaze.start(:root => Ramaze.options.roots, :started => true)
13
18
 
14
- cwd = File.dirname(__FILE__)
15
- require "#{cwd}/start"
16
- Ramaze.start(:started => true)
17
- run Innate
19
+ run Ramaze
@@ -1,88 +1,31 @@
1
- module Blog
2
- class Controller < Ramaze::Controller
3
- engine :Nagoro
4
- layout(:default){|path, wish| wish !~ /rss|atom/ }
5
- map_layouts '/'
6
- map nil, :blog
7
- app.location = '/'
8
- trait :app => :blog
9
- helper :form, :auth, :formatting
10
-
11
- trait :auth_table => lambda{
12
- password = Digest::SHA1.hexdigest(Blog.options.admin.password)
13
- {Blog.options.admin.name => password}
14
- }
15
-
16
- private
17
-
18
- def author_url
19
- Blog.options.author.url || request.domain(Main.r('/'))
20
- end
21
-
22
- def sidebar
23
- out = Ramaze::Gestalt.new
24
-
25
- Blog.options.sidebar.elements.each do |element|
26
- name, title, *contents = __send__("sidebar_#{element}")
27
-
28
- out.ul(:class => name) do
29
- out.li(:class => :title){ title }
30
- contents.flatten.each do |content|
31
- out.li{ content.to_s }
32
- end
33
- end
34
- end
35
-
36
- out.to_s
37
- end
38
-
39
- def sidebar_bio
40
- return :bio, 'About me', Blog.options.sidebar.bio.text.to_s
41
- end
42
-
43
- def sidebar_admin
44
- if logged_in?
45
- links = [ a('New entry', Entries.r(:new)),
46
- a('Logout', Main.r(:logout)) ]
47
- return :actions, 'Administration', links
48
- else
49
- return :login, 'Login', <<FORM.strip
50
- <form method="post" action="#{r :login}">
51
- #{form_text 'Username', :username}
52
- #{form_password 'Password', :password}
53
- #{form_submit 'Login'}
54
- </form>
55
- FORM
56
- end
57
- end
58
-
59
- def sidebar_history
60
- limit = 4; Blog.options.sidebar.history.size
61
- entries = Entry.select(:id, :title).order(:published.desc).limit(limit)
62
-
63
- return :history, 'History',
64
- entries.map{|e| a(e.title, e.href) }
65
- end
66
-
67
- # Don't rel="tag" them, this is bad practice according to microformats
68
- #
69
- # The query makes sure that we only select tags that have entries
70
- # associated with them.
71
- def sidebar_tagcloud
72
- tags = Tag.filter(:id => EntriesTags.select(:tag_id)).select(:name).map(:name)
73
- cloud = []
74
-
75
- tagcloud(tags, 0.8, 2.0).each do |tag, weight|
76
- style = "font-size: %0.2fem" % weight
77
- cloud << "<a href='#{Tags.r(tag)}' style='#{style}'>#{h(tag)}</a>"
78
- end
79
-
80
- return :tagcloud, 'Tags', cloud.sort.join("\n")
81
- end
82
- end
1
+ ##
2
+ # Base controller that provides a few things used by sub controllers throughout
3
+ # this example application.
4
+ #
5
+ # @author Yorick Peterse
6
+ # @since 26-09-2011
7
+ #
8
+ class BaseController < Ramaze::Controller
9
+ engine :etanni
10
+ layout :default
11
+ helper :blue_form, :user, :xhtml, :paginate
12
+
13
+ # Configures the Paginate helper so that it shows a maximum of 10 posts per
14
+ # page and uses the "page" query string key to determine the current page.
15
+ # This will result in URLs such as /posts?page=2. Note that when calling the
16
+ # paginate() method you can override these settings.
17
+ trait :paginate => {
18
+ :var => 'page',
19
+ :limit => 10
20
+ }
21
+
22
+ # Tells the User helper what model class should be used for the authenticate()
23
+ # method. By default this is already set to "User" so technically this isn't
24
+ # required but to make it easier to understand what's going on I decided to
25
+ # put it here.
26
+ trait :user_model => User
83
27
  end
84
28
 
85
- require 'controller/main'
86
- require 'controller/entry'
87
- require 'controller/tag'
88
- require 'controller/comment'
29
+ # Load all other controllers
30
+ require __DIR__('posts')
31
+ require __DIR__('users')
@@ -0,0 +1,232 @@
1
+ ##
2
+ # The Posts controller is used to display a list of all the posts that have been
3
+ # added as well as providing a way of adding, removing and updating posts.
4
+ #
5
+ # @author Yorick Peterse
6
+ # @since 26-09-2011
7
+ #
8
+ class Posts < BaseController
9
+ map '/'
10
+
11
+ # Sets the content type and view name based on the extension in the URL. For
12
+ # example, a request to /posts/feed.rss would render the view feed.rss.xhtml
13
+ # and set the content type to application/rss+xml.
14
+ provide(:atom, :type => 'application/atom+xml') do |action, body|
15
+ # Disable the layout.
16
+ action.layout = false
17
+
18
+ # Let's make sure the body is actually rendered. Using "return" would cause
19
+ # a local jumper error.
20
+ body
21
+ end
22
+
23
+ # These methods require the user to be logged in. If this isn't the case the
24
+ # user will be redirected back to the previous page and a message is
25
+ # displayed.
26
+ before(:edit, :new, :save, :delete) do
27
+ # "unless logged_in?" is the same as "if !logged_in?" but in my opinion is a
28
+ # bit nicer to the eyes.
29
+ unless logged_in?
30
+ flash[:error] = 'You need to be logged in to view that page'
31
+
32
+ # Posts.r() is a method that generates a route to a given method and a set
33
+ # of parameters. Calling #to_s on this object would produce a string
34
+ # containing a URL. For example, Posts.r(:edit, 10).to_s would result in
35
+ # "/edit/10".
36
+ redirect(Posts.r(:index))
37
+ end
38
+ end
39
+
40
+ ##
41
+ # Shows an overview of all the posts that have been added. These posts are
42
+ # paginated using the Paginate helper.
43
+ #
44
+ # @author Yorick Peterse
45
+ # @since 26-09-2011
46
+ #
47
+ def index
48
+ @posts = paginate(Post.eager(:comments, :user))
49
+ @title = 'Posts'
50
+ end
51
+
52
+ ##
53
+ # Returns a list of all posts as either an RSS feed or an Atom feed.
54
+ #
55
+ # @author Yorick Peterse
56
+ # @since 27-09-2011
57
+ #
58
+ def feed
59
+ @posts = Post.all
60
+
61
+ render_view(:feed)
62
+ end
63
+
64
+ ##
65
+ # Shows a single post along with all it's comments.
66
+ #
67
+ # @author Yorick Peterse
68
+ # @since 26-09-2011
69
+ # @param [Fixnum] id The ID of the post to view.
70
+ #
71
+ def view(id)
72
+ @post = Post[id]
73
+
74
+ if @post.nil?
75
+ flash[:error] = 'The specified post is invalid'
76
+ redirect_referrer
77
+ end
78
+
79
+ @title = @post.title
80
+ @created_at = @post.created_at.strftime('%Y-%m-%d')
81
+ @new_comment = flash[:form_data] || Comment.new
82
+ end
83
+
84
+ ##
85
+ # Allows users to create a new post, given the user is logged in.
86
+ #
87
+ # @author Yorick Peterse
88
+ # @since 26-09-2011
89
+ #
90
+ def new
91
+ @post = flash[:form_data] || Post.new
92
+ @title = 'New post'
93
+
94
+ render_view(:form)
95
+ end
96
+
97
+ ##
98
+ # Allows a user to edit an existing blog post.
99
+ #
100
+ # @author Yorick Peterse
101
+ # @since 26-09-2011
102
+ # @param [Fixnum] id The ID of the blog post to edit.
103
+ #
104
+ def edit(id)
105
+ @post = flash[:form_data] || Post[id]
106
+
107
+ # Make sure the post is valid
108
+ if @post.nil?
109
+ flash[:error] = 'The specified post is invalid'
110
+ redirect_referrer
111
+ end
112
+
113
+ @title = "Edit #{@post.title}"
114
+
115
+ render_view(:form)
116
+ end
117
+
118
+ ##
119
+ # Adds a new comment to an existing post and redirects the user back to the
120
+ # post.
121
+ #
122
+ # @author Yorick Peterse
123
+ # @since 27-09-2011
124
+ #
125
+ def add_comment
126
+ data = request.subset(:post_id, :username, :comment)
127
+ comment = Comment.new
128
+
129
+ # If the user is logged in the user_id field should be set instead of the
130
+ # username field.
131
+ if logged_in?
132
+ data.delete('username')
133
+ data['user_id'] = user.id
134
+ end
135
+
136
+ begin
137
+ comment.update(data)
138
+ flash[:success] = 'The comment has been added'
139
+ rescue => e
140
+ Ramaze::Log.error(e)
141
+
142
+ flash[:form_errors] = comment.errors
143
+ flash[:error] = 'The comment could not be added'
144
+ end
145
+
146
+ redirect_referrer
147
+ end
148
+
149
+ ##
150
+ # Saves the changes made by Posts#edit() and Posts#new(). While these two
151
+ # methods could have their own methods for saving the data the entire process
152
+ # is almost identical and thus this would be somewhat useless.
153
+ #
154
+ # @author Yorick Peterse
155
+ # @since 26-09-2011
156
+ #
157
+ def save
158
+ # Fetch the POST data to use for a new Post object or for updating an
159
+ # existing one.
160
+ data = request.subset(:title, :body)
161
+ id = request.params['id']
162
+ data['user_id'] = user.id
163
+
164
+ # If an ID is given it's assumed the user wants to edit an existing post,
165
+ # otherwise a new one will be created.
166
+ if !id.nil? and !id.empty?
167
+ post = Post[id]
168
+
169
+ # Let's make sure the post is valid
170
+ if post.nil?
171
+ flash[:error] = 'The specified post is invalid'
172
+ redirect_referrer
173
+ end
174
+
175
+ success = 'The post has been updated'
176
+ error = 'The post could not be updated'
177
+ # Create a new post
178
+ else
179
+ post = Post.new
180
+ success = 'The post has been created'
181
+ error = 'The post could not be created'
182
+ end
183
+
184
+ # Now that we have a Post object and the messages to display it's time to
185
+ # actually insert/update the data. This is wrapped in a begin/rescue block
186
+ # so that any errors can be handled nicely.
187
+ begin
188
+ # Post#update() can be used for both new objects and existing ones. In
189
+ # case the object doesn't exist in the database it will be automatically
190
+ # created.
191
+ post.update(data)
192
+
193
+ flash[:success] = success
194
+
195
+ # Redirect the user back to the correct page.
196
+ redirect(Posts.r(:edit, post.id))
197
+ rescue => e
198
+ Ramaze::Log.error(e)
199
+
200
+ # Store the submitted data and the errors. The errors are used by
201
+ # BlueForm, the form data is used so that the user doesn't have to
202
+ # re-enter all data every time something goes wrong.
203
+ flash[:form_data] = post
204
+ flash[:form_errors] = post.errors
205
+ flash[:error] = error
206
+
207
+ redirect_referrer
208
+ end
209
+ end
210
+
211
+ ##
212
+ # Removes a single post from the database.
213
+ #
214
+ # @author Yorick Peterse
215
+ # @since 26-09-2011
216
+ # @param [Fixnum] id The ID of the post to remove.
217
+ #
218
+ def delete(id)
219
+ # The call is wrapped in a begin/rescue block so any errors can be handled
220
+ # properly. Without this the user would bump into a nasty stack trace and
221
+ # probably would have no clue as to what's going on.
222
+ begin
223
+ Post.filter(:id => id).destroy
224
+ flash[:success] = 'The specified post has been removed'
225
+ rescue => e
226
+ Ramaze::Log.error(e.message)
227
+ flash[:error] = 'The specified post could not be removed'
228
+ end
229
+
230
+ redirect(Posts.r(:index))
231
+ end
232
+ end # Posts