blogit 1.0.0.rc1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -31
  3. data/Rakefile +6 -2
  4. data/app/assets/stylesheets/blogit/themes/default.css +4 -0
  5. data/app/assets/stylesheets/blogit/themes/default.css.map +7 -0
  6. data/app/assets/stylesheets/blogit/themes/default.min.css +2 -0
  7. data/app/assets/stylesheets/blogit/themes/default.min.css.map +7 -0
  8. data/app/assets/stylesheets/blogit/themes/default.sass +2 -0
  9. data/app/assets/stylesheets/blogit/themes/default/base/_colors.sass +1 -0
  10. data/app/assets/stylesheets/blogit/themes/default/base/_typography.sass +1 -0
  11. data/app/assets/stylesheets/blogit/themes/default/blocks/_archives.sass +18 -0
  12. data/app/assets/stylesheets/blogit/themes/default/blocks/_comments.sass +7 -0
  13. data/app/assets/stylesheets/blogit/themes/default/blocks/_forms.sass +9 -0
  14. data/app/assets/stylesheets/blogit/themes/default/blocks/_headers.sass +4 -0
  15. data/app/assets/stylesheets/blogit/themes/default/blocks/_posts.sass +8 -0
  16. data/app/assets/stylesheets/blogit/themes/default/blocks/_related_posts_list.sass +3 -0
  17. data/app/assets/stylesheets/blogit/themes/default/blocks/_share_bars.sass +7 -0
  18. data/app/{views/blogit/posts/_no_comments.html.erb → assets/stylesheets/blogit/themes/default/blocks/_tag_list.sass} +0 -0
  19. data/app/assets/stylesheets/blogit/themes/default/blocks/_tags.sass +4 -0
  20. data/app/controllers/blogit/application_controller.rb +15 -31
  21. data/app/controllers/blogit/comments_controller.rb +48 -30
  22. data/app/controllers/blogit/posts_controller.rb +52 -86
  23. data/app/helpers/blogit/application_helper.rb +59 -69
  24. data/app/helpers/blogit/comments_helper.rb +20 -0
  25. data/app/helpers/blogit/layout_helper.rb +33 -0
  26. data/app/helpers/blogit/posts_helper.rb +36 -34
  27. data/app/models/blogit/post.rb +55 -6
  28. data/app/views/blogit/archive/_list.html.erb +5 -0
  29. data/app/views/blogit/archive/_month.html.erb +9 -0
  30. data/app/views/blogit/archive/_year.html.erb +7 -0
  31. data/app/views/blogit/{posts → comments}/_active_record_comments.html.erb +2 -1
  32. data/app/views/blogit/comments/_comment.html.erb +10 -14
  33. data/app/views/blogit/comments/_comments_count.html.erb +8 -0
  34. data/app/views/blogit/{posts → comments}/_disqus_comments.html.erb +0 -0
  35. data/app/views/blogit/comments/_form.html.erb +25 -18
  36. data/app/views/blogit/comments/_no_comments.html.erb +0 -0
  37. data/app/views/blogit/comments/create.js.erb +2 -2
  38. data/app/views/blogit/posts/_archiveable.html.erb +3 -0
  39. data/app/views/blogit/posts/_blog_post_spacer.html.erb +1 -1
  40. data/app/views/blogit/posts/_blogger_information.html.erb +9 -4
  41. data/app/views/blogit/posts/_meta_tags.html.erb +32 -0
  42. data/app/views/blogit/posts/_post.html.erb +6 -9
  43. data/app/views/blogit/posts/_post_footer.html.erb +1 -0
  44. data/app/views/blogit/posts/_post_head.html.erb +3 -2
  45. data/app/views/blogit/posts/_related.html.erb +7 -16
  46. data/app/views/blogit/posts/_related_post.html.erb +4 -0
  47. data/app/views/blogit/posts/_share_bar.html.erb +5 -6
  48. data/app/views/blogit/posts/_tags.html.erb +8 -0
  49. data/app/views/blogit/posts/index.html.erb +16 -11
  50. data/app/views/blogit/posts/show.html.erb +28 -4
  51. data/app/views/blogit/tags/_tag.html.erb +3 -0
  52. data/config/locales/en.yml +3 -2
  53. data/config/spring.rb +1 -0
  54. data/db/migrate/20150618184415_add_description_to_posts.rb +5 -0
  55. data/lib/blogit.rb +4 -5
  56. data/lib/blogit/archive.rb +8 -0
  57. data/lib/blogit/archive/archive_error.rb +3 -0
  58. data/lib/blogit/archive/archiveable.rb +20 -0
  59. data/lib/blogit/archive/list.rb +52 -0
  60. data/lib/blogit/archive/month.rb +34 -0
  61. data/lib/blogit/archive/year.rb +40 -0
  62. data/lib/blogit/blogs.rb +11 -5
  63. data/lib/blogit/configuration.rb +157 -147
  64. data/lib/blogit/parsers/html_parser.rb +6 -3
  65. data/lib/blogit/parsers/markdown_parser.rb +30 -5
  66. data/lib/blogit/parsers/textile_parser.rb +18 -8
  67. data/lib/blogit/renderers/html_with_albino.rb +1 -1
  68. data/lib/blogit/version.rb +1 -1
  69. data/lib/generators/templates/blogit.rb +23 -57
  70. data/lib/tasks/blogit.rake +42 -0
  71. data/lib/tasks/blogit/css.rake +22 -0
  72. data/lib/tasks/blogit/doc.rake +21 -0
  73. data/lib/tasks/seed_blog_posts.yml +95 -0
  74. data/lib/validators/absence_validator.rb +2 -2
  75. data/spec/blogit_spec.rb +3 -3
  76. data/spec/controllers/blogit/comments_controller_spec.rb +31 -86
  77. data/spec/controllers/blogit/posts_controller_spec.rb +33 -344
  78. data/spec/dummy/Rakefile +1 -1
  79. data/spec/dummy/app/assets/stylesheets/application.sass +7 -0
  80. data/spec/dummy/app/assets/stylesheets/base.sass +1 -0
  81. data/spec/dummy/app/assets/stylesheets/base/_html.sass +15 -0
  82. data/spec/dummy/app/assets/stylesheets/blocks.sass +1 -0
  83. data/spec/dummy/app/assets/stylesheets/blocks/_layout.sass +21 -0
  84. data/spec/dummy/app/views/layouts/application.html.erb +21 -18
  85. data/spec/dummy/app/views/layouts/custom.html.erb +2 -1
  86. data/spec/dummy/config.ru +0 -1
  87. data/spec/dummy/config/application.rb +1 -0
  88. data/spec/dummy/config/database.yml +5 -3
  89. data/spec/dummy/config/environments/production.rb +7 -2
  90. data/spec/dummy/config/environments/test.rb +6 -1
  91. data/spec/dummy/db/development.sqlite3 +0 -0
  92. data/spec/dummy/db/migrate/{20140511174024_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb → 20150619080551_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb} +0 -0
  93. data/spec/dummy/db/migrate/{20140511174025_add_missing_unique_indices.acts_as_taggable_on_engine.rb → 20150619080552_add_missing_unique_indices.acts_as_taggable_on_engine.rb} +0 -0
  94. data/spec/dummy/db/migrate/{20140511174026_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb → 20150619080553_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb} +0 -0
  95. data/spec/dummy/db/migrate/20150619080554_add_missing_taggable_index.acts_as_taggable_on_engine.rb +10 -0
  96. data/spec/dummy/db/migrate/20150619080555_change_collation_for_tag_names.acts_as_taggable_on_engine.rb +10 -0
  97. data/spec/dummy/db/schema.rb +9 -7
  98. data/spec/dummy/db/seeds.rb +17 -0
  99. data/spec/dummy/lib/tasks/dummy.rake +29 -0
  100. data/spec/dummy/log/development.log +22286 -1489
  101. data/spec/dummy/log/test.log +4608 -11518
  102. data/spec/factories.rb +10 -5
  103. data/spec/helpers/blogit/application_helper_spec.rb +10 -73
  104. data/spec/helpers/blogit/posts_helper_spec.rb +8 -63
  105. data/spec/injectables/dummy_archiveable.rb +6 -0
  106. data/spec/lib/archive/list_spec.rb +60 -0
  107. data/spec/lib/archive/month_spec.rb +17 -0
  108. data/spec/lib/archive/year_spec.rb +38 -0
  109. data/spec/lib/blogit/parsers/html_parser_spec.rb +1 -1
  110. data/spec/lib/blogit/parsers/markdown_parser_spec.rb +7 -6
  111. data/spec/lib/blogit/parsers/textile_parser_spec.rb +1 -1
  112. data/spec/lib/blogs_spec.rb +2 -2
  113. data/spec/lib/configuration_spec.rb +21 -49
  114. data/spec/models/blogit/comment_spec.rb +19 -19
  115. data/spec/models/blogit/post_spec.rb +63 -28
  116. data/spec/rails_helper.rb +28 -0
  117. data/spec/spec_helper.rb +2 -11
  118. data/spec/support/helpers/css_matchers.rb +42 -0
  119. metadata +193 -124
  120. data/app/assets/stylesheets/blogit/index.css +0 -84
  121. data/app/views/blogit/comments/_admin_links.html.erb +0 -3
  122. data/app/views/blogit/posts/_comments_count.html.erb +0 -5
  123. data/app/views/blogit/posts/_form.html.erb +0 -49
  124. data/app/views/blogit/posts/_post_body.html.erb +0 -1
  125. data/app/views/blogit/posts/_post_links.html.erb +0 -6
  126. data/app/views/blogit/posts/edit.html.erb +0 -3
  127. data/app/views/blogit/posts/new.html.erb +0 -3
  128. data/lib/tasks/blog_tasks.rake +0 -4
  129. data/spec/dummy/app/assets/stylesheets/application.css +0 -21
  130. data/spec/dummy/config/initializers/blogit.rb +0 -88
  131. data/spec/dummy/db/migrate/20140511174028_create_blogit_posts.blogit.rb +0 -16
  132. data/spec/dummy/db/migrate/20140511174029_create_blogit_comments.blogit.rb +0 -16
  133. data/spec/dummy/db/test.sqlite3 +0 -0
  134. data/spec/dummy/tmp/cache/assets/CB5/DD0/sprockets%2F346324d2a51df58457807bee661c449c +0 -0
  135. data/spec/dummy/tmp/cache/assets/CB6/ED0/sprockets%2F4390d06699f3ad4262e342be530f9f91 +0 -0
  136. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  137. data/spec/dummy/tmp/cache/assets/CE7/230/sprockets%2F6f493a817d97133a8dbf674bcd322670 +0 -0
  138. data/spec/dummy/tmp/cache/assets/CEA/490/sprockets%2F9697d4fb1ed26d80f3c715611c8d4373 +0 -0
  139. data/spec/dummy/tmp/cache/assets/CEE/310/sprockets%2F89642af8492e579dcd7162a0e2b7f155 +0 -0
  140. data/spec/dummy/tmp/cache/assets/D01/8C0/sprockets%2F332d5a9ce3e800c6c4a7a99058023ba2 +0 -0
  141. data/spec/dummy/tmp/cache/assets/D11/CC0/sprockets%2F3a12dfa6665b5318fa99d097203ac7e7 +0 -0
  142. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  143. data/spec/dummy/tmp/cache/assets/D3D/1E0/sprockets%2Ffbaabd57fa2c9d426f0c318156705667 +0 -0
  144. data/spec/dummy/tmp/cache/assets/D3E/920/sprockets%2F3efa8d0fc958c223647cb704183b65ca +0 -0
  145. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  146. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  147. data/spec/dummy/tmp/cache/assets/D61/6F0/sprockets%2F02da53eeca228bcef0c49278517111fe +0 -0
  148. data/spec/dummy/tmp/cache/assets/DCA/9B0/sprockets%2Fdf0e8f8a85e5d4056b3fe1cec3b7131a +0 -0
  149. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  150. data/spec/dummy/tmp/cache/assets/E02/A60/sprockets%2Fb32faeede196f7a933c3a2794e7ed0bd +0 -0
  151. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  152. data/spec/dummy/tmp/cache/assets/development/sprockets/02da53eeca228bcef0c49278517111fe +0 -0
  153. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  154. data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  155. data/spec/dummy/tmp/cache/assets/development/sprockets/2ff93f9f5ed9970021c7704ff93237c8 +0 -0
  156. data/spec/dummy/tmp/cache/assets/development/sprockets/332d5a9ce3e800c6c4a7a99058023ba2 +0 -0
  157. data/spec/dummy/tmp/cache/assets/development/sprockets/346324d2a51df58457807bee661c449c +0 -0
  158. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  159. data/spec/dummy/tmp/cache/assets/development/sprockets/3a12dfa6665b5318fa99d097203ac7e7 +0 -0
  160. data/spec/dummy/tmp/cache/assets/development/sprockets/3ed52366904e135bd833590814b6ac6d +0 -0
  161. data/spec/dummy/tmp/cache/assets/development/sprockets/4390d06699f3ad4262e342be530f9f91 +0 -0
  162. data/spec/dummy/tmp/cache/assets/development/sprockets/6f493a817d97133a8dbf674bcd322670 +0 -0
  163. data/spec/dummy/tmp/cache/assets/development/sprockets/89642af8492e579dcd7162a0e2b7f155 +0 -0
  164. data/spec/dummy/tmp/cache/assets/development/sprockets/89dc196c51ae83634b664c0c33052008 +0 -0
  165. data/spec/dummy/tmp/cache/assets/development/sprockets/8dd8236b00c868ba248fe30cd9c14c2a +0 -0
  166. data/spec/dummy/tmp/cache/assets/development/sprockets/9239a04d094a872c1cf77ac391072ea8 +0 -0
  167. data/spec/dummy/tmp/cache/assets/development/sprockets/b3ffb6bd243399012806331ce393ae4f +0 -0
  168. data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  169. data/spec/dummy/tmp/cache/assets/development/sprockets/d53accc3e58037ee4005e41221b8846b +0 -0
  170. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  171. data/spec/dummy/tmp/cache/assets/development/sprockets/df0e8f8a85e5d4056b3fe1cec3b7131a +0 -0
  172. data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  173. data/spec/routing/post_routing_spec.rb +0 -49
@@ -3,21 +3,45 @@ class Blogit::Parsers::MarkdownParser
3
3
  require "nokogiri"
4
4
  require "albino"
5
5
  require "blogit/renderers"
6
-
6
+
7
+ # A String containing the content to be parsed
8
+ attr_reader :content
9
+
7
10
  def initialize(content)
8
11
  @content = content
9
12
  end
10
13
 
14
+ # The parsed content
15
+ #
16
+ # Returns an HTML safe String
11
17
  def parsed
12
18
  ensure_pygments_is_installed if Blogit::configuration.highlight_code_syntax
13
-
14
- renderer = Blogit::configuration.highlight_code_syntax ? Redcarpet::Render::HTMLWithAlbino : Redcarpet::Render::HTML
15
- markdown = Redcarpet::Markdown.new(renderer, Blogit.configuration.redcarpet_options)
16
- html_content = markdown.render(@content).html_safe
19
+ markdown.render(content).html_safe
17
20
  end
18
21
 
22
+
19
23
  private
20
24
 
25
+
26
+ # The Redcarpet renderer to use
27
+ def renderer
28
+ if Blogit::configuration.highlight_code_syntax
29
+ Redcarpet::Render::HTMLWithAlbino
30
+ else
31
+ Redcarpet::Render::HTML
32
+ end
33
+ end
34
+
35
+ # The Redcarpet Markdown handler
36
+ def markdown
37
+ @markdown ||= Redcarpet::Markdown.new(renderer,
38
+ Blogit.configuration.redcarpet_options)
39
+ end
40
+
41
+
42
+ # Ensures pygments is installed
43
+ #
44
+ # Raises StandardError if pygments is not available on this machine
21
45
  def ensure_pygments_is_installed
22
46
  warning = <<-WARNING
23
47
  [blogit] The pygmentize command could not be found in your load path!
@@ -34,6 +58,7 @@ WARNING
34
58
  end
35
59
 
36
60
  # Check if an executable exists in the load path
61
+ #
37
62
  # Returns nil if no executable is found
38
63
  def which(cmd)
39
64
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
@@ -1,13 +1,23 @@
1
- class Blogit::Parsers::TextileParser
1
+ module Blogit
2
+ module Parsers
3
+ class TextileParser
2
4
 
3
- require "redcloth"
5
+ require "redcloth"
6
+
7
+ # A String containing the content to be parsed
8
+ attr_reader :content
4
9
 
5
- def initialize(content)
6
- @content = content
7
- end
10
+ def initialize(content)
11
+ @content = content
12
+ end
8
13
 
9
- def parsed
10
- RedCloth.new(@content).to_html
14
+ # The parsed content
15
+ #
16
+ # Returns an HTML safe String
17
+ def parsed
18
+ RedCloth.new(content).to_html
19
+ end
20
+
21
+ end
11
22
  end
12
-
13
23
  end
@@ -1,4 +1,4 @@
1
- # create a custom renderer that allows highlighting of code blocks
1
+ # Create a custom renderer that allows highlighting of code blocks
2
2
  class Redcarpet::Render::HTMLWithAlbino < Redcarpet::Render::HTML
3
3
 
4
4
  def block_code(code, language)
@@ -1,3 +1,3 @@
1
1
  module Blogit
2
- VERSION = "1.0.0.rc1"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -2,95 +2,61 @@
2
2
  Blogit.configure do |config|
3
3
 
4
4
  # What kind of comments do you want to add to your blog ? (:active_record, :disqus or :no)
5
- # config.include_comments = :active_record
5
+ config.include_comments = :active_record
6
6
 
7
7
  # When using disqus comments, what is the shortname of your forum ?
8
- # config.disqus_shortname = ""
8
+ config.disqus_shortname = "YOURUSERNAME"
9
9
 
10
10
  # Should there be a share bar on every post ?
11
- # config.include_share_bar = false
11
+ config.include_share_bar = true
12
12
 
13
13
  # Twitter username used in the share bar
14
- # config.twitter_username = ""
15
-
16
- # The name of the controller method we'll call to return the current blogger.
17
- # Change this if you use something other than current_user.
18
- # Eg. current_admin_user (if using ActiveAdmin)
19
- # config.current_blogger_method = :current_user
14
+ config.twitter_username = "@YOURUSERNAME"
20
15
 
21
16
  # What method do we call on blogger to show who they are?
22
- # config.blogger_display_name_method = :username
17
+ config.blogger_display_name_method = :username
23
18
 
24
19
  # Which DateTime::FORMATS format do we use to display blog and comment publish time
25
- # config.datetime_format = :short
20
+ config.datetime_format = :short
26
21
 
27
22
  # No. of posts to show per page
28
- # config.posts_per_page = 5
29
-
30
- # The name of the before filter we'll call to authenticate the current user.
31
- # config.authentication_method = :login_required
23
+ config.posts_per_page = 5
32
24
 
33
25
  # If set to true, the comments form will POST and DELETE to the comments
34
26
  # controller using AJAX calls.
35
- # config.ajax_comments = true
36
-
37
- # If set to true, the create, edit, update and destroy actions
38
- # will be included. If set to false, you'll have to set these
39
- # yourself elsewhere in the app.
40
- # config.include_admin_actions = true
41
-
42
- # If set to true, links for new posts, editing posts and deleting comments
43
- # will be available. If set to false, you'll have to set these
44
- # yourself in the templates.
45
- # config.include_admin_links = true
27
+ config.ajax_comments = true
46
28
 
47
29
  # The default format for parsing the blog content.
48
- # config.default_parser = :markdown
30
+ config.default_parser = :markdown
49
31
 
50
32
  # If blog content contains code, this should be highlighted using
51
33
  # albino.
52
- # config.highlight_code_syntax = true
34
+ config.highlight_code_syntax = true
53
35
 
54
36
  # RSS Feed title content
55
- # config.rss_feed_title = "A blog about ponies!"
37
+ config.rss_feed_title = "#{Rails.application.engine_name.titleize} Blog Posts"
56
38
 
57
39
  # RSS Feed description content
58
- # config.rss_feed_description = "Get your daily pony news here!"
59
-
60
- # Should blogit ping search engines with your sitemap
61
- # when posts are created, updated or destroyed?
62
- #
63
- # Can pass true to ping all supported search engines, or an array of search
64
- # engine names. e.g. [:google, :bing]
65
- #
66
- # Defaults to false
67
- # config.ping_search_engines = false
40
+ config.rss_feed_description = "Latest from #{Rails.application.engine_name.titleize}"
68
41
 
69
42
  # When using redcarpet as content parser, pass these options as defaults.
70
43
  # @see here for more options: https://github.com/tanoku/redcarpet
71
- # config.redcarpet_options = {
72
- # hard_wrap: true,
73
- # filter_html: true,
74
- # autolink: true,
75
- # no_intraemphasis: true,
76
- # fenced_code_blocks: true,
77
- # gh_blockcode: true
78
- # }
79
-
80
- # If set to true, it will be possible to call named routes of the main app
81
- # directly, without the "main_app." prefix.
82
- # Useful in the case where you don't want to change the main app's layout,
83
- # but it does not expand correctly from inside blogit because some main
84
- # app's named routes are missing.
85
- # config.inline_main_app_named_routes = true
44
+ config.redcarpet_options = {
45
+ hard_wrap: true,
46
+ filter_html: true,
47
+ autolink: true,
48
+ no_intraemphasis: true,
49
+ fenced_code_blocks: true,
50
+ gh_blockcode: true
51
+ }
86
52
 
87
53
  # If this is set, Blogit::PostsController will use the layout named here
88
- # config.layout = "custom_layout"
54
+ config.layout = "application"
89
55
 
90
56
  # List of states that will be visible to the public
91
- # config.active_states = [:published]
57
+ config.active_states = [:published]
92
58
 
93
59
  # List of states that will hide the posts from the public.
94
- # config.hidden_states = [:draft, :archive]
60
+ config.hidden_states = [:draft, :archive]
95
61
 
96
62
  end
@@ -0,0 +1,42 @@
1
+ require 'yaml'
2
+ load "lib/tasks/blogit/css.rake"
3
+
4
+ namespace :blogit do
5
+
6
+ desc "Add a bunch of mock blog posts to the database for dev"
7
+ task :seed => :environment do
8
+ if Rails.env.production?
9
+ warn "Can't seed your production database bro, too risky!"
10
+ else
11
+ load_all_models
12
+ seed_blog_content.each do |blog_post_atts|
13
+ state = Blogit.configuration.active_states.first
14
+ begin
15
+ blogger.first.blog_posts.create!(blog_post_atts.merge(state: state))
16
+ rescue NoMethodError
17
+ warn "Couldn't find a blogger model record :("
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+
24
+ private
25
+
26
+
27
+ def seed_blog_content
28
+ YAML.load(File.read(File.join(File.dirname(__FILE__), "seed_blog_posts.yml")))
29
+ end
30
+
31
+
32
+ def load_all_models
33
+ Dir[Rails.root.join("app/models/**/*.rb")].each { |file| load file }
34
+ end
35
+
36
+ # The fellow who's going to write these posts...
37
+ def blogger
38
+ ActiveRecord::Base.subclasses.detect(&:blogs?) ||
39
+ warn("Can't seed your database, couldn't find a model that #blogs?")
40
+ end
41
+
42
+ end
@@ -0,0 +1,22 @@
1
+ namespace :blogit do
2
+
3
+ desc "Alias of blogit:css:compile"
4
+ task :css => [:"css:compile"]
5
+
6
+ namespace :css do
7
+
8
+ desc "Compiles blogit sass files to css and .min.css"
9
+ task :compile do
10
+ system "sass -r sass-globbing --no-cache --quiet \
11
+ --load-path=app/assets/stylesheets/blogit/themes \
12
+ app/assets/stylesheets/blogit/themes/default.sass \
13
+ app/assets/stylesheets/blogit/themes/default.css"
14
+
15
+ system "sass -r sass-globbing --no-cache --quiet --style=compressed \
16
+ --load-path=app/assets/stylesheets/blogit/themes \
17
+ app/assets/stylesheets/blogit/themes/default.sass \
18
+ app/assets/stylesheets/blogit/themes/default.min.css"
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ namespace :blogit do
2
+
3
+ desc "Alias of blogit:doc:compile"
4
+ task :doc => [:"doc:compile"]
5
+
6
+ namespace :doc do
7
+
8
+
9
+ DOC_FILES = ["Contributing", "TODOS", "Upgrading"].map { |filename|
10
+ "./doc/#{filename}.md"
11
+ }.join(",")
12
+
13
+ desc "Builds the blogit documentation using YARD-Tomdoc"
14
+ task :compile do
15
+ system("yard --plugin tomdoc --markup markdown --readme ./doc/Home.md "\
16
+ "--files #{DOC_FILES} "\
17
+ "--title 'Blogit - Add a blog to your Ruby on Rails application'")
18
+ end
19
+ end
20
+
21
+ end
@@ -0,0 +1,95 @@
1
+ -
2
+ title: Everything you wanted to know about the Honey-Badger
3
+
4
+ # Courtesy of Wikipedia: https://en.wikipedia.org/wiki/Honey_badger
5
+ description: |
6
+ The honey badger (Mellivora capensis), also known as the ratel or is a species of mustelid native to Africa, Southwest Asia, and the Indian subcontinent. Despite its name, the honey badger does not closely resemble other badger species; instead, it bears more anatomical similarities to weasels. It is classed as Least Concern by the IUCN owing to its extensive range and general environmental adaptations. It is primarily a carnivorous species and has few natural predators because of its thick skin and ferocious defensive abilities.
7
+
8
+ body: |
9
+ The honey badger has a fairly long body, but is distinctly thick-set and broad across the back. Its skin is remarkably loose, and allows it to turn and twist freely within it. The skin around the neck is 6 millimetres (0.24 in) thick, an adaptation to fighting conspecifics. The head is small and flat, with a short muzzle. The eyes are small, and the ears are little more than ridges on the skin, another possible adaptation to avoiding damage while fighting.
10
+
11
+ ### How it looks
12
+
13
+ The honey badger has short and sturdy legs, with five toes on each foot. The feet are armed with very strong claws, which are short on the hind legs and remarkably long on the forelimbs. It is a partially plantigrade animal whose soles are thickly padded and naked up to the wrists. The tail is short and is covered in long hairs, save for below the base.
14
+
15
+ Honey badgers are the largest terrestrial mustelids in Africa. Adults measure 23 to 28 cm (9.1 to 11.0 in) in shoulder height and 55–77 cm (22–30 in) in body length, with the tail adding another 12–30 cm (4.7–11.8 in). Females are smaller than males. Males weigh 9 to 16 kg (20 to 35 lb) while females weigh 5 to 10 kg (11 to 22 lb) on average. Skull length is 13.9–14.5 cm (5.5–5.7 in) in males and 13 cm (5.1 in) for females.
16
+
17
+ There are two pairs of mammae. The honey badger possesses an anal pouch which, unusual among mustelids, is eversible,d a trait shared with hyenas and mongooses. The smell of the pouch is reportedly "suffocating", and may assist in calming bees when raiding beehives.
18
+
19
+ The skull bears little similarity to that of the European badger, and greatly resembles a larger version of a marbled polecat skull. The skull is very solidly built, with that of adults having no trace of an independent bone structure. The braincase is broader than that of dogs."
20
+
21
+ tag_list: "honeybadger, badass, animal, awesome"
22
+
23
+ -
24
+ title: Why katanas are so cool
25
+ # Courtesy of Wikipedia: https://en.wikipedia.org/wiki/Katana
26
+ description: |
27
+ Historically, katana (刀) were one of the traditionally made Japanese swords (日本刀 nihontō) that were used by the samurai of feudal Japan. Modern versions of the katana are sometimes made using non-traditional materials and methods. The katana is characterized by its distinctive appearance: a curved, slender, single-edged blade with a circular or squared guard and long grip to accommodate two hands.
28
+
29
+ body: |
30
+ The production of swords in Japan is divided into specific time periods:
31
+
32
+ * Jokoto (ancient swords, until around 900 A.D.)
33
+ * Koto (old swords from around 900–1596)
34
+ * Shinto (new swords 1596–1780)
35
+ * Shinshinto (newer swords 1781–1876)
36
+ * Gendaito (modern swords 1876–1945)
37
+ * Shinsakuto (newly made swords 1953–present)
38
+
39
+ The first use of "katana" (gatana) as a word to describe a long sword that was different from a tachi occurs as early as the Kamakura Period (1185–1333). These references to "[uchigatana](https://en.wikipedia.org/wiki/Uchigatana)" and "tsubagatana" seem to indicate a different style of sword, possibly a less costly sword for lower-ranking warriors. The evolution of the tachi into the katana seems to have started during the early Muromachi period (1337 to 1573).
40
+
41
+ Starting around the year 1400, long swords signed with the "katana" signature were made. This was in response to samurai wearing their tachi in what is now called "katana style" (cutting edge up). Japanese swords are traditionally worn with the signature facing away from the wearer. When a tachi was worn in the style of a katana, with the cutting edge up, the tachi's signature would be facing the wrong way. The fact that swordsmiths started signing swords with a katana signature shows that some samurai of that time period had started wearing their swords in a different manner.
42
+
43
+ The rise in popularity of katana amongst samurai came about due to the changing nature of close-combat warfare. The quicker draw of the sword was well suited to combat where victory depended heavily on fast response times. The katana further facilitated this by being worn thrust through a belt-like sash (obi) with the sharpened edge facing up. Ideally, samurai could draw the sword and strike the enemy in a single motion. Previously, the curved tachi had been worn with the edge of the blade facing down and suspended from a belt.
44
+
45
+ The length of the katana blade varied considerably during the course of its history. In the late 14th and early 15th centuries, katana blades tended to have lengths between 70 and 73 cm (27½ and 28½ in). During the early 16th century, the average length approached closer to 60 cm (23½ in). By the late 16th century, the average length returned to approximately 73 cm (28½ in).
46
+
47
+ The katana was often paired with a similar smaller companion sword, such as a wakizashi or it could also be worn with the tantō, a smaller, similarly shaped dagger. The pairing of a katana with a smaller sword is called the daishō. Only samurai could wear the daisho: it represented the social power and personal honor of the [samurai](https://en.wikipedia.org/wiki/Samurai).
48
+
49
+ ## Modern katana (gendaito)
50
+
51
+ During the Meiji period, the samurai class was gradually disbanded, and the special privileges granted to them were taken away including the right to carry swords in public. The Haitōrei Edict in 1876 forbade the carrying of swords in public except for certain individuals, such as former samurai lords (daimyo), the military, and police. Skilled swordsmiths had trouble making a living during this period as Japan modernized its military, and many swordsmiths started making other items, such as farm equipment, tools, and cutlery. Military action by Japan in China and Russia during the Meiji period helped revive interest in swords, but it was not until the Showa period that swords were produced on a large scale again. Japanese military swords produced between 1875 and 1945 are referred to as guntō (military swords).
52
+
53
+ During the pre-World War II military buildup and throughout the war, all Japanese officers were required to wear a sword. Traditionally made swords were produced during this period, but in order to supply such large numbers of swords, blacksmiths with little or no knowledge of traditional Japanese sword manufacture were recruited. In addition, supplies of the Japanese steel (tamahagane) used for swordmaking were limited, so several other types of steel were used, as well. Quicker methods of forging were also used, such as the use of power-hammers, and quenching the blade in oil, rather than hand forging and water quenching. The non-traditionally made swords from this period are called "showato," after the regnal name of the Emperor Hirohito, and in 1937, the Japanese government started requiring the use of special stamps on the tang (nakago) to distinguish these swords from traditionally made swords. During this period of war, older antique swords were remounted for use in military mounts. Presently, in Japan, showato are not considered to be "true" Japanese swords, and they can be confiscated. Outside of Japan, however, they are collected as historical artifacts.
54
+
55
+ tag_list: "swords, katana, katanas, japan, awesome"
56
+ -
57
+ title: Have you ever tried this weird traditional food?!
58
+ description: |
59
+ Haggis is a savoury pudding containing sheep's pluck ([heart, liver and lungs](https://en.wikipedia.org/wiki/Offal)); minced with onion, oatmeal, suet, spices, and salt, mixed with stock, traditionally encased in the animal's stomach though now often in an artificial casing instead. According to the 2001 English edition of the Larousse Gastronomique: "Although its description is not immediately appealing, haggis has an excellent nutty texture and delicious savoury flavour".
60
+
61
+ It is believed that food similar to haggis (though not so named), perishable offal quickly cooked inside an animal's stomach, all conveniently available after a hunt, was eaten from ancient times.
62
+
63
+ body: |
64
+ Haggis is popularly assumed to be of Scottish origin, but there is a lack of historical evidence that could conclusively attribute its origins to any one place. The first known written recipes for a dish of the name made with offal and herbs, are, as "hagese", in the verse cookbook Liber Cure Cocorum dating from around 1430 in Lancashire, North West England, and, as "hagws of a schepe" from an English cookbook also of c1430.
65
+
66
+ > For hagese'.
67
+ > Þe hert of schepe, þe nere þou take,
68
+ > Þo bowel noght þou shalle forsake,
69
+ > On þe turbilen made, and boyled wele,
70
+ > Hacke alle togeder with gode persole,
71
+
72
+ The Scottish poem Flyting of Dunbar and Kennedy, which is dated before 1520 (the generally accepted date prior to the death of William Dunbar, one of the composers), refers to 'haggeis'.
73
+
74
+ > Thy fowll front had, and he that Bartilmo flaid;
75
+ > The gallowis gaipis eftir thy graceles gruntill, As thow wald for ane haggeis, hungry gled.
76
+ > — William Dunbar, Flyting of Dunbar and Kennedy
77
+
78
+ An early printed recipe for haggis appears in 1615 in “The English Huswife” by Gervase Markham. It contains a section entitled “Skill in Oate meale”.
79
+
80
+ > The use and vertues of these two severall kinds of Oate-meales in maintaining the Family, they are so many (according to the many customes of many Nations) that it is almost impossible to recken all;” and then proceeds to give a description of “oat-meale mixed with blood, and the Liver of either Sheepe, Calfe or Swine, maketh that pudding which is called the Haggas or Haggus, of whose goodnesse it is in vaine to boast, because there is hardly to be found a man that doth not affect them
81
+ > — Gervase Markham, The English Huswife
82
+
83
+ Food writer Alan Davidson suggests that the Ancient Romans were the first known to have made products of the haggis type. Even earlier, a kind of primitive haggis is referred to in Homer's Odyssey, in book 20, (towards the end of the eighth century BC) when Odysseus is compared to "a man before a great blazing fire turning swiftly this way and that a stomach full of fat and blood, very eager to have it roasted quickly." Haggis was "born of necessity, as a way to utilize the least expensive cuts of meat and the innards as well."
84
+
85
+ Clarissa Dickson Wright says that it "came to Scotland in a longship [i.e., from Scandinavia] even before Scotland was a single nation." She cites etymologist Walter William Skeat as further suggestion of possible Scandinavian origins: Skeat claimed that the hag– element of the word is derived from the Old Norse haggw or the Old Icelandic hoggva (höggva in modern Icelandic), Modern Scots hag, meaning 'to hew' or strike with a sharp weapon, relating to the chopped-up contents of the dish.
86
+
87
+ Dickson Wright suggests that haggis was invented as a way of cooking quick-spoiling offal near the site of a hunt, without the need to carry along an additional cooking vessel. The liver and kidneys could be grilled directly over a fire, but this treatment was unsuitable for the stomach, intestines, or lungs. Chopping up the lungs and stuffing the stomach with them and whatever fillers might have been on hand, then boiling the assembly—probably in a vessel made from the animal's hide—was one way to make sure these parts were not wasted.
88
+
89
+ ### Folklore
90
+
91
+ In the absence of hard facts as to haggis' origins, popular folklore has provided some notions. One is that the dish originates from the days of the old Scottish cattle drovers. When the men left the Highlands to drive their cattle to market in Edinburgh the women would prepare rations for them to eat during the long journey down through the glens. They used the ingredients that were most readily available in their homes and conveniently packaged them in a sheep's stomach allowing for easy transportation during the journey. Other speculations have been based on Scottish slaughtering practices. When a chieftain or laird required an animal to be slaughtered for meat (whether sheep or cattle) the workmen were allowed to keep the offal as their share.
92
+
93
+ A joke sometimes maintained is that a haggis is a small Scottish animal with longer legs on one side, so that it can run around the steep hills of the Scottish Highlands without falling over. The Hebridean Haggis is "thought" to be the original native species. The Lewis Haggis is different from the Haggis on the mainland: unlike its mainland relative all its legs are of the same length. According to one poll, 33% of American visitors to Scotland believed haggis to be an animal
94
+
95
+ tag_list: "Haggis, food, scotland"
@@ -1,9 +1,9 @@
1
1
  module Validators
2
2
 
3
- # Checks that an attribute is absent.
4
- # The opposite of PresenceValidator
3
+ # Checks that an attribute is absent. The opposite of Rails's PresenceValidator
5
4
  class AbsenceValidator < ActiveModel::EachValidator
6
5
 
6
+ # This is a Rails method for custom Validators. Please read {http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates_each the Rails docs} for more info
7
7
  def validate_each(record, attribute, value)
8
8
  record.errors.add(attribute, :invalid, options) unless value.blank?
9
9
  end
@@ -1,14 +1,14 @@
1
- require "spec_helper"
1
+ require "rails_helper"
2
2
 
3
3
  describe Blogit do
4
4
 
5
- it "should allow developers to set configurations with a block" do
5
+ it "allows developers to set configurations with a block" do
6
6
  initial_value = Blogit.configuration.current_blogger_method
7
7
  Blogit.configure do |config|
8
8
  config.current_blogger_method = :logged_in_user
9
9
  end
10
10
  user_set_value = Blogit.configuration.current_blogger_method
11
- initial_value.should_not eql(user_set_value)
11
+ expect(initial_value).not_to eql(user_set_value)
12
12
  end
13
13
 
14
14
  after :all do
@@ -1,111 +1,56 @@
1
- require 'spec_helper'
1
+ require 'rails_helper'
2
2
 
3
3
  describe Blogit::CommentsController do
4
+
5
+ before do
6
+ @routes = Blogit::Engine.routes
7
+ end
4
8
 
5
9
  let(:blog_post) { Blogit::Post.first || create(:post) }
6
-
10
+
11
+ let(:comment_attributes) { attributes_for(:comment) }
12
+
7
13
  describe "POST create" do
8
-
9
- before do
10
- @comment_attributes = attributes_for(:comment)
11
- end
12
-
14
+
15
+
13
16
  def do_post(format = :html)
14
- post :create, post_id: blog_post.id,
15
- comment: @comment_attributes, use_route: :blogit, format: format
17
+ post :create, post_id: blog_post.id,
18
+ comment: comment_attributes, format: format
16
19
  end
17
20
 
18
- describe "whith JS" do
19
-
20
- it "should persist comment" do
21
- lambda { do_post(:js) }.should change { blog_post.comments.count }.by(1)
21
+ subject { do_post(:js) }
22
+
23
+ context "when POST is AJAX" do
24
+
25
+ it "persists comment" do
26
+ expect { subject }.to change { blog_post.comments.count }.by(1)
27
+ end
28
+
29
+ it "returns a status :created" do
30
+ subject
31
+ expect(response.status).to eql(201)
22
32
  end
23
-
24
- # The rest is handled in the view
25
-
33
+
26
34
  end
27
-
35
+
28
36
  describe "with HTML" do
29
-
30
- it "should persist comment" do
31
- lambda { do_post(:html) }.should change { blog_post.comments.count }.by(1)
37
+
38
+ it "persists the comment" do
39
+ expect { do_post(:html) }.to change { blog_post.comments.count }.by(1)
32
40
  end
33
-
41
+
34
42
  it "should redirect to the blog post" do
35
43
  do_post
36
- response.should redirect_to(controller.post_url(blog_post))
44
+ expect(response).to redirect_to(controller.post_url(blog_post))
37
45
  end
38
46
 
39
47
  it "should display a flash notice" do
40
48
  do_post
41
- flash[:notice].should be_present
42
- end
43
-
44
- end
45
-
46
- end
47
-
48
- describe "DELETE destroy" do
49
-
50
- def do_delete(format = :html)
51
- delete :destroy, id: @comment.id,
52
- post_id: blog_post.id, format: format, use_route: :blogit
53
- end
54
-
55
- before do
56
- @comment = create(:comment, post: blog_post)
57
- end
58
-
59
- describe "when user logged in" do
60
-
61
- before do
62
- mock_login
49
+ expect(flash[:notice]).to be_present
63
50
  end
64
-
65
- describe "whith JS" do
66
-
67
- it "should destroy the comment" do
68
- lambda { do_delete(:js) }.should change { blog_post.reload.comments.count }
69
- end
70
-
71
- end
72
-
73
- describe "with HTML" do
74
51
 
75
- it "should destroy the comment" do
76
- lambda { do_delete(:html) }.should change { blog_post.reload.comments.count }
77
- end
78
-
79
- it "should redirect to the blog post " do
80
- do_delete
81
- response.should redirect_to(controller.post_url(blog_post))
82
- end
83
-
84
- end
85
-
86
52
  end
87
-
88
- describe "when user is not logged in" do
89
-
90
-
91
- describe "whith JS" do
92
-
93
- it 'should not destroy the comment' do
94
- lambda { do_delete }.should_not change { Comment.count }
95
- end
96
-
97
- end
98
53
 
99
- describe "with HTML" do
100
-
101
- it "should not destroy the comment" do
102
- lambda { do_delete }.should_not change { Comment.count }
103
- end
104
-
105
- end
106
-
107
- end
108
-
109
54
  end
110
55
 
111
56
  end