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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 5105b8f4cd7c534450c0e096d48411dae0376e38cc9a18ddd2c15a2a672ee2ab
4
- data.tar.gz: e84688eb0d998f84a99bd04694999893326a15973f17f3bf8e75f2ca6b96ad07
2
+ SHA1:
3
+ metadata.gz: c022efd2bcc520c8c917470ed78cfc6d59383a6d
4
+ data.tar.gz: 7b0e965d6149141d91764bff9405ba0bf5407d17
5
5
  SHA512:
6
- metadata.gz: fc6d24ab9e3e7fdacb225d0fce839b3eca60c5ad5a4b7c990898e5063275e32075bf3e5d636ed58888349a38adb4b296590511dd152a97dc8b6eaf20eafdd20d
7
- data.tar.gz: 124ae97fb1073610667bc5a35b345b46edc95c9635baa53f23dd01beff4f5693ada7be3fc2446f9de602ced9f8179d41fd5d8179739a5f716e77d4e6c58501ae
6
+ metadata.gz: 0fdd4fe4cbb4e0a5bd4ca0d965464bea38a54075470cd326529d9b3d297626dc1235a14292aa90093b99863d91a5596adc58b27e667c309f883303967fece7ca
7
+ data.tar.gz: fcc25d31d20948003c2759801034cf981a522a3e5cc8541751e11f46bad4552ecbd9abab7fb769f2317b4464c2b705e36a64bcc0f8c07bf5631574f889fab35b
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2023 Code and Effect Inc.
1
+ Copyright 2018 Code and Effect Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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 Bootstrap3](http://getbootstrap.com)
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 effective_posts/additional_fields
1
+ //= require effective_pages/additional_fields
@@ -55,7 +55,7 @@ module Admin
55
55
 
56
56
  authorize_effective_posts!
57
57
 
58
- if @post.update(post_params)
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.update(draft: false)
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
- EffectiveResources.authorize!(self, :admin, :effective_posts)
125
- EffectiveResources.authorize!(self, action_name.to_sym, @post || Effective::Post)
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
- EffectiveResources.authorize!(self, :index, Effective::Post)
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
- EffectiveResources.authorize!(self, :show, @post)
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
- EffectiveResources.authorize!(self, :new, @post)
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
- EffectiveResources.authorize!(self, :create, @post)
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
- EffectiveResources.authorize!(self, :edit, @post)
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
- EffectiveResources.authorize!(self, :update, @post)
82
+ EffectivePosts.authorize!(self, :update, @post)
81
83
 
82
- if @post.update(post_params)
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
- EffectiveResources.authorize!(self, :destroy, @post)
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 at %l:%M %p')}",
23
- ("to #{link_to_post_category(post.category)}" if Array(EffectivePosts.categories).length > 1),
24
- ("by #{post.user.to_s.presence || 'Unknown'}" if EffectivePosts.post_meta_author && post.user.present?)
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 < EffectivePosts.parent_mailer_class
3
- include EffectiveMailer
4
-
2
+ class PostsMailer < ActionMailer::Base
5
3
  helper EffectivePostsHelper
6
4
 
7
- def post_submitted_to_admin(post_param, opts = {})
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
- subject = subject_for(__method__, 'Post Submitted', @post, opts)
11
- headers = headers_for(resource, opts)
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
- mail(to: mailer_admin, subject: subject, **headers)
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, optional: true
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?(EffectiveAssets)
41
- scope = scope.includes(attachments: :asset)
42
- end
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.where(category: category)
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
- EffectivePosts.send_email(email, self)
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
@@ -0,0 +1,9 @@
1
+ module Effective
2
+ module Snippets
3
+ class ReadMoreDivider < Snippet
4
+ TOKEN = "<div style='display: none;'>READ_MORE_DIVIDER</div>"
5
+
6
+ attribute :throwaway, String
7
+ end
8
+ end
9
+ end
@@ -1,16 +1,13 @@
1
- - if EffectivePosts.submissions_enabled && EffectivePosts.submissions_require_approval && !post.approved?
2
- = link_to effective_posts.admin_approve_post_path(post.id), title: 'Approve' do
3
- %span.glyphicon.glyphicon-ok
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
- = link_to effective_posts.edit_admin_post_path(post.id), title: 'Settings' do
6
- %span.glyphicon.glyphicon-cog
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
- = link_to effective_post_path(post, (post.draft? ? {preview: true} : nil)), title: 'View', target: '_blank' do
9
- %span.glyphicon.glyphicon-eye-open
10
+ = dropdown_link_to 'View', effective_post_path(post, preview: true), target: '_blank'
10
11
 
11
- - if EffectivePosts.use_fullscreen_editor
12
- = link_to effective_post_path(post, edit: true), title: 'Edit Content', 'data-no-turbolink': true, target: '_blank' do
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
- = simple_form_for(post, (EffectivePosts.admin_simple_form_options || {}).merge(:url => (post.persisted? ? effective_posts.admin_post_path(post.id) : effective_posts.admin_posts_path))) do |f|
2
- = f.input :title, hint: 'The title of your post.'
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.input :category,
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.input :category, as: :hidden, input_html: { value: (EffectivePosts.categories.first || 'posts') }
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.input :draft, hint: 'Save this post as a draft. It will not be accessible on the website.'
11
+ = f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
15
12
 
16
- = f.input :published_at,
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.input :body,
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.input :roles, collection: EffectiveRoles.roles_collection(f.object), as: :check_boxes, hint: '* leave blank for a regular public post that anyone can view'
18
+ = f.checks :roles, EffectiveRoles.roles_collection(f.object), hint: '* leave blank for a regular public post that anyone can view'
29
19
 
30
- .form-actions.effective-post-actions
31
- = f.button :submit, 'Save', data: { disable_with: 'Saving...' }, class: 'btn btn-primary'
20
+ = f.submit do
21
+ = f.save 'Save'
32
22
  - if EffectivePosts.use_fullscreen_editor
33
- = f.button :submit, 'Save and Edit Content', data: { disable_with: 'Saving...' }, class: 'btn btn-primary'
34
- = f.button :submit, 'Save and Add New', data: { disable_with: 'Saving...' }, class: 'btn btn-default'
35
- = f.button :submit, 'Save and Duplicate', data: { disable_with: 'Saving...' }, class: 'btn btn-default'
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.well{style: ('display: none' unless f.object.category == 'events')}
5
- %h4 Event Information
6
- = form.input :start_at, as: (:effective_date_time_picker if defined?(EffectiveFormInputs)),
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
- = form.input :end_at, as: (:effective_date_time_picker if defined?(EffectiveFormInputs)),
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
- = form.input :location, required: false, hint: 'Display a location where this event is taking place.'
11
+ = form.text_field :location, required: false, hint: 'Display a location where this event is taking place.'
14
12
 
15
- = form.input :website_name, label: 'External website',
16
- placeholder: 'Buy Tickets', hint: 'The label of an external website.'
13
+ = form.text_field :website_name, label: 'External website',
14
+ placeholder: 'Buy Tickets', hint: 'The label of an external website.'
17
15
 
18
- = form.input :website_href, label: 'External website address',
19
- placeholder: 'http://', hint: 'The address of an external website (start with http:// or https://).'
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
- = simple_form_for(post, (EffectivePosts.simple_form_options || {}).merge(url: (post.persisted? ? effective_posts.post_path(post.id) : effective_posts.posts_path))) do |f|
2
- = f.input :title, hint: 'The title of your post.'
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.input :category,
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.input :category, as: :hidden, input_html: { value: (EffectivePosts.categories.first || 'posts') }
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.input :published_at,
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.input :body,
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
- .form-actions
26
- = f.button :submit, 'Save', data: { disable_with: 'Saving...' }, class: 'btn btn-primary'
27
- = link_to 'Cancel', effective_posts.posts_path
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 (EffectivePosts.authorized?(controller, :edit, @post) rescue false)
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 template: '/effective/posts/show'
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.admin_approve_post_url(@post)
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.admin_approve_post_url(@post)
22
+ %p= link_to 'Approve Post', effective_posts.admin_approve_post_path(@post)
@@ -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
- # Please see config/initializers/effective_resources.rb for default effective_* gem mailer settings
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
- # Configure the class responsible to send e-mails.
73
- # config.mailer = 'Effective::PostsMailer'
74
- #
75
- # Override effective_resource mailer defaults
76
- #
77
- # config.parent_mailer = nil # The parent class responsible for sending emails
78
- # config.deliver_method = nil # The deliver method, deliver_later or deliver_now
79
- # config.mailer_layout = nil # Default mailer layout
80
- # config.mailer_sender = nil # Default From value
81
- # config.mailer_admin = nil # Default To value for Admin correspondence
82
- # config.mailer_subject = nil # Proc.new method used to customize Subject
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
- app.config.to_prepare do
8
- ActiveSupport.on_load :action_controller_base do
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
@@ -1,3 +1,3 @@
1
1
  module EffectivePosts
2
- VERSION = '0.7.0'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -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
- def self.config_keys
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
- :categories, :use_category_routes,
17
- :use_effective_roles, :use_fullscreen_editor,
14
+ mattr_accessor :layout
15
+ mattr_accessor :simple_form_options
16
+ mattr_accessor :admin_simple_form_options
18
17
 
19
- :per_page, :post_meta_author,
18
+ mattr_accessor :categories
19
+ mattr_accessor :use_category_routes
20
20
 
21
- :submissions_enabled, :submissions_require_current_user, :submissions_require_approval, :submissions_note,
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
- include EffectiveGem
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.mailer_class
29
- mailer&.constantize || Effective::PostsMailer
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
 
@@ -11,7 +11,7 @@ module EffectivePosts
11
11
  if not ActiveRecord::Base.timestamped_migrations
12
12
  Time.new.utc.strftime("%Y%m%d%H%M%S")
13
13
  else
14
- "%.3d" % (current_migration_number(dirname) + 1)
14
+ '%.3d' % (current_migration_number(dirname) + 1)
15
15
  end
16
16
  end
17
17
 
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.7.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: 2023-05-26 00:00:00.000000000 Z
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: sassc
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: '4'
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: '4'
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
- - Rakefile
136
- - app/assets/config/effective_posts_manifest.js
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
- rubygems_version: 3.3.7
204
- signing_key:
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,2 +0,0 @@
1
- //= link_directory ../javascripts .js
2
- //= link_directory ../stylesheets .css
@@ -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