blogit 0.4.8 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/README.md +11 -3
  2. data/app/assets/javascripts/blogit/archive.js +8 -0
  3. data/app/assets/javascripts/blogit/index.js +1 -1
  4. data/app/assets/stylesheets/blogit/index.css +10 -1
  5. data/app/controllers/blogit/comments_controller.rb +7 -7
  6. data/app/controllers/blogit/posts_controller.rb +12 -10
  7. data/app/helpers/blogit/application_helper.rb +23 -4
  8. data/app/helpers/blogit/posts_helper.rb +47 -3
  9. data/app/models/blogit/comment.rb +2 -0
  10. data/app/models/blogit/post.rb +26 -8
  11. data/app/views/blogit/comments/_admin_links.html.erb +2 -2
  12. data/app/views/blogit/comments/_comment.html.erb +8 -8
  13. data/app/views/blogit/comments/_form.html.erb +17 -18
  14. data/app/views/blogit/posts/_active_record_comments.html.erb +4 -0
  15. data/app/views/blogit/posts/_blogger_information.html.erb +1 -1
  16. data/app/views/blogit/posts/_comments_count.html.erb +2 -2
  17. data/app/views/blogit/posts/_disqus_comments.html.erb +14 -0
  18. data/app/views/blogit/posts/_empty.html.erb +2 -2
  19. data/app/views/blogit/posts/_form.html.erb +9 -9
  20. data/app/views/blogit/posts/_no_comments.html.erb +0 -0
  21. data/app/views/blogit/posts/_post.html.erb +6 -6
  22. data/app/views/blogit/posts/_post_links.html.erb +1 -1
  23. data/app/views/blogit/posts/_share_bar.html.erb +45 -0
  24. data/app/views/blogit/posts/edit.html.erb +2 -2
  25. data/app/views/blogit/posts/index.html.erb +7 -7
  26. data/app/views/blogit/posts/new.html.erb +1 -1
  27. data/app/views/blogit/posts/show.html.erb +2 -6
  28. data/config/locales/en.yml +48 -0
  29. data/config/locales/fr.yml +61 -0
  30. data/lib/blogit/configuration.rb +69 -30
  31. data/lib/blogit/version.rb +1 -1
  32. data/lib/generators/templates/blogit.rb +34 -18
  33. data/spec/controllers/blogit/posts_controller_spec.rb +75 -75
  34. data/spec/dummy/app/helpers/application_helper.rb +1 -0
  35. data/spec/dummy/app/views/layouts/application.html.erb +8 -4
  36. data/spec/dummy/config/application.rb +1 -1
  37. data/spec/dummy/config/initializers/blogit.rb +21 -12
  38. data/spec/dummy/db/development.sqlite3 +0 -0
  39. data/spec/dummy/db/test.sqlite3 +0 -0
  40. data/spec/dummy/log/development.log +155 -0
  41. data/spec/dummy/log/test.log +7310 -0
  42. data/spec/helpers/blogit/application_helper_spec.rb +63 -8
  43. data/spec/helpers/blogit/posts_helper_spec.rb +114 -6
  44. data/spec/lib/blogit/parsers/markdown_parser_spec.rb +7 -3
  45. data/spec/lib/configuration_spec.rb +43 -19
  46. data/spec/models/blogit/post_spec.rb +51 -53
  47. data/spec/spec_helper.rb +1 -1
  48. metadata +158 -36
data/README.md CHANGED
@@ -55,6 +55,9 @@ we'll also throw in:
55
55
  * An XML Sitemap located at `/blog/posts.xml`
56
56
  * An RSS feed located at `/blog/posts.rss`
57
57
  * Page Caching and Sweeping
58
+ * Internationalization (see the [locales file](https://github.com/KatanaCode/blogit/blob/master/config/locales/en.yml) for configurable options)
59
+ * Share links (Google+, Twitter & Facebook)
60
+ * [Disquss Comments](http://disqus.com)
58
61
 
59
62
  ## Issues
60
63
 
@@ -96,8 +99,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
96
99
 
97
100
  ## Credits
98
101
 
99
- Developed by [katana:code](http://katanacode.com)
102
+ Developed by [Katana Code](http://katanacode.com)
100
103
 
101
- ## About katana:code
104
+ with generous contributions from:
102
105
 
103
- katana:code are [Ruby on Rails Developers Based in Edinburgh, Scotland](http://katanacode.com/ "katana:code").
106
+ * [Philou](https://github.com/philou)
107
+ * [Stewart McKee](https://github.com/stewartmckee)
108
+
109
+ ## About Katana Code
110
+
111
+ Katana Code are [Ruby on Rails Developers Based in Edinburgh, Scotland](http://katanacode.com/ "Katana Code").
@@ -0,0 +1,8 @@
1
+ // Supporting functions for the display of post archives
2
+
3
+ jQuery(function(){
4
+ $("a[data-blogit-click-to-toggle-children]").click(function(event){
5
+ event.preventDefault();
6
+ $(this).siblings('ul').toggle();
7
+ })
8
+ })
@@ -1 +1 @@
1
- //
1
+ //= require_tree .
@@ -4,7 +4,7 @@ article.blog_post {
4
4
  }
5
5
  .blog_post header h1 a{
6
6
  text-decoration: none;
7
- color: #55D;
7
+ color: #55D;
8
8
  }
9
9
  .blog_post p{
10
10
  line-height: 1.6em;
@@ -73,3 +73,12 @@ article.blog_post {
73
73
  .blog_comment .actions, .blog_post .actions{
74
74
  text-align: right;
75
75
  }
76
+
77
+ #blog_share_bar {
78
+ width: 600px;
79
+ margin: 0.5em auto;
80
+ }
81
+
82
+ .social_button {
83
+ display: inline-block;
84
+ }
@@ -2,7 +2,7 @@ module Blogit
2
2
  class CommentsController < ApplicationController
3
3
 
4
4
  blogit_authenticate except: [:create]
5
-
5
+
6
6
  blogit_sweeper(:create, :update, :destroy)
7
7
 
8
8
 
@@ -14,9 +14,9 @@ module Blogit
14
14
  @comment.save
15
15
  }
16
16
 
17
- format.html {
18
- if @comment.save
19
- redirect_to(post, notice: "Successfully added comment!")
17
+ format.html {
18
+ if @comment.save
19
+ redirect_to(post, notice: t(:successfully_added_comment, scope: 'blogit.comments'))
20
20
  else
21
21
  render "blogit/posts/show"
22
22
  end
@@ -30,16 +30,16 @@ module Blogit
30
30
  @comment = post.comments.find(params[:id])
31
31
  @comment.destroy
32
32
  respond_to do |format|
33
- format.html { redirect_to(post, notice: "Successfully removed comment.") }
33
+ format.html { redirect_to(post, notice: t(:successfully_removed_comment, scope: 'blogit.comments'))}
34
34
  format.js
35
35
  end
36
36
  end
37
-
37
+
38
38
  private
39
39
 
40
40
  def post
41
41
  @post ||= Blogit::Post.find(params[:post_id])
42
42
  end
43
-
43
+
44
44
  end
45
45
  end
@@ -1,13 +1,16 @@
1
1
  module Blogit
2
-
3
- class PostsController < ApplicationController
4
2
 
5
- unless blogit_conf.include_admin_actions
3
+ # Using explicit ::Blogit::ApplicationController fixes NoMethodError 'blogit_authenticate' in
4
+ # the main_app
5
+ class PostsController < ::Blogit::ApplicationController
6
+
7
+ # We can't use blogit_conf here because it sometimes raises NoMethodError in main app's routes
8
+ unless Blogit.configuration.include_admin_actions
6
9
  before_filter :raise_404, except: [:index, :show, :tagged]
7
10
  end
8
11
 
9
12
  blogit_authenticate(except: [:index, :show, :tagged])
10
-
13
+
11
14
  blogit_cacher(:index, :show, :tagged)
12
15
  blogit_sweeper(:create, :update, :destroy)
13
16
 
@@ -26,8 +29,7 @@ module Blogit
26
29
  end
27
30
 
28
31
  def show
29
- @post = Post.find(params[:id])
30
- @comment = @post.comments.new
32
+ @post = Post.find(params[:id])
31
33
  end
32
34
 
33
35
  def tagged
@@ -46,7 +48,7 @@ module Blogit
46
48
  def create
47
49
  @post = current_blogger.blog_posts.new(params[:post])
48
50
  if @post.save
49
- redirect_to @post, notice: 'Blog post was successfully created.'
51
+ redirect_to @post, notice: t(:blog_post_was_successfully_created, scope: 'blogit.posts')
50
52
  else
51
53
  render action: "new"
52
54
  end
@@ -55,7 +57,7 @@ module Blogit
55
57
  def update
56
58
  @post = current_blogger.blog_posts.find(params[:id])
57
59
  if @post.update_attributes(params[:post])
58
- redirect_to @post, notice: 'Blog post was successfully updated.'
60
+ redirect_to @post, notice: t(:blog_post_was_successfully_updated, scope: 'blogit.posts')
59
61
  else
60
62
  render action: "edit"
61
63
  end
@@ -64,7 +66,7 @@ module Blogit
64
66
  def destroy
65
67
  @post = current_blogger.blog_posts.find(params[:id])
66
68
  @post.destroy
67
- redirect_to posts_url, notice: "Blog post was successfully destroyed."
69
+ redirect_to posts_url, notice: t(:blog_post_was_successfully_destroyed, scope: 'blogit.posts')
68
70
  end
69
71
 
70
72
  private
@@ -76,4 +78,4 @@ module Blogit
76
78
 
77
79
  end
78
80
 
79
- end
81
+ end
@@ -12,7 +12,7 @@ module Blogit
12
12
 
13
13
  # Returns the first error message for an ActiveRecord model instance
14
14
  # @param object A model instance to check
15
- # @param attribute A symbol or string for attribute name to check for
15
+ # @param attribute A symbol or string for attribute name to check for
16
16
  # errors
17
17
  def errors_on(object, attribute)
18
18
  error_message = object.errors[attribute].first
@@ -26,13 +26,13 @@ module Blogit
26
26
  end
27
27
 
28
28
  # A helper method for creating a +<div>+ tag with class 'actions'
29
- # Used for option links and form buttons
29
+ # Used for option links and form buttons
30
30
  def actions(content_or_options={}, options ={}, &block)
31
31
  div_with_default_class(:actions, content_or_options, options, &block)
32
32
  end
33
33
 
34
34
  # A helper method for creating a +<div>+ tag with class 'login_required'
35
- # Will only render content if there is a logged in user
35
+ # Will only render content if there is a logged in user
36
36
  def login_required(content_or_options={}, options ={}, &block)
37
37
  if current_blogger and blogit_conf.include_admin_links
38
38
  div_with_default_class(:login_required, content_or_options, options, &block)
@@ -57,12 +57,31 @@ module Blogit
57
57
  content_tag(:time, time_string, options)
58
58
  end
59
59
 
60
+ # Can search for named routes directly in the main app, omitting
61
+ # the "main_app." prefix
62
+ def method_missing method, *args, &block
63
+ if main_app_url_helper?(method)
64
+ main_app.send(method, *args)
65
+ else
66
+ super
67
+ end
68
+ end
69
+ def respond_to?(method)
70
+ main_app_url_helper?(method) or super
71
+ end
72
+
60
73
  private
61
74
 
75
+ def main_app_url_helper?(method)
76
+ Blogit::configuration.inline_main_app_named_routes and
77
+ (method.to_s.end_with?('_path') or method.to_s.end_with?('_url')) and
78
+ main_app.respond_to?(method)
79
+ end
80
+
62
81
  def div_with_default_class(default_class, content_or_options={}, options={}, &block)
63
82
  if block_given?
64
83
  content = capture(&block)
65
- options = content_or_options
84
+ options = content_or_options
66
85
  else
67
86
  content = content_or_options
68
87
  end
@@ -1,8 +1,8 @@
1
1
  module Blogit
2
2
  module PostsHelper
3
-
3
+
4
4
  # Creates a div tag with class 'blog_post_' + name
5
- # Eg:
5
+ # Eg:
6
6
  # blog_post_tag(:title, "") # => <div class="blog_post_title"></div>
7
7
  def blog_post_tag(name, content_or_options = {}, options ={}, &block)
8
8
  if block_given?
@@ -14,6 +14,50 @@ module Blogit
14
14
  options[:class] = "#{options[:class]} blog_post_#{name}".strip
15
15
  content_tag(name, content, options)
16
16
  end
17
-
17
+
18
+ # A comments tag corresponding to the comments configuration
19
+ def comments_for(post)
20
+ render(partial: "blogit/posts/#{Blogit.configuration.include_comments}_comments", locals: { post: post, comment: Blogit::Comment.new })
21
+ end
22
+
23
+ # A share bar as configured
24
+ def share_bar_for(post)
25
+ if !Blogit.configuration.include_share_bar
26
+ ""
27
+ else
28
+ render(partial: "blogit/posts/share_bar", locals: { post: post})
29
+ end
30
+ end
31
+
32
+ # Creates a ul tag tree with posts by year and monthes. Include
33
+ # blogit/archive.js to enabled expand collapse.
34
+ # @param year_css [String, Symbol] The CSS class of the year UL tag
35
+ # @param month_css [String, Symbol] The CSS class of the month UL tag
36
+ # @param post_css [String, Symbol] The CSS class of the year LI tag
37
+ # @param archive_posts [ActiveRecord::Relation, Array] The posts to be included in the archive (defaults to Post.all)
38
+ def blog_posts_archive_tag(year_css, month_css, post_css, archive_posts = Post.all)
39
+ posts_tree = archive_posts.chunk {|post| post.created_at.year}.map do |year, posts_of_year|
40
+ [year, posts_of_year.chunk {|post| l(post.created_at, format: :plain_month_only) }]
41
+ end
42
+
43
+ result = []
44
+ result << "<ul class=\"#{year_css}\">"
45
+ posts_tree.each do |year, posts_by_month|
46
+ result << "<li><a data-blogit-click-to-toggle-children>#{year}</a><ul class=\"#{month_css}\">"
47
+ posts_by_month.each do |month, posts|
48
+ result << "<li><a data-blogit-click-to-toggle-children>#{CGI.escape_html(month)}</a><ul class=\"#{post_css}\">"
49
+ posts.each do |post|
50
+ result << "<li><a href=\"#{blogit.post_path(post)}\">#{CGI.escape_html(post.title)}</a></li>"
51
+ end
52
+ result << "</ul></li>"
53
+ end
54
+ result << "</ul></li>"
55
+ end
56
+ result << "</ul>"
57
+
58
+ result.join.html_safe
59
+ end
60
+
18
61
  end
62
+
19
63
  end
@@ -30,6 +30,8 @@ module Blogit
30
30
  # = Attributes =
31
31
  # ==============
32
32
 
33
+ attr_accessible :name, :nickname, :email, :body, :website
34
+
33
35
  # nickname acts as a "honeypot" to catch spam
34
36
  # the form field should be hidden using CSS and so
35
37
  # if present, must be spam.
@@ -3,13 +3,18 @@ module Blogit
3
3
 
4
4
  require "acts-as-taggable-on"
5
5
  require "kaminari"
6
-
7
- acts_as_taggable
6
+
7
+ acts_as_taggable
8
8
 
9
9
  self.table_name = "blog_posts"
10
10
 
11
11
  self.paginates_per Blogit.configuration.posts_per_page
12
12
 
13
+ # ==============
14
+ # = Attributes =
15
+ # ==============
16
+ attr_accessible :title, :body, :tag_list
17
+
13
18
  # ===============
14
19
  # = Validations =
15
20
  # ===============
@@ -20,12 +25,19 @@ module Blogit
20
25
 
21
26
  # =================
22
27
  # = Assosciations =
23
- # =================
28
+ # =================
24
29
 
25
30
  belongs_to :blogger, :polymorphic => true
26
31
 
27
- if Blogit.configuration.include_comments
28
- has_many :comments, :class_name => "Blogit::Comment"
32
+ has_many :comments, :class_name => "Blogit::Comment"
33
+
34
+ def comments
35
+ check_comments_config
36
+ super()
37
+ end
38
+ def comments=(value)
39
+ check_comments_config
40
+ super(value)
29
41
  end
30
42
 
31
43
  # ==========
@@ -48,13 +60,19 @@ module Blogit
48
60
  # Otherwise, returns an empty string
49
61
  def blogger_display_name
50
62
  if self.blogger and !self.blogger.respond_to?(Blogit.configuration.blogger_display_name_method)
51
- raise ConfigurationError,
63
+ raise ConfigurationError,
52
64
  "#{self.blogger.class}##{Blogit.configuration.blogger_display_name_method} is not defined"
53
65
  elsif self.blogger.nil?
54
66
  ""
55
67
  else
56
- self.blogger.send Blogit.configuration.blogger_display_name_method
68
+ self.blogger.send Blogit.configuration.blogger_display_name_method
57
69
  end
58
70
  end
71
+
72
+ private
73
+
74
+ def check_comments_config
75
+ raise RuntimeError.new("Posts only allow active record comments (check blogit configuration)") unless Blogit.configuration.include_comments == :active_record
76
+ end
59
77
  end
60
- end
78
+ end
@@ -1,3 +1,3 @@
1
1
  <%= login_required(class: "actions") do %>
2
- <%= link_to("delete", [@post, @comment], method: :delete) %>
3
- <% end %>
2
+ <%= link_to(t(:delete, scope: 'blogit.comments'), [@post, comment], method: :delete, confirm: t(:are_you_sure_you_want_to_remove_this_comment, scope: 'blogit.comments')) %>
3
+ <% end %>
@@ -1,19 +1,19 @@
1
1
  <%= content_tag(:article, id: "blog_comment_#{comment.id}", class: "blog_comment") do %>
2
2
  <%= content_tag(:div, class: "blog_comment_name", id: "blog_comment_#{comment.id}_name") do %>
3
- <%= comment.website? ? link_to(comment.name, comment.website) : comment.name %> wrote:
3
+ <%=t :wrote, scope: 'blogit.comments', author: comment.website? ? link_to(comment.name, comment.website) : comment.name %>
4
4
  <% end %>
5
-
6
5
 
7
- <%= content_tag(:div, class: "blog_comment_body",
6
+
7
+ <%= content_tag(:div, class: "blog_comment_body",
8
8
  id: "blog_comment_#{comment.id}_body") do %>
9
9
  <%= format_content comment.body || "" %>
10
10
  <% end %>
11
-
11
+
12
12
  <%= blog_comment_tag(:footer) do %>
13
- Posted on <%= time_tag(comment.created_at, Blogit.configuration.datetime_format) %>
13
+ <%=t :posted_on, scope: 'blogit.comments'%> <%= time_tag(comment.created_at, Blogit.configuration.datetime_format) %>
14
14
  <% end %>
15
-
16
- <%= render partial: "blogit/comments/admin_links" %>
17
-
15
+
16
+ <%= render partial: "blogit/comments/admin_links", locals: {comment: comment} %>
17
+
18
18
  <% end if comment.persisted? %>
19
19
 
@@ -1,42 +1,41 @@
1
1
 
2
- <%= form_for [@post, @comment], remote: true,
2
+ <%= form_for [post, comment], remote: true,
3
3
  html: {
4
4
  class: "new_blog_comment", id: "new_blog_comment" } do |f| -%>
5
-
6
- <p>Leave a comment</p>
7
-
5
+
6
+ <p><%=t :leave_a_comment, scope: 'blogit.comments'%></p>
7
+
8
8
  <%= field class: "hidden" do %>
9
9
  <%= f.label :nickname %>
10
10
  <%= f.text_field :nickname %>
11
11
  Hide me using CSS
12
12
  <% end %>
13
-
13
+
14
14
  <%= field do %>
15
- <%= f.label :name, "Name *" %><br>
15
+ <%= f.label :name, t(:name, scope: 'blogit.comments') %><br>
16
16
  <%= f.text_field :name %>
17
- <%= errors_on(@comment, :name) %>
17
+ <%= errors_on(comment, :name) %>
18
18
  <% end %>
19
-
19
+
20
20
  <%= field do %>
21
- <%= f.label :email, "Email" %> (never displayed)<br>
21
+ <%= f.label :email, t(:email_never_displayed, scope: 'blogit.comments') %><br>
22
22
  <%= f.email_field :email %>
23
- <%= errors_on(@comment, :email) %>
23
+ <%= errors_on(comment, :email) %>
24
24
  <% end %>
25
25
 
26
26
  <%= field do %>
27
- <%= f.label :website, "Your Website" %><br>
27
+ <%= f.label :website, t(:your_website, scope: 'blogit.comments') %><br>
28
28
  <%= f.url_field :website %>
29
- <%= errors_on(@comment, :website) %>
29
+ <%= errors_on(comment, :website) %>
30
30
  <% end %>
31
31
 
32
-
33
32
  <%= field do %>
34
- <%= f.label :body, "Your comment *" %><br>
33
+ <%= f.label :body, t(:your_comment, scope: 'blogit.comments') %><br>
35
34
  <%= f.text_area :body %><br>
36
- <%= errors_on(@comment, :body) %>
35
+ <%= errors_on(comment, :body) %>
37
36
  <% end %>
38
-
37
+
39
38
  <%= actions do %>
40
- <%= f.submit "Add Comment", :disable_with => 'Adding Comment...' %>
39
+ <%= f.submit t(:add_comment, scope: 'blogit.comments'), :disable_with => t(:adding_comment, scope: 'blogit.comments') %>
41
40
  <% end %>
42
- <% end -%>
41
+ <% end -%>