skripteria/wn-site-search-plugin

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

安装: 406

依赖: 0

建议者: 0

安全: 0

星标: 5

关注者: 1

分支: 3

开放问题: 0

类型:winter-plugin

v2.0.2 2021-10-19 14:53 UTC

This package is auto-updated.

Last update: 2024-09-08 11:52:04 UTC


README

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

感谢 OFFLINE Gmbh 开发了这个优秀的插件,它最初是为 October CMS 定制的!

支持的语言

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

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

当前支持的内容类型

支持但已禁用

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

{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' %}

在显示之前更改结果集合

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

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

[searchResults]
resultsPerPage = 10
showProviderBadge = 1
noResultsMessage = "Your search returned no results."
visitPageMessage = "Visit page"
==
function onInit()
{
    \Event::listen('skripteria.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 组件执行完整搜索。

添加自定义插件内容支持

简单方法

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

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

搜索自定义 documents 的示例

public function boot()
{
    \Event::listen('skripteria.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 -= \Skripteria\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 类准备就绪时,请在插件的自启动方法中注册对 skripteria.sitesearch.extend 事件的监听器。在那里,您可以返回一个 ResultsProvider(或一个数组中的多个)将在用户在您的网站上运行搜索时包含。

搜索自定义 documents 的高级示例

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

        // or
        // return [new DocumentsSearchProvider(), new FilesSearchProvider()];
    });
}
<?php
use Skripteria\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/skripteria/sitesearch/components/searchresults目录下的所有文件复制到themes/your-theme/partials/searchResults,并根据需要进行修改。

如果您为searchResults组件提供了一个别名,请确保将标记放在适当的分部目录中themes/your-theme/partials/your-given-alias