Every time the_title(), the_content(), the_permalink(), or get_the_excerpt() appears in a WordPress theme file, a template tag is being called. WordPress template tags are the functions that output or return data within theme templates — they are the primary interface between WordPress’s data layer and the HTML the browser renders. Understanding the full range of template tags, when to echo versus return, and how to use their parameters transforms theme development from copying working snippets to writing intentional, maintainable template code. This fits into the wider topic we cover in our Complete Guide to WordPress How.
WordPress Template Tags — The Fundamental Concepts
WordPress template tags are PHP functions designed for use in template files. They fall into two categories based on how they deliver their output: functions that directly echo HTML to the page (the_title(), the_content(), the_permalink()) and functions that return data as a PHP value for use in expressions (get_the_title(), get_the_content(), get_permalink()). The naming convention is consistent: functions prefixed with “the_” echo output; functions prefixed with “get_the_” or “get_” return values.
Use “the_” functions when the output goes directly into the HTML template:
<article>
<h1><?php the_title(); ?></h1>
<div class="content"><?php the_content(); ?></div>
<a href="<?php the_permalink(); ?>">Read more</a>
</article>
Use “get_” functions when the data needs to be processed before output — stored in a variable, passed to another function, conditionally displayed, or escaped differently than the default:
<?php
$title = get_the_title();
$custom_title = strtoupper($title); // Modify the data
echo '<h1>' . esc_html($custom_title) . '</h1>';
// Or pass to another function
update_post_meta($post->ID, 'cached_title', get_the_title());
?>
This echo/return distinction is fundamental to WordPress template tags usage. Calling the_title() inside an HTML attribute value produces escaped output (because the function uses esc_attr internally for attribute context), while get_the_title() returns raw data that requires explicit escaping. Understanding the context — whether output goes to HTML body, HTML attributes, JavaScript, or a database — determines which version to use and what escaping to apply. According to the WordPress developer documentation, all template tag functions should be used within the WordPress Loop unless documented otherwise — functions like the_title() and the_content() query the current post from the global $post variable, which is only correctly set inside the Loop.
Essential WordPress Template Tags Reference
The most frequently used WordPress template tags cover the data that appears on nearly every WordPress site — post metadata, author information, category and tag data, and pagination controls.
Post content and metadata:
the_title()— post title, escaped for HTML output. Parameters: before ($before), after ($after), display (true=echo, false=return).the_content($more_link_text)— full post content with shortcodes processed, embeds rendered, More tag split applied.the_excerpt()— post excerpt (manual or auto-generated). No parameters; the excerpt filter handles customisation.the_permalink()— post URL. Get version:get_permalink($post_id).the_date($format)— publication date. Get version:get_the_date($format, $post_id).the_modified_date($format)— last modified date, useful for SEO freshness signalling.the_ID()— current post ID. Get version:get_the_ID().
Author data WordPress template tags:
the_author()— display name.get_the_author_meta($field, $user_id)returns any author profile field.the_author_posts_link()— author name linked to their archive page.get_avatar($user_id, $size)— avatar HTML img element. Returns, does not echo.
Taxonomy and meta tags:
the_category($separator)— category links.get_the_category($post_id)returns the category objects array.the_tags($before, $sep, $after)— tag links with configurable formatting.the_terms($post_id, $taxonomy, $before, $sep, $after)— any taxonomy’s terms for a post.get_post_meta($post_id, $key, $single)— custom field value. Core meta retrieval used constantly in templates.
Template Tags for Media and Featured Images
Media-related WordPress template tags handle featured images, gallery output, and attachment data — the most visually impactful elements in most WordPress templates.
Featured image WordPress template tags: the_post_thumbnail($size, $attr) outputs the full img HTML element for the current post’s featured image. The $size parameter accepts registered image size slugs (‘thumbnail’, ‘medium’, ‘large’, ‘full’, or a custom registered size) or an array of pixel dimensions [width, height]. The $attr parameter array overrides img tag attributes — use it to add classes, IDs, loading attributes, or override the alt text. get_the_post_thumbnail_url($post_id, $size) returns just the image URL for use in inline styles, data attributes, or JSON output rather than an HTML img element. has_post_thumbnail($post_id) checks whether a featured image is set — use it to conditionally show a fallback image when no featured image is assigned, rather than outputting an empty img tag or broken image placeholder.
Attachment and gallery WordPress template tags for the media library: wp_get_attachment_image($attachment_id, $size, $icon, $attr) returns the img element for any media library item by ID — useful for displaying specific images from the media library that are not the post’s featured image. wp_get_attachment_url($attachment_id) returns the URL of any media library file. get_attached_media($type, $post_id) returns all media items attached to a specific post — useful for building custom gallery templates that display all images uploaded to a specific post. Our guide on fixing WordPress images not displaying covers the image delivery infrastructure that must be correct before template tags can output images correctly — broken media library references produce empty or broken img tags regardless of which template tag is used.
Conditional Template Tags and Loop Functions
Conditional WordPress template tags return true or false based on the current page context — they are the mechanism for displaying different content on different page types within a single template file.
Core conditional tags:
is_single()— true on single post pages. Optional parameter: specific post ID or slug.is_page($page)— true on a specific page. Parameter: page ID, slug, or title.is_archive()— true on any archive page (category, tag, date, author, custom taxonomy).is_category($category)— true on category archive pages.is_home()— true on the blog posts index (the page showing latest posts).is_front_page()— true on the site’s front page (whether that is the blog index or a static page).is_user_logged_in()— true when the visitor is authenticated.current_user_can($capability)— true when the current user has the specified capability.
Use conditional WordPress template tags to add template logic: show a featured image only on single posts (if (is_single()) { the_post_thumbnail(); }), display a custom call to action only to logged-out visitors (if (!is_user_logged_in()) { get_template_part('template-parts/cta'); }), or show different navigation based on the archive type. These conditionals replace the common anti-pattern of creating separate template files for every small variation — a single archive.php with conditionals handles category archives, tag archives, and date archives cleanly. For WordPress template tags that need to check multiple conditions, combine conditionals with standard PHP operators: if (is_archive() && !is_author()) targets all archives except author archives. Our guide on creating WordPress custom post types covers the custom conditional tags like is_singular('portfolio') and is_post_type_archive('portfolio') that apply to custom post types alongside the built-in conditional template tags.
Template Part Functions and Advanced Usage
Template include functions — a category of WordPress template tags — organise maintainable themes — they allow breaking complex templates into reusable, manageable pieces using WordPress template tags designed for this purpose.
Core include functions: get_header($name) loads header.php or header-$name.php from the theme folder. get_footer($name) loads footer.php or footer-$name.php. get_sidebar($name) loads sidebar.php or sidebar-$name.php. get_template_part($slug, $name) is the most flexible — it loads $slug.php or $slug-$name.php, falling back to $slug.php if the $name variant does not exist. Pass data to template parts via the third parameter (WordPress 5.5+): get_template_part('template-parts/card', 'post', ['post' => $post, 'show_thumbnail' => true]) — the passed array is available as $args inside the template part.
Advanced WordPress template tags usage includes custom Walker classes for modifying menu output, custom Loop implementations with WP_Query, and filter-based tag modification. Modifying template tag output using filters provides flexibility without overriding template files: add_filter('the_title', function($title, $id) { return is_admin() ? '[' . $id . '] ' . $title : $title; }, 10, 2); — this adds the post ID prefix to titles in the admin without changing any template file. Filters apply wherever the template tag is called, making them ideal for site-wide modifications that would require editing multiple template files. Reviews from the WordPress developer handbook on template tags confirm that using get_template_part() with passed arguments is the recommended pattern for reusable template components in modern WordPress theme development, replacing the older approach of using global variables to pass data between templates.
Escaping output is inseparable from correct WordPress template tags usage — every value output to the browser must be escaped for the appropriate context to prevent Cross-Site Scripting (XSS) vulnerabilities. WordPress provides context-specific escaping functions: esc_html($value) for HTML text content (converts < and > to entities), esc_attr($value) for HTML attribute values, esc_url($url) for URLs in href and src attributes, and esc_js($value) for values embedded in JavaScript. The built-in “the_” template tags handle their own escaping internally — the_title() escapes correctly for HTML context. But when using “get_” functions and constructing custom output, explicit escaping is the developer’s responsibility. A template that outputs <?php echo get_the_title(); ?> without escaping produces code that the WordPress VIP scanner and PHPCS plugin rules flag as a security issue. Always use <?php echo esc_html(get_the_title()); ?> instead — the escaping adds negligible overhead while eliminating an entire class of injection vulnerabilities from the theme code.
Performance considerations for WordPress template tags in custom templates include minimising database queries by using the Object Cache and avoiding repeated identical calls. Calling get_the_title() ten times for the same post ID triggers ten database lookups without object caching (with caching, the first call queries the DB and subsequent calls hit the cache). In performance-critical templates, store the value in a variable on the first call and reuse the variable: $title = get_the_title(); /* use $title multiple times */. For post meta accessed frequently in a template, retrieve all meta with get_post_meta($post_id) (no $key parameter returns all meta as an array) rather than calling get_post_meta($post_id, 'specific_key', true) for each field separately — the single all-meta query populates the internal cache for all fields, making subsequent individual field access hits on the cache rather than additional queries.
Localisation of template output using WordPress template tags in combination with WordPress’s translation system produces correct multilingual output. When hardcoded strings appear alongside template tag output in theme files, wrap them in translation functions: echo esc_html__('Published on:', 'textdomain') . ' ' . esc_html(get_the_date()); — this makes the “Published on:” label translatable while the date value comes from WordPress’s date formatting (which respects the WordPress locale settings). Template tags that output user-visible strings — the_category_list(), the_tags(), the_author() — already use WordPress’s translation infrastructure internally and output correctly localised text when the WordPress locale is set. The combination of translatable hardcoded strings plus locale-aware template tags produces fully internationalised theme templates without any additional multilingual plugin dependency for template-level string translation.
Custom WordPress template tags — developer-created wrapper functions that combine multiple core template tags with additional logic — are a common pattern in well-organised themes. Creating a custom template tag function for frequently used output patterns (a post card with thumbnail, title, excerpt, and meta) in a single function call simplifies template files and centralises the output logic: function mytheme_post_card($post_id = null) { $post_id = $post_id ?: get_the_ID(); echo '<article class="card">'; if (has_post_thumbnail($post_id)) { echo get_the_post_thumbnail($post_id, 'medium'); } echo '<h2>' . esc_html(get_the_title($post_id)) . '</h2>'; echo '<p>' . esc_html(get_the_excerpt()) . '</p>'; echo '</article>'; }. Calling mytheme_post_card() in any archive or index template outputs the complete card HTML with consistent markup, and updating the card design requires changing only the custom function rather than finding every place the card is used across the theme’s template files.
Pagination WordPress template tags are some of the most consistently misused functions in WordPress theme development, often resulting in pagination that does not appear or links to non-existent pages. The correct pagination tags: the_posts_pagination(array $args) outputs pagination for the main query; the_post_navigation(array $args) outputs previous/next post links for single posts; paginate_links($args) generates pagination HTML for custom WP_Query instances (requires manually setting the $paged variable and the query’s paged argument). The most common pagination bug: using paginate_links() with a custom WP_Query without passing the correct max_num_pages from the custom query and the current $paged variable — this produces pagination that shows incorrect page counts or links to page 1 repeatedly. Always use: $paged = get_query_var('paged') ?: 1; $query = new WP_Query(['paged' => $paged]); /* loop */ paginate_links(['total' => $query->max_num_pages]); for correct custom query pagination with all template tags producing accurate output.
Documentation-driven development with WordPress template tags means reading the complete function signature in the WordPress developer documentation before using any tag in production — many template tags have parameters and return values that are not obvious from their name alone. The developer.wordpress.org reference for each function lists all parameters, their defaults, possible values, and return types, with examples showing common usage patterns. For example, the_content() accepts a $more_link_text parameter that customises the “Read more” link text — most developers do not know this because the function works correctly with no arguments and the parameter is rarely documented in tutorials. Developing the habit of consulting the official reference for each template tag, rather than copying from tutorials that may show incomplete usage, produces more robust and maintainable WordPress theme code that takes advantage of the full functionality each tag provides. If this sounds familiar, WordPress Date Format is worth a look.





