spud_blog 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/spud/admin/post_categories.js +2 -0
- data/app/assets/javascripts/spud/admin/post_comments.js +2 -0
- data/app/assets/javascripts/spud/admin/posts.js +29 -0
- data/app/assets/stylesheets/spud/admin/post_categories.css +4 -0
- data/app/assets/stylesheets/spud/admin/post_comments.css +4 -0
- data/app/assets/stylesheets/spud/admin/posts.css +49 -0
- data/app/controllers/blog_controller.rb +65 -0
- data/app/controllers/spud/admin/post_categories_controller.rb +46 -0
- data/app/controllers/spud/admin/post_comments_controller.rb +41 -0
- data/app/controllers/spud/admin/posts_controller.rb +54 -0
- data/app/helpers/blog_helper.rb +14 -0
- data/app/helpers/spud/admin/post_categories_helper.rb +2 -0
- data/app/helpers/spud/admin/post_comments_helper.rb +2 -0
- data/app/helpers/spud/admin/posts_helper.rb +15 -0
- data/app/models/spud_post.rb +62 -0
- data/app/models/spud_post_category.rb +58 -0
- data/app/models/spud_post_comment.rb +5 -0
- data/app/views/blog/_comment.html.erb +4 -0
- data/app/views/blog/_comment_form.html.erb +17 -0
- data/app/views/blog/index.html.erb +33 -0
- data/app/views/blog/show.html.erb +23 -0
- data/app/views/layouts/spud/admin/post.html.erb +7 -0
- data/app/views/spud/admin/post_categories/_form.html.erb +39 -0
- data/app/views/spud/admin/post_categories/edit.html.erb +1 -0
- data/app/views/spud/admin/post_categories/index.html.erb +29 -0
- data/app/views/spud/admin/post_categories/new.html.erb +1 -0
- data/app/views/spud/admin/post_categories/show.html.erb +0 -0
- data/app/views/spud/admin/posts/_category.html.erb +9 -0
- data/app/views/spud/admin/posts/_form.html.erb +60 -0
- data/app/views/spud/admin/posts/edit.html.erb +1 -0
- data/app/views/spud/admin/posts/index.html.erb +33 -0
- data/app/views/spud/admin/posts/new.html.erb +1 -0
- data/app/views/spud/admin/posts/show.html.erb +0 -0
- data/config/application.rb +48 -0
- data/config/boot.rb +6 -0
- data/config/routes.rb +27 -0
- data/lib/spud_blog/configuration.rb +8 -0
- data/lib/spud_blog/engine.rb +29 -0
- data/lib/spud_blog.rb +6 -0
- metadata +105 -0
@@ -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,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,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,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,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> </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' %>
|
File without changes
|
@@ -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> </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
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,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
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: []
|