effective_posts 1.2.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +4 -9
- data/app/controllers/admin/posts_controller.rb +9 -125
- data/app/controllers/effective/posts_controller.rb +20 -15
- data/app/datatables/effective_posts_datatable.rb +3 -1
- data/app/helpers/effective_posts_helper.rb +4 -24
- data/app/mailers/effective/posts_mailer.rb +2 -1
- data/app/models/effective/post.rb +43 -57
- data/app/views/admin/posts/_form.html.haml +8 -9
- data/app/views/admin/posts/excerpts.html.haml +2 -2
- data/app/views/effective/posts/_post.html.haml +1 -1
- data/app/views/effective/posts/_sidebar.html.haml +1 -2
- data/app/views/effective/posts/show.html.haml +1 -2
- data/app/views/effective/posts/submitted.html.haml +1 -1
- data/config/effective_posts.rb +2 -34
- data/config/routes.rb +7 -10
- data/db/migrate/01_create_effective_posts.rb.erb +1 -2
- data/lib/effective_posts.rb +14 -49
- data/lib/effective_posts/engine.rb +1 -1
- data/lib/effective_posts/version.rb +1 -1
- metadata +4 -54
- data/app/assets/javascripts/effective/snippets/read_more_divider.js.coffee +0 -22
- data/app/helpers/effective_truncate_html_helper.rb +0 -73
- data/app/models/effective/access_denied.rb +0 -17
- data/app/models/effective/snippets/read_more_divider.rb +0 -11
- data/app/views/admin/posts/_actions.html.haml +0 -13
- data/app/views/admin/posts/edit.html.haml +0 -3
- data/app/views/admin/posts/new.html.haml +0 -3
- data/app/views/effective/snippets/_read_more_divider.html.haml +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 850461d12290e86cc451412a56caaac5fccfc469c58d8a8a716f8b1efc1a0d40
|
4
|
+
data.tar.gz: 44069bc3c8563a6e91f467a7a9f1458d1cd0e6a3f79eb039abae1be473b76e7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cac1f40075ce9ad990c53ba9f4b0feb2bb887fe9a3b4931e0ed15b5ee574593537b1da261f728e84c08b588e0a2f68ad51a366f4949a93afd037f36b717ff15
|
7
|
+
data.tar.gz: fd63bde9093980a4f7e41660d6a11f7e317a52fe9ddaaace0b5addda9f6016138ff8feec88771f52ccf76c497b9b2a7715099714ef66ca7c4f8207b30e13930c
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
|
3
3
|
A blog implementation with WYSIWYG content editing, post scheduling, pagination and optional top level routes for each post category.
|
4
4
|
|
5
|
-
## effective_posts
|
5
|
+
## effective_posts 2.0
|
6
6
|
|
7
|
-
This is the
|
7
|
+
This is the 2.0 series of effective_posts.
|
8
8
|
|
9
|
-
This requires Twitter Bootstrap 4 and Rails
|
9
|
+
This requires Twitter Bootstrap 4 and Rails 6+
|
10
10
|
|
11
11
|
Please check out [Effective Posts 0.x](https://github.com/code-and-effect/effective_posts/tree/bootstrap3) for more information using this gem with Bootstrap 3.
|
12
12
|
|
13
13
|
## Getting Started
|
14
14
|
|
15
|
-
Please first install the [
|
15
|
+
Please first install the [effective_datatables](https://github.com/code-and-effect/effective_datatables) gem.
|
16
16
|
|
17
17
|
Please download and install [Twitter Bootstrap4](http://getbootstrap.com)
|
18
18
|
|
@@ -64,8 +64,6 @@ You can schedule a post to appear at a later date by setting the published_at va
|
|
64
64
|
|
65
65
|
As well, if you're using the [effective_roles](https://github.com/code-and-effect/effective_roles) gem, you will be able to configure permissions so that only permitted users may view this post.
|
66
66
|
|
67
|
-
Once you click `Save and Edit Content` you will be brought into the effective_regions editor where you may enter the content for your post. Click `Insert Snippet` -> `Read more divider` from the toolbar to place a divider into your post. Only the content above the Read more divider, the excerpt content, will be displayed on any posts#index screens. The full content will be displayed on the posts#show screen.
|
68
|
-
|
69
67
|
|
70
68
|
## Category Routes
|
71
69
|
|
@@ -78,9 +76,6 @@ If disabled, all posts will be available at `/posts`, with posts for a specific
|
|
78
76
|
|
79
77
|
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.
|
80
78
|
|
81
|
-
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.
|
82
|
-
|
83
|
-
|
84
79
|
## Pagination
|
85
80
|
|
86
81
|
The [effective_bootstrap](https://github.com/code-and-effect/effective_bootstrap) gem is used for pagination on all posts#index type screens.
|
@@ -1,136 +1,20 @@
|
|
1
1
|
module Admin
|
2
2
|
class PostsController < ApplicationController
|
3
|
-
before_action(:authenticate_user!)
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_posts) }
|
4
5
|
|
5
|
-
|
6
|
+
include Effective::CrudController
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
@datatable = EffectivePostsDatatable.new(self)
|
10
|
-
|
11
|
-
authorize_effective_posts!
|
12
|
-
end
|
13
|
-
|
14
|
-
def new
|
15
|
-
@post = Effective::Post.new(published_at: Time.zone.now)
|
16
|
-
@page_title = 'New Post'
|
17
|
-
|
18
|
-
authorize_effective_posts!
|
19
|
-
end
|
20
|
-
|
21
|
-
def create
|
22
|
-
@post = Effective::Post.new(post_params)
|
23
|
-
@post.user = current_user if defined?(current_user)
|
24
|
-
|
25
|
-
@page_title = 'New Post'
|
26
|
-
|
27
|
-
authorize_effective_posts!
|
28
|
-
|
29
|
-
if @post.save
|
30
|
-
if params[:commit] == 'Save and Edit Content'
|
31
|
-
redirect_to effective_regions.edit_path(effective_posts.post_path(@post), :exit => effective_posts.edit_admin_post_path(@post))
|
32
|
-
elsif params[:commit] == 'Save and Add New'
|
33
|
-
flash[:success] = 'Successfully created post'
|
34
|
-
redirect_to effective_posts.new_admin_post_path
|
35
|
-
elsif params[:commit] == 'Save and View'
|
36
|
-
redirect_to effective_posts.post_path(@post)
|
37
|
-
else
|
38
|
-
flash[:success] = 'Successfully created post'
|
39
|
-
redirect_to effective_posts.edit_admin_post_path(@post)
|
40
|
-
end
|
41
|
-
else
|
42
|
-
flash.now[:danger] = 'Unable to create post'
|
43
|
-
render :action => :new
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def edit
|
48
|
-
@post = Effective::Post.find(params[:id])
|
49
|
-
@page_title = 'Edit Post'
|
50
|
-
|
51
|
-
authorize_effective_posts!
|
52
|
-
end
|
53
|
-
|
54
|
-
def update
|
55
|
-
@post = Effective::Post.find(params[:id])
|
56
|
-
@page_title = 'Edit Post'
|
57
|
-
|
58
|
-
authorize_effective_posts!
|
59
|
-
|
60
|
-
if @post.update_attributes(post_params)
|
61
|
-
if params[:commit] == 'Save and Edit Content'
|
62
|
-
redirect_to effective_regions.edit_path(effective_posts.post_path(@post), :exit => effective_posts.edit_admin_post_path(@post))
|
63
|
-
elsif params[:commit] == 'Save and Add New'
|
64
|
-
flash[:success] = 'Successfully updated post'
|
65
|
-
redirect_to effective_posts.new_admin_post_path
|
66
|
-
elsif params[:commit] == 'Save and View'
|
67
|
-
redirect_to effective_posts.post_path(@post)
|
68
|
-
elsif params[:commit] == 'Duplicate'
|
69
|
-
begin
|
70
|
-
post = @post.duplicate!
|
71
|
-
flash[:success] = 'Successfully saved and duplicated post.'
|
72
|
-
flash[:info] = "You are now editing the duplicated post. This new post has been created as a Draft."
|
73
|
-
rescue => e
|
74
|
-
flash.delete(:success)
|
75
|
-
flash[:danger] = "Unable to duplicate post: #{e.message}"
|
76
|
-
end
|
77
|
-
|
78
|
-
redirect_to effective_posts.edit_admin_post_path(post || @post)
|
79
|
-
else
|
80
|
-
flash[:success] = 'Successfully updated post'
|
81
|
-
redirect_to effective_posts.edit_admin_post_path(@post)
|
82
|
-
end
|
83
|
-
else
|
84
|
-
flash.now[:danger] = 'Unable to update post'
|
85
|
-
render :action => :edit
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def destroy
|
90
|
-
@post = Effective::Post.find(params[:id])
|
91
|
-
|
92
|
-
authorize_effective_posts!
|
93
|
-
|
94
|
-
if @post.destroy
|
95
|
-
flash[:success] = 'Successfully deleted post'
|
96
|
-
else
|
97
|
-
flash[:danger] = 'Unable to delete post'
|
98
|
-
end
|
99
|
-
|
100
|
-
redirect_to effective_posts.admin_posts_path
|
101
|
-
end
|
102
|
-
|
103
|
-
def approve
|
104
|
-
@post = Effective::Post.find(params[:id])
|
105
|
-
@page_title = 'Approve Post'
|
106
|
-
|
107
|
-
authorize_effective_posts!
|
108
|
-
|
109
|
-
if @post.update_attributes(draft: false)
|
110
|
-
flash[:success] = 'Successfully approved post. It is now displayed on the website.'
|
111
|
-
else
|
112
|
-
flash[:danger] = "Unable to approve post: #{@post.errors.full_messages.join(', ')}"
|
113
|
-
end
|
114
|
-
|
115
|
-
redirect_to(:back) rescue redirect_to(effective_posts.admin_posts_path)
|
116
|
-
end
|
117
|
-
|
118
|
-
def excerpts
|
119
|
-
@posts = Effective::Post.includes(:regions)
|
120
|
-
@page_title = 'Post Excerpts'
|
121
|
-
|
122
|
-
authorize_effective_posts!
|
8
|
+
if (config = EffectivePosts.layout)
|
9
|
+
layout(config.kind_of?(Hash) ? config[:admin] : config)
|
123
10
|
end
|
124
11
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
EffectivePosts.authorize!(self, :admin, :effective_posts)
|
129
|
-
EffectivePosts.authorize!(self, action_name.to_sym, @post || Effective::Post)
|
130
|
-
end
|
12
|
+
submit :save, 'Save'
|
13
|
+
submit :save, 'Save and View', redirect: -> { effective_posts.post_path(resource) }
|
14
|
+
submit :save, 'Duplicate', redirect: -> { effective_posts.new_admin_post_path(duplicate_id: resource.id) }
|
131
15
|
|
132
16
|
def post_params
|
133
|
-
params.require(:effective_post).permit
|
17
|
+
params.require(:effective_post).permit!
|
134
18
|
end
|
135
19
|
|
136
20
|
end
|
@@ -1,15 +1,21 @@
|
|
1
1
|
module Effective
|
2
2
|
class PostsController < ApplicationController
|
3
|
-
|
3
|
+
if defined?(Devise)
|
4
|
+
before_action :authenticate_user!, only: [:new, :create, :edit, :update],
|
5
|
+
if: -> { EffectivePosts.submissions_require_current_user }
|
6
|
+
end
|
7
|
+
|
8
|
+
include Effective::CrudController
|
4
9
|
|
5
|
-
|
6
|
-
|
10
|
+
if (config = EffectivePosts.layout)
|
11
|
+
layout(config.kind_of?(Hash) ? (config[:application] || config[:posts]) : config)
|
12
|
+
end
|
7
13
|
|
8
14
|
def index
|
9
15
|
@posts ||= Effective::Post.posts(
|
10
16
|
user: current_user,
|
11
17
|
category: params[:category],
|
12
|
-
unpublished:
|
18
|
+
unpublished: EffectiveResources.authorized?(self, :admin, :effective_posts)
|
13
19
|
)
|
14
20
|
|
15
21
|
@posts = @posts.paginate(page: params[:page])
|
@@ -23,28 +29,27 @@ module Effective
|
|
23
29
|
@posts = @posts.where(search) if search.present?
|
24
30
|
end
|
25
31
|
|
26
|
-
|
32
|
+
EffectiveResources.authorize!(self, :index, Effective::Post)
|
27
33
|
|
28
34
|
@page_title ||= [(params[:category] || 'Blog').to_s.titleize, (" - Page #{params[:page]}" if params[:page])].compact.join
|
29
35
|
@canonical_url ||= helpers.effective_post_category_url(params[:category], page: params[:page])
|
30
36
|
end
|
31
37
|
|
32
38
|
def show
|
33
|
-
@posts ||= Effective::Post.posts(user: current_user, category: params[:category], unpublished:
|
39
|
+
@posts ||= Effective::Post.posts(user: current_user, category: params[:category], unpublished: EffectiveResources.authorized?(self, :admin, :effective_posts))
|
34
40
|
@post = @posts.find(params[:id])
|
35
41
|
|
36
42
|
if @post.respond_to?(:roles_permit?)
|
37
43
|
raise Effective::AccessDenied.new('Access Denied', :show, @post) unless @post.roles_permit?(current_user)
|
38
44
|
end
|
39
45
|
|
40
|
-
|
46
|
+
EffectiveResources.authorize!(self, :show, @post)
|
41
47
|
|
42
|
-
if
|
48
|
+
if EffectiveResources.authorized?(self, :admin, :effective_posts)
|
43
49
|
flash.now[:warning] = [
|
44
50
|
'Hi Admin!',
|
45
51
|
('You are viewing a hidden post.' unless @post.published?),
|
46
52
|
'Click here to',
|
47
|
-
("<a href='#{effective_regions.edit_path(effective_posts.post_path(@post, exit: effective_posts.post_path(@post)))}' class='alert-link' data-no-turbolink='true' data-turbolinks='false'>edit post content</a> or" unless admin_edit?),
|
48
53
|
("<a href='#{effective_posts.edit_admin_post_path(@post)}' class='alert-link'>edit post settings</a>.")
|
49
54
|
].compact.join(' ')
|
50
55
|
end
|
@@ -59,7 +64,7 @@ module Effective
|
|
59
64
|
@post ||= Effective::Post.new(published_at: Time.zone.now)
|
60
65
|
@page_title = 'New Post'
|
61
66
|
|
62
|
-
|
67
|
+
EffectiveResources.authorize!(self, :new, @post)
|
63
68
|
end
|
64
69
|
|
65
70
|
def create
|
@@ -67,7 +72,7 @@ module Effective
|
|
67
72
|
@post.user = current_user if defined?(current_user)
|
68
73
|
@post.draft = (EffectivePosts.submissions_require_approval == true)
|
69
74
|
|
70
|
-
|
75
|
+
EffectiveResources.authorize!(self, :create, @post)
|
71
76
|
|
72
77
|
if @post.save
|
73
78
|
@page_title ||= 'Post Submitted'
|
@@ -89,7 +94,7 @@ module Effective
|
|
89
94
|
@post ||= Effective::Post.find(params[:id])
|
90
95
|
@page_title ||= 'Edit Post'
|
91
96
|
|
92
|
-
|
97
|
+
EffectiveResources.authorize!(self, :edit, @post)
|
93
98
|
end
|
94
99
|
|
95
100
|
def update
|
@@ -97,7 +102,7 @@ module Effective
|
|
97
102
|
draft_was = @post.draft
|
98
103
|
@post.draft = (EffectivePosts.submissions_require_approval == true)
|
99
104
|
|
100
|
-
|
105
|
+
EffectiveResources.authorize!(self, :update, @post)
|
101
106
|
|
102
107
|
if @post.update_attributes(post_params)
|
103
108
|
@page_title ||= 'Post Submitted'
|
@@ -118,7 +123,7 @@ module Effective
|
|
118
123
|
def destroy
|
119
124
|
@post ||= Effective::Post.find(params[:id])
|
120
125
|
|
121
|
-
|
126
|
+
EffectiveResources.authorize!(self, :destroy, @post)
|
122
127
|
|
123
128
|
if @post.destroy
|
124
129
|
flash[:success] = 'Successfully deleted post'
|
@@ -136,7 +141,7 @@ module Effective
|
|
136
141
|
end
|
137
142
|
|
138
143
|
def admin_edit?
|
139
|
-
|
144
|
+
EffectiveResources.authorized?(self, :admin, :effective_posts) && (params[:edit].to_s == 'true')
|
140
145
|
end
|
141
146
|
|
142
147
|
end
|
@@ -25,7 +25,9 @@ class EffectivePostsDatatable < Effective::Datatable
|
|
25
25
|
|
26
26
|
col :created_at, label: 'Submitted at', visible: false
|
27
27
|
|
28
|
-
actions_col
|
28
|
+
actions_col do |post|
|
29
|
+
dropdown_link_to('View', effective_post_path(post), target: '_blank')
|
30
|
+
end
|
29
31
|
end
|
30
32
|
|
31
33
|
collection do
|
@@ -3,7 +3,7 @@ require 'cgi'
|
|
3
3
|
module EffectivePostsHelper
|
4
4
|
|
5
5
|
def effective_posts_header_tags
|
6
|
-
return unless @post
|
6
|
+
return unless @post && @post.kind_of?(Effective::Post) && @post.persisted?
|
7
7
|
|
8
8
|
@effective_pages_og_type = 'article'
|
9
9
|
|
@@ -69,7 +69,7 @@ module EffectivePostsHelper
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def admin_post_status_badge(post)
|
72
|
-
return nil unless
|
72
|
+
return nil unless EffectiveResources.authorized?(self, :admin, :effective_posts)
|
73
73
|
|
74
74
|
if post.draft?
|
75
75
|
content_tag(:span, 'DRAFT', class: 'badge badge-info')
|
@@ -78,29 +78,9 @@ module EffectivePostsHelper
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
# Only supported options are:
|
82
|
-
# :label => 'Read more' to set the label of the 'Read More' link
|
83
|
-
# :omission => '...' passed to the final text node's truncate
|
84
|
-
# :length => 200 to set the max inner_text length of the content
|
85
81
|
# All other options are passed to the link_to 'Read more'
|
86
|
-
def post_excerpt(post,
|
87
|
-
|
88
|
-
divider = content.index(Effective::Snippets::ReadMoreDivider::TOKEN)
|
89
|
-
excerpt = post.excerpt.to_s
|
90
|
-
|
91
|
-
read_more = (read_more_link && label.present?) ? readmore_link(post, label: label) : ''
|
92
|
-
|
93
|
-
html = (
|
94
|
-
if divider.present?
|
95
|
-
truncate_html(content, Effective::Snippets::ReadMoreDivider::TOKEN, '')
|
96
|
-
elsif length.present?
|
97
|
-
truncate_html(excerpt, length, omission)
|
98
|
-
else
|
99
|
-
excerpt
|
100
|
-
end
|
101
|
-
).html_safe
|
102
|
-
|
103
|
-
(html + read_more).html_safe
|
82
|
+
def post_excerpt(post, label: 'Continue reading')
|
83
|
+
(post.excerpt.to_s + readmore_link(post, label: label)).html_safe
|
104
84
|
end
|
105
85
|
|
106
86
|
def read_more_link(post, options = {})
|
@@ -10,7 +10,8 @@ module Effective
|
|
10
10
|
mail(
|
11
11
|
to: EffectivePosts.mailer[:admin_email],
|
12
12
|
from: EffectivePosts.mailer[:default_from],
|
13
|
-
subject: subject_for_post_submitted_to_admin(@post)
|
13
|
+
subject: subject_for_post_submitted_to_admin(@post),
|
14
|
+
tenant: (Tenant.current if defined?(Tenant))
|
14
15
|
)
|
15
16
|
end
|
16
17
|
|
@@ -1,55 +1,63 @@
|
|
1
1
|
module Effective
|
2
2
|
class Post < ActiveRecord::Base
|
3
|
-
|
3
|
+
attr_accessor :current_user
|
4
|
+
|
4
5
|
acts_as_slugged
|
5
6
|
|
6
|
-
if
|
7
|
-
|
8
|
-
end
|
7
|
+
log_changes if respond_to?(:log_changes)
|
8
|
+
acts_as_role_restricted if respond_to?(:acts_as_role_restricted)
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
has_one_attached :image
|
11
|
+
|
12
|
+
has_rich_text :excerpt
|
13
|
+
has_rich_text :body
|
13
14
|
|
14
15
|
self.table_name = EffectivePosts.posts_table_name.to_s
|
15
16
|
|
16
|
-
belongs_to :user, optional: true
|
17
|
+
belongs_to :user, polymorphic: true, optional: true
|
18
|
+
|
19
|
+
effective_resource do
|
20
|
+
title :string
|
21
|
+
description :string
|
17
22
|
|
18
|
-
|
19
|
-
|
20
|
-
# description :string
|
23
|
+
category :string
|
24
|
+
slug :string
|
21
25
|
|
22
|
-
|
26
|
+
draft :boolean
|
27
|
+
published_at :datetime
|
28
|
+
tags :text
|
23
29
|
|
24
|
-
|
30
|
+
roles_mask :integer
|
25
31
|
|
26
|
-
|
27
|
-
|
28
|
-
|
32
|
+
# Event Fields
|
33
|
+
start_at :datetime
|
34
|
+
end_at :datetime
|
29
35
|
|
30
|
-
|
36
|
+
location :string
|
37
|
+
website_name :string
|
38
|
+
website_href :string
|
31
39
|
|
32
|
-
|
33
|
-
|
34
|
-
# end_at :datetime
|
35
|
-
# location :string
|
36
|
-
# website_name :website_name
|
37
|
-
# website_href :website_href
|
40
|
+
timestamps
|
41
|
+
end
|
38
42
|
|
39
|
-
|
43
|
+
before_validation(if: -> { current_user.present? }) do
|
44
|
+
self.user ||= current_user
|
45
|
+
end
|
40
46
|
|
41
47
|
validates :title, presence: true, length: { maximum: 255 }
|
42
48
|
validates :description, presence: true, length: { maximum: 150 }
|
43
49
|
validates :category, presence: true
|
44
50
|
validates :published_at, presence: true
|
45
51
|
|
46
|
-
validates :start_at, presence: true, if: -> { category == 'events'}
|
52
|
+
validates :start_at, presence: true, if: -> { category == 'events' }
|
47
53
|
|
48
54
|
scope :drafts, -> { where(draft: true) }
|
49
55
|
scope :published, -> { where(draft: false).where("#{EffectivePosts.posts_table_name}.published_at < ?", Time.zone.now) }
|
50
56
|
scope :unpublished, -> { where(draft: true).or(where("#{EffectivePosts.posts_table_name}.published_at > ?", Time.zone.now)) }
|
51
57
|
scope :with_category, -> (category) { where(category: category.to_s.downcase) }
|
52
58
|
|
59
|
+
scope :deep, -> { with_rich_text_excerpt_and_embeds.with_rich_text_body_and_embeds }
|
60
|
+
|
53
61
|
scope :paginate, -> (page: nil, per_page: EffectivePosts.per_page) {
|
54
62
|
page = (page || 1).to_i
|
55
63
|
offset = [(page - 1), 0].max * per_page
|
@@ -58,7 +66,7 @@ module Effective
|
|
58
66
|
}
|
59
67
|
|
60
68
|
scope :posts, -> (user: nil, category: nil, unpublished: false) {
|
61
|
-
scope = all.
|
69
|
+
scope = all.deep.order(published_at: :desc)
|
62
70
|
|
63
71
|
if defined?(EffectiveRoles) && EffectivePosts.use_effective_roles
|
64
72
|
if user.present? && user.respond_to?(:roles)
|
@@ -77,16 +85,12 @@ module Effective
|
|
77
85
|
scope
|
78
86
|
}
|
79
87
|
|
80
|
-
def to_param
|
81
|
-
slug.presence || "#{id}-#{title.parameterize}"
|
82
|
-
end
|
83
|
-
|
84
88
|
def to_s
|
85
89
|
title.presence || 'New Post'
|
86
90
|
end
|
87
91
|
|
88
92
|
def published?
|
89
|
-
!draft? && published_at < Time.zone.now
|
93
|
+
!draft? && published_at.present? && published_at < Time.zone.now
|
90
94
|
end
|
91
95
|
|
92
96
|
def approved?
|
@@ -97,25 +101,18 @@ module Effective
|
|
97
101
|
category == 'events'
|
98
102
|
end
|
99
103
|
|
100
|
-
def body
|
101
|
-
region(:body).content
|
102
|
-
end
|
103
|
-
|
104
|
-
def body=(input)
|
105
|
-
region(:body).content = input
|
106
|
-
end
|
107
|
-
|
108
104
|
# 3.333 words/second is the default reading speed.
|
109
105
|
def time_to_read_in_seconds(reading_speed = 3.333)
|
110
106
|
(regions.to_a.sum { |region| (region.content || '').scan(/\w+/).size } / reading_speed).seconds
|
111
107
|
end
|
112
108
|
|
113
109
|
def send_post_submitted_to_admin!
|
114
|
-
|
110
|
+
deliver_method = EffectivePosts.mailer[:deliver_method] || raise('expected an EffectivePosts.deliver_method')
|
111
|
+
Effective::PostsMailer.post_submitted_to_admin(to_param).send(deliver_method)
|
115
112
|
end
|
116
113
|
|
117
114
|
# Returns a duplicated post object, or throws an exception
|
118
|
-
def duplicate
|
115
|
+
def duplicate
|
119
116
|
Post.new(attributes.except('id', 'updated_at', 'created_at')).tap do |post|
|
120
117
|
post.title = post.title + ' (Copy)'
|
121
118
|
post.slug = post.slug + '-copy'
|
@@ -124,26 +121,15 @@ module Effective
|
|
124
121
|
regions.each do |region|
|
125
122
|
post.regions.build(region.attributes.except('id', 'updated_at', 'created_at'))
|
126
123
|
end
|
127
|
-
|
128
|
-
post.save!
|
129
124
|
end
|
130
125
|
end
|
131
126
|
|
132
|
-
|
127
|
+
def duplicate!
|
128
|
+
duplicate.tap { |post| post.save! }
|
129
|
+
end
|
133
130
|
|
134
|
-
def
|
135
|
-
|
136
|
-
if EffectivePosts.mailer[:delayed_job_deliver] && EffectivePosts.mailer[:deliver_method] == :deliver_later
|
137
|
-
Effective::PostsMailer.delay.public_send(email, *mailer_args)
|
138
|
-
elsif EffectivePosts.mailer[:deliver_method].present?
|
139
|
-
Effective::PostsMailer.public_send(email, *mailer_args).public_send(EffectivePosts.mailer[:deliver_method])
|
140
|
-
else
|
141
|
-
Effective::PostsMailer.public_send(email, *mailer_args).deliver_now
|
142
|
-
end
|
143
|
-
rescue => e
|
144
|
-
raise e unless Rails.env.production?
|
145
|
-
return false
|
146
|
-
end
|
131
|
+
def approve!
|
132
|
+
update!(draft: false)
|
147
133
|
end
|
148
134
|
|
149
135
|
end
|
@@ -3,7 +3,13 @@
|
|
3
3
|
|
4
4
|
- if f.object.persisted? || f.object.errors.include?(:slug)
|
5
5
|
- current_url = effective_posts.post_path(f.object)
|
6
|
-
|
6
|
+
|
7
|
+
= f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages.'
|
8
|
+
|
9
|
+
= f.text_field :slug, required: f.object.persisted?,
|
10
|
+
hint: "The slug controls this post's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This post is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url && f.object.slug.present? }".html_safe
|
11
|
+
|
12
|
+
= f.text_field :description, hint: 'The content of the post meta tags.', maxlength: 150
|
7
13
|
|
8
14
|
- if Array(EffectivePosts.categories).length > 1
|
9
15
|
= f.select :category, EffectivePosts.categories
|
@@ -13,8 +19,7 @@
|
|
13
19
|
- if EffectivePosts.use_active_storage
|
14
20
|
= f.file_field :image, hint: 'An image for your post'
|
15
21
|
|
16
|
-
= f.
|
17
|
-
= f.text_field :description, hint: 'The content of the post meta tags.', maxlength: 150
|
22
|
+
= f.rich_text_area :body, hint: 'The main body of your post'
|
18
23
|
|
19
24
|
= render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
|
20
25
|
|
@@ -22,18 +27,12 @@
|
|
22
27
|
|
23
28
|
= f.check_box :draft, hint: 'Save this post as a draft. It will not be accessible on the website.'
|
24
29
|
|
25
|
-
- unless EffectivePosts.use_fullscreen_editor
|
26
|
-
= f.ck_editor :body, hint: 'The content of your post.'
|
27
|
-
|
28
30
|
- if defined?(EffectiveRoles) && f.object.respond_to?(:roles) && EffectivePosts.use_effective_roles
|
29
31
|
= render partial: '/admin/posts/roles', locals: { post: post, form: f, f: f }
|
30
32
|
|
31
33
|
= f.submit do
|
32
34
|
= f.save 'Save'
|
33
35
|
|
34
|
-
- if EffectivePosts.use_fullscreen_editor
|
35
|
-
= f.save 'Save and Edit Content', class: 'btn btn-secondary'
|
36
|
-
|
37
36
|
= f.save 'Save and View', class: 'btn btn-secondary'
|
38
37
|
|
39
38
|
- if f.object.persisted?
|
@@ -18,11 +18,10 @@
|
|
18
18
|
- if posts.length == 0
|
19
19
|
%li= link_to 'None', effective_posts.posts_path, class: 'disabled'
|
20
20
|
|
21
|
-
- if
|
21
|
+
- if EffectiveResources.authorized?(self, :admin, :effective_posts)
|
22
22
|
%h4.dashboard-title Admin
|
23
23
|
%ul.list-unstyled
|
24
24
|
%li= link_to 'All Posts', effective_posts.admin_posts_path
|
25
25
|
|
26
26
|
- if @post.present?
|
27
|
-
%li= link_to 'Edit Post Content', effective_regions.edit_path(effective_posts.post_path(@post, exit: effective_posts.post_path(@post)))
|
28
27
|
%li= link_to 'Edit Post Settings', effective_posts.edit_admin_post_path(@post)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
%p= EffectivePosts.submissions_note
|
4
4
|
|
5
|
-
- if
|
5
|
+
- if EffectiveResources.authorized?(controller, :edit, @post)
|
6
6
|
%p= link_to 'Edit Post', effective_posts.edit_post_path(@post), class: 'btn btn-primary btn-edit-post'
|
7
7
|
|
8
8
|
%hr
|
data/config/effective_posts.rb
CHANGED
@@ -29,39 +29,8 @@ EffectivePosts.setup do |config|
|
|
29
29
|
# The author is the user that created the Effective::Post object
|
30
30
|
config.post_meta_author = true
|
31
31
|
|
32
|
-
# Authorization Method
|
33
|
-
#
|
34
|
-
# This method is called by all controller actions with the appropriate action and resource
|
35
|
-
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
36
|
-
#
|
37
|
-
# Use via Proc (and with CanCan):
|
38
|
-
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
39
|
-
#
|
40
|
-
# Use via custom method:
|
41
|
-
# config.authorization_method = :my_authorization_method
|
42
|
-
#
|
43
|
-
# And then in your application_controller.rb:
|
44
|
-
#
|
45
|
-
# def my_authorization_method(action, resource)
|
46
|
-
# current_user.is?(:admin)
|
47
|
-
# end
|
48
|
-
#
|
49
|
-
# Or disable the check completely:
|
50
|
-
# config.authorization_method = false
|
51
|
-
config.authorization_method = Proc.new do |controller, action, resource|
|
52
|
-
authorize!(action, resource)
|
53
|
-
resource.respond_to?(:roles_permit?) ? resource.roles_permit?(current_user) : true
|
54
|
-
end
|
55
|
-
|
56
32
|
# Layout Settings
|
57
|
-
#
|
58
|
-
config.layout = {
|
59
|
-
posts: 'application',
|
60
|
-
admin: 'admin'
|
61
|
-
}
|
62
|
-
|
63
|
-
# Add additional permitted params
|
64
|
-
# config.permitted_params += [:additional_field]
|
33
|
+
# config.layout = { application: 'application', admin: 'admin' }
|
65
34
|
|
66
35
|
# Display the effective roles 'choose roles' input when an admin creates a new post
|
67
36
|
config.use_effective_roles = false
|
@@ -107,8 +76,7 @@ EffectivePosts.setup do |config|
|
|
107
76
|
default_from: 'info@example.com',
|
108
77
|
admin_email: 'admin@example.com',
|
109
78
|
|
110
|
-
deliver_method:
|
111
|
-
delayed_job_deliver: false
|
79
|
+
deliver_method: :deliver_now
|
112
80
|
}
|
113
81
|
|
114
82
|
end
|
data/config/routes.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
EffectivePosts::Engine.routes.draw do
|
2
2
|
namespace :admin do
|
3
|
-
resources :posts, except: [:show]
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
resources :posts, except: [:show] do
|
4
|
+
if EffectivePosts.submissions_enabled && EffectivePosts.submissions_require_approval
|
5
|
+
post :approve, on: :member
|
6
|
+
end
|
7
7
|
end
|
8
8
|
|
9
9
|
match 'posts/excerpts', to: 'posts#excerpts', via: :get
|
10
10
|
end
|
11
11
|
|
12
|
-
scope :
|
12
|
+
scope module: 'effective' do
|
13
13
|
categories = Array(EffectivePosts.categories).map { |cat| cat.to_s unless cat == 'posts'}.compact
|
14
14
|
onlies = ([:index, :show] unless EffectivePosts.submissions_enabled)
|
15
15
|
|
@@ -33,9 +33,6 @@ EffectivePosts::Engine.routes.draw do
|
|
33
33
|
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
unless Rails.application.routes.routes.find { |r| r.name == 'effective_posts' }
|
39
|
-
mount EffectivePosts::Engine => '/', :as => 'effective_posts'
|
40
|
-
end
|
36
|
+
Rails.application.routes.draw do
|
37
|
+
mount EffectivePosts::Engine => '/', :as => 'effective_posts'
|
41
38
|
end
|
data/lib/effective_posts.rb
CHANGED
@@ -1,64 +1,29 @@
|
|
1
|
-
require 'nokogiri'
|
2
1
|
require 'effective_datatables'
|
3
|
-
require '
|
2
|
+
require 'effective_resources'
|
4
3
|
require 'effective_posts/engine'
|
5
4
|
require 'effective_posts/version'
|
6
5
|
|
7
6
|
module EffectivePosts
|
8
|
-
mattr_accessor :posts_table_name
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
mattr_accessor :use_effective_roles
|
22
|
-
mattr_accessor :use_fullscreen_editor
|
23
|
-
mattr_accessor :use_active_storage
|
24
|
-
|
25
|
-
mattr_accessor :per_page
|
26
|
-
mattr_accessor :post_meta_author
|
27
|
-
|
28
|
-
mattr_accessor :submissions_enabled
|
29
|
-
mattr_accessor :submissions_require_current_user
|
30
|
-
mattr_accessor :submissions_require_approval
|
31
|
-
mattr_accessor :submissions_note
|
32
|
-
|
33
|
-
# These are hashes of configs
|
34
|
-
mattr_accessor :mailer
|
35
|
-
|
36
|
-
def self.setup
|
37
|
-
yield self
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.authorized?(controller, action, resource)
|
41
|
-
@_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
|
42
|
-
|
43
|
-
return !!authorization_method unless authorization_method.respond_to?(:call)
|
44
|
-
controller = controller.controller if controller.respond_to?(:controller)
|
45
|
-
|
46
|
-
begin
|
47
|
-
!!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
|
48
|
-
rescue *@_exceptions
|
49
|
-
false
|
50
|
-
end
|
8
|
+
def self.config_keys
|
9
|
+
[
|
10
|
+
:posts_table_name, :layout, :categories,
|
11
|
+
:use_category_routes, :use_blog_routes,
|
12
|
+
:use_effective_roles, :use_fullscreen_editor, :use_active_storage,
|
13
|
+
:per_page, :post_meta_author,
|
14
|
+
:submissions_enabled, :submissions_require_current_user,
|
15
|
+
:submissions_require_approval, :submissions_note,
|
16
|
+
:mailer
|
17
|
+
]
|
51
18
|
end
|
52
19
|
|
53
|
-
|
54
|
-
raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
|
55
|
-
end
|
20
|
+
include EffectiveGem
|
56
21
|
|
57
22
|
def self.permitted_params
|
58
|
-
|
23
|
+
[
|
59
24
|
:title, :excerpt, :description, :draft, :category, :slug, :published_at, :body, :tags, :extra,
|
60
25
|
:image, :start_at, :end_at, :location, :website_name, :website_href, roles: []
|
61
|
-
]
|
26
|
+
]
|
62
27
|
end
|
63
28
|
|
64
29
|
end
|
@@ -10,7 +10,7 @@ module EffectivePosts
|
|
10
10
|
end
|
11
11
|
|
12
12
|
# Set up our default configuration options.
|
13
|
-
initializer "effective_posts.defaults", :
|
13
|
+
initializer "effective_posts.defaults", before: :load_config_initializers do |app|
|
14
14
|
# Set up our defaults, as per our initializer template
|
15
15
|
eval File.read("#{config.root}/config/effective_posts.rb")
|
16
16
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_posts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: '6'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: '6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: sass
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -38,20 +38,6 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: nokogiri
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: effective_bootstrap
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,7 +53,7 @@ dependencies:
|
|
67
53
|
- !ruby/object:Gem::Version
|
68
54
|
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
56
|
+
name: effective_resources
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
@@ -82,34 +68,6 @@ dependencies:
|
|
82
68
|
version: '0'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: effective_datatables
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: 4.0.0
|
90
|
-
type: :runtime
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: 4.0.0
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: effective_regions
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '0'
|
104
|
-
type: :runtime
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: effective_resources
|
113
71
|
requirement: !ruby/object:Gem::Requirement
|
114
72
|
requirements:
|
115
73
|
- - ">="
|
@@ -132,7 +90,6 @@ extra_rdoc_files: []
|
|
132
90
|
files:
|
133
91
|
- MIT-LICENSE
|
134
92
|
- README.md
|
135
|
-
- app/assets/javascripts/effective/snippets/read_more_divider.js.coffee
|
136
93
|
- app/assets/javascripts/effective_posts.js
|
137
94
|
- app/assets/javascripts/effective_posts/additional_fields.js.coffee
|
138
95
|
- app/assets/stylesheets/effective_posts.scss
|
@@ -140,18 +97,12 @@ files:
|
|
140
97
|
- app/controllers/effective/posts_controller.rb
|
141
98
|
- app/datatables/effective_posts_datatable.rb
|
142
99
|
- app/helpers/effective_posts_helper.rb
|
143
|
-
- app/helpers/effective_truncate_html_helper.rb
|
144
100
|
- app/mailers/effective/posts_mailer.rb
|
145
|
-
- app/models/effective/access_denied.rb
|
146
101
|
- app/models/effective/post.rb
|
147
|
-
- app/models/effective/snippets/read_more_divider.rb
|
148
|
-
- app/views/admin/posts/_actions.html.haml
|
149
102
|
- app/views/admin/posts/_form.html.haml
|
150
103
|
- app/views/admin/posts/_roles.html.haml
|
151
|
-
- app/views/admin/posts/edit.html.haml
|
152
104
|
- app/views/admin/posts/excerpts.html.haml
|
153
105
|
- app/views/admin/posts/index.html.haml
|
154
|
-
- app/views/admin/posts/new.html.haml
|
155
106
|
- app/views/effective/posts/_additional_fields.html.haml
|
156
107
|
- app/views/effective/posts/_categories.html.haml
|
157
108
|
- app/views/effective/posts/_event.html.haml
|
@@ -168,7 +119,6 @@ files:
|
|
168
119
|
- app/views/effective/posts/show.html.haml
|
169
120
|
- app/views/effective/posts/submitted.html.haml
|
170
121
|
- app/views/effective/posts_mailer/post_submitted_to_admin.html.haml
|
171
|
-
- app/views/effective/snippets/_read_more_divider.html.haml
|
172
122
|
- app/views/layouts/effective_posts_mailer_layout.html.haml
|
173
123
|
- config/effective_posts.rb
|
174
124
|
- config/routes.rb
|
@@ -1,22 +0,0 @@
|
|
1
|
-
CKEDITOR.dialog.add 'read_more_divider', (editor) -> # Must match the class name of the snippet
|
2
|
-
title: 'Read more divider',
|
3
|
-
minWidth: 200,
|
4
|
-
minHeight: 100,
|
5
|
-
contents: [
|
6
|
-
{
|
7
|
-
id: 'read_more_info', # Just an html id, doesn't really matter what is here
|
8
|
-
elements: [
|
9
|
-
{
|
10
|
-
id: 'throwaway'
|
11
|
-
type: 'html',
|
12
|
-
html: 'Insert a read more divider to separate excerpt content from the full content.',
|
13
|
-
setup: (widget) -> this.setValue(widget.data.throwaway)
|
14
|
-
commit: (widget) -> widget.setData('throwaway', 'throwaway')
|
15
|
-
},
|
16
|
-
{
|
17
|
-
type: 'html',
|
18
|
-
html: 'Anything above the read more divider will be treated as excerpt content<br>and everything below the divider will also be included in the full content.'
|
19
|
-
}
|
20
|
-
]
|
21
|
-
}
|
22
|
-
]
|
@@ -1,73 +0,0 @@
|
|
1
|
-
module EffectiveTruncateHtmlHelper
|
2
|
-
# Truncates HTML or text to a certain inner_text character limit.
|
3
|
-
#
|
4
|
-
# If given HTML, the underlying markup may be much longer than length, but the displayed text
|
5
|
-
# will be no longer than (length + omission) characters.
|
6
|
-
def truncate_html(text, length_or_content = 200, omission = '...')
|
7
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(text)
|
8
|
-
|
9
|
-
if length_or_content.kind_of?(String)
|
10
|
-
content = (Nokogiri::HTML::DocumentFragment.parse(length_or_content).children.first.inner_text rescue length_or_content)
|
11
|
-
doc.tap { |doc| _truncate_node_to_content(doc, content, omission) }.inner_html
|
12
|
-
elsif length_or_content.kind_of?(Integer)
|
13
|
-
doc.tap { |doc| _truncate_node_to_length(doc, length_or_content, omission) }.inner_html
|
14
|
-
else
|
15
|
-
raise 'Unsupported datatype passed to second argument of truncate_html. Expecting integer or string.'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def _truncate_node_to_content(node, content, omission, seen = false)
|
20
|
-
if seen == true
|
21
|
-
node.remove
|
22
|
-
elsif node.children.blank?
|
23
|
-
index = node.content.index(content)
|
24
|
-
|
25
|
-
if index.present?
|
26
|
-
if node.parent.try(:content) == content # If my parent node just has my text in it, remove parent node too
|
27
|
-
node.parent.remove
|
28
|
-
elsif index == 0
|
29
|
-
node.remove
|
30
|
-
else
|
31
|
-
node.content = truncate(node.content, length: index+omission.to_s.length, separator: ' ', omission: omission)
|
32
|
-
end
|
33
|
-
|
34
|
-
seen = true
|
35
|
-
end
|
36
|
-
else
|
37
|
-
node.children.each { |child| seen = _truncate_node_to_content(child, content, omission, seen) }
|
38
|
-
end
|
39
|
-
|
40
|
-
seen
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
def _truncate_node_to_length(node, length, omission)
|
45
|
-
if node.inner_text.length <= length
|
46
|
-
# Do nothing, we're already reached base case
|
47
|
-
elsif node.name == 'a'
|
48
|
-
node.remove # I don't want to truncate anything in a link
|
49
|
-
elsif node.children.blank?
|
50
|
-
# I need to truncate myself, and I'm certainly a text node
|
51
|
-
if node.text?
|
52
|
-
node.content = truncate(node.content, length: length+omission.to_s.length, separator: ' ', omission: omission)
|
53
|
-
else
|
54
|
-
node.remove
|
55
|
-
end
|
56
|
-
else # Go through all the children, and delete anything after the length has been reached
|
57
|
-
child_length = 0
|
58
|
-
|
59
|
-
node.children.each do |child|
|
60
|
-
child_length > length ? (child.remove) : (child_length += child.inner_text.length)
|
61
|
-
end
|
62
|
-
|
63
|
-
# We have now removed all nodes after length, but the last node is longer than our length
|
64
|
-
# child_length is the inner_text length of all included nodes
|
65
|
-
# And we only have to truncate the last child to get under length
|
66
|
-
|
67
|
-
child = node.children.last
|
68
|
-
child_max_length = length - (child_length - child.inner_text.length)
|
69
|
-
|
70
|
-
_truncate_node_to_length(child, child_max_length, omission)
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
unless defined?(Effective::AccessDenied)
|
2
|
-
module Effective
|
3
|
-
class AccessDenied < StandardError
|
4
|
-
attr_reader :action, :subject
|
5
|
-
|
6
|
-
def initialize(message = nil, action = nil, subject = nil)
|
7
|
-
@message = message
|
8
|
-
@action = action
|
9
|
-
@subject = subject
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_s
|
13
|
-
@message || I18n.t(:'unauthorized.default', :default => 'Access Denied')
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
= dropdown(variation: :dropleft) do
|
2
|
-
- if datatable.admin_namespace?
|
3
|
-
- if EffectivePosts.submissions_enabled && EffectivePosts.submissions_require_approval && !post.approved?
|
4
|
-
= dropdown_link_to 'Approve', effective_posts.admin_approve_post_path(post)
|
5
|
-
|
6
|
-
= dropdown_link_to 'Edit', effective_posts.edit_admin_post_path(post)
|
7
|
-
- if EffectivePosts.use_fullscreen_editor
|
8
|
-
= dropdown_link_to 'Edit Content', effective_post_path(post, edit: true), title: 'Edit Content', 'data-no-turbolink': true, 'data-turbolinks': false, target: '_blank'
|
9
|
-
|
10
|
-
= dropdown_link_to 'View', effective_post_path(post), target: '_blank'
|
11
|
-
|
12
|
-
= dropdown_link_to "Delete", effective_posts.admin_post_path(post),
|
13
|
-
data: { method: :delete, confirm: "Really delete #{post}?" }
|
@@ -1,9 +0,0 @@
|
|
1
|
-
- if effectively_editting?
|
2
|
-
%p.show-block-adjust{:style => 'border-top: 2px dashed black; text-align: center;', :title => 'anything above this line will be treated as excerpt content'}
|
3
|
-
%span{:style => 'background: #ddd; display: inline-block; padding: 0px 6px 4px 6px; border-radius: 0px 0px 10px 10px;'}
|
4
|
-
Read more...
|
5
|
-
- else
|
6
|
-
= Effective::Snippets::ReadMoreDivider::TOKEN.html_safe
|
7
|
-
|
8
|
-
|
9
|
-
|