ForgeWP

Practice: Build a Featured Story Section

Use a category-filtered query to show one featured story, including a readable fallback for posts without images.

Start with Build a Latest Posts Block. Build a second block named Featured Story that displays the newest published Post in the featured category.

In this exercise, featured is a category you create and assign. That makes curation a standard Post-editing task. WordPress's sticky-post setting and a custom field named featured are separate ways of marking content; this exercise uses the category slug.

1. Prepare the content

On your WordPress test site:

  1. Create a category named Featured with the slug featured.
  2. Assign two published Posts to it and give them different publication dates.
  3. Keep another published Post outside that category.
  4. Leave the newest matching Post without a featured image for the first test.

The query should display the newest matching Post, even when a newer Post exists outside the category.

2. Build the block

Theme terminal: scaffold a separate featured-story block
pnpm forgewp make:block FeaturedStory --attributes=heading

Work in src/blocks/FeaturedStory.tsx. Keep the listing block from the recipe so both can be inserted into the same Page.

Your block should have:

  • Registered name featured-story and inserter title Featured Story.
  • An inline-editable section heading, initially Featured story.
  • A WpQueryLoop using postType="post", categoryName="featured", and postsPerPage={1}.
  • Explicit newest-first date ordering.
  • A child card that reads the title, excerpt, permalink, and featured image from the current Post.
  • The recipe's placeholder SVG when the Post has no featured image.
  • A stacked layout on narrow screens and a side-by-side image/text layout on wider screens.

Acceptance criteria

Table · 2 columns
Test
Expected result
Two published Posts match the category
Exactly one card: the newest matching Post
A newer Post is outside the category
It stays outside the featured section
The chosen Post has no image
A styled placeholder appears; title, excerpt, and link remain usable
You add a featured image
The visitor page displays that image after saving and cache refresh
You change the section heading
The new heading survives an editor reload
You change the Post's title
The card follows the Post data while the block heading stays independent
You remove all matching Posts from the category
The example's query area is empty; choose a deliberate empty-state design for production
You insert the listing and featured blocks together
Each query uses its own result context

Test the live result on a Page using ForgeWP Builder or a template with a saved-content slot. The query's selection is verified against published WordPress data.

Hints

Hint 1: Filter by slug

Use categoryName="featured". The slug, rather than the category's display label, is the query input. Adding this category to WordPress is a content step; adding the query prop selects it.

Hint 2: Supply an image fallback

Use useWpFeaturedImage() || "/assets/story-placeholder.svg" as the image source. This calls the hook once and uses the theme asset when the returned URL is empty. Keep the fallback file created in the recipe.

Hint 3: Separate the headings

The section heading is a saved block attribute, while the story title comes from useWpTitle() inside the query. Give the story title a linked heading under the section heading.

Hint 4: Share the card layout

A card component in the same file can be used in both edit and save. Keep the card beneath WpQueryLoop in each view so it receives the queried Post's context.

Verify and compare

Theme terminal: check and export the featured block
pnpm typecheck
pnpm forgewp export --validate --strict

Update the test theme, insert Featured Story, and run through the acceptance criteria. Inspect blocks/featured-story/render.php for the one-post limit, category filter, date ordering, and post-context reset.

Then open Solution: Featured Story Section to compare your bindings and query settings.

Extension

Change the category slug to curate a second section, such as travel-tips. Create matching Posts in WordPress and verify that each block uses the intended category. Keep this version's query choices in source; configurable query controls can be a separate iteration.