如何在WordPress图片附件详情页添加WYSIWYG/TinyMCE编辑器?
Yep, you’re on the right track—you’ll need a mix of PHP tweaks to set up the field properly and JavaScript (in your admin.js) to initialize TinyMCE on that field. Let’s walk through this step by step with your existing code:
1. Update Your PHP Field to Use a Textarea
TinyMCE targets <textarea> elements, so first modify your test function to replace the default input with a textarea (and give it a unique ID, critical for handling multiple attachments on the same page):
add_filter( 'attachment_fields_to_edit', [self::class, 'test'], 10, 2 ); function test($fields, $post) { $meta = get_post_meta( $post->ID, 'buy_now', true ); // Replace basic input with a textarea (TinyMCE requires this) $fields['buy_now'] = [ 'label' => __('Buy Now Content', 'your-text-domain'), 'input' => 'html', 'html' => sprintf( '<textarea id="buy_now_%d" name="attachments[%d][buy_now]" rows="8" cols="50">%s</textarea>', $post->ID, $post->ID, esc_textarea($meta) // Sanitize existing content for the textarea ), 'helps' => __('Add formatted content for the buy now section.', 'your-text-domain') ]; return $fields; }
2. Add a Save Handler for the Meta Field
Don’t forget to save the formatted content—add this filter to handle saving the TinyMCE output:
add_filter( 'attachment_fields_to_save', [self::class, 'save_buy_now_meta'], 10, 2 ); function save_buy_now_meta($post, $attachment) { if (isset($attachment['buy_now'])) { // Use wp_kses_post to safely filter HTML content update_post_meta($post['ID'], 'buy_now', wp_kses_post($attachment['buy_now'])); } return $post; }
3. Initialize TinyMCE in admin.js
Now add this JavaScript to your admin.js to turn the textarea into a WYSIWYG editor:
jQuery(document).ready(function($) { // Make sure TinyMCE is loaded before trying to initialize it if (typeof tinymce !== 'undefined') { // Target all our buy_now textareas (IDs start with "buy_now_") $('textarea[id^="buy_now_"]').each(function() { const editorId = $(this).attr('id'); // Initialize TinyMCE with custom settings (tweak toolbar/options as needed) tinymce.init({ selector: `#${editorId}`, toolbar: 'bold italic | alignleft aligncenter alignright | link unlink | bullist numlist | undo redo', menubar: false, statusbar: false, height: 200, // Critical: Sync TinyMCE content back to the textarea when saving setup: function(editor) { editor.on('change', () => editor.save()); } }); }); } });
4. Load Your Admin Script on the Right Pages
Ensure your admin.js loads only on media/attachment pages (to avoid unnecessary overhead) with this PHP hook:
add_action('admin_enqueue_scripts', [self::class, 'enqueue_admin_scripts']); function enqueue_admin_scripts($hook) { // Only load on media upload/edit pages if ($hook !== 'upload.php' && $hook !== 'media.php') { return; } wp_enqueue_script( 'your-plugin-admin-js', plugin_dir_url(__FILE__) . 'admin.js', // Adjust the path to your file ['jquery', 'wp-tinymce'], // Depend on jQuery and TinyMCE core filemtime(plugin_dir_path(__FILE__) . 'admin.js'), // Cache-busting for updates true // Load in the footer for better performance ); }
The key thing here is that TinyMCE needs a textarea to attach to, and you have to explicitly sync its content back to the original textarea (via editor.save()) so WordPress can save the meta value correctly.
内容的提问来源于stack exchange,提问作者Britt Danzer

