spanjaan / wn-site-search-plugin

此插件为 WinterCMS 添加全局搜索功能。

安装: 2

依赖: 0

建议: 0

安全: 0

星星: 0

关注者: 1

分支: 0

开放问题: 0

类型:winter-plugin

v1.0.1 2024-09-03 08:01 UTC

This package is auto-updated.

Last update: 2024-10-03 08:25:30 UTC


README

此插件为 WinterCMS 添加全局搜索功能。

分支自

此插件是 WinterCMS 兼容的原始 OFFLINE.SiteSearch 插件 for OctoberCMS 的分支。它已被修改以与 WinterCMS 无缝配合,保留了原始功能,并增加了针对 WinterCMS 生态系统的特定增强。

安装

composer require spanjaan/wn-site-search-plugin

可用语言

  • 英语
  • 德语
  • 捷克语
  • 俄语
  • 波斯语(法尔西语)
  • 葡萄牙语

您可以将所有内容翻译成自己的语言。

当前支持的内容类型

支持但已禁用

以下插件受支持但默认禁用。您可以通过删除以下文件中的注释手动激活它们

{PLUGIN ROOT}/models/settings/fields.yaml
{PLUGIN ROOT}/classes/SearchService.php

通过 Winter.Translate 支持多语言内容。

根据要求添加对更多插件的支持。

您可以将此插件轻松扩展以搜索自定义插件的 内容。有关更多信息,请参阅文档。

为您的插件获取原生支持

如果您是插件开发者并希望在自己的内容中为 SiteSearch 获取原生支持,请提交您的搜索提供者的拉取请求。

我们无法为每个插件添加支持,但将为 Winter Marketplace 上具有显著项目数的任何插件添加支持。

组件

searchResults

将此组件放在您的页面上以显示搜索结果。

使用示例

创建一个将查询发送到您的搜索页面的搜索表单

搜索表单
<form action="{{ 'search' | page }}" method="get">
    <input name="q" type="text" placeholder="What are you looking for?" autocomplete="off">
    <button type="submit">Search</button>
</form>

重要:使用 q 参数发送用户的查询。

您还可以使用下面描述的 searchInput 组件为您生成此表单。

搜索结果

创建一个页面以显示您的搜索结果。将 searchResults 组件添加到其中。使用 searchResults.query 参数显示用户的搜索查询。

title = "Search results"
url = "/search"
layout = "default"

[searchResults]
resultsPerPage = 10
showProviderBadge = 1
noResultsMessage = "Your search did not return any results."
visitPageMessage = "Visit page"
==
<h2>Search results for {{ searchResults.query }}</h2>

{% component 'searchResults' %}
用于设置组件样式的示例 CSS
.ss-result {
    margin-bottom: 2em;
}
.ss-result__aside {
    float: right;
    margin-left: .5em;
}
.ss-result__title {
    font-weight: bold;
    margin-bottom: .5em;
}
.ss-result__badge {
    font-size: .7em;
    padding: .2em .5em;
    border-radius: 4px;
    margin-left: .75em;
    background: #eee;
    display: inline-block;
}
.ss-result__text {
    margin-bottom: .5em;
}
.ss-result__url {
}

在搜索之前修改查询

如果您想在搜索执行之前修改用户的搜索查询,您可以从页面的 onStart 方法调用 searchResults 组件的 forceQuery 方法。

[searchResults]
resultsPerPage = 10
showProviderBadge = 1
noResultsMessage = "Your search returned no results."
visitPageMessage = "Visit page"
==
function onStart()
{
    $query = Request::get('q');
    $query = str_replace('ё', 'e', $query);
    $this->page->components['searchResults']->forceQuery($query);
}
==
{% component 'searchResults' %}

在显示之前更改结果集合

您可以监听 spanjaan.sitesearch.results 事件并根据需要修改查询。

这很有用,可以删除某些结果或更改排序顺序。

[searchResults]
resultsPerPage = 10
showProviderBadge = 1
noResultsMessage = "Your search returned no results."
visitPageMessage = "Visit page"
==
function onInit()
{
    \Event::listen('spanjaan.sitesearch.results', function ($results) {
        // return $results->filter(...);
        return $results->sortByDesc('model.custom_attribute');
    });
}
==
{% component 'searchResults' %}

属性

以下属性可用于更改组件的行为。

resultsPerPage

每页显示多少个结果。

showProviderBadge

搜索通过查询多个提供者(页面、博客或其他)进行。如果此选项启用,则每个搜索结果都会标记一个徽章以显示哪个提供者返回了结果。

如果您网站上有许多不同的实体(例如团队、员工、页面、博客条目),则此选项很有用。

noResultsMessage

如果没有结果返回,则显示此消息。

visitPageMessage

每个搜索结果下方都放置了一个链接。使用此属性来更改该链接的文本。

searchInput

将此组件放置在任何您想要显示具有“边打边搜”功能简单搜索输入的地方。

使用示例

searchInput组件添加到任何布局、部分或页面。

title = "Home"
url = "/"
...

[searchInput]
useAutoComplete = 1
autoCompleteResultCount = 5
showProviderBadge = 1
searchPage = "search.htm"
==
{% component 'searchInput' %}
用于设置组件样式的示例 CSS
.ss-search-form {
    position: relative;
}
.ss-search-form__results {
    display: none;
    position: absolute;
    left: 0;
    top: 35px;
    width: 100%;
    background: #fff;
    padding: 1em;
    box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
}
.ss-search-form__results--visible {
    display: block;
}

属性

以下属性可用于更改组件的行为。

useAutoComplete

如果启用此属性,则在用户开始键入时将执行搜索查询。

autoCompleteResultCount

将在输入框下方显示这么多结果给用户。用户可以点击“显示所有结果”链接,如果已通过searchPage属性指定,将带她到完整的搜索结果页面。

showProviderBadge

搜索通过查询多个提供者(页面、博客或其他)进行。如果此选项启用,则每个搜索结果都会标记一个徽章以显示哪个提供者返回了结果。

如果您网站上有许多不同的实体(例如团队、员工、页面、博客条目),则此选项很有用。

searchPage

放置searchResults组件的页面的文件名。如果用户点击“显示所有结果”链接,它将带他到这个页面,在那里使用searchResults组件执行完整的搜索。

添加对自定义插件内容的支持

简单方法

要为您的自定义插件返回搜索结果,在插件的自定义启动方法中注册对spanjaan.sitesearch.query事件的监听器。

返回包含一个provider字符串和results数组的数组。每个结果必须提供至少一个title键。

搜索自定义documents的示例

public function boot()
{
    \Event::listen('spanjaan.sitesearch.query', function ($query) {

        // The controller is used to generate page URLs.
        $controller = \Cms\Classes\Controller::getController() ?? new \Cms\Classes\Controller();

        // Search your plugin's contents
        $items = YourCustomDocumentModel
            ::where('title', 'like', "%${query}%")
            ->orWhere('content', 'like', "%${query}%")
            ->get();

        // Now build a results array
        $results = $items->map(function ($item) use ($query, $controller) {

            // If the query is found in the title, set a relevance of 2
            $relevance = mb_stripos($item->title, $query) !== false ? 2 : 1;

            // Optional: Add an age penalty to older results. This makes sure that
            // newer results are listed first.
            // if ($relevance > 1 && $item->created_at) {
            //    $ageInDays = $item->created_at->diffInDays(\Illuminate\Support\Carbon::now());
            //    $relevance -= \SpAnjaan\Sitesearch\Classes\Providers\ResultsProvider::agePenaltyForDays($ageInDays);
            // }

            return [
                'title'     => $item->title,
                'text'      => $item->content,
                'url'       => $controller->pageUrl('cms-page-file-name', ['slug' => $item->slug]),
                'thumb'     => optional($item->images)->first(), // Instance of System\Models\File
                'relevance' => $relevance, // higher relevance results in a higher
                                           // position in the results listing
                // 'meta' => 'data',       // optional, any other information you want
                                           // to associate with this result
                // 'model' => $item,       // optional, pass along the original model[]
            ];
        });

        return [
            'provider' => 'Document', // The badge to display for this result
            'results'  => $results,
        ];
    });
}

就是这样!

高级方法

如果您需要更多灵活性,您还可以创建自己的ResultsProvider类。只需扩展SiteSearch的ResultProvider并实现所需的方法。查看此插件提供的现有提供者,以了解所有可能性。

当您的自己的ResultsProvider类就绪时,在插件的自定义启动方法中注册对spanjaan.sitesearch.extend事件的监听器。在那里您可以返回一个ResultsProvider(或数组中的多个)每次用户在您的网站上运行搜索时都会包含在内。

搜索自定义documents的高级示例

public function boot()
{
    Event::listen('spanjaan.sitesearch.extend', function () {
        return new DocumentsSearchProvider();

        // or
        // return [new DocumentsSearchProvider(), new FilesSearchProvider()];
    });
}
<?php
use SpAnjaan\Sitesearch\Classes\Providers\ResultsProvider;

class DocumentsSearchProvider extends ResultsProvider
{
    public function search()
    {
        // Get your matching models
        $matching = YourCustomDocumentModel::where('title', 'like', "%{$this->query}%")
                                           ->orWhere('content', 'like', "%{$this->query}%")
                                           ->get();

        // Create a new Result for every match
        foreach ($matching as $match) {
            $result            = $this->newResult();

            $result->relevance = 1;
            $result->title     = $match->title;
            $result->text      = $match->description;
            $result->url       = $match->url;
            $result->thumb     = $match->image;
            $result->model     = $match;
            $result->meta      = [
                'some_data' => $match->some_other_property,
            ];

            // Add the results to the results collection
            $this->addResult($result);
        }

        return $this;
    }

    public function displayName()
    {
        return 'My Result';
    }

    public function identifier()
    {
        return 'VendorName.PluginName';
    }
}

设置

您可以在Winter CMS后端管理此插件的所有设置。

Winter.Pages

不需要特殊配置。

Winter.Blog

确保在后台设置中将包含blogPost组件的CMS页面选为博客文章页面

您可以通过{{ result.meta }}在搜索结果中访问帖子的发布日期。

Feegleweb.Octoshop

确保将产品详细页面URL设置设置为指向正确的URL。仅指定URL的固定部分:/product。如果您的产品位于/product/:slug下,则默认值即可。

Jiri.JKShop

确保将产品详细页面URL设置设置为指向正确的URL。仅指定URL的固定部分:/product。如果您的产品位于/product/:slug下,则默认值即可。

您可以通过{{ result.meta }}在搜索结果中访问文章的价格。

Indikator.News

确保将新闻帖子页面设置设置为指向正确的URL。仅指定URL的固定部分:/news/post。如果您的产品位于/news/post/:slug下,则默认值即可。

RadiantWeb.ProBlog

确保将博客文章页面URL设置设置为指向正确的URL。仅指定URL的固定部分:/blog。如果您的帖子位于/blog/:category/:slug下,则默认值即可。

ArrizalAmin.Portfolio

确保将项目详细页面URL设置设置为指向正确的URL。仅指定URL的固定部分:/portfolio/project。如果您的详细页面位于/portfolio/project/:slug下,则默认值即可。

VojtaSvoboda.Brands

确保将品牌详细页面URL设置设置为指向正确的URL。仅指定URL的固定部分:/brand。如果您的品牌详细页面位于/brand/:slug下,则仅插入/brand,无需slug参数。

CMS页面(实验性)

如果您想为CMS页面提供搜索结果,请将enabled设置更改为开启

您必须专门将组件 siteSearchInclude 添加到您希望搜索的每个 CMS 页面。没有这个组件的页面 将不会被搜索

此功能与包含组件但不需要依赖 URL 参数或其他变量(如页面编号)的简单页面结合得最好。具有动态 URL(如 /page/:slug)的 CMS 页面不会从搜索结果列表中正确链接。

如果您有具有更复杂动态内容的 CMS 页面,请考虑编写自己的搜索提供程序(参见 添加对自定义插件内容的支持

覆盖默认标记

要覆盖默认标记,请将 plugins/spanjaan/sitesearch/components/searchresults 下的所有文件复制到 themes/your-theme/partials/searchResults,并根据需要进行修改。

如果您为 searchResults 组件指定了别名,请确保将标记放入适当的部分目录 themes/your-theme/partials/your-given-alias