{"id":5627,"date":"2019-03-07T17:54:14","date_gmt":"2019-03-07T16:54:14","guid":{"rendered":"https:\/\/florianbrinkmann.com\/en\/?p=5627"},"modified":"2020-02-09T11:10:01","modified_gmt":"2020-02-09T10:10:01","slug":"modify-save-function-of-blocks","status":"publish","type":"post","link":"https:\/\/florianbrinkmann.com\/en\/modify-save-function-of-blocks-5627\/","title":{"rendered":"Modify save function of block"},"content":{"rendered":"\n<p>Sometimes there is a block for the WordPress block editor that is <em>almost<\/em> what we want, but it would be necessary to modify the markup it saves to the database. This post shows how we can filter the save function of a block to get that done.<\/p>\n\n\n\n<!--more-->\n\n\n\n<div class=\"update-box\">\n\n<p><strong>Update from March 8, 2019:<\/strong> Under the German version of the article, <a href=\"https:\/\/florianbrinkmann.com\/6683\/save-funktion-eines-blocks-aendern\/#comment-125142\">Julian wrote a comment<\/a> in which he says that you need to pay attention to not modify selectors that the block uses for getting attribute values.<\/p>\n\n<p>So if, for example, a gallery block uses an element with the class <code class=\"lang-html\">gallery-item<\/code> to get the attribute values for the images, you must not modify that class, because that would result in an error in the editor.<\/p>\n\n<\/div>\n\n\n\n<p>Recently I used the container block from the <a href=\"https:\/\/wpstackable.com\/\">Stackable<\/a> plugin but was not happy with a few styles it comes with. My first plan was to deregister the CSS file of the plugin and enqueue a modified version. But then I decided to just remove a \u2013 for me \u2013 unnecessary wrapper element that is used by the unwanted styles.<\/p>\n\n\n\n<p>There are several <a href=\"https:\/\/wordpress.org\/gutenberg\/handbook\/designers-developers\/developers\/filters\/block-filters\/\">block filters<\/a> for hooking into blocks, one of them is <code class=\"lang-js\">blocks.getSaveElement<\/code> to modify the save function. Stackable has a GitHub repo that lets us get the original <a href=\"https:\/\/github.com\/gambitph\/Stackable\/blob\/master\/src\/block\/container\/save.js\">save function of the Container block<\/a> easily, and we take the code between the curly brackets as a starting point for our modifications.<\/p>\n\n\n\n<p>This is the final code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-keyword\">import<\/span> {\n\tgetColorObjectByColorValue,\n\tgetColorClassName,\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'@wordpress\/editor'<\/span>\n<span class=\"hljs-keyword\">import<\/span> classnames <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'classnames'<\/span>\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">slugGetSaveElement<\/span>(<span class=\"hljs-params\"> element, blockType, attributes <\/span>) <\/span>{\n\t<span class=\"hljs-keyword\">if<\/span> ( blockType.name !== <span class=\"hljs-string\">'ugb\/container'<\/span> ) {\n\t\t<span class=\"hljs-keyword\">return<\/span> element;\n\t}\n\n\t<span class=\"hljs-keyword\">if<\/span> ( blockType.name === <span class=\"hljs-string\">'ugb\/container'<\/span> ) {\n\t\t<span class=\"hljs-keyword\">const<\/span> {\n\t\t\tclassName,\n\t\t} = element.props\n\t\n\t\t<span class=\"hljs-keyword\">const<\/span> {\n\t\t\ttextColor,\n\t\t\tbackgroundColor,\n\t\t} = attributes\n\n\t\t<span class=\"hljs-keyword\">let<\/span> hasTextColor = <span class=\"hljs-literal\">false<\/span>,\n\t\t\ttextColorClass = <span class=\"hljs-string\">''<\/span>,\n\t\t\thasBackgroundColor = <span class=\"hljs-literal\">false<\/span>,\n\t\t\tbackgroundColorClass = <span class=\"hljs-string\">''<\/span>;\n\n\t\t<span class=\"hljs-keyword\">const<\/span> textColorObj = getColorObjectByColorValue( backgroundColors, textColor );\n\t\t<span class=\"hljs-keyword\">const<\/span> backgroundColorObj = getColorObjectByColorValue( backgroundColors, backgroundColor );\n\n\t\t<span class=\"hljs-keyword\">if<\/span> ( textColorObj !== <span class=\"hljs-literal\">undefined<\/span> ) {\n\t\t\thasTextColor = <span class=\"hljs-literal\">true<\/span>;\n\t\t\ttextColorClass = getColorClassName( <span class=\"hljs-string\">'color'<\/span>, textColorObj.slug );\n\t\t}\n\n\t\t<span class=\"hljs-keyword\">if<\/span> ( backgroundColorObj !== <span class=\"hljs-literal\">undefined<\/span> ) {\n\t\t\thasBackgroundColor = <span class=\"hljs-literal\">true<\/span>;\n\t\t\tbackgroundColorClass = getColorClassName( <span class=\"hljs-string\">'background-color'<\/span>, backgroundColorObj.slug );\n\t\t}\n\t\n\t\t<span class=\"hljs-keyword\">const<\/span> mainClasses = classnames(\n\t\t\t<span class=\"hljs-string\">'ugb-container'<\/span>, {\n\t\t\t\t&#91; textColorClass ]: hasTextColor,\n\t\t\t\t&#91; backgroundColorClass ]: hasBackgroundColor,\n\t\t\t}\n\t\t)\n\t\n\t\t<span class=\"hljs-keyword\">return<\/span> (\n\t\t\t<span class=\"xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">{<\/span> <span class=\"hljs-attr\">mainClasses<\/span> }&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">className<\/span>=<span class=\"hljs-string\">\"ugb-container__wrapper\"<\/span>&gt;<\/span>\n\t\t\t\t\t<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">InnerBlocks.Content<\/span> \/&gt;<\/span>\n\t\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n\t\t\t<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span><\/span>\n\t\t)\n\t}\n}\n\nwp.hooks.addFilter(\n\t<span class=\"hljs-string\">'blocks.getSaveElement'<\/span>,\n\t<span class=\"hljs-string\">'slug\/get-save-element'<\/span>,\n\tslugGetSaveElement\n);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>First, we test for the block name to only modify the save function of the wanted block. If we have the wanted block, the following modifications are made compared to the block\u2019s original save function:<\/p>\n\n\n\n<p>I removed a lot of the code that handles the class names and inline styles, because I do not need them, and replaced them with classes for text and background color. The <code class=\"lang-js\">props<\/code> object that is used in the original function is available via <code class=\"lang-js\">element.props<\/code> in our function, <code class=\"lang-js\">props.attributes<\/code> via <code class=\"lang-js\">attributes<\/code>.<\/p>\n\n\n\n<p>Then I removed the <code class=\"lang-js\">div<\/code> with the class <code class=\"lang-js\">ugb-container__content-wrapper<\/code>, and that\u2019s it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes there is a block for the WordPress block editor that is almost what we want, but it would be necessary to modify the markup it saves to the database. This post shows how we can filter the save function of a block to get that done.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"wpf_show_in_dewp_planet_feed":false,"flobn_post_versions":"","webmentions_disabled_pings":false,"webmentions_disabled":false,"lazy_load_responsive_images_disabled":false,"footnotes":""},"categories":[115],"tags":[],"class_list":["post-5627","post","type-post","status-publish","format-standard","hentry","category-wordpress-snippets"],"wp-worthy-pixel":{"ignored":false,"public":"8061c02661ef481db059a9eb2d4ada3c","server":"vg04.met.vgwort.de","url":"https:\/\/vg04.met.vgwort.de\/na\/8061c02661ef481db059a9eb2d4ada3c"},"wp-worthy-type":"normal","_links":{"self":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/5627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/comments?post=5627"}],"version-history":[{"count":20,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/5627\/revisions"}],"predecessor-version":[{"id":5952,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/posts\/5627\/revisions\/5952"}],"wp:attachment":[{"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/media?parent=5627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/categories?post=5627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/florianbrinkmann.com\/en\/wp-json\/wp\/v2\/tags?post=5627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}