effective_posts 0.7.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/MIT-LICENSE +1 -1
- data/README.md +9 -1
- data/app/assets/javascripts/effective/snippets/read_more_divider.js.coffee +22 -0
- data/app/assets/javascripts/effective_posts.js +1 -1
- data/app/controllers/admin/posts_controller.rb +5 -5
- data/app/controllers/effective/posts_controller.rb +12 -14
- data/app/helpers/effective_posts_helper.rb +19 -5
- data/app/mailers/effective/posts_mailer.rb +24 -7
- data/app/models/effective/access_denied.rb +17 -0
- data/app/models/effective/datatables/posts.rb +39 -0
- data/app/models/effective/post.rb +23 -18
- data/app/models/effective/snippets/read_more_divider.rb +9 -0
- data/app/views/admin/posts/_actions.html.haml +10 -13
- data/app/views/admin/posts/_form.html.haml +13 -24
- data/app/views/effective/posts/_additional_fields.html.haml +10 -12
- data/app/views/effective/posts/_form.html.haml +13 -19
- data/app/views/effective/posts/submitted.html.haml +2 -2
- data/app/views/effective/posts_mailer/post_submitted_to_admin.html.haml +2 -2
- data/config/effective_posts.rb +47 -27
- data/lib/effective_posts/engine.rb +2 -5
- data/lib/effective_posts/version.rb +1 -1
- data/lib/effective_posts.rb +38 -15
- data/lib/generators/effective_posts/install_generator.rb +1 -1
- metadata +17 -29
- data/Rakefile +0 -24
- data/app/assets/config/effective_posts_manifest.js +0 -2
- data/app/helpers/effective_kaminari_helper.rb +0 -16
- /data/app/assets/javascripts/{effective_posts → effective_pages}/additional_fields.js.coffee +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c022efd2bcc520c8c917470ed78cfc6d59383a6d
|
4
|
+
data.tar.gz: 7b0e965d6149141d91764bff9405ba0bf5407d17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fdd4fe4cbb4e0a5bd4ca0d965464bea38a54075470cd326529d9b3d297626dc1235a14292aa90093b99863d91a5596adc58b27e667c309f883303967fece7ca
|
7
|
+
data.tar.gz: fcc25d31d20948003c2759801034cf981a522a3e5cc8541751e11f46bad4552ecbd9abab7fb769f2317b4464c2b705e36a64bcc0f8c07bf5631574f889fab35b
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
@@ -7,11 +7,19 @@ Built ontop of effective_regions for post content entry and Kaminari for paginat
|
|
7
7
|
Rails 3.2.x and 4.x
|
8
8
|
|
9
9
|
|
10
|
+
## effective_posts 1.0
|
11
|
+
|
12
|
+
This is the 1.0 series of effective_posts.
|
13
|
+
|
14
|
+
This requires Twitter Bootstrap 4 and Rails 5.1+
|
15
|
+
|
16
|
+
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.
|
17
|
+
|
10
18
|
## Getting Started
|
11
19
|
|
12
20
|
Please first install the [effective_regions](https://github.com/code-and-effect/effective_regions) and [effective_datatables](https://github.com/code-and-effect/effective_datatables) gems.
|
13
21
|
|
14
|
-
Please download and install [Twitter
|
22
|
+
Please download and install [Twitter Bootstrap4](http://getbootstrap.com)
|
15
23
|
|
16
24
|
Add to your Gemfile:
|
17
25
|
|
@@ -0,0 +1,22 @@
|
|
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 +1 @@
|
|
1
|
-
//= require
|
1
|
+
//= require effective_pages/additional_fields
|
@@ -55,7 +55,7 @@ module Admin
|
|
55
55
|
|
56
56
|
authorize_effective_posts!
|
57
57
|
|
58
|
-
if @post.
|
58
|
+
if @post.update_attributes(post_params)
|
59
59
|
if params[:commit] == 'Save and Edit Content'
|
60
60
|
redirect_to effective_regions.edit_path(effective_posts.post_path(@post), :exit => effective_posts.edit_admin_post_path(@post))
|
61
61
|
elsif params[:commit] == 'Save and Add New'
|
@@ -102,7 +102,7 @@ module Admin
|
|
102
102
|
|
103
103
|
authorize_effective_posts!
|
104
104
|
|
105
|
-
if @post.
|
105
|
+
if @post.update_attributes(draft: false)
|
106
106
|
flash[:success] = 'Successfully approved post. It is now displayed on the website.'
|
107
107
|
else
|
108
108
|
flash[:danger] = "Unable to approve post: #{@post.errors.full_messages.join(', ')}"
|
@@ -121,12 +121,12 @@ module Admin
|
|
121
121
|
private
|
122
122
|
|
123
123
|
def authorize_effective_posts!
|
124
|
-
|
125
|
-
|
124
|
+
EffectivePosts.authorize!(self, :admin, :effective_posts)
|
125
|
+
EffectivePosts.authorize!(self, action_name.to_sym, @post || Effective::Post)
|
126
126
|
end
|
127
127
|
|
128
128
|
def post_params
|
129
|
-
params.require(:effective_post).permit
|
129
|
+
params.require(:effective_post).permit(EffectivePosts.permitted_params)
|
130
130
|
end
|
131
131
|
|
132
132
|
end
|
@@ -5,8 +5,6 @@ module Effective
|
|
5
5
|
before_action :authenticate_user!, only: [:new, :create, :edit, :update],
|
6
6
|
if: -> { EffectivePosts.submissions_require_current_user }
|
7
7
|
|
8
|
-
after_action :monkey_patch_for_kaminari, only: [:index]
|
9
|
-
|
10
8
|
def index
|
11
9
|
@posts ||= Effective::Post.posts(user: current_user, category: params[:category])
|
12
10
|
@posts = @posts.page(params[:page]).per(EffectivePosts.per_page)
|
@@ -20,7 +18,7 @@ module Effective
|
|
20
18
|
@posts = @posts.where(search) if search.present?
|
21
19
|
end
|
22
20
|
|
23
|
-
|
21
|
+
EffectivePosts.authorize!(self, :index, Effective::Post)
|
24
22
|
|
25
23
|
@page_title = (params[:page_title] || params[:category] || params[:defaults].try(:[], :category) || 'Posts').titleize
|
26
24
|
end
|
@@ -29,7 +27,11 @@ module Effective
|
|
29
27
|
@posts ||= Effective::Post.posts(user: current_user, category: params[:category], drafts: (params[:edit].to_s == 'true' || params[:preview].to_s == 'true'))
|
30
28
|
@post = @posts.find(params[:id])
|
31
29
|
|
32
|
-
|
30
|
+
if @post.respond_to?(:roles_permit?)
|
31
|
+
raise Effective::AccessDenied.new('Access Denied', :show, @post) unless @post.roles_permit?(current_user)
|
32
|
+
end
|
33
|
+
|
34
|
+
EffectivePosts.authorize!(self, :show, @post)
|
33
35
|
|
34
36
|
@page_title = @post.title
|
35
37
|
end
|
@@ -39,7 +41,7 @@ module Effective
|
|
39
41
|
@post ||= Effective::Post.new(published_at: Time.zone.now)
|
40
42
|
@page_title = 'New Post'
|
41
43
|
|
42
|
-
|
44
|
+
EffectivePosts.authorize!(self, :new, @post)
|
43
45
|
end
|
44
46
|
|
45
47
|
def create
|
@@ -47,7 +49,7 @@ module Effective
|
|
47
49
|
@post.user = current_user if defined?(current_user)
|
48
50
|
@post.draft = (EffectivePosts.submissions_require_approval == true)
|
49
51
|
|
50
|
-
|
52
|
+
EffectivePosts.authorize!(self, :create, @post)
|
51
53
|
|
52
54
|
if @post.save
|
53
55
|
@page_title ||= 'Post Submitted'
|
@@ -69,7 +71,7 @@ module Effective
|
|
69
71
|
@post ||= Effective::Post.find(params[:id])
|
70
72
|
@page_title ||= 'Edit Post'
|
71
73
|
|
72
|
-
|
74
|
+
EffectivePosts.authorize!(self, :edit, @post)
|
73
75
|
end
|
74
76
|
|
75
77
|
def update
|
@@ -77,9 +79,9 @@ module Effective
|
|
77
79
|
draft_was = @post.draft
|
78
80
|
@post.draft = (EffectivePosts.submissions_require_approval == true)
|
79
81
|
|
80
|
-
|
82
|
+
EffectivePosts.authorize!(self, :update, @post)
|
81
83
|
|
82
|
-
if @post.
|
84
|
+
if @post.update_attributes(post_params)
|
83
85
|
@page_title ||= 'Post Submitted'
|
84
86
|
flash.now[:success] = 'Successfully re-submitted post'
|
85
87
|
|
@@ -98,7 +100,7 @@ module Effective
|
|
98
100
|
def destroy
|
99
101
|
@post ||= Effective::Post.find(params[:id])
|
100
102
|
|
101
|
-
|
103
|
+
EffectivePosts.authorize!(self, :destroy, @post)
|
102
104
|
|
103
105
|
if @post.destroy
|
104
106
|
flash[:success] = 'Successfully deleted post'
|
@@ -115,9 +117,5 @@ module Effective
|
|
115
117
|
params.require(:effective_post).permit(EffectivePosts.permitted_params)
|
116
118
|
end
|
117
119
|
|
118
|
-
def monkey_patch_for_kaminari
|
119
|
-
@template = @template.tap { |template| template.extend(EffectiveKaminariHelper) }
|
120
|
-
end
|
121
|
-
|
122
120
|
end
|
123
121
|
end
|
@@ -8,7 +8,20 @@ module EffectivePostsHelper
|
|
8
8
|
if EffectivePosts.use_category_routes
|
9
9
|
effective_posts.post_path(post, opts).sub('/posts', "/#{category}")
|
10
10
|
else
|
11
|
-
effective_posts.post_path(post, opts)
|
11
|
+
effective_posts.post_path(post, opts.merge(category: category))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def effective_post_category_path(category, opts = nil)
|
16
|
+
return effective_posts.posts_path unless category.present?
|
17
|
+
|
18
|
+
category = category.to_s.downcase
|
19
|
+
opts ||= {}
|
20
|
+
|
21
|
+
if EffectivePosts.use_category_routes
|
22
|
+
"/#{category}"
|
23
|
+
else
|
24
|
+
effective_posts.posts_path(opts.merge(category: category))
|
12
25
|
end
|
13
26
|
end
|
14
27
|
|
@@ -16,12 +29,13 @@ module EffectivePostsHelper
|
|
16
29
|
render(partial: 'effective/posts/post', locals: { post: post })
|
17
30
|
end
|
18
31
|
|
19
|
-
def post_meta(post)
|
32
|
+
def post_meta(post, date: true, datetime: false, category: true, author: true)
|
20
33
|
[
|
21
34
|
'Published',
|
22
|
-
"on #{post.published_at.strftime('%B %d, %Y
|
23
|
-
("
|
24
|
-
("
|
35
|
+
("on #{post.published_at.strftime('%B %d, %Y')}" if date),
|
36
|
+
("on #{post.published_at.strftime('%B %d, %Y at %l:%M %p')}" if datetime),
|
37
|
+
("to #{link_to_post_category(post.category)}" if category && Array(EffectivePosts.categories).length > 1),
|
38
|
+
("by #{post.user.to_s.presence || 'Unknown'}" if author && EffectivePosts.post_meta_author && post.user.present?)
|
25
39
|
].compact.join(' ').html_safe
|
26
40
|
end
|
27
41
|
|
@@ -1,17 +1,34 @@
|
|
1
1
|
module Effective
|
2
|
-
class PostsMailer <
|
3
|
-
include EffectiveMailer
|
4
|
-
|
2
|
+
class PostsMailer < ActionMailer::Base
|
5
3
|
helper EffectivePostsHelper
|
6
4
|
|
7
|
-
|
5
|
+
layout EffectivePosts.mailer[:layout].presence || 'effective_posts_mailer_layout'
|
6
|
+
|
7
|
+
def post_submitted_to_admin(post_param)
|
8
8
|
@post = (post_param.kind_of?(Effective::Post) ? post_param : Effective::Post.find(post_param))
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
mail(
|
11
|
+
to: EffectivePosts.mailer[:admin_email],
|
12
|
+
from: EffectivePosts.mailer[:default_from],
|
13
|
+
subject: subject_for_post_submitted_to_admin(@post)
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
12
18
|
|
13
|
-
|
19
|
+
def subject_for_post_submitted_to_admin(post)
|
20
|
+
string_or_callable = EffectivePosts.mailer[:subject_for_post_submitted_to_admin]
|
21
|
+
|
22
|
+
if string_or_callable.respond_to?(:call) # This is a Proc or a function, not a string
|
23
|
+
string_or_callable = self.instance_exec(post, &string_or_callable)
|
24
|
+
end
|
25
|
+
|
26
|
+
prefix_subject(string_or_callable.presence || "A new post has been submitted that needs approval")
|
14
27
|
end
|
15
28
|
|
29
|
+
def prefix_subject(text)
|
30
|
+
prefix = (EffectivePosts.mailer[:subject_prefix].to_s rescue '')
|
31
|
+
prefix.present? ? (prefix.chomp(' ') + ' ' + text) : text
|
32
|
+
end
|
16
33
|
end
|
17
34
|
end
|
@@ -0,0 +1,17 @@
|
|
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
|
@@ -0,0 +1,39 @@
|
|
1
|
+
if Gem::Version.new(EffectiveDatatables::VERSION) < Gem::Version.new('3.0')
|
2
|
+
module Effective
|
3
|
+
module Datatables
|
4
|
+
class Posts < Effective::Datatable
|
5
|
+
datatable do
|
6
|
+
default_order :published_at, :desc
|
7
|
+
|
8
|
+
table_column :published_at
|
9
|
+
table_column :id, visible: false
|
10
|
+
|
11
|
+
table_column :title
|
12
|
+
table_column :category, filter: { type: :select, values: EffectivePosts.categories }
|
13
|
+
|
14
|
+
if EffectivePosts.submissions_enabled
|
15
|
+
table_column :approved, column: 'NOT(draft)', as: :boolean do |post|
|
16
|
+
post.draft ? 'No' : 'Yes'
|
17
|
+
end
|
18
|
+
|
19
|
+
table_column :draft, visible: false
|
20
|
+
else
|
21
|
+
table_column :draft
|
22
|
+
end
|
23
|
+
|
24
|
+
table_column :start_at
|
25
|
+
table_column :end_at, visible: false
|
26
|
+
table_column :location, visible: false
|
27
|
+
|
28
|
+
table_column :created_at, label: 'Submitted at', visible: false
|
29
|
+
|
30
|
+
table_column :actions, sortable: false, filter: false, partial: '/admin/posts/actions'
|
31
|
+
end
|
32
|
+
|
33
|
+
def collection
|
34
|
+
Effective::Post.all
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,12 +1,11 @@
|
|
1
1
|
module Effective
|
2
2
|
class Post < ActiveRecord::Base
|
3
|
-
acts_as_role_restricted if defined?(EffectiveRoles)
|
4
|
-
acts_as_asset_box :image if defined?(EffectiveAssets)
|
3
|
+
acts_as_role_restricted if defined?(EffectiveRoles) && EffectivePosts.use_effective_roles
|
5
4
|
acts_as_regionable
|
6
5
|
|
7
6
|
self.table_name = EffectivePosts.posts_table_name.to_s
|
8
7
|
|
9
|
-
belongs_to :user
|
8
|
+
belongs_to :user
|
10
9
|
|
11
10
|
# Attributes
|
12
11
|
# title :string
|
@@ -33,20 +32,19 @@ module Effective
|
|
33
32
|
|
34
33
|
scope :drafts, -> { where(draft: true) }
|
35
34
|
scope :published, -> { where(draft: false).where("#{EffectivePosts.posts_table_name}.published_at < ?", Time.zone.now) }
|
35
|
+
scope :with_category, -> (category) { where(category: category.to_s.downcase) }
|
36
36
|
|
37
37
|
scope :posts, -> (user: nil, category: nil, drafts: false) {
|
38
|
-
scope = includes(:regions).order(published_at: :desc)
|
38
|
+
scope = all.includes(:regions).order(published_at: :desc)
|
39
39
|
|
40
|
-
if defined?(
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
if user.present? && user.respond_to?(:roles) && defined?(EffectiveRoles)
|
45
|
-
scope = scope.for_role(user.roles)
|
40
|
+
if defined?(EffectiveRoles) && EffectivePosts.use_effective_roles
|
41
|
+
if user.present? && user.respond_to?(:roles)
|
42
|
+
scope = scope.for_role(user.roles)
|
43
|
+
end
|
46
44
|
end
|
47
45
|
|
48
46
|
if category.present?
|
49
|
-
scope = scope.
|
47
|
+
scope = scope.with_category(category)
|
50
48
|
end
|
51
49
|
|
52
50
|
if drafts.blank?
|
@@ -86,7 +84,7 @@ module Effective
|
|
86
84
|
end
|
87
85
|
|
88
86
|
def send_post_submitted_to_admin!
|
89
|
-
send_email(:post_submitted_to_admin)
|
87
|
+
send_email(:post_submitted_to_admin, to_param)
|
90
88
|
end
|
91
89
|
|
92
90
|
# Returns a duplicated post object, or throws an exception
|
@@ -95,10 +93,6 @@ module Effective
|
|
95
93
|
post.title = post.title + ' (Copy)'
|
96
94
|
post.draft = true
|
97
95
|
|
98
|
-
if defined?(EffectiveAssets) && image.present?
|
99
|
-
post.add_to_asset_box(:image, image)
|
100
|
-
end
|
101
|
-
|
102
96
|
regions.each do |region|
|
103
97
|
post.regions.build(region.attributes.except('id', 'updated_at', 'created_at'))
|
104
98
|
end
|
@@ -109,8 +103,19 @@ module Effective
|
|
109
103
|
|
110
104
|
private
|
111
105
|
|
112
|
-
def send_email(email)
|
113
|
-
|
106
|
+
def send_email(email, *mailer_args)
|
107
|
+
begin
|
108
|
+
if EffectivePosts.mailer[:delayed_job_deliver] && EffectivePosts.mailer[:deliver_method] == :deliver_later
|
109
|
+
Effective::PostsMailer.delay.public_send(email, *mailer_args)
|
110
|
+
elsif EffectivePosts.mailer[:deliver_method].present?
|
111
|
+
Effective::PostsMailer.public_send(email, *mailer_args).public_send(EffectivePosts.mailer[:deliver_method])
|
112
|
+
else
|
113
|
+
Effective::PostsMailer.public_send(email, *mailer_args).deliver_now
|
114
|
+
end
|
115
|
+
rescue => e
|
116
|
+
raise e unless Rails.env.production?
|
117
|
+
return false
|
118
|
+
end
|
114
119
|
end
|
115
120
|
|
116
121
|
end
|
@@ -1,16 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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)
|
4
5
|
|
5
|
-
=
|
6
|
-
|
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, target: '_blank'
|
7
9
|
|
8
|
-
=
|
9
|
-
%span.glyphicon.glyphicon-eye-open
|
10
|
+
= dropdown_link_to 'View', effective_post_path(post, preview: true), target: '_blank'
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
%span.glyphicon.glyphicon-edit
|
14
|
-
|
15
|
-
= link_to effective_posts.admin_post_path(post.id), title: 'Delete', data: { method: :delete, confirm: 'Are you sure you want to delete? This cannot be undone.' } do
|
16
|
-
%span.glyphicon.glyphicon-trash
|
12
|
+
= dropdown_link_to "Delete", effective_posts.admin_post_path(post),
|
13
|
+
data: { method: :delete, confirm: "Really delete #{post}?" }
|
@@ -1,36 +1,25 @@
|
|
1
|
-
=
|
2
|
-
= f.
|
1
|
+
= effective_form_with(model: post, url: post.persisted? ? effective_posts.admin_post_path(post.id) : effective_posts.admin_posts_path) do |f|
|
2
|
+
= f.text_field :title, hint: 'The title of your post.'
|
3
3
|
|
4
4
|
- if Array(EffectivePosts.categories).length > 1
|
5
|
-
= f.
|
6
|
-
as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
|
7
|
-
collection: EffectivePosts.categories,
|
8
|
-
include_blank: false
|
5
|
+
= f.select :category, EffectivePosts.categories
|
9
6
|
- else
|
10
|
-
= f.
|
7
|
+
= f.hidden_field :category, (EffectivePosts.categories.first || 'posts')
|
11
8
|
|
12
9
|
= render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
|
13
10
|
|
14
|
-
= f.
|
11
|
+
= f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
|
15
12
|
|
16
|
-
= f.
|
17
|
-
as: (defined?(EffectiveFormInputs) ? :effective_date_time_picker : :datetime),
|
18
|
-
label: 'Publish date',
|
19
|
-
hint: 'When your post will be displayed on the website.'
|
13
|
+
= f.check_box :draft, hint: 'Save this post as a draft. It will not be accessible on the website.'
|
20
14
|
|
21
|
-
= f.
|
22
|
-
as: (defined?(EffectiveFormInputs) ? :effective_ckeditor_text_area : :text),
|
23
|
-
hint: 'The body of your post.',
|
24
|
-
toolbar: 'full',
|
25
|
-
required: true
|
15
|
+
= f.editor :body, delta: false
|
26
16
|
|
27
17
|
- if defined?(EffectiveRoles) and f.object.respond_to?(:roles) && EffectivePosts.use_effective_roles
|
28
|
-
= f.
|
18
|
+
= f.checks :roles, EffectiveRoles.roles_collection(f.object), hint: '* leave blank for a regular public post that anyone can view'
|
29
19
|
|
30
|
-
.
|
31
|
-
= f.
|
20
|
+
= f.submit do
|
21
|
+
= f.save 'Save'
|
32
22
|
- if EffectivePosts.use_fullscreen_editor
|
33
|
-
= f.
|
34
|
-
= f.
|
35
|
-
= f.
|
36
|
-
= link_to 'Cancel', effective_posts.admin_posts_path
|
23
|
+
= f.save 'Save and Edit Content'
|
24
|
+
= f.save 'Save and Add New'
|
25
|
+
= f.save 'Save and Duplicate'
|
@@ -1,19 +1,17 @@
|
|
1
1
|
-# Adding additional .effective-posts-category-#{category} will correctly show/hide on Posts#new forms
|
2
2
|
|
3
3
|
- # Event specific fields
|
4
|
-
.effective-post-category-events.
|
5
|
-
|
6
|
-
|
7
|
-
required: false,
|
8
|
-
hint: 'Display a start time for this event.'
|
4
|
+
.effective-post-category-events.card.mb-4{style: ('display: none' unless f.object.category == 'events')}
|
5
|
+
.card-body
|
6
|
+
%h5.card-title Event Info
|
7
|
+
= form.datetime_field :start_at, required: false, hint: 'Display a start time for this event.'
|
9
8
|
|
10
|
-
|
11
|
-
hint: 'Display an end time of this event.'
|
9
|
+
= form.datetime_field :end_at, required: false, hint: 'Display an end time of this event.'
|
12
10
|
|
13
|
-
|
11
|
+
= form.text_field :location, required: false, hint: 'Display a location where this event is taking place.'
|
14
12
|
|
15
|
-
|
16
|
-
|
13
|
+
= form.text_field :website_name, label: 'External website',
|
14
|
+
placeholder: 'Buy Tickets', hint: 'The label of an external website.'
|
17
15
|
|
18
|
-
|
19
|
-
|
16
|
+
= form.url_field :website_href, label: 'External website address',
|
17
|
+
placeholder: 'http://', hint: 'The address of an external website (start with http:// or https://).'
|
@@ -1,27 +1,21 @@
|
|
1
|
-
=
|
2
|
-
= f.
|
1
|
+
= effective_form_with(model: post, url: post.persisted? ? effective_posts.post_path(post.id) : effective_posts.posts_path) do |f|
|
2
|
+
= f.text_field :title, hint: 'The title of your post.'
|
3
3
|
|
4
4
|
- if Array(EffectivePosts.categories).length > 1
|
5
|
-
= f.
|
6
|
-
as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
|
7
|
-
collection: EffectivePosts.categories,
|
8
|
-
include_blank: false
|
5
|
+
= f.select :category, EffectivePosts.categories
|
9
6
|
- else
|
10
|
-
= f.
|
7
|
+
= f.hidden_field :category, (EffectivePosts.categories.first || 'posts')
|
11
8
|
|
12
9
|
= render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
|
13
10
|
|
14
|
-
= f.
|
15
|
-
as: (defined?(EffectiveFormInputs) ? :effective_date_time_picker : :datetime),
|
16
|
-
label: 'Publish date',
|
17
|
-
hint: 'When should this be displayed on the website.'
|
11
|
+
= f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
|
18
12
|
|
19
|
-
= f.
|
20
|
-
as: (defined?(EffectiveFormInputs) ? :effective_ckeditor_text_area : :text),
|
21
|
-
hint: 'The body of your post. You can add content here, or with the full screen editor on the next page.',
|
22
|
-
toolbar: 'simple',
|
23
|
-
required: true
|
13
|
+
= f.text_area :body
|
24
14
|
|
25
|
-
.
|
26
|
-
|
27
|
-
|
15
|
+
/ = f.input :body,
|
16
|
+
/ as: (defined?(EffectiveFormInputs) ? :effective_ckeditor_text_area : :text),
|
17
|
+
/ hint: 'The body of your post. You can add content here, or with the full screen editor on the next page.',
|
18
|
+
/ toolbar: 'simple',
|
19
|
+
/ required: true
|
20
|
+
|
21
|
+
= f.submit 'Save'
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
%p= EffectivePosts.submissions_note
|
4
4
|
|
5
|
-
- if
|
5
|
+
- if EffectivePosts.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
|
9
9
|
|
10
|
-
= render
|
10
|
+
= render file: '/effective/posts/show'
|
@@ -1,6 +1,6 @@
|
|
1
1
|
%p A new post has been submitted and needs your approval before it may be displayed on the website:
|
2
2
|
|
3
|
-
%p= link_to 'Approve Post', effective_posts.
|
3
|
+
%p= link_to 'Approve Post', effective_posts.admin_approve_post_path(@post)
|
4
4
|
|
5
5
|
%hr
|
6
6
|
|
@@ -19,4 +19,4 @@
|
|
19
19
|
|
20
20
|
%hr
|
21
21
|
|
22
|
-
%p= link_to 'Approve Post', effective_posts.
|
22
|
+
%p= link_to 'Approve Post', effective_posts.admin_approve_post_path(@post)
|
data/config/effective_posts.rb
CHANGED
@@ -22,6 +22,30 @@ EffectivePosts.setup do |config|
|
|
22
22
|
# The author is the user that created the Effective::Post object
|
23
23
|
config.post_meta_author = true
|
24
24
|
|
25
|
+
# Authorization Method
|
26
|
+
#
|
27
|
+
# This method is called by all controller actions with the appropriate action and resource
|
28
|
+
# If the method returns false, an Effective::AccessDenied Error will be raised (see README.md for complete info)
|
29
|
+
#
|
30
|
+
# Use via Proc (and with CanCan):
|
31
|
+
# config.authorization_method = Proc.new { |controller, action, resource| can?(action, resource) }
|
32
|
+
#
|
33
|
+
# Use via custom method:
|
34
|
+
# config.authorization_method = :my_authorization_method
|
35
|
+
#
|
36
|
+
# And then in your application_controller.rb:
|
37
|
+
#
|
38
|
+
# def my_authorization_method(action, resource)
|
39
|
+
# current_user.is?(:admin)
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# Or disable the check completely:
|
43
|
+
# config.authorization_method = false
|
44
|
+
config.authorization_method = Proc.new do |controller, action, resource|
|
45
|
+
authorize!(action, resource)
|
46
|
+
resource.respond_to?(:roles_permit?) ? resource.roles_permit?(current_user) : true
|
47
|
+
end
|
48
|
+
|
25
49
|
# Layout Settings
|
26
50
|
# Configure the Layout per controller, or all at once
|
27
51
|
config.layout = {
|
@@ -32,21 +56,6 @@ EffectivePosts.setup do |config|
|
|
32
56
|
# Add additional permitted params
|
33
57
|
# config.permitted_params += [:additional_field]
|
34
58
|
|
35
|
-
# SimpleForm Options
|
36
|
-
# This Hash of options will be passed into any client facing simple_form_for() calls
|
37
|
-
config.simple_form_options = {}
|
38
|
-
config.admin_simple_form_options = {} # For the /admin/posts/new form
|
39
|
-
|
40
|
-
# config.simple_form_options = {
|
41
|
-
# html: {class: 'form-horizontal'},
|
42
|
-
# wrapper: :horizontal_form,
|
43
|
-
# wrapper_mappings: {
|
44
|
-
# boolean: :horizontal_boolean,
|
45
|
-
# check_boxes: :horizontal_radio_and_checkboxes,
|
46
|
-
# radio_buttons: :horizontal_radio_and_checkboxes
|
47
|
-
# }
|
48
|
-
# }
|
49
|
-
|
50
59
|
# Display the effective roles 'choose roles' input when an admin creates a new post
|
51
60
|
config.use_effective_roles = true
|
52
61
|
|
@@ -67,18 +76,29 @@ EffectivePosts.setup do |config|
|
|
67
76
|
config.submissions_note = "News & Event submitted! A confirmation email has been sent to the website owner. When approved, your submission will appear on the website."
|
68
77
|
|
69
78
|
# Mailer Settings
|
70
|
-
#
|
79
|
+
# effective_posts will send the admin an email when a post is submitted
|
80
|
+
# For all the emails, the same :subject_prefix will be prefixed. Leave as nil / empty string if you don't want any prefix
|
71
81
|
#
|
72
|
-
#
|
73
|
-
#
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
77
|
-
|
78
|
-
#
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
|
82
|
+
# The subject_for_post_submitted_to_admin can be one of:
|
83
|
+
# - nil / empty string to use the built in defaults
|
84
|
+
# - A string with the full subject line for this email
|
85
|
+
# - A Proc to create the subject line based on the email
|
86
|
+
# In all three of these cases, the subject_prefix will still be used.
|
87
|
+
|
88
|
+
# The Procs are the same for admin & buyer receipt, the seller Proc is different
|
89
|
+
# subject_for_post_submitted_to_admin: Proc.new { |post| "Post needs approval"}
|
90
|
+
|
91
|
+
config.mailer = {
|
92
|
+
subject_prefix: '[example]',
|
93
|
+
subject_for_post_submitted_to_admin: '',
|
94
|
+
|
95
|
+
layout: 'effective_posts_mailer_layout',
|
96
|
+
|
97
|
+
default_from: 'info@example.com',
|
98
|
+
admin_email: 'admin@example.com',
|
99
|
+
|
100
|
+
deliver_method: nil, # :deliver (rails < 4.2), :deliver_now (rails >= 4.2) or :deliver_later
|
101
|
+
delayed_job_deliver: false
|
102
|
+
}
|
83
103
|
|
84
104
|
end
|
@@ -4,10 +4,8 @@ module EffectivePosts
|
|
4
4
|
|
5
5
|
# Include Helpers to base application
|
6
6
|
initializer 'effective_posts.action_controller' do |app|
|
7
|
-
|
8
|
-
|
9
|
-
helper EffectivePostsHelper
|
10
|
-
end
|
7
|
+
ActiveSupport.on_load :action_controller do
|
8
|
+
helper EffectivePostsHelper
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
@@ -16,6 +14,5 @@ module EffectivePosts
|
|
16
14
|
# Set up our defaults, as per our initializer template
|
17
15
|
eval File.read("#{config.root}/config/effective_posts.rb")
|
18
16
|
end
|
19
|
-
|
20
17
|
end
|
21
18
|
end
|
data/lib/effective_posts.rb
CHANGED
@@ -1,39 +1,62 @@
|
|
1
1
|
require 'kaminari'
|
2
2
|
require 'nokogiri'
|
3
|
-
require 'effective_resources'
|
4
3
|
require 'effective_datatables'
|
5
4
|
require 'effective_regions'
|
6
5
|
require 'effective_posts/engine'
|
7
6
|
require 'effective_posts/version'
|
8
7
|
|
9
8
|
module EffectivePosts
|
9
|
+
mattr_accessor :posts_table_name
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
:posts_table_name, :permitted_params,
|
14
|
-
:layout, :simple_form_options, :admin_simple_form_options,
|
11
|
+
mattr_accessor :authorization_method
|
12
|
+
mattr_accessor :permitted_params
|
15
13
|
|
16
|
-
|
17
|
-
|
14
|
+
mattr_accessor :layout
|
15
|
+
mattr_accessor :simple_form_options
|
16
|
+
mattr_accessor :admin_simple_form_options
|
18
17
|
|
19
|
-
|
18
|
+
mattr_accessor :categories
|
19
|
+
mattr_accessor :use_category_routes
|
20
20
|
|
21
|
-
|
21
|
+
mattr_accessor :use_effective_roles
|
22
|
+
mattr_accessor :use_fullscreen_editor
|
22
23
|
|
23
|
-
|
24
|
+
mattr_accessor :per_page
|
25
|
+
mattr_accessor :post_meta_author
|
26
|
+
|
27
|
+
mattr_accessor :submissions_enabled
|
28
|
+
mattr_accessor :submissions_require_current_user
|
29
|
+
mattr_accessor :submissions_require_approval
|
30
|
+
mattr_accessor :submissions_note
|
31
|
+
|
32
|
+
# These are hashes of configs
|
33
|
+
mattr_accessor :mailer
|
34
|
+
|
35
|
+
def self.setup
|
36
|
+
yield self
|
24
37
|
end
|
25
38
|
|
26
|
-
|
39
|
+
def self.authorized?(controller, action, resource)
|
40
|
+
@_exceptions ||= [Effective::AccessDenied, (CanCan::AccessDenied if defined?(CanCan)), (Pundit::NotAuthorizedError if defined?(Pundit))].compact
|
41
|
+
|
42
|
+
return !!authorization_method unless authorization_method.respond_to?(:call)
|
43
|
+
controller = controller.controller if controller.respond_to?(:controller)
|
44
|
+
|
45
|
+
begin
|
46
|
+
!!(controller || self).instance_exec((controller || self), action, resource, &authorization_method)
|
47
|
+
rescue *@_exceptions
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
27
51
|
|
28
|
-
def self.
|
29
|
-
|
52
|
+
def self.authorize!(controller, action, resource)
|
53
|
+
raise Effective::AccessDenied.new('Access Denied', action, resource) unless authorized?(controller, action, resource)
|
30
54
|
end
|
31
55
|
|
32
56
|
def self.permitted_params
|
33
57
|
@@permitted_params ||= [
|
34
58
|
:title, :draft, :category, :published_at, :body, :tags, :extra,
|
35
|
-
:start_at, :end_at, :location, :website_name, :website_href,
|
36
|
-
(EffectiveAssets.permitted_params if defined?(EffectiveAssets)), roles: []
|
59
|
+
:start_at, :end_at, :location, :website_name, :website_href, roles: []
|
37
60
|
].compact
|
38
61
|
end
|
39
62
|
|
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 3.2.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: sass
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -66,20 +66,6 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: simple_form
|
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'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: effective_ckeditor
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,16 +84,16 @@ dependencies:
|
|
98
84
|
name: effective_datatables
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
|
-
- - "
|
87
|
+
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
89
|
+
version: 4.0.0
|
104
90
|
type: :runtime
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
|
-
- - "
|
94
|
+
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
96
|
+
version: 4.0.0
|
111
97
|
- !ruby/object:Gem::Dependency
|
112
98
|
name: effective_regions
|
113
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,19 +118,20 @@ extra_rdoc_files: []
|
|
132
118
|
files:
|
133
119
|
- MIT-LICENSE
|
134
120
|
- README.md
|
135
|
-
-
|
136
|
-
- app/assets/
|
121
|
+
- app/assets/javascripts/effective/snippets/read_more_divider.js.coffee
|
122
|
+
- app/assets/javascripts/effective_pages/additional_fields.js.coffee
|
137
123
|
- app/assets/javascripts/effective_posts.js
|
138
|
-
- app/assets/javascripts/effective_posts/additional_fields.js.coffee
|
139
124
|
- app/assets/stylesheets/effective_posts.scss
|
140
125
|
- app/controllers/admin/posts_controller.rb
|
141
126
|
- app/controllers/effective/posts_controller.rb
|
142
127
|
- app/datatables/effective_posts_datatable.rb
|
143
|
-
- app/helpers/effective_kaminari_helper.rb
|
144
128
|
- app/helpers/effective_posts_helper.rb
|
145
129
|
- app/helpers/effective_truncate_html_helper.rb
|
146
130
|
- app/mailers/effective/posts_mailer.rb
|
131
|
+
- app/models/effective/access_denied.rb
|
132
|
+
- app/models/effective/datatables/posts.rb
|
147
133
|
- app/models/effective/post.rb
|
134
|
+
- app/models/effective/snippets/read_more_divider.rb
|
148
135
|
- app/views/admin/posts/_actions.html.haml
|
149
136
|
- app/views/admin/posts/_form.html.haml
|
150
137
|
- app/views/admin/posts/edit.html.haml
|
@@ -185,7 +172,7 @@ homepage: https://github.com/code-and-effect/effective_posts
|
|
185
172
|
licenses:
|
186
173
|
- MIT
|
187
174
|
metadata: {}
|
188
|
-
post_install_message:
|
175
|
+
post_install_message:
|
189
176
|
rdoc_options: []
|
190
177
|
require_paths:
|
191
178
|
- lib
|
@@ -200,8 +187,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
187
|
- !ruby/object:Gem::Version
|
201
188
|
version: '0'
|
202
189
|
requirements: []
|
203
|
-
|
204
|
-
|
190
|
+
rubyforge_project:
|
191
|
+
rubygems_version: 2.5.2.3
|
192
|
+
signing_key:
|
205
193
|
specification_version: 4
|
206
194
|
summary: A blog implementation with WYSIWYG content editing, post scheduling, pagination
|
207
195
|
and optional top level routes for each post category.
|
data/Rakefile
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
begin
|
3
|
-
require 'bundler/setup'
|
4
|
-
rescue LoadError
|
5
|
-
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
-
end
|
7
|
-
|
8
|
-
# Our tasks
|
9
|
-
load 'lib/tasks/effective_posts_tasks.rake'
|
10
|
-
|
11
|
-
# Testing tasks
|
12
|
-
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
13
|
-
load 'rails/tasks/engine.rake'
|
14
|
-
|
15
|
-
require "bundler/vendored_thor"
|
16
|
-
Bundler::GemHelper.install_tasks
|
17
|
-
|
18
|
-
require 'rspec/core'
|
19
|
-
require 'rspec/core/rake_task'
|
20
|
-
|
21
|
-
desc "Run all specs in spec directory (excluding plugin specs)"
|
22
|
-
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
23
|
-
|
24
|
-
task :default => :spec
|
@@ -1,16 +0,0 @@
|
|
1
|
-
# This extends the @template.url_for method to work with Kaminari
|
2
|
-
# It is only extended on the posts#index method, for minimal pollution
|
3
|
-
|
4
|
-
module EffectiveKaminariHelper
|
5
|
-
def url_for(params)
|
6
|
-
if params.kind_of?(Hash) && params[:controller] == 'effective/posts' && params[:action] == 'index'
|
7
|
-
params.delete(:page) if params[:page].blank?
|
8
|
-
params.delete(:category) if EffectivePosts.use_category_routes
|
9
|
-
params = params.except(:action, :controller, :only_path)
|
10
|
-
|
11
|
-
request.path.to_s + (params.present? ? '?' : '') + params.to_param
|
12
|
-
else
|
13
|
-
super
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
/data/app/assets/javascripts/{effective_posts → effective_pages}/additional_fields.js.coffee
RENAMED
File without changes
|