Home › Forums › Newsletter Plugin Support › Composer regenerates all blocks, discards typed content, with no confirmation
- This topic has 1 reply, 2 voices, and was last updated 1 day, 6 hours ago by
Michael.
-
AuthorPosts
-
September 7, 2026 at 7:46 pm #358444
User
ParticipantNewsletter 9.3.5, WordPress on managed hosting (Pressable). FPCLChoir.com
What happened:
I created a new newsletter using the Recent Posts template. I added content to the top of the template, taking perhaps 10 or 15 minutes to compose that content. At no action of my own, the page reverted to the standard blog template page. It maintained the settings I had selected, one post as opposed to the default four, but it replaced my entire content with the out-of-the-box content. There is no newsletter showing up as a draft and nothing in the database behind the scenes either.
Looking at the code, I believe the mechanism is this:
1.
composer/composer.js:361binds#tnpb-settings-apply, the “Apply” button in the composer settings panel, to an AJAX call with actiontnpc_regenerate_email.2.
composer/composer-admin.php:401 ajax_tnpc_regenerate_email()hands the content toNewsletterComposer::regenerate_blocks().3.
composer/composer.php:842 regenerate_blocks()rebuilds the body exclusively from the data-json attributes:preg_match_all('/data-json="(.*?)"/m', $content, $matches, PREG_PATTERN_ORDER);then for each match it decodes the options, calls
render_block(), and accumulates$result['content'] .= $block_html. The existing rendered HTML is not carried forward at all.That matches what I saw precisely. My block option, one post, is stored in data-json and survived. My typed content was in the rendered HTML and did not.
One thing I would ask you to check, and I have NOT proved this: inline edits appear to be persisted as an inline_edits entry inside the block options, at composer-admin.php:169 and :278. The tnpc_render path has an extra decode for that field at composer-admin.php:366-367, for the case where it arrives as a string rather than an array.
regenerate_blocks()atcomposer.php:863does a singleoptions_decode()with no equivalent step. If the field arrives double-encoded on that path it would be dropped silently, which would explain the loss. That is a candidate rather than a finding.Two suggestions:
1. Confirm before regenerating when the body is not empty. Apply is destructive, it does not say so, and there is no undo. There is no
confirm()anywhere incomposer.js.2. The same regeneration runs when a template is chosen, because
load_template()callsjQuery('#tnpb-settings-apply').click()atcomposer.js:166. So selecting a template also replaces everything without asking.Related, and the reason the loss was total rather than annoying: there is no autosave in the composer, and the newsletter row is not created until the first successful save at
emails/composer.php:26. Before that first save there is no id, so there is no version history to fall back on. The Versions feature is genuinely good and better than most plugins offer, but it cannot help with a newsletter that has never been saved. Creating the draft row when the composer is first opened would have saved this one.Thanks for the plugin.
September 8, 2026 at 8:56 am #358453Michael
KeymasterHello,
first of all, thank you for your considerations. I’ve passed this to our senior developer, we will take a look at your findings and get back as soon as possible.
Michael
-
AuthorPosts
- You must be logged in to reply to this topic.