{"id":1382,"date":"2023-04-18T13:05:27","date_gmt":"2023-04-18T12:05:27","guid":{"rendered":"https:\/\/editjournal.redakt.eu\/faxmodem\/?p=1382"},"modified":"2023-04-18T13:51:22","modified_gmt":"2023-04-18T12:51:22","slug":"gutenberg-block-editor-toggle-control-custom-css-classname","status":"publish","type":"post","link":"https:\/\/editjournal.redakt.eu\/faxmodem\/blog\/wordpress\/gutenberg-block-editor-toggle-control-custom-css-classname\/","title":{"rendered":"Adding custom toggle control to Gutenberg Block Editor"},"content":{"rendered":"<p><strong>Requirement<\/strong>. Every header (<code>core\/heading<\/code>) block needs to have a toggle control for adding or removing a custom class name to\/from the resulting element.<\/p>\n<p><strong>Usage example<\/strong>. Building an automatic table of contents generator, which will pick only the headers having the custom class name. The admin needs to easily select headers that should be used for the table of contents.<\/p>\n<p>(Related: here's how to define a custom static Block element acting as a placeholder where the table of contents, generated with Javascript, will be inserted: <a href=\"https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/block-tutorial\/writing-your-first-block-type\/\">https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/block-tutorial\/writing-your-first-block-type\/<\/a>.)<\/p>\n<p>The following PHP code goes under <code>wp-content\/plugins\/exampleplugin\/exampleplugin.php<\/code>:<\/p>\n<pre><code>&lt;?php\n\/**\n * @package ExamplePlugin\n * @version 1.0\n *\/\n\/*\nPlugin Name: ExamplePlugin\nPlugin URI: http:\/\/example.com\/\nDescription: Custom\nAuthor: ExamplePlugin\nVersion: 1.0\nAuthor URI: http:\/\/example.com\/\n*\/\n\nfunction enqueue_block_editor_adjustments() {\n    wp_register_script(\n        &#039;block_editor_adjustments&#039;,\n        plugin_dir_url( __FILE__ ) . &#039;block_editor_adjustments.js&#039;,\n        [ &#039;wp-blocks&#039;, &#039;wp-dom&#039;, &#039;wp-dom-ready&#039;, &#039;wp-edit-post&#039; ],\n        filemtime( plugin_dir_path( __FILE__ ) . &#039;block_editor_adjustments.js&#039; )\n    );\n    wp_enqueue_script( &#039;block_editor_adjustments&#039; );\n}\n\nadd_action( &#039;enqueue_block_editor_assets&#039;, &#039;enqueue_block_editor_adjustments&#039; );<\/code><\/pre>\n<p>The above adds our custom Javascript file in the editor.<\/p>\n<p>And here is the <code>wp-content\/plugins\/exampleplugin\/block_editor_adjustments.js<\/code> file:<\/p>\n<pre><code>\/\/ Register our property at core\/heading\nwp.hooks.addFilter(\n    &#039;blocks.registerBlockType&#039;,\n    &#039;ExamplePlugin\/block_editor_adjustments&#039;, \/\/ our custom namespace\n    function(settings, name) {\n        if (name !== &#039;core\/heading&#039;) { \/\/ skip other core blocks\n            return settings;\n        }\n        settings.attributes = Object.assign(settings.attributes, {\n            showInTableOfContents: { \/\/ showInTableOfContents is our property name\n                type: &#039;boolean&#039;,\n                default: false\n            }\n        });\n        return settings;\n    }\n);\n\n\/\/ Display the custom ToggleControl for every header; toggle the custom property\nwp.hooks.addFilter(\n    &#039;editor.BlockEdit&#039;,\n    &#039;ExamplePlugin\/block_editor_adjustments&#039;,\n    wp.compose.createHigherOrderComponent(function(BlockEdit) {\n        return function(props) {\n            if (props.name !== &#039;core\/heading&#039;) { \/\/ skip other core blocks\n                return wp.element.createElement( BlockEdit, props );\n            }\n            console.log(&#039;here are the props&#039;, props);\n            return wp.element.createElement(\n                wp.element.Fragment,\n                {},\n                wp.element.createElement( BlockEdit, props ),\n                wp.element.createElement(\n                    wp.blockEditor.InspectorControls,\n                    {},\n                    wp.element.createElement(\n                        wp.components.PanelBody,\n                        {},\n                        wp.element.createElement(\n                            wp.components.ToggleControl,\n                            {\n                                label: &#039;Show in Table of Contents&#039;,\n                                checked: props.attributes.showInTableOfContents,\n                                onChange: ( value ) =&gt; {\n                                    props.setAttributes( { showInTableOfContents: value } );\n                                },\n                            }\n                        )\n                    )\n                )\n            );\n        };\n    })\n);\n\n\/\/ Convert the custom property value into CSS class name on every save\nwp.hooks.addFilter(\n    &#039;blocks.getSaveContent.extraProps&#039;,\n    &#039;ExamplePlugin\/block_editor_adjustments&#039;,\n    function(extraProps, blockType, attributes) {\n        if (blockType.name !== &#039;core\/heading&#039;) { \/\/ skip other core blocks\n            return extraProps;\n        }\n        if (attributes.showInTableOfContents) {\n            extraProps.className = extraProps.className + &#039; fq_contents_header&#039;;\n        }\n        return extraProps;\n    }\n);<\/code><\/pre>\n<p>General idea and guidance:<\/p>\n<ul>\n<li><a href=\"https:\/\/mariecomet.fr\/en\/2021\/12\/14\/adding-options-controls-existing-gutenberg-block\/\">https:\/\/mariecomet.fr\/en\/2021\/12\/14\/adding-options-controls-existing-gutenberg-block\/<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/MarieComet\/core-block-custom-attributes\/blob\/main\/src\/attributes\/sidebarSelect.js\">https:\/\/github.com\/MarieComet\/core-block-custom-attributes\/blob\/main\/src\/attributes\/sidebarSelect.js<\/a><\/li>\n<\/ul>\n<p>Documentation:<\/p>\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/support\/topic\/wp-hooks-addfilter-syntax\/#post-12762922\"><code>addFilter()<\/code> syntax<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/filters\/block-filters\/#blocks-registerblocktype\"><code>blocks.registerBlockType<\/code> hook<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/filters\/block-filters\/#editor-blockedit\"><code>editor.BlockEdit<\/code> hook<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-element\/#createelement\"><code>wp.element.createElement()<\/code><\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/packages\/packages-compose\/#createhigherordercomponent\"><code>wp.compose.createHigherOrderComponent()<\/code><\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/components\/toggle-control\/\"><code>ToggleControl<\/code> documentation<\/a><\/li>\n<\/ul>\n<p>Other, helpful:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/block-tutorial\/block-supports-in-static-blocks\/\">https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/block-tutorial\/block-supports-in-static-blocks\/<\/a> shows that edit and save callbacks can be potentially defined right inside registerBlockType, but I cgot stuck at BlockEdit not being available<\/li>\n<li>the above approach is in this OP code <a href=\"https:\/\/wordpress.stackexchange.com\/questions\/346612\/how-to-get-the-togglecontrol-gutenberg-component-working-for-a-php-block\">https:\/\/wordpress.stackexchange.com\/questions\/346612\/how-to-get-the-togglecontrol-gutenberg-component-working-for-a-php-block<\/a> and the answer shows the working ToggleControl example<\/li>\n<li><a href=\"https:\/\/github.com\/WordPress\/gutenberg\/issues\/20213\">https:\/\/github.com\/WordPress\/gutenberg\/issues\/20213<\/a><\/li>\n<li><a href=\"https:\/\/awhitepixel.com\/blog\/add-custom-settings-to-existing-wordpress-gutenberg-blocks\/\">https:\/\/awhitepixel.com\/blog\/add-custom-settings-to-existing-wordpress-gutenberg-blocks\/<\/a> <code>editor.BlockEdit<\/code> + <code>blocks.getSaveContent.extraProps<\/code> usage example<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Requirement. Every header (core\/heading) block needs to have a toggle control for adding or removing a custom class name to\/from the resulting element. Usage example. Building an automatic table of contents generator, which will pick only the headers having the custom class name. The admin needs to easily select headers that should be used for&hellip; <a class=\"more-link\" href=\"https:\/\/editjournal.redakt.eu\/faxmodem\/blog\/wordpress\/gutenberg-block-editor-toggle-control-custom-css-classname\/\">Continue reading <span class=\"screen-reader-text\">Adding custom toggle control to Gutenberg Block Editor<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[674],"tags":[677,1074],"class_list":["post-1382","post","type-post","status-publish","format-standard","hentry","category-wordpress","tag-wordpress","tag-wordpress-gutenberg","entry"],"_links":{"self":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1382","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/comments?post=1382"}],"version-history":[{"count":3,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1382\/revisions"}],"predecessor-version":[{"id":1388,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/posts\/1382\/revisions\/1388"}],"wp:attachment":[{"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/media?parent=1382"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/categories?post=1382"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/editjournal.redakt.eu\/faxmodem\/wp-json\/wp\/v2\/tags?post=1382"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}