Routing

All unknown URLs are redirected to index.php by .htaccess. The router parses the URI and dispatches to the correct template.


parseRequestUri(): array

Reads the url_slug_* values from the active locale, splits the URI into segments, and applies these rules:

SegmentsPatternResult
(empty)Homepage
{plural_slug}/e.g. projects/Content type list
{cat_slug}/2+ segments, prefix = category slugCategory page
{tag_slug}/{name}/Tag page
{type_slug}/{slug}/Article or page without categorySingle content item
{type_slug}/{cat…}/{slug}/Project with hierarchical categorySingle project

Returns a normalised routing array: [type, slug, category, tag].


Localised URL slugs

URL prefixes are defined per locale in the lang files:

"url_slug_article":  "article",
"url_slug_articles": "articles",
"url_slug_project":  "project",
"url_slug_projects": "projects",
"url_slug_page":     "page",
"url_slug_pages":    "pages",
"url_slug_category": "category",
"url_slug_tag":      "tag"

These keys drive URL generation (cleanUrl()), admin URL generation (admin_content_url()), and route parsing (parseRequestUri()) simultaneously.


Load order

index.php
  ↓
functions.php
  ├── core-functions.php
  ├── data-functions.php
  ├── theme-api.php → template-functions.php
  ├── data-layer.php
  ├── lang-cache.php
  └── theme/{active}/functions.php
  ↓
loadSettings()
sl_build_data_array() → lightweight index for all types
$GLOBALS['data'] = $data
  ↓
parseRequestUri() → routing
  ↓
If single-item (type + slug):
  sl_load_item_by_slug() → one JSON file read
  $data[$type] = [$fullItem]  ← overwrites index
  ↓
processContent() / renderCategoryPage() / renderTagPage()
  ↓
loadThemeTemplate('header', [...])
echo $pageContent
loadThemeTemplate('footer', [...])