You build a post card for the archive screen. Days later the search results need the same card, so you copy the markup across. At that moment you have created two sources of truth. The problem does not appear now; it appears two months later when you add a badge to the card and only fix one of them.
This class of breakage is silent. No error, no warning, and unless somebody views both screens side by side, nothing reveals it. So the goal is not to fix the drift but to make drift impossible.
Give the markup one owner
get_template_part() puts a fragment of markup in its own file and calls it wherever it is needed. The fragment becomes the single owner, and screen templates merely invoke it.
<?php
// The same call from archive.php, search.php, anywhere
while ( have_posts() ) :
the_post();
get_template_part( 'template-parts/card', 'note' );
endwhile;
The second argument names a variant. The call above looks for template-parts/card-note.php first and falls back to template-parts/card.php. That gives you a base plus variants almost for free.
The child theme rule applies here too. Fragments go through locate_template(), so a copy in the child wins over the parent. To change a single fragment of a parent theme, copy just that one file across.
Pass data as arguments
Fragments often need slightly different values per call site. The old approach was to set a global before the call and read it inside, which forces the fragment to know about its caller and kills reuse. Pass an array as the third argument instead and read it as $args.
<?php
get_template_part( 'template-parts/card', 'note', [
'heading' => 'h3',
'compact' => true,
] );
// inside template-parts/card-note.php
$heading = $args['heading'] ?? 'h2';
$compact = ! empty( $args['compact'] );
Keeping the defaults inside the fragment is the important half. Call sites that pass nothing still work, and the fragment stays self-contained.
What should not become a template part
get_template_part() echoes rather than returns. So when you find yourself wanting the result as a string and reaching for output buffering, treat that urge as a signal: this wants to be a function. Returning strings is not a template fragment’s job.
There is an opposite failure too. Extracting markup that appears on exactly one screen — and always will — means you now open two files to understand one page. The criterion is reuse, not length.
Finding markup you already duplicated is simple: pick one distinctive class name and search the whole theme for it. If the same class appears in more than one template, that is your extraction candidate.
How we run structural clean-up work is published step by step on our process page, and further reading on theme structure lives in the Themes & plugins archive.
Next part
With markup tidy, the stylesheet side is next. The following part covers wiring up an SCSS build, and the argument that never quite dies in WordPress themes: do you commit the compiled output?