Editor Dreams

I’m starting some exploratory research into future editor options for ClassicPress, and I’d value community input before any conclusions are drawn.

I’m not proposing a replacement for the current editor, nor suggesting immediate change. What I’m trying to understand is:

What concrete author-facing problems would need to be solved for a significant editor evolution to be justified at all?

From my own experience as a content creator, the issues that most affect trust in the editor are not visual polish, but content integrity and control — for example:

  • loss or corruption of formatting between edit and publish

  • external content slipping into documents unnoticed

  • ineffective validation and feedback before save/publish

  • poor native handling of document formats (e.g. DOCX, PDF, paginated documents)

  • limited support for headers, footers, structured templates

  • weak versioning (e.g. no way to manage linked documents as a single versioned unit)

I’m also interested in features that don’t need to exist on day one, but would be easier to support long-term if the editor were designed with them in mind (e.g. advanced content manipulation, reminders, mail-merge-like workflows).

One strong personal preference: maximising document space and keeping controls discoverable without scrolling, with clear warnings and guidance before publication rather than after.

With all that in mind:

What are your own editor “deal-breakers” or must-fix failures?
What capabilities would make you say “yes, this is worth evolving”?

I’m particularly interested in concrete pain points and acceptance criteria rather than specific implementations.

Personally, I want it to be a textarea. That would make me the happiest.

Objectively now, I am happy with the editor, and I think the jQuery dependency needs to be removed. There have been a few discussions on this, but nothing has been set in stone.

So, if anything, the editor needs to be simplified.

I like this, as an evolution of TinyMCE - https://www.hugerte.org/

2 Likes

This looks remarkably like the new editor interface that I’ve just started implementing as a new editor UI, mine has fewer buttons currently. Theoretically, I should be able to run both, side by side. But I recognise that style.

In addition, I have just started adding a possible replacement to the TinyMCE core, and this also, should be able to run side by side with the existing stack, and, there should be no issues flipping form one editor to the other, providing that we keep the overall feature set in tune.
But this is just an initial feasibility, the proof of the pudding is in the eating. and right now, my new editor is actually getting it’s core from a CDN, I can read an existing tiny document on an editor hosted in the cloud, which is an alternative option that we can make available. But I do have another project, as I said, to put that core system in ClassicPress, running side by side with Tiny. I personally think this is a mandatory requirement. But I am trying to end up with at least one other in my analysis soup.

When I say I’m adding buttons, they are all optional, of course, and, you can remove buttons, and even the entire menu, with a bit of code.
There is one option that might help. The ability to remive or only use that menu bar. No buttons, or only selected buttons. I’m not sure that’s an option, but I’m going to fork Advanced Editor soon, to change the button system in order to reduced the visible button count without removing the buttons. I could add some more options in regard to those kinds of choices. The new fork will also allow you to create your own buttons too.
And, no need to worry about plugin size, either. I have a plan for that too.

The problem here is that the old/current TinyMCE has evolved into Tiny, which is a proprietary library with a “not so nice” license, too.

2 Likes

HugeRTE is a fork of TinyMCE - I was in contact with the solo dev keeping it up in the past. It could be a drop in replacement BUT some features are missing and coding them into it and maintaining it would be too much to ask from the core team.
What was discussed is finding a replacement with following features:

  • Vanilla JS based
  • WYSIWYG (no block based editors)
  • ability to handle visual tab + code tab + possibly Markdown + Possibly support for Latex.
  • possibly it needs to be maintained (meaning no dead projects to take over basically)
2 Likes

I know it might be premature… at most I spent a day on it that’s worth two… if nobody likes it, nothing’s lost… I worked on it yesterday and immediately got to work because TinyMCE has 20,000 lines of code and this one about 500… It has almost everything, but not everything. It’s very simple to maintain and it’s completely ours. No external dependencies of any kind. I made it as a plugin to install and activate for now. It’s a single file… I also put it in the community along with other plugins… If you have the time and feel like it, I would really appreciate honest and objective feedback. Sorry if I took the liberty, but I couldn’t resist :wink:

=== Lean Bunker Native Editor ===
Contributors: leanbunker
Tags: editor, classicpress, wysiwyg, native, seo, autonomous
Requires at least: ClassicPress 1.0
Tested up to: ClassicPress 1.4
Stable tag: 0.0.11+api
License: GPLv2 or later
License URI: GNU General Public License v2.0 - GNU Project - Free Software Foundation

Pure native WYSIWYG editor for ClassicPress. Built for stability, autonomy, and large-scale SEO systems.

== Description ==

Lean Bunker Native Editor replaces TinyMCE and Quicktags with a lightweight, dependency-free HTML editor based on contenteditable. It is designed for developers and autonomous SEO systems that require full control over HTML output, atomic edits, and fingerprinting.

Unlike traditional editors, it:

  • Shows content exactly as it will appear on the frontend (inherits theme styles 1:1)
  • Never imposes typography, fonts, or decorative CSS
  • Preserves custom data attributes (e.g., data-lb-fix-id) critical for SEO automation
  • Works reliably on sites with 200,000+ posts
  • Supports autosave, revisions, media library, and bulk operations
  • Exposes a clean, documented JavaScript API for third-party plugins

This is not a general-purpose editor. It is a precision tool for architects of self-optimizing SEO machines.

== Features ==

  • :white_check_mark: Zero dependencies: pure PHP + vanilla JavaScript
  • :white_check_mark: Raw HTML loading via get_post_field(‘post_content’, …, ‘raw’) — no double-escaping
  • :white_check_mark: kses whitelist for data-lb-* attributes (fix IDs, strategies, experiments)
  • :white_check_mark: Real-time sync between contenteditable and hidden textarea
  • :white_check_mark: Autosave-safe: forces sync before every WordPress autosave AJAX call
  • :white_check_mark: Back/forward browser cache support via pageshow event
  • :white_check_mark: MutationObserver to detect non-user DOM changes (e.g., from SEO AI scripts)
  • :white_check_mark: Full Media Library integration (images, video, audio)
  • :white_check_mark: Public API: window.LBEditor for safe, explicit plugin integrations
  • :white_check_mark: No interference with REST API, bulk edit, or cron jobs

== Public JavaScript API ==

The plugin exposes a global object: window.LBEditor

Available methods:

  • LBEditor.insertHTML(html: string) → boolean
    Inserts HTML at cursor position (or appends if no selection). Returns true on success.

  • LBEditor.setContent(html: string) → boolean
    Replaces the entire editor content.

  • LBEditor.getContent() → string | null
    Returns current raw HTML (empty string if placeholder is active).

  • LBEditor.isAvailable() → boolean
    Returns true if the LB editor is active on the current page.

Example usage in another plugin:

if (window.LBEditor && window.LBEditor.isAvailable()) {
    window.LBEditor.insertHTML('<p>Generated by AI</p>');
}

All methods are synchronous, safe, and do not throw errors.

== Security & Hardening ==

  • Content is loaded directly from the database without wp_kses_post() filtering
  • On save, WordPress applies kses, but the plugin whitelists:
    • Tags: a, span, p, div, h1-h6, blockquote
    • Attributes: data-lb-fix-id, data-lb-strategy, data-lb-experiment-id, data-lb-group
  • No eval(), no innerHTML from untrusted sources
  • All user input handled via document.execCommand or controlled string replacement

== Compatibility ==

  • :white_check_mark: ClassicPress 1.0+
  • :white_check_mark: PHP 7.4+
  • :white_check_mark: All public post types (post, page, custom post types)
  • :cross_mark: Not compatible with Gutenberg, TinyMCE, or other visual editors
  • :cross_mark: Do not run alongside plugins that modify the editor (e.g., TinyMCE Advanced)

== Installation ==

  1. Upload the plugin folder to /wp-content/plugins/
  2. Activate “Lean Bunker Native Editor” from the Plugins screen
  3. Ensure no other editor-modifying plugins are active

== Frequently Asked Questions ==

= Does it work with my SEO AI plugin? =

Yes — but you must update your plugin to use window.LBEditor.insertHTML() instead of tinymce.activeEditor.insertContent(). The new API is explicit, safe, and documented.

= Why doesn’t it show shortcode previews? =

This editor shows raw HTML, not rendered output. Shortcodes are preserved as text. This is intentional: autonomous systems must operate on deterministic HTML, not visual approximations.

= Can I use it on a 500k-post site? =

Yes. It avoids WP_Query(-1), uses efficient DOM events, and never loads unnecessary assets.

= Does it break revisions or autosave? =

No. It enhances them by ensuring the textarea is always synchronized before WordPress saves.

== Changelog ==

= 0.0.11+api =

  • Restored stable core from v0.0.11
  • Added public API: window.LBEditor (insertHTML, setContent, getContent, isAvailable)
  • Removed fragile TinyMCE emulation
  • Improved developer experience with explicit integration pattern
  • Full compatibility with autonomous SEO systems

= 0.0.11 =

  • Fixed double-escaping via get_post_field(‘raw’)
  • Reliable autosave and revision support
  • Back/forward browser navigation fixed
  • MutationObserver for non-user edits

= 0.0.10 =

  • Added wp.autosave.server.addBeforeSaveCallback for reliable autosave

= 0.0.9 =

  • Added pageshow event support for browser cache navigation

= 0.0.8 =

  • Added kses whitelist for data-lb-* attributes
  • Added real-time sync for crash recovery

== Upgrade Notice ==

= 0.0.11+api =
If you were using experimental TinyMCE emulation, remove it. Use the new LBEditor API instead for reliable, explicit integrations.

== Author Notes ==

This plugin was built for one purpose: to enable autonomous, self-optimizing SEO systems that require bit-perfect control over HTML. It sacrifices convenience for determinism, and simplicity for truth.

You are not just editing text. You are training a machine.

— Riccardo, Lean Bunker

Is This:

<?php /** * Plugin Name: Lean Bunker Native Editor * Description: Pure native WYSIWYG editor for ClassicPress. Stable, lightweight, with developer-friendly API. * Version: 0.0.11+api * Author: Lean Bunker * License: GPL-2.0+ * Note: Built for autonomy, stability, and control. Includes LBEditor public API. */ if (!defined('ABSPATH')) exit; if (!class_exists('LB_NativeEditor')) { class LB_NativeEditor { const V = '0.0.11+api'; const SLUG = 'lb-native-editor'; private static $i = null; private function __construct() { $this->init(); } public static function get() { return self::$i ?: self::$i = new self; } private function init() { add_filter('user_can_richedit', '__return_false', 9999); add_action('admin_init', [$this, 'rm_tinymce'], 1); add_filter('the_editor', [$this, 'replace_editor'], 10, 1); add_action('admin_head', [$this, 'add_styles'], 9999); add_action('admin_footer', [$this, 'add_editor_script'], 9999); add_filter('wp_kses_allowed_html', [$this, 'allow_lb_attributes'], 10, 2); } public function rm_tinymce() { remove_action('admin_print_footer_scripts', 'wp_tiny_mce', 50); remove_action('admin_head', 'wp_enqueue_editor', 10); foreach (get_post_types(['public' => true], 'names') as $t) { remove_post_type_support($t, 'editor'); add_post_type_support($t, 'editor'); } } public function replace_editor($output) { global $pagenow, $post; if (!in_array($pagenow, ['post.php', 'post-new.php'], true)) return $output; $content = '

Write here...

'; $raw_content = ''; if ($post && !empty($post->ID)) { $raw_content = get_post_field('post_content', $post->ID, 'raw'); if (!empty(trim($raw_content))) { $content = $raw_content; } } return '
B I U S 1. 🔗 × 🖼️
' . $content . '
' . esc_textarea($raw_content) . '
'; } public function allow_lb_attributes($tags, $context) { if ($context === 'post') { $attrs = ['data-lb-fix-id', 'data-lb-strategy', 'data-lb-experiment-id', 'data-lb-group']; foreach (['a', 'span', 'p', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'blockquote'] as $tag) { if (!isset($tags[$tag])) $tags[$tag] = []; foreach ($attrs as $attr) { $tags[$tag][$attr] = true; } } } return $tags; } public function add_styles() { global $pagenow; if (!in_array($pagenow, ['post.php', 'post-new.php'], true)) return; echo ' /* Hide legacy editors */ #content-tmce, #content-html, .wp-switch-editor, #wp-content-editor-tools .wp-editor-tabs, .quicktags-toolbar, #mce_fullscreen_container, .mce-container, .ed_toolbar, .wp-editor-expand .wp-editor-tools { display:none !important; visibility:hidden !important; } /* Toolbar */ #lb-editor-toolbar { background:#f8f9fa; border:1px solid #ddd; border-radius:4px 4px 0 0; padding:8px 12px; display:flex; gap:6px; align-items:center; font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; box-shadow:0 1px 1px rgba(0,0,0,0.04); z-index:9999; } #lb-heading-select { cursor:pointer; appearance:auto; } .lb-btn { width:28px; height:26px; display:flex; align-items:center; justify-content:center; background:#fff; border:1px solid #ccc; border-radius:3px; font-size:15px; font-weight:500; color:#333; user-select:none; cursor:pointer; transition:all 0.15s; } .lb-btn:hover { background:#e9f0f7; border-color:#007cba; color:#007cba; } .lb-btn:active { background:#007cba; color:#fff; } /* Editor */ .lb-wysiwyg-editor { padding:20px; border:2px solid #ddd; border-top:none; border-radius:0 0 4px 4px; background:#fff; min-height:500px; width:100%; box-sizing:border-box; outline:none; resize:vertical; overflow-y:auto; word-wrap:break-word; box-shadow:inset 0 1px 2px rgba(0,0,0,0.07); font-family:inherit !important; font-size:inherit !important; line-height:inherit !important; color:inherit !important; } .lb-wysiwyg-editor:focus { border-color:#007cba; box-shadow:0 0 0 3px rgba(0,123,255,0.15), inset 0 1px 2px rgba(0,0,0,0.07); } /* Structural only */ .lb-wysiwyg-editor img { max-width:100% !important; height:auto !important; display:block !important; margin:1em auto !important; } .lb-wysiwyg-editor ul { list-style-type:disc !important; padding-left:35px !important; margin:1em 0 !important; } .lb-wysiwyg-editor ol { list-style-type:decimal !important; padding-left:35px !important; margin:1em 0 !important; } .lb-wysiwyg-editor blockquote { border-left:3px solid #ddd !important; padding:0.8em 1.2em !important; margin:1.2em 0 !important; background:rgba(0,0,0,0.02) !important; } .lb-wysiwyg-editor a { color:#007cba !important; text-decoration:underline !important; } .lb-wysiwyg-editor pre, .lb-wysiwyg-editor code { background:#f8f9fa !important; padding:0.2em 0.4em !important; border-radius:3px !important; font-family:monospace !important; } .lb-wysiwyg-editor pre { display:block !important; padding:1em !important; margin:1em 0 !important; overflow-x:auto !important; } '; } public function add_editor_script() { global $pagenow; if (!in_array($pagenow, ['post.php', 'post-new.php'], true)) return; echo ''; } public static function instance() { return self::get(); } } function lb_native_editor_init() { if (is_admin()) LB_NativeEditor::instance(); } add_action('plugins_loaded', 'lb_native_editor_init'); } // End class_exists

just go back to focus on content with a markdown editor. The biggest thing to bridge is insertion of media (and this is probably where there need to be coding for any non tinymce editor).

For bloggers markdown might be easy enough to learn (this is afterall what whatsapp, facebook uses, so it not even too geeky) and agencies probably edit content in word or google docs in whih thy also manage comments and versioning.

But people here probably have their own experiance and it will be nie to have feedback. This is not an either/or option, markdown can live next to tinymce and for pages that require more control over presentation there are always page builders.

Do you mean you want to insert pre-defined markup into the Text or HTML editor?

markdown is not a predefined markup, it is just a way for users to write semantic content without the need for understanding HTML. It is not a one to one match but can be good enough when visual formatting can be left to the theme.
I am sure you are familiar with it, and the current implementation of tinymce in wordpress actually supports a very limited syntax, but just in case I will link to the standard - Basic Syntax | Markdown Guide . note that there are different dialects, but don’t think you realy have to support more than the basics. biggest challange is probably adding media and links in an easy way to the content

We’ve already got insertion of media worked out. It’s in the Text widget in the nightly version of CP, and one of the drivers for that is so that it’s not dependent on TinyMCE. Sure, there will have to be a few adjustments to accommodate whatever new editor we finally go with, but they should be trivial to accomplish.