Skip to content

URL Routing & Slug Resolution

Flow ID: CF-03 | Module(s): eshop | Complexity: Medium

Business Overview

All storefront URLs pass through a central dispatcher that resolves human-readable slugs to the correct entity. The system supports multilingual URLs, canonical redirects for SEO, and a caching layer for fast slug lookups.

What happens behind the scenes:

  • Every non-explicit URL hits _remap() in Adv_eshop.php
  • The dispatcher tries entity types in order: checkout → product → category → custom → 404
  • Old URLs stored in shop_product_mui.url field redirect to canonical format
  • Multilingual support: default language has no prefix, others use /en/, /el/, etc.

Key business behaviors:

  • Product slugs checked BEFORE category slugs (product wins on conflict)
  • All slug lookups cached via PSCache with slug_lang composite index
  • customRemap() is the primary client extension point for custom URL patterns
  • Canonical URL format: /vendors/{vendor_slug}/{product_slug}

Dispatch Chain

HTTP Request → routes.php (explicit matches: /search, /blog, /customer, /tag, etc.)
    ↓ (no match)
Adv_eshop::_remap($method, $params)
    ├─ 1. baseCheckout()   → /checkout, /checkout/get_response/*, /checkout/handle/*
    ├─ 2. baseProduct()    → slug lookup → Adv_products::index()
    ├─ 3. baseCategory()   → slug lookup → Adv_product_categories::index()
    ├─ 4. customRemap()    → CLIENT EXTENSION POINT (returns false by default)
    └─ 5. error_404()

Explicit Routes

Defined in application/config/routes.php (all doubled with (\w{2})/ prefix for multilingual):

PatternTargetPurpose
tag/(.+)eshop/product_tags/...Tag pages
searchsearch/indexProduct search
customer / signupeshop/customerAccount pages
blog / blog/(.+)blogBlog
vendorseshop/vendorsVendor listing
promoeshop/promo/indexPromotions
waiting_listeshop/waiting_listStock notifications

Dynamic routes via @include('my_routes.php') and auto-generated category routes.


Slug Resolution

Product (baseProduct() line 57-81)

  1. Split URL at last /categorySlug + productSlug
  2. Cache check: existsBySlug($productSlug)SELECT 1 FROM shop_product_mui WHERE slug=? AND lang=?
  3. If found + category valid → products->index($catSlug, $prodSlug)
  4. If not found → try findSlugsByUrl($method) for old URL redirect

Category (baseCategory() line 91-103)

  1. parseCategorySlugAndOffset() — numeric last segment = page number
  2. Cache check: existsBySlug($slug) on shop_product_category_mui
  3. If found → product_categories->index($slug, $offset)

Client Extension Points

customRemap() (line 52-55)

Primary hook for custom URL patterns. Override in client controller:

php
protected function customRemap(string $method): bool {
    if ($method === 'black-friday') {
        $this->load->module('eshop/promotions');
        $this->promotions->blackFridayLanding();
        return true;  // handled
    }
    return false;  // continue to 404
}

Route Configuration

  • application/config/my_routes.php — client custom routes
  • Auto-generated category routes via Seoroutes library

Data Model

TableFieldIndexPurpose
shop_product_muislugslug_langProduct slug lookup
shop_product_muiurlOld/custom URLs for redirect
shop_product_category_muislugslug_langCategory slug lookup
shop_vendor_muivendor_slugVendor slug
blog_post_muislugBlog post slug