effective_pages 3.5.0 → 3.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: cf8ab6a872f5612cfc81a80d9a4616ef18ca85dc6b360e693fb24cd6039ced4e
4
- data.tar.gz: 903d3aec8b320e7a69e6cd01a971e2ef3c09f57ed38103e357e031b9fd418090
3
+ metadata.gz: 1a4bbe810bd4f30ca02c101c48465763f4c6f246bb2e89afa70ddb79e117df8b
4
+ data.tar.gz: a8780dabcf25e0403836da65af42af2497c120cbd6fa9b67388d2f66c24b2e74
5
5
  SHA512:
6
- metadata.gz: d4c3f5328c83713f2efba331743bcd99870432f2ba9d5defcda5926a82c2ad6d124191fec7987cb87442cc6d681869d8a4ccbf917394657f4d30be940b208479
7
- data.tar.gz: 7a8fad535372027cd5b87b2b0f72508f26731d6e07b3d0ef7e6b6bb007396674306cbe9e8f37974ad134d577d65989036a7d7774331d08dec0345191a7f02e2a
6
+ metadata.gz: 612e18117979fdc36a5eaf6db3db0041ec2192006a7965d23357efd56fd18f6976cfefb95eeb4159ad16db765e9a275d06abd235abd0d062aab2bd34288123ae
7
+ data.tar.gz: 301c723e79df66b45159ac505badabea9eac1ea68bd56eda0c57ef57ae4f9d1f6a47418c18bd985c9a75fada67ec20df6317f17a8483d1a0ce8fe96049a7b588
data/README.md CHANGED
@@ -211,6 +211,10 @@ if user.is?(:admin)
211
211
  end
212
212
  ```
213
213
 
214
+ ## Search
215
+
216
+ If you use `pg_search` then `Effective::Pages` will be also included on its `multisearch` by default, allowing you to search across all pages.
217
+
214
218
  ## License
215
219
 
216
220
  MIT License. Copyright [Code and Effect Inc.](http://www.codeandeffect.com/)
@@ -0,0 +1,15 @@
1
+ module Admin
2
+ class PermalinksController < ApplicationController
3
+ before_action(:authenticate_user!) if defined?(Devise)
4
+ before_action { EffectiveResources.authorize!(self, :admin, :effective_pages) }
5
+
6
+ include Effective::CrudController
7
+
8
+ page_title 'Permalinks'
9
+
10
+ def permitted_params
11
+ params.require(:effective_permalink).permit!
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ module Effective
2
+ class PermalinksController < ApplicationController
3
+ def redirect
4
+ @permalink = Effective::Permalink.find_by! slug: params[:slug]
5
+
6
+ authorize! :redirect, @permalink
7
+
8
+ redirect_to redirect_path_for(@permalink), allow_other_host: (@permalink.target == :url)
9
+ end
10
+
11
+ private
12
+
13
+ def redirect_path_for(permalink)
14
+ permalink.target == :attachment ? attachment_url(permalink.attachment) : permalink.url
15
+ end
16
+
17
+ def attachment_url(permalink)
18
+ Rails.application.routes.url_helpers.rails_blob_path(permalink, only_path: true)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ class EffectivePermalinksDatatable < Effective::Datatable
2
+
3
+ datatable do
4
+ col :id, visible: false
5
+ col :updated_at, visible: false
6
+
7
+ col :title
8
+ col :slug
9
+ col :summary
10
+
11
+ actions_col
12
+ end
13
+
14
+ collection do
15
+ Effective::Permalink.deep.all
16
+ end
17
+
18
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module EffectiveAlertsHelper
3
4
 
4
5
  def effective_alerts
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EffectivePermalinksHelper
4
+
5
+ def permalinks
6
+ @_effective_permalinks ||= Effective::Permalink.deep.order(:id)
7
+ end
8
+
9
+ def permalink_to(permalink_or_slug, options = {})
10
+ permalink =
11
+ if permalink_or_slug.kind_of?(String)
12
+ Effective::Permalink.find_by(slug: slug)
13
+ else
14
+ permalink_or_slug
15
+ end
16
+
17
+ link_to permalink, permalink.redirect_path, options
18
+ end
19
+
20
+ end
@@ -1,5 +1,38 @@
1
1
  module Effective
2
2
  class Page < ActiveRecord::Base
3
+ if defined?(PgSearch)
4
+ include PgSearch::Model
5
+
6
+ pg_search_scope :search,
7
+ against: [
8
+ :title,
9
+ :menu_title,
10
+ :meta_description,
11
+ :slug,
12
+ ],
13
+ associated_against: {
14
+ rich_texts: [:body],
15
+ },
16
+ using: { tsearch: { highlight: true }, trigram: { word_similarity: true } }
17
+
18
+ multisearchable against: [
19
+ :title,
20
+ :menu_title,
21
+ :meta_description,
22
+ :slug,
23
+ ],
24
+ associated_against: {
25
+ rich_texts: [:body],
26
+ },
27
+ using: {
28
+ trigram: {},
29
+ tsearch: {
30
+ highlight: true,
31
+ }
32
+ },
33
+ ranked_by: ":trigram" # Could rank by any column/expression, e.g.: (books.num_pages * :trigram) + (:tsearch / 2.0)
34
+ end
35
+
3
36
  attr_accessor :current_user
4
37
  attr_accessor :menu_root_level
5
38
 
@@ -76,6 +109,14 @@ module Effective
76
109
  published.where(menu: false).or(published.where(menu: true).where.not(id: menu_root_with_children))
77
110
  }
78
111
 
112
+ # Maybe change paginate to be an isolated function instead of a scope, so we can use it with PgSearch::Document when doing a whole app search?
113
+ scope :paginate, -> (page: nil, per_page: nil) {
114
+ page = (page || 1).to_i
115
+ offset = [(page - 1), 0].max * per_page
116
+
117
+ limit(per_page).offset(offset)
118
+ }
119
+
79
120
  before_validation(if: -> { menu? && menu_position.blank? }) do
80
121
  self.menu_position = (self.class.where(menu_parent: menu_parent).maximum(:menu_position) || -1) + 1
81
122
  end
@@ -0,0 +1,53 @@
1
+ module Effective
2
+ class Permalink < ApplicationRecord
3
+ self.table_name = (EffectivePages.permalinks_table_name || :permalinks).to_s
4
+
5
+ has_one_attached :attachment
6
+ has_one_purgable :attachment
7
+
8
+ acts_as_slugged
9
+
10
+ log_changes if respond_to?(:log_changes)
11
+
12
+ scope :deep, -> { with_attached_attachment }
13
+
14
+ effective_resource do
15
+ title :string
16
+ slug :string
17
+
18
+ url :string
19
+
20
+ summary :text
21
+
22
+ timestamps
23
+ end
24
+
25
+ validate :attachment_and_url_cannot_both_be_present
26
+
27
+ validates :title, presence: true
28
+ validates :attachment, presence: true, if: -> { url.blank? }
29
+ validates :url, presence: true, if: -> { attachment.blank? }, url: true
30
+
31
+ public
32
+
33
+ def to_s
34
+ title.presence || model_name.human
35
+ end
36
+
37
+ def redirect_path
38
+ "/permalinks/#{slug}"
39
+ end
40
+
41
+ def target
42
+ url.present? ? :url : :attachment
43
+ end
44
+
45
+ private
46
+
47
+ def attachment_and_url_cannot_both_be_present
48
+ if url.present? && (attachment.attached? && !attachment.marked_for_destruction?)
49
+ self.errors.add(:base, 'Attachment and URL cannot both be present')
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ = tabs do
2
+ = tab 'Permalink' do
3
+ = render '/admin/permalinks/form_permalink', permalink: permalink
4
+
5
+ - if permalink.persisted?
6
+ = tab 'Logs' do
7
+ = render_datatable(permalink.log_changes_datatable, inline: true, namespace: :admin)
@@ -0,0 +1,8 @@
1
+ = effective_form_with(model: [:admin, permalink], engine: true) do |f|
2
+ = f.text_field :title, required: true, hint: 'Title of the permalink to be displayed'
3
+ = f.text_field :slug, required: true, hint: 'Slug for link of the permalink'
4
+ = f.text_field :summary, required: true, hint: 'Summary explanation of the permalink not displayed'
5
+ = f.url_field :url, required: false, hint: 'The link if redirecting to a website or specific page'
6
+ = f.file_field :attachment, required: false, hint: 'The attachment of the permalink if redirecting to a document, image or other file'
7
+
8
+ = effective_submit(f)
@@ -4,6 +4,7 @@ EffectivePages.setup do |config|
4
4
  config.page_banners_table_name = :page_banners
5
5
  config.carousel_items_table_name = :carousel_items
6
6
  config.alerts_table_name = :alerts
7
+ config.permalinks_table_name = :permalinks
7
8
 
8
9
  # The menu names a page can belong to
9
10
  config.menus = [:main, :footer]
data/config/routes.rb CHANGED
@@ -2,15 +2,18 @@
2
2
 
3
3
  EffectivePages::Engine.routes.draw do
4
4
  namespace :admin do
5
- resources :pages, except: [:show]
6
- resources :page_sections, only: [:index, :edit, :update]
7
- resources :page_banners, except: [:show]
8
- resources :menus, only: [:index]
9
- resources :carousel_items, except: [:show]
10
- resources :alerts, except: [:show]
5
+ resources :pages, except: [:show]
6
+ resources :page_sections, only: [:index, :edit, :update]
7
+ resources :page_banners, except: [:show]
8
+ resources :menus, only: [:index]
9
+ resources :carousel_items, except: [:show]
10
+ resources :alerts, except: [:show]
11
+ resources :permalinks, except: [:show]
11
12
  end
12
13
 
13
14
  scope module: 'effective' do
15
+ get '/permalinks/:slug', to: 'permalinks#redirect', as: :permalink_redirect
16
+
14
17
  match '*id', to: 'pages#show', via: :get, as: :page, constraints: lambda { |req|
15
18
  Effective::Page.find_by_slug_or_id(req.path_parameters[:id] || '/').present?
16
19
  }
@@ -81,6 +81,15 @@ class CreateEffectivePages < ActiveRecord::Migration[4.2]
81
81
  t.timestamps
82
82
  end
83
83
 
84
+ create_table <%= @permalinks_table_name %>, if_not_exists: true do |t|
85
+ t.string :title
86
+ t.string :slug
87
+ t.string :url
88
+ t.text :summary
89
+
90
+ t.timestamps
91
+ end
92
+
84
93
  end
85
94
 
86
95
  def self.down
@@ -89,6 +98,7 @@ class CreateEffectivePages < ActiveRecord::Migration[4.2]
89
98
  drop_table <%= @page_sections_table_name %>
90
99
  drop_table <%= @carousel_items_table_name %>
91
100
  drop_table <%= @alerts_table_name %>
101
+ drop_table <%= @permalinks_table_name %>
92
102
  end
93
103
 
94
104
  end
@@ -12,6 +12,7 @@ module EffectivePages
12
12
  helper EffectivePageBannersHelper
13
13
  helper EffectiveMenusHelper
14
14
  helper EffectiveAlertsHelper
15
+ helper EffectivePermalinksHelper
15
16
  end
16
17
  end
17
18
  end
@@ -1,3 +1,3 @@
1
1
  module EffectivePages
2
- VERSION = '3.5.0'.freeze
2
+ VERSION = '3.6.0'.freeze
3
3
  end
@@ -7,7 +7,7 @@ require 'effective_pages/version'
7
7
  module EffectivePages
8
8
  def self.config_keys
9
9
  [
10
- :pages_table_name, :page_sections_table_name, :page_banners_table_name, :carousel_items_table_name, :alerts_table_name,
10
+ :pages_table_name, :page_sections_table_name, :page_banners_table_name, :carousel_items_table_name, :alerts_table_name, :permalinks_table_name,
11
11
  :pages_path, :excluded_pages, :layouts_path, :excluded_layouts,
12
12
  :site_og_image, :site_og_image_width, :site_og_image_height,
13
13
  :site_title, :site_title_suffix, :fallback_meta_description, :google_analytics_code,
@@ -25,6 +25,7 @@ module EffectivePages
25
25
  @page_banners_table_name = ':' + EffectivePages.page_banners_table_name.to_s
26
26
  @carousel_items_table_name = ':' + EffectivePages.carousel_items_table_name.to_s
27
27
  @alerts_table_name = ':' + EffectivePages.alerts_table_name.to_s
28
+ @permalinks_table_name = ':' + EffectivePages.permalinks_table_name.to_s
28
29
 
29
30
  migration_template ('../' * 3) + 'db/migrate/01_create_effective_pages.rb.erb', 'db/migrate/create_effective_pages.rb'
30
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: effective_pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.0
4
+ version: 3.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-06-01 00:00:00.000000000 Z
11
+ date: 2023-06-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -84,24 +84,29 @@ files:
84
84
  - app/controllers/admin/page_banners_controller.rb
85
85
  - app/controllers/admin/page_sections_controller.rb
86
86
  - app/controllers/admin/pages_controller.rb
87
+ - app/controllers/admin/permalinks_controller.rb
87
88
  - app/controllers/effective/pages_controller.rb
89
+ - app/controllers/effective/permalinks_controller.rb
88
90
  - app/datatables/effective_alerts_datatable.rb
89
91
  - app/datatables/effective_carousel_items_datatable.rb
90
92
  - app/datatables/effective_page_banners_datatable.rb
91
93
  - app/datatables/effective_page_sections_datatable.rb
92
94
  - app/datatables/effective_pages_datatable.rb
93
95
  - app/datatables/effective_pages_menu_datatable.rb
96
+ - app/datatables/effective_permalinks_datatable.rb
94
97
  - app/helpers/effective_alerts_helper.rb
95
98
  - app/helpers/effective_carousels_helper.rb
96
99
  - app/helpers/effective_menus_helper.rb
97
100
  - app/helpers/effective_page_banners_helper.rb
98
101
  - app/helpers/effective_page_sections_helper.rb
99
102
  - app/helpers/effective_pages_helper.rb
103
+ - app/helpers/effective_permalinks_helper.rb
100
104
  - app/models/effective/alert.rb
101
105
  - app/models/effective/carousel_item.rb
102
106
  - app/models/effective/page.rb
103
107
  - app/models/effective/page_banner.rb
104
108
  - app/models/effective/page_section.rb
109
+ - app/models/effective/permalink.rb
105
110
  - app/views/admin/alerts/_form.html.haml
106
111
  - app/views/admin/alerts/_form_alert.html.haml
107
112
  - app/views/admin/carousel_items/_form.html.haml
@@ -118,6 +123,8 @@ files:
118
123
  - app/views/admin/pages/_form_menu.html.haml
119
124
  - app/views/admin/pages/_form_page.html.haml
120
125
  - app/views/admin/pages/_rich_text_areas.html.haml
126
+ - app/views/admin/permalinks/_form.html.haml
127
+ - app/views/admin/permalinks/_form_permalink.html.haml
121
128
  - app/views/effective/alerts/_alert.html.haml
122
129
  - app/views/effective/carousels/_carousel.html.haml
123
130
  - app/views/effective/pages/_menu.html.haml