Shortcodes & Template Tags
warning
Shortcodes can become unmaintainable if they handle layout. Keep shortcodes small and focused on data/output, not page structure.
Shortcodes & Template Tags Explained
| Tool | What it is | Best for |
|---|---|---|
| Shortcode | Content-level reusable snippet | dates, small components |
| Template tag | Theme helper function | repeated theme logic |
| Hook callback | Inject output into regions | banners, credits |
Why It Matters
- Shortcodes let Elements and blocks reuse content without duplication.
- Template tags keep PHP logic consistent across hooks/templates.
- Safe patterns prevent XSS and broken markup.
How It Works
Shortcodes are registered with add_shortcode() and run through do_shortcode() when content is rendered.
flowchart LR
CONTENT[Post/element content] --> SC[Shortcode]
SC --> RUN[Shortcode callback]
RUN --> OUT[HTML output]
Practical Walkthrough
Step 1: Inspect GeneratePress Template Tags (Reference)
inspect-parent-template-tags.sh
cd /var/www/html/wp-content/themes/generatepress
ls inc | grep template-tags || true
Step 2: Create a Safe Shortcode
wp-content/themes/generatepress-child/functions.php
<?php
add_shortcode( 'year', function() {
return esc_html( gmdate( 'Y' ) );
} );
Step 3: Create a Template Tag Helper
wp-content/themes/generatepress-child/inc/template-tags.php
<?php
function gp_child_site_name(): string {
return (string) get_bloginfo( 'name' );
}
Step 4: Include Template Tags in Your Bootstrap
wp-content/themes/generatepress-child/functions.php
<?php
require_once get_stylesheet_directory() . '/inc/template-tags.php';
Practical Examples
Example 1: Use Shortcodes in Elements
Element content
<small>© [year] Example Co.</small>
Example 2: Shortcode with Attributes (Safe)
functions.php
<?php
add_shortcode( 'notice', function( $atts ) {
$atts = shortcode_atts( array( 'text' => '' ), $atts );
return '<div class="notice">' . esc_html( (string) $atts['text'] ) . '</div>';
} );
Usage:
[notice text="Hello"]
Example 3: Shortcode for a Safe URL
functions.php
<?php
add_shortcode( 'home_link', function() {
return esc_url( home_url( '/' ) );
} );
Usage:
<a href="[home_link]">Home</a>
Example 4: Allow Limited HTML
If you must allow limited markup, use wp_kses_post() and document it.
Best Practices
| Practice | Why |
|---|---|
| Escape output | Prevent XSS |
| Keep shortcodes small | Maintainability |
| Avoid nested shortcodes | Debugging complexity |
| Prefer blocks for layout | Better UX |
| Prefix shortcode names | Avoid collisions |
| Return strings, do not echo | Prevents weird output order |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Shortcode prints raw text | Not processed | Ensure content runs through do_shortcode() |
| Shortcode breaks layout | Output not wrapped | Return valid HTML with a wrapper |
| XSS risk | Unescaped output | Use esc_html, esc_url, wp_kses_post |
| Shortcode runs in wrong context | Hook or editor differences | Test in front end and scope usage |
Hands-On
- Create a
[year]shortcode. - Use it inside a Hook Element or footer hook.
- Add one shortcode with attributes and ensure output is escaped.
- Create one template tag helper and use it in a hook.
Quick Reference
shortcodes-cheatsheet.sh
cd /var/www/html/wp-content/themes/generatepress-child
grep -R "add_shortcode" -n . | head
What's Next
- Next: Debugging Custom Code (OLS)
- Related: Security & Hardening