So I must be missing some essential piece that preserves html.
No, your code is OK.
However, I would require the second parameter ($editor_id
) and check whether its value is attachment_content
which is the editor ID for the media description textarea on the “Edit Media” page. I also wouldn’t add the 'textarea_name' => 'content'
part.
once I save my changes, and then go back to edit media and save again,
it converts all the html to encoded html entities
Yes, and it happens because WordPress applies format_to_edit()
(see source on Trac) and then format_for_editor()
(see source on Trac), and these functions both use htmlspecialchars()
, therefore the HTML would be escaped twice.
So for example, <h2>
becomes &lt;h2&gt;
which in the Text/HTML mode of the editor becomes <h2>
and then in the Visual mode appears as <h2>
.
So how to fix the issue?
Unfortunately, as of WordPress 5.8, there is no hook for bypassing/disabling the first or second HTML escaping, but you can try the following trick which disables the second escaping by unhooking format_for_editor()
from the the_editor_content
filter if the current editor ID is attachment_content
:
function my_fix_the_editor_content_double_escaping( $content ) {
remove_filter( 'the_editor_content', 'format_for_editor' );
// * We're not actually modifying the content, but only adding the above code.
return $content;
}
// * Use this instead of the code you have in the question.
add_filter( 'wp_editor_settings', function ( $settings, $editor_id ) {
// Check if the current page is the "Edit Media" page (at wp-admin/post.php), and if
// so, we customize the editor settings.
if ( is_admin() && 'attachment' === get_current_screen()->id &&
'attachment_content' === $editor_id
) {
// Change only what need to be changed.
$settings['wpautop'] = true;
$settings['textarea_rows'] = 10;
$settings['media_buttons'] = false;
$settings['tinymce'] = true;
add_filter( 'the_editor_content', 'my_fix_the_editor_content_double_escaping', 1 );
}
return $settings; // Note: ALWAYS return it!
}, 10, 2 );
So I hope that helps and don’t worry, WordPress will automatically re-hook format_for_editor()
back onto the_editor_content
, therefore no need to manually re-hook it.