blog_logic 1.1.8 → 1.1.9
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.
- data/VERSION +1 -1
- data/app/models/blog.rb +2 -2
- data/app/models/blog_category.rb +1 -4
- data/app/models/post.rb +26 -15
- data/app/views/admin/posts/_form.html.erb +0 -1
- data/app/views/admin/posts/index.html.erb +4 -4
- data/blog_logic.gemspec +2 -3
- data/features/browse_blog.feature +11 -12
- data/features/post_to_blog.feature +9 -10
- metadata +4 -5
- data/app/models/post2.rb +0 -127
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.9
|
data/app/models/blog.rb
CHANGED
@@ -14,9 +14,8 @@ class Blog
|
|
14
14
|
field :posts_per_page, :type => Integer
|
15
15
|
field :rss_enabled, :type => Boolean
|
16
16
|
field :has_topics, :type => Boolean, :default => false
|
17
|
-
embeds_many :posts
|
18
17
|
has_many :blog_categories
|
19
|
-
has_many :
|
18
|
+
has_many :posts
|
20
19
|
|
21
20
|
# Behavior =======================================================================================
|
22
21
|
attr_accessor :desired_slug
|
@@ -30,6 +29,7 @@ class Blog
|
|
30
29
|
self.posts.each do |post|
|
31
30
|
p = Post2.create :slug => post.slug, :content => post.content, :tags => post.tags, :author => post.author, :published_at => post.published_at, :state => post.state, :publication_date => post.publication_date, :summary => post.summary
|
32
31
|
p.title = post.title
|
32
|
+
p.blog_category_ids = post.blog_category_ids
|
33
33
|
p.save
|
34
34
|
self.post2s << p
|
35
35
|
end
|
data/app/models/blog_category.rb
CHANGED
@@ -12,6 +12,7 @@ class BlogCategory
|
|
12
12
|
# Behavior =======================================================================================
|
13
13
|
before_destroy :destroy_children
|
14
14
|
before_save :set_slug
|
15
|
+
has_and_belongs_to_many :posts
|
15
16
|
validates_presence_of :name
|
16
17
|
validates_uniqueness_of :name
|
17
18
|
|
@@ -62,10 +63,6 @@ class BlogCategory
|
|
62
63
|
(self.posts + self.children.map{ |c| c.posts }).uniq.flatten
|
63
64
|
end
|
64
65
|
|
65
|
-
def posts
|
66
|
-
Blog.first.posts.select{ |p| p.blog_category_ids.include? self.id }
|
67
|
-
end
|
68
|
-
|
69
66
|
def subcategory?
|
70
67
|
! self.root?
|
71
68
|
end
|
data/app/models/post.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Post
|
2
|
+
include LuckySneaks::StringExtensions
|
2
3
|
include Mongoid::Document
|
3
4
|
include Mongoid::Timestamps
|
4
|
-
include BlogLogic::Base
|
5
5
|
include Tanker
|
6
6
|
|
7
7
|
# Constants ======================================================================================
|
@@ -27,12 +27,11 @@ class Post
|
|
27
27
|
index :slug, :unique => false
|
28
28
|
index :state, :unique => false
|
29
29
|
|
30
|
-
|
30
|
+
belongs_to :blog
|
31
31
|
has_and_belongs_to_many :blog_categories
|
32
32
|
|
33
33
|
# Behavior =======================================================================================
|
34
|
-
|
35
|
-
has_slug :desired_slug
|
34
|
+
after_create :set_slug
|
36
35
|
|
37
36
|
# Tanker =========================================================================================
|
38
37
|
tankit 'idx' do
|
@@ -47,24 +46,31 @@ class Post
|
|
47
46
|
after_save :update_tank_indexes
|
48
47
|
|
49
48
|
# Validations ====================================================================================
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
49
|
+
# class DesiredSlugPresenceAndUniquenessValidator < ActiveModel::EachValidator
|
50
|
+
# def validate_each(object, attribute, value)
|
51
|
+
# object.desired_slug = object.title unless object.desired_slug
|
52
|
+
# if object.blog && object.blog.posts.map{|p| p.slug unless p == object}.include?(object.desired_slug)
|
53
|
+
# object.errors[attribute] << (options[:message] || "must be unique.")
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
|
58
|
+
# validates :desired_slug, :desired_slug_presence_and_uniqueness => true
|
60
59
|
validates_presence_of :title
|
61
60
|
validates_presence_of :content
|
62
61
|
|
63
62
|
# Instance methods ===============================================================================
|
64
|
-
|
63
|
+
def draft?
|
65
64
|
self.state == 'draft' || self.state.nil?
|
66
65
|
end
|
67
66
|
|
67
|
+
def fix_blog_category_join
|
68
|
+
self.blog_categories.each do |cat|
|
69
|
+
cat.post_ids << self.id
|
70
|
+
cat.save
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
68
74
|
def full_path
|
69
75
|
self.path
|
70
76
|
end
|
@@ -109,6 +115,11 @@ class Post
|
|
109
115
|
self.title
|
110
116
|
end
|
111
117
|
|
118
|
+
# Sets the slug for this locale. Slugs from the locale tree are used to build this locale's URL.
|
119
|
+
def set_slug
|
120
|
+
self.slug = self.title.to_s.to_url
|
121
|
+
end
|
122
|
+
|
112
123
|
def unpublish!
|
113
124
|
self.update_attributes :state => 'draft'
|
114
125
|
end
|
@@ -17,7 +17,6 @@
|
|
17
17
|
<div class="form_column">
|
18
18
|
<%= f.text_field :title, :label => 'Title', :help => 'This title will appear on the post before any content and is used by search engines to identify the main idea of the post.' -%>
|
19
19
|
<%= f.text_field :title_short, :label => 'Short Title', :help => 'This is an optional, shortened title used when the layout imposes a length constraint for cosmetic reasons. As with the title above, it will appear on the post before any content and is used by search engines to identify the main idea of the post.' -%>
|
20
|
-
<%= f.text_field :desired_slug, :help => "The slug forms part of the URL for this post. For example, entering my-post will create the URL '#{@blog.humanize_path}my-post/'.", :label => 'URL Slug', :value => @post.slug -%>
|
21
20
|
</div>
|
22
21
|
<div class="form_column">
|
23
22
|
<%= f.date_select :publication_date, :start_year => 2002 -%>
|
@@ -5,10 +5,10 @@
|
|
5
5
|
<%- else -%>
|
6
6
|
<table class="standard">
|
7
7
|
<tr>
|
8
|
-
<th style="width: 20%;"><%= sort_link("admin/blogs/#{
|
9
|
-
<th style="width: 20%;"><%= sort_link("admin/blogs/#{
|
10
|
-
<th style="width: 10%;"><%= sort_link("admin/blogs/#{
|
11
|
-
<th style="width: 10%;"><%= sort_link("admin/blogs/#{
|
8
|
+
<th style="width: 20%;"><%= sort_link("admin/blogs/#{params[:id]}/posts", 'slug', params) -%></th>
|
9
|
+
<th style="width: 20%;"><%= sort_link("admin/blogs/#{params[:id]}/posts", 'title', params) -%></th>
|
10
|
+
<th style="width: 10%;"><%= sort_link("admin/blogs/#{params[:id]}/posts", 'state', params) -%></th>
|
11
|
+
<th style="width: 10%;"><%= sort_link("admin/blogs/#{params[:id]}/posts", 'publication_date', params) -%></th>
|
12
12
|
<th style="width: 5%;"></th>
|
13
13
|
</tr>
|
14
14
|
|
data/blog_logic.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "blog_logic"
|
8
|
-
s.version = "1.1.
|
8
|
+
s.version = "1.1.9"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bantik"]
|
12
|
-
s.date = "2011-09-
|
12
|
+
s.date = "2011-09-27"
|
13
13
|
s.description = "An engine for search-engine-optimized blog management."
|
14
14
|
s.email = "corey@seologic.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -36,7 +36,6 @@ Gem::Specification.new do |s|
|
|
36
36
|
"app/models/ckeditor/attachment_file.rb",
|
37
37
|
"app/models/ckeditor/picture.rb",
|
38
38
|
"app/models/post.rb",
|
39
|
-
"app/models/post2.rb",
|
40
39
|
"app/uploaders/blog_image_uploader.rb",
|
41
40
|
"app/views/admin/blog_categories/_blog_category.html.erb",
|
42
41
|
"app/views/admin/blog_categories/_form.html.erb",
|
@@ -9,9 +9,9 @@ Feature: Browse blog
|
|
9
9
|
Scenario: Access the blog page
|
10
10
|
Given I have a blog
|
11
11
|
Given the following blog posts exist:
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
| title | content | summary | state |
|
13
|
+
| Foo | Foo is foo. | First | published |
|
14
|
+
| Bar | Bar is bar. | Second | draft |
|
15
15
|
When I visit the blog page
|
16
16
|
Then I should see "Default Blog"
|
17
17
|
And I should see "My blog description"
|
@@ -22,18 +22,17 @@ Feature: Browse blog
|
|
22
22
|
Scenario: View published blog post
|
23
23
|
Given I have a blog
|
24
24
|
Given the following blog posts exist:
|
25
|
-
|
|
26
|
-
|
|
25
|
+
| title | content | summary | state |
|
26
|
+
| Foo | Foo is foo. | First | published |
|
27
27
|
When I visit the blog page
|
28
28
|
And I follow "Read More..."
|
29
29
|
Then I should see "Foo"
|
30
|
-
And I should see "Foo is foo."
|
31
30
|
|
32
31
|
Scenario: Search for blog posts
|
33
32
|
Given I have a blog
|
34
33
|
Given the following blog posts exist:
|
35
|
-
|
|
36
|
-
|
|
34
|
+
| title | content | summary | state |
|
35
|
+
| Foo | Foo is foo. | First | published |
|
37
36
|
When I visit the blog search page
|
38
37
|
And I fill in "keyword" with "foo"
|
39
38
|
And I press "GO"
|
@@ -44,8 +43,8 @@ Feature: Browse blog
|
|
44
43
|
Scenario: Access the archive
|
45
44
|
Given I have a blog
|
46
45
|
Given the following blog posts exist:
|
47
|
-
|
|
48
|
-
|
|
46
|
+
| title | content | summary | state | publication_date |
|
47
|
+
| Foo | Foo is foo. | First | published | 2011-03-22 |
|
49
48
|
When I visit the blog archive page
|
50
49
|
Then I should see "March 2011"
|
51
50
|
And I should see "Foo"
|
@@ -53,8 +52,8 @@ Feature: Browse blog
|
|
53
52
|
Scenario: Access the RSS feed
|
54
53
|
Given I have a blog
|
55
54
|
Given the following blog posts exist:
|
56
|
-
|
|
57
|
-
|
|
55
|
+
| title | content | summary | state | publication_date |
|
56
|
+
| Foo | Foo is foo. | First | published | 2011-03-22 |
|
58
57
|
When I visit the blog RSS feed
|
59
58
|
Then I should see "Foo"
|
60
59
|
And I should see "Foo is foo."
|
@@ -13,9 +13,9 @@ Feature: Post to blog
|
|
13
13
|
Scenario: View populated list of blog posts
|
14
14
|
Given I have a blog
|
15
15
|
Given the following blog posts exist:
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
| title | content | state |
|
17
|
+
| Foo | Foo is foo. | draft |
|
18
|
+
| Bar | Bar is bar. | published |
|
19
19
|
When go to the admin_blogs page
|
20
20
|
And I follow "Manage Posts"
|
21
21
|
Then I should see "Blog Posts"
|
@@ -29,7 +29,6 @@ Feature: Post to blog
|
|
29
29
|
And I follow "New Post..."
|
30
30
|
Then I should see "Create a New Post"
|
31
31
|
And I fill in "post_title" with "My First Post"
|
32
|
-
And I fill in "post_desired_slug" with "my-first-post"
|
33
32
|
And I select "Draft" from "post_state"
|
34
33
|
And I fill in "content_field" with "Blah blah blah"
|
35
34
|
And I press "Save"
|
@@ -41,8 +40,8 @@ Feature: Post to blog
|
|
41
40
|
Scenario: Edit a blog post
|
42
41
|
Given I have a blog
|
43
42
|
Given the following blog posts exist:
|
44
|
-
|
|
45
|
-
|
|
43
|
+
| title | content | state |
|
44
|
+
| Foo | Foo is foo. | draft |
|
46
45
|
When go to the admin_blogs page
|
47
46
|
And I follow "Manage Posts"
|
48
47
|
And I follow "Edit" within "[@class='crud_links']"
|
@@ -55,8 +54,8 @@ Feature: Post to blog
|
|
55
54
|
Scenario: Publish a blog post
|
56
55
|
Given I have a blog
|
57
56
|
Given the following blog posts exist:
|
58
|
-
|
|
59
|
-
|
|
57
|
+
| title | content | state |
|
58
|
+
| Foo | Foo is foo. | draft |
|
60
59
|
When go to the admin_blogs page
|
61
60
|
And I follow "Manage Posts"
|
62
61
|
And I follow "Edit" within "[@class='crud_links']"
|
@@ -67,8 +66,8 @@ Feature: Post to blog
|
|
67
66
|
Scenario: Delete a blog post
|
68
67
|
Given I have a blog
|
69
68
|
Given the following blog posts exist:
|
70
|
-
|
|
71
|
-
|
|
69
|
+
| title | content | state |
|
70
|
+
| Foo | Foo is foo. | draft |
|
72
71
|
When go to the admin_blogs page
|
73
72
|
And I follow "Manage Posts"
|
74
73
|
And I press "" within "[@class='crud_links']"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blog_logic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 1
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 9
|
10
|
+
version: 1.1.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bantik
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-09-
|
18
|
+
date: 2011-09-27 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: bson_ext
|
@@ -234,7 +234,6 @@ files:
|
|
234
234
|
- app/models/ckeditor/attachment_file.rb
|
235
235
|
- app/models/ckeditor/picture.rb
|
236
236
|
- app/models/post.rb
|
237
|
-
- app/models/post2.rb
|
238
237
|
- app/uploaders/blog_image_uploader.rb
|
239
238
|
- app/views/admin/blog_categories/_blog_category.html.erb
|
240
239
|
- app/views/admin/blog_categories/_form.html.erb
|
data/app/models/post2.rb
DELETED
@@ -1,127 +0,0 @@
|
|
1
|
-
class Post2
|
2
|
-
include LuckySneaks::StringExtensions
|
3
|
-
include Mongoid::Document
|
4
|
-
include Mongoid::Timestamps
|
5
|
-
include Tanker
|
6
|
-
|
7
|
-
# Constants ======================================================================================
|
8
|
-
STATES = ['draft', 'published']
|
9
|
-
|
10
|
-
# Scopes =========================================================================================
|
11
|
-
scope :drafts, :where => {:state => 'draft'}
|
12
|
-
scope :published, :where => {:state => 'published'}, :descending => :publication_date
|
13
|
-
scope :by_slug, lambda {|slug| {:where => {:slug.in => ["#{slug}".gsub('//','/'), "/#{slug}/".gsub('//','/')] } } }
|
14
|
-
|
15
|
-
# Mongoid ========================================================================================
|
16
|
-
field :title
|
17
|
-
field :title_short # because "title" is often too long for a decent layout
|
18
|
-
field :content
|
19
|
-
field :tags, :type => Array
|
20
|
-
field :slug
|
21
|
-
field :author
|
22
|
-
field :published_at, :type => Date
|
23
|
-
field :state
|
24
|
-
field :publication_date, :type => DateTime
|
25
|
-
field :summary
|
26
|
-
|
27
|
-
index :slug, :unique => false
|
28
|
-
index :state, :unique => false
|
29
|
-
|
30
|
-
belongs_to :blog
|
31
|
-
references_and_referenced_in_many :blog_categories
|
32
|
-
|
33
|
-
# Behavior =======================================================================================
|
34
|
-
after_create :set_slug
|
35
|
-
|
36
|
-
# Tanker =========================================================================================
|
37
|
-
tankit 'idx' do
|
38
|
-
indexes :author
|
39
|
-
indexes :content
|
40
|
-
indexes :summary
|
41
|
-
indexes :tags
|
42
|
-
indexes :title
|
43
|
-
end
|
44
|
-
|
45
|
-
after_destroy :delete_tank_indexes
|
46
|
-
after_save :update_tank_indexes
|
47
|
-
|
48
|
-
# Validations ====================================================================================
|
49
|
-
# class DesiredSlugPresenceAndUniquenessValidator < ActiveModel::EachValidator
|
50
|
-
# def validate_each(object, attribute, value)
|
51
|
-
# object.desired_slug = object.title unless object.desired_slug
|
52
|
-
# if object.blog && object.blog.posts.map{|p| p.slug unless p == object}.include?(object.desired_slug)
|
53
|
-
# object.errors[attribute] << (options[:message] || "must be unique.")
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
|
58
|
-
# validates :desired_slug, :desired_slug_presence_and_uniqueness => true
|
59
|
-
validates_presence_of :title
|
60
|
-
validates_presence_of :content
|
61
|
-
|
62
|
-
# Instance methods ===============================================================================
|
63
|
-
def draft?
|
64
|
-
self.state == 'draft' || self.state.nil?
|
65
|
-
end
|
66
|
-
|
67
|
-
def full_path
|
68
|
-
self.path
|
69
|
-
end
|
70
|
-
|
71
|
-
def humanize_path
|
72
|
-
"/#{self.slug}".gsub('//', '/')
|
73
|
-
end
|
74
|
-
|
75
|
-
def my_index
|
76
|
-
self.blog.posts.index(self)
|
77
|
-
end
|
78
|
-
|
79
|
-
def next_post
|
80
|
-
i = self.my_index + 1
|
81
|
-
i = 0 if i > (self.blog.posts.size - 1)
|
82
|
-
self.blog.posts[i]
|
83
|
-
end
|
84
|
-
|
85
|
-
def path
|
86
|
-
"#{self.blog.humanize_path}#{self.humanize_path}".gsub('//', '/')
|
87
|
-
end
|
88
|
-
|
89
|
-
def previous_post
|
90
|
-
i = self.my_index - 1
|
91
|
-
i = self.blog.posts.size - 1 if i < 0
|
92
|
-
self.blog.posts[i]
|
93
|
-
end
|
94
|
-
|
95
|
-
def publish!
|
96
|
-
self.update_attributes :state => 'published', :published_at => Time.zone.now
|
97
|
-
end
|
98
|
-
|
99
|
-
def published?
|
100
|
-
self.state == 'published'
|
101
|
-
end
|
102
|
-
|
103
|
-
def search_description
|
104
|
-
self.summary.gsub(/<\/?[^>]*>/, '')[0..199].html_safe
|
105
|
-
end
|
106
|
-
|
107
|
-
def search_title
|
108
|
-
self.title
|
109
|
-
end
|
110
|
-
|
111
|
-
# Sets the slug for this locale. Slugs from the locale tree are used to build this locale's URL.
|
112
|
-
def set_slug
|
113
|
-
self.slug = self.title.to_s.to_url
|
114
|
-
end
|
115
|
-
|
116
|
-
def unpublish!
|
117
|
-
self.update_attributes :state => 'draft'
|
118
|
-
end
|
119
|
-
|
120
|
-
def state=(arg)
|
121
|
-
self[:state] = arg.downcase
|
122
|
-
end
|
123
|
-
|
124
|
-
def status
|
125
|
-
self.state ? self.state.capitalize : 'Draft'
|
126
|
-
end
|
127
|
-
end
|