Shortcode Templates

Every shortcode that renders something complicated, a login form, a directory grid, a course outline, gets its HTML from a template file. Attributes tweak that output: labels, widths, button text. Templates transform it. When you want different markup, a field layout no parameter offers, a wrapper the theme can hook onto, you don't fight the shortcode. You take over its template.

The system is deliberate: the plugin ships with a set of working templates, and your theme can override any of them, one at a time, without touching the plugin. Your customizations survive plugin updates because the plugin's copies are never the ones being edited.

Try CSS first

Before you open a template, check whether CSS can do the job. Most look-and-feel changes can: the shipped markup carries classes you can restyle, and a few lines in your stylesheet change spacing, colors, and typography on every form at once.

Templates are for when the HTML itself is wrong for your design. The layout needs different elements, the form fields belong in a different arrangement, or markup the theme expects is missing. That's the layer CSS can't reach.

The override workflow

  1. In your (child) theme, create a torii/shortcodes/ directory.

  2. In the plugin, find the template you want to change under templates/shortcodes/. Copy only that file into your theme directory, keeping the same name and sub-path. Editing the login form means copying one file, not the whole folder.

  3. Edit your copy. Change the markup, add classes, move pieces around. The plugin now checks your theme first and prefers your copy over its own.

Use a child theme

The same logic that says don't edit the plugin applies to your theme: a theme update will overwrite files in the theme directory. Put your overrides in a child theme and the parent can update safely while your customizations survive. If you're already using a child theme for other customizations, this is where the torii/shortcodes/ directory belongs.

What a template can and can't do

A template controls appearance: the HTML structure, the classes on it, any inline styles or scripts it needs. The template only shapes how the result is presented.

The template can't change what the shortcode does. The business logic: what gets saved, which tags apply, who sees what. All of that lives safely in Torii's PHP code.

That division is what keeps overrides safe: functionality updates come from the plugin, and your layout edits stay yours.

Rules to follow when customizing

Copy only what you're changing. A stock template left in your theme is a file that won't receive fixes and improvements the plugin's copy gets. The fewer overrides you maintain, the fewer places to look when something behaves differently after an update.

Keep the hidden fields. The nonce, the signature, the redirect targets: hidden inputs the form needs to validate and route the submission. Strip them and the form submits nothing, with no error telling you why. Rearrange the visible fields however you like; the invisible ones stay.

Leave form fields valid. Whatever you do to the layout, the inputs that matter need to remain real inputs with their names intact.

End files without a closing ?> tag. Torii templates follow the WordPress core convention: a file that is pure PHP ends without a closing ?>. It looks like a mistake the first time you see it. It isn't. If a template ends with ?> and anything follows it, even one stray newline typed past the tag, that whitespace gets sent to the browser as output. A single blank line emitted at the wrong time breaks redirect headers, mangles RSS feeds, and shifts your layout a mysterious pixel. Omitting the closing tag makes the failure impossible. When your edited template ends in PHP, just stop typing.

What's inside a template

Templates are plain PHP and HTML. When one renders, four things are in scope:

  • $atts, the resolved shortcode attributes
  • $content, anything between the opening and closing shortcode tags
  • $code, the shortcode name
  • $data, the prepared values the handler built for this render, form field definitions, error state, user data

A trimmed-down real example, from the set-password form's template:

<form id="set_password_form" method="post">
    <input type="hidden" name="torii_form_type" value="torii_set_password">
    <input type="hidden" name="redirect_to" value="<?php echo esc_attr( $atts['redirect_to'] ?? '' ); ?>">
    <?php echo wp_nonce_field( 'torii_set_password', '_wpnonce', true, false ); ?>
    <?php echo $data['error_html'] ?? ''; ?>
    <p>
        <label for="new">New password</label>
        <input id="new" type="password" name="new_password" autocomplete="new-password">
    </p>
    <button type="submit">Set Password</button>
</form>

Notice what the example keeps: the hidden fields, the nonce, the form type. The visible arrangement is yours; the machinery stays intact.

The best starting point for any override is the shipped template itself. Copy it, and reshape what's there rather than writing from zero, because the shipped version already knows the field names and hidden inputs the handler expects.

Which shortcodes are templatable

Shortcodes that render substantial interfaces run through templates. The set includes the login form (bare, combo, and horizontal variants), the registration form (basic, full, and custom via inner content), the profile update form, the password and email change forms, the magic link request form, the member directory (grid, list, row, search, pagination, no-results, denied, map popup, and nine card styles), the group accounts dashboard, passkey setup and management, the TOTP setup, verify, manage, and recovery code screens, the Zoom embed, and the Sushi LMS display shortcodes, course outlines, progress bars, lesson navigation, and the rest.

The simple shortcodes don't use templates and don't need them: the conditionals that wrap content, the value displays like [memb_member], the tag operations. Their output is a line or a wrapper, and if you want different markup around them, you write it yourself in the page.

A few standalone screens run through the same loader outside the shortcode stack, in their own namespace folder rather than under shortcodes/. The SSO sign-in error screen is one: it renders from the sso/interstitial template when a provider handshake fails, and a broken or missing override falls back to a plain WordPress error page rather than a blank one.

Hooks

The wpal/torii/shortcodes/template-paths filter (array of search paths) adds extra locations the loader will check, after the theme and before the plugin.