Concerns: pushword/admin, pushword/admin-block-editor, pushword/conversation, pushword/core, @pushword/js-helper
The block editor's Group block gains a Collapsible checkbox. Unchecked it is the <div> wrapper it always was; checked it exports {{ startShowMore() }} / {{ endShowMore() }} — the read-more block — carrying its anchor as the block id and its class on the show-more wrapper.
That wrapper holds the toggle, the content and the button, so layout classes do not belong there: for a collapsible grid, nest a plain group inside a collapsible one. The class field says which of the two it is aiming at.
Nothing to do, unless you ship your own editorjs_widget.html.twig — there is no new tool to declare, groupStart and groupEnd are the same two.
Bodies written before {{ startShowMore() }} existed are read as Group blocks with the box ticked, and written back as the comments they were — opening a page never rewrites them. Give one an anchor or a class and it upgrades to the Twig call, the only spelling able to carry them.
To convert them deliberately:
php bin/console pw:show-more:convert --dry-run # what would change
php bin/console pw:show-more:convert
It rewrites paired markers and puts them on lines of their own — a marker glued to the paragraph above it is not a block the editor can show. Markers with no partner, or inside a fenced code block, are left alone and reported.
They were an MD5 of the wrapped text, so every edit gave the block a new id — losing the "already opened" memory ShowMore.js keeps in localStorage, and rewriting the file on a static build. They now come from the page slug and a counter, as {{ startShowMore() }} already did.
Ids therefore change once, on the first render after upgrading. Nothing to do: the markdown fragment pool is keyed on the rendered text, so the new ids simply miss it and render fresh.
{{ reviews() }} folded itself past the second review using a copy of the show-more markup with an id drawn from random(). Since the call is written in page bodies, that random id was baked into the block text the fragment pool is keyed on: every render of every page holding it wrote a new entry nothing would ever read back. One real site had grown a 275 MB pool with a 0% hit rate on those pages, and its static build rewrote them on every run.
It now calls startShowMore(), which resolves your own /component/show_more.html.twig — the copy hardcoded @Pushword, so a site that had overridden the component was not getting it here.
Reclaim the space the old entries took, once:
rm -rf var/cache/pushword-pools
If you override conversation/reviewList.html.twig, apply the same change: drop the {% set id = 'sh-' ~ random(...) %} and the {% use %}, and call {{ startShowMore() }} / {{ endShowMore() }} where it emitted {{ block('before') }} / {{ block('after') }}. An override already calling the functions has the same fix — drop the id and name the argument you do pass, {{ startShowMore(showMoreExtraClass: '…') }}, letting endShowMore() take the id off the open stack. Its first argument is the background, not the id: {{ endShowMore(id) }} puts that id in the gradient's class list, which only goes unnoticed when your show_more.html.twig sets the background itself.
endShowMore() kept a single id rather than a stack.Twig\ShowMore resets between requests. In worker mode (FrankenPHP) and in one process rendering many pages, the second page numbered its blocks from where the first stopped.