almanac 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +76 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/images/almanac/background.jpg +0 -0
  5. data/app/assets/images/almanac/icons/compose.png +0 -0
  6. data/app/assets/images/almanac/icons/feed.png +0 -0
  7. data/app/assets/images/almanac/icons/gear.png +0 -0
  8. data/app/assets/images/almanac/icons/glyphicons-halflings-white.png +0 -0
  9. data/app/assets/images/almanac/icons/glyphicons-halflings.png +0 -0
  10. data/app/assets/images/almanac/icons/upload.png +0 -0
  11. data/app/assets/images/almanac/logo.jpg +0 -0
  12. data/app/assets/javascripts/almanac/2-jquery.backstretch.js +357 -0
  13. data/app/assets/javascripts/almanac/3-pixastic.js +637 -0
  14. data/app/assets/javascripts/almanac/4-bootstrap-datepicker.js +454 -0
  15. data/app/assets/javascripts/almanac/5-main.coffee.erb +46 -0
  16. data/app/assets/javascripts/almanac/application.js +16 -0
  17. data/app/assets/stylesheets/almanac/1-datepicker.css +7 -0
  18. data/app/assets/stylesheets/almanac/2-main.css.scss +279 -0
  19. data/app/assets/stylesheets/almanac/application.css +15 -0
  20. data/app/controllers/almanac/application_controller.rb +24 -0
  21. data/app/controllers/almanac/blogs_controller.rb +64 -0
  22. data/app/controllers/almanac/comments_controller.rb +41 -0
  23. data/app/controllers/almanac/images_controller.rb +29 -0
  24. data/app/controllers/almanac/posts_controller.rb +109 -0
  25. data/app/helpers/almanac/application_helper.rb +4 -0
  26. data/app/models/almanac/blog.rb +32 -0
  27. data/app/models/almanac/comment.rb +20 -0
  28. data/app/models/almanac/image.rb +10 -0
  29. data/app/models/almanac/post.rb +55 -0
  30. data/app/views/almanac/blogs/_form.html.haml +76 -0
  31. data/app/views/almanac/blogs/_topbar.html.haml +5 -0
  32. data/app/views/almanac/blogs/edit.html.haml +4 -0
  33. data/app/views/almanac/blogs/new.html.haml +3 -0
  34. data/app/views/almanac/blogs/spam.html.haml +15 -0
  35. data/app/views/almanac/posts/_form.html.haml +52 -0
  36. data/app/views/almanac/posts/_post.html.haml +59 -0
  37. data/app/views/almanac/posts/edit.html.haml +1 -0
  38. data/app/views/almanac/posts/index.html.haml +30 -0
  39. data/app/views/almanac/posts/index.rss.builder +18 -0
  40. data/app/views/almanac/posts/new.html.haml +1 -0
  41. data/app/views/almanac/posts/show.html.haml +4 -0
  42. data/app/views/almanac/posts/tag.html.haml +22 -0
  43. data/app/views/layouts/almanac/_ga.html.haml +10 -0
  44. data/app/views/layouts/almanac/_twitter_follow.html.haml +2 -0
  45. data/app/views/layouts/almanac/application.html.haml +52 -0
  46. data/config/routes.rb +22 -0
  47. data/db/migrate/20121009222451_create_almanac_posts.rb +17 -0
  48. data/db/migrate/20121010033555_create_almanac_blogs.rb +14 -0
  49. data/db/migrate/20121017032059_add_excerpt_to_almanac_posts.rb +11 -0
  50. data/db/migrate/20121017210007_create_almanac_files.rb +15 -0
  51. data/db/migrate/20121017221819_rename_file_to_image.rb +9 -0
  52. data/db/migrate/20121025223403_add_image_fields_to_almanac_blogs.rb +13 -0
  53. data/db/migrate/20121029211221_add_new_fields_to_blogs.rb +15 -0
  54. data/db/migrate/20121029221815_acts_as_taggable_on_migration.rb +30 -0
  55. data/db/migrate/20121101030836_create_almanac_comments.rb +16 -0
  56. data/db/migrate/20121102181941_add_rakismet_fields_to_blogs.rb +13 -0
  57. data/db/migrate/20121102185130_add_spam_to_comments.rb +11 -0
  58. data/db/migrate/20121110000024_add_written_at_to_posts.rb +11 -0
  59. data/db/migrate/20121112205256_add_background_fields_to_blogs.rb +13 -0
  60. data/db/migrate/20121113010557_add_footer_to_almanac_blogs.rb +11 -0
  61. data/db/migrate/20121114043648_change_default_value_for_background_tiles_in_almanac_blogs.rb +9 -0
  62. data/lib/almanac.rb +16 -0
  63. data/lib/almanac/MarkdownParser.rb +18 -0
  64. data/lib/almanac/engine.rb +9 -0
  65. data/lib/almanac/version.rb +3 -0
  66. data/lib/tasks/almanac_tasks.rake +4 -0
  67. data/spec/controllers/blogs_controller_spec.rb +80 -0
  68. data/spec/controllers/comments_controller_spec.rb +51 -0
  69. data/spec/controllers/posts_controller_spec.rb +120 -0
  70. data/spec/dummy/README.rdoc +261 -0
  71. data/spec/dummy/Rakefile +7 -0
  72. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  73. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  74. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  75. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  76. data/spec/dummy/app/models/ability.rb +13 -0
  77. data/spec/dummy/app/models/user.rb +11 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  79. data/spec/dummy/config.ru +4 -0
  80. data/spec/dummy/config/application.rb +59 -0
  81. data/spec/dummy/config/boot.rb +10 -0
  82. data/spec/dummy/config/database.yml +25 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +37 -0
  85. data/spec/dummy/config/environments/production.rb +67 -0
  86. data/spec/dummy/config/environments/test.rb +37 -0
  87. data/spec/dummy/config/initializers/almanac.rb +1 -0
  88. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  89. data/spec/dummy/config/initializers/devise.rb +233 -0
  90. data/spec/dummy/config/initializers/dragonfly.rb +7 -0
  91. data/spec/dummy/config/initializers/inflections.rb +15 -0
  92. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  93. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  94. data/spec/dummy/config/initializers/session_store.rb +8 -0
  95. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  96. data/spec/dummy/config/locales/en.yml +5 -0
  97. data/spec/dummy/config/routes.rb +14 -0
  98. data/spec/dummy/db/migrate/20121009230705_create_almanac_posts.rb +18 -0
  99. data/spec/dummy/db/migrate/20121010033827_create_almanac_blogs.rb +15 -0
  100. data/spec/dummy/db/migrate/20121102224650_add_excerpt_to_almanac_posts.rb +12 -0
  101. data/spec/dummy/db/migrate/20121102224651_create_almanac_files..rb +16 -0
  102. data/spec/dummy/db/migrate/20121102224652_rename_file_to_image.rb +10 -0
  103. data/spec/dummy/db/migrate/20121102224653_add_image_fields_to_almanac_blogs.rb +14 -0
  104. data/spec/dummy/db/migrate/20121102224654_add_new_fields_to_almanac_blogs.rb +16 -0
  105. data/spec/dummy/db/migrate/20121102224655_acts_as_taggable_on_migration.rb +31 -0
  106. data/spec/dummy/db/migrate/20121102224656_create_almanac_comments.rb +17 -0
  107. data/spec/dummy/db/migrate/20121102224657_add_rakismet_fields_to_almanac_blogs.rb +14 -0
  108. data/spec/dummy/db/migrate/20121102224658_add_spam_to_almanac_comments.rb +12 -0
  109. data/spec/dummy/db/migrate/20121106220325_devise_create_users.rb +46 -0
  110. data/spec/dummy/db/migrate/20121114032144_add_written_at_to_almanac_posts.rb +12 -0
  111. data/spec/dummy/db/migrate/20121114032145_add_background_fields_to_almanac_blogs.rb +14 -0
  112. data/spec/dummy/db/migrate/20121114032146_add_footer_to_almanac_blogs.rb +12 -0
  113. data/spec/dummy/db/schema.rb +98 -0
  114. data/spec/dummy/db/test.sqlite3 +0 -0
  115. data/spec/dummy/log/production.log +1 -0
  116. data/spec/dummy/log/test.log +2930 -0
  117. data/spec/dummy/public/404.html +26 -0
  118. data/spec/dummy/public/422.html +26 -0
  119. data/spec/dummy/public/500.html +25 -0
  120. data/spec/dummy/public/favicon.ico +0 -0
  121. data/spec/dummy/script/rails +6 -0
  122. data/spec/factories.rb +72 -0
  123. data/spec/models/blog_spec.rb +16 -0
  124. data/spec/models/comment_spec.rb +35 -0
  125. data/spec/models/post_spec.rb +79 -0
  126. data/spec/spec_helper.rb +37 -0
  127. metadata +485 -0
@@ -0,0 +1,41 @@
1
+ require_dependency "almanac/application_controller"
2
+
3
+ module Almanac
4
+ class CommentsController < ApplicationController
5
+ load_and_authorize_resource class: Almanac::Comment
6
+ respond_to :html
7
+
8
+ def create
9
+ @comment = Comment.new(params[:comment])
10
+ @post = Post.find(params[:post_id])
11
+
12
+ @comment.post = @post
13
+
14
+ respond_with(@comment) do |format|
15
+ @comment.spam = (@blog.rakismet_key?) ? @comment.spam? : false
16
+
17
+ if @comment.save
18
+ format.html {
19
+ redirect_to post_path(@comment.post),
20
+ :notice => (@comment.spam) ? "Your comment looks like spam, it won't be published." : "Comment was successfully posted."
21
+ }
22
+ else
23
+ format.html { redirect_to post_path(@post), :alert => 'Something went wrong, try again.' }
24
+ end
25
+ end
26
+ end
27
+
28
+ def destroy
29
+ @post = Post.find(params[:post_id])
30
+ @comment = Comment.find(params[:id])
31
+ respond_to do |format|
32
+ if @comment.destroy
33
+ format.html { redirect_to post_path(@post), :notice => 'Comment was successfully deleted.' }
34
+ format.js { render :nothing => true }
35
+ else
36
+ format.html { redirect_to post_path(@post), :alert => 'Something went wrong, try again.' }
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,29 @@
1
+ require_dependency "almanac/application_controller"
2
+
3
+ module Almanac
4
+ class ImagesController < ApplicationController
5
+ load_and_authorize_resource class: Almanac::Image
6
+ respond_to :html
7
+
8
+ def create
9
+ @blog = Almanac::Blog.first
10
+ @image = Image.new(params[:image])
11
+
12
+ if params[:post_id] == "0"
13
+ @post = Post.create( { :published => false, :author_id => current_user.id, :blog_id => @blog.id } )
14
+ else
15
+ @post = Post.find(params[:post_id])
16
+ end
17
+
18
+ @image.post = @post
19
+
20
+ respond_with(@image) do |format|
21
+ if @image.save
22
+ format.html { redirect_to edit_post_path(@image.post), :notice => 'Image was successfully created.' }
23
+ else
24
+ format.html { render :action => :back, :alert => 'Something went wrong, try again.' }
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,109 @@
1
+ require_dependency "almanac/application_controller"
2
+
3
+ module Almanac
4
+ class PostsController < ApplicationController
5
+ load_and_authorize_resource class: Almanac::Post
6
+ respond_to :html
7
+ before_filter :only => [:show, :edit, :update, :delete] do |controller|
8
+ @post = Post.find(params[:id])
9
+ end
10
+ before_filter :only => [:show] do |controller|
11
+ if @post.published
12
+ @comments = @post.comments.where(:spam => false)
13
+ end
14
+ end
15
+
16
+ def index
17
+ @posts = (@blog.nil?) ? [] : Post.recent(params)
18
+ @drafts = (@blog.nil? or current_user.nil?) ? [] : Post.drafts(params)
19
+
20
+ respond_with(@posts) do |format|
21
+ if @blog.nil?
22
+ unless current_user.nil?
23
+ format.html { redirect_to new_blog_path }
24
+ end
25
+ else
26
+ format.html
27
+ format.rss { render :layout => false }
28
+ end
29
+ end
30
+ end
31
+
32
+ def tag
33
+ @posts = (@blog.nil?) ? [] : Post.tagged(params)
34
+ @tag = params[:tag_name]
35
+
36
+ respond_with(@posts) do |format|
37
+ if @blog.nil?
38
+ unless current_user.nil?
39
+ format.html { redirect_to new_path }
40
+ end
41
+ else
42
+ format.html
43
+ format.rss { render :layout => false }
44
+ end
45
+ end
46
+ end
47
+
48
+ def show
49
+ respond_with(@post) do |format|
50
+ format.html
51
+ end
52
+ end
53
+
54
+ def new
55
+ @post = Post.new
56
+ @post.id = 0
57
+ @images = @post.images
58
+
59
+ respond_with(@post) do |format|
60
+ format.html
61
+ end
62
+ end
63
+
64
+ def create
65
+ @post = Post.new(params[:post])
66
+ @post.blog = Almanac::Blog.first
67
+ @post.author_id = current_user.id
68
+
69
+ respond_with(@post) do |format|
70
+ if @post.save
71
+ format.html { redirect_to :root, :notice => 'Post was successfully created.' }
72
+ else
73
+ @post.id = 0
74
+ format.html { render :action => "new", :alert => 'Something went wrong, try again.' }
75
+ end
76
+ end
77
+ end
78
+
79
+ def edit
80
+ respond_to do |format|
81
+ format.html
82
+ end
83
+ end
84
+
85
+ def update
86
+ @post.blog = Almanac::Blog.first
87
+
88
+ respond_with(@post) do |format|
89
+ if @post.update_attributes(params[:post])
90
+ format.html { redirect_to :root, :notice => 'Post was successfully updated.' }
91
+ else
92
+ format.html { render :action => "edit" }
93
+ end
94
+ end
95
+ end
96
+
97
+ def destroy
98
+ post_id = @post.id
99
+ respond_to do |format|
100
+ if @post.destroy
101
+ format.html { redirect_to :root, :notice => 'Post was successfully deleted.' }
102
+ format.js { render :nothing => true }
103
+ else
104
+ format.html { redirect_to post_path(@post), :alert => 'Something went wrong, try again.' }
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,4 @@
1
+ module Almanac
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,32 @@
1
+ class Almanac::Blog < ActiveRecord::Base
2
+ belongs_to :author, :class_name => Almanac.user_class
3
+
4
+ attr_accessible :title, :description, :author_id, :logo, :background, :retained_logo,
5
+ :retained_background, :google_analytics, :twitter, :rakismet_key,
6
+ :rakismet_url, :background_tile, :background_blur, :footer
7
+
8
+ image_accessor :logo do
9
+ after_assign{|a| a.process!(:thumb, '100x100#').encode(:png) }
10
+ end
11
+ image_accessor :background do
12
+ after_assign{|a| a.process!(:thumb, '1200x>').encode(:png) }
13
+ end
14
+
15
+ before_save :author=
16
+ before_create :check_for_uniqueness
17
+
18
+ validates_presence_of :author_id
19
+ validates_presence_of :title
20
+ validates_inclusion_of :background_blur, :in => [0, 1, 2]
21
+
22
+ def author=
23
+ @author = Almanac.user_class.constantize.find(self.author_id)
24
+ end
25
+
26
+ private
27
+ def check_for_uniqueness
28
+ unless Almanac::Blog.first == nil
29
+ raise "You can only have one blog."
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ class Almanac::Comment < ActiveRecord::Base
2
+ include Rakismet::Model
3
+
4
+ belongs_to :post
5
+
6
+ attr_accessible :body, :author_email, :author_name, :post_id
7
+
8
+ validates_presence_of :author_name
9
+ validates_presence_of :author_email
10
+ validates_presence_of :post
11
+ validates_presence_of :body
12
+
13
+ rakismet_attrs :author => :author_name, :author_email => :author_email
14
+
15
+ default_scope order('id ASC')
16
+
17
+ def self.spam
18
+ self.where(:spam => true)
19
+ end
20
+ end
@@ -0,0 +1,10 @@
1
+ class Almanac::Image < ActiveRecord::Base
2
+ belongs_to :post
3
+
4
+ attr_accessible :image, :thumb, :post_id
5
+
6
+ image_accessor :image do
7
+ copy_to(:thumb){|a| a.thumb('100x100#') }
8
+ end
9
+ image_accessor :thumb
10
+ end
@@ -0,0 +1,55 @@
1
+ class Almanac::Post < ActiveRecord::Base
2
+ belongs_to :blog
3
+ belongs_to :author, :class_name => Almanac.user_class
4
+ has_many :images, :dependent => :destroy
5
+ has_many :comments, :dependent => :destroy
6
+
7
+ attr_accessible :title, :body, :published, :excerpt, :author_id, :blog_id, :tag_list, :written_at
8
+
9
+ validates_presence_of :blog_id
10
+ validates_presence_of :written_at
11
+ validates_presence_of :author_id
12
+ validates_presence_of :title, :if => lambda {|_| _.published }
13
+ validates_presence_of :body, :if => lambda {|_| _.published }
14
+
15
+
16
+ before_save :author=
17
+ after_initialize :set_written_at
18
+
19
+ acts_as_taggable
20
+
21
+ self.per_page = 10
22
+
23
+ default_scope order('written_at DESC, id DESC')
24
+
25
+ def self.recent(params)
26
+ self.where(:published => true).paginate(:page => posts_page(params), :per_page => posts_limit(params))
27
+ end
28
+
29
+ def self.drafts(params)
30
+ self.where(:published => false)
31
+ end
32
+
33
+ def self.tagged(params)
34
+ self.where(:published => true).tagged_with(params[:tag_name]).paginate(:page => posts_page(params), :per_page => posts_limit(params))
35
+ end
36
+
37
+ private
38
+ def self.posts_limit(params)
39
+ (params[:limit].blank?) ? self.per_page : params[:limit]
40
+ end
41
+
42
+ private
43
+ def self.posts_page(params)
44
+ (params[:page].blank?) ? 1 : params[:page]
45
+ end
46
+
47
+ private
48
+ def set_written_at
49
+ self.written_at ||= Date.today if new_record?
50
+ end
51
+
52
+ def author=
53
+ @author = Almanac.user_class.constantize.find(self.author_id)
54
+ end
55
+ end
@@ -0,0 +1,76 @@
1
+ = form_for @blog, :html => {:multipart => true} do |f|
2
+ = f.hidden_field :retained_logo
3
+ = f.hidden_field :retained_background
4
+ - if @blog.errors.any?
5
+ #error_explanation
6
+ %h5
7
+ = pluralize(@blog.errors.count, "error")
8
+ prohibited this blog from being saved:
9
+ %ul
10
+ - @blog.errors.full_messages.each do |msg|
11
+ %li= msg
12
+ %h4 Main
13
+ .field
14
+ = f.label :title
15
+ = f.text_field :title
16
+ .field
17
+ = f.label :description
18
+ = f.text_area :description, :placeholder => "What is your blog about? This will go under RSS feed.", :rows => 2
19
+ .field
20
+ = f.label :footer
21
+ = f.text_area :footer, :placeholder => "You can use markdown in this field.", :rows => 2
22
+
23
+ %h4 Graphics
24
+ .field
25
+ = f.label :logo
26
+ = f.file_field :logo
27
+
28
+ .field
29
+ = f.label :background, "Background Image"
30
+ = f.file_field :background
31
+
32
+ .field
33
+ %label
34
+ Background Behavior
35
+ .row-fluid
36
+ .span2
37
+ = label :background_tile, "false", :class => "radio" do
38
+ = f.radio_button :background_tile, false
39
+ Stretch
40
+ .span2
41
+ = label :background_tile, "true", :class => "radio" do
42
+ = f.radio_button :background_tile, true
43
+ Tile
44
+ .field
45
+ %label
46
+ Background Blur
47
+ .row-fluid
48
+ .span2
49
+ = label :background_blur, 0, :class => "radio" do
50
+ = f.radio_button :background_blur, 0
51
+ Off
52
+ .span2
53
+ = label :background_blur, 1, :class => "radio" do
54
+ = f.radio_button :background_blur, 1
55
+ Normal
56
+ .span2
57
+ = label :background_blur, 2, :class => "radio" do
58
+ = f.radio_button :background_blur, 2
59
+ Strong
60
+
61
+ %h4 Under the Hood
62
+ .field
63
+ = f.label :twitter, "Your Twitter Handle"
64
+ = f.text_field :twitter, :placeholder => "e.g. vasinov"
65
+ .field
66
+ = f.label :google_analytics, "Google Analytics ID"
67
+ = f.text_field :google_analytics, :placeholder => "e.g. UA-00000000-1"
68
+ .field
69
+ = f.label :rakismet_key, "Akismet Antispam Key"
70
+ = f.text_field :rakismet_key, :placeholder => "e.g. husd38d123dd"
71
+ .field
72
+ = f.label :rakismet_url, "Akismet Antispam URL"
73
+ = f.text_field :rakismet_url, :placeholder => "e.g. http://blog.yourdomain.com"
74
+
75
+ .actions
76
+ = f.submit :class => "btn btn-primary"
@@ -0,0 +1,5 @@
1
+ %ul.nav.nav-tabs
2
+ %li{ :class => (action_name == "edit") ? "active" : ""}
3
+ = link_to "Settings", edit_blog_path(@blog)
4
+ %li{ :class => (action_name == "spam") ? "active" : ""}
5
+ = link_to "Spam", spam_blog_path(@blog)
@@ -0,0 +1,4 @@
1
+ %h3.head Blog Internals
2
+ .well
3
+ = render "topbar"
4
+ = render "form"
@@ -0,0 +1,3 @@
1
+ %h3.head New Blog
2
+ .well
3
+ = render "form"
@@ -0,0 +1,15 @@
1
+ %h3.head Spam Comments
2
+ .well
3
+ = render "topbar"
4
+ - if @comments.empty?
5
+ There aren't any spam comments at the moment. Congratulations!
6
+ - else
7
+ - @comments.each do |comment|
8
+ .well
9
+ %h5
10
+ = "#{comment.author_name} said #{time_ago_in_words comment.created_at} ago:"
11
+ = comment.body
12
+ .actions
13
+ - if can? :delete, comment
14
+ = link_to post_comment_path(comment.post, comment), :confirm => 'Are you sure?', :method => :delete, :class => "" do
15
+ %i.icon-trash.icon
@@ -0,0 +1,52 @@
1
+ %h3.head Post Images
2
+ .well
3
+ = form_for([@post, @post.images.build], :html => { :multipart => true }) do |f|
4
+ .custom-upload
5
+ %input{:name => "image[image]", :type => "file"}
6
+ .fake-file
7
+ %input{:disabled => "disabled"}
8
+ = f.submit :class => "btn btn-small", :value => "Upload Image"
9
+ - unless @post.images.empty?
10
+ .images
11
+ - @post.images.each do |image|
12
+ - if image.id
13
+ - unless image.thumb.nil?
14
+ .image-thumb
15
+ = image_tag image.thumb.url
16
+ %p.centered
17
+ %a{ :href => "#add", :class => "add-photo", "data-image" => image.image.url } Add To Post
18
+ -#%a{ :class => "close"} &times;
19
+ %h3.head Post Editor
20
+ .well
21
+ = form_for @post do |f|
22
+ - if @post.errors.any?
23
+ #error_explanation.well
24
+ %h4
25
+ = pluralize(@post.errors.count, "error")
26
+ prohibited this post from being saved:
27
+ %ul
28
+ - @post.errors.full_messages.each do |msg|
29
+ %li= msg
30
+ .row-fluid
31
+ .span6
32
+ .field
33
+ = f.label :title, "Post Title"
34
+ = f.text_field :title, :placeholder => "Title is required."
35
+ .span6
36
+ .field
37
+ = f.label :written_at, "Timestamp"
38
+ = f.text_field :written_at, :class => "datepicker"
39
+ .field
40
+ = f.label :excerpt, "Excerpt"
41
+ = f.text_area :excerpt, :placeholder => "This is where you can put a summary of your post. You can use Markdown here. It's not required.", :rows => 2
42
+ .field
43
+ = f.label :body, "Main Content"
44
+ = f.text_area :body, :placeholder => "This is where your post goes. You can use markdown here."
45
+ .field
46
+ = f.label :tag_list, "Tags"
47
+ = f.text_field :tag_list, :placeholder => "Comma-separated tags."
48
+ %label.checkbox
49
+ = f.check_box :published
50
+ = f.label :published, "Publish"
51
+ .actions
52
+ = f.submit :class => "btn btn-primary"