{"id":290102,"date":"2026-03-19T21:39:30","date_gmt":"2026-03-19T21:39:30","guid":{"rendered":"https:\/\/fr.wordpress.org\/plugins\/juz-rich-text-extender\/"},"modified":"2026-03-19T21:39:01","modified_gmt":"2026-03-19T21:39:01","slug":"juz-rich-text-extender","status":"publish","type":"plugin","link":"https:\/\/hat.wordpress.org\/plugins\/juz-rich-text-extender\/","author":23066318,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.0.0","stable_tag":"1.0.0","tested":"6.9.4","requires":"6.1","requires_php":"7.0","requires_plugins":null,"header_name":"JuZ Rich Text Extender","header_author":"Ju'Z[ed]","header_description":"Extends the Gutenberg block editor toolbar with custom inline format buttons.","assets_banners_color":"20201f","last_updated":"2026-03-19 21:39:01","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/juzed.dev\/projets\/juz-rich-text-extender","header_author_uri":"https:\/\/juzed.dev\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":83,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"juzed","date":"2026-03-19 21:39:01"}},"upgrade_notice":{"1.0.0":"<p>Initial release \u2014 no upgrade steps required.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3486837,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3486837,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3486837,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3486837,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3486837,"resolution":"1","location":"assets","locale":""}},"screenshots":{"1":"Custom inline format buttons added to the Gutenberg toolbar.","2":"A button is automatically disabled when its nesting would be invalid."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[148076,258157,12737,1541],"plugin_category":[],"plugin_contributors":[242698],"plugin_business_model":[],"class_list":["post-290102","plugin","type-plugin","status-publish","hentry","plugin_tags-gutenberg","plugin_tags-inline-formats","plugin_tags-rich-text","plugin_tags-toolbar","plugin_contributors-juzed","plugin_committers-juzed"],"banners":{"banner":"https:\/\/ps.w.org\/juz-rich-text-extender\/assets\/banner-772x250.jpg?rev=3486837","banner_2x":"https:\/\/ps.w.org\/juz-rich-text-extender\/assets\/banner-1544x500.jpg?rev=3486837","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/juz-rich-text-extender\/assets\/icon-128x128.png?rev=3486837","icon_2x":"https:\/\/ps.w.org\/juz-rich-text-extender\/assets\/icon-256x256.png?rev=3486837","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/juz-rich-text-extender\/assets\/screenshot-1.png?rev=3486837","caption":"Custom inline format buttons added to the Gutenberg toolbar."}],"raw_content":"<!--section=description-->\n<p>JuZ Rich Text Extender allows developers to register custom inline format buttons in the Gutenberg (block editor) toolbar. Each button applies a specific HTML inline tag with an optional CSS class to the selected text.<\/p>\n\n<p>The plugin includes a built-in nesting validation system: buttons are automatically disabled when their use would produce invalid HTML nesting (e.g. <code>&lt;a&gt;<\/code> inside <code>&lt;a&gt;<\/code>). When a format is already active, its button remains enabled so it can always be toggled off.<\/p>\n\n<p><strong>Key features:<\/strong><\/p>\n\n<ul>\n<li>Register custom inline formats (tag + CSS class) via a WordPress filter<\/li>\n<li><code>tagName<\/code> defaults to <code>span<\/code>, which is strongly recommended for compatibility<\/li>\n<li>Smart nesting validation against the full active tag stack (for non-span tags)<\/li>\n<li>Buttons are visually disabled when nesting is not allowed<\/li>\n<li>Exhaustive inline tag ruleset (<code>span<\/code>, <code>a<\/code>, <code>strong<\/code>, <code>em<\/code>, <code>mark<\/code>, <code>code<\/code>, <code>u<\/code>, <code>s<\/code>, <code>i<\/code>, <code>b<\/code>, <code>q<\/code>, <code>cite<\/code>, <code>abbr<\/code>, <code>small<\/code>, <code>sub<\/code>, <code>sup<\/code>)<\/li>\n<li>Inline tag rules are filterable for full customisation by themes or other plugins<\/li>\n<\/ul>\n\n<p><strong>For developers:<\/strong><\/p>\n\n<p>Formats and inline tag rules are both exposed via WordPress filters, making the plugin fully extensible without modifying core files.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>juz-rich-text-extender<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Use the <code>juz_rich_text_extender\/formats<\/code> filter to register your custom inline formats.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20register%20a%20custom%20format%3F\"><h3>How do I register a custom format?<\/h3><\/dt>\n<dd><p>Use the <code>juz_rich_text_extender\/formats<\/code> filter to add your formats. Each format must be an associative array with the following keys:<\/p>\n\n<ul>\n<li><code>name<\/code> - unique identifier (used as the format type slug)<\/li>\n<li><code>title<\/code> - label shown in the toolbar tooltip<\/li>\n<li><code>tagName<\/code> - HTML inline tag to apply. Optional, defaults to <code>span<\/code>. See the caution note below.<\/li>\n<li><code>className<\/code> - CSS class applied to the tag<\/li>\n<li><code>icon<\/code> - a Dashicon slug or SVG string<\/li>\n<\/ul>\n\n<p>Example:<\/p>\n\n<pre><code>add_filter( 'juz_rich_text_extender\/formats', function( $formats ) {\n    $formats[] = [\n        'name'      =&gt; 'highlight',\n        'title'     =&gt; __( 'Highlight', 'your-text-domain' ),\n        'className' =&gt; 'my-highlight',\n        'icon'      =&gt; 'editor-textcolor',\n    ];\n    return $formats;\n} );\n<\/code><\/pre>\n\n<p><strong>CAUTION:<\/strong> <code>tagName<\/code> is optional and defaults to <code>span<\/code>, which is strongly recommended. Using any other tag may produce invalid HTML nesting or conflict with Gutenberg's internal formats (e.g. <code>core\/link<\/code> for <code>&lt;a&gt;<\/code> tags). If you do specify a custom tag, the nesting validation system will still protect against invalid HTML where possible, but you may encounter editor limitations. See \"How do I apply a custom class to a link?\" for more details.<\/p><\/dd>\n<dt id=\"how%20do%20i%20customise%20the%20inline%20tag%20nesting%20rules%3F\"><h3>How do I customise the inline tag nesting rules?<\/h3><\/dt>\n<dd><p>Use the <code>juz_rich_text_extender\/inline_tags<\/code> filter. Each tag entry has three keys: <code>canSelfNest<\/code> (bool), <code>canNestIn<\/code> (array of tag names), and <code>canContain<\/code> (array of tag names).<\/p>\n\n<p>Example:<\/p>\n\n<pre><code>add_filter( 'juz_rich_text_extender\/inline_tags', function( $tags ) {\n    \/\/ Allow &lt;kbd&gt; as a custom inline tag\n    $tags['kbd'] = [\n        'canSelfNest' =&gt; false,\n        'canNestIn'   =&gt; [ 'p', 'li', 'span', 'strong', 'em' ],\n        'canContain'  =&gt; [],\n    ];\n    return $tags;\n} );\n<\/code><\/pre><\/dd>\n<dt id=\"why%20is%20a%20button%20greyed%20out%20in%20the%20toolbar%3F\"><h3>Why is a button greyed out in the toolbar?<\/h3><\/dt>\n<dd><p>The nesting validation system detected that applying this format at the current cursor position would produce invalid HTML. For example, clicking <code>&lt;a&gt;<\/code> while already inside an <code>&lt;a&gt;<\/code> tag is forbidden by the HTML specification, so the button is disabled. This validation only applies to formats using a non-span <code>tagName<\/code>.<\/p><\/dd>\n<dt id=\"can%20i%20override%20nesting%20rules%20for%20an%20existing%20tag%3F\"><h3>Can I override nesting rules for an existing tag?<\/h3><\/dt>\n<dd><p>Yes. Use the <code>juz_rich_text_extender\/inline_tags<\/code> filter and modify the entry for the tag you want to change before returning the array.<\/p><\/dd>\n<dt id=\"how%20do%20i%20apply%20a%20custom%20class%20to%20a%20link%3F\"><h3>How do I apply a custom class to a link?<\/h3><\/dt>\n<dd><p>Gutenberg manages <code>&lt;a&gt;<\/code> tags internally via its own <code>core\/link<\/code> format, which makes it unreliable to apply a custom <code>&lt;a&gt;<\/code>-based format on top of an existing link. The recommended approach is to leave <code>tagName<\/code> unset (defaults to <code>span<\/code>) and target it in CSS using the <code>:has()<\/code> selector:<\/p>\n\n<pre><code>add_filter( 'juz_rich_text_extender\/formats', function( $formats ) {\n    $formats[] = [\n        'name'      =&gt; 'button',\n        'title'     =&gt; __( 'Button', 'your-text-domain' ),\n        'className' =&gt; 'btn',\n        'icon'      =&gt; 'button',\n    ];\n    return $formats;\n} );\n<\/code><\/pre>\n\n<p>Then in your CSS:<\/p>\n\n<pre><code>a:has(&gt; .btn) {\n    display: inline-block;\n    padding: 0.5em 1em;\n    background: #0073aa;\n    color: #fff;\n    border-radius: 4px;\n    text-decoration: none;\n}\n<\/code><\/pre>\n\n<p>This approach produces valid HTML (<code>&lt;a href=\"...\"&gt;&lt;span class=\"btn\"&gt;text&lt;\/span&gt;&lt;\/a&gt;<\/code>), survives the HTML \u2194 visual editor round-trip without issues, and is supported by all modern browsers.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<li>Custom inline format registration via filter.<\/li>\n<li>tagName defaults to span for maximum compatibility.<\/li>\n<li>Smart nesting validation on the full active tag stack for non-span tags.<\/li>\n<li>Exhaustive inline tag ruleset covering all standard HTML inline elements.<\/li>\n<li>Filterable inline tag rules for themes and plugins.<\/li>\n<\/ul>","raw_excerpt":"Extends the Gutenberg block editor toolbar with custom inline format buttons, with smart nesting validation based on HTML spec rules.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/290102","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=290102"}],"author":[{"embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/juzed"}],"wp:attachment":[{"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=290102"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=290102"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=290102"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=290102"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=290102"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/hat.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=290102"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}