about summary refs log tree commit diff stats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/stylesheets/main/entries.scss62
-rw-r--r--app/assets/stylesheets/main/layout.scss4
-rw-r--r--app/controllers/comments_controller.rb59
-rw-r--r--app/helpers/application_helper.rb10
-rw-r--r--app/helpers/comments_helper.rb5
-rw-r--r--app/models/blog.rb2
-rw-r--r--app/models/comment.rb36
-rw-r--r--app/views/blogs/_blog.html.haml2
-rw-r--r--app/views/blogs/show.html.haml5
-rw-r--r--app/views/comments/_comment.html.haml13
-rw-r--r--app/views/comments/_form.html.haml23
-rw-r--r--app/views/comments/_layout.html.haml6
12 files changed, 220 insertions, 7 deletions
diff --git a/app/assets/stylesheets/main/entries.scss b/app/assets/stylesheets/main/entries.scss index 56cd221..5fbd4ef 100644 --- a/app/assets/stylesheets/main/entries.scss +++ b/app/assets/stylesheets/main/entries.scss
@@ -219,3 +219,65 @@
219 margin-left: 1.5em; 219 margin-left: 1.5em;
220 } 220 }
221} 221}
222
223.blog-comment {
224 margin: 0 1em;
225
226 .comment-avatar {
227 float: right;
228 margin-top: 1em;
229 }
230}
231
232#comment-form {
233 fieldset {
234 border: 0;
235
236 &#comment-body-field {
237 label {
238 display: none;
239 }
240
241 textarea {
242 margin-top: 1em;
243 width: 99%;
244 height: 6em;
245 resize: none;
246 }
247 }
248
249 &#comment-other-fields {
250 display: table;
251 padding: 1em;
252 width: 75%;
253 margin: 0 auto;
254
255 .comment-field {
256 display: table-row;
257
258 .comment-field-label {
259 text-align: right;
260 display: table-cell;
261 padding-right: 1em;
262 padding-bottom: 1em;
263 width: 50%;
264
265 label:after {
266 content: ":";
267 }
268 }
269
270 .field_with_errors {
271 label {
272 color: red;
273 }
274 }
275
276 .comment-field-input {
277 display: table-cell;
278 width: 50%;
279 }
280 }
281 }
282 }
283}
diff --git a/app/assets/stylesheets/main/layout.scss b/app/assets/stylesheets/main/layout.scss index 278113a..9283f36 100644 --- a/app/assets/stylesheets/main/layout.scss +++ b/app/assets/stylesheets/main/layout.scss
@@ -199,3 +199,7 @@ blockquote.bubble.bottom::after {
199 text-decoration: underline; 199 text-decoration: underline;
200 } 200 }
201} 201}
202
203.clear {
204 clear: both;
205}
diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb new file mode 100644 index 0000000..60c8f6a --- /dev/null +++ b/app/controllers/comments_controller.rb
@@ -0,0 +1,59 @@
1class CommentsController < ApplicationController
2 def create
3 @blog = Blog.find_by_slug(params[:slug])
4
5 raise ActiveRecord::RecordNotFound unless @blog
6 raise ActiveRecord::RecordNotFound unless @blog.published
7
8 @comment = @blog.comments.new(comment_params)
9
10 unless @comment.valid?
11 flash.alert = "Error posting comment."
12 render "blogs/show"
13 return
14 end
15
16 akismet_vars = %w{ HTTP_ACCEPT HTTP_ACCEPT_ENCODING }
17 akismet_params = {
18 type: "comment",
19 text: @comment.body,
20 created_at: DateTime.now,
21 author: @comment.username,
22 author_email: @comment.email,
23 author_url: @comment.website,
24 post_url: url_for(@comment.blog),
25 post_modified_at: @comment.blog.updated_at,
26 referrer: request.referrer,
27 env: request.env.slice(*akismet_vars)
28 }
29
30 is_spam, is_blatant = Akismet.check(request.ip, request.user_agent, akismet_params)
31
32 if is_blatant
33 # I am lying.
34 flash.notice = "Comment submitted successfully! It will need to be moderated before it shows up on the blog."
35 else
36 if is_spam
37 @comment.status = :pending
38 flash_message = "Comment submitted successfully! It will need to be moderated before it shows up on the blog."
39 else
40 @comment.status = :published
41 flash_message = "Comment posted successfully!"
42 end
43
44 if @comment.save
45 flash.notice = flash_message
46 else
47 flash.alert = "Error posting comment."
48 end
49 end
50
51 redirect_to @comment.blog
52 end
53
54 private
55
56 def comment_params
57 params.require(:comment).permit(:username, :email, :website, :body)
58 end
59end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 861dd11..14d56cf 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb
@@ -19,9 +19,15 @@ module ApplicationHelper
19 link_to title, {:sort => col, :dir => direction}, {:class => css_class} 19 link_to title, {:sort => col, :dir => direction}, {:class => css_class}
20 end 20 end
21 21
22 def markdown(text) 22 def markdown(text, params = {})
23 options = { fenced_code_blocks: true, highlight: true } 23 options = { fenced_code_blocks: true, highlight: true }
24 Redcarpet::Markdown.new(HTML.new(), options).render(text).html_safe 24
25 html_options = {}
26 if params[:restricted]
27 html_options[:filter_html] = true
28 end
29
30 Redcarpet::Markdown.new(HTML.new(html_options), options).render(text).html_safe
25 end 31 end
26 32
27end 33end
diff --git a/app/helpers/comments_helper.rb b/app/helpers/comments_helper.rb new file mode 100644 index 0000000..5939adc --- /dev/null +++ b/app/helpers/comments_helper.rb
@@ -0,0 +1,5 @@
1module CommentsHelper
2 def show_comments(blog)
3 render "comments/layout", blog: blog
4 end
5end
diff --git a/app/models/blog.rb b/app/models/blog.rb index 415167c..b677e2b 100644 --- a/app/models/blog.rb +++ b/app/models/blog.rb
@@ -3,6 +3,8 @@ class Blog < ApplicationRecord
3 3
4 acts_as_taggable 4 acts_as_taggable
5 5
6 has_many :comments
7
6 validates :title, presence: true 8 validates :title, presence: true
7 validates :body, presence: true, if: :published 9 validates :body, presence: true, if: :published
8 validates :slug, presence: true, format: /\A[-a-z0-9]+\z/, if: :published 10 validates :slug, presence: true, format: /\A[-a-z0-9]+\z/, if: :published
diff --git a/app/models/comment.rb b/app/models/comment.rb new file mode 100644 index 0000000..9697100 --- /dev/null +++ b/app/models/comment.rb
@@ -0,0 +1,36 @@
1class Comment < ApplicationRecord
2 extend Enumerize
3
4 belongs_to :blog
5
6 validates :body, presence: true
7 validates :username, presence: true
8 validates :email, presence: true, format: URI::MailTo::EMAIL_REGEXP
9
10 scope :published_and_ordered, -> { where(status: :published).order(published_at: :asc) }
11
12 enumerize :status,
13 in: [:published, :pending, :rejected],
14 default: :published,
15 predicates: true
16
17 before_save :set_published_at
18
19 def gravatar_url
20 hash = Digest::MD5.hexdigest(email)
21 "https://www.gravatar.com/avatar/#{hash}?size=40&default=identicon&rating=g"
22 end
23
24 private
25
26 def set_published_at
27 if self.published?
28 if self.published_at.blank?
29 self.published_at = DateTime.now
30 end
31 else
32 self.published_at = nil
33 end
34 end
35
36end
diff --git a/app/views/blogs/_blog.html.haml b/app/views/blogs/_blog.html.haml index 26657e7..8972c2e 100644 --- a/app/views/blogs/_blog.html.haml +++ b/app/views/blogs/_blog.html.haml
@@ -15,4 +15,4 @@
15 %cite.bubble 15 %cite.bubble
16 %strong Hatkirby 16 %strong Hatkirby
17 on 17 on
18 = blog.published_at.strftime("%m-%d-%Y") 18 = blog.published_at.strftime("%B #{blog.published_at.day.ordinalize}, %Y at %-I:%M:%S%P")
diff --git a/app/views/blogs/show.html.haml b/app/views/blogs/show.html.haml index 9bff12b..0c549ac 100644 --- a/app/views/blogs/show.html.haml +++ b/app/views/blogs/show.html.haml
@@ -1,7 +1,4 @@
1- title @blog.title 1- title @blog.title
2.breadcrumb= link_to "← Back to home page", root_path 2.breadcrumb= link_to "← Back to home page", root_path
3= render @blog, short: false 3= render @blog, short: false
4%footer#blog-footer 4= show_comments(@blog)
5 This entry was posted on
6 = succeed "." do
7 %time= @blog.published_at.strftime("%B #{@blog.published_at.day.ordinalize}, %Y at %-I:%M:%S%P")
diff --git a/app/views/comments/_comment.html.haml b/app/views/comments/_comment.html.haml new file mode 100644 index 0000000..3e10759 --- /dev/null +++ b/app/views/comments/_comment.html.haml
@@ -0,0 +1,13 @@
1.blog-comment
2 %blockquote.bubble.rounded.bottom
3 = image_tag comment.gravatar_url, class: "comment-avatar"
4 = markdown(comment.body, { restricted: true })
5 .clear
6 %cite.bubble
7 %strong
8 - if comment.website.empty?
9 = comment.username
10 - else
11 = link_to comment.username, comment.website
12 on
13 = comment.published_at.strftime("%B #{comment.published_at.day.ordinalize}, %Y at %-I:%M:%S%P")
diff --git a/app/views/comments/_form.html.haml b/app/views/comments/_form.html.haml new file mode 100644 index 0000000..f6df807 --- /dev/null +++ b/app/views/comments/_form.html.haml
@@ -0,0 +1,23 @@
1= form_for @comment || blog.comments.new, html: { id: "comment-form" } do |f|
2 %fieldset#comment-body-field
3 %blockquote.bubble.rounded.bottom
4 = f.label :body
5 = f.text_area :body
6 %cite.bubble Feel free to post a comment! You may use Markdown.
7 - if @comment and @comment.errors.any?
8 %ul#form-errors
9 - @comment.errors.full_messages.each do |msg|
10 %li= msg
11 %fieldset#comment-other-fields
12 .comment-name-field.comment-field
13 .comment-field-label= f.label :username
14 .comment-field-input= f.text_field :username
15 .comment-email-field.comment-field
16 .comment-field-label= f.label :email
17 .comment-field-input= f.text_field :email, type: :email
18 .comment-website-field.comment-field
19 .comment-field-label= f.label :website, "Website (Optional)"
20 .comment-field-input= f.text_field :website, type: :url
21 .comment-submit-button.comment-field
22 .comment-field-label
23 .comment-field-input= f.submit "Post"
diff --git a/app/views/comments/_layout.html.haml b/app/views/comments/_layout.html.haml new file mode 100644 index 0000000..9acf6b0 --- /dev/null +++ b/app/views/comments/_layout.html.haml
@@ -0,0 +1,6 @@
1%a{ name: "comments" }
2#comments
3 %h2 Comments
4 - blog.comments.published_and_ordered.each do |comment|
5 = render comment
6 = render "comments/form", blog: blog