Skip to content

fix(collections): preserve inner blocks in card indicator#407

Merged
adekbadek merged 3 commits into
releasefrom
hotfix/collections-missing-inner-blocks
Jun 30, 2026
Merged

fix(collections): preserve inner blocks in card indicator#407
adekbadek merged 3 commits into
releasefrom
hotfix/collections-missing-inner-blocks

Conversation

@adekbadek

Copy link
Copy Markdown
Member

All Submissions:

Changes proposed in this Pull Request:

Monorepo port of Automattic/newspack-plugin#4726 (by @laurelfulford). The original PR fixed this in the legacy newspack-plugin repo, but the same bug still exists unfixed in the monorepo, which is now the primary release source. Code is from the original PR; this PR carries it to where it ships.

In Collections, the 'Card' Collection Indicator Style reassembled post content from $block['innerHTML'], which drops inner blocks - e.g. core/list-item children of a core/list, or columns in a Columns block. Switching to render_block( $block ) preserves inner blocks (and renders dynamic blocks correctly).

Also includes:

  • A regression test (test_insert_after_nth_block_preserves_inner_blocks) asserting <li> items survive.
  • An update to the existing test for the WP 7.0+ wp-block-paragraph class now emitted by render_block().

Closes NPPM-2831.

How to test the changes in this Pull Request:

  1. On a site running Collections, go to Newspack > Settings > Collections and set 'Collection Indicator Style' to 'Card'.
  2. Create a post with a List block containing several items, assigned to a published collection. Publish.
  3. View the post on the front-end; before this fix the list renders as an empty <ul></ul> (items dropped). After it, the items appear.
  4. Smoke test that the post otherwise renders correctly.

Unit-level: n test-php --filter Content_Inserter (14 tests, 56 assertions). The regression test fails on the old innerHTML code (empty <ul>) and passes with render_block().

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully run tests with your changes locally?

Co-Authored-By: Laurel Fulford <laurel.fulford@automattic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018KyqFFJm1pq4RgHDgyAKWe
Copilot AI review requested due to automatic review settings June 24, 2026 10:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@adekbadek adekbadek marked this pull request as ready for review June 24, 2026 10:47
@adekbadek adekbadek requested a review from a team as a code owner June 24, 2026 10:48
@dkoo dkoo self-assigned this Jun 26, 2026

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed the fix and the blocker (details inline) in manual testing.

Thanks for porting this — the core fix is right and the regression test is a good guard. render_block() is the correct way to reassemble parsed blocks so inner blocks (list items, columns) and dynamic blocks survive, and I confirmed the existing suite (14 tests / 56 assertions) passes on this branch.

One blocker before merge: rendering blocks inside the the_content priority-1 filter introduces a re-entrancy regression. self::$the_content_has_rendered is set only after insert_after_nth_block() runs, so a dynamic block that re-applies the_content during that render (Query Loop / core/post-content, core/template-part, core/post-time-to-read) re-enters the indicator filter with the guard still false. The result: a card-style post that is in a published collection and contains such a block injects the outer post's collection card into the nested/queried post's content — and that output is cached for all readers. I reproduced this in a live env (WP 7.0). It's a one-line fix plus a regression test. There's also a smaller test-brittleness suggestion below.

@github-actions github-actions Bot added [Status] Needs Changes or Feedback Pull request needs changes or feedback and removed [Status] Needs Review labels Jun 26, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018KyqFFJm1pq4RgHDgyAKWe
@adekbadek

Copy link
Copy Markdown
Member Author

Thanks for the thorough manual review @dkoo - all three points addressed in da9f45b:

  • Blocker (re-entrancy / cached card leak into nested the_content): Reproduced first with a failing regression test (a dynamic block that re-applies the_content during render yielded two cards), then fixed by moving the self::$the_content_has_rendered guard above the switch so nested re-entry short-circuits. Test now asserts exactly one card; normal single-post render confirmed unchanged. This was latent in the original PR too, so good thing we re-reviewed on the way over.
  • Suggestion (WP 7.0 wp-block-paragraph coupling): Assertions now check inner text + ordering instead of the core wrapper class.
  • Nit (lock in inner-block placement): The inner-blocks test now also asserts the <ul class="wp-block-list"> wrapper, that items render within it, and the insert/order positions.

Full suite green (15 tests, 63 assertions).

@adekbadek adekbadek requested a review from dkoo June 29, 2026 14:06

@dkoo dkoo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, @adekbadek! All three points from the previous review are addressed and verified. The guard is now set before the blocks are rendered, so a dynamic block that re-applies the_content during the card render (Query Loop / core/post-content, etc.) short-circuits on re-entry instead of leaking the outer post's collection card into nested/queried content; there's a dedicated regression test asserting the card renders exactly once. The test assertions no longer couple to the WP 7.0+ wp-block-paragraph class, and the inner-blocks test now locks in list-wrapper placement and ordering.

I re-verified on the live front-end: the Query Loop collection post that previously rendered three cards (two leaked into the queried siblings) now renders exactly one, with the list-block post still rendering its items correctly. Full suite green (15 tests / 63 assertions). LGTM — thanks for the quick, thorough turnaround.

@github-actions github-actions Bot added [Status] Approved Pull request has been approved and removed [Status] Needs Changes or Feedback Pull request needs changes or feedback labels Jun 29, 2026
@adekbadek adekbadek enabled auto-merge (squash) June 30, 2026 09:02
@adekbadek adekbadek merged commit 96f5e6e into release Jun 30, 2026
9 checks passed
@github-actions

Copy link
Copy Markdown

Hey @adekbadek, good job getting this PR merged! 🎉

Now, the needs-changelog label has been added to it.

Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label.

If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label.

Thank you! ❤️

matticbot pushed a commit that referenced this pull request Jun 30, 2026
## newspack [6.44.1](https://github.com/Automattic/newspack-workspace/compare/newspack@6.44.0...newspack@6.44.1) (2026-06-30)

### Bug Fixes

* **collections:** preserve inner blocks in card indicator ([#407](#407)) ([96f5e6e](96f5e6e))
@adekbadek adekbadek deleted the hotfix/collections-missing-inner-blocks branch June 30, 2026 09:18
matticbot pushed a commit that referenced this pull request Jun 30, 2026
## [4.26.7](https://github.com/Automattic/newspack-workspace/compare/newspack-blocks@4.26.6...newspack-blocks@4.26.7) (2026-06-30)

### Bug Fixes

* **checkout:** sync repeat trial pricing in modal checkout ([#264](#264)) ([#468](#468)) ([d7d2356](d7d2356))
* **collections:** preserve inner blocks in card indicator ([#407](#407)) ([96f5e6e](96f5e6e))
matticbot pushed a commit that referenced this pull request Jul 9, 2026
## [2.23.7](https://github.com/Automattic/newspack-workspace/compare/newspack-theme@2.23.6...newspack-theme@2.23.7) (2026-07-09)

### Bug Fixes

* **access-control:** restore long-lived institutional IP access cookie ([14b3aad](14b3aad)), closes [#136](#136) [#4749](https://github.com/Automattic/newspack-workspace/issues/4749) [#4749](https://github.com/Automattic/newspack-workspace/issues/4749)
* **blocks:** restrict articles endpoint to viewable post types ([cde3e84](cde3e84))
* **checkout:** sync repeat trial pricing in modal checkout ([#264](#264)) ([#468](#468)) ([d7d2356](d7d2356))
* **collections:** preserve inner blocks in card indicator ([#407](#407)) ([96f5e6e](96f5e6e))
* **content-gate:** keep commenting per Discussion Settings on metered posts (NPPD-1829, [#459](#459)) ([43d4fc6](43d4fc6))
* **group-subscription:** render metabox on non-HPOS order storage ([#426](#426)) ([c542f0b](c542f0b))
* **group-subscription:** validate invite before creating an account ([ee44068](ee44068))
* **listings:** authorize self-serve premium listing create/delete ([#507](#507)) ([60efb47](60efb47))
* **newsletters:** add status control to ads quick edit ([#478](#478)) ([4a3fab1](4a3fab1))
* **newsletters:** limit ad editor status to active/inactive ([d7c741c](d7c741c))
* **oauth:** verify Google token audience on sign-in ([9aa30b9](9aa30b9))
* **popups:** restrict prompt preview to prompt managers ([c763c38](c763c38))
* **reader-activation:** load RAS scripts after commons (NPPM-2951) ([#414](#414)) ([d2dab16](d2dab16))
* **salesforce:** verify WooCommerce webhook signature ([80ab615](80ab615))
* **themes:** remove unintended highlight behind colored text ([#574](#574)) ([d94254c](d94254c))

### Features

* **gates:** capture gate id on landing-page conversions (NPPD-1887) ([#575](#575)) ([20e84f8](20e84f8))
* **newsletters:** dated per-ad impression/click stats (NPPD-1861) ([#543](#543)) ([078271d](078271d))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] Approved Pull request has been approved

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants