tb_blog 1.0

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 (85) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +29 -0
  4. data/Readme.markdown +130 -0
  5. data/app/assets/images/spud/admin/news_thumb.png +0 -0
  6. data/app/assets/images/spud/admin/news_thumb@2x.png +0 -0
  7. data/app/assets/images/spud/admin/posts_thumb.png +0 -0
  8. data/app/assets/javascripts/spud/admin/post_categories.js +116 -0
  9. data/app/assets/javascripts/spud/admin/posts.js +71 -0
  10. data/app/assets/javascripts/spud/blog/sitemaps.js +2 -0
  11. data/app/assets/javascripts/spud/blog.js +41 -0
  12. data/app/assets/stylesheets/news.css +4 -0
  13. data/app/assets/stylesheets/spud/admin/posts.css +113 -0
  14. data/app/assets/stylesheets/spud/blog/sitemaps.css +4 -0
  15. data/app/assets/stylesheets/spud/blog/validity.css +3 -0
  16. data/app/controllers/blog_controller.rb +135 -0
  17. data/app/controllers/news_controller.rb +80 -0
  18. data/app/controllers/spud/admin/news_posts_controller.rb +62 -0
  19. data/app/controllers/spud/admin/post_categories_controller.rb +59 -0
  20. data/app/controllers/spud/admin/post_comments_controller.rb +68 -0
  21. data/app/controllers/spud/admin/posts_controller.rb +62 -0
  22. data/app/controllers/spud/blog/sitemaps_controller.rb +9 -0
  23. data/app/helpers/blog_helper.rb +25 -0
  24. data/app/helpers/news_helper.rb +2 -0
  25. data/app/helpers/spud/admin/news_posts_helper.rb +2 -0
  26. data/app/helpers/spud/admin/post_categories_helper.rb +2 -0
  27. data/app/helpers/spud/admin/post_comments_helper.rb +2 -0
  28. data/app/helpers/spud/admin/posts_helper.rb +22 -0
  29. data/app/helpers/spud/blog/sitemaps_helper.rb +2 -0
  30. data/app/models/spud_post.rb +171 -0
  31. data/app/models/spud_post_categories_post.rb +5 -0
  32. data/app/models/spud_post_category.rb +70 -0
  33. data/app/models/spud_post_category_sweeper.rb +41 -0
  34. data/app/models/spud_post_comment.rb +19 -0
  35. data/app/models/spud_post_comment_sweeper.rb +33 -0
  36. data/app/models/spud_post_site.rb +9 -0
  37. data/app/models/spud_post_sweeper.rb +47 -0
  38. data/app/views/blog/_comment.html.erb +4 -0
  39. data/app/views/blog/_comment_form.html.erb +20 -0
  40. data/app/views/blog/index.html.erb +35 -0
  41. data/app/views/blog/index.rss.builder +18 -0
  42. data/app/views/blog/show.html.erb +37 -0
  43. data/app/views/news/index.html.erb +35 -0
  44. data/app/views/news/index.rss.builder +18 -0
  45. data/app/views/news/show.html.erb +27 -0
  46. data/app/views/spud/admin/news_posts/edit.html.erb +3 -0
  47. data/app/views/spud/admin/news_posts/index.html.erb +44 -0
  48. data/app/views/spud/admin/news_posts/new.html.erb +3 -0
  49. data/app/views/spud/admin/post_categories/_category.html.erb +14 -0
  50. data/app/views/spud/admin/post_categories/_form.html.erb +23 -0
  51. data/app/views/spud/admin/post_categories/edit.html.erb +1 -0
  52. data/app/views/spud/admin/post_categories/index.html.erb +9 -0
  53. data/app/views/spud/admin/post_categories/new.html.erb +1 -0
  54. data/app/views/spud/admin/post_comments/index.html.erb +47 -0
  55. data/app/views/spud/admin/posts/_category.html.erb +9 -0
  56. data/app/views/spud/admin/posts/_form.html.erb +117 -0
  57. data/app/views/spud/admin/posts/edit.html.erb +3 -0
  58. data/app/views/spud/admin/posts/index.html.erb +50 -0
  59. data/app/views/spud/admin/posts/new.html.erb +3 -0
  60. data/app/views/spud/blog/sitemaps/show.xml.builder +16 -0
  61. data/config/routes.rb +94 -0
  62. data/db/migrate/20120125180945_create_spud_posts.rb +15 -0
  63. data/db/migrate/20120125181022_create_spud_post_categories.rb +13 -0
  64. data/db/migrate/20120125181359_create_spud_post_comments.rb +13 -0
  65. data/db/migrate/20120127143054_add_url_to_spud_posts.rb +6 -0
  66. data/db/migrate/20120127144942_add_url_to_spud_post_categories.rb +8 -0
  67. data/db/migrate/20120210165540_add_is_news_to_spud_posts.rb +6 -0
  68. data/db/migrate/20120309181917_add_meta_to_posts.rb +6 -0
  69. data/db/migrate/20120413020437_add_comments_counter_to_spud_posts.rb +12 -0
  70. data/db/migrate/20120713150446_create_spud_post_sites.rb +11 -0
  71. data/db/migrate/20120825142547_add_spam_fields_to_spud_post_comments.rb +8 -0
  72. data/db/migrate/20120825144506_add_permalink_to_spud_post_comments.rb +5 -0
  73. data/db/migrate/20121113135812_add_nested_set_to_post_categories.rb +21 -0
  74. data/db/migrate/20130120151857_add_content_format_to_spud_posts.rb +5 -0
  75. data/db/migrate/20130121130612_add_content_processed_to_spud_post.rb +5 -0
  76. data/lib/generators/spud/blog/random_posts_generator.rb +60 -0
  77. data/lib/generators/spud/blog/views_generator.rb +19 -0
  78. data/lib/spud_blog/configuration.rb +25 -0
  79. data/lib/spud_blog/engine.rb +64 -0
  80. data/lib/spud_blog/version.rb +5 -0
  81. data/lib/tasks/spud_blog_tasks.rake +4 -0
  82. data/lib/tb_blog.rb +6 -0
  83. data/test/fixtures/spud_post_sites.yml +9 -0
  84. data/test/unit/spud_post_site_test.rb +7 -0
  85. metadata +338 -0
@@ -0,0 +1,171 @@
1
+ class SpudPost < ActiveRecord::Base
2
+ spud_searchable
3
+
4
+ has_and_belongs_to_many :categories,
5
+ :class_name => 'SpudPostCategory',
6
+ :join_table => 'spud_post_categories_posts',
7
+ :foreign_key => 'spud_post_id'
8
+ belongs_to :author, :class_name => 'SpudUser', :foreign_key => 'spud_user_id'
9
+ has_many :comments, :class_name => 'SpudPostComment'
10
+ has_many :visible_comments, :class_name => 'SpudPostComment',:conditions => {:spam => [nil,false]}
11
+ has_many :spam_comments, :class_name => "SpudPostComment", :conditions => {:spam => true}
12
+ has_many :spud_permalinks,:as => :attachment
13
+ has_many :spud_post_sites, :dependent => :destroy
14
+
15
+ scope :publicly, where('visible = true AND published_at <= ?', Time.now.utc).order('published_at desc')
16
+ scope :future_posts, where('visible = true AND published_at > ?', Time.now.utc)
17
+ validates_presence_of :title, :content, :published_at, :spud_user_id, :url_name
18
+ validates_uniqueness_of :url_name
19
+ before_validation :set_url_name
20
+ before_save :postprocess_content
21
+
22
+ after_save :set_spud_site_ids
23
+
24
+ attr_accessible :is_news,:published_at,:title,:content,:spud_user_id,:url_name,:visible,:comments_enabled,:meta_keywords,:meta_description,:category_ids, :spud_site_ids, :content_format
25
+ attr_accessor :spud_site_ids
26
+
27
+ def self.for_spud_site(spud_site_id)
28
+ return joins(:spud_post_sites).where(:spud_post_sites => {:spud_site_id => spud_site_id})
29
+ end
30
+
31
+ def self.public_posts(page, per_page)
32
+ return where('visible = ? AND published_at <= ?', true,Time.now.utc).order('published_at desc').includes(:categories).paginate(:page => page, :per_page => per_page)
33
+ end
34
+
35
+ def self.public_blog_posts(page, per_page)
36
+ return self.public_posts(page, per_page).where(:is_news => false)
37
+ end
38
+
39
+ def self.public_news_posts(page, per_page)
40
+ return self.public_posts(page, per_page).where(:is_news => true)
41
+ end
42
+
43
+ def self.recent_posts(limit=5)
44
+ return where('visible = ? AND published_at <= ?', true, Time.now.utc).order('published_at desc').limit(limit)
45
+ end
46
+
47
+ def self.recent_blog_posts(limit=5)
48
+ return self.recent_posts(limit).where(:is_news => false)
49
+ end
50
+
51
+ def self.recent_news_posts(limit=5)
52
+ return self.recent_posts(limit).where(:is_news => true)
53
+ end
54
+
55
+ def self.from_archive(date_string)
56
+ begin
57
+ date = Date.strptime(date_string, "%Y-%b")
58
+ return where(:published_at => date..date.end_of_month)
59
+ rescue
60
+ return all
61
+ end
62
+ end
63
+
64
+ #def self.posts_for_category_archive(category, )
65
+
66
+ # Returns an array of Date objects for months with public posts
67
+ def self.months_with_public_posts
68
+ # Select
69
+ # Month(published_at) as published_month,
70
+ # Year(published_at) as published_year
71
+ # From spud_posts
72
+ # Where visible = 1
73
+ # And published_at < '2012-01-30'
74
+ # Group By published_month, published_year
75
+ # Order By published_year desc, published_month desc
76
+ records = SpudPost.select('Extract(Month from published_at) as published_month, Extract(Year from published_at) as published_year').where('visible = ? AND published_at < ?', true, DateTime.now).group('published_month, published_year').order('published_year desc, published_month desc')
77
+ begin
78
+ return records.collect{ |r| Date.new(r[:published_year].to_i, r[:published_month].to_i) }
79
+ rescue Exception => e
80
+ logger.fatal "Exception occurred while fetching post archive dates:\n #{e.to_s}"
81
+ return []
82
+ end
83
+ end
84
+
85
+ def self.months_with_public_news_posts
86
+ records = SpudPost.select('Extract(Month from published_at) as published_month, Extract(Year from published_at) as published_year').where('visible = ? AND published_at < ? AND is_news = ?', true, DateTime.now, true).group('published_month, published_year').order('published_year desc, published_month desc')
87
+ begin
88
+ return records.collect{ |r| Date.new(r[:published_year].to_i, r[:published_month].to_i) }
89
+ rescue Exception => e
90
+ logger.fatal "Exception occurred while fetching post archive dates:\n #{e.to_s}"
91
+ end
92
+ end
93
+
94
+ def self.months_with_public_blog_posts
95
+ records = SpudPost.select('Extract(Month from published_at) as published_month, Extract(Year from published_at) as published_year').where('visible = ? AND published_at < ? AND is_news = ?', true, DateTime.now, false).group('published_month, published_year').order('published_year desc, published_month desc')
96
+ begin
97
+ return records.collect{ |r| Date.new(r[:published_year].to_i, r[:published_month].to_i) }
98
+ rescue Exception => e
99
+ logger.fatal "Exception occurred while fetching post archive dates:\n #{e.to_s}"
100
+ end
101
+ end
102
+
103
+ def postprocess_content
104
+ if self.content_format == 'Markdown'
105
+ require 'redcarpet'
106
+ renderer = Redcarpet::Render::HTML.new
107
+ extensions = {fenced_code_blocks: true}
108
+ redcarpet = Redcarpet::Markdown.new(renderer, extensions)
109
+ self.content_processed = redcarpet.render self.content
110
+ else
111
+ template = Liquid::Template.parse(self.content)
112
+ self.content_processed = template.render()
113
+ end
114
+ end
115
+
116
+ def content_processed
117
+ if read_attribute(:content_processed).blank?
118
+ postprocess_content
119
+ end
120
+ read_attribute(:content_processed)
121
+ end
122
+
123
+ def content_processed=(content)
124
+ write_attribute(:content_processed,content)
125
+ end
126
+
127
+ def display_date
128
+ return published_at.strftime("%b %d, %Y")
129
+ end
130
+
131
+ def is_public?
132
+ return (published_at < DateTime.now) && visible
133
+ end
134
+
135
+ def is_private?
136
+ return !is_public?
137
+ end
138
+
139
+ # Spud site ids getter
140
+ def spud_site_ids
141
+ if @spud_site_ids.nil?
142
+ @spud_site_ids = spud_post_sites.collect{ |site| site.spud_site_id }
143
+ end
144
+ return @spud_site_ids
145
+ end
146
+
147
+ # Spud site ids setter
148
+ def spud_site_ids=(site_ids)
149
+ if site_ids.is_a?(Array)
150
+ @spud_site_ids = site_ids.collect{ |id| id.to_i }
151
+ else
152
+ raise 'Site ids must be an Array'
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def set_url_name
159
+ self.url_name = "#{self.published_at.strftime('%Y-%m-%d')}-#{self.title.parameterize}"
160
+ end
161
+
162
+ def set_spud_site_ids
163
+ if Spud::Core.multisite_mode_enabled
164
+ _spud_post_sites = []
165
+ self.spud_site_ids.each do |site_id|
166
+ _spud_post_sites << SpudPostSite.new(:spud_post_id => id, :spud_site_id => site_id)
167
+ end
168
+ self.spud_post_sites = _spud_post_sites
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,5 @@
1
+ class SpudPostCategoriesPost < ActiveRecord::Base
2
+ attr_accessible :spud_post_id, :spud_post_category_id
3
+ belongs_to :spud_post
4
+ belongs_to :spud_post_category
5
+ end
@@ -0,0 +1,70 @@
1
+ class SpudPostCategory < ActiveRecord::Base
2
+ spud_searchable
3
+ acts_as_nested_set
4
+
5
+ has_and_belongs_to_many :posts,
6
+ :class_name => 'SpudPost',
7
+ :join_table => 'spud_post_categories_posts',
8
+ :foreign_key => 'spud_post_category_id'
9
+
10
+ validates_presence_of :name, :url_name
11
+ validates_uniqueness_of :name, :url_name
12
+ before_validation :set_url_name
13
+
14
+ before_destroy :update_child_categories
15
+
16
+ attr_accessible :name, :url_name, :parent_id
17
+
18
+ # tell awesome_nested_set not to destroy descendants
19
+ def skip_before_destroy
20
+ return true
21
+ end
22
+
23
+ def self.grouped
24
+ return all.group_by(&:parent_id)
25
+ end
26
+
27
+ # Returns an array of categories in order of heirarchy
28
+ # :fitler Filters out a category by ID, and all of its children
29
+ # :value Pick an attribute to be used in the value field, defaults to ID
30
+ def self.options_for_categories(config={})
31
+ collection = config[:collection] || self.grouped
32
+ level = config[:level] || 0
33
+ parent_id = config[:parent_id] || nil
34
+ filter = config[:filter] || nil
35
+ value = config[:value] || :id
36
+ list = []
37
+ if collection[parent_id]
38
+ collection[parent_id].each do |c|
39
+ if c.id != filter
40
+ list << [level.times.collect{ '- ' }.join('') + c.name, c[value]]
41
+ list += self.options_for_categories({:collection => collection, :parent_id => c.id, :level => level+1, :filter => filter, :value => value})
42
+ end
43
+ end
44
+ end
45
+ return list
46
+ end
47
+
48
+ def posts_with_children
49
+ category_ids = self.self_and_ancestors.collect{ |category| category.id }
50
+ post_ids = SpudPostCategoriesPost.where(:spud_post_category_id => category_ids).collect{ |it| it.spud_post_id }
51
+ return SpudPost.where(:id => post_ids)
52
+ end
53
+
54
+ private
55
+
56
+ def set_url_name
57
+ self.url_name = self.name.parameterize
58
+ end
59
+
60
+ def parent_is_valid
61
+ if parent_id == self.id
62
+ errors.add :base, 'Category cannot be its own parent'
63
+ end
64
+ end
65
+
66
+ def update_child_categories
67
+ self.children.update_all(:parent_id => self.parent_id)
68
+ self.class.rebuild!
69
+ end
70
+ end
@@ -0,0 +1,41 @@
1
+ class SpudPostCategorySweeper < ActionController::Caching::Sweeper
2
+
3
+ observe SpudPostCategory
4
+
5
+ def after_save(record)
6
+ expire_cache_for(record)
7
+ end
8
+
9
+ def after_destroy(record)
10
+ expire_cache_for(record)
11
+ end
12
+
13
+ private
14
+
15
+ def expire_cache_for(record)
16
+ if Spud::Blog.config.cache_mode = :action
17
+ SpudPost.find_each do |p|
18
+ if p.is_news && Spud::Blog.config.news_enabled
19
+ expire_action news_post_url(p.url_name)
20
+ elsif Spud::Blog.config.blog_enabled
21
+ expire_action blog_post_url(p.url_name)
22
+ end
23
+ end
24
+ expire_action news_url if Spud::Blog.config.news_enabled
25
+ expire_action blog_url if Spud::Blog.config.blog_enabled
26
+ expire_action spud_blog_sitemap_url
27
+ end
28
+ if Spud::Blog.config.cache_mode = :full_page
29
+ SpudPost.find_each do |p|
30
+ if p.is_news && Spud::Blog.config.news_enabled
31
+ expire_page news_post_path(p.url_name)
32
+ elsif Spud::Blog.config.blog_enabled
33
+ expire_page blog_post_path(p.url_name)
34
+ end
35
+ end
36
+ expire_page news_path if Spud::Blog.config.news_enabled
37
+ expire_page blog_path if Spud::Blog.config.blog_enabled
38
+ expire_page spud_blog_sitemap_path(:format => :xml)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ class SpudPostComment < ActiveRecord::Base
2
+ if Spud::Blog.enable_rakismet
3
+ include Rakismet::Model
4
+ before_save :rakismet_check_for_spam
5
+ end
6
+
7
+
8
+ validates_presence_of :author, :content
9
+ belongs_to :post, :class_name => 'SpudPost', :foreign_key => 'spud_post_id', :counter_cache => :comments_count
10
+
11
+ attr_accessible :author,:content,:spud_post_id,:referrer,:spam,:user_agent,:user_ip,:permalink
12
+
13
+
14
+ def rakismet_check_for_spam
15
+ self.spam = self.spam?
16
+ return true
17
+ end
18
+
19
+ end
@@ -0,0 +1,33 @@
1
+ class SpudPostCommentSweeper < ActionController::Caching::Sweeper
2
+
3
+ observe SpudPostComment
4
+
5
+ def after_save(record)
6
+ expire_cache_for(record)
7
+ end
8
+
9
+ def after_destroy(record)
10
+ expire_cache_for(record)
11
+ end
12
+
13
+ private
14
+
15
+ def expire_cache_for(record)
16
+ unless record.post.nil?
17
+ if Spud::Blog.config.cache_mode == :action
18
+ if record.post.is_news
19
+ expire_action news_post_url(record.post.url_name)
20
+ else
21
+ expire_action blog_post_url(record.post.url_name)
22
+ end
23
+ end
24
+ if Spud::Blog.config.cache_mode == :full_page
25
+ if record.post.is_news
26
+ expire_page news_post_path(record.post.url_name)
27
+ else
28
+ expire_page blog_post_path(record.post.url_name)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,9 @@
1
+ class SpudPostSite < ActiveRecord::Base
2
+ attr_accessible :spud_post_id, :spud_site_id
3
+ belongs_to :spud_post
4
+
5
+ def spud_site
6
+ return Spud::Core.site_config_for_id(spud_site_id)
7
+ end
8
+
9
+ end
@@ -0,0 +1,47 @@
1
+ class SpudPostSweeper < ActionController::Caching::Sweeper
2
+
3
+ observe SpudPost
4
+
5
+ def after_create(record)
6
+ expire_cache_for(record)
7
+ end
8
+
9
+ def before_update(record)
10
+ expire_cache_for(record)
11
+ end
12
+
13
+ def after_destroy(record)
14
+ expire_cache_for(record)
15
+ end
16
+
17
+ private
18
+
19
+ def expire_cache_for(record)
20
+ if Spud::Blog.config.cache_mode == :action
21
+ expire_action spud_blog_sitemap_url
22
+ if !record.is_news && Spud::Blog.config.blog_enabled
23
+ expire_action blog_url
24
+ expire_action blog_url(:format => :rss)
25
+ expire_action blog_post_url(record.url_name)
26
+ elsif Spud::Blog.config.news_enabled
27
+ expire_action news_url
28
+ expire_action news_url(:format => :rss)
29
+ expire_action news_post_url(record.url_name)
30
+ end
31
+ end
32
+ if Spud::Blog.config.cache_mode == :full_page
33
+ expire_page spud_blog_sitemap_path(:format => :xml)
34
+ if record.is_news && Spud::Blog.config.news_enabled
35
+ expire_page news_path
36
+ expire_page news_path(:format => :rss)
37
+ expire_page news_post_path(record.url_name)
38
+ elsif Spud::Blog.config.blog_enabled
39
+ expire_page blog_path
40
+ expire_page blog_path(:format => :rss)
41
+ expire_page blog_post_path(record.url_name)
42
+ end
43
+ end
44
+ # expire_page spud_sitemap_path(:format => :xml)
45
+ end
46
+
47
+ end
@@ -0,0 +1,4 @@
1
+ <li>
2
+ <h6>Posted by: <%= comment.author %></h6>
3
+ <p><%= comment.content %></p>
4
+ </li>
@@ -0,0 +1,20 @@
1
+ <%= form_for @comment, :url => blog_post_path(@post) do |f| %>
2
+ <div>
3
+ <%= f.label :author %>
4
+ <%= f.text_field :author %>
5
+ </div>
6
+ <div>
7
+ <%= f.label :content %>
8
+ <%= f.text_area :content %>
9
+ </div>
10
+ <div class="comment_validity">
11
+ <%= label_tag 'Comment Validation' %>
12
+ <%= text_field_tag 'comment_validation' %>
13
+ </div>
14
+ <div>
15
+ <%= f.submit 'Post Comment' %>
16
+ </div>
17
+
18
+ <% end %>
19
+ <%= stylesheet_link_tag "spud/blog/validity.css", :media => "all" %>
20
+
@@ -0,0 +1,35 @@
1
+ <% content_for :title do %>
2
+ Blog | <%=current_site_name%>
3
+ <% end %>
4
+
5
+ <% content_for :head do %>
6
+ <%= spud_blog_rss_link %>
7
+ <% end %>
8
+
9
+ <div id="spud_blog_filters">
10
+ <%= form_tag blog_path, :class => 'spud_blog_filter_form' do %>
11
+ <label>Category:</label>
12
+ <%= spud_post_category_select %>
13
+ <label>Month:</label>
14
+ <%= spud_post_archive_select %>
15
+ <input type="submit" value="Submit" />
16
+ <% end %>
17
+ </div>
18
+
19
+ <div id="spud_blog_posts">
20
+ <% if @posts.any? %>
21
+ <% @posts.each do |post| %>
22
+ <div class="spud_blog_post">
23
+ <h3><%= link_to post.title, blog_post_path(post.url_name) %></h3>
24
+ <h4>Posted by <%= post.author.full_name %> on <%= post.display_date %></h4>
25
+ <div class="spud_blog_post_content">
26
+ <%= truncate_html post.content_processed.html_safe, :length => 250 %>
27
+ </div>
28
+ </div>
29
+ <% end %>
30
+ <% else %>
31
+ <p>No posts were found in this category</p>
32
+ <% end %>
33
+ </div>
34
+
35
+ <%= will_paginate @posts %>
@@ -0,0 +1,18 @@
1
+ xml.instruct! :xml, :version => "1.0"
2
+ xml.rss :version => "2.0" do
3
+ xml.channel do
4
+ xml.title "#{Spud::Core.site_name} Blog Articles"
5
+ xml.description "Blog articles for #{Spud::Core.site_name}"
6
+ xml.link blog_url(:format => :rss)
7
+
8
+ for article in @posts
9
+ xml.item do
10
+ xml.title article.title
11
+ xml.description article.content_processed
12
+ xml.pubDate article.created_at.to_s(:rfc822)
13
+ xml.link blog_post_url(article.url_name)
14
+ xml.guid blog_post_url(article.url_name)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ <% content_for :title do %>
2
+ <%= @post.title %> | <%=current_site_name%>
3
+ <% end %>
4
+
5
+ <% content_for :head do %>
6
+ <%= spud_blog_rss_link %>
7
+ <meta name="description" content="<%= @post.meta_description %>" />
8
+ <% if @post.meta_keywords.blank? %>
9
+ <meta name="keywords" content="<%= @post.categories.collect{ |c| c.name }.join(',') %>" />
10
+ <% else %>
11
+ <meta name="keywords" content="<%= @post.meta_keywords %>" />
12
+ <% end %>
13
+ <% end %>
14
+
15
+ <div class="spud_blog_post">
16
+ <h3><%= @post.title %></h3>
17
+ <h4>Posted by <%= @post.author.full_name %> on <%= @post.display_date %></h4>
18
+ <% if @post.categories.any? %>
19
+ <p id="spud_blog_post_categories">
20
+ Filed under
21
+ <%= raw(@post.categories.collect{ |c| link_to c.name, blog_category_path(c.url_name) }.join(', ')) %>
22
+ </p>
23
+ <% end %>
24
+ <div id="spud_blog_post_content">
25
+ <%= raw @post.content_processed %>
26
+ </div>
27
+ </div>
28
+
29
+ <% if @post.comments_enabled %>
30
+ <div class="spud_blog_post_comment">
31
+ <h5>Post a Comment:</h5>
32
+ <%= render 'comment_form' %>
33
+ </div>
34
+ <ul id="spud_blog_post_comments">
35
+ <%= render :partial => 'comment', :collection => @post.visible_comments %>
36
+ </ul>
37
+ <% end %>
@@ -0,0 +1,35 @@
1
+ <% content_for :title do %>
2
+ News | <%=current_site_name%>
3
+ <% end %>
4
+
5
+ <% content_for :head do %>
6
+ <%= spud_news_rss_link %>
7
+ <% end %>
8
+
9
+ <div id="spud_news_filters">
10
+ <%= form_tag news_path, :class => 'spud_blog_filter_form' do %>
11
+ <label>Category:</label>
12
+ <%= spud_post_category_select %>
13
+ <label>Month:</label>
14
+ <%= spud_post_archive_select %>
15
+ <input type="submit" value="Submit" />
16
+ <% end %>
17
+ </div>
18
+
19
+ <div id="spud_news_posts">
20
+ <% if @posts.any? %>
21
+ <% @posts.each do |post| %>
22
+ <div class="spud_news_post">
23
+ <h3><%= link_to post.title, news_post_path(post.url_name) %></h3>
24
+ <h4>Posted by <%= post.author.full_name %> on <%= post.display_date %></h4>
25
+ <div class="spud_news_post_content">
26
+ <%= truncate_html post.content.html_safe, :length => 250 %>
27
+ </div>
28
+ </div>
29
+ <% end %>
30
+ <% else %>
31
+ <p>No posts were found in this category</p>
32
+ <% end %>
33
+ </div>
34
+
35
+ <%= will_paginate @posts %>
@@ -0,0 +1,18 @@
1
+ xml.instruct! :xml, :version => "1.0"
2
+ xml.rss :version => "2.0" do
3
+ xml.channel do
4
+ xml.title "#{Spud::Core.site_name} News"
5
+ xml.description "News articles for #{Spud::Core.site_name}"
6
+ xml.link news_url(:format => :rss)
7
+
8
+ for article in @posts
9
+ xml.item do
10
+ xml.title article.title
11
+ xml.description article.content
12
+ xml.pubDate article.created_at.to_s(:rfc822)
13
+ xml.link news_post_url(article.url_name)
14
+ xml.guid news_post_url(article.url_name)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ <% content_for :title do %>
2
+ <%= @post.title %> | <%=current_site_name%>
3
+ <% end %>
4
+
5
+ <% content_for :head do %>
6
+ <%= spud_news_rss_link %>
7
+ <meta name="description" content="<%= @post.meta_description %>" />
8
+ <% if @post.meta_keywords.blank? %>
9
+ <meta name="keywords" content="<%= @post.categories.collect{ |c| c.name }.join(',') %>" />
10
+ <% else %>
11
+ <meta name="keywords" content="<%= @post.meta_keywords %>" />
12
+ <% end %>
13
+ <% end %>
14
+
15
+ <div class="spud_news_post">
16
+ <h3><%= @post.title %></h3>
17
+ <h4>Posted by <%= @post.author.full_name %> on <%= @post.display_date %></h4>
18
+ <% if @post.categories.any? %>
19
+ <p id="spud_news_post_categories">
20
+ Filed under
21
+ <%= raw(@post.categories.collect{ |c| link_to c.name, news_category_path(c.url_name) }.join(', ')) %>
22
+ </p>
23
+ <% end %>
24
+ <div id="spud_news_post_content">
25
+ <%= raw @post.content %>
26
+ </div>
27
+ </div>
@@ -0,0 +1,3 @@
1
+ <%= form_for @post, :url => spud_admin_news_post_path(@post), :html => {:class => 'form-horizontal'} do |f| %>
2
+ <%= render :partial => '/spud/admin/posts/form', :locals => {:f => f} %>
3
+ <% end %>
@@ -0,0 +1,44 @@
1
+ <%= content_for :data_controls do %>
2
+ <%= link_to "Manage Categories", spud_admin_post_categories_path, :class => 'btn spud_blog_manage_categories', :title => 'Manage Categories' %>
3
+ <%= link_to "New Post", new_spud_admin_news_post_path, :class => "btn btn-primary", :title => "New Post" %>
4
+ <% end %>
5
+
6
+ <%=content_for :detail do %>
7
+ <table class="admin-table">
8
+ <thead>
9
+ <tr>
10
+ <th>Title</th>
11
+ <th>Author</th>
12
+ <th>Published At</th>
13
+ <th>&nbsp;</th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @posts.each do |post| %>
18
+ <tr>
19
+
20
+ <td>
21
+ <%= link_to edit_spud_admin_news_post_path(post) do %>
22
+ <%=post.title%>
23
+ <%if !post.visible%>
24
+ <span class="badge">Draft</span>
25
+ <%end%>
26
+ <%end%>
27
+ </td>
28
+ <td><%= post.author.full_name %></td>
29
+ <td><%= link_to(post.published_at.strftime('%m/%d/%Y'), news_post_path(post.url_name)) %></td>
30
+ <td align="right">
31
+ <%= link_to 'Delete', spud_admin_news_post_path(post), :method => :delete, :confirm => 'Are you sure you want to delete this post?', :class => 'btn btn-small btn-danger' %>
32
+ </td>
33
+ </tr>
34
+ <%end%>
35
+ </tbody>
36
+ </table>
37
+ <div class="spud_admin_pagination">
38
+ <%= will_paginate @posts %>
39
+ </div>
40
+
41
+ <script>
42
+ $(document).ready(spud.admin.post_categories.index);
43
+ </script>
44
+ <%end%>
@@ -0,0 +1,3 @@
1
+ <%= form_for @post, :url => spud_admin_news_posts_path do |f| %>
2
+ <%= render :partial => '/spud/admin/posts/form', :locals => {:f => f} %>
3
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <%= content_tag :li, :class => 'spud_blog_category_manager_item', 'data-id' => category.id do %>
2
+ <span class="spud_blog_category_manager_item_name">
3
+ <%= category.name %>
4
+ </span>
5
+ <span class="spud_blog_category_manager_item_actions">
6
+ <%= link_to 'Edit', edit_spud_admin_post_category_path(category), :class => 'btn btn-mini spud_blog_category_edit' %>
7
+ <%= link_to 'Delete', spud_admin_post_category_path(category), :class => 'btn btn-mini btn-danger spud_blog_category_delete' %>
8
+ </span>
9
+ <ul class="spud_blog_category_manager_item_children">
10
+ <% if @post_categories[category.id] %>
11
+ <%= render :partial => 'category', :collection => @post_categories[category.id] %>
12
+ <% end %>
13
+ </ul>
14
+ <% end %>