在实现搜索结果分页时,我遇到了在 Shopware 6 中生成 SEO 友好 URL 的问题。我有一个自定义 Twig 模板,它从店面扩展了 pagination.html.twig 模板。该代码非常适合在类别中生成 SEO URL,但从搜索结果页面导航到第 2 页(从第 1 页)时遇到问题。
问题似乎围绕着我如何修改 seoParams 并处理搜索结果页面的 currentNavigationId 。这是代码的简化版本
{# Extend the 'pagination.html.twig' template from the storefront #}
{% sw_extends '@Storefront/storefront/component/pagination.html.twig' %}
{# Define the 'component_pagination' block #}
{% block component_pagination %}
{# Access the 'SwagPagination' data from the context #}
{% set SwagPaginationData = context.context.extensions.SwagPagination %}
{# Check if SwagPagination is active #}
{% if SwagPaginationData.active %}
{# Check if active navigation ID is defined in page header #}
{% if page.header.navigation.active.id is defined %}
{% set currentNavigationId = page.header.navigation.active.id %}
{% endif %}
{# Check if navigation ID is defined in search filters #}
{% if searchResult.currentFilters.navigationId is defined %}
{% set currentNavigationId = searchResult.currentFilters.navigationId %}
{% endif %}
{# Loop through each page #}
{% for i in 1..totalPages %}
{# Set up an empty SEO parameters object #}
{% set seoParams = {} %}
{# Retrieve and modify query parameters #}
{% set seoParams = context.context.extensions.tanmarNgSeoPagination.queryParameters %}
{#slots and no-aggregations are not needed query parameters#}
{% set keysToRemove = ['slots', 'no-aggregations'] %}
{% set seoParams = seoParams|remove_keys(keysToRemove) %}
{# Check if the current page is not equal to the current iteration #}
{% if i != currentPage %}
{% if currentPage %}
{% set seoParams = seoParams|merge({ p: i }) %}
{% endif %}
{# Properly encode the SEO parameters into a string before using it #}
{% set seoParams = '?' ~ seoParams|url_encode %}
{# Check if currentNavigationId is defined and generate SEO-friendly URL #}
{% if currentNavigationId is defined %}
{{ dump(seoParams) }}
<a href="{{ seoUrl('frontend.navigation.page', { navigationId: currentNavigationId }) ~ seoParams }}"></a>
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
{# Call the parent pagination block #}
{{ parent() }}
{% endblock %}
我的 StorefrontRenderSubscriber 是:
class StorefrontRenderSubscriber implements EventSubscriberInterface {
protected const EXTENSION_NAME = "swagPagination";
protected ConfigService $configService;
protected LoggerHelper $loggerHelper;
public function __construct(ConfigService $configService, LoggerHelper $loggerHelper) {
$this->configService = $configService;
$this->loggerHelper = $loggerHelper;
}
/**
* Get subscribed events for this subscriber.
*
* @return array The list of subscribed events and their associated methods
*/
public static function getSubscribedEvents(): array {
return [
StorefrontRenderEvent::class => 'onStorefrontRender'
];
}
/**
* Callback method for the storefront render event.
*
* @param StorefrontRenderEvent $event The event object
* @return void
*/
public function onStorefrontRender(StorefrontRenderEvent $event): void {
try {
// Retrieve the current request
$request = $event->getRequest();
// Retrieve all query parameters
$queryParameters = $request->query->all();
// dd($queryParameters);
// Create an instance of SwagPaginationData
$pluginData = new SwagPaginationData();
// Get the configuration and check if it's active, add queryParameters
$config = $this->configService->getConfig();
if ($config && $config->isActive()) {
$pluginData->assign([
'active' => $config->isActive(),
'queryParameters' => $queryParameters,
/*
* add more fields here
*/
]);
}
// Add the extension to the context
$event->getContext()->addExtension(self::EXTENSION_NAME, $pluginData);
} catch (\Throwable $e) {
// Log any exceptions
$this->loggerHelper->logThrowable($e);
}
}
}
我已经检查了 URL 编码、seoUrl 函数和整体逻辑,但我似乎无法弄清楚为什么从搜索结果页面导航到第 2 页时没有正确生成 SEO URL。任何见解或建议将不胜感激。
我注意到一件事。当我搜索某些内容时,浏览器的链接会发生变化,从而从链接 http://localhost/Clothing/Men/ 中删除“/Clothing/Men/”并将其更改为 http://localhost/search?search=new
提前感谢您的帮助!
搜索页面使用与导航页面不同的路线。它也不采用
navigationId
作为参数,因为它不与某个特定类别相关联。您可以检查页面是否具有当前的 searchTerm
属性,如果有,则为正确的 frontend.search.page
路由名称生成 URL。执行此操作时,您还可以将 searchTerm
添加到其余参数中,因为您需要分页中的更多 URL 才能继续使用该搜索词。
{% if page.searchTerm is defined %}
{% set seoUrl = seoUrl('frontend.search.page') %}
{% set seoParams = seoParams|merge({ search: page.searchTerm }) %}
{% else %}
{% set seoUrl = seoUrl('frontend.navigation.page', { navigationId: currentNavigationId }) %}
{% endif %}
{% set seoParams = '?' ~ seoParams|url_encode %}
<a href="{{ seoUrl ~ seoParams }}"></a>