Skip to content

For developers

Entity

Landing pages are the DAL entity repertus_seo_filter_landingpage, reachable via the Admin API under /api/repertus-seo-filter-landingpage, including search (/api/search/repertus-seo-filter-landingpage) and the Sync API.

Important fields and associations:

FieldMeaning
name, title, description, metaTitle, metaDescription, keywordsTranslatable text fields; title and metaTitle are required
breadcrumbText of the breadcrumb entry; no admin field, API only
ogTitle, ogDescription, openGraphMediaIdOpen Graph data; stored, currently not output in the storefront
enabled, robotType, sitemapPrio, changeFreq, sitemapExcludeState and SEO strategy
configurationModeshared or per_sales_channel
categoryId, useScNavCategory or sales channel navigation
properties, manufacturersFilter combination (M:N to property_group_option and product_manufacturer)
parametersAdditional listing parameters as type/value pairs, for example min-price = 10. Only maintainable via API, no admin UI.
salesChannelsVisibility in shared mode
children, parentId, salesChannelIdSales channel variants in per_sales_channel mode
cmsPageId, slotConfigLayout and element contents
canonicalForeignKeyTarget of the canonical URL (foreign key of a seo_url)

Creating a landing page via API:

json
POST /api/repertus-seo-filter-landingpage
{
  "name": "Tableware in cream",
  "title": "Tableware/Cream",
  "metaTitle": "Buy cream tableware",
  "enabled": true,
  "configurationMode": "shared",
  "robotType": "follow, index",
  "categoryId": "0190…",
  "properties": [{ "id": "0190…" }],
  "salesChannels": [{ "id": "0190…" }]
}

After creation the indexer generates the SEO URLs; asynchronously with queue indexing.

Switching the configuration mode via API

The mode switch is not a field update but two actions that create or merge variants and move the SEO URLs along:

POST /api/_action/repertus/seo-filter-landingpage/{id}/convert-to-per-sales-channel
POST /api/_action/repertus/seo-filter-landingpage/{id}/convert-to-shared
     { "chosenVariantId": "…" }

Admin API writes to landing pages in per_sales_channel mode are rejected with HTTP 403 without an active in-app extension; converting back to shared is always allowed.

Storefront routes

RoutePurpose
GET /landingpage/{landingpageId} (frontend.repertus.landingpage.page)Storefront page; the SEO URL points here
GET /widgets/landingpage/{navigationId}/checkCheck from the listing whether the active filters match a landing page
/widgets/cms/tonur-seo-filter-landingpage/{landingpageId} and …/filterXHR loading of listing and filters

Events

  • Tonur\SeoFilterLandingpages\Storefront\Page\Landingpage\LandingpagePageLoadedEvent fires after the storefront page is loaded and carries LandingpagePage, context and request. The page extends the navigation page by landingpage and parentCategoryUrl.
  • Tonur\SeoFilterLandingpages\Core\Content\Landingpage\Event\SeoFilterLandingpageIndexerEvent fires after indexing and triggers SEO URL generation.

Templates

The plugin extends these storefront templates:

  • storefront/page/content/index.html.twig: breadcrumb block
  • storefront/layout/breadcrumb.html.twig: landing page as breadcrumb element
  • storefront/component/product/listing.html.twig: listing options (landing page filters, back button, check URL)
  • storefront/element/cms-element-product-listing.html.twig: XHR URLs of the listing

The JavaScript plugin TonurSeoFilterLandingpageListingPlugin overrides Shopware's Listing plugin globally (PluginManager.override('Listing', …)). It locks the landing page filters, renders the back button and sends the redirect check to frontend.repertus.landingpage.check on every filter change in every listing. Custom listing overrides have to extend it or trigger the check themselves.

Generating landing pages

The command bin/console repertus:seo-filter-landingpage:generate-for-filter creates landing pages in bulk via the Sync API. The data is provided by services extending Tonur\SeoFilterLandingpages\DataProvider\LandingpageDataProvider and tagged with tonur.seo_filter_landingpages.landingpage_data_provider:

php
class ColorLandingpageProvider extends LandingpageDataProvider
{
    public function getAction(): string { return 'upsert'; }
    public function getEntity(): string { return 'repertus_seo_filter_landingpage'; }
    public function getPayload(): array { /* list of landing page payloads */ }
}

After the import the SEO URLs of the new landing pages are generated right away.

SEO URL template

The route frontend.repertus.landingpage.page is registered with the SEO URL system. Inside the template all fields of the landing page are available under landingpage, complemented by propertyIds, manufacturerIds, parameters and, with an assigned category, seoBreadcrumb.