WP Editor
Textarea with the WordPress Editor like the one you use on the blog posts edit pages.
$options = [
'demo_wp_editor' => [
'label' => __( 'Rich Text Editor', 'unysonplus' ), // or false to hide the label column
'type' => 'wp-editor',
'value' => 'Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium',
'desc' => __( 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
'unysonplus' ),
'help' => sprintf( "%s \n\n'\"<br/><br/>\n\n <b>%s</b>",
__( 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
'unysonplus' ),
__( 'Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium',
'unysonplus' )
),
'reinit' => true,
// — Optional attributes you can add —
// 'size' => 'small', // small, medium, large
// 'editor_height' => 160,
// 'wpautop' => true,
// 'editor_type' => false,
// 'shortcodes' => false,
// 'attr' => [ 'class' => 'my-class', 'data-foo' => 'bar' ], // extra HTML attributes
// 'dynamic_content' => false, // hide the Dynamic Content (database) picker
],
];
Reading the value
wp-editor returns a string — output it directly.
In a shortcode
The shortcode framework passes the option values into view.php as $atts:
echo wp_kses_post( $atts['demo_wp_editor'] );
In a page template — a per-page option
Options defined on a post/page (a metabox) are read with fw_get_db_post_option():
$value = fw_get_db_post_option( get_the_ID(), 'demo_wp_editor' );
echo wp_kses_post( $value );
When the field is one of several inside a box/group, read the whole group once and pick fields by key — the common CPT pattern (e.g. a review or book box):
$book = fw_get_db_post_option( get_the_ID(), 'book' );
echo wp_kses_post( $book['demo_wp_editor'] );
In Theme Settings — a global option
Global options are read with fw_get_db_settings_option():
$value = fw_get_db_settings_option( 'demo_wp_editor' );
echo wp_kses_post( $value );
Saved value
fw_print( fw_get_db_settings_option( 'demo_wp_editor' ) ) outputs — the shape of this option type's stored value:
<p>Rich text <strong>content</strong> from the editor.</p>
In Gutenberg blocks (the React control)
wp-editor is one of the option types that also has a React version, so it can appear inside a Gutenberg block's sidebar.
Everything above is rendered by PHP. A block's settings sidebar is a React app and will not accept ready-made HTML from PHP, so the option type gets a second renderer. Both read the same schema and both produce the same saved value. See text for the full explanation.
What the wp-editor control does
It edits the markup directly, in a plain code field — not a WYSIWYG.
The obvious choice is Gutenberg's RichText, and it is the wrong one here.
RichText edits the contents of one block-level element. This option stores a whole HTML fragment, which routinely contains several — <p>a</p><p>b</p>, a <ul>, a heading. There is no lossless way to hand that to a single RichText: you either strip the outer tag (mangling anything with more than one block) or nest tags that were not nested. Both silently corrupt content authored in the page builder, and neither failure is visible until someone opens the page again.
Editing the markup is plainer and lossless — the right trade for a second authoring surface whose whole justification is that it agrees with the first. Rich editing stays in the page builder.
With wpautop on (the default), saving through the page builder runs the value through wpautop() and strips newlines, so typing Hello stores <p>Hello</p>.
A transforming save is the shape most likely to corrupt content a little more on each edit, so it is asserted in the test suite: the transform is idempotent for plain text, blank-line paragraphs, already-wrapped <p>, inline markup, lists and empty values. Saving repeatedly does not drift the markup.
Set 'wpautop' => false to store exactly what is written.
A block's attributes go from the editor straight to the element's PHP view — _get_value_from_input() never runs on that path, so wpautop() never runs either.
The practical difference: type Hello into this field in a block and the element receives Hello, unwrapped. Type it in the page builder and the element receives <p>Hello</p>. Same input, different markup, and the unwrapped version inherits none of the paragraph styling.
So write real markup here — <p>Hello</p> — rather than relying on a transform that only one of the two surfaces performs. The field edits HTML directly for exactly this kind of reason.
Making the two agree means validating block attributes at render time. That was measured against every block's output: two blocks improved, and one lost a working control, because switch requires its JSON-encoded wire format and every block already saved holds the raw value. It is a deliberate migration rather than a flag, and it has not been done — the reasoning is recorded in class-fw-extension-gutenberg.php.