effective_posts 2.6.2 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/effective/posts_controller.rb +9 -4
- data/app/datatables/effective_posts_datatable.rb +3 -3
- data/app/helpers/effective_posts_helper.rb +25 -6
- data/app/models/effective/post.rb +4 -3
- data/app/views/admin/posts/_form_post.html.haml +20 -23
- data/app/views/effective/posts/_form.html.haml +17 -12
- data/app/views/effective/posts/_layout.html.haml +2 -3
- data/app/views/effective/posts/_post.html.haml +14 -5
- data/app/views/effective/posts/index.html.haml +4 -4
- data/app/views/effective/posts/show.html.haml +6 -4
- data/config/effective_posts.rb +6 -0
- data/config/locales/effective_posts.en.yml +7 -0
- data/lib/effective_posts/version.rb +1 -1
- data/lib/effective_posts.rb +1 -1
- metadata +3 -3
- data/app/views/effective/posts/_spacer.html.haml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a1c81f231ae730f44dcbbfb64bead77d9a2530a3b6f4e2bdea6455f5ea78ca2
|
4
|
+
data.tar.gz: 0ef00c73d74471e23a06c322444f209ab58fd21fce475a9783ecc93e8dadc011
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eb6a0e3530b97ba6cd1679c4bb137dfe91937806ca6284a016a930509e416e49fed55ec489af4753aec4d0fcd783e5bcf88ca9bc62c6f629fddaa3c4f2fc442
|
7
|
+
data.tar.gz: 600dec645eb265e938d44315ecf2299755bbc678d8d0e8535fc690eff63867a0b884d3612b1b56c70403b6afeb844cf34c0b918be07020ae825458462598d8de
|
@@ -27,9 +27,15 @@ module Effective
|
|
27
27
|
@posts = @posts.where(search) if search.present?
|
28
28
|
end
|
29
29
|
|
30
|
+
if @category.present?
|
31
|
+
@page_title = @category.to_s
|
32
|
+
else
|
33
|
+
@page_title ||= view_context.posts_name_label
|
34
|
+
end
|
35
|
+
|
30
36
|
EffectiveResources.authorize!(self, :index, Effective::Post)
|
31
37
|
|
32
|
-
@page_title ||= [(@category ||
|
38
|
+
@page_title ||= [(@category || view_context.posts_name_label).to_s.titleize, (" - Page #{params[:page]}" if params[:page])].compact.join
|
33
39
|
@canonical_url ||= helpers.effective_post_category_url(params[:category], page: params[:page])
|
34
40
|
end
|
35
41
|
|
@@ -52,13 +58,12 @@ module Effective
|
|
52
58
|
'Hi Admin!',
|
53
59
|
('You are viewing a hidden post.' unless @post.published?),
|
54
60
|
('You are viewing an archived post.' if @post.archived?),
|
55
|
-
'
|
56
|
-
("<a href='#{effective_posts.edit_admin_post_path(@post)}' class='alert-link'>edit post settings</a>.")
|
61
|
+
("<a href='#{effective_posts.edit_admin_post_path(@post)}' class='alert-link'>Edit this post</a>.")
|
57
62
|
].compact.join(' ')
|
58
63
|
end
|
59
64
|
|
60
65
|
@page_title ||= @post.title
|
61
|
-
@meta_description ||= @post.description
|
66
|
+
@meta_description ||= (@post.description.presence || @post.title)
|
62
67
|
@canonical_url ||= effective_posts.post_url(@post)
|
63
68
|
end
|
64
69
|
|
@@ -26,12 +26,12 @@ class EffectivePostsDatatable < Effective::Datatable
|
|
26
26
|
|
27
27
|
col :draft?, as: :boolean, visible: false
|
28
28
|
col :published?, as: :boolean
|
29
|
-
col :published_start_at
|
30
|
-
col :published_end_at
|
29
|
+
col :published_start_at, label: "Published start"
|
30
|
+
col :published_end_at, label: "Published end"
|
31
31
|
|
32
32
|
col :archived
|
33
33
|
|
34
|
-
col :start_at
|
34
|
+
col :start_at, visible: EffectivePosts.categories.include?('Events')
|
35
35
|
col :end_at, visible: false
|
36
36
|
col :location, visible: false
|
37
37
|
col :created_at, label: 'Submitted at', visible: false
|
@@ -2,6 +2,21 @@ require 'cgi'
|
|
2
2
|
|
3
3
|
module EffectivePostsHelper
|
4
4
|
|
5
|
+
# Posts
|
6
|
+
def posts_name_label
|
7
|
+
et('effective_posts.name')
|
8
|
+
end
|
9
|
+
|
10
|
+
# Post
|
11
|
+
def post_label
|
12
|
+
et(Effective::Post)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Posts
|
16
|
+
def posts_label
|
17
|
+
ets(Effective::Post)
|
18
|
+
end
|
19
|
+
|
5
20
|
def effective_posts_header_tags
|
6
21
|
return unless @post && @post.kind_of?(Effective::Post) && @post.persisted? && @post.published?
|
7
22
|
|
@@ -54,17 +69,20 @@ module EffectivePostsHelper
|
|
54
69
|
link_to(category.to_s.titleize, effective_post_category_path(category), title: category.to_s.titleize)
|
55
70
|
end
|
56
71
|
|
72
|
+
def badge_to_post_category(category, options = {})
|
73
|
+
category = category.to_s.downcase
|
74
|
+
link_to(category.to_s.titleize, effective_post_category_path(category), title: category.to_s.titleize, class: "badge badge-primary badge-post mb-2 effective-posts-#{category.parameterize}")
|
75
|
+
end
|
76
|
+
|
57
77
|
def render_post(post)
|
58
78
|
render(partial: 'effective/posts/post', locals: { post: post })
|
59
79
|
end
|
60
80
|
|
61
81
|
def post_meta(post, date: true, datetime: false, category: true, author: true)
|
62
82
|
[
|
63
|
-
'
|
64
|
-
("
|
65
|
-
("
|
66
|
-
("to #{link_to_post_category(post.category)}" if category && Array(EffectivePosts.categories).length > 1),
|
67
|
-
("by #{post.user.to_s.presence || 'Unknown'}" if author && EffectivePosts.post_meta_author && post.user.present?)
|
83
|
+
("#{post.published_start_at.strftime('%A, %B %d, %Y')}" if date && post.published_start_at),
|
84
|
+
("#{post.published_start_at.strftime('%A, %B %d, %Y · %l:%M%P')}" if datetime && post.published_start_at),
|
85
|
+
("#{post.user.to_s.presence || 'Unknown'}" if author && EffectivePosts.post_meta_author && post.user.present?)
|
68
86
|
].compact.join(' ').html_safe
|
69
87
|
end
|
70
88
|
|
@@ -82,7 +100,8 @@ module EffectivePostsHelper
|
|
82
100
|
|
83
101
|
# All other options are passed to the link_to 'Read more'
|
84
102
|
def post_excerpt(post, label: 'Continue reading')
|
85
|
-
|
103
|
+
content = post.excerpt.presence || post.body.presence
|
104
|
+
(content.to_s + readmore_link(post, label: label)).html_safe
|
86
105
|
end
|
87
106
|
|
88
107
|
def read_more_link(post, options = {})
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Effective
|
2
4
|
class Post < ActiveRecord::Base
|
3
5
|
self.table_name = (EffectivePosts.posts_table_name || :posts).to_s
|
4
6
|
|
5
7
|
if defined?(PgSearch)
|
6
8
|
include PgSearch::Model
|
7
|
-
|
8
9
|
multisearchable against: [:body]
|
9
10
|
end
|
10
11
|
|
@@ -55,8 +56,8 @@ module Effective
|
|
55
56
|
self.user ||= current_user
|
56
57
|
end
|
57
58
|
|
58
|
-
validates :title, presence: true
|
59
|
-
validates :description,
|
59
|
+
validates :title, presence: true
|
60
|
+
validates :description, length: { maximum: 150 }
|
60
61
|
validates :category, presence: true
|
61
62
|
validates :start_at, presence: true, if: -> { category == 'events' }
|
62
63
|
|
@@ -1,51 +1,48 @@
|
|
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
|
+
- if Array(EffectivePosts.categories).length > 1
|
5
|
+
= f.select :category, EffectivePosts.categories
|
6
|
+
- else
|
7
|
+
= f.hidden_field :category, value: (EffectivePosts.categories.first || 'posts')
|
8
|
+
|
4
9
|
-# acts_as_published
|
5
10
|
= f.hide_if(:save_as_draft, true) do
|
6
11
|
.row
|
7
12
|
.col-md-6
|
8
|
-
= f.datetime_field :published_start_at, hint: 'The page will
|
13
|
+
= f.datetime_field :published_start_at, label: 'Published start', hint: 'The page will appear on the website after this date and time. Leave blank to publish immediately'
|
9
14
|
.col-md-6
|
10
|
-
= f.datetime_field :published_end_at, hint: 'The page will
|
15
|
+
= f.datetime_field :published_end_at, label: 'Published end', hint: 'The page will not appear on the website after this date and time. Leave blank for no end date.', date_linked: false
|
11
16
|
|
12
17
|
= 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
18
|
|
14
|
-
|
15
|
-
hint: "150 character summary. Appears on Google search results underneath the post title. ",
|
16
|
-
input_html: { maxlength: 150 }
|
17
|
-
|
19
|
+
- # acts_as_slugged
|
18
20
|
- if f.object.persisted? || f.object.errors.include?(:slug)
|
19
21
|
- current_url = effective_posts.post_path(f.object)
|
20
22
|
|
21
23
|
= f.text_field :slug, required: f.object.persisted?,
|
22
24
|
hint: "The slug controls this post's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This post is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url && f.object.slug.present? }".html_safe
|
23
25
|
|
24
|
-
- if
|
25
|
-
= f.
|
26
|
-
|
27
|
-
= f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages.'
|
28
|
-
|
29
|
-
- if Array(EffectivePosts.categories).length > 1
|
30
|
-
= f.select :category, EffectivePosts.categories
|
31
|
-
- else
|
32
|
-
= f.hidden_field :category, value: (EffectivePosts.categories.first || 'posts')
|
33
|
-
|
34
|
-
- if f.object.class.respond_to?(:acts_as_tagged?)
|
35
|
-
= render 'effective/tags/fields', f: f
|
26
|
+
- if EffectivePosts.use_description
|
27
|
+
= f.text_field :description, label: "Meta description", input_html: { maxlength: 150 },
|
28
|
+
hint: "150 character summary that appears on Google search result pages."
|
36
29
|
|
37
30
|
- if EffectivePosts.use_active_storage
|
38
|
-
= f.file_field :image, hint:
|
31
|
+
= f.file_field :image, label: "Image preview", hint: "Optional. Shown on the posts index and post pages. Dimensions are 220px tall and 350px wide."
|
32
|
+
|
33
|
+
- if EffectivePosts.use_excerpt
|
34
|
+
- if defined?(EffectiveArticleEditor)
|
35
|
+
= f.article_editor :excerpt, hint: 'Will be used for the post excerpt on index pages. Leave blank to use the body instead.'
|
36
|
+
- else
|
37
|
+
= f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages. Leave blank to use the body instead.'
|
39
38
|
|
40
39
|
- if defined?(EffectiveArticleEditor)
|
41
|
-
= f.article_editor :body
|
40
|
+
= f.article_editor :body
|
42
41
|
- else
|
43
|
-
= f.rich_text_area :body
|
42
|
+
= f.rich_text_area :body
|
44
43
|
|
45
44
|
= render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
|
46
45
|
|
47
|
-
= f.check_box :archived, label: 'Yes, this post is archived. It will not be displayed.'
|
48
|
-
|
49
46
|
- if EffectivePosts.use_effective_roles
|
50
47
|
= render partial: '/admin/posts/roles', locals: { post: post, form: f, f: f }
|
51
48
|
|
@@ -1,30 +1,35 @@
|
|
1
1
|
= effective_form_with(model: post, engine: true) do |f|
|
2
2
|
= f.text_field :title, hint: 'The title of your post.'
|
3
3
|
|
4
|
-
- if f.object.persisted? || f.object.errors.include?(:slug)
|
5
|
-
- current_url = effective_posts.post_path(f.object)
|
6
|
-
= f.text_field :slug, hint: "The slug controls this post's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This post is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url && f.object.slug.present? }".html_safe
|
7
|
-
|
8
4
|
- if Array(EffectivePosts.categories).length > 1
|
9
5
|
= f.select :category, EffectivePosts.categories
|
10
6
|
- else
|
11
7
|
= f.hidden_field :category, value: (EffectivePosts.categories.first || 'posts')
|
12
8
|
|
13
|
-
-
|
14
|
-
|
9
|
+
- # acts_as_slugged
|
10
|
+
- if f.object.persisted? || f.object.errors.include?(:slug)
|
11
|
+
- current_url = effective_posts.post_path(f.object)
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
- else
|
19
|
-
= f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages.'
|
13
|
+
= f.text_field :slug, required: f.object.persisted?,
|
14
|
+
hint: "The slug controls this post's internet address. Be careful, changing the slug will break links that other websites may have to the old address.<br>#{('This post is currently reachable via ' + link_to(current_url.gsub(f.object.slug, '<strong>' + f.object.slug + '</strong>').html_safe, current_url)) if current_url && f.object.slug.present? }".html_safe
|
20
15
|
|
21
|
-
|
16
|
+
- if EffectivePosts.use_description
|
17
|
+
= f.text_field :description, hint: 'The content of the post meta tags.', maxlength: 150
|
22
18
|
|
23
|
-
|
19
|
+
- if EffectivePosts.use_active_storage
|
20
|
+
= f.file_field :image, hint: 'An image for your post'
|
21
|
+
|
22
|
+
- if EffectivePosts.use_excerpt
|
23
|
+
- if defined?(EffectiveArticleEditor)
|
24
|
+
= f.article_editor :excerpt, hint: 'Will be used for the post excerpt on index pages.'
|
25
|
+
- else
|
26
|
+
= f.rich_text_area :excerpt, hint: 'Will be used for the post excerpt on index pages.'
|
24
27
|
|
25
28
|
- if defined?(EffectiveArticleEditor)
|
26
29
|
= f.article_editor :body, hint: 'The main body of your post'
|
27
30
|
- else
|
28
31
|
= f.rich_text_area :body, hint: 'The main body of your post'
|
29
32
|
|
33
|
+
= render partial: '/effective/posts/additional_fields', locals: { post: post, form: f, f: f }
|
34
|
+
|
30
35
|
= f.submit 'Save'
|
@@ -1,3 +1,2 @@
|
|
1
|
-
.
|
2
|
-
|
3
|
-
.col-sm-4= render 'sidebar'
|
1
|
+
.effective-posts.mb-3
|
2
|
+
= yield
|
@@ -1,9 +1,18 @@
|
|
1
|
-
.effective-post
|
2
|
-
|
1
|
+
.col.effective-post.mb-5
|
2
|
+
- if EffectivePosts.categories.length > 1 && post.category.present?
|
3
|
+
= badge_to_post_category(post.category)
|
3
4
|
|
4
|
-
|
5
|
+
- if EffectivePosts.use_active_storage && post.image && post.image.attached?
|
6
|
+
= link_to effective_posts.post_path(post) do
|
7
|
+
= image_tag url_for(post.image), class: "effective-posts-image d-none d-lg-flex align-self-start mb-2", alt: post.title, width: "350", height: "220"
|
8
|
+
|
9
|
+
.effective-posts-meta.mb-2
|
5
10
|
= post_meta(post, author: false)
|
6
11
|
= admin_post_status_badge(post)
|
7
12
|
|
8
|
-
.
|
9
|
-
|
13
|
+
%h2.effective-posts-title= link_to post, effective_post_path(post)
|
14
|
+
|
15
|
+
- if EffectivePosts.use_excerpt && post.excerpt.present?
|
16
|
+
.effective-posts-excerpt
|
17
|
+
= post.excerpt
|
18
|
+
|
@@ -1,8 +1,8 @@
|
|
1
|
-
%h1= @page_title
|
2
|
-
|
3
1
|
= render 'layout' do
|
4
|
-
.effective-
|
5
|
-
|
2
|
+
%h1.effective-title.mb-4= @page_title
|
3
|
+
|
4
|
+
.row.row-cols-1.row-cols-lg-3.effective-posts
|
5
|
+
= render @posts
|
6
6
|
|
7
7
|
%nav.d-flex.justify-content-center
|
8
8
|
= bootstrap_paginate(@posts, per_page: EffectivePosts.per_page)
|
@@ -1,12 +1,14 @@
|
|
1
1
|
= render 'layout' do
|
2
2
|
.effective-post
|
3
|
-
|
4
|
-
|
5
|
-
%p.post-meta.text-muted
|
3
|
+
.effective-posts-meta.mb-2
|
6
4
|
= post_meta(@post, author: false)
|
7
5
|
= admin_post_status_badge(@post)
|
8
6
|
|
7
|
+
%h1.effective-post-title.mb-4= @page_title
|
8
|
+
|
9
9
|
= render 'effective/posts/event', post: @post
|
10
10
|
|
11
|
-
.
|
11
|
+
.effective-posts-body.mb-5
|
12
12
|
= @post.body
|
13
|
+
|
14
|
+
= link_to("← #{posts_name_label}" .html_safe, effective_posts.posts_path, class: "btn btn-secondary my-4")
|
data/config/effective_posts.rb
CHANGED
@@ -41,6 +41,12 @@ EffectivePosts.setup do |config|
|
|
41
41
|
# Display a file upload field when the admin creates a new post to collect a post.image
|
42
42
|
config.use_active_storage = true
|
43
43
|
|
44
|
+
# Display the google search results description field on admin form
|
45
|
+
config.use_description = true
|
46
|
+
|
47
|
+
# Display the excerpt field on admin form
|
48
|
+
config.use_excerpt = true
|
49
|
+
|
44
50
|
# Submissions
|
45
51
|
# Allow users to submit posts (optionally for approval) to display on the website
|
46
52
|
config.submissions_enabled = true
|
data/lib/effective_posts.rb
CHANGED
@@ -10,7 +10,7 @@ module EffectivePosts
|
|
10
10
|
:categories, :event_categories,
|
11
11
|
:mailer, :parent_mailer, :deliver_method, :mailer_layout, :mailer_sender, :mailer_admin, :mailer_subject,
|
12
12
|
:use_category_routes, :use_blog_routes,
|
13
|
-
:use_effective_roles, :use_active_storage,
|
13
|
+
:use_effective_roles, :use_active_storage, :use_description, :use_excerpt,
|
14
14
|
:per_page, :post_meta_author,
|
15
15
|
:submissions_enabled, :submissions_require_current_user,
|
16
16
|
:submissions_require_approval, :submissions_note
|
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
|
+
version: 2.7.1
|
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: 2024-07-
|
11
|
+
date: 2024-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -196,7 +196,6 @@ files:
|
|
196
196
|
- app/views/effective/posts/_post.html.haml
|
197
197
|
- app/views/effective/posts/_recent_posts.html.haml
|
198
198
|
- app/views/effective/posts/_sidebar.html.haml
|
199
|
-
- app/views/effective/posts/_spacer.html.haml
|
200
199
|
- app/views/effective/posts/_upcoming_events.html.haml
|
201
200
|
- app/views/effective/posts/edit.html.haml
|
202
201
|
- app/views/effective/posts/index.html.haml
|
@@ -205,6 +204,7 @@ files:
|
|
205
204
|
- app/views/effective/posts/submitted.html.haml
|
206
205
|
- app/views/effective/posts_mailer/post_submitted.html.haml
|
207
206
|
- config/effective_posts.rb
|
207
|
+
- config/locales/effective_posts.en.yml
|
208
208
|
- config/routes.rb
|
209
209
|
- db/migrate/101_create_effective_posts.rb
|
210
210
|
- lib/effective_posts.rb
|
@@ -1 +0,0 @@
|
|
1
|
-
%hr
|