Skip to main content

Ship template parts from an add-on

Premium Intermediate

Register a directory once at boot and every Benecaster template lookup can find your parts — both ones that replace a core default and ones core has never heard of.

How It Works

A file at templates/guest/profile-card.php inside your plugin answers the template name guest/profile-card. The directory mirrors core’s templates/ structure exactly, and core does not need a template of that name for yours to resolve.

Search order, in full:

child theme  →  parent theme  →  registered add-on dirs  →  plugin defaults

Notes

  • A theme wins over everything you register. Your directory overrides only core’s own
    defaults. A site owner who put a file in {theme}/benecaster/ did so on purpose, and an add-on quietly outranking it would produce a bug with no visible cause — their file is right there and simply stops taking effect.

  • Among add-ons the order is boot order, which nobody controls. Two add-ons registering the
    same template name is not a supported arrangement. If yours must win, give the part a distinct name rather than relying on registration order.

  • Registration is not required for a theme to override your part. Once a name resolves
    through this chain, a site owner can drop {theme}/benecaster/guest/profile-card.php in place and it wins — so treat any part you ship as a public template, and keep the variables you pass into it stable.

  • benecaster_locate_template() will not report your directory. It answers “has the
    theme overridden this?” and deliberately ignores add-on directories. For “what would actually load?”, use benecaster_get_template_path().

  • Registering the same directory twice is a no-op, so a double boot is harmless. A
    directory that does not exist simply never matches.

Related

Code

<?php
add_action( 'benecaster_boot', function (): void {
    benecaster_register_template_directory( plugin_dir_path( __FILE__ ) . 'templates' );
} );

// Anywhere in the add-on — resolves through the full chain, so a theme
// override of the same part still wins.
benecaster_get_template_part( 'guest/profile-card', [ 'guest_id' => $guest_id ] );

View on GitHub →

Hooks Used

Need this built rather than just documented? See our services →