blogit 0.4.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 -%>