WHA Docs

Developer Reference

Query builder, component system, helper utilities, and other developer tools available in the theme and mu-plugin framework.

Query Builder (yax-query)

The yax-query mu-plugin provides a fluent interface on top of WP_Query. It handles post status defaults, pagination math, and taxonomy query nesting so you can focus on what you're asking for.

Get all providers (paginated)

$providers = yax_query('wha_providers')->perPage(12)->get();
$providers = new WP_Query([
    'post_type'      => 'wha_providers',
    'posts_per_page' => 12,
    'post_status'    => 'publish',
]);

Get providers at a location, sorted by menu order

$providers = yax_query('wha_providers')
    ->perPage(-1)
    ->orderBy('menu_order')
    ->order('ASC')
    ->taxInclude('wha_providers_locations', $term_id)
    ->get();
$providers = new WP_Query([
    'post_type'      => 'wha_providers',
    'posts_per_page' => -1,
    'post_status'    => 'publish',
    'orderby'        => 'menu_order',
    'order'          => 'ASC',
    'tax_query'      => [
        [
            'taxonomy' => 'wha_providers_locations',
            'field'    => 'term_id',
            'terms'    => $term_id,
        ],
    ],
]);

Filtered provider search with multi-taxonomy filters, keyword search, and pagination

This is the real-world query behind the "Find a Provider" page — users filter by specialty, location, language, and role simultaneously while searching by name.

$providers = yax_query('wha_providers')
    ->perPage(12)
    ->page($page)
    ->search($keyword)
    ->taxInclude('wha_providers_specialties', $specialty_ids)
    ->taxInclude('wha_providers_locations', $location_ids)
    ->taxInclude('wha_providers_languages', $language_ids)
    ->taxInclude('wha_providers_roles', $role_ids)
    ->orderBy('title')
    ->order('ASC')
    ->get();
$tax_query = [
    ['taxonomy' => 'wha_providers_locations', 'operator' => 'EXISTS'],
];

if (!empty($specialty_ids)) {
    $tax_query[] = [
        'taxonomy' => 'wha_providers_specialties',
        'field'    => 'term_id',
        'terms'    => array_map('intval', $specialty_ids),
        'operator' => 'IN',
    ];
}
if (!empty($location_ids)) {
    $tax_query[] = [
        'taxonomy' => 'wha_providers_locations',
        'field'    => 'term_id',
        'terms'    => array_map('intval', $location_ids),
        'operator' => 'IN',
    ];
}
if (!empty($language_ids)) {
    $tax_query[] = [
        'taxonomy' => 'wha_providers_languages',
        'field'    => 'term_id',
        'terms'    => array_map('intval', $language_ids),
        'operator' => 'IN',
    ];
}
if (!empty($role_ids)) {
    $tax_query[] = [
        'taxonomy' => 'wha_providers_roles',
        'field'    => 'term_id',
        'terms'    => array_map('intval', $role_ids),
        'operator' => 'IN',
    ];
}

$query = new WP_Query([
    'post_type'      => 'wha_providers',
    'posts_per_page' => 12,
    'paged'          => $page,
    'post_status'    => 'publish',
    'orderby'        => 'title',
    'order'          => 'ASC',
    'tax_query'      => $tax_query,
    's'              => $keyword,
]);
SELECT SQL_CALC_FOUND_ROWS p.* FROM wp_posts p
INNER JOIN wp_term_relationships tr1 ON p.ID = tr1.object_id
INNER JOIN wp_term_taxonomy tt1 ON tr1.term_taxonomy_id = tt1.term_taxonomy_id
  AND tt1.taxonomy = 'wha_providers_locations'
INNER JOIN wp_term_relationships tr2 ON p.ID = tr2.object_id
INNER JOIN wp_term_taxonomy tt2 ON tr2.term_taxonomy_id = tt2.term_taxonomy_id
  AND tt2.taxonomy = 'wha_providers_specialties'
  AND tt2.term_id IN ({$specialty_ids})
INNER JOIN wp_term_relationships tr3 ON p.ID = tr3.object_id
INNER JOIN wp_term_taxonomy tt3 ON tr3.term_taxonomy_id = tt3.term_taxonomy_id
  AND tt3.taxonomy = 'wha_providers_languages'
  AND tt3.term_id IN ({$language_ids})
WHERE p.post_type = 'wha_providers'
  AND p.post_status = 'publish'
  AND (p.post_title LIKE '%{$keyword}%'
       OR p.post_content LIKE '%{$keyword}%')
ORDER BY p.post_title ASC
LIMIT 12 OFFSET {($page - 1) * 12};

Provider data is cached in 5-minute transients on AJAX collection endpoints to mitigate the N+1 query pattern in the data handler.

Component System

The yax-components mu-plugin provides a PHP component rendering system. Pages are built from ACF flexible content fields — each layout maps to a component file.

How It Works

  1. Content editors add sections to a page using ACF's flexible content field ("Components")
  2. The theme calls get_components() which iterates through the ACF layouts
  3. Each layout name maps to a PHP file in components/sections/ (e.g., layout herosections/hero.php)
  4. Each component receives its ACF field data as props

Key Functions

FunctionPurpose
get_components()Iterate and render all ACF flexible content sections on the current post
get_component($name, $props)Render a single component by name with explicit props
set_props()Define expected props with defaults for a component
merge_props()Merge additional attributes into a props array
join_props()Concatenate string props (useful for CSS classes)

Usage

In a template file:

<?php get_components(); ?>

This renders every section the editor added to the page. For manual component rendering:

<?php get_component('ui/card', [
    'title' => get_the_title(),
    'image' => get_the_post_thumbnail_url(),
    'url'   => get_the_permalink(),
]); ?>

Icon System

SVG icons are loaded by get_icon($name) from assets/dist/icons/. It normalizes icons to width="1em" height="1em" and adds aria-hidden. The the_icon($name) wrapper sanitizes with wp_kses().

Asset Versioning

The theme uses content-hash cache busting via yax-common utilities:

FunctionPurpose
yax_asset($path)Returns the themed URL for an asset
yax_asset_version($path)Returns a content hash from mix-manifest.json for cache busting

In production, URLs look like: app.css?ver=c3f97dd56f5e46be03ea

WHA Query Helpers

functions/queries.wha.php provides WHA-specific query helpers built on top of yax-query:

FunctionPurpose
wha_term_for_related_post($taxonomy, $post_id)Resolve a taxonomy term whose ACF related_post field matches a post ID
wha_providers_by_location_term($term_id, $args)Get providers assigned to a location term
wha_providers_by_location_post($post_id, $args)Get providers at a location post (resolves the term automatically)
wha_posts_by_provider_post($post_id, $args)Get blog posts attributed to a provider
wha_get_attributed_provider_ids($post_id)Get provider IDs attributed to a blog post

On this page