effective_posts 2.4.2 → 2.6.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
2
  SHA256:
3
- metadata.gz: 84c27105c23c603f005a3389dba3e7f04a13c88e9d46f0fe7c135a1b5f40bf07
4
- data.tar.gz: d9d1637b7f30a5190455e5337848ad6fcbffe129d943483ccadeb8f611e426b4
3
+ metadata.gz: 333ef424bbeceb95702ecd079b9f8337fbc9d482ccc27bf545fac284e6cb43fa
4
+ data.tar.gz: 3ce82e06eac036d8e49a93be1a7dc7509e5f4b2658e0f2949f5ee7159e239de2
5
5
  SHA512:
6
- metadata.gz: eb22ed3626f8637052610a9d7a12cc9a08ea3bf09589953e3a7d1ee681e1f6ff73c7f250f00eb612ed7e50567f0515667c0a33c817cddcef09fb3f3bf8455266
7
- data.tar.gz: 4ea9ec43edfd22c8c37ef8348757d8c2e4ce4208168be17a0cf93b0490df235d2b59a0cba0b679313ce1fb79941b8e4ea1ac36418c7c98b1e8057476fae213b6
6
+ metadata.gz: 4c8a3a3bee762962cc9570e227eb361f29187a053f80ce9a8e28fee94e0e3c9a4394883d044cc1ed570592e794f3e1d9ddc8970d5975caf6673cdad66352c77d
7
+ data.tar.gz: cf41cebfc376de36684806d95cfda9dfb4f3fa7ecd2419b02920c9689f18937f23828716cefd48081697176ca601d6b1401296acd9983ad3a3202a2cd1637e54
@@ -36,7 +36,9 @@ module Effective
36
36
  def show
37
37
  @category = EffectivePosts.category(params[:category])
38
38
 
39
- @posts ||= Effective::Post.posts(user: current_user, unpublished: EffectiveResources.authorized?(self, :admin, :effective_posts))
39
+ admin = EffectiveResources.authorized?(self, :admin, :effective_posts)
40
+
41
+ @posts ||= Effective::Post.posts(user: current_user, unpublished: admin, archived: admin)
40
42
  @post = @posts.find(params[:id])
41
43
 
42
44
  if @post.respond_to?(:roles_permit?)
@@ -45,10 +47,11 @@ module Effective
45
47
 
46
48
  EffectiveResources.authorize!(self, :show, @post)
47
49
 
48
- if EffectiveResources.authorized?(self, :admin, :effective_posts)
50
+ if admin
49
51
  flash.now[:warning] = [
50
52
  'Hi Admin!',
51
53
  ('You are viewing a hidden post.' unless @post.published?),
54
+ ('You are viewing an archived post.' if @post.archived?),
52
55
  'Click here to',
53
56
  ("<a href='#{effective_posts.edit_admin_post_path(@post)}' class='alert-link'>edit post settings</a>.")
54
57
  ].compact.join(' ')
@@ -61,7 +64,7 @@ module Effective
61
64
 
62
65
  # Public user submit a post functionality
63
66
  def new
64
- @post ||= Effective::Post.new(published_at: Time.zone.now)
67
+ @post ||= Effective::Post.new
65
68
  @page_title = 'New Post'
66
69
 
67
70
  EffectiveResources.authorize!(self, :new, @post)
@@ -1,31 +1,35 @@
1
1
  class EffectivePostsDatatable < Effective::Datatable
2
+ bulk_actions do
3
+ bulk_action('Archive selected', effective_posts.bulk_archive_admin_posts_path)
4
+ bulk_action('Unarchive selected', effective_posts.bulk_unarchive_admin_posts_path)
5
+ end
6
+
2
7
  filters do
3
- scope :all
8
+ scope :unarchived, label: 'All'
4
9
  scope :published
5
- scope :unpublished
10
+ scope :draft
6
11
  scope :news
7
12
  scope :events
13
+ scope :archived
8
14
  end
9
15
 
10
16
  datatable do
11
- order :published_at, :desc
17
+ order :published_start_at, :desc
18
+
19
+ bulk_actions_col
12
20
 
13
- col :published_at
14
21
  col :id, visible: false
15
22
 
16
23
  col :title
17
24
  col :slug, visible: false
18
25
  col :category, search: { collection: EffectivePosts.categories }
19
26
 
20
- if EffectivePosts.submissions_enabled
21
- col :approved, sql_column: 'NOT(draft)', as: :boolean do |post|
22
- post.draft? ? 'No' : 'Yes'
23
- end
27
+ col :draft?, as: :boolean, visible: false
28
+ col :published?, as: :boolean
29
+ col :published_start_at
30
+ col :published_end_at
24
31
 
25
- col :draft, visible: false
26
- else
27
- col :draft
28
- end
32
+ col :archived
29
33
 
30
34
  col :start_at
31
35
  col :end_at, visible: false
@@ -10,7 +10,7 @@ module EffectivePostsHelper
10
10
  tags = [
11
11
  tag(:meta, itemprop: 'author', content: @post.user.to_s),
12
12
  tag(:meta, itemprop: 'publisher', content: @post.user.to_s),
13
- tag(:meta, itemprop: 'datePublished', content: (@post.published_at || Time.zone.now).strftime('%FT%T%:z')),
13
+ tag(:meta, itemprop: 'datePublished', content: (@post.published_start_at || Time.zone.now).strftime('%FT%T%:z')),
14
14
  tag(:meta, itemprop: 'headline', content: @post.title)
15
15
  ].join("\n").html_safe
16
16
  end
@@ -61,8 +61,8 @@ module EffectivePostsHelper
61
61
  def post_meta(post, date: true, datetime: false, category: true, author: true)
62
62
  [
63
63
  'Published',
64
- ("on #{post.published_at.strftime('%B %d, %Y')}" if date && post.published_at),
65
- ("on #{post.published_at.strftime('%B %d, %Y at %l:%M %p')}" if datetime && post.published_at),
64
+ ("on #{post.published_start_at.strftime('%B %d, %Y')}" if date && post.published_start_at),
65
+ ("on #{post.published_start_at.strftime('%B %d, %Y at %l:%M %p')}" if datetime && post.published_start_at),
66
66
  ("to #{link_to_post_category(post.category)}" if category && Array(EffectivePosts.categories).length > 1),
67
67
  ("by #{post.user.to_s.presence || 'Unknown'}" if author && EffectivePosts.post_meta_author && post.user.present?)
68
68
  ].compact.join(' ').html_safe
@@ -71,10 +71,12 @@ module EffectivePostsHelper
71
71
  def admin_post_status_badge(post)
72
72
  return nil unless EffectiveResources.authorized?(self, :admin, :effective_posts)
73
73
 
74
- if post.draft?
74
+ if post.archived?
75
+ content_tag(:span, 'ARCHIVED', class: 'badge badge-info')
76
+ elsif post.draft?
75
77
  content_tag(:span, 'DRAFT', class: 'badge badge-info')
76
78
  elsif post.published? == false
77
- content_tag(:span, "TO BE PUBLISHED AT #{post.published_at&.strftime('%F %H:%M') || 'LATER'}", class: 'badge badge-info')
79
+ content_tag(:span, "TO BE PUBLISHED AT #{post.published_start_at&.strftime('%F %H:%M') || 'LATER'}", class: 'badge badge-info')
78
80
  end
79
81
  end
80
82
 
@@ -1,5 +1,7 @@
1
1
  module Effective
2
2
  class Post < ActiveRecord::Base
3
+ self.table_name = (EffectivePosts.posts_table_name || :posts).to_s
4
+
3
5
  if defined?(PgSearch)
4
6
  include PgSearch::Model
5
7
 
@@ -8,20 +10,20 @@ module Effective
8
10
 
9
11
  attr_accessor :current_user
10
12
 
13
+ belongs_to :user, polymorphic: true, optional: true
14
+
15
+ acts_as_role_restricted if respond_to?(:acts_as_role_restricted)
16
+ acts_as_archived
17
+ acts_as_published
11
18
  acts_as_slugged
12
- log_changes if respond_to?(:log_changes)
13
19
  acts_as_tagged if respond_to?(:acts_as_tagged)
14
- acts_as_role_restricted if respond_to?(:acts_as_role_restricted)
20
+ log_changes if respond_to?(:log_changes)
15
21
 
16
22
  has_one_attached :image
17
23
 
18
24
  has_rich_text :excerpt
19
25
  has_rich_text :body
20
26
 
21
- self.table_name = (EffectivePosts.posts_table_name || :posts).to_s
22
-
23
- belongs_to :user, polymorphic: true, optional: true
24
-
25
27
  effective_resource do
26
28
  title :string
27
29
  description :string
@@ -29,11 +31,14 @@ module Effective
29
31
  category :string
30
32
  slug :string
31
33
 
32
- draft :boolean
33
- published_at :datetime
34
+ published_start_at :datetime
35
+ published_end_at :datetime
36
+ legacy_draft :boolean # No longer used. To be removed.
37
+
34
38
  tags :text
35
39
 
36
40
  roles_mask :integer
41
+ archived :boolean
37
42
 
38
43
  # Event Fields
39
44
  start_at :datetime
@@ -53,20 +58,21 @@ module Effective
53
58
  validates :title, presence: true, length: { maximum: 255 }
54
59
  validates :description, presence: true, length: { maximum: 150 }
55
60
  validates :category, presence: true
56
- validates :published_at, presence: true, unless: -> { draft? }
57
61
  validates :start_at, presence: true, if: -> { category == 'events' }
58
62
 
59
- scope :drafts, -> { where(draft: true) }
60
- scope :published, -> { where(draft: false).where("published_at < ?", Time.zone.now) }
61
- scope :unpublished, -> { where(draft: true).or(where("published_at > ?", Time.zone.now)) }
62
- scope :with_category, -> (category) { where(category: category) }
63
+ scope :unarchived, -> { where(archived: false) }
64
+ scope :archived, -> { where(archived: true) }
65
+
66
+ scope :for_sitemap, -> { published.unarchived }
63
67
 
64
68
  # Kind of a meta category
65
- scope :news, -> { where(category: EffectivePosts.news_categories) }
66
- scope :events, -> { where(category: EffectivePosts.event_categories) }
69
+ scope :news, -> { unarchived.where(category: EffectivePosts.news_categories) }
70
+ scope :events, -> { unarchived.where(category: EffectivePosts.event_categories) }
71
+
72
+ scope :with_category, -> (category) { where(category: category) } # Don't add unarchived here
67
73
 
68
74
  scope :deep, -> {
69
- base = with_rich_text_excerpt_and_embeds.with_rich_text_body_and_embeds
75
+ base = with_attached_image.with_rich_text_excerpt_and_embeds.with_rich_text_body_and_embeds
70
76
  base = base.includes(:pg_search_document) if defined?(PgSearch)
71
77
  base
72
78
  }
@@ -78,8 +84,8 @@ module Effective
78
84
  limit(per_page).offset(offset)
79
85
  }
80
86
 
81
- scope :posts, -> (user: nil, category: nil, unpublished: false) {
82
- scope = all.deep.order(published_at: :desc)
87
+ scope :posts, -> (user: nil, category: nil, unpublished: false, archived: false) {
88
+ scope = all.deep.order(published_start_at: :desc)
83
89
 
84
90
  if defined?(EffectiveRoles) && EffectivePosts.use_effective_roles
85
91
  if user.present? && user.respond_to?(:roles)
@@ -95,6 +101,10 @@ module Effective
95
101
  scope = scope.published
96
102
  end
97
103
 
104
+ unless archived
105
+ scope = scope.unarchived
106
+ end
107
+
98
108
  scope
99
109
  }
100
110
 
@@ -102,12 +112,8 @@ module Effective
102
112
  title.presence || 'New Post'
103
113
  end
104
114
 
105
- def published?
106
- !draft? && published_at.present? && published_at < Time.zone.now
107
- end
108
-
109
115
  def approved?
110
- draft == false
116
+ published?
111
117
  end
112
118
 
113
119
  def event?
@@ -134,11 +140,12 @@ module Effective
134
140
  post.assign_attributes(
135
141
  title: post.title + ' (Copy)',
136
142
  slug: post.slug + '-copy',
137
- draft: true,
138
143
  body: body,
139
144
  excerpt: excerpt
140
145
  )
141
146
 
147
+ post.assign_attributes(published_start_at: nil, published_end_at: nil)
148
+
142
149
  post
143
150
  end
144
151
 
@@ -147,7 +154,7 @@ module Effective
147
154
  end
148
155
 
149
156
  def approve!
150
- update!(draft: false)
157
+ update!(published_start_at: Time.zone.now)
151
158
  end
152
159
 
153
160
  end
@@ -1,6 +1,20 @@
1
1
  = effective_form_with(model: [:admin, post], engine: true) do |f|
2
2
  = f.text_field :title, hint: 'The title of your post.'
3
3
 
4
+ -# acts_as_published
5
+ = f.hide_if(:save_as_draft, true) do
6
+ .row
7
+ .col-md-6
8
+ = f.datetime_field :published_start_at, hint: 'The page will be available starting on this date and time.'
9
+ .col-md-6
10
+ = f.datetime_field :published_end_at, hint: 'The page will no longer be available after this date and time. Leave blank for no end date.', date_linked: false
11
+
12
+ = f.check_box :save_as_draft, label: "Save as a draft. It will not appear on the website and can only be accessed by admin users."
13
+
14
+ = f.text_field :description,
15
+ hint: "150 character summary. Appears on Google search results underneath the post title. ",
16
+ input_html: { maxlength: 150 }
17
+
4
18
  - if f.object.persisted? || f.object.errors.include?(:slug)
5
19
  - current_url = effective_posts.post_path(f.object)
6
20
 
@@ -12,8 +26,6 @@
12
26
  - else
13
27
  = f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages.'
14
28
 
15
- = f.text_field :description, hint: 'The content of the post meta tags.', maxlength: 150
16
-
17
29
  - if Array(EffectivePosts.categories).length > 1
18
30
  = f.select :category, EffectivePosts.categories
19
31
  - else
@@ -32,9 +44,7 @@
32
44
 
33
45
  = render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
34
46
 
35
- = f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
36
-
37
- = f.check_box :draft, hint: 'Save this post as a draft. It will not be accessible on the website.'
47
+ = f.check_box :archived, label: 'Yes, this post is archived. It will not be displayed.'
38
48
 
39
49
  - if EffectivePosts.use_effective_roles
40
50
  = render partial: '/admin/posts/roles', locals: { post: post, form: f, f: f }
@@ -22,10 +22,6 @@
22
22
 
23
23
  = render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
24
24
 
25
- = f.datetime_field :published_at, label: 'Publish date', hint: 'When should this be displayed on the website.'
26
-
27
- = f.check_box :draft, hint: 'Save this post as a draft. It will not be accessible on the website.'
28
-
29
25
  - if defined?(EffectiveArticleEditor)
30
26
  = f.article_editor :body, hint: 'The main body of your post'
31
27
  - else
data/config/routes.rb CHANGED
@@ -2,6 +2,11 @@ EffectivePosts::Engine.routes.draw do
2
2
  namespace :admin do
3
3
  resources :posts, except: [:show] do
4
4
  post :approve, on: :member
5
+
6
+ post :archive, on: :member
7
+ post :unarchive, on: :member
8
+ post :bulk_archive, on: :collection
9
+ post :bulk_unarchive, on: :collection
5
10
  end
6
11
  end
7
12
 
@@ -10,12 +10,14 @@ class CreateEffectivePosts < ActiveRecord::Migration[6.0]
10
10
  t.string :category
11
11
  t.string :slug
12
12
 
13
- t.boolean :draft, :default => false
14
- t.datetime :published_at
13
+ t.datetime :published_start_at
14
+ t.datetime :published_end_at
15
+ t.boolean :legacy_draft, default: false
15
16
 
16
17
  t.text :tags
17
18
 
18
- t.integer :roles_mask, :default => 0
19
+ t.integer :roles_mask, default: 0
20
+ t.boolean :archived, default: false
19
21
 
20
22
  # Events fields
21
23
  t.datetime :start_at
@@ -1,3 +1,3 @@
1
1
  module EffectivePosts
2
- VERSION = '2.4.2'.freeze
2
+ VERSION = '2.6.0'.freeze
3
3
  end
@@ -25,7 +25,7 @@ module EffectivePosts
25
25
 
26
26
  def self.permitted_params
27
27
  @permitted_params ||= [
28
- :title, :excerpt, :description, :draft, :category, :slug, :published_at, :body, :tags, :extra,
28
+ :title, :excerpt, :description, :save_as_draft, :category, :slug, :published_start_at, :published_end_at, :body, :tags, :extra,
29
29
  :image, :start_at, :end_at, :location, :website_name, :website_href, roles: []
30
30
  ]
31
31
  end
@@ -13,8 +13,6 @@ class EffectivePostsMailerPreview < ActionMailer::Preview
13
13
  post = Effective::Post.new(
14
14
  title: 'An example post',
15
15
  category: EffectivePosts.categories.first.presence || 'posts',
16
- published_at: Time.zone.now,
17
- draft: true,
18
16
  body: 'This is a new post that has been submitted by a public user.'
19
17
  )
20
18
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_posts
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.2
4
+ version: 2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Code and Effect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-01 00:00:00.000000000 Z
11
+ date: 2024-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails