Skip to content
Snippets Groups Projects
Commit 9e8eb27b authored by Artem Dmitriiev's avatar Artem Dmitriiev Committed by Adam G-H
Browse files

Issue #3468271 by a.dmitriiev, phenaproxima, breidert, pameeela, poker10,...

Issue #3468271 by a.dmitriiev, phenaproxima, breidert, pameeela, poker10, catch: Add recipe for basic search with autocomplete
parent e27aa21e
No related branches found
No related tags found
1 merge request!127Resolve #3468271 "Search backend"
Pipeline #346728 failed
......@@ -62,6 +62,8 @@ default:
URL: 'git@git.drupal.org:project/drupal_cms_page.git'
- DIR: recipes/drupal_cms_privacy_basic
URL: 'git@git.drupal.org:project/drupal_cms_privacy_basic.git'
- DIR: recipes/drupal_cms_search
URL: 'git@git.drupal.org:project/drupal_cms_search.git'
- DIR: recipes/drupal_cms_seo_basic
URL: 'git@git.drupal.org:project/drupal_cms_seo_basic.git'
- DIR: recipes/drupal_cms_seo_tools
......
......@@ -64,6 +64,10 @@
"type": "path",
"url": "recipes/drupal_cms_privacy_basic"
},
"search": {
"type": "path",
"url": "recipes/drupal_cms_search"
},
"seo_basic": {
"type": "path",
"url": "recipes/drupal_cms_seo_basic"
......
{
"name": "drupal/drupal_cms_search",
"type": "drupal-recipe",
"description": "Provides a simple database-powered search, with autocomplete support.",
"require": {
"drupal/core": ">=10.4",
"drupal/search_api": "1.35",
"drupal/search_api_autocomplete": "^1.9",
"drupal/search_api_exclude": "^2.0",
"drupal/simple_search_form" : "^1.5"
},
"extra": {
"patches": {
"drupal/search_api": {
"#3483366: Allow to set the same view mode for all entity bundles in Search API plugins": "https://www.drupal.org/files/issues/2024-11-15/3483366-global-view-modes_0.patch"
},
"drupal/core": {
"#3483353: EntityDisplayBase::createCopy() naïvely assumes that the duplicate doesn't already exist": "https://www.drupal.org/files/issues/2024-11-15/3483353-create-copy-entity-display-config-action.patch"
}
}
},
"version": "dev-main"
}
status: true
dependencies:
config:
- search_api.server.database
- core.entity_view_mode.node.search_index
module:
- node
- search_api
- search_api_exclude
id: content
name: 'Content'
description: 'Can search within all content types.'
read_only: false
field_settings:
rendered_item:
label: 'Rendered HTML output'
property_path: rendered_item
type: text
configuration:
roles:
- anonymous
view_mode:
'entity:node':
':default': search_index
title:
label: Title
datasource_id: 'entity:node'
property_path: title
type: text
boost: 3.0
dependencies:
module:
- node
type:
label: 'Content type'
datasource_id: 'entity:node'
property_path: type
type: string
dependencies:
module:
- node
datasource_settings:
'entity:node':
bundles:
default: true
selected: { }
languages:
default: true
selected: { }
processor_settings:
add_url: { }
aggregated_field: { }
custom_value: { }
entity_status: { }
entity_type: { }
highlight:
weights:
postprocess_query: 0
prefix: '<strong>'
suffix: '</strong>'
excerpt: true
excerpt_always: false
excerpt_length: 256
exclude_fields: { }
highlight: always
highlight_partial: true
html_filter:
weights:
preprocess_index: -15
preprocess_query: -15
all_fields: false
fields:
- rendered_item
- title
- type
title: true
alt: true
tags:
b: 2
h1: 5
h2: 3
h3: 2
strong: 2
ignorecase:
weights:
preprocess_index: -20
preprocess_query: -20
all_fields: false
fields:
- rendered_item
- title
- type
language_with_fallback: { }
node_exclude: { }
rendered_item: { }
reverse_entity_references: { }
stemmer:
weights:
preprocess_index: 0
preprocess_query: 0
all_fields: false
fields:
- rendered_item
- title
exceptions:
mexican: mexic
texan: texa
tokenizer:
weights:
preprocess_index: -6
preprocess_query: -6
all_fields: false
fields:
- rendered_item
- title
spaces: ''
ignored: ._-
overlap_cjk: 1
minimum_word_size: '3'
tracker_settings:
default:
indexing_order: lifo
options:
cron_limit: 10
index_directly: true
track_changes_in_references: true
server: database
status: true
dependencies:
module:
- search_api_db
id: database
name: 'Database'
description: 'Uses database tables for indexing content.'
backend: search_api_db
backend_config:
database: 'default:default'
min_chars: 3
matching: partial
phrase: bigram
status: true
dependencies:
config:
- search_api.index.content
- views.view.search
module:
- views
- search_api_autocomplete
id: content_autocomplete
label: Content Autocomplete
index_id: content
suggester_settings:
live_results:
fields: { }
highlight:
enabled: false
field: ''
suggest_keys: false
view_modes: { }
suggester_weights:
live_results: 0
suggester_limits: { }
search_settings:
'views:search':
displays:
default: true
selected: { }
options:
limit: 10
min_length: 1
show_count: false
delay: null
submit_button_selector: ':submit'
autosubmit: true
status: true
dependencies:
config:
- search_api.index.content
module:
- search_api
- user
id: search
label: Search
module: views
description: 'Displays search results.'
tag: ''
base_table: search_api_index_content
base_field: search_api_id
display:
default:
id: default
display_title: Default
display_plugin: default
position: 0
display_options:
title: Search
fields:
rendered_item:
id: rendered_item
table: search_api_index_content
field: rendered_item
relationship: none
group_type: group
admin_label: ''
entity_type: null
entity_field: null
plugin_id: search_api
label: ''
exclude: false
alter:
alter_text: false
text: ''
make_link: false
path: ''
absolute: false
external: false
replace_spaces: false
path_case: none
trim_whitespace: false
alt: ''
rel: ''
link_class: ''
prefix: ''
suffix: ''
target: ''
nl2br: false
max_length: 0
word_boundary: true
ellipsis: true
more_link: false
more_link_text: ''
more_link_path: ''
strip_tags: false
trim: false
preserve_tags: ''
html: false
element_type: ''
element_class: ''
element_label_type: ''
element_label_class: ''
element_label_colon: true
element_wrapper_type: ''
element_wrapper_class: ''
element_default_classes: true
empty: ''
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_item: false
use_highlighting: false
multi_type: separator
multi_separator: ', '
pager:
type: mini
options:
offset: 0
pagination_heading_level: h4
items_per_page: 10
total_pages: null
id: 0
tags:
next: ››
previous: ‹‹
expose:
items_per_page: false
items_per_page_label: 'Items per page'
items_per_page_options: '5, 10, 25, 50'
items_per_page_options_all: false
items_per_page_options_all_label: '- All -'
offset: false
offset_label: Offset
exposed_form:
type: basic
options:
submit_button: Find
reset_button: false
reset_button_label: Reset
exposed_sorts_label: 'Sort by'
expose_sort_order: true
sort_asc_label: Asc
sort_desc_label: Desc
access:
type: perm
options:
perm: 'access content'
cache:
type: search_api_tag
options: { }
empty: { }
sorts:
search_api_relevance:
id: search_api_relevance
table: search_api_index_content
field: search_api_relevance
relationship: none
group_type: group
admin_label: ''
plugin_id: search_api
order: DESC
expose:
label: ''
field_identifier: ''
exposed: false
arguments: { }
filters:
search_api_fulltext:
id: search_api_fulltext
table: search_api_index_content
field: search_api_fulltext
relationship: none
group_type: group
admin_label: ''
plugin_id: search_api_fulltext
operator: or
value: ''
group: 1
exposed: true
expose:
operator_id: search_api_fulltext_op
label: ''
description: ''
use_operator: false
operator: search_api_fulltext_op
operator_limit_selection: false
operator_list: { }
identifier: text
required: false
remember: false
multiple: false
remember_roles:
authenticated: authenticated
anonymous: '0'
content_editor: '0'
administrator: '0'
expose_fields: false
placeholder: 'Enter search keywords'
searched_fields_id: search_api_fulltext_searched_fields
value_maxlength: 128
is_grouped: false
group_info:
label: ''
description: ''
identifier: ''
optional: true
widget: select
multiple: false
remember: false
default_group: All
default_group_multiple: { }
group_items: { }
parse_mode: terms
min_length: null
fields: { }
style:
type: default
row:
type: search_api
options:
view_modes:
'entity:node':
':default': search_result
query:
type: search_api_query
options:
bypass_access: false
skip_access: false
preserve_facet_query_args: false
query_tags: { }
relationships: { }
header: { }
footer: { }
display_extenders: { }
cache_metadata:
max-age: -1
contexts:
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags:
- 'config:search_api.index.content'
- 'search_api_list:content'
page_1:
id: page_1
display_title: Page
display_plugin: page
position: 1
display_options:
display_extenders: { }
path: search
cache_metadata:
max-age: -1
contexts:
- 'languages:language_interface'
- url
- url.query_args
- 'user.node_grants:view'
- user.permissions
tags:
- 'config:search_api.index.content'
- 'search_api_list:content'
name: Search
type: Drupal CMS
description: Provides a simple database-powered search, with autocomplete support.
install:
- block
# Basic search is for node entity type only at the moment.
- node
- search_api
- search_api_autocomplete
- search_api_db
- search_api_exclude
- simple_search_form
- views
config:
strict: false
import:
# Use core node view modes for indexing and displaying results.
node:
- core.entity_view_mode.node.search_index
- core.entity_view_mode.node.search_result
actions:
# Enable Search API Exclude for all content types.
node.type.*:
setThirdPartySetting:
module: search_api_exclude
key: enabled
value: 1
createForEachIfNotExists:
# Create view display "Search result highlighting input" for all available content types.
core.entity_view_display.node.%bundle.search_result:
status: true
targetEntityType: node
mode: search_result
bundle: '%bundle'
# Create view display "Search Index" for all available content types.
core.entity_view_display.node.*.default:
# Clone the "Default" view display by default.
createCopy:
mode: search_index
use_existing: true
# Make sure view display "Search result highlighting input" contains field "Search result excerpt".
core.entity_view_display.node.*.search_result:
setComponent:
name: search_api_excerpt
options:
weight: 0
region: content
# Add the search form to the header of the page.
block.block.search_form:
placeBlockInDefaultTheme:
id: search_form
# The region accepts an array keyed by theme name.
region:
olivero: primary_menu
drupal_cms_olivero: primary_menu
# A fallback used if no match found in the region array.
default_region: content
# Place the block before any blocks already in the region.
position: first
plugin: simple_search_form_block
settings:
label: 'Search form'
label_display: '0'
provider: simple_search_form
action_path: /search
get_parameter: text
input_type: search_api_autocomplete
search_api_autocomplete:
search_id: content_autocomplete
display: page_1
arguments: ''
filter: text
input_label: Search
input_label_display: invisible
input_placeholder: 'Enter search keywords'
input_css_classes: ''
submit_display: true
submit_label: Find
input_keep_value: false
preserve_url_query_parameters: { }
user.role.anonymous:
grantPermission: 'use search_api_autocomplete for content_autocomplete'
user.role.authenticated:
grantPermission: 'use search_api_autocomplete for content_autocomplete'
<?php
declare(strict_types=1);
namespace Drupal\Tests\drupal_cms_search\Functional;
use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait;
use Drupal\Tests\BrowserTestBase;
/**
* @group drupal_cms_search
*/
class ComponentValidationTest extends BrowserTestBase {
use RecipeTestTrait;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritdoc}
*/
protected static $modules = ['block', 'node'];
public function test(): void {
// The PlaceBlock config action has a core bug, where it doesn't account
// for the possibility of there being no blocks in a region. As a
// workaround, prevent that from happening by placing a useless block into
// the content region.
$this->drupalPlaceBlock('system_powered_by_block');
$dir = realpath(__DIR__ . '/../../..');
// The recipe should apply cleanly.
$this->applyRecipe($dir);
// Apply it again to prove that it is idempotent.
$this->applyRecipe($dir);
}
}
......@@ -14,6 +14,7 @@
"drupal/drupal_cms_media_tools": "*",
"drupal/drupal_cms_olivero": "*",
"drupal/drupal_cms_privacy_basic": "*",
"drupal/drupal_cms_search": "*",
"drupal/drupal_cms_seo_basic": "*",
"drupal/drupal_cms_dashboard": "*",
"drupal/easy_email_express": "1.0.1",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment