rails_blog_engine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/BOOTSTRAP-LICENSE.txt +13 -0
  2. data/MIT-LICENSE +20 -0
  3. data/PYGMENTS-LICENSE.txt +28 -0
  4. data/RAILS-LICENSE.txt +22 -0
  5. data/README.md +165 -0
  6. data/Rakefile +79 -0
  7. data/app/assets/javascripts/rails_blog_engine/comments.js +2 -0
  8. data/app/assets/javascripts/rails_blog_engine/posts.js +3 -0
  9. data/app/assets/javascripts/rails_blog_engine.js +3 -0
  10. data/app/assets/stylesheets/rails_blog_engine/bootstrap_extracts.css.scss +252 -0
  11. data/app/assets/stylesheets/rails_blog_engine/code.css.scss +71 -0
  12. data/app/assets/stylesheets/rails_blog_engine/comments.css.scss +29 -0
  13. data/app/assets/stylesheets/rails_blog_engine/posts.css.scss +46 -0
  14. data/app/assets/stylesheets/rails_blog_engine/simple_form.css.scss +70 -0
  15. data/app/assets/stylesheets/rails_blog_engine.css +6 -0
  16. data/app/controllers/rails_blog_engine/application_controller.rb +26 -0
  17. data/app/controllers/rails_blog_engine/comments_controller.rb +47 -0
  18. data/app/controllers/rails_blog_engine/posts_controller.rb +67 -0
  19. data/app/helpers/rails_blog_engine/application_helper.rb +52 -0
  20. data/app/helpers/rails_blog_engine/comments_helper.rb +4 -0
  21. data/app/helpers/rails_blog_engine/posts_helper.rb +13 -0
  22. data/app/models/rails_blog_engine/comment.rb +74 -0
  23. data/app/models/rails_blog_engine/post.rb +73 -0
  24. data/app/views/rails_blog_engine/comments/_comment.html.haml +10 -0
  25. data/app/views/rails_blog_engine/comments/_form.html.haml +6 -0
  26. data/app/views/rails_blog_engine/comments/_tools.html.haml +10 -0
  27. data/app/views/rails_blog_engine/comments/new.html.haml +6 -0
  28. data/app/views/rails_blog_engine/posts/_comments_section.html.haml +11 -0
  29. data/app/views/rails_blog_engine/posts/_form.html.haml +7 -0
  30. data/app/views/rails_blog_engine/posts/_post.html.haml +20 -0
  31. data/app/views/rails_blog_engine/posts/_tools.html.haml +2 -0
  32. data/app/views/rails_blog_engine/posts/edit.html.haml +5 -0
  33. data/app/views/rails_blog_engine/posts/index.atom.builder +14 -0
  34. data/app/views/rails_blog_engine/posts/index.html.haml +15 -0
  35. data/app/views/rails_blog_engine/posts/new.html.haml +5 -0
  36. data/app/views/rails_blog_engine/posts/show.html.haml +8 -0
  37. data/config/locales/rails_blog_engine.en.yml +15 -0
  38. data/config/locales/simple_form.en.yml +24 -0
  39. data/config/routes.rb +24 -0
  40. data/db/migrate/20110912153527_create_rails_blog_engine_posts.rb +10 -0
  41. data/db/migrate/20110913190319_add_fields_to_rails_blog_engine_post.rb +12 -0
  42. data/db/migrate/20111125111958_create_rails_blog_engine_comments.rb +21 -0
  43. data/lib/generators/rails_blog_engine/install/USAGE +11 -0
  44. data/lib/generators/rails_blog_engine/install/install_generator.rb +51 -0
  45. data/lib/generators/rails_blog_engine/install/templates/rails_blog_engine.rb +13 -0
  46. data/lib/rails_blog_engine/ability.rb +16 -0
  47. data/lib/rails_blog_engine/engine.rb +5 -0
  48. data/lib/rails_blog_engine/filters/base.rb +17 -0
  49. data/lib/rails_blog_engine/filters/code.rb +21 -0
  50. data/lib/rails_blog_engine/filters.rb +53 -0
  51. data/lib/rails_blog_engine/version.rb +3 -0
  52. data/lib/rails_blog_engine.rb +18 -0
  53. data/lib/tasks/rails_blog_engine_tasks.rake +4 -0
  54. metadata +384 -0
@@ -0,0 +1,29 @@
1
+ .rails_blog_engine_comment.show {
2
+ border: 1px solid lightgrey;
3
+ padding: 10px 10px 0 10px;
4
+ margin-bottom: 20px;
5
+ max-width: 600px;
6
+
7
+ &.spam {
8
+ background: lighten(#ffb6c1, 10%);
9
+ border-color: lighten(#ffb6c1, 5%);
10
+ color: darkgrey;
11
+ }
12
+
13
+ >.byline {
14
+ margin-top: 0;
15
+ margin-bottom: 10px;
16
+ font-weight: normal;
17
+
18
+ a.comment-link {
19
+ color: inherit;
20
+ &:link, &:visited { text-decoration: none; }
21
+ &:hover, &:active { text-decoration: underline; }
22
+ }
23
+ }
24
+
25
+ >.comment-tools {
26
+ float: right;
27
+ margin: 0 0 10px 10px;
28
+ }
29
+ }
@@ -0,0 +1,46 @@
1
+ // Place all the styles for posts and lists of posts here. We assume a
2
+ // light background color.
3
+
4
+ .rails_blog_engine_posts {
5
+ .new_post.btn, nav {
6
+ margin-bottom: 20px;
7
+ }
8
+ }
9
+
10
+ .rails_blog_engine_post {
11
+ color: black;
12
+ margin-bottom: 20px;
13
+
14
+ // Clear top margins. We'll use the bottom margin for spacing.
15
+ >h1, >p.byline, >.body {
16
+ margin-top: 0;
17
+ }
18
+
19
+ >h1 {
20
+ margin-bottom: 0px;
21
+ .btn {
22
+ vertical-align: text-bottom;
23
+ }
24
+ }
25
+
26
+ >p.byline {
27
+ margin-bottom: 10px;
28
+ color: grey;
29
+ }
30
+
31
+ // This works at both the top level and in nested comments.
32
+ .body {
33
+ >blockquote, >dl, >embed, >h1, >h2, >h3, >h4, >h5, >h6, >hr, >object, >ol,
34
+ >p, >pre, >table, >ul, >aside, >figure, >header, >hgroup, >section {
35
+ margin-bottom: 10px;
36
+ }
37
+ }
38
+
39
+ // We use this for moderation warnings.
40
+ >.flash.notice {
41
+ border: 1px solid #049cdb;
42
+ background: #c7eefe;
43
+ padding: 10px;
44
+ max-width: 600px;
45
+ }
46
+ }
@@ -0,0 +1,70 @@
1
+ .rails_blog_engine_post.simple_form, .rails_blog_engine_post .simple_form {
2
+
3
+ // Copied from
4
+ // https://github.com/plataformatec/simple_form/wiki/CSS-for-simple_form,
5
+ // tweaked to remove .simple_form, and nested inside our namespace.
6
+ div.input {
7
+ margin-bottom: 10px;
8
+ }
9
+
10
+ label {
11
+ float: left;
12
+ width: 100px;
13
+ text-align: right;
14
+ margin: 2px 10px;
15
+ }
16
+
17
+ div.boolean, input[type='submit'] {
18
+ margin-left: 120px;
19
+ }
20
+
21
+ div.boolean label, label.collection_radio {
22
+ float: none;
23
+ margin: 0;
24
+ }
25
+
26
+ label.collection_radio {
27
+ margin-right: 10px;
28
+ vertical-align: -2px;
29
+ margin-left: 2px;
30
+ }
31
+
32
+ .field_with_errors {
33
+ background-color: #ff3333;
34
+ }
35
+
36
+ .error {
37
+ clear: left;
38
+ color: black;
39
+ display: block;
40
+ margin-left: 120px;
41
+ font-size: 12px;
42
+ }
43
+
44
+ .hint {
45
+ clear: left;
46
+ margin-left: 120px;
47
+ font-size: 12px;
48
+ color: #555;
49
+ display: block;
50
+ font-style: italic;
51
+ }
52
+
53
+ input.radio {
54
+ margin-right: 5px;
55
+ vertical-align: -3px;
56
+ }
57
+
58
+ input.check_boxes {
59
+ margin-left: 3px;
60
+ vertical-align: -3px;
61
+ }
62
+
63
+ label.collection_check_boxes {
64
+ float: none;
65
+ margin: 0;
66
+ vertical-align: -2px;
67
+ margin-left: 2px;
68
+ }
69
+
70
+ }
@@ -0,0 +1,6 @@
1
+ /*
2
+ * Include the CSS files required by rails_blog_engine.
3
+ *
4
+ *= require_self
5
+ *= require_tree ./rails_blog_engine
6
+ */
@@ -0,0 +1,26 @@
1
+ module RailsBlogEngine
2
+ class ApplicationController < ActionController::Base
3
+ # Use our parent application's layout, so that we "auto-blend" into
4
+ # the existing look-and-feel of the site.
5
+ layout 'application'
6
+
7
+ helper_method :post_permalink_url
8
+ helper_method :post_permalink_path
9
+
10
+ protected
11
+
12
+ def post_permalink_local_path(post)
13
+ date = post.published_at.utc
14
+ sprintf('%04d/%02d/%02d/%s', date.year, date.month,
15
+ date.day, post.permalink)
16
+ end
17
+
18
+ def post_permalink_path(post)
19
+ root_path + post_permalink_local_path(post)
20
+ end
21
+
22
+ def post_permalink_url(post)
23
+ root_url + post_permalink_local_path(post)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,47 @@
1
+ module RailsBlogEngine
2
+ class CommentsController < ApplicationController
3
+ before_filter :load_post
4
+
5
+ load_and_authorize_resource :class => "RailsBlogEngine::Comment"
6
+ skip_load_resource :create
7
+
8
+ def create
9
+ @comment = @post.comments.create(params[:comment]) do |c|
10
+ # Record some extra information from our environment. Most of this
11
+ # is used by the spam filter.
12
+ c.author_ip = request.remote_ip
13
+ c.author_user_agent = request.env['HTTP_USER_AGENT']
14
+ c.author_can_post = can?(:create, RailsBlogEngine::Post)
15
+ c.referrer = request.env['HTTP_REFERER']
16
+ end
17
+
18
+ if @comment.valid?
19
+ @comment.run_spam_filter
20
+ if @comment.filtered_as_spam?
21
+ flash[:comment_notice] = "Your comment has been held for moderation."
22
+ redirect_to(post_permalink_path(@post) + '#comment-flash')
23
+ else
24
+ redirect_to(post_permalink_path(@post) + "#comment-#{@comment.id}")
25
+ end
26
+ else
27
+ render "new"
28
+ end
29
+ end
30
+
31
+ def mark_as_spam
32
+ @comment.mark_as_spam!
33
+ redirect_to(post_permalink_path(@post) + "#comment-#{@comment.id}")
34
+ end
35
+
36
+ def mark_as_ham
37
+ @comment.mark_as_ham!
38
+ redirect_to(post_permalink_path(@post) + "#comment-#{@comment.id}")
39
+ end
40
+
41
+ protected
42
+
43
+ def load_post
44
+ @post = Post.find(params[:post_id])
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,67 @@
1
+ module RailsBlogEngine
2
+ class PostsController < ApplicationController
3
+ before_filter :load_recently_published, :only => :index
4
+ before_filter :load_by_permalink, :only => :show
5
+
6
+ load_and_authorize_resource :class => "RailsBlogEngine::Post"
7
+
8
+ def index
9
+ respond_to do |format|
10
+ format.html { @posts = @posts.page(params[:page]).per(5) }
11
+ format.atom { @posts = @posts.limit(15) }
12
+ end
13
+ end
14
+
15
+ def new
16
+ end
17
+
18
+ def create
19
+ @post.author = current_user
20
+ @post.publish
21
+ if @post.save
22
+ redirect_to(post_permalink_path(@post),
23
+ :notice => "Post was successfully created.")
24
+ else
25
+ render :action => :new
26
+ end
27
+ end
28
+
29
+ def show
30
+ @comments = comments_to_display.order(:created_at)
31
+ @comment = Comment.new {|c| c.post = @post }
32
+ end
33
+
34
+ def edit
35
+ end
36
+
37
+ def update
38
+ @post.update_attributes(params[:post])
39
+ if @post.save
40
+ redirect_to(post_permalink_path(@post),
41
+ :notice => "Post was successfully updated.")
42
+ else
43
+ render :action => :edit
44
+ end
45
+ end
46
+
47
+ protected
48
+
49
+ def load_recently_published
50
+ @posts = Post.recently_published
51
+ end
52
+
53
+ def load_by_permalink
54
+ date = Time.utc(params[:year], params[:month], params[:day])
55
+ @post = Post.where(:published_at => (date..date.end_of_day),
56
+ :permalink => params[:permalink]).first!
57
+ end
58
+
59
+ def comments_to_display
60
+ if can?(:update, RailsBlogEngine::Comment)
61
+ @post.comments
62
+ else
63
+ @post.comments.visible
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,52 @@
1
+ module RailsBlogEngine
2
+ module ApplicationHelper
3
+ # Process a block of text as Markdown, using our filters, and sanitize
4
+ # any usafe HTML. You can pass <code>:trusted? => true</code> to allow
5
+ # images and links without nofollow.
6
+ def markdown(md_text, options={})
7
+ config = sanitize_config(options[:trusted?] || false)
8
+ filtered = Filters.apply_all_to(md_text)
9
+ Sanitize.clean(RDiscount.new(filtered, :smart).to_html, config).html_safe
10
+ end
11
+
12
+ # The URL of our Atom feed. Rails refuses to generate this in any simple
13
+ # fashion, so we do it manually.
14
+ def feed_url
15
+ root_url + "posts.atom"
16
+ end
17
+
18
+ # Get extra HTML classes for the specified comment.
19
+ def comment_classes(comment)
20
+ comment.state.sub(/\A(filtered|marked)_as_/, '')
21
+ end
22
+
23
+ # Generate HTML describing the author of a comment.
24
+ def comment_author_html(comment)
25
+ if comment.author_url && !comment.author_url.blank?
26
+ link_to comment.author_byline, comment.author_url, :rel => "nofollow"
27
+ else
28
+ comment.author_byline
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ # Choose a configuration for the Sanitizer gem.
35
+ def sanitize_config(trusted)
36
+ if trusted then CUSTOM_RELAXED_CONFIG else Sanitize::Config::BASIC end
37
+ end
38
+
39
+ # Allow a few extra tags, mostly for use by our source-code highlighting
40
+ # filter.
41
+ def self.customize_sanitize_config(sanitize_config)
42
+ new_config = {}
43
+ sanitize_config.each {|k,v| new_config[k] = v.dup }
44
+ new_config[:elements] += ['div', 'span']
45
+ new_config[:attributes].merge!('div' => ['class'], 'span' => ['class'])
46
+ new_config
47
+ end
48
+
49
+ # The Sanitize configuration used for trusted posters.
50
+ CUSTOM_RELAXED_CONFIG = customize_sanitize_config(Sanitize::Config::RELAXED)
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ module RailsBlogEngine
2
+ module CommentsHelper
3
+ end
4
+ end
@@ -0,0 +1,13 @@
1
+ module RailsBlogEngine
2
+ module PostsHelper
3
+ # Link to the comments section of a post.
4
+ def link_to_comments_section(post)
5
+ if post.comments.visible.empty?
6
+ link_to("Comment", post_permalink_path(post) + "#comments")
7
+ else
8
+ link_to(pluralize(post.comments.visible.count, 'comment'),
9
+ post_permalink_path(post) + "#comments")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,74 @@
1
+ module RailsBlogEngine
2
+ class Comment < ActiveRecord::Base
3
+ # Define the functions spam?, spam!, and ham!.
4
+ include Rakismet::Model
5
+
6
+ belongs_to :post, :class_name => 'RailsBlogEngine::Post'
7
+
8
+ validates :author_byline, :presence => true
9
+ validates :body, :presence => true
10
+
11
+ # Comments that are visible to the public.
12
+ scope(:visible,
13
+ where(:state => ['unfiltered', 'filtered_as_ham', 'marked_as_ham']))
14
+
15
+ # These fields are directly settable by the user.
16
+ attr_accessible :author_byline, :author_email, :author_url, :body
17
+
18
+ # Tell rakismet where to find the fields it needs for the spam filter.
19
+ # We don't need to specify fields which already have the right name.
20
+ #
21
+ # TODO: Include article permalink.
22
+ rakismet_attrs(:author => :author_byline, :content => :body,
23
+ :user_ip => :author_ip, :user_agent => :author_user_agent)
24
+
25
+ # A state machine which keeps track of our spam filter status.
26
+ state_machine :state, :initial => :unfiltered do
27
+ state :unfiltered
28
+ state :filtered_as_ham
29
+ state :filtered_as_spam
30
+ state :marked_as_ham
31
+ state :marked_as_spam
32
+
33
+ event :filter_as_ham do
34
+ transition :unfiltered => :filtered_as_ham
35
+ end
36
+
37
+ event :filter_as_spam do
38
+ transition :unfiltered => :filtered_as_spam
39
+ end
40
+
41
+ event :mark_as_ham do
42
+ transition [:filtered_as_spam, :marked_as_spam] => :marked_as_ham
43
+ end
44
+
45
+ event :mark_as_spam do
46
+ transition :unfiltered => :marked_as_spam
47
+ transition [:filtered_as_ham, :marked_as_ham] => :marked_as_spam
48
+ end
49
+
50
+ after_transition any => :marked_as_ham, :do => :train_as_ham
51
+ after_transition any => :marked_as_spam, :do => :train_as_spam
52
+ end
53
+
54
+ # Run the spam filter on this comment and update it appropriately.
55
+ def run_spam_filter
56
+ return unless Rakismet.key
57
+ if spam?
58
+ filter_as_spam!
59
+ else
60
+ filter_as_ham!
61
+ end
62
+ end
63
+
64
+ # Train our spam filter to treat messages like this as ham.
65
+ def train_as_ham
66
+ ham! if Rakismet.key
67
+ end
68
+
69
+ # Train our spam filter to treat messages like this as spam.
70
+ def train_as_spam
71
+ spam! if Rakismet.key
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,73 @@
1
+ module RailsBlogEngine
2
+ class Post < ActiveRecord::Base
3
+ belongs_to :author, :polymorphic => true
4
+ has_many :comments, :class_name => 'RailsBlogEngine::Comment'
5
+
6
+ validates :title, :presence => true
7
+ validates :body, :presence => true
8
+ validates(:state, :presence => true,
9
+ :inclusion => { :in => %w(unpublished published) })
10
+ validates :permalink, :presence => true, :uniqueness => true
11
+ validates :author, :presence => true
12
+ validates :author_byline, :presence => true
13
+ validates :published_at, :presence => true, :if => :published?
14
+
15
+ attr_accessible :title, :body, :permalink, :author
16
+
17
+ # Recently published posts. Use this with +limit+.
18
+ scope :recently_published,
19
+ where(:state => 'published').order('published_at DESC')
20
+
21
+ # We use a state machine to represent our publication state. This is
22
+ # mostly because I visualize a UI with a great big "Publish" button,
23
+ # and not a "Published" checkbox in a form.
24
+ #
25
+ # If you'd like to upgrade your blog into a content-management system
26
+ # with some kind of pre-publication review, just adjust the states and
27
+ # transitions.
28
+ state_machine :state, :initial => :unpublished do
29
+ state :unpublished
30
+ state :published
31
+
32
+ event :publish do
33
+ transition :unpublished => :published
34
+ end
35
+
36
+ event :unpublish do
37
+ transition :published => :unpublished
38
+ end
39
+
40
+ before_transition any => :published do |post, transition|
41
+ post.published_at ||= Time.now
42
+ end
43
+ end
44
+
45
+ before_validation :record_author_byline
46
+
47
+ protected
48
+
49
+ # Since the byline is computed from a polymorphic author association in
50
+ # a complicated fashion, we want to cache it in this object where it's
51
+ # available all the time.
52
+ def record_author_byline
53
+ byline = self.class.author_byline(author)
54
+ self.author_byline = byline unless self.author_byline == byline
55
+ end
56
+
57
+ class << self
58
+ # Try to generate a reasonable byline for an author. We use a
59
+ # +author.byline+ method if present, and default to +author.email+
60
+ # stripped of its domain.
61
+ def author_byline(author)
62
+ case
63
+ when author.respond_to?(:byline) && author.byline
64
+ author.byline
65
+ when author.respond_to?(:email) && author.email
66
+ author.email.sub(/@.*\z/, '')
67
+ else
68
+ 'unknown'
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,10 @@
1
+ .rails_blog_engine_comment.show{:class => comment_classes(comment)}
2
+ = render(:partial => 'rails_blog_engine/comments/tools',
3
+ :locals => { :comment => comment })
4
+ %h4.byline
5
+ %a{:name => "comment-#{comment.id}"}
6
+ = comment_author_html(comment)
7
+ said
8
+ %a{:class => "comment-link", :href => "#comment-#{comment.id}"}= distance_of_time_in_words_to_now(comment.created_at)
9
+ ago:
10
+ %div.body~ markdown(comment.body, :trusted? => comment.author_can_post?)
@@ -0,0 +1,6 @@
1
+ = simple_form_for(comment, :url => post_comments_path(comment.post)) do |f|
2
+ = f.input :author_byline
3
+ = f.input :author_email
4
+ = f.input :author_url
5
+ = f.input :body
6
+ = f.button :submit, :class => "new_comment btn primary"
@@ -0,0 +1,10 @@
1
+ - if can?(:update, comment)
2
+ .comment-tools
3
+ - if can?(:mark_as_ham, comment) && comment.can_mark_as_ham?
4
+ = link_to("Not Spam",
5
+ mark_as_ham_post_comment_path(comment.post, comment),
6
+ :method => :post, :class => "btn")
7
+ - if can?(:mark_as_spam, comment) && comment.can_mark_as_spam?
8
+ = link_to("Spam",
9
+ mark_as_spam_post_comment_path(comment.post, comment),
10
+ :method => :post, :class => "btn")
@@ -0,0 +1,6 @@
1
+ - content_for :title do
2
+ New Comment
3
+
4
+ <h1>New Comment</h1>
5
+
6
+ = render :partial => 'form', :locals => { :comment => @comment }
@@ -0,0 +1,11 @@
1
+ %h3.comments
2
+ %a(name="comments") Comments
3
+
4
+ = render @comments
5
+
6
+ - if flash[:comment_notice]
7
+ %p.flash.notice
8
+ %a(name="comment-flash")= flash[:comment_notice]
9
+
10
+ = render(:partial => 'rails_blog_engine/comments/form',
11
+ :locals => { :comment => @comment })
@@ -0,0 +1,7 @@
1
+ = simple_form_for(post,
2
+ :input_html => { :class => "rails_blog_engine_post" }) do |f|
3
+ = f.input :title
4
+ = f.input :permalink
5
+ = f.input :body
6
+ = f.input :published_at
7
+ = f.button :submit, :class => "update_post btn primary"
@@ -0,0 +1,20 @@
1
+ .rails_blog_engine_post
2
+ %h1
3
+ = link_to_unless_current(post.title, post_permalink_path(post))
4
+ = render(:partial => 'rails_blog_engine/posts/tools',
5
+ :locals => { :post => post })
6
+ %p.byline
7
+ Posted
8
+ = distance_of_time_in_words_to_now(post.published_at)
9
+ ago by
10
+ = post.author_byline
11
+
12
+ %div.body~ markdown(post.body, :trusted? => true)
13
+
14
+ - if current_page?(post_permalink_path(post))
15
+ = render(:partial => 'rails_blog_engine/posts/comments_section',
16
+ :locals => { :post => post, :comments => @comments,
17
+ :comment => @comment })
18
+ - else
19
+ %p.links
20
+ = link_to_comments_section(post)
@@ -0,0 +1,2 @@
1
+ - if can?(:update, RailsBlogEngine::Post)
2
+ = link_to "Edit", edit_post_path(post), :class => "edit_post btn secondary"
@@ -0,0 +1,5 @@
1
+ - content_for :title do
2
+ Edit Post
3
+ %h1 Edit Post
4
+
5
+ = render :partial => 'form', :locals => { :post => @post }
@@ -0,0 +1,14 @@
1
+ atom_feed(:root_url => root_url, :url => feed_url) do |feed|
2
+ feed.title t('rails_blog_engine.blog.title')
3
+ feed.updated @posts.map(&:updated_at).sort.reverse.first
4
+ @posts.each do |post|
5
+ feed.entry(post, :published => post.published_at,
6
+ :url => post_permalink_url(post)) do |entry|
7
+ entry.title post.title
8
+ entry.content markdown(post.body), :type => 'html'
9
+ entry.author do |author|
10
+ author.name post.author_byline
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ - content_for :title do
2
+ = t('rails_blog_engine.blog.title')
3
+ - content_for :head do
4
+ = auto_discovery_link_tag :atom, feed_url
5
+ - if params[:page]
6
+ -# Don't index pages after the first, but still follow links.
7
+ - content_for :head do
8
+ %meta(name="robots" content="noindex, follow")
9
+
10
+ .rails_blog_engine_posts
11
+ - if can?(:create, RailsBlogEngine::Post)
12
+ = link_to "New Post", new_post_path, :class => "new_post btn large primary"
13
+
14
+ = render @posts
15
+ = paginate @posts
@@ -0,0 +1,5 @@
1
+ - content_for :title do
2
+ New Post
3
+ %h1 New Post
4
+
5
+ = render :partial => 'form', :locals => { :post => @post }
@@ -0,0 +1,8 @@
1
+ - content_for :title do
2
+ = @post.title
3
+
4
+ = t('rails_blog_engine.blog.title')
5
+ - content_for :head do
6
+ = auto_discovery_link_tag :atom, feed_url
7
+
8
+ = render @post
@@ -0,0 +1,15 @@
1
+ en:
2
+ rails_blog_engine:
3
+ blog:
4
+ title: "Blog"
5
+ activerecord:
6
+ attributes:
7
+ rails_blog_engine/comment:
8
+ author_byline: "Your name"
9
+ author_email: "Your email"
10
+ author_url: "Your website"
11
+ body: "Comment"
12
+ helpers:
13
+ submit:
14
+ comment:
15
+ create: "Post Comment"