effective_posts 0.2.4 → 0.2.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4984a1f52ef5576bf0261b0964c222a5ebb83d47
4
- data.tar.gz: 9decb44d570738d663dee90116f197d86f9c23c4
3
+ metadata.gz: 579841290e09b748845c8ae7579e9804abb3eb98
4
+ data.tar.gz: 26f9819558a657cde932da4f0f9d3ae6b9089e99
5
5
  SHA512:
6
- metadata.gz: ce3d371e294fcfcb67513c506c7faf4fe09b9126b45c66ba6f2b0e1e4b58894e19e88e13157ff517b09d084a918c5ec3b1c4d8aa3c429ee443571507dd65565e
7
- data.tar.gz: 1836774e1a72bd266955100d38187faab51ded91caaa4597f1d2c1b8fccdd0f6e14ba184268ec892bc431f50da065766ec0b19d1699b25c03287deedbb175d16
6
+ metadata.gz: 25e40384bbddf29e3f04c7fff34bf0cb5f9bede594296bf98fe991a9eacd9f67a95f53bbcd28d0dc5c8213a1f2bdeaba54a37f6344bc81f561422746ebccf4f3
7
+ data.tar.gz: 1419866b4ac11195f7cfc493fc9f6feea94f382be9465c426280776cec90f38b70494254209fac175bb9273751a8ebd1066f329faebe6523046ce6cc67c815df
data/README.md CHANGED
@@ -70,6 +70,8 @@ If disabled, all posts will be available at `/posts`, with posts for a specific
70
70
 
71
71
  Use `link_to_post_category(:blog)` to display a link to the Blog page. The helper considers `config.use_category_routes` and puts in the correct url.
72
72
 
73
+ Use `post_excerpt(post)` to display the excerpt for a post. Or `post_excerpt(post, :length => 200)` to truncate it and add a Read more link where appropriate.
74
+
73
75
 
74
76
  ## Pagination
75
77
 
@@ -1,42 +1,47 @@
1
1
  module EffectivePostsHelper
2
2
  def render_post(post)
3
- render(:partial => 'effective/posts/post', :locals => {:post => post})
3
+ render(partial: 'effective/posts/post', locals: { post: post })
4
4
  end
5
5
 
6
6
  def post_meta(post)
7
7
  [
8
- "Published",
9
- "on #{post.published_at.strftime("%B %d, %Y at %l:%M %p")}",
8
+ 'Published',
9
+ "on #{post.published_at.strftime('%B %d, %Y at %l:%M %p')}",
10
10
  ("to #{link_to_post_category(post.category)}" if Array(EffectivePosts.categories).length > 1),
11
11
  ("by #{post.user.to_s.presence || 'Unknown'}" if EffectivePosts.post_meta_author)
12
12
  ].compact.join(' ').html_safe
13
13
  end
14
14
 
15
15
  def post_excerpt(post, options = {})
16
- content = effective_region(post, :content) { "<p>Default content</p>".html_safe }
16
+ content = effective_region(post, :content) { '<p>Default content</p>'.html_safe }
17
17
 
18
- index = content.index(Effective::Snippets::ReadMoreDivider::TOKEN)
18
+ divider = content.index(Effective::Snippets::ReadMoreDivider::TOKEN)
19
+ length = options.delete(:length)
19
20
 
20
- if index.present? # We have to return the excerpt and add a Read more... link
21
- content[0...index].html_safe +
22
- content_tag(:p, :class => 'post-read-more') do
23
- link_to((options.delete(:label) || 'Read more...'), effective_post_path(post), options)
24
- end
21
+ if divider.present?
22
+ content[0...divider] + readmore_link(post, options)
23
+ elsif length.present? && content.length > length
24
+ truncate_html(content, length, '...', readmore_link(post, options))
25
25
  else
26
26
  content
27
- end
27
+ end.html_safe
28
28
  end
29
29
 
30
30
  def link_to_post_category(category, options = {})
31
31
  category = category.to_s.downcase
32
32
 
33
- href = EffectivePosts.use_category_routes ? "/#{category}" : effective_posts.posts_path(:category => category.to_s)
33
+ href = EffectivePosts.use_category_routes ? "/#{category}" : effective_posts.posts_path(category: category.to_s)
34
34
  link_to(category.to_s.titleize, href, options)
35
35
  end
36
36
 
37
37
  def effective_post_path(post)
38
38
  category = post.category.to_s.downcase
39
- EffectivePosts.use_category_routes ? "/#{category}/#{post.to_param}" : effective_posts.post_path(post, :category => category.to_s)
39
+ EffectivePosts.use_category_routes ? "/#{category}/#{post.to_param}" : effective_posts.post_path(post, category: category.to_s)
40
40
  end
41
41
 
42
+ def readmore_link(post, options)
43
+ content_tag(:p, class: 'post-read-more') do
44
+ link_to((options.delete(:label) || 'Read more'), effective_posts.post_path(post), options)
45
+ end
46
+ end
42
47
  end
@@ -0,0 +1,77 @@
1
+ # Modified from
2
+ # http://blog.madebydna.com/all/code/2010/06/04/ruby-helper-to-cleanly-truncate-html.html
3
+
4
+ module EffectiveTruncateHtmlHelper
5
+ def chunk_html(text, max_length = 2, _ellipsis = '...', read_more = nil)
6
+ doc = Nokogiri::HTML::DocumentFragment.parse text
7
+
8
+ if doc.children.length >= max_length
9
+ doc.children.last.remove while doc.children.length > max_length
10
+ doc.children.last.add_next_sibling Nokogiri::HTML::DocumentFragment.parse("<p>#{ read_more }</p>")
11
+ end
12
+
13
+ doc.inner_html.html_safe
14
+ end
15
+
16
+ def truncate_html(text, max_length = 200, ellipsis = '...', read_more = nil)
17
+ ellipsis_length = ellipsis.to_s.length
18
+ doc = Nokogiri::HTML::DocumentFragment.parse text
19
+ content_length = doc.inner_text.length
20
+ actual_length = max_length - ellipsis_length
21
+
22
+ if content_length > actual_length
23
+ truncated_node = doc.truncate_html(actual_length)
24
+
25
+ last_node = truncated_node
26
+ while last_node.respond_to?(:children) && last_node.children.present?
27
+ last_node = last_node.children.reverse.find { |node| node.try(:name) != 'a' } # Find the last non-A node
28
+ end
29
+
30
+ if read_more.present?
31
+ read_more_node = Nokogiri::HTML::DocumentFragment.parse(read_more.to_s)
32
+ last_node.add_next_sibling(read_more_node)
33
+ end
34
+
35
+ if ellipsis.present?
36
+ ellipsis_node = Nokogiri::XML::Text.new(ellipsis.to_s, doc)
37
+ last_node.add_next_sibling(ellipsis_node)
38
+ end
39
+
40
+ truncated_node.inner_html
41
+ else
42
+ text.to_s
43
+ end.html_safe
44
+ end
45
+ end
46
+
47
+ module NokogiriTruncator
48
+ module NodeWithChildren
49
+ def truncate_html(max_length)
50
+ return self if inner_text.length <= max_length
51
+ truncated_node = dup
52
+ truncated_node.children.remove
53
+
54
+ children.each do |node|
55
+ remaining_length = max_length - truncated_node.inner_text.length
56
+ break if remaining_length <= 10
57
+ truncated_node.add_child node.truncate_html(remaining_length)
58
+ end
59
+ truncated_node
60
+ end
61
+ end
62
+
63
+ module TextNode
64
+ include ActionView::Helpers::TextHelper
65
+
66
+ def truncate_html(max_length)
67
+ truncated = truncate(content, length: max_length, separator: ' ', omission: '')
68
+
69
+ # Nokogiri::XML::Text.new(truncate(content.to_s, :length => (max_length-1)), parent)
70
+ Nokogiri::XML::Text.new(truncated, parent)
71
+ end
72
+ end
73
+ end
74
+
75
+ Nokogiri::HTML::DocumentFragment.send(:include, NokogiriTruncator::NodeWithChildren)
76
+ Nokogiri::XML::Element.send(:include, NokogiriTruncator::NodeWithChildren)
77
+ Nokogiri::XML::Text.send(:include, NokogiriTruncator::TextNode)
@@ -8,7 +8,7 @@ module Effective
8
8
  belongs_to :user
9
9
 
10
10
  structure do
11
- title :string, :validates => [:presence]
11
+ title :string, :validates => [:presence, :length => {:maximum => 255}]
12
12
  category :string, :validates => [:presence]
13
13
 
14
14
  published_at :datetime, :validates => [:presence]
@@ -1,3 +1,3 @@
1
1
  module EffectivePosts
2
- VERSION = '0.2.4'.freeze
2
+ VERSION = '0.2.5'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_posts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-11 00:00:00.000000000 Z
11
+ date: 2015-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: migrant
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -154,6 +168,7 @@ files:
154
168
  - app/controllers/effective/posts_controller.rb
155
169
  - app/helpers/effective_kaminari_helper.rb
156
170
  - app/helpers/effective_posts_helper.rb
171
+ - app/helpers/effective_truncate_html_helper.rb
157
172
  - app/models/effective/access_denied.rb
158
173
  - app/models/effective/datatables/posts.rb
159
174
  - app/models/effective/post.rb