Skip to content

Developer notes

Overview · Installation · Configuration · Usage · FAQ

Item Value
Add-on ID kv_seo_filter_landing_pages (scheme 3.0, priority 1000)
PHP namespace Tygh\Addons\KvSeoFilterLandingPages
Tables ?:kv_sflp_pages (category, normalized features_hash, status, robots, sitemap, links, position, banner link, product count), ?:kv_sflp_page_descriptions (per language: slug, H1, meta, intro, bottom text, link text)
Image pairs object type kv_sflp (banner)
Admin controller `kv_seo_filter_landing_pages.manage
  • Filter hash. The core format <filter_id>-<value>-<value>_<filter_id>-<from>-<to>[-<currency>] is the same in 4.17 and 4.21. Hash::normalize() sorts filters and list values and trims range numbers, so a combination matches however the browser ordered it.
  • Routing. get_route runs before the core SEO add-on: for a URI ending in /<slug>/ (or /<slug>/page-N/) the candidates with that slug are checked by building their URL (category SEO URL without trailing slash or extension + /<slug>/, in the candidate’s language) and comparing the path. A match becomes categories.view with category_id + features_hash, sets $_SERVER['X-SEO-REWRITE'] (so the core does not redirect it) and runtime.kv_sflp_route. Disabled pages, other filters in the query, an inactive add-on or an invalid license answer with a 301 to the filtered category URL.
  • Links. url_post (priority 1900, after the core SEO add-on) rewrites categories.view?category_id=…&features_hash=… to the landing URL when an active page matches.
  • Redirect mode. categories.pre.php sends a plain GET of a matching filtered URL to the landing page (301).
  • Content. categories.post.php assigns kv_sflp_page (H1, texts, banner), replaces category_data.category with the H1, adds the breadcrumb and the meta data; kv_sflp_links for the links block.
  • Head. dispatch_before_display (priority 2870: after SEO Meta Templates 2850, before SEO Pro Suite 2900) sets the canonical, prev/next and hreflang URLs and re-applies the meta data. seo_is_indexed_page removes features_hash from the categories.view noindex rule for landing pages.
  • Sitemap. google_sitemap_generate_sitemap_for_storefront_after_items writes the pages with the core helpers (fn_google_sitemap_print_item_info, fn_google_sitemap_check_counter).
Hook Where (4.17.2 / 4.21.2) Why
get_route fn.control.php 836 / 843 serve landing URLs
url_post (priority 1900) fn.common.php 3946 / 4039 landing URLs in links
dispatch_before_display (priority 2870) fn.control.php 623 / 630 canonical, hreflang, meta
seo_is_indexed_page seo/func.php 1240 / 1278 landing pages indexable
google_sitemap_generate_sitemap_for_storefront_after_items google_sitemap/func.php 416 / 416 sitemap entries
delete_category_post fn.categories.php 1112 / 1096 delete the pages of deleted categories
delete_product_filter_post, delete_product_feature_variants_post fn.filters.php 452 / 452, fn.features.php 2035 / 2061 disable pages that use deleted filters or values
init_templater_post fn.init.php (only while an upgrade sync is pending) Upgrade\Synchronizer
before_dispatch static handler of License\Client (admin area, console) license checks and notices

Template hooks (storefront): categories:view_description (override on landing pages: banner, intro, top links; post: top links on category pages), categories:view (post: bottom text and bottom links), index:styles, index:scripts. Nova uses the Responsive category template, so the same hooks apply.

Config::storefrontActive() (enabled in the settings + cached License\Client::isActive()) gates routing (redirect instead of the landing page), link rewriting, the redirect mode, the page content, the links block and the sitemap. Admin pages always work. Cron: php admin.php --dispatch=kv_seo_filter_landing_pages_license.check.

The output depends only on the URL. Page data, the slug map and the links are read through Registry::getOrSetCache() with the add-on tables as conditions, so editing a page invalidates the cached pages. Nothing is written to ?:storage_data or the session at runtime.

app/addons/kv_seo_filter_landing_pages/
addon.xml init.php func.php
controllers/backend/{kv_seo_filter_landing_pages,kv_seo_filter_landing_pages_license}.php
controllers/frontend/categories.{pre,post}.php
schemas/menu/menu.post.php schemas/permissions/admin.post.php
Tygh/Addons/KvSeoFilterLandingPages/{Config,Hash,Pages,Router,Storefront,Sitemap,Csv,Generator,Syntax}.php
Tygh/Addons/KvSeoFilterLandingPages/License/* Tygh/Addons/KvSeoFilterLandingPages/Upgrade/Synchronizer.php
design/backend/templates/addons/kv_seo_filter_landing_pages/
views/kv_seo_filter_landing_pages/{manage,update,generate,import}.tpl
views/kv_seo_filter_landing_pages/components/{tabs,category_select,filters}.tpl
hooks/index/{styles,scripts}.post.tpl hooks/addons/* license/*
design/backend/css/addons/kv_seo_filter_landing_pages/{styles,license}.less
js/addons/kv_seo_filter_landing_pages/{backend,func}.js
var/themes_repository/responsive/templates/addons/kv_seo_filter_landing_pages/
hooks/categories/{view_description.override,view_description.post,view.post}.tpl
components/links.tpl hooks/index/{styles,scripts}.post.tpl
var/themes_repository/responsive/css/addons/kv_seo_filter_landing_pages/styles.less
var/langs/en/addons/kv_seo_filter_landing_pages.po