Classic Theme Media and Images

SkillMedia

Build or audit media and image output in classic WordPress themes on WP 7.1. Covers `add_theme_support( 'post-thumbnails' )`, `add_image_size()`, `set_post_thumbnail_size()`, `has_post_thumbnail()`, `the_post_thumbnail()`, `get_the_post_thumbnail()`, `wp_get_attachment_image()`, responsive `srcset` and `sizes`, `loading`/`decoding`/`fetchpriority`, attachment metadata contracts, client-side processed uploads, alt text, decorative images, regeneration requirements, and common mistakes such as hand-built `img` tags, full-size archive images, removed dimensions, and broken CLS.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Classic Theme Media and Images skill

What this skill tells your AI

The instructions your AI receives, as published by lonsdale201/wp-agent-skills in theme-development/classic-theme-media-images/SKILL.md and read by ahel’s review.

Use this when adding or reviewing featured images, attachment images, custom image sizes, responsive image attributes, image accessibility, or theme asset images in a classic PHP theme.

When to Use This Skill

  • Adding featured image support.
  • Rendering thumbnails in archives, cards, heroes, or singular templates.
  • Registering custom image sizes.
  • Replacing hand-built <img> tags with WordPress image functions.
  • Fixing layout shift, oversized images, missing alt text, or broken responsive image output.

Enable Featured Images

Enable post thumbnails during theme setup.

add_action( 'after_setup_theme', 'mytheme_setup' );

function mytheme_setup() {
	add_theme_support( 'post-thumbnails' );
}

Rules:

  • Register theme support on after_setup_theme.
  • Use add_theme_support( 'post-thumbnails', array( 'post', 'page' ) ) only when intentionally limiting post types.
  • Do not assume featured image UI exists until support is declared.

Register Image Sizes

Register reusable sizes in theme setup.

add_action( 'after_setup_theme', 'mytheme_image_sizes' );

function mytheme_image_sizes() {
	set_post_thumbnail_size( 1200, 675, true );
	add_image_size( 'mytheme-hero', 1600, 900, true );
	add_image_size( 'mytheme-card', 640, 360, true );
	add_image_size( 'mytheme-portrait', 480, 640, array( 'center', 'top' ) );
}

Rules:

  • Use named sizes for repeated layouts.
  • Use hard crop only when the design truly needs fixed framing.
  • Named sizes affect newly generated image metadata. Existing uploads need thumbnail regeneration.
  • Do not register dozens of one-off sizes; each size increases storage and processing work.
  • Prefix custom size names with the theme slug.

Render Featured Images

Use core thumbnail functions.

if ( has_post_thumbnail() ) {
	the_post_thumbnail(
		'mytheme-card',
		array(
			'class' => 'entry-card-image',
		)
	);
}

Rules:

  • Use has_post_thumbnail() before rendering optional image areas.
  • Use the_post_thumbnail() for direct output.
  • Use get_the_post_thumbnail() when composing a larger string.
  • Use appropriate sizes: cards should not use full.
  • Keep width/height attributes unless there is a strong reason; they help prevent layout shift.
  • Do not hand-build upload URLs from _thumbnail_id meta.

Attachment Images

For attachment IDs, use wp_get_attachment_image().

echo wp_get_attachment_image(
	$attachment_id,
	'mytheme-card',
	false,
	array(
		'class' => 'media-card-image',
	)
);

Core adds useful defaults:

  • src.
  • width and height.
  • attachment alt text from _wp_attachment_image_alt.
  • image size classes.
  • responsive srcset and sizes when metadata is available.
  • loading optimization attributes such as loading, decoding, and fetchpriority when appropriate.

Do not replace this with a manual <img src="..."> unless the image is not a WordPress attachment.

WordPress 7.1 metadata contract

wp_get_attachment_metadata() now returns false if stored or filtered metadata is not an array. When a sizes key exists but a filter makes it non-array, core normalizes it to an empty array. Treat the return as array|false, and treat sizes as optional; never index it blindly.

wp_filesize() now always returns a non-negative integer. Numeric filter results are cast, negative pre-filter values are ignored, and a negative or non-numeric final filter value is clamped to zero. Zero still means either an empty file or an unavailable size, so it is not proof that the attachment is invalid.

WordPress 7.1 can process supported images in the browser before upload. Theme rendering must remain agnostic to whether the server or client created the sub-sizes: use attachment IDs and core image helpers, not filename conventions or assumptions that every size was derived in a single server request.

Alt Text

Rules:

  • Informative images need useful alt text.
  • Decorative images should use empty alt text: alt="".
  • Featured images often need context-specific alt text. Attachment alt may be enough, but review it.
  • Do not use the post title as a blind default for every image if it duplicates adjacent text.
  • Do not keyword-stuff alt text.

For a linked post thumbnail in an archive card, the link text/title may already describe the post. In that case, an empty alt can avoid repetition:

printf(
	'<a class="entry-card-link" href="%1$s">%2$s</a>',
	esc_url( get_permalink() ),
	get_the_post_thumbnail(
		get_the_ID(),
		'mytheme-card',
		array( 'alt' => '' )
	)
);

Responsive and Performance Attributes

WordPress image functions can output srcset, sizes, loading, decoding, and fetchpriority.

Rules:

  • Prefer CSS plus correct image sizes over manually overriding srcset.
  • Pass a custom sizes attribute only when the default is wrong for the layout.
  • Do not remove width/height attributes globally; that usually harms CLS.
  • Avoid full images in archives, grids, related posts, and menus.
  • Use loading => 'eager' or fetchpriority => 'high' only for the primary above-the-fold image.
  • Do not set every image to eager/high priority.

Example hero image:

the_post_thumbnail(
	'mytheme-hero',
	array(
		'class'         => 'hero-image',
		'loading'       => 'eager',
		'fetchpriority' => 'high',
	)
);

Use this only for the page's primary visual, not every singular featured image by default.

Theme Asset Images

For static images shipped with the theme, use theme file helpers and normal escaping.

<img
	src="<?php echo esc_url( get_theme_file_uri( 'assets/images/pattern.png' ) ); ?>"
	alt=""
	width="320"
	height="180"
>

Rules:

  • Use get_theme_file_uri() for child-theme-overridable assets.
  • Use get_template_directory_uri() only when the parent theme asset must not be overridden.
  • Static theme images do not get attachment metadata, srcset, or media-library alt text automatically.
  • Include explicit dimensions for static images when known.

Background Images

When an image carries content, do not put it only in CSS background.

Rules:

  • Use CSS background images for decoration.
  • Use real <img> output for meaningful content.
  • For Customizer-selected background/header images, validate URLs and escape with esc_url().
  • Avoid inline style attributes with unvalidated image URLs.

Review Checklist

  • Featured image support is declared on after_setup_theme.
  • Custom image sizes are named, prefixed, and not excessive.
  • Existing-upload regeneration is considered after adding sizes.
  • Templates use the_post_thumbnail() or wp_get_attachment_image().
  • Archive/card layouts avoid full image size.
  • Width/height attributes are preserved.
  • Alt text is intentional for informative vs decorative images.
  • Priority/eager loading is used only for primary above-the-fold images.
  • Static theme images use theme file helpers and escaped URLs.
  • No upload URLs are built manually from metadata.
  • wp_get_attachment_metadata() failure and a missing/empty sizes map are handled.
  • Client-processed and ordinary server-processed attachments render through the same public helpers.

Common Mistakes

  • Hand-building <img> tags for attachment IDs and losing srcset.
  • Removing image dimensions globally to make CSS easier.
  • Using full-size images in archive cards.
  • Registering a new image size and forgetting existing uploads need regeneration.
  • Setting every thumbnail to loading="eager" or fetchpriority="high".
  • Reusing post titles as alt text even when the adjacent title already names the link.

References

Signals

GitHub stars
22
Forks
2
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
classic-theme-media-images
Source
github.com/lonsdale201/wp-agent-skills