bumble 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +16 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/Readme.mdown +8 -0
- data/app/controllers/bumble_controller.rb +45 -0
- data/app/controllers/comments_controller.rb +99 -0
- data/app/controllers/password_resets_controller.rb +34 -0
- data/app/controllers/posts_controller.rb +103 -0
- data/app/controllers/user_sessions_controller.rb +22 -0
- data/app/controllers/users_controller.rb +60 -0
- data/app/helpers/bumble_helper.rb +50 -0
- data/app/models/asset.rb +57 -0
- data/app/models/comment.rb +78 -0
- data/app/models/notifier.rb +35 -0
- data/app/models/post.rb +57 -0
- data/app/models/posts/blog.rb +3 -0
- data/app/models/posts/code.rb +3 -0
- data/app/models/posts/image.rb +3 -0
- data/app/models/posts/link.rb +7 -0
- data/app/models/posts/quote.rb +3 -0
- data/app/models/posts/video.rb +4 -0
- data/app/models/user.rb +35 -0
- data/app/models/user_session.rb +2 -0
- data/app/views/comments/_comment.html.haml +14 -0
- data/app/views/comments/_form.html.haml +9 -0
- data/app/views/comments/edit.html.haml +7 -0
- data/app/views/comments/index.atom.builder +15 -0
- data/app/views/comments/new.html.haml +7 -0
- data/app/views/layouts/_sidebar.html.haml +20 -0
- data/app/views/layouts/bumble.html.haml +35 -0
- data/app/views/notifier/activation_confirmation.erb +5 -0
- data/app/views/notifier/activation_instructions.erb +5 -0
- data/app/views/notifier/new_comment_alert.erb +8 -0
- data/app/views/notifier/password_reset_instructions.erb +8 -0
- data/app/views/password_resets/edit.html.haml +10 -0
- data/app/views/password_resets/new.html.haml +7 -0
- data/app/views/posts/_form.html.haml +10 -0
- data/app/views/posts/_post.html.haml +16 -0
- data/app/views/posts/_preview.html.haml +8 -0
- data/app/views/posts/edit.html.haml +10 -0
- data/app/views/posts/forms/_blog.html.haml +4 -0
- data/app/views/posts/forms/_code.html.haml +6 -0
- data/app/views/posts/forms/_image.html.haml +9 -0
- data/app/views/posts/forms/_link.html.haml +6 -0
- data/app/views/posts/forms/_quote.html.haml +4 -0
- data/app/views/posts/forms/_video.html.haml +6 -0
- data/app/views/posts/index.atom.builder +15 -0
- data/app/views/posts/index.html.haml +21 -0
- data/app/views/posts/new.html.haml +8 -0
- data/app/views/posts/search.html.haml +27 -0
- data/app/views/posts/show.html.haml +22 -0
- data/app/views/posts/types/_blog.html.haml +4 -0
- data/app/views/posts/types/_code.html.haml +7 -0
- data/app/views/posts/types/_image.html.haml +3 -0
- data/app/views/posts/types/_link.html.haml +3 -0
- data/app/views/posts/types/_quote.html.haml +2 -0
- data/app/views/posts/types/_video.html.haml +5 -0
- data/app/views/user_sessions/new.html.haml +10 -0
- data/app/views/users/_form.html.haml +12 -0
- data/app/views/users/_user.html.haml +3 -0
- data/app/views/users/delete.html.haml +5 -0
- data/app/views/users/edit.html.haml +8 -0
- data/app/views/users/index.html.haml +3 -0
- data/app/views/users/new.html.haml +7 -0
- data/app/views/users/show.html.haml +6 -0
- data/bumble.gemspec +31 -0
- data/config/initializers/bumble.rb +9 -0
- data/config/initializers/haml.rb +2 -0
- data/config/initializers/html5_forms.rb +163 -0
- data/config/initializers/inflections.rb +10 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/initializers/will_paginate.rb +3 -0
- data/config/routes.rb +29 -0
- data/lib/bumble.rb +18 -0
- data/lib/bumble/version.rb +3 -0
- data/lib/generators/bumble/assets_generator.rb +10 -0
- data/lib/generators/bumble/migrations_generator.rb +40 -0
- data/lib/generators/bumble/templates/assets/images/.gitignore +0 -0
- data/lib/generators/bumble/templates/assets/images/close.png +0 -0
- data/lib/generators/bumble/templates/assets/images/email.png +0 -0
- data/lib/generators/bumble/templates/assets/images/feed.png +0 -0
- data/lib/generators/bumble/templates/assets/images/image.png +0 -0
- data/lib/generators/bumble/templates/assets/images/loading.gif +0 -0
- data/lib/generators/bumble/templates/assets/images/preview.png +0 -0
- data/lib/generators/bumble/templates/assets/images/shortcut.png +0 -0
- data/lib/generators/bumble/templates/assets/images/youtube.png +0 -0
- data/lib/generators/bumble/templates/assets/javascripts/admin.js +95 -0
- data/lib/generators/bumble/templates/assets/javascripts/bumble.js +76 -0
- data/lib/generators/bumble/templates/assets/javascripts/iphone.js +7 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.autogrow.js +37 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.cookie.js +96 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.form.js +665 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.hint.js +44 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.jgrow.js +85 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.js +154 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.core.js +18 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.tabs.js +13 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.ui.widget.js +18 -0
- data/lib/generators/bumble/templates/assets/javascripts/jquery.validate.js +16 -0
- data/lib/generators/bumble/templates/assets/javascripts/modernizr.js +13 -0
- data/lib/generators/bumble/templates/assets/javascripts/ui.core.js +289 -0
- data/lib/generators/bumble/templates/assets/javascripts/ui.tabs.js +593 -0
- data/lib/generators/bumble/templates/migrations/add_approved_to_comments.rb +15 -0
- data/lib/generators/bumble/templates/migrations/add_delta_to_posts.rb +9 -0
- data/lib/generators/bumble/templates/migrations/add_missing_indexes.rb +24 -0
- data/lib/generators/bumble/templates/migrations/add_url_to_users.rb +9 -0
- data/lib/generators/bumble/templates/migrations/create_assets.rb +18 -0
- data/lib/generators/bumble/templates/migrations/create_comments.rb +19 -0
- data/lib/generators/bumble/templates/migrations/create_posts.rb +25 -0
- data/lib/generators/bumble/templates/migrations/create_users.rb +28 -0
- data/lib/generators/bumble/templates/migrations/full_text_search.rb +13 -0
- data/public/stylesheets/sass/bumble.sass +423 -0
- data/public/stylesheets/sass/iphone.sass +79 -0
- data/public/stylesheets/sass/print.sass +2 -0
- data/public/stylesheets/sass/reset.sass +49 -0
- data/test/factories.rb +28 -0
- data/test/functional/comments_controller_test.rb +177 -0
- data/test/functional/password_resets_controller_test.rb +61 -0
- data/test/functional/posts_controller_test.rb +181 -0
- data/test/test_helper.rb +113 -0
- data/test/unit/comment_test.rb +18 -0
- data/test/unit/post_test.rb +18 -0
- data/test/unit/user_test.rb +37 -0
- metadata +403 -0
data/app/models/asset.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
class Asset < ActiveRecord::Base
|
4
|
+
|
5
|
+
belongs_to :post
|
6
|
+
|
7
|
+
attr_accessible :attachment, :attachment_url, :attachment_remote_url
|
8
|
+
attr_accessor :attachment_url
|
9
|
+
|
10
|
+
has_attached_file :attachment,
|
11
|
+
:storage => :s3,
|
12
|
+
:path => ":basename:normalized_style.:extension",
|
13
|
+
:default_style => :original,
|
14
|
+
:bucket => 'bumble_production',
|
15
|
+
:s3_credentials => { :access_key_id => ENV['s3_access_key_id'], :secret_access_key => ENV['s3_secret_access_key'] },
|
16
|
+
:s3_headers => { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate },
|
17
|
+
:styles => { :thumb => '500x500>'}
|
18
|
+
|
19
|
+
|
20
|
+
Paperclip.interpolates :normalized_style do |attachment, style|
|
21
|
+
"_#{style}" if attachment.instance.image? && style != :original
|
22
|
+
end
|
23
|
+
|
24
|
+
before_validation :download_remote_file, :if => :attachment_url_provided?
|
25
|
+
|
26
|
+
validates_presence_of :attachment_file_name
|
27
|
+
validates_presence_of :attachment_remote_url, :if => :attachment_url_provided?, :message => 'is invalid or inaccessible'
|
28
|
+
validates_uniqueness_of :attachment_file_name
|
29
|
+
|
30
|
+
before_post_process :image? # bypass image processing if not an image
|
31
|
+
|
32
|
+
def image?
|
33
|
+
!(attachment_content_type =~ /^image.*/).nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
attachment_file_name
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def attachment_url_provided?
|
43
|
+
!self.attachment_url.blank?
|
44
|
+
end
|
45
|
+
|
46
|
+
def download_remote_file
|
47
|
+
self.attachment = do_download_remote_file
|
48
|
+
self.attachment_remote_url = attachment_url
|
49
|
+
end
|
50
|
+
|
51
|
+
def do_download_remote_file
|
52
|
+
io = open(URI.parse(attachment_url))
|
53
|
+
def io.original_filename; base_uri.path.split('/').last; end
|
54
|
+
io.original_filename.blank? ? nil : io
|
55
|
+
rescue # catch errors with validations
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
class Comment < ActiveRecord::Base
|
2
|
+
include Gravtastic
|
3
|
+
belongs_to :post # TODO , :counter_cache => true
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
validates_presence_of :post, :body
|
7
|
+
validates_presence_of :author_name, :author_email, :if => :anonymous?
|
8
|
+
validates_format_of :author_email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :allow_blank => :true
|
9
|
+
|
10
|
+
is_gravtastic :with => :email, :rating => 'R', :size => 30
|
11
|
+
|
12
|
+
after_save :set_parent_delta
|
13
|
+
after_create :email_post_author
|
14
|
+
|
15
|
+
scope :ham, :conditions => {:approved => true}
|
16
|
+
scope :spam, :conditions => {:approved => false}
|
17
|
+
scope :old, lambda {{:conditions => ["created_at < :now", { :now => 14.days.ago }]}}
|
18
|
+
|
19
|
+
def set_parent_delta
|
20
|
+
self.post.update_attributes(:delta => true)
|
21
|
+
end
|
22
|
+
|
23
|
+
def email_post_author
|
24
|
+
Notifier.deliver_new_comment_alert(self) unless user_id == post.user_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def anonymous?
|
28
|
+
!user_id?
|
29
|
+
end
|
30
|
+
|
31
|
+
def email
|
32
|
+
user_id.blank? ? author_email : user.email
|
33
|
+
end
|
34
|
+
|
35
|
+
def author
|
36
|
+
user_id.blank? ? author_name : user.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def author_url
|
40
|
+
anonymous? ? read_attribute(:author_url) : user.url
|
41
|
+
end
|
42
|
+
|
43
|
+
before_create :check_for_spam
|
44
|
+
|
45
|
+
def request=(request)
|
46
|
+
self.user_ip = request.remote_ip
|
47
|
+
self.user_agent = request.env['HTTP_USER_AGENT']
|
48
|
+
self.referrer = request.env['HTTP_REFERER']
|
49
|
+
end
|
50
|
+
|
51
|
+
def check_for_spam
|
52
|
+
self.approved = !Akismetor.spam?(akismet_attributes)
|
53
|
+
true # return true so it doesn't stop save
|
54
|
+
end
|
55
|
+
|
56
|
+
def akismet_attributes
|
57
|
+
{
|
58
|
+
:key => '4a8bfe691b69',
|
59
|
+
:blog => "http://#{DOMAIN}",
|
60
|
+
:user_ip => user_ip,
|
61
|
+
:user_agent => user_agent,
|
62
|
+
:comment_author => author,
|
63
|
+
:comment_author_email => email,
|
64
|
+
:comment_author_url => author_url,
|
65
|
+
:comment_content => body
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def mark_as_spam!
|
70
|
+
update_attribute(:approved, false)
|
71
|
+
Akismetor.submit_spam(akismet_attributes)
|
72
|
+
end
|
73
|
+
|
74
|
+
def mark_as_ham!
|
75
|
+
update_attribute(:approved, true)
|
76
|
+
Akismetor.submit_ham(akismet_attributes)
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class Notifier < ActionMailer::Base
|
2
|
+
def password_reset_instructions(user)
|
3
|
+
setup(user)
|
4
|
+
subject "Password Reset Instructions"
|
5
|
+
body :edit_password_reset_url => edit_password_reset_url(user.perishable_token)
|
6
|
+
end
|
7
|
+
|
8
|
+
def activation_instructions(user)
|
9
|
+
setup(user)
|
10
|
+
subject "Activation Instructions"
|
11
|
+
body :account_activation_url => activate_url(user.perishable_token)
|
12
|
+
end
|
13
|
+
|
14
|
+
def activation_confirmation(user)
|
15
|
+
setup(user)
|
16
|
+
subject "Welcome to #{DOMAIN}"
|
17
|
+
body :root_url => root_url
|
18
|
+
end
|
19
|
+
|
20
|
+
def new_comment_alert(comment)
|
21
|
+
setup(comment.post.user)
|
22
|
+
subject "New comment on #{comment.post.title}"
|
23
|
+
body :comment => comment
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def setup(user)
|
29
|
+
recipients user.email
|
30
|
+
from "#{DOMAIN} <noreply@#{DOMAIN}>"
|
31
|
+
subject "#{DOMAIN} Message"
|
32
|
+
sent_on Time.now
|
33
|
+
body :user => user
|
34
|
+
end
|
35
|
+
end
|
data/app/models/post.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
class Post < ActiveRecord::Base
|
2
|
+
has_many :assets, :dependent => :destroy
|
3
|
+
has_many :comments, :dependent => :destroy, :order => :created_at
|
4
|
+
belongs_to :user
|
5
|
+
|
6
|
+
accepts_nested_attributes_for :assets
|
7
|
+
|
8
|
+
# has_permalink :title, :unless => Proc.new { |post| post.read_attribute(:title).blank? }
|
9
|
+
|
10
|
+
validates_presence_of :user, :published_at
|
11
|
+
|
12
|
+
before_validation :format_published_at
|
13
|
+
|
14
|
+
def asset
|
15
|
+
assets.first
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_param
|
19
|
+
permalink.blank? ? id.to_s : permalink
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.types
|
23
|
+
Dir[File.expand_path('../posts',__FILE__)+'/*.rb'].each { |f| require_dependency f }
|
24
|
+
self.subclasses.collect(&:to_s).sort
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.find_by_permalink_or_id(param)
|
28
|
+
Post.find_by_permalink(param) || Post.find(param)
|
29
|
+
end
|
30
|
+
|
31
|
+
cattr_reader :per_page
|
32
|
+
@@per_page = 5
|
33
|
+
|
34
|
+
scope :all_public, :conditions => {:publicly_viewable => true}
|
35
|
+
scope :all_private, :conditions => {:publicly_viewable => false}
|
36
|
+
scope :published, lambda {{:conditions => ["published_at < :now", { :now => Time.now.utc }]}}
|
37
|
+
|
38
|
+
def title
|
39
|
+
read_attribute(:title).blank? ? "Post #{id}" : read_attribute(:title)
|
40
|
+
end
|
41
|
+
|
42
|
+
index do
|
43
|
+
title
|
44
|
+
link_url
|
45
|
+
image_url
|
46
|
+
video_embed
|
47
|
+
description
|
48
|
+
quote
|
49
|
+
permalink
|
50
|
+
type
|
51
|
+
via
|
52
|
+
end
|
53
|
+
|
54
|
+
def format_published_at
|
55
|
+
self.published_at = Time.now if self.published_at.nil?
|
56
|
+
end
|
57
|
+
end
|
data/app/models/user.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
class User < ActiveRecord::Base
|
2
|
+
|
3
|
+
acts_as_authentic
|
4
|
+
|
5
|
+
validates_presence_of :first_name
|
6
|
+
|
7
|
+
is_gravtastic :with => :email, :rating => 'R', :size => 30
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
first_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
[first_name, last_name].reject(&:blank?).join(' ')
|
15
|
+
end
|
16
|
+
|
17
|
+
def activate!
|
18
|
+
self.update_attributes(:activated_at => Time.now)
|
19
|
+
end
|
20
|
+
|
21
|
+
def deliver_password_reset_instructions!
|
22
|
+
reset_perishable_token!
|
23
|
+
Notifier.deliver_password_reset_instructions(self)
|
24
|
+
end
|
25
|
+
|
26
|
+
def deliver_activation_instructions!
|
27
|
+
reset_perishable_token!
|
28
|
+
Notifier.deliver_activation_instructions(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
def deliver_activation_confirmation!
|
32
|
+
reset_perishable_token!
|
33
|
+
Notifier.deliver_activation_confirmation(self)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
.vcard[comment]{:class => ('author' if comment.user_id == comment.post.user.id)}
|
2
|
+
= link_to_unless comment.author_url.blank?, image_tag(comment.gravatar_url, :class => 'photo'), h(comment.author_url)
|
3
|
+
= markdown comment.body
|
4
|
+
%p.meta
|
5
|
+
= format_datetime_ago(comment.created_at)
|
6
|
+
by
|
7
|
+
= link_to_unless comment.author_url.blank?, h(comment.author), h(comment.author_url), :rel => :nofollow, :class => 'url fn'
|
8
|
+
- if current_user
|
9
|
+
\-
|
10
|
+
= link_to 'Edit', edit_post_comment_path(comment.post, comment)
|
11
|
+
|
|
12
|
+
= link_to 'Delete', post_comment_path(comment.post, comment), :class => :delete
|
13
|
+
|
|
14
|
+
= spam_link_for comment
|
@@ -0,0 +1,9 @@
|
|
1
|
+
- unless current_user
|
2
|
+
= form.label :author_name, 'Name'
|
3
|
+
.field= form.text_field :author_name, :class => "required", :placeholder => 'Name..'
|
4
|
+
= form.label :author_email, 'Email'
|
5
|
+
.field= form.email_field :author_email, :class => "required email", :placeholder => 'Email..', :autocorrect => 'off'
|
6
|
+
= form.label :author_url, 'Url'
|
7
|
+
.field= form.url_field :author_url, :class => 'url', :placeholder => 'Url..'
|
8
|
+
= form.label :body, 'Your Comment'
|
9
|
+
.field= form.text_area :body, :rows => 6, :class => "required", :placeholder => 'Your comment..'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
atom_feed(:schema_date => 2008, :root_url => root_url, :url => comments_url(:format => :atom)) do |feed|
|
2
|
+
feed.title "Comments"
|
3
|
+
feed.updated @comments.first.updated_at
|
4
|
+
|
5
|
+
for comment in @comments
|
6
|
+
feed.entry(comment, :url => post_url(comment.post, :anchor => dom_id(comment))) do |entry|
|
7
|
+
entry.title "Comment #{comment.id}"
|
8
|
+
entry.author do |author|
|
9
|
+
author.name comment.author
|
10
|
+
author.uri comment.author_url
|
11
|
+
end
|
12
|
+
entry.content markdown(comment.body), :type => 'html'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#sidebar
|
2
|
+
%h3 Search
|
3
|
+
- form_tag search_posts_path, :method => :get, :id => 'search_form' do
|
4
|
+
.field= text_field_tag :query, params[:query], :placeholder => 'Keywords..', :type => 'search'
|
5
|
+
= submit_tag 'Search'
|
6
|
+
%h3 Links
|
7
|
+
%ul#links
|
8
|
+
%li.feed= link_to "Feed", posts_path(:format => :atom)
|
9
|
+
%li.email= mail_to CONTACT_EMAIL, "Email"
|
10
|
+
|
11
|
+
- if current_user
|
12
|
+
%h3 Admin
|
13
|
+
%p
|
14
|
+
= pluralize(Post.count, 'post')
|
15
|
+
and
|
16
|
+
= pluralize(Comment.count, 'comment')
|
17
|
+
%p
|
18
|
+
= link_to "Edit account", edit_user_path(current_user)
|
19
|
+
or
|
20
|
+
= link_to "Logout", logout_path
|
@@ -0,0 +1,35 @@
|
|
1
|
+
!!!
|
2
|
+
%html.no-js
|
3
|
+
%head
|
4
|
+
%meta{'http-equiv' => 'Content-Type', :content => "text/html; charset=utf-8"}
|
5
|
+
%meta{:name => 'author', :content => 'Bumble'}
|
6
|
+
%meta{:name => 'keywords', :content => 'keywords'}
|
7
|
+
%meta{:name => 'description', :content => page_description}
|
8
|
+
= auto_discovery_link_tag :atom, posts_url(:format => :atom), :title => 'Posts feed'
|
9
|
+
= auto_discovery_link_tag :atom, comments_url(:format => :atom), :title => 'Comments feed'
|
10
|
+
- if protect_against_forgery?
|
11
|
+
:javascript
|
12
|
+
var AUTH_TOKEN=#{form_authenticity_token.inspect};
|
13
|
+
= stylesheet_link_tag('bumble', :media => 'screen, print')
|
14
|
+
= javascript_include_tag 'jquery', 'jquery.validate', 'jquery.form', 'jquery.hint', 'jquery.autogrow', 'modernizr', 'bumble'
|
15
|
+
- if current_user
|
16
|
+
= javascript_include_tag 'jquery.cookie', 'jquery.ui.core', 'jquery.ui.widget', 'jquery.ui.tabs', 'admin'
|
17
|
+
- if iphone?
|
18
|
+
%meta{:name => "viewport", :content => "width=device-width; initial-scale=1.0; maximum-scale=1.0;"}
|
19
|
+
= stylesheet_link_tag 'iphone'
|
20
|
+
= javascript_include_tag 'iphone'
|
21
|
+
%title= page_title
|
22
|
+
= yield :header
|
23
|
+
%body
|
24
|
+
#header
|
25
|
+
%h1= link_to DOMAIN, root_path, :rel => :home
|
26
|
+
#content
|
27
|
+
- flash.each do |key, msg|
|
28
|
+
.flash{:id => key}= msg
|
29
|
+
= yield
|
30
|
+
= render 'layouts/sidebar'
|
31
|
+
#footer
|
32
|
+
= link_to '#header', :class => 'up', :title => 'Back to top' do
|
33
|
+
↑
|
34
|
+
Powered by
|
35
|
+
= link_to "Bumble", 'http://github.com/andrew/bumble'
|
@@ -0,0 +1,8 @@
|
|
1
|
+
A new comment has been posted on <%= @comment.post.title %> by <%= @comment.author %><%= " (#{@comment.author_url})" if @comment.author_url.present? %>:
|
2
|
+
|
3
|
+
<%= @comment.body %>
|
4
|
+
|
5
|
+
It<%= @comment.approved ? " doesn't look like" : "'s been marked as" %> spam.
|
6
|
+
|
7
|
+
-----
|
8
|
+
See it here: <%= post_url(@comment.post, :anchor => dom_id(@comment)) %>
|