Twig templating support with Timber + Timber cache integration
Design with clarity, ship with confidence. With Twig and Timber, your theme’s markup is clean, readable, and reusable – no more tangled PHP templates. Timber transforms WordPress data into elegant Twig views, so developers write less boilerplate and designers get predictable, consistent HTML that mirrors the design system.
Speed comes standard. In development, Twig auto‑reloads and debug is on for rapid iteration; in production, compiled templates are cached for instant responses. Our integration dials in Timber’s environment and cache settings underinc/WP/Cache.php, letting you tune behavior via simple filters – no complex setup required.
The result: a modern, maintainable rendering pipeline that elevates your content and keeps pages fast. Build components once, reuse everywhere, and trust that your templates render beautifully – every time.
Clean views: Twig keeps markup expressive and logic‑light.
Consistent rendering: Timber bridges WP data to shared templates (blocks, pages, partials).
Performance built‑in: Environment‑aware caching toggled viachisel_*filters.
Bootstrapping and global context
- Core classes
inc/WP/Site.phpextendsTimber\Site, wires global context and class maps.inc/WP/Twig.phpextends Twig with custom functions.inc/WP/Cache.phpconfigures Timber cache and Twig env options.
- Global context additions (
Site::add_to_context()ininc/WP/Site.php)logo→Components::get_logo()menus→Components::get_menus()sidebar→Components::get_sidebar()footer_sidebars→Components::get_footer_sidebars()the_title→Components::get_the_title()
- Class maps (typed Timber objects)
timber/post/classmap→ mapspost,page,product,attachmentto custom classestimber/term/classmap→ mapscategory,product_catto custom classes
- Templates are under
views/:- Objects/partials like
views/objects/icon.twig - Page templates index.php, single.php, etc., call
Timber::render(...)/Timber::compile(...).
- Objects/partials like
Twig functions (helpers)
Defined in inc/WP/Twig.php via timber/twig:
get_nav_menu(name)→ fetch fromcontext['menus']timber_set_product(post)→ WooCommerce helperpost_classes(classes, prefix='c-post--')→ ITCSS-friendly classnamesslider_prepare_params(params)→ preparesdata-*attributes/valuesget_responsive_image(id, size='medium', attrs=[])→ responsive<img>HTMLcomments_template()→ comments list + formbem(name, ...modifiers)→ BEM class builder viaThemeHelpers::bem()breadcrumbs()→ Yoast breadcrumbs (if plugin active)get_icon(args)→ rendersviews/objects/icon.twigand caches result
Usage example (Twig):
<nav class="c-nav">
{{ get_nav_menu('primary') }}
</nav>
{{ get_responsive_image(post.thumbnail_id, 'large') }}
<div class="{{ bem('c-card', 'featured', is_preview ? 'preview' : false) }}"></div>TwigBlocks + Twig locations
Twig templates for blocks are discovered automatically:
- Native:
inc/WP/Blocks.php::tiwg_files_locations()addssrc/blocks/{block}/totimber/locations - ACF:
inc/WP/AcfBlocks.php::tiwg_files_locations()addssrc/blocks-acf/{block}/ - Rendering:
- Native helper:
BlocksHelpers::render_twig_file(blockName, context)→ rendersbuild/blocks/{block}/{block}.twigpath (base configured inBlocks::$blocks_twig_base_path) - ACF rendering: BlocksHelpers::acf_block_render(…) resolves
{block}.twigunderbuild/blocks-acf/{slug}/withCacheHelpers::expiry(), after enriching context (fields, classes, wrapper attributes)
- Native helper:
Caching and environment
inc/WP/Cache.phptimber/cache/mode→Loader::CACHE_USE_DEFAULT(can be filtered)timber/twig/environment/options:cachetoggled bychisel_environment_cacheauto_reloadanddebugfollowThemeHelpers::is_dev_env()
CacheHelpers::expiry()controls compile cache TTL used in multiple places.
Practical tips:
- For dev, Twig auto-reload and debug are on.
- For prod, enable Twig cache (set
WP_DEBUGfalse and allowchisel_environment_cache).
Typical render flow
- A WP template (e.g., page.php) builds
$context = Timber::context()→ includeslogo,menus, etc. - It calls
Timber::render('views/page.twig', $context) - Inside Twig, use the registered functions to render menus, images, icons, breadcrumbs, etc.
- Blocks (native/ACF) render their Twig files automatically via the block lifecycle classes.
Where to put your templates
- Page/Archive templates →
views/(e.g.,views/page.twig,views/single.twig) - Shared objects/partials →
views/objects/(e.g.,icon.twig) - Block-specific Twig → co-locate in:
src/blocks/{block}/(native)src/blocks-acf/{block}/(ACF)- The locations are auto-added to
Timberby the block classes.
How class maps work
Timber’s class maps let you replace generic Timber\Post, Timber\Term, and Timber\Image with your own rich domain objects – automatically and predictably.
- Stronger domain model: Attach real behavior to content types (e.g.,
ChiselProduct::get_thumbnail(), ChiselProductCategory::get_thumbnail()), not scattered helper calls. - Cleaner Twig: Move logic into methods, so templates stay declarative:
{{ product.get_thumbnail() }}instead of inline PHP / logic. - Consistency across the site: Every instance of a CPT/taxonomy uses the same API, reducing bugs and copy‑paste.
- Easier testing and refactoring: Centralize behavior in classes; update once, propagate everywhere.
- WooCommerce‑aware defaults: Graceful fallbacks (placeholder images, size filters) live inside
ChiselProduct/ChiselProductCategory, not in your templates.
Existing custom Timber classes
inc/WP/ChiselPost.phpextendsTimber\PostAdds helpers likeget_thumbnail()that returns responsive HTML viaImageHelpers.inc/WP/ChiselProduct.phpextendsTimber\PostWooCommerce‑aware; resolves placeholder IDs and renders responsive thumbnails.inc/WP/ChiselImage.phpextendsTimber\ImageAddsresponsive($size, $attrs)for attachment images.inc/WP/ChiselTerm.phpextendsTimber\TermBase term class.inc/WP/ChiselProductCategory.phpextendsTimber\Term. Provides category thumbnails with Woo placeholder fallback.
Extending with your own CPT and taxonomy
- Create a custom Post class
- File:
inc/WP/ChiselMovie.php - Namespace:
Chisel\WP - Extend
Timber\Postand add your domain logic.
<?php
namespace Chisel\WP;
use Timber\Post as TimberPost;
class ChiselMovie extends TimberPost {
public function rating_badge() {
return $this->meta( 'rating' ) ? 'Rated: ' . esc_html( $this->meta( 'rating' ) ) : '';
}
}PHP- Map your CPT to the class
- In
inc/WP/Site.php→post_classmap()add:
<?php
$custom_classmap = array(
// ...
'movie' => ChiselMovie::class,
);PHP- Create a custom Term class (optional)
- File:
inc/WP/ChiselGenre.php - Extend
Timber\Termand add helpers.
<?php
namespace Chisel\WP;
use Timber\Term as TimberTerm;
class ChiselGenre extends TimberTerm {
public function icon() {
return $this->meta( 'icon' ) ?: 'default';
}
}
PHP- Map your taxonomy to the class
- In
inc/WP/Site.php→term_classmap()add:
<?php
$custom_classmap = array(
// ...
'genre' => ChiselGenre::class,
);PHPUsing in Twig and PHP
- Twig: The objects auto‑upgrade to your classes:
{{ post.get_thumbnail('large') }} (from ChiselPost){{ product.get_thumbnail() }} (from ChiselProduct){{ term.get_thumbnail() }}forproduct_cat(fromChiselProductCategory){{ image.responsive('medium', { class: 'c-image' }) }} (from ChiselImage)
- PHP:
Timber::get_post()andTimber::get_terms()return your mapped classes automatically.
Tips
- Keep classes under
inc/WP/with namespaceChisel\WPto match existing patterns. - Map the CPT slug/taxonomy name exactly (e.g.,
movie,genre). - Add lazy properties or helpers (like
get_thumbnail()) to keep Twig clean and logic‑light.
Summary
- Timber is initialized via Site, extended via Twig, and optimized via Cache.
- Global context is enriched with
logo,menus, sidebars, and computed titles. - Rich Twig utilities simplify rendering menus, BEM classes, responsive images, breadcrumbs, icons, sliders, and comments.
- Block Twig templates are auto-discovered from
src/blocks/**andsrc/blocks-acf/**, aligning with your block system.