effective_posts 0.7.1 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: f1437eacfc9cc73589cdb1f9a1477a25a87d49c7eba2c6cbadebb09f7244e96a
4
- data.tar.gz: 548e4c3801f7711dd822a031d6e0c3418d9fc965c56e531aa581be3cabc44d50
2
+ SHA1:
3
+ metadata.gz: c022efd2bcc520c8c917470ed78cfc6d59383a6d
4
+ data.tar.gz: 7b0e965d6149141d91764bff9405ba0bf5407d17
5
5
  SHA512:
6
- metadata.gz: 8f63e0bb1fbdc1a9bb24ed01c8c3b8165a6e6c3f73b691f7e2c28c0dd7ce61110c7a8ff2b82a9539e93987fae685f1df33c1f676a59920ff8369fabfa02e4a9d
7
- data.tar.gz: 1af93b7d75e8e662e80bc0c160ba1f033168d157fc3aa5307f5d4ab4436750623a4e757f573866ad0217debf2d477371a77361616fb93a8cdf409b32f2e04b93
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,18 +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(resource, opts = {})
8
- @post = resource
9
- raise('expected a post') unless resource.kind_of?(Effective::Post)
5
+ layout EffectivePosts.mailer[:layout].presence || 'effective_posts_mailer_layout'
10
6
 
11
- subject = subject_for(__method__, 'Post Submitted', resource, opts)
12
- headers = headers_for(resource, opts)
7
+ def post_submitted_to_admin(post_param)
8
+ @post = (post_param.kind_of?(Effective::Post) ? post_param : Effective::Post.find(post_param))
13
9
 
14
- mail(to: mailer_admin, subject: subject, **headers)
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
15
  end
16
16
 
17
+ private
18
+
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")
27
+ end
28
+
29
+ def prefix_subject(text)
30
+ prefix = (EffectivePosts.mailer[:subject_prefix].to_s rescue '')
31
+ prefix.present? ? (prefix.chomp(' ') + ' ' + text) : text
32
+ end
17
33
  end
18
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.1'.freeze
2
+ VERSION = '1.0.0'.freeze
3
3
  end
@@ -1,37 +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
- :mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject,
15
- :layout, :simple_form_options, :admin_simple_form_options,
11
+ mattr_accessor :authorization_method
12
+ mattr_accessor :permitted_params
16
13
 
17
- :categories, :use_category_routes, :use_effective_roles, :use_fullscreen_editor,
18
- :per_page, :post_meta_author,
14
+ mattr_accessor :layout
15
+ mattr_accessor :simple_form_options
16
+ mattr_accessor :admin_simple_form_options
19
17
 
20
- :submissions_enabled, :submissions_require_current_user, :submissions_require_approval, :submissions_note,
21
- ]
18
+ mattr_accessor :categories
19
+ mattr_accessor :use_category_routes
20
+
21
+ mattr_accessor :use_effective_roles
22
+ mattr_accessor :use_fullscreen_editor
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
22
37
  end
23
38
 
24
- 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
25
51
 
26
- def self.mailer_class
27
- 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)
28
54
  end
29
55
 
30
56
  def self.permitted_params
31
57
  @@permitted_params ||= [
32
58
  :title, :draft, :category, :published_at, :body, :tags, :extra,
33
- :start_at, :end_at, :location, :website_name, :website_href,
34
- (EffectiveAssets.permitted_params if defined?(EffectiveAssets)), roles: []
59
+ :start_at, :end_at, :location, :website_name, :website_href, roles: []
35
60
  ].compact
36
61
  end
37
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.1
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-11-08 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