The Lyquix theme replaces the standard WordPress template hierarchy with a custom routing engine. Instead of using WordPress theme files like single.php, page.php, or archive.php, all routing flows through a single entry point (custom.php) and a PHP router.
The custom.php file (copied from custom.dist.php during installation) defines the entire HTML structure of your site:
<!DOCTYPE html>
<html>
<head>
Meta tags, GTM, wp_head(), favicons
</head>
<body>
<header>
Alerts, navigation menus
</header>
<main>
<article>
Router output ← Page/post content rendered here
</article>
CTA module
</main>
<footer>
Navigation, social icons, sharing
</footer>
Popups, browser alerts, LiveReload
</body>
</html>
The key line is \lqx\router\render() inside the <article> tag. This is where the router determines which template to load based on the current request.
The router (\lqx\router\render()) checks the current WordPress request and loads the matching template file from php/custom/templates/.
The router follows a specific fallback hierarchy for each request type:
front-page.php(ifis_front_page())home.php(ifis_home())
404.php(ifis_404())search.php(ifis_search())
For custom post type archives (is_post_type_archive()):
archive-{post_type}.phparchive.php
For category archives (is_category()):
category-{slug}.phpcategory.php
For taxonomy archives (is_tax()):
taxonomy-{taxonomy}-{term}.phptaxonomy-{taxonomy}.phptaxonomy.php
For tag archives (is_tag()):
tag-{slug}.phptag.php
For author archives (is_author()):
author-{name}.phpauthor.php
For date archives (is_date()):
day-{year}-{month}-{day}.php/day.phpmonth-{year}-{month}.php/month.phpyear-{year}.php/year.phpdate.php(fallback for any date)
For blog posts and custom post types (is_single()):
{post_type}-{slug}.php{post_type}.php
For pages (is_page()):
page-{slug}.php{page-template-slug}.php(WordPress page template)page.php
For attachments (is_attachment()):
{mime_type}-{slug}.php{mime_type}-{mime_subtype}.php{mime_type}.phpattachment.php
If no template is found:
- Archives fall back to
archive.phpin the child theme, thenphp/archive.phpin the parent theme - Singular posts fall back to
singular.phpin the child theme, thenphp/singular.phpin the parent theme - If nothing matches, the router displays a debug error page
All template files live in php/custom/templates/ in the child theme. To create a new template:
Create php/custom/templates/page.php:
<?php
// Default page template
the_content();Create php/custom/templates/post.php:
<?php
// Blog post template
?>
<h1><?php the_title(); ?></h1>
<div class="meta">
<time><?php the_date(); ?></time>
<span><?php the_author(); ?></span>
</div>
<?php the_content(); ?>Create php/custom/templates/page-about.php for a page with slug "about":
<?php
// About page with custom layout
?>
<div class="about-page">
<?php the_content(); ?>
</div>For complex routing needs that don't fit the standard hierarchy, you can add custom logic in php/custom/router.php. This file is loaded when the standard router doesn't find a matching template for archive or singular requests:
<?php
// php/custom/router.php
// Example: Route events archive to a custom template
if (is_post_type_archive('event')) {
$tmpl_name = 'events-archive';
}
// Example: Route by custom field value
if (is_singular('product') && get_field('product_type') === 'digital') {
$tmpl_name = 'product-digital';
}Set $tmpl_name to the filename (without .php) of the template in php/custom/templates/.
The theme also supports WordPress page templates registered through the page-templates/ directory:
| Template | Purpose |
|---|---|
chromeless.php |
Renders content without header, footer, or navigation |
raw.php |
Raw output template |
To create a new page template, copy page-templates/template.dist.php and modify it. The template will appear in the Page Attributes panel in Gutenberg.
When a page template is selected, the router resolves it by stripping the page-templates/ prefix and .php extension to find a matching template in php/custom/templates/.
Inside any template file, you have access to:
- All standard WordPress template functions (
the_content(),the_title(), etc.) - All Lyquix namespaced functions (
\lqx\util\*,\lqx\blocks\*, etc.) - ACF functions (
get_field(),the_field(), etc.) - The global
$wp_queryobject