radiant-forum-extension 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/README.md +37 -56
  2. data/VERSION +1 -1
  3. data/app/controllers/forum_base_controller.rb +78 -0
  4. data/app/controllers/forums_controller.rb +5 -34
  5. data/app/controllers/posts_controller.rb +61 -153
  6. data/app/controllers/topics_controller.rb +6 -63
  7. data/app/helpers/forum_helper.rb +24 -48
  8. data/app/models/forum.rb +5 -18
  9. data/app/models/post.rb +53 -55
  10. data/app/models/post_attachment.rb +9 -6
  11. data/app/models/topic.rb +20 -113
  12. data/app/views/admin/reader_configuration/_edit_forum.html.haml +4 -2
  13. data/app/views/admin/reader_configuration/_forum.html.haml +6 -2
  14. data/app/views/forums/_forum.html.haml +14 -20
  15. data/app/views/forums/_latest.html.haml +12 -0
  16. data/app/views/forums/_standard_parts.html.haml +49 -0
  17. data/app/views/forums/index.html.haml +16 -24
  18. data/app/views/forums/show.html.haml +18 -28
  19. data/app/views/pages/_comment.html.haml +1 -1
  20. data/app/views/posts/_attachments.html.haml +13 -0
  21. data/app/views/posts/_confirm_delete.html.haml +10 -0
  22. data/app/views/posts/_context.html.haml +16 -0
  23. data/app/views/posts/_edit_links.html.haml +11 -0
  24. data/app/views/posts/_form.html.haml +40 -2
  25. data/app/views/posts/_latest.html.haml +10 -17
  26. data/app/views/posts/_new_attachment.html.haml +2 -0
  27. data/app/views/posts/_post.html.haml +25 -60
  28. data/app/views/posts/{_search.html.haml → _search_form.html.haml} +1 -1
  29. data/app/views/posts/_uploader.html.haml +2 -2
  30. data/app/views/posts/edit.html.haml +26 -13
  31. data/app/views/posts/index.html.haml +19 -27
  32. data/app/views/posts/new.html.haml +27 -7
  33. data/app/views/posts/remove.html.haml +27 -0
  34. data/app/views/posts/show.html.haml +20 -7
  35. data/app/views/readers/_forum_messages.html.haml +20 -0
  36. data/app/views/readers/_messages_summary.html.haml +3 -0
  37. data/app/views/topics/_context.html.haml +12 -0
  38. data/app/views/topics/_latest.html.haml +14 -16
  39. data/app/views/topics/_locked.html.haml +1 -1
  40. data/app/views/topics/_replies.html.haml +6 -0
  41. data/app/views/topics/_reply.html.haml +23 -0
  42. data/app/views/topics/_topic.html.haml +14 -43
  43. data/app/views/topics/_voices.html.haml +5 -0
  44. data/app/views/topics/index.html.haml +11 -24
  45. data/app/views/topics/show.html.haml +25 -38
  46. data/config/initializers/radiant_config.rb +5 -1
  47. data/config/locales/en.yml +73 -27
  48. data/config/routes.rb +3 -4
  49. data/db/migrate/20101222160900_page_posts.rb +21 -0
  50. data/db/migrate/20101222163605_no_comment_forum.rb +10 -0
  51. data/db/migrate/20110105103827_topic_merely_associative.rb +23 -0
  52. data/db/migrate/20110111080550_detach_observer.rb +11 -0
  53. data/db/migrate/20110127113852_import_attachments.rb +9 -0
  54. data/forum_extension.rb +12 -13
  55. data/lib/commentable_model.rb +98 -0
  56. data/lib/forum_page.rb +2 -22
  57. data/lib/forum_reader_sessions_controller.rb +14 -0
  58. data/lib/forum_readers_controller.rb +2 -9
  59. data/lib/forum_red_cloth3.rb +23 -4
  60. data/lib/forum_red_cloth4.rb +23 -4
  61. data/lib/forum_tags.rb +298 -194
  62. data/lib/sanitize/config/forum.rb +47 -0
  63. data/public/images/furniture/blank.png +0 -0
  64. data/public/images/furniture/emoticons.png +0 -0
  65. data/public/javascripts/forum.js +349 -93
  66. data/public/javascripts/jquery.tools.min.js +195 -0
  67. data/public/punymce/blank.htm +1 -0
  68. data/public/punymce/css/content.css +4 -0
  69. data/public/punymce/css/editor.css +58 -0
  70. data/public/punymce/i18n/sv.js +28 -0
  71. data/public/punymce/img/icons.gif +0 -0
  72. data/public/punymce/img/icons_uncompressed.png +0 -0
  73. data/public/punymce/plugins/bbcode.js +1 -0
  74. data/public/punymce/plugins/bbcode_src.js +50 -0
  75. data/public/punymce/plugins/editsource/css/editor.css +3 -0
  76. data/public/punymce/plugins/editsource/editsource.js +1 -0
  77. data/public/punymce/plugins/editsource/editsource_src.js +81 -0
  78. data/public/punymce/plugins/editsource/img/icons.gif +0 -0
  79. data/public/punymce/plugins/emoticons/css/content.css +13 -0
  80. data/public/punymce/plugins/emoticons/css/editor.css +17 -0
  81. data/public/punymce/plugins/emoticons/emoticons.js +1 -0
  82. data/public/punymce/plugins/emoticons/emoticons_src.js +303 -0
  83. data/public/punymce/plugins/emoticons/img/emoticons.gif +0 -0
  84. data/public/punymce/plugins/emoticons/img/emoticons.png +0 -0
  85. data/public/punymce/plugins/emoticons/img/trans.gif +0 -0
  86. data/public/punymce/plugins/entities.js +1 -0
  87. data/public/punymce/plugins/entities_src.js +37 -0
  88. data/public/punymce/plugins/forceblocks.js +1 -0
  89. data/public/punymce/plugins/forceblocks_src.js +465 -0
  90. data/public/punymce/plugins/forcenl.js +1 -0
  91. data/public/punymce/plugins/forcenl_src.js +26 -0
  92. data/public/punymce/plugins/image/css/editor.css +1 -0
  93. data/public/punymce/plugins/image/image.js +1 -0
  94. data/public/punymce/plugins/image/image_src.js +30 -0
  95. data/public/punymce/plugins/image/img/icons.gif +0 -0
  96. data/public/punymce/plugins/link/css/editor.css +2 -0
  97. data/public/punymce/plugins/link/img/icons.gif +0 -0
  98. data/public/punymce/plugins/link/link.js +1 -0
  99. data/public/punymce/plugins/link/link_src.js +36 -0
  100. data/public/punymce/plugins/paste.js +1 -0
  101. data/public/punymce/plugins/paste_src.js +169 -0
  102. data/public/punymce/plugins/protect.js +1 -0
  103. data/public/punymce/plugins/protect_src.js +30 -0
  104. data/public/punymce/plugins/safari2x.js +1 -0
  105. data/public/punymce/plugins/safari2x_src.js +284 -0
  106. data/public/punymce/plugins/tabfocus.js +1 -0
  107. data/public/punymce/plugins/tabfocus_src.js +45 -0
  108. data/public/punymce/plugins/textcolor/css/editor.css +7 -0
  109. data/public/punymce/plugins/textcolor/img/icons.gif +0 -0
  110. data/public/punymce/plugins/textcolor/textcolor.js +1 -0
  111. data/public/punymce/plugins/textcolor/textcolor_src.js +73 -0
  112. data/public/punymce/puny_mce.js +1 -0
  113. data/public/punymce/puny_mce_full.js +1 -0
  114. data/public/punymce/puny_mce_src.js +1460 -0
  115. data/public/stylesheets/sass/forum.sass +175 -169
  116. data/radiant-forum-extension.gemspec +81 -19
  117. data/spec/controllers/admin/forums_controller_spec.rb +2 -2
  118. data/spec/controllers/forums_controller_spec.rb +3 -6
  119. data/spec/controllers/posts_controller_spec.rb +76 -59
  120. data/spec/controllers/topics_controller_spec.rb +4 -95
  121. data/spec/datasets/forum_readers_dataset.rb +1 -0
  122. data/spec/datasets/forums_dataset.rb +91 -10
  123. data/spec/lib/commentable_model_spec.rb +88 -0
  124. data/spec/lib/forum_page_spec.rb +2 -34
  125. data/spec/lib/forum_site_spec.rb +2 -3
  126. data/spec/lib/forum_tags_spec.rb +35 -0
  127. data/spec/models/forum_spec.rb +31 -20
  128. data/spec/models/post_spec.rb +40 -39
  129. data/spec/models/topic_spec.rb +29 -71
  130. data/spec/spec_helper.rb +10 -1
  131. metadata +84 -22
  132. data/app/views/posts/_reply.html.haml +0 -35
  133. data/app/views/posts/_upload.html.haml +0 -2
  134. data/app/views/posts/preview.html.haml +0 -32
  135. data/app/views/posts/search.html.haml +0 -63
  136. data/app/views/posts/search.rss.builder +0 -14
  137. data/app/views/topics/_form.html.haml +0 -30
  138. data/app/views/topics/_help.html.haml +0 -8
  139. data/app/views/topics/comments.html.haml +0 -6
  140. data/app/views/topics/edit.html.haml +0 -26
  141. data/app/views/topics/new.html.haml +0 -56
  142. data/spec/datasets/forum_pages_dataset.rb +0 -11
  143. data/spec/datasets/posts_dataset.rb +0 -31
  144. data/spec/datasets/topics_dataset.rb +0 -37
data/README.md CHANGED
@@ -1,69 +1,58 @@
1
1
  # Forum
2
2
 
3
- This is a simple but comprehensive forum implementation that plugs into radiant. It's fairly well-featured, including:
3
+ This is a tidy but comprehensive forum implementation that plugs into radiant and supports both discussion forums and page comments.
4
+
5
+ This new (as I write) version 2 is a complete rewrite with a lot of internal clarification in preparation for rails 3. It's in late beta at the moment: bug fixes, documentation and packaging for public release.
6
+
7
+ The forum is designed to be pick-and-mixed with other radiant extensions, so it's very focused on being an excellent forum and doesn't do anything else. I hope you will find it's very good at what it does do:
4
8
 
5
9
  * forums, topics, posts etc
6
10
  * page comments
7
11
  * simple but effective forum search
8
12
  * rss feeds of pretty much anything (including search queries and individual authors)
9
- * textile-formatted messages with html sanitized
10
- * smilies :(
11
13
  * multiple message attachments and helpful image-handling
12
14
  * configurable message-editing interval during which authors can make corrections
15
+ * minimal wysiwig message editing including smilies :(
16
+ * ajax edit-in-place
13
17
 
14
- I've tried to keep it simple and tidy both inside and out. This is helped by the fact that all the user-management is in the reader extension, so you should find this one easy to adapt and extend.
18
+ I've tried to keep it simple and tidy both inside and out. This is helped by the fact that all the user-management is in the reader extension, so you should find this is easy to adapt and extend. The admin interface on the other hand is pretty basic: we expect most administration to happen through the public pages but there does need to be at least a dashboard to give a better overview. That will come soon.
15
19
 
16
- The forum was derived long ago from [Beast](http://beast.caboo.se) and the fossilised bones will still be visible here and there. It has been in use on various sites in various versions for three years, but in making it ready for publication I've pretty much refactored the whole thing and probably optimised new bugs into it. Please let me know as soon as you spot one.
20
+ As far as I know this is the best forum software available for rails. I look forward to finding out that it's not.
17
21
 
18
22
  ## Status
19
23
 
20
- Mature and stable, but I'm a bit habitual with it so may have overlooked some rough edges in parts of the interface I don't visit much. It would benefit from wider use.
21
-
22
- There's a lot going on here and plenty of places for me to hide bugs, but the tests are fairly thorough.
24
+ This code has been surviving in the world for four or five years (and more, since some it originally came from Beast), but this version is about 75% new and you know what that means: new bugs. Github issues, please.
23
25
 
24
26
  ## Latest
25
27
 
26
- * Quite a lot of tidying up and trimming of the interface
27
- * sample javascripts and layout updated
28
- * Updated for 0.8.1 with gem and extension dependencies, and many small fixes to keep up with the `reader` and `group_forum` extensions.
28
+ * Inline editing with editable-for-interval setting
29
+ * Punymce-based wysiwig editing.
30
+ * Page comments data structure simplified. Migration required.
31
+ * Everything internationalized
32
+ * Scripting all moved over to jquery (mootools was too niche, sadly)
33
+ * Uses the new radiant configuration interface
34
+ * Basic admin interface as well as readerland administration
35
+ * Editable interval for messages
36
+
37
+ This version is not wholly multi-site compatible at the moment, since it relies heavily on configuration items that are not yet site-scoped. They will be soon.
29
38
 
30
39
  ## Still to do
31
40
 
32
- * Moderators among readership
33
- * Reinstate message preview
34
- * Reinstate email-monitoring
41
+ * Allow moderation by selected readers
35
42
  * Message-problem button
36
- * Admin pages that are less crappy
37
- * Anonymous page-comment option
43
+ * Admin dashboard
38
44
 
39
45
  ## Requirements
40
46
 
41
- Radiant 0.8.1 (we're using the new config machinery) with the [reader](http://github.com/spanner/radiant-reader-extension) extension. Reader has a few requirements of its own so it's best to install that one first, make sure it's testing clean and then install the forum.
47
+ Radiant 0.9.2 (we're using the new configuration interface) with the [reader](http://github.com/spanner/radiant-reader-extension) extension. Reader has a few requirements of its own so it's best to install that one first, make sure it's testing clean and then install the forum.
42
48
 
43
- We also require [will_paginate](http://github.com/mislav/will_paginate/) and [paperclip](http://github.com/thoughtbot/paperclip/) as gems. The latter is for post attachments, and if you're using [paperclipped](http://github.com/kbingman/paperclipped) (which vendors paperclip) then you can probably skip it. Otherwise:
49
+ We also require [will_paginate](http://github.com/mislav/will_paginate/) and [paperclip](http://github.com/thoughtbot/paperclip/) as gems but you will already have those.
44
50
 
45
51
  sudo rake gems:install
46
52
 
47
53
  should get everything you need.
48
54
 
49
- The forum is compatible with multi_site but you have to use [sites](https://github.com/spanner/radiant-sites-extension) instead if you want forums and readers site-scoped.
50
-
51
- ## Installation
52
-
53
- The usual:
54
-
55
- git submodule add git://github.com/spanner/radiant-forum-extension.git vendor/extensions/forum
56
-
57
- Check the extension loading order in environment.rb (you will need `share_layouts`, `reader` and perhaps `multi_site` to load before this one) and then:
58
-
59
- rake radiant:extensions:forum:migrate
60
- rake radiant:extensions:forum:update
61
-
62
- As well as the basic machinery this should give you:
63
-
64
- * a basic forum.css that you will want to improve upon,
65
- * an admin/forum.css that you can probably leave alone,
66
- * a sample layout that should be enough to let you experiment
55
+ The forum is compatible with multi_site but you should use [sites](https://github.com/spanner/radiant-sites-extension) instead if you want forums and readers site-scoped.
67
56
 
68
57
  ## Administration
69
58
 
@@ -71,30 +60,26 @@ The forum is easy to use and almost entirely separate from your page hierarchy.
71
60
 
72
61
  ## Configuration
73
62
 
74
- A few config options can be set:
75
-
76
- * `forum.layout` should be the name of the layout you want to use for reader-facing forum pages. See below for more detail.
77
- * `forum.default_forum` is the name of the forum that will be selected by default in the new-message form
78
- * `forum.editable_period` is the number of minutes for which posts remain editable by their authors once they have been submitted
63
+ There is now a configuration panel for the forum and you shouldn't have to do any console-tinkering.
79
64
 
80
65
  ## Layouts
81
66
 
82
- We use `share_layouts` to present your forum pages inside the radiant layout of your choice. Set the config option 'forum.layout' to the name of the layout you want to use (or see below for multi_site instructions). Your layout can work in the usual way: all we do is define page parts for you to include with `<r:content part="something" />`. These are the parts available:
67
+ Forum pages have their own controllers but they are presented inside your normal radiant layouts. Use the configuration interface to choose the layout you want to use. Your layout can work in the usual way: all we do is define page parts for you to include with `<r:content part="something" />`. These are the parts available:
83
68
 
84
69
  * the main page content (that you get with a bare `<r:content />`) gives you the main list, object or form.
85
70
  * 'pagetitle' will be the main page heading (eg the name of the topic): `<r:content part="pagetitle" />`
86
71
  * 'breadcrumbs' is what you'd expect: usually something simple like Forum > Category name
87
- * 'breadhead' is an up-one-level link that you may want to include in the page header
72
+ * 'breadhead' is a minimal breadcrumb link that you may want to include in the page header
88
73
  * 'feed' is an icon link to the RSS feed for whatever you are currently looking at (and works for most things including searches, of which more below)
89
74
  * 'mugshot' is a gravatar for the author of this topic or post
90
75
  * 'credits' is the authorship summary for this topic or post
91
76
 
92
- These parts are only defined where they're relevent, so you can do something like this:
77
+ These parts are only defined where they're relevant, so you can do something like this:
93
78
 
94
79
  <h1 class="pagetitle">
95
- <r:content part="mugshot" />
80
+ <r:content part="person" />
96
81
  <r:content part="breadhead" />
97
- <r:content part="pagetitle" />
82
+ <r:title />
98
83
  <r:content part="feed" />
99
84
  </h1>
100
85
 
@@ -106,10 +91,6 @@ You probably also want to include this somewhere, as on all reader-service pages
106
91
 
107
92
  Have a look at the included sample layout for a starting point.
108
93
 
109
- ## Multi_site
110
-
111
- The forum is fine under multi_site. If you use [our version](http://github.com/spanner/radiant-multi-site-extension) then everything will be site-scoped for you. In that case, the forum layout is chosen for each site using a dropdown on the (currently extremely scruffy) site-editing page. Everything else works in just the same way and you should be able to run several forums next to each other without problems.
112
-
113
94
  ## Private discussion
114
95
 
115
96
  If you install the [reader_group](http://github.com/spanner/radiant-reader_group-extension) and [group_forum](http://github.com/spanner/radiant-group_forum-extension) extensions then your forums can be made visible only to designated groups, as with pages and other groupable items.
@@ -118,7 +99,7 @@ If you install the [reader_group](http://github.com/spanner/radiant-reader_group
118
99
 
119
100
  The forum has its own simple search mechanism. It's not very bright but it has two great advantages: you can combine text search with filtering by author and category, and you can bookmark any search query as an RSS feed to be alerted when new posts match that search. There are arguments for integrating this with eg `sphinx_search` but at the moment I quite like keeping them separate: I find that searching for messages is not the same as searching for pages, but usually a different group seeking different results. Let me know if you disagree.
120
101
 
121
- To enable the search, you can either link to `/forum/posts/search` or put `<r:forum_search>` somewhere in your forum layout. See the tag documentation for control of the search form presentation.
102
+ The search is implemented just by passing parameters to posts_controller#index, so you can link to addresses like `/forum/posts?q=something&reader_id=45` or put `<r:forum_search>` somewhere in your forum layout. See the tag documentation for control of the search form presentation.
122
103
 
123
104
  ## Page Comments
124
105
 
@@ -129,7 +110,7 @@ The page cache means we don't want anything personal on the page itself - no edi
129
110
  * Put `<r:comments:remote />` on the page instead and a stub will be included suitable for your scripts to grab. A simple example is included in platform/forum.js.
130
111
  * `<r:comments:all /><r:comments:link />` is more efficient but less friendly: it will give you a static list of all comments followed by a reply link. Posting a comment clears the page cache, btw.
131
112
 
132
- You can also use `<r:comments:each>...</r:comments:each>` and the various r:comment tags to compose page comments however you like. See the tags-available documentation for details.
113
+ You can also use `<r:comments:each>...</r:comments:each>` and the various `r:forum:post` tags to compose page comments however you like. See the tags-available documentation for details.
133
114
 
134
115
  ## Security & Spam
135
116
 
@@ -137,19 +118,19 @@ The reader extension includes email confirmation and a simple honeytrap that sho
137
118
 
138
119
  ## Scripting the forum interface
139
120
 
140
- I've presented this in the simplest way possible, on the assumption that everyone will want to do their own thing with it. An unobtrusive javascript front end (based on mootools but without much fanciness) is included to make things a little bit more friendly: it includes edit-in-place for posts, a bit of code to handle bringing page comments into the page, and some generally-useful routines like notice faders. That's about it, but I hope it will provide a starting point. The 'forum_example' layout that is created on installation should bring in that javascript and enough css for you to see it all working. For local reasons it's all stored under `javascripts/platform/...`
121
+ The forum comes with some jquery-based scripting to handle inline administration and a few other useful functions. It's entirely unobtrusive and I assume you will want to replace or extend it. You should find the page DOM is quite simple and robust.
141
122
 
142
123
  ## Smilies
143
124
 
144
- I've included a basic set here and a redcloth extension that catches :smile: notation alongside the textile markup. There's a javascript front end in the works for that - click on the smiley, you know - which will also soon appear here.
125
+ Included here is a redcloth extension to handle emoticons of the type inserted by the punymce toolbar we're using. Since we have control of both ends I've customised the set to make accidental emoticons less likely. There will soon be an option to disable them completely.
145
126
 
146
127
  ## Bugs
147
128
 
148
- Very likely. [Github issues](http://github.com/spanner/radiant-forum-extension/issues), please, or for little things an email or github message is fine.
129
+ In the short term, quite likely. [Github issues](http://github.com/spanner/radiant-forum-extension/issues), please, or for little things an email or github message is fine.
149
130
 
150
131
  ## Author & Copyright
151
132
 
152
133
  * William Ross, for spanner. will at spanner.org
153
134
  * Originally based on dear old Beast, currently not visible at [http://beast.caboo.se](http://beast.caboo.se)
154
- * Copyright 2007-9 spanner ltd
135
+ * Copyright 2007-11 spanner ltd
155
136
  * released under the same terms as Rails and/or Radiant
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.1
1
+ 2.0.0
@@ -0,0 +1,78 @@
1
+ class ForumBaseController < ReaderActionController
2
+
3
+ include Radiant::Pagination::Controller
4
+ radiant_layout { |c| Radiant::Config['forum.layout'] || Radiant::Config['reader.layout'] }
5
+ before_filter :require_login_unless_public
6
+ before_filter :establish_context
7
+ helper :forum, :reader
8
+
9
+ protected
10
+
11
+ def require_login_unless_public
12
+ return false unless Radiant::Config['forum.public?'] || require_reader && require_activated_reader
13
+ end
14
+
15
+ def establish_context
16
+ @reader = Reader.find(params[:reader_id]) unless params[:reader_id].blank?
17
+ @topic = Topic.find(params[:topic_id]) unless params[:topic_id].blank?
18
+ @forum = Forum.find(params[:forum_id]) unless params[:forum_id].blank?
19
+ @page = Page.find(params[:page_id]) unless params[:page_id].blank?
20
+ end
21
+
22
+ def redirect_to_post
23
+
24
+ Rails.logger.warn "!!! redirecting to post #{@post.inspect}"
25
+ Rails.logger.warn "! which will have topic #{@post.topic} and within it page #{@post.page_when_paginated}"
26
+
27
+ if (@post.page)
28
+ redirect_to "#{@post.page.url}?#{WillPaginate::ViewHelpers.pagination_options[:param_name]}=#{@post.page_when_paginated}##{@post.dom_id}"
29
+ elsif @post.first?
30
+ redirect_to forum_topic_path(@post.topic.forum, @post.topic)
31
+ else
32
+ post_location = {WillPaginate::ViewHelpers.pagination_options[:param_name] => @post.page_when_paginated, :anchor => @post.dom_id}
33
+ redirect_to forum_topic_url(@post.topic.forum, @post.topic, post_location)
34
+ end
35
+ end
36
+
37
+ def redirect_to_topic
38
+ redirect_to forum_topic_path(@forum, @topic)
39
+ end
40
+
41
+ def redirect_to_page_or_topic
42
+ if @page
43
+ redirect_to @page.url
44
+ elsif @topic
45
+ redirect_to forum_topic_url(@topic.forum, @topic)
46
+ end
47
+ end
48
+
49
+ def redirect_to_forum
50
+ respond_to do |format|
51
+ format.html { redirect_to forum_path(@forum) }
52
+ end
53
+ end
54
+
55
+ def render_page_or_feed(template_name = action_name)
56
+ respond_to do |format|
57
+ format.html { render :action => template_name }
58
+ format.rss { render :action => template_name, :layout => 'feed' }
59
+ format.js { render :action => template_name, :layout => false }
60
+ end
61
+ end
62
+
63
+ def redirect_to_admin
64
+ redirect_to admin_forums_url
65
+ end
66
+
67
+ def render_locked
68
+ respond_to do |format|
69
+ format.html {
70
+ flash[:error] = t('topic_locked')
71
+ redirect_to_page_or_topic
72
+ }
73
+ format.js { render :partial => 'topics/locked' }
74
+ end
75
+ false
76
+ end
77
+
78
+ end
@@ -1,42 +1,13 @@
1
- class ForumsController < ReaderActionController
2
- include Radiant::Pagination::Controller
3
- helper :forum
1
+ class ForumsController < ForumBaseController
4
2
 
5
- before_filter :private_forum
6
- before_filter :find_forum, :only => :show
7
- before_filter :no_changes_here, :except => [:index, :show]
8
-
9
- radiant_layout { |controller| Radiant::Config['forum.layout'] || Radiant::Config['reader.layout'] }
10
-
11
3
  def index
12
- # visible is an open scope that can be overridden in other extensions, ie group_forum
13
- @forums = Forum.visible.paginate(:all, pagination_parameters.merge(:order => "position"))
4
+ @forums = Forum.all.paginate(pagination_parameters)
14
5
  end
15
6
 
16
7
  def show
17
- respond_to do |format|
18
- format.html {
19
- @topics = Topic.paginate_by_forum_id(params[:id], pagination_parameters.merge(:include => :replied_by, :order => 'sticky desc, replied_at desc'))
20
- }
21
- format.rss {
22
- @topics = Topic.paginate_by_forum_id(params[:id], pagination_parameters.merge(:include => :replied_by, :order => 'replied_at desc'))
23
- render :layout => 'feed'
24
- }
25
- end
26
- end
27
-
28
- def no_changes_here
29
- redirect_to admin_forums_url
30
- end
31
-
32
- protected
33
-
34
- def private_forum
35
- return false unless Radiant::Config['forum.public?'] || require_reader && require_activated_reader
36
- end
37
-
38
- def find_forum
39
8
  @forum = Forum.find(params[:id])
9
+ @topics = @forum.topics.stickyfirst.paginate(pagination_parameters)
10
+ render_page_or_feed
40
11
  end
41
-
12
+
42
13
  end
@@ -1,220 +1,128 @@
1
- class PostsController < ReaderActionController
2
- include Radiant::Pagination::Controller
3
- helper :forum
4
-
5
- before_filter :private_forum
6
- before_filter :require_activated_reader, :except => [:index, :show, :search]
7
- before_filter :find_topic_or_page, :except => [:index, :search]
1
+ class PostsController < ForumBaseController
2
+
3
+ before_filter :require_activated_reader, :except => [:index, :show]
4
+ before_filter :find_post, :only => [:show, :edit, :update, :remove, :destroy]
8
5
  before_filter :require_unlocked_topic_and_page, :only => [:new, :create]
9
- before_filter :find_post, :except => [:index, :search, :new, :create]
10
- before_filter :build_post, :only => [:new]
6
+ before_filter :build_post, :only => [:new, :create]
11
7
  before_filter :require_authority, :only => [:edit, :update, :destroy]
12
8
 
13
- radiant_layout { |controller| Radiant::Config['forum.layout'] || Radiant::Config['reader.layout'] }
14
-
15
- @@default_query_options = {
16
- :page => 1,
17
- :per_page => 20,
18
- :order => 'posts.created_at desc',
19
- :include => [:topic, :forum, :reader]
20
- }
21
-
22
9
  def index
23
- @posts = Post.visible.paginate(:all, @@default_query_options.merge(pagination_parameters))
24
- render_page_or_feed
25
- end
26
-
27
- def search
28
- conditions = []
29
- @reader = Reader.find(params[:reader_id]) unless params[:reader_id].blank?
30
- @topic = Topic.find(params[:topic_id]) unless params[:topic_id].blank?
31
- @forum = Forum.find(params[:forum_id]) unless params[:forum_id].blank?
32
-
33
- conditions << Post.send(:sanitize_sql, ["posts.reader_id = ?", @reader.id]) if @reader
34
- conditions << Post.send(:sanitize_sql, ["posts.topic_id = ?", @topic.id]) if @topic
35
- conditions << Post.send(:sanitize_sql, ["posts.forum_id = ?", @forum.id]) if @forum
36
- conditions << Post.send(:sanitize_sql, ['LOWER(posts.body) LIKE ?', "%#{params[:q]}%"]) unless params[:q].blank?
37
- @searching = true if conditions.any?
38
-
39
- @posts = Post.paginate(:all, @@default_query_options.merge(:conditions => @searching ? conditions.collect { |c| "(#{c})" }.join(' AND ') : nil, :page => params[:page], :per_page => params[:per_page]))
40
-
41
- # for summary of the set, and onward links
42
- @forums = @posts.collect(&:forum).uniq
43
- @topics = @posts.collect(&:topic).uniq
44
- @readers = @posts.collect(&:reader).uniq
45
-
10
+ posts = Post.scoped
11
+ posts = posts.from(@reader) if @reader
12
+ posts = posts.in_topic(@topic) if @topic
13
+ posts = posts.in_forum(@forum) if @forum
14
+ posts = posts.containing(@term) if @term = params[:q]
15
+ @posts = posts.paginate(pagination_parameters)
46
16
  render_page_or_feed
47
17
  end
48
18
 
49
19
  def monitored
50
- @searching = true
51
- options = @@query_options.merge(:conditions => ['monitorships.reader_id = ? and monitorships.active = ?', params[:reader_id], true])
52
- options[:joins] += ' inner join monitorships on monitorships.topic_id = topics.id'
53
- options[:page] = params[:page] || 1
54
- @posts = Post.paginate(:all, options)
55
- @title = "Topics you're watching"
20
+ @topics = current_reader.monitored_topics
21
+ @posts = Post.in_topics(@topics).paginate(pagination_parameters)
56
22
  render_page_or_feed
57
23
  end
58
24
 
59
25
  def show
60
26
  respond_to do |format|
61
- format.html { redirect_to_page_or_topic }
27
+ format.html { redirect_to_post }
62
28
  format.js { render :layout => false }
63
29
  end
64
30
  end
65
31
 
66
- # this is typically called by xht to bring a comment form into a page or a reply form into a topic
67
- # if the reader is not logged in, reader_required should have intervened and caused the return of a login form instead
68
-
69
32
  def new
33
+ unless @post.topic || @post.page
34
+ @forum ||= Forum.find_by_name(Radiant::Config['forum.default_forum'])
35
+ @post.topic = @forum.topics.new
36
+ end
70
37
  respond_to do |format|
71
- format.html { render :template => 'posts/new' } # we specify the template because in theory we could be reverting from a post to create
72
- format.js { render :partial => 'posts/reply' }
38
+ format.html { }
39
+ format.js { render :partial => 'posts/form', :layout => false }
73
40
  end
74
41
  end
75
42
 
76
43
  def create
77
- if @topic.new_record?
78
- # only happens if it's a page comment and the topic has just been built
79
- @topic.reader = current_reader
80
- @topic.save!
81
- end
82
- @post = @topic.posts.create!(params[:post])
83
-
84
- Radiant::Cache.clear if @page
85
-
44
+ @post.save!
45
+ Radiant::Cache.clear if @post.page
86
46
  respond_to do |format|
87
- format.html { redirect_to_page_or_topic }
88
- format.js { render :action => 'show', :layout => false }
47
+ format.html { redirect_to_post }
48
+ format.js { render :partial => 'post' }
89
49
  end
90
- end
91
-
92
- def topic_locked
50
+ rescue ActiveRecord::RecordInvalid
51
+ flash[:error] = t("validation_failure")
93
52
  respond_to do |format|
94
- format.html do
95
- flash[:notice] = 'Topic is locked.'
96
- redirect_to_page_or_topic
97
- end
98
- format.js { render :partial => 'topics/locked' }
53
+ format.html { render :action => 'new' }
54
+ format.js { render :partial => 'posts/form' }
99
55
  end
100
- return
101
56
  end
102
-
57
+
103
58
  def edit
104
59
  respond_to do |format|
105
- format.html { render }
106
- format.js { render :layout => false }
60
+ format.html { }
61
+ format.js { render :partial => 'posts/form' }
107
62
  end
108
63
  end
109
64
 
110
65
  def update
111
66
  @post.attributes = params[:post]
112
67
  @post.save!
113
- @post.save_attachments(params[:files])
114
- Radiant::Cache.clear if @post.topic.page
68
+ Radiant::Cache.clear if @post.page
69
+ respond_to do |format|
70
+ format.html { redirect_to_post }
71
+ format.js { render :partial => 'post' }
72
+ end
115
73
  rescue ActiveRecord::RecordInvalid
116
- flash[:error] = "Sorry: message can't be empty"
117
- ensure
74
+ flash[:error] = t("validation_failure")
118
75
  respond_to do |format|
119
- format.html { redirect_to_page_or_topic }
120
- format.js { render :partial => 'post', :layout => false }
121
- format.json { render :json => @post.as_json }
76
+ format.html { render :action => 'edit' }
77
+ format.js { render :partial => 'posts/form' }
78
+ end
79
+ end
80
+
81
+ def remove
82
+ respond_to do |format|
83
+ format.html {}
84
+ format.js { render :partial => 'confirm_delete' }
122
85
  end
123
86
  end
124
87
 
125
88
  def destroy
126
89
  if @post.first?
127
90
  @post.topic.destroy
128
- flash[:notice] = "Topic removed"
129
- respond_to do |format|
130
- format.html { redirect_to_forum }
131
- format.js { render :partial => 'post', :layout => false }
132
- end
91
+ flash[:notice] = t("topic_removed")
92
+ redirect_to_forum
133
93
  else
134
94
  @post.destroy
135
- flash[:notice] = "Post removed"
136
95
  respond_to do |format|
137
- format.html { redirect_to_page_or_topic }
138
- format.js { render :partial => 'post', :layout => false }
96
+ format.html {
97
+ flash[:notice] = t("post_removed")
98
+ redirect_to_page_or_topic
99
+ }
100
+ format.js { render :partial => 'post' }
139
101
  end
140
102
  end
141
103
  end
142
104
 
143
105
  protected
144
106
 
145
- def private_forum
146
- return false unless Radiant::Config['forum.public?'] || require_reader && require_activated_reader
107
+ def find_post
108
+ @post ||= Post.find(params[:id])
147
109
  end
148
110
 
149
111
  def require_authority
150
- (current_user && current_user.admin?) || @post.editable_by?(current_reader) # includes an editable-interval check
112
+ current_reader.is_admin? || @post.editable_by?(current_reader) # includes an editable-interval check
151
113
  end
152
114
 
153
- def find_topic_or_page
154
- if params[:page_id]
155
- @page = Page.find(params[:page_id])
156
- @topic = @page.find_or_build_topic
157
- @forum = @topic.forum if @topic
158
- elsif params[:topic_id]
159
- @topic = Topic.find(params[:topic_id], :include => :forum)
160
- @forum = @topic.forum if @topic
161
- end
162
- end
163
-
164
115
  def require_unlocked_topic_and_page
165
- return page_locked if @page && @page.locked?
166
- return topic_locked if @topic.locked?
116
+ return render_locked if @page && @page.locked?
117
+ return render_locked if @topic && @topic.locked?
167
118
  true
168
119
  end
169
120
 
170
- def find_post
171
- @post = @topic.posts.find(params[:id])
172
- end
173
-
174
121
  def build_post
175
122
  @post = Post.new(params[:post])
176
- @post.topic = @topic if @topic
177
123
  @post.reader = current_reader
124
+ @post.page ||= @page
125
+ @post.topic ||= @topic
178
126
  end
179
-
180
- def redirect_to_page_or_topic
181
- if (@topic.page)
182
- post_location = @post ? "##{@post.dom_id}" : ""
183
- redirect_to @topic.page.url + post_location
184
- else
185
- post_location = @post ? {:page => @post.topic_page, :anchor => @post.dom_id} : {}
186
- redirect_to forum_topic_url(@topic.forum, @topic, post_location)
187
- end
188
- end
189
-
190
- def redirect_to_forum
191
- redirect_to forum_url(@topic.forum)
192
- end
193
-
194
- def page_locked
195
- respond_to do |format|
196
- format.html {
197
- flash[:error] = 'This page is not commentable.'
198
- redirect_to @page.url
199
- }
200
- format.js {
201
- render :template => 'locked', :layout => false
202
- }
203
- end
204
- false
205
- end
206
-
207
- def topic_locked
208
- respond_to do |format|
209
- format.html {
210
- flash[:error] = 'This topic is locked.'
211
- redirect_to_page_or_topic
212
- }
213
- format.js {
214
- render :partial => 'topics/locked'
215
- }
216
- end
217
- false
218
- end
219
-
127
+
220
128
  end