spud_blog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []