spud_blog 0.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 (40) hide show
  1. data/app/assets/javascripts/spud/admin/post_categories.js +2 -0
  2. data/app/assets/javascripts/spud/admin/post_comments.js +2 -0
  3. data/app/assets/javascripts/spud/admin/posts.js +29 -0
  4. data/app/assets/stylesheets/spud/admin/post_categories.css +4 -0
  5. data/app/assets/stylesheets/spud/admin/post_comments.css +4 -0
  6. data/app/assets/stylesheets/spud/admin/posts.css +49 -0
  7. data/app/controllers/blog_controller.rb +65 -0
  8. data/app/controllers/spud/admin/post_categories_controller.rb +46 -0
  9. data/app/controllers/spud/admin/post_comments_controller.rb +41 -0
  10. data/app/controllers/spud/admin/posts_controller.rb +54 -0
  11. data/app/helpers/blog_helper.rb +14 -0
  12. data/app/helpers/spud/admin/post_categories_helper.rb +2 -0
  13. data/app/helpers/spud/admin/post_comments_helper.rb +2 -0
  14. data/app/helpers/spud/admin/posts_helper.rb +15 -0
  15. data/app/models/spud_post.rb +62 -0
  16. data/app/models/spud_post_category.rb +58 -0
  17. data/app/models/spud_post_comment.rb +5 -0
  18. data/app/views/blog/_comment.html.erb +4 -0
  19. data/app/views/blog/_comment_form.html.erb +17 -0
  20. data/app/views/blog/index.html.erb +33 -0
  21. data/app/views/blog/show.html.erb +23 -0
  22. data/app/views/layouts/spud/admin/post.html.erb +7 -0
  23. data/app/views/spud/admin/post_categories/_form.html.erb +39 -0
  24. data/app/views/spud/admin/post_categories/edit.html.erb +1 -0
  25. data/app/views/spud/admin/post_categories/index.html.erb +29 -0
  26. data/app/views/spud/admin/post_categories/new.html.erb +1 -0
  27. data/app/views/spud/admin/post_categories/show.html.erb +0 -0
  28. data/app/views/spud/admin/posts/_category.html.erb +9 -0
  29. data/app/views/spud/admin/posts/_form.html.erb +60 -0
  30. data/app/views/spud/admin/posts/edit.html.erb +1 -0
  31. data/app/views/spud/admin/posts/index.html.erb +33 -0
  32. data/app/views/spud/admin/posts/new.html.erb +1 -0
  33. data/app/views/spud/admin/posts/show.html.erb +0 -0
  34. data/config/application.rb +48 -0
  35. data/config/boot.rb +6 -0
  36. data/config/routes.rb +27 -0
  37. data/lib/spud_blog/configuration.rb +8 -0
  38. data/lib/spud_blog/engine.rb +29 -0
  39. data/lib/spud_blog.rb +6 -0
  40. metadata +105 -0
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,29 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
3
+
4
+ Spud = (typeof(Spud) == 'undefined') ? {} : Spud;
5
+ Spud.Admin = (typeof(Spud.Admin) == 'undefined') ? {} : Spud.Admin;
6
+
7
+ Spud.Admin.Posts = new function(){
8
+
9
+ var self = this;
10
+
11
+ this.edit = function(){
12
+ $('input[type=submit],.close_dialog').button();
13
+ initDatePicker();
14
+ initWysiwym();
15
+ $('#spud_post_new_category_form button').live('click', self.didSubmitCategory);
16
+ };
17
+
18
+ this.didSubmitCategory = function(event){
19
+ $.ajax({
20
+ url: $('#spud_post_new_category_path').val(),
21
+ type: 'post',
22
+ dataType: 'json',
23
+ data: {
24
+ 'spud_post_category[name]': $('#spud_post_new_category_name').val(),
25
+ 'spud_post_category[parent_id]': $('#spud_post_new_category_parent_id').val()
26
+ }
27
+ });
28
+ };
29
+ };
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,49 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
5
+
6
+ #spud_post_categories_form{
7
+ list-style-type: none;
8
+ margin: 15px 0 15px 20px;
9
+ padding: 0 0 0 20px;
10
+ height: 200px;
11
+ width: 400px;
12
+ background: white;
13
+ border: 1px solid #ccc;
14
+ padding: 10px;
15
+ overflow: scroll;
16
+ }
17
+ #spud_post_categories_form ul{
18
+ list-style-type: none;
19
+ margin: 3px 0;
20
+ padding: 0 0 0 20px;
21
+ }
22
+ #spud_post_categories_form label{
23
+ float: none;
24
+ text-align: left;
25
+ }
26
+ #spud_post_new_category_form{
27
+ background: white;
28
+ border: 1px solid #ccc;
29
+ margin: 15px 0 15px 20px;
30
+ padding: 10px 20px;
31
+ overflow: hidden;
32
+ width: 380 px;
33
+ }
34
+ #spud_post_new_category_form h5{
35
+ margin: 0 0 5px;
36
+ }
37
+ #spud_post_new_category_form div{
38
+ margin: 5px 0;
39
+ }
40
+ #spud_post_new_category_form label{
41
+ float: none;
42
+ margin: 0 1px 0 0;
43
+ font-size: 12px;
44
+ display: inline-block;
45
+ width: 50px;
46
+ }
47
+ #spud_post_new_category_form input[type=button]{
48
+ margin-left: 55px;
49
+ }
@@ -0,0 +1,65 @@
1
+ class BlogController < ApplicationController
2
+
3
+ respond_to :html, :xml, :json
4
+ before_filter :find_post, :only => [:show, :create_comment]
5
+ layout Spud::Blog.default_layout
6
+
7
+ def index
8
+ @posts = SpudPost.for_frontend(params[:page], params[:per_page])
9
+ respond_with @posts
10
+ end
11
+
12
+ def category
13
+ @post_category = SpudPostCategory.find_by_url_name(params[:category_url_name])
14
+ if @post_category.nil?
15
+ redirect_to blog_path
16
+ else
17
+ if request.post?
18
+ redirect_to blog_category_path(params[:category_url_name])
19
+ else
20
+ @posts = @post_category.posts.for_frontend(params[:page], params[:per_page])
21
+ respond_with @posts do |format|
22
+ format.html { render 'index' }
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def archive
29
+ if request.post?
30
+ redirect_to blog_archive_path(params[:blog_archive])
31
+ else
32
+ @posts = SpudPost.from_archive(params[:blog_archive]).for_frontend(params[:page], params[:per_page])
33
+ respond_with @posts do |format|
34
+ format.html { render 'index' }
35
+ end
36
+ end
37
+ end
38
+
39
+ def show
40
+ if @post.comments_enabled
41
+ @comment = SpudPostComment.new(:spud_post_id => params[:id])
42
+ end
43
+ respond_with @post
44
+ end
45
+
46
+ def create_comment
47
+ return unless params[:comment_validation].empty? # trap spam bots
48
+ @comment = @post.comments.new(params[:spud_post_comment])
49
+ flash[:notice] = 'Your comment has been posted, however it will not appear until it is approved.' if @comment.save
50
+ respond_with @comment do |format|
51
+ format.html { redirect_to blog_post_path(@post, :anchor => 'spud_post_comment_form') }
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def find_post
58
+ @post = SpudPost.find_by_url_name(params[:id])
59
+ if @post.blank? || @post.is_private?
60
+ flash[:error] = "Post not found!"
61
+ redirect_to blog_path and return false
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,46 @@
1
+ class Spud::Admin::PostCategoriesController < Spud::Admin::ApplicationController
2
+
3
+ layout 'spud/admin/post'
4
+ respond_to :html, :xml, :json
5
+ before_filter :find_category, :only => [:show, :edit, :update, :destroy]
6
+ add_breadcrumb 'Post Categories', :spud_admin_post_categories_path
7
+
8
+ belongs_to_spud_app :post_categories
9
+
10
+ def index
11
+ @post_categories = SpudPostCategory.order('name asc').includes(:posts).paginate(:page => params[:page], :per_page => 15)
12
+ respond_with @post_categories
13
+ end
14
+
15
+ def edit
16
+ respond_with @post_category
17
+ end
18
+
19
+ def update
20
+ flash[:notice] = 'Post Category was successfully updated' if @post_category.update_attributes(params[:spud_post_category])
21
+ respond_with @post_category, :location => spud_admin_post_categories_path
22
+ end
23
+
24
+ def new
25
+ @post_category = SpudPostCategory.new
26
+ respond_with @post_category
27
+ end
28
+
29
+ def create
30
+ @post_category = SpudPostCategory.new(params[:spud_post_category])
31
+ flash[:notice] = 'Post Category was successfully created' if @post_category.save
32
+ respond_with @post_category, :location => spud_admin_post_categories_path
33
+ end
34
+
35
+ def destroy
36
+ flash[:notice] = 'Post Category was successfully deleted' if @post_category.destroy
37
+ respond_with @post_category, :location => spud_admin_post_categories_path
38
+ end
39
+
40
+ private
41
+
42
+ def find_category
43
+ @post_category = SpudPostCategory.find(params[:id])
44
+ end
45
+
46
+ end
@@ -0,0 +1,41 @@
1
+ class Spud::Admin::PostCommentsController < Spud::Admin::ApplicationController
2
+
3
+ respond_to :html, :xml, :json
4
+ before_filter :find_comment, :only => [:show, :edit, :update, :destroy]
5
+
6
+ def index
7
+ if params[:post_id]
8
+ @post_comments = SpudPost.find(params[:post_id]).comments
9
+ else
10
+ @post_comments = SpudPost.all
11
+ end
12
+ respond_with @post_comments
13
+ end
14
+
15
+ def show
16
+ respond_with @post_comment
17
+ end
18
+
19
+ def edit
20
+ respond_with @post_comment
21
+ end
22
+
23
+ def update
24
+
25
+ end
26
+
27
+ def create
28
+
29
+ end
30
+
31
+ def destroy
32
+
33
+ end
34
+
35
+ private
36
+
37
+ def find_comment
38
+ @post_comment = SpudPostComment.find(params[:id])
39
+ end
40
+
41
+ end
@@ -0,0 +1,54 @@
1
+ class Spud::Admin::PostsController < Spud::Admin::ApplicationController
2
+
3
+ layout 'spud/admin/post'
4
+ respond_to :html, :xml, :json
5
+ before_filter :find_post, :only => [:show, :edit, :update, :destroy]
6
+ add_breadcrumb 'Posts', :spud_admin_posts_path
7
+
8
+ belongs_to_spud_app :posts
9
+
10
+ def index
11
+ @posts = SpudPost.order('published_at desc').includes(:comments).paginate(:page => params[:page], :per_page => 15)
12
+ respond_with @posts
13
+ end
14
+
15
+ def edit
16
+ @categories = SpudPostCategory.grouped
17
+ respond_with @post
18
+ end
19
+
20
+ def update
21
+ @categories = SpudPostCategory.grouped
22
+ flash[:notice] = 'Post was successfully updated.' if @post.update_attributes(params[:spud_post])
23
+ respond_with @post, :location => spud_admin_posts_path
24
+ end
25
+
26
+ def new
27
+ @categories = SpudPostCategory.grouped
28
+ @post = SpudPost.new(:published_at => Date.today, :spud_user_id => current_user.id)
29
+ respond_with @post
30
+ end
31
+
32
+ def create
33
+ @categories = SpudPostCategory.grouped
34
+ @post = SpudPost.new(params[:spud_post])
35
+ flash[:notice] = 'Post was successfully created.' if @post.save
36
+ respond_with @post, :location => spud_admin_posts_path
37
+ end
38
+
39
+ def destroy
40
+ flash[:notice] = 'Post was successfully deleted.' if @post.destroy
41
+ respond_with @post, :location => spud_admin_posts_path
42
+ end
43
+
44
+ private
45
+
46
+ def find_post
47
+ @post = SpudPost.find(params[:id])
48
+ if @post.blank?
49
+ flash[:error] = "Post not found!"
50
+ redirect_to spud_admin_posts_path and return false
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,14 @@
1
+ module BlogHelper
2
+
3
+ def spud_blog_category_select
4
+ select_tag 'category_url_name', options_for_select(SpudPostCategory.options_for_categories(:value => :url_name), params[:category_url_name]), :include_blank => true
5
+ end
6
+
7
+ def spud_blog_archive_select
8
+ dates = SpudPost.months_with_public_posts
9
+ return select_tag 'blog_archive', options_for_select(SpudPost.months_with_public_posts.collect{ |d|
10
+ [d.strftime('%B %Y'), d.strftime('%Y-%b').downcase]
11
+ }, params[:blog_archive]), :include_blank => true
12
+ end
13
+
14
+ end
@@ -0,0 +1,2 @@
1
+ module Spud::Admin::PostCategoriesHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ module Spud::Admin::PostCommentsHelper
2
+ end
@@ -0,0 +1,15 @@
1
+ module Spud::Admin::PostsHelper
2
+
3
+ def options_for_parent_category(parent_id = 0)
4
+ if @categories[parent_id]
5
+ return @categories[parent_id].collect{ |c|
6
+ opts = [c.name, c.id]
7
+ opts += options_for_parent_category(c.id)
8
+ }
9
+ else
10
+ return []
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,62 @@
1
+ class SpudPost < ActiveRecord::Base
2
+
3
+ has_and_belongs_to_many :categories,
4
+ :class_name => 'SpudPostCategory',
5
+ :join_table => 'spud_post_categories_posts',
6
+ :foreign_key => 'spud_post_id'
7
+ belongs_to :author, :class_name => 'SpudUser', :foreign_key => 'spud_user_id'
8
+ has_many :comments, :class_name => 'SpudPostComment'
9
+
10
+ validates_presence_of :title, :content, :published_at, :spud_user_id, :url_name
11
+ validates_uniqueness_of :url_name
12
+ before_validation :set_url_name
13
+
14
+ def self.for_frontend(page, per_page)
15
+ return where('visible = 1 AND published_at <= ?', DateTime.now).order('published_at desc').includes(:comments, :categories).paginate(:page => page, :per_page => per_page)
16
+ end
17
+
18
+ def self.from_archive(date_string)
19
+ begin
20
+ date = Date.strptime(date_string, "%Y-%b")
21
+ return where(:published_at => date..date.end_of_month)
22
+ rescue
23
+ return all
24
+ end
25
+ end
26
+
27
+ def self.recent_posts(limit=5)
28
+ return where('visible = 1 AND published_at <= ?', DateTime.now).order('published_at desc').limit(limit)
29
+ end
30
+
31
+ # Returns an array of Date objects for months with public posts
32
+ def self.months_with_public_posts
33
+ # Select
34
+ # Month(published_at) as published_month,
35
+ # Year(published_at) as published_year
36
+ # From spud_posts
37
+ # Where visible = 1
38
+ # And published_at < '2012-01-30'
39
+ # Group By published_month, published_year
40
+ # Order By published_year desc, published_month desc
41
+ records = select('Month(published_at) as published_month, Year(published_at) as published_year').where('visible = 1 And published_at < ?', DateTime.now).group('published_month, published_year').order('published_year desc, published_month desc')
42
+ return records.collect{ |r| Date.new(r[:published_year], r[:published_month]) }
43
+ end
44
+
45
+ def display_date
46
+ return published_at.strftime("%b %d, %Y")
47
+ end
48
+
49
+ def is_public?
50
+ return (published_at < DateTime.now) && visible
51
+ end
52
+
53
+ def is_private?
54
+ return !is_public?
55
+ end
56
+
57
+ private
58
+
59
+ def set_url_name
60
+ self.url_name = "#{self.published_at.strftime('%Y-%m-%d')}-#{self.title.parameterize}"
61
+ end
62
+ end
@@ -0,0 +1,58 @@
1
+ class SpudPostCategory < ActiveRecord::Base
2
+
3
+ has_and_belongs_to_many :posts,
4
+ :class_name => 'SpudPost',
5
+ :join_table => 'spud_post_categories_posts',
6
+ :foreign_key => 'spud_post_category_id'
7
+ has_many :children, :class_name => 'SpudPostCategory', :foreign_key => 'parent_id'
8
+
9
+ validates_presence_of :name, :url_name
10
+ validates_uniqueness_of :name, :url_name
11
+ validate :parent_is_valid
12
+ before_validation :set_url_name
13
+
14
+ before_destroy :update_child_categories
15
+
16
+ scope :top_level, where(:parent_id => 0).order('name asc')
17
+
18
+ def self.grouped
19
+ return all.group_by(&:parent_id)
20
+ end
21
+
22
+ # Returns an array of categories in order of heirarchy
23
+ # :fitler Filters out a category by ID, and all of its children
24
+ # :value Pick an attribute to be used in the value field, defaults to ID
25
+ def self.options_for_categories(config={})
26
+ collection = config[:collection] || self.grouped
27
+ level = config[:level] || 0
28
+ parent_id = config[:parent_id] || 0
29
+ filter = config[:filter] || nil
30
+ value = config[:value] || :id
31
+ list = []
32
+ if collection[parent_id]
33
+ collection[parent_id].each do |c|
34
+ if c.id != filter
35
+ list << [level.times.collect{ '- ' }.join('') + c.name, c[value]]
36
+ list += self.options_for_categories({:collection => collection, :parent_id => c.id, :level => level+1, :filter => filter})
37
+ end
38
+ end
39
+ end
40
+ return list
41
+ end
42
+
43
+ private
44
+
45
+ def set_url_name
46
+ self.url_name = self.name.parameterize
47
+ end
48
+
49
+ def parent_is_valid
50
+ if parent_id == self.id
51
+ errors.add :base, 'Category cannot be its own parent'
52
+ end
53
+ end
54
+
55
+ def update_child_categories
56
+ self.children.update_all(:parent_id => self.parent_id)
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ class SpudPostComment < ActiveRecord::Base
2
+
3
+ validates_presence_of :author, :content
4
+
5
+ end
@@ -0,0 +1,4 @@
1
+ <li>
2
+ <h6>Posted by: <%= comment.author %></h6>
3
+ <p><%= comment.content %></p>
4
+ </li>
@@ -0,0 +1,17 @@
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 style="display:none;">
11
+ <%= label_tag 'Comment Validation' %>
12
+ <%= text_field_tag 'comment_validation' %>
13
+ </div>
14
+ <div>
15
+ <%= f.submit 'Post Comment' %>
16
+ </div>
17
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <div id="spud_blog_categories">
2
+ <%= form_tag '/blog/category' do %>
3
+ <label>Filter By Category:</label>
4
+ <%= spud_blog_category_select %>
5
+ <input type="submit" value="Submit" />
6
+ <% end %>
7
+ </div>
8
+
9
+ <div id="spud_blog_archive">
10
+ <%= form_tag '/blog/archive' do %>
11
+ <label>Filter By Month:</label>
12
+ <%= spud_blog_archive_select %>
13
+ <input type="submit" value="Submit" />
14
+ <% end %>
15
+ </div>
16
+
17
+ <div id="spud_blog_posts">
18
+ <% if @posts.any? %>
19
+ <% @posts.each do |post| %>
20
+ <div class="spud_blog_post">
21
+ <h3><%= link_to post.title, blog_post_path(post.url_name) %></h3>
22
+ <h4>Posted by <%= post.author.full_name %> on <%= post.display_date %></h4>
23
+ <div class="spud_blog_post_content">
24
+ <%= raw post.content %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+ <% else %>
29
+ <p>No posts were found in this category</p>
30
+ <% end %>
31
+ </div>
32
+
33
+ <%= will_paginate @posts %>
@@ -0,0 +1,23 @@
1
+ <div class="spud_blog_post">
2
+ <h3><%= @post.title %></h3>
3
+ <h4>Posted by <%= @post.author.full_name %> on <%= @post.display_date %></h4>
4
+ <% if @post.categories.any? %>
5
+ <p id="spud_blog_post_categories">
6
+ Filed under
7
+ <%= raw(@post.categories.collect{ |c| link_to c.name, blog_category_path(c.url_name) }.join(', ')) %>
8
+ </p>
9
+ <% end %>
10
+ <div id="spud_blog_post_content">
11
+ <%= raw @post.content %>
12
+ </div>
13
+ </div>
14
+
15
+ <% if @post.comments_enabled %>
16
+ <div class="spud_blog_post_comment">
17
+ <h5>Post a Comment:</h5>
18
+ <%= render 'comment_form' %>
19
+ </div>
20
+ <ul id="spud_blog_post_comments">
21
+ <%= render :partial => 'comment', :collection => @post.comments %>
22
+ </ul>
23
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <%=content_for :head do %>
2
+
3
+ <%= javascript_include_tag "wymeditor/jquery.wymeditor.min" %>
4
+ <%= javascript_include_tag "spud/admin/posts" %>
5
+ <%= stylesheet_link_tag 'spud/admin/posts' %>
6
+ <% end %>
7
+ <%= render :template => 'layouts/spud/admin/detail' %>
@@ -0,0 +1,39 @@
1
+ <%= form_for @post_category, :url => spud_admin_post_category_path(@post_category), :html => {:class => 'right_aligned_form'} do |f| %>
2
+
3
+ <% if @post_category.errors.any? %>
4
+ <div class="spud_admin_form_error_list">
5
+ <h4><%= pluralize(@post_category.errors.count, "error") %> prohibited you from saving this post:</h4>
6
+ <ul>
7
+ <% @post_category.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <fieldset>
15
+ <legend>Post Category</legend>
16
+ <ol>
17
+ <li>
18
+ <%= f.label :name %>
19
+ <%= f.text_field :name %>
20
+ </li>
21
+ <li>
22
+ <%= label_tag 'Parent' %>
23
+ <select name="spud_post_category[parent_id]">
24
+ <option value="0">No Parent</option>
25
+ <%= options_for_select(SpudPostCategory.options_for_categories(:filter => @post_category.id), @post_category.parent_id) %>
26
+ </select>
27
+ </li>
28
+ </ol>
29
+ </fieldset>
30
+
31
+ <fieldset class="submit">
32
+ <%= f.submit 'Save Post Category' %> or <%= link_to "cancel", request.referer %>
33
+ </fieldset>
34
+
35
+ <% end %>
36
+
37
+ <script type="text/javascript">
38
+ $(document).ready(Spud.Admin.Posts.edit);
39
+ </script>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,29 @@
1
+ <%= content_for :data_controls do %>
2
+ <%= link_to "New Post Category", new_spud_admin_post_category_path, :class => "button", :title => "New Post Category" %>
3
+ <% end %>
4
+
5
+ <%=content_for :detail do %>
6
+ <table class="admin-table">
7
+ <thead>
8
+ <tr>
9
+ <th>Name</th>
10
+ <th># Occurances</th>
11
+ <th>&nbsp;</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% @post_categories.each do |category| %>
16
+ <tr>
17
+ <td><%= link_to category.name, edit_spud_admin_post_category_path(category) %></td>
18
+ <td><%= category.posts.size %></td>
19
+ <td align="right">
20
+ <%= link_to 'Delete', spud_admin_post_category_path(category), :method => :delete, :confirm => 'Are you sure you want to delete this category?', :class => 'spud_admin_button_delete' %>
21
+ </td>
22
+ </tr>
23
+ <%end%>
24
+ </tbody>
25
+ </table>
26
+ <div class="spud_admin_pagination">
27
+ <%= will_paginate @post_categories %>
28
+ </div>
29
+ <%end%>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,9 @@
1
+ <li class="spud_post_form_category">
2
+ <%= check_box_tag 'spud_post[category_ids][]', category.id, @post.category_ids.include?(category.id), :id => "spud_post_category_#{category.id}" %>
3
+ <%= label_tag "spud_post_category_#{category.id}", category.name %>
4
+ <% if @categories[category.id] %>
5
+ <ul>
6
+ <%= render :partial => 'category', :collection => @categories[category.id] %>
7
+ </ul>
8
+ <% end %>
9
+ </li>
@@ -0,0 +1,60 @@
1
+ <%= form_for @post, :url => spud_admin_post_path(@post), :html => {:class => 'right_aligned_form'} do |f| %>
2
+
3
+ <% if @post.errors.any? %>
4
+ <div class="spud_admin_form_error_list">
5
+ <h4><%= pluralize(@post.errors.count, "error") %> prohibited you from saving this post:</h4>
6
+ <ul>
7
+ <% @post.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <fieldset>
15
+ <legend>Post Title</legend>
16
+ <p>
17
+ <%= f.text_field :title, :class => 'full-width' %>
18
+ </p>
19
+ </fieldset>
20
+
21
+ <div>
22
+ <%= f.label :content %>
23
+ <%= f.text_area :content, :class => 'wysiwym' %>
24
+ </div>
25
+
26
+ <fieldset>
27
+ <legend>Categories</legend>
28
+ <ul id="spud_post_categories_form">
29
+ <%= render :partial => 'category', :collection => @categories[0] %>
30
+ </ul>
31
+ </fieldset>
32
+
33
+ <fieldset>
34
+ <legend>Advanced</legend>
35
+ <ol>
36
+ <li>
37
+ <%= f.label :published_at, 'Publish Date' %>
38
+ <%= f.text_field :published_at, :class => 'spud_form_date_picker' %>
39
+ </li>
40
+ <li>
41
+ <%= f.label :visible %>
42
+ <%= f.check_box :visible %>
43
+ </li>
44
+ <li>
45
+ <%= f.label :comments_enabled %>
46
+ <%= f.check_box :comments_enabled %>
47
+ </li>
48
+ </ol>
49
+ </fieldset>
50
+
51
+ <fieldset class="submit">
52
+ <%= f.hidden_field :spud_user_id %>
53
+ <%= f.submit 'Save Post', :class => "wymupdate"%> or <%= link_to "cancel",request.referer %>
54
+ </fieldset>
55
+
56
+ <% end %>
57
+
58
+ <script type="text/javascript">
59
+ $(document).ready(Spud.Admin.Posts.edit);
60
+ </script>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
@@ -0,0 +1,33 @@
1
+ <%= content_for :data_controls do %>
2
+ <%= link_to "New Post", new_spud_admin_post_path, :class => "button", :title => "New Post" %>
3
+ <% end %>
4
+
5
+ <%=content_for :detail do %>
6
+ <table class="admin-table">
7
+ <thead>
8
+ <tr>
9
+ <th>Title</th>
10
+ <th>Author</th>
11
+ <th>Published At</th>
12
+ <th>Comments</th>
13
+ <th>&nbsp;</th>
14
+ </tr>
15
+ </thead>
16
+ <tbody>
17
+ <% @posts.each do |post| %>
18
+ <tr>
19
+ <td><%= link_to post.title, edit_spud_admin_post_path(post) %></td>
20
+ <td><%= post.author.full_name %></td>
21
+ <td><%= post.published_at.strftime('%m/%d/%Y') %></td>
22
+ <td><%= post.comments.size %></td>
23
+ <td align="right">
24
+ <%= link_to 'Delete', spud_admin_post_path(post), :method => :delete, :confirm => 'Are you sure you want to delete this post?', :class => 'spud_admin_button_delete' %>
25
+ </td>
26
+ </tr>
27
+ <%end%>
28
+ </tbody>
29
+ </table>
30
+ <div class="spud_admin_pagination">
31
+ <%= will_paginate @posts %>
32
+ </div>
33
+ <%end%>
@@ -0,0 +1 @@
1
+ <%= render 'form' %>
File without changes
@@ -0,0 +1,48 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'rails/all'
4
+
5
+ if defined?(Bundler)
6
+ # If you precompile assets before deploying to production, use this line
7
+ Bundler.require *Rails.groups(:assets => %w(development test))
8
+ # If you want your assets lazily compiled in production, use this line
9
+ # Bundler.require(:default, :assets, Rails.env)
10
+ end
11
+
12
+ module SpudTest
13
+ class Application < Rails::Application
14
+ # Settings in config/environments/* take precedence over those specified here.
15
+ # Application configuration should go into files in config/initializers
16
+ # -- all .rb files in that directory are automatically loaded.
17
+
18
+ # Custom directories with classes and modules you want to be autoloadable.
19
+ # config.autoload_paths += %W(#{config.root}/extras)
20
+
21
+ # Only load the plugins named here, in the order given (default is alphabetical).
22
+ # :all can be used as a placeholder for all plugins not explicitly named.
23
+ # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24
+
25
+ # Activate observers that should always be running.
26
+ # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27
+
28
+ # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29
+ # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30
+ # config.time_zone = 'Central Time (US & Canada)'
31
+
32
+ # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33
+ # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34
+ # config.i18n.default_locale = :de
35
+
36
+ # Configure the default encoding used in templates for Ruby 1.9.
37
+ config.encoding = "utf-8"
38
+
39
+ # Configure sensitive parameters which will be filtered from the log file.
40
+ config.filter_parameters += [:password]
41
+
42
+ # Enable the asset pipeline
43
+ config.assets.enabled = true
44
+
45
+ # Version of your assets, change this if you want to expire all your assets
46
+ config.assets.version = '1.0'
47
+ end
48
+ end
data/config/boot.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'rubygems'
2
+
3
+ # Set up gems listed in the Gemfile.
4
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5
+
6
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
data/config/routes.rb ADDED
@@ -0,0 +1,27 @@
1
+ Rails.application.routes.draw do
2
+
3
+ namespace :spud do
4
+ namespace :admin do
5
+ resources :posts do
6
+ resources :post_comments, :path => 'comments', :only => :index
7
+ end
8
+ resources :post_comments, :except => :new
9
+ resources :post_categories
10
+ end
11
+ end
12
+
13
+ get 'blog/category/:category_url_name', :controller => 'blog', :action => 'category', :page => 1, :as => 'blog_category'
14
+ get 'blog/category/:category_id/page/:page', :controller => 'blog', :action => 'category'
15
+ post 'blog/category', :controller => 'blog', :action => 'category'
16
+
17
+ get 'blog/archive/:blog_archive', :controller => 'blog', :action => 'archive', :page => 1, :as => 'blog_archive'
18
+ get 'blog/archive/:blog_archive/page/:page', :controller => 'blog', :action => 'archive'
19
+ post 'blog/archive', :controller => 'blog', :action => 'archive'
20
+
21
+ get 'blog', :controller => 'blog', :action => 'index', :page => 1
22
+ get '/blog/page/:page', :controller => 'blog', :action => 'index'
23
+ resources :blog_posts, :path => 'blog', :controller => 'blog', :only => [:show] do
24
+ post '/', :on => :member, :controller => 'blog', :action => 'create_comment'
25
+ end
26
+
27
+ end
@@ -0,0 +1,8 @@
1
+ module Spud
2
+ module Blog
3
+ include ActiveSupport::Configurable
4
+ config_accessor :default_layout, :news_enabled
5
+ self.default_layout = 'application'
6
+ self.news_enabled = false
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ require 'spud_core'
2
+ module Spud
3
+ module Blog
4
+ class Engine < Rails::Engine
5
+ engine_name :spud_blog
6
+ initializer :admin do
7
+ Spud::Core.config.admin_applications += [{
8
+ :name => 'Posts',
9
+ :thumbnail => 'spud/admin/posts_thumb.png',
10
+ :url => '/spud/admin/posts',
11
+ :order => 1
12
+ },{
13
+ :name => 'Post Categories',
14
+ :thumbnail => 'spud/admin/posts_thumb.png',
15
+ :url => '/spud/admin/post_categories',
16
+ :order => 2
17
+ }]
18
+ end
19
+ initializer :assets do
20
+ Rails.application.config.assets.precompile += ['spud/admin/posts.css']
21
+ end
22
+ initializer :associations do
23
+ SpudUser.class_eval do
24
+ has_many :posts, :class_name => 'SpudPost'
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/spud_blog.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Spud
2
+ module Blog
3
+ require 'spud_blog/configuration'
4
+ require 'spud_blog/engine' if defined?(Rails)
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spud_blog
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Greg Woods
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: spud_core
16
+ requirement: &70256639893240 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.4.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70256639893240
25
+ - !ruby/object:Gem::Dependency
26
+ name: will_paginate
27
+ requirement: &70256639892320 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70256639892320
36
+ description:
37
+ email: greg@westlakedesign.com
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - app/assets/javascripts/spud/admin/post_categories.js
43
+ - app/assets/javascripts/spud/admin/post_comments.js
44
+ - app/assets/javascripts/spud/admin/posts.js
45
+ - app/assets/stylesheets/spud/admin/post_categories.css
46
+ - app/assets/stylesheets/spud/admin/post_comments.css
47
+ - app/assets/stylesheets/spud/admin/posts.css
48
+ - app/controllers/blog_controller.rb
49
+ - app/controllers/spud/admin/post_categories_controller.rb
50
+ - app/controllers/spud/admin/post_comments_controller.rb
51
+ - app/controllers/spud/admin/posts_controller.rb
52
+ - app/helpers/blog_helper.rb
53
+ - app/helpers/spud/admin/post_categories_helper.rb
54
+ - app/helpers/spud/admin/post_comments_helper.rb
55
+ - app/helpers/spud/admin/posts_helper.rb
56
+ - app/models/spud_post.rb
57
+ - app/models/spud_post_category.rb
58
+ - app/models/spud_post_comment.rb
59
+ - app/views/blog/_comment.html.erb
60
+ - app/views/blog/_comment_form.html.erb
61
+ - app/views/blog/index.html.erb
62
+ - app/views/blog/show.html.erb
63
+ - app/views/layouts/spud/admin/post.html.erb
64
+ - app/views/spud/admin/post_categories/_form.html.erb
65
+ - app/views/spud/admin/post_categories/edit.html.erb
66
+ - app/views/spud/admin/post_categories/index.html.erb
67
+ - app/views/spud/admin/post_categories/new.html.erb
68
+ - app/views/spud/admin/post_categories/show.html.erb
69
+ - app/views/spud/admin/posts/_category.html.erb
70
+ - app/views/spud/admin/posts/_form.html.erb
71
+ - app/views/spud/admin/posts/edit.html.erb
72
+ - app/views/spud/admin/posts/index.html.erb
73
+ - app/views/spud/admin/posts/new.html.erb
74
+ - app/views/spud/admin/posts/show.html.erb
75
+ - config/application.rb
76
+ - config/boot.rb
77
+ - config/routes.rb
78
+ - lib/spud_blog.rb
79
+ - lib/spud_blog/configuration.rb
80
+ - lib/spud_blog/engine.rb
81
+ homepage:
82
+ licenses: []
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ! '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.15
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Spud Blog Engine
105
+ test_files: []