effective_search 0.2.0 → 0.2.1
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 +4 -4
- data/app/assets/stylesheets/effective_search/base.scss +26 -0
- data/app/controllers/admin/search_contents_controller.rb +13 -0
- data/app/datatables/admin/effective_search_contents_datatable.rb +23 -0
- data/app/models/concerns/effective_search_search.rb +29 -6
- data/app/models/effective/search_content.rb +42 -0
- data/app/views/admin/search_contents/_form.html.haml +7 -0
- data/app/views/admin/search_contents/_form_search_content.html.haml +13 -0
- data/app/views/effective/search/_form.html.haml +5 -3
- data/app/views/effective/search/_search.html.haml +26 -7
- data/app/views/effective/search/index.html.haml +7 -0
- data/app/views/effective/search_contents/_search_content.html.haml +16 -0
- data/config/routes.rb +1 -0
- data/db/migrate/101_create_effective_search.rb +9 -0
- data/lib/effective_search/version.rb +1 -1
- data/lib/effective_search.rb +1 -1
- metadata +7 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 11770692b109202d028619f343a7f20e32cf84ebb5d25862c1783af0b7247522
|
4
|
+
data.tar.gz: 9feec5773a0e9cb0c0f308f94d956dd68f7d92e063781d2e6a45a65359a4423a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62b1a07b867c7ab4d071b637971d61066703053e7489487fc59dda87cb4a20f0a866085c7021e566ae7557f7e8769c871f769a4912c2d0c882ab973b5c3ddeaa
|
7
|
+
data.tar.gz: 2b683dcf2e40676564757a1b5ab93dd9b1a5618a8fccba94f7a24b0c88f11de4cf8a360d661c0a54a1c630dc4edee9ded771e5729154264b1a7f36970752fd52
|
@@ -29,3 +29,29 @@ div.effective-search {
|
|
29
29
|
background-position: calc(100% - 0.75rem) center !important;
|
30
30
|
}
|
31
31
|
}
|
32
|
+
|
33
|
+
// Search contents
|
34
|
+
.search-content {
|
35
|
+
box-shadow: 0px 3px 16px #00000029 !important;
|
36
|
+
border-radius: 0.25rem !important;
|
37
|
+
margin-bottom: 3rem;
|
38
|
+
}
|
39
|
+
|
40
|
+
.search-content-title {
|
41
|
+
font-size: 1.75rem;
|
42
|
+
margin-bottom: 0.5rem;
|
43
|
+
}
|
44
|
+
|
45
|
+
.search-content-image {
|
46
|
+
min-width: 300px;
|
47
|
+
min-height: 300px;
|
48
|
+
}
|
49
|
+
|
50
|
+
.search-content-body {
|
51
|
+
padding: 30px;
|
52
|
+
}
|
53
|
+
|
54
|
+
.search-content-link {
|
55
|
+
font-weight: 700;
|
56
|
+
text-decoration: none;
|
57
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Admin
|
2
|
+
class SearchContentsController < ApplicationController
|
3
|
+
before_action(:authenticate_user!) if defined?(Devise)
|
4
|
+
before_action { EffectiveResources.authorize!(self, :admin, :effective_search) }
|
5
|
+
|
6
|
+
include Effective::CrudController
|
7
|
+
|
8
|
+
def permitted_params
|
9
|
+
params.require(:effective_search_content).permit!
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Admin
|
2
|
+
class EffectiveSearchContentsDatatable < Effective::Datatable
|
3
|
+
datatable do
|
4
|
+
order :updated_at, :desc
|
5
|
+
|
6
|
+
col :id, visible: false
|
7
|
+
col :created_at, visible: false
|
8
|
+
col :updated_at, visible: false
|
9
|
+
|
10
|
+
col :title
|
11
|
+
col :url
|
12
|
+
col :keywords
|
13
|
+
col :rich_text_body, label: 'Body', visible: false
|
14
|
+
col :file, visible: false
|
15
|
+
|
16
|
+
actions_col
|
17
|
+
end
|
18
|
+
|
19
|
+
collection do
|
20
|
+
Effective::SearchContent.deep.all
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -30,6 +30,11 @@ module EffectiveSearchSearch
|
|
30
30
|
nil
|
31
31
|
end
|
32
32
|
|
33
|
+
# These classes should not be searched
|
34
|
+
def unsearchable_types
|
35
|
+
['Effective::Permalink', 'Effective::SearchContent']
|
36
|
+
end
|
37
|
+
|
33
38
|
def per_page
|
34
39
|
24
|
35
40
|
end
|
@@ -47,6 +52,18 @@ module EffectiveSearchSearch
|
|
47
52
|
@search_results
|
48
53
|
end
|
49
54
|
|
55
|
+
# This is Set #1 of results we display on the search page
|
56
|
+
def search_contents
|
57
|
+
return [] unless present?
|
58
|
+
@search_contents ||= Effective::Resource.new(Effective::SearchContent.deep).search_any(term, columns: [:keywords])
|
59
|
+
end
|
60
|
+
|
61
|
+
# This is Set #2 of results we display on the search page
|
62
|
+
def permalinks
|
63
|
+
return [] unless present?
|
64
|
+
@permalinks ||= Effective::Resource.new(Effective::Permalink.deep).search_any(term, columns: [:title, :summary])
|
65
|
+
end
|
66
|
+
|
50
67
|
# The unpaginated results of the search
|
51
68
|
def search_results
|
52
69
|
@search_results || []
|
@@ -62,9 +79,7 @@ module EffectiveSearchSearch
|
|
62
79
|
|
63
80
|
# View helper
|
64
81
|
def authorized?(result)
|
65
|
-
|
66
|
-
|
67
|
-
searchable = result.searchable
|
82
|
+
searchable = result.try(:searchable) || result
|
68
83
|
|
69
84
|
return false if searchable.blank?
|
70
85
|
return false if searchable.try(:draft?)
|
@@ -79,7 +94,7 @@ module EffectiveSearchSearch
|
|
79
94
|
|
80
95
|
# View helper
|
81
96
|
def title(result)
|
82
|
-
(result.try(:searchable).try(:title) || result.
|
97
|
+
(result.try(:searchable).try(:title) || result.try(:title) || result).to_s.html_safe
|
83
98
|
end
|
84
99
|
|
85
100
|
# View helper
|
@@ -89,7 +104,7 @@ module EffectiveSearchSearch
|
|
89
104
|
|
90
105
|
# View helper
|
91
106
|
def body(result)
|
92
|
-
content = result.try(:pg_search_highlight) || result.to_s
|
107
|
+
content = (result.try(:pg_search_highlight) || result.try(:rich_text_body) || result).to_s
|
93
108
|
scrubs.each { |pattern| content.gsub!(pattern, '') }
|
94
109
|
content.html_safe
|
95
110
|
end
|
@@ -120,6 +135,10 @@ module EffectiveSearchSearch
|
|
120
135
|
collection = collection.where(searchable_type: searchable_types)
|
121
136
|
end
|
122
137
|
|
138
|
+
if unsearchable_types.present?
|
139
|
+
collection = collection.where.not(searchable_type: unsearchable_types)
|
140
|
+
end
|
141
|
+
|
123
142
|
# Preload what we need
|
124
143
|
collection = collection.includes(searchable: [:rich_text_body])
|
125
144
|
|
@@ -129,7 +148,9 @@ module EffectiveSearchSearch
|
|
129
148
|
|
130
149
|
# Sort of a view helper. The result is passed through here
|
131
150
|
def effective_path(result)
|
132
|
-
|
151
|
+
class_name = result.try(:searchable_type) || result.class.name
|
152
|
+
|
153
|
+
case class_name
|
133
154
|
when 'Effective::Page'
|
134
155
|
EffectivePages::Engine.routes.url_helpers.page_path(result.searchable)
|
135
156
|
when 'Effective::Permalink'
|
@@ -138,6 +159,8 @@ module EffectiveSearchSearch
|
|
138
159
|
EffectivePosts::Engine.routes.url_helpers.post_path(result.searchable)
|
139
160
|
when 'Effective::Event'
|
140
161
|
EffectiveEvents::Engine.routes.url_helpers.event_path(result.searchable)
|
162
|
+
when 'Effective::SearchContent'
|
163
|
+
result.url
|
141
164
|
end
|
142
165
|
end
|
143
166
|
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Provides content areas that will be displayed for specific search terms
|
2
|
+
|
3
|
+
module Effective
|
4
|
+
class SearchContent < ActiveRecord::Base
|
5
|
+
self.table_name = (EffectiveSearch.search_contents_table_name || :search_contents).to_s
|
6
|
+
|
7
|
+
# For the body
|
8
|
+
has_many_rich_texts
|
9
|
+
|
10
|
+
has_one_attached :file
|
11
|
+
has_one_purgable :file
|
12
|
+
|
13
|
+
log_changes if respond_to?(:log_changes)
|
14
|
+
|
15
|
+
effective_resource do
|
16
|
+
title :string
|
17
|
+
url :string
|
18
|
+
keywords :string
|
19
|
+
|
20
|
+
timestamps
|
21
|
+
end
|
22
|
+
|
23
|
+
validates :title, presence: true
|
24
|
+
validates :url, presence: true, url: true
|
25
|
+
validates :keywords, presence: true
|
26
|
+
|
27
|
+
validates :file, content_type: :image
|
28
|
+
validates :file, size: { less_than: 2.megabytes }
|
29
|
+
|
30
|
+
scope :deep, -> { with_attached_file.includes(:rich_texts) }
|
31
|
+
scope :sorted, -> { order(:title) }
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
title.presence || model_name.human
|
35
|
+
end
|
36
|
+
|
37
|
+
# As per has_many_rich_texts
|
38
|
+
def body
|
39
|
+
rich_text_body
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
= tabs do
|
2
|
+
= tab 'Search Content' do
|
3
|
+
= render '/admin/search_contents/form_search_content', search_content: search_content
|
4
|
+
|
5
|
+
- if search_content.persisted?
|
6
|
+
= tab 'Logs' do
|
7
|
+
= render_datatable(search_content.log_changes_datatable, inline: true, namespace: :admin)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
= effective_form_with(model: [:admin, search_content], engine: true) do |f|
|
2
|
+
= f.text_field :title
|
3
|
+
= f.url_field :url, hint: 'The URL of the page to link to'
|
4
|
+
= f.text_field :keywords, hint: 'A comma separated list of keywords'
|
5
|
+
|
6
|
+
- if defined?(EffectiveArticleEditor)
|
7
|
+
= f.article_editor :rich_text_body, label: 'Body', hint: 'The main content'
|
8
|
+
- else
|
9
|
+
= f.rich_text_area :rich_text_body, label: 'Body', hint: 'The main content'
|
10
|
+
|
11
|
+
= f.file_field :file, label: 'Attachment', hint: 'Upload an image to display on this search content'
|
12
|
+
|
13
|
+
= effective_submit(f)
|
@@ -1,5 +1,7 @@
|
|
1
1
|
= effective_form_with(scope: :q, model: search, method: :get, url: effective_search.search_path) do |f|
|
2
|
-
|
2
|
+
.row
|
3
|
+
.col-lg-4
|
4
|
+
= f.text_field :term, label: false, placeholder: 'Search', autofocus: true, class: "py-4 px-3 shadow-sm border-0"
|
3
5
|
|
4
|
-
= f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
|
5
|
-
= link_to 'Reset', request.path
|
6
|
+
-# = f.save('Search', class: 'btn btn-primary btn-search mr-3', name: nil)
|
7
|
+
-# = link_to 'Reset', request.path
|
@@ -5,13 +5,32 @@
|
|
5
5
|
%hr
|
6
6
|
|
7
7
|
- results = search.results(page: params[:page])
|
8
|
+
- search_contents = search.search_contents.select { |resource| search.authorized?(resource) }
|
9
|
+
- permalinks = search.permalinks.select { |resource| search.authorized?(resource) }
|
8
10
|
|
9
|
-
- if
|
10
|
-
|
11
|
+
- if search_contents.present?
|
12
|
+
= render(collection: search_contents, partial: 'effective/search_contents/search_content', locals: { search: search })
|
11
13
|
|
12
|
-
|
13
|
-
-
|
14
|
-
|
14
|
+
.row
|
15
|
+
- if permalinks.present?
|
16
|
+
.col-xl-4.col-lg-5
|
17
|
+
%h3 Downloads
|
18
|
+
%hr.mt-0
|
19
|
+
%ul
|
20
|
+
- permalinks.each do |permalink|
|
21
|
+
%li= link_to(permalink.title, permalink.redirect_path, target: '_blank', title: permalink.title)
|
15
22
|
|
16
|
-
|
17
|
-
|
23
|
+
-# Search results
|
24
|
+
%div{class: (permalinks.present? ? 'col-xl-8 col-lg-7' : 'col')}
|
25
|
+
%h3 Pages
|
26
|
+
%hr.mt-0
|
27
|
+
|
28
|
+
- if results.length == 0
|
29
|
+
.alert.alert-info There are no results for your search. Please try again.
|
30
|
+
|
31
|
+
- if results.length > 0
|
32
|
+
- collection = results.with_pg_search_highlight.select { |result| search.authorized?(result) }
|
33
|
+
= render(collection: collection, partial: 'effective/search/result', locals: { search: search })
|
34
|
+
|
35
|
+
%nav.d-flex.justify-content-center
|
36
|
+
= bootstrap_paginate(results, per_page: search.per_page)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
.search-content.d-flex
|
2
|
+
- title = search.title(search_content)
|
3
|
+
- url = search.path(search_content)
|
4
|
+
|
5
|
+
- if search_content.file.attached?
|
6
|
+
= link_to(url, title: title) do
|
7
|
+
= image_tag(url_for(search_content.file), alt: title, class: 'img-fluid search-content-image d-none d-md-block', height: search_content.file.metadata['height'], width: search_content.file.metadata['width'])
|
8
|
+
|
9
|
+
.search-content-body
|
10
|
+
%h4.search-content-title= link_to(title, url, title: title)
|
11
|
+
= search.body(search_content)
|
12
|
+
|
13
|
+
.search-content-link
|
14
|
+
= link_to(url, title: title) do
|
15
|
+
View more
|
16
|
+
%span.pl-1 →
|
data/config/routes.rb
CHANGED
@@ -11,6 +11,14 @@ class CreateEffectiveSearch < ActiveRecord::Migration[7.0]
|
|
11
11
|
t.belongs_to :searchable, polymorphic: true, index: true
|
12
12
|
t.timestamps null: false
|
13
13
|
end
|
14
|
+
|
15
|
+
create_table :search_contents, if_not_exists: true do |t|
|
16
|
+
t.string :title
|
17
|
+
t.string :url
|
18
|
+
t.string :keywords
|
19
|
+
|
20
|
+
t.timestamps
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
24
|
def down
|
@@ -21,5 +29,6 @@ class CreateEffectiveSearch < ActiveRecord::Migration[7.0]
|
|
21
29
|
|
22
30
|
# PgSearch multisearch table
|
23
31
|
drop_table :pg_search_documents, if_exists: true
|
32
|
+
drop_table :search_contents, if_exists: true
|
24
33
|
end
|
25
34
|
end
|
data/lib/effective_search.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_search
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
@@ -165,16 +165,22 @@ files:
|
|
165
165
|
- app/assets/javascripts/effective_search/base.js
|
166
166
|
- app/assets/stylesheets/effective_search.scss
|
167
167
|
- app/assets/stylesheets/effective_search/base.scss
|
168
|
+
- app/controllers/admin/search_contents_controller.rb
|
168
169
|
- app/controllers/effective/search_controller.rb
|
170
|
+
- app/datatables/admin/effective_search_contents_datatable.rb
|
169
171
|
- app/helpers/effective_search_helper.rb
|
170
172
|
- app/models/concerns/effective_search_search.rb
|
171
173
|
- app/models/effective/search.rb
|
174
|
+
- app/models/effective/search_content.rb
|
175
|
+
- app/views/admin/search_contents/_form.html.haml
|
176
|
+
- app/views/admin/search_contents/_form_search_content.html.haml
|
172
177
|
- app/views/effective/search/_form.html.haml
|
173
178
|
- app/views/effective/search/_form_nav_item.html.haml
|
174
179
|
- app/views/effective/search/_layout.html.haml
|
175
180
|
- app/views/effective/search/_result.html.haml
|
176
181
|
- app/views/effective/search/_search.html.haml
|
177
182
|
- app/views/effective/search/index.html.haml
|
183
|
+
- app/views/effective/search_contents/_search_content.html.haml
|
178
184
|
- config/effective_search.rb
|
179
185
|
- config/routes.rb
|
180
186
|
- db/migrate/101_create_effective_search.rb
|