1const n=`--- 2date: 2022-02-21 3slug: 2022-02-21-understanding-how-gutenberg-saves-data 4title: Understanding How Gutenberg Saves Data 5image: wordpress.jpg 6categories: WordPress 7tags: gutenberg,wordpress 8--- 9 10<p>With full-site editing released in WordPress 5.9, it's becoming 11impossible to ignore Gutenberg, the block editor. I've been avoiding 12it, as I think creating WordPress sites in plain PHP works great. 13One of the pain points that I've had in the past learning to write 14custom blocks is that it takes me much longer to create a custom block 15than to just style a custom shortcode. However, it is hard to beat 16that slick Gutenberg UI for users.</p><p>I spent some time recently digging through the ever-changing WordPress 17codex, learning as much as I could about the system. Once thing that 18always bugged me was understanding how the code <em>worked</em>, and how the 19content of the blocks were <em>saved</em> to the database. I knew that 20there was an <strong>edit</strong> and a <strong>save</strong> function, but it never really 21made much sense to me. I was used to just using PHP to echo out my content, 22and styling it with CSS. If I wanted to change the way something looked, 23I could easily change it in code.</p><p>After doing some experimenting, I learned a lot, and I think that I can provide 24a concise and easy way of understanding what you're actually developing 25when you are creating a custom block.</p><h3 id="separation-of-two-presentations">Separation of Two Presentations</h3> 26<p>It's kind of strange to think about, but you really have two different 27presentations. One is for the block editor itself, and one is for what 28the readers will see on the front-end of the WordPress site. </p><p>At first thought when reading that sentence you would probably think that 29they would be the same, since after all we are working with a WYSIWYG 30editor, right?</p><p>The main difference to remember here is that the editor will need to 31use special components that allow the user to interact and change content 32within the block. On the front-end, we're just needing to display 33the saved data in a stylish way. It should look very similar in the 34editor and on the front-end.</p><blockquote> 35<p>When I say "front-end", I am specifically referring to what the reader 36on the site would see.</p></blockquote> 37<h3 id="a-simple-example">A Simple Example</h3> 38<p>I've created a simple block using the <a href="https://developer.wordpress.org/block-editor/reference-guides/packages/packages-create-block/">Create Block</a> 39package provided by WordPress. Let's take a look at the <em>edit</em> function:</p><pre><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> useBlockProps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/block-editor'</span><span class="token punctuation">;</span> 40<span class="token keyword">import</span> <span class="token string">'./editor.scss'</span><span class="token punctuation">;</span> 41 42<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">Edit</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 43 <span class="token keyword">return</span> <span class="token punctuation">(</span> 44 <span class="token operator"><</span>p <span class="token punctuation">{</span><span class="token operator">...</span><span class="token function">useBlockProps</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">></span> 45 This is the editor text<span class="token operator">!</span> 46 <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> 47 <span class="token punctuation">)</span><span class="token punctuation">;</span> 48<span class="token punctuation">}</span> 49</code></pre><p>And we can take a look at it in the editor by adding the block to a new post:</p><p><img src="/images/simple-editor-block.png" alt="The simple example block shown in the Gutenberg editor"></p><p>This is pretty straightforward. The <em>edit</em> function is called when the example block is 50added to the editor, and renders out a paragraph with some text. But what happens when 51we publish it? Here's what we have in our <em>save</em> function:</p><pre><code class="language-javascript"><span class="token keyword">
51import</span> <span class="token punctuation">{</span> useBlockProps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/block-editor'</span><span class="token punctuation">;</span> 52 53<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 54 <span class="token keyword">return</span> <span class="token punctuation">(</span> 55 <span class="token operator"><</span>p <span class="token punctuation">{</span><span class="token operator">...</span>useBlockProps<span class="token punctuation">.</span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">></span> 56 This is the saved text<span class="token operator">!</span> 57 <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> 58 <span class="token punctuation">)</span><span class="token punctuation">;</span> 59<span class="token punctuation">}</span> 60</code></pre><p>And here is what is saved in the database:</p><pre><code class="language-html"><span class="token comment"><!-- wp:create-block/simple --></span> 61<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>wp-block-create-block-simple<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>This is the saved text!<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> 62<span class="token comment"><!-- /wp:create-block/simple --></span> 63</code></pre><p>Let's unpack a couple of things here. The <em>save</em> function renders out the 64HTML that is actually saved to the database. The comment that is at the 65beginning and end of the content notes the block that created this content. 66This corresponds to the name of the block that you specify within your 67<strong>block.json</strong> file. Take a look at the <em>name</em> property, it matches 68what is saved in the database.</p><pre><code class="language-json"><span class="token punctuation">{</span> 69 <span class="token property">"$schema"</span><span class="token operator">:</span> <span class="token string">"https://schemas.wp.org/trunk/block.json"</span><span class="token punctuation">,</span> 70 <span class="token property">"apiVersion"</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span> 71 <span class="token property">"name"</span><span class="token operator">:</span> <span class="token string">"create-block/simple"</span><span class="token punctuation">,</span> 72 ... 73</code></pre><blockquote> 74<p>Since the block content is saved to the 75database, this means that any changes to your block code will not 76affect existing saved blocks. That content would have to be 77opened in the editor, and re-published.</p></blockquote> 78<h3 id="saving-content-data-with-attributes">Saving Content Data with Attributes</h3> 79<p>So you have your <em>edit</em> and <em>save</em> functions created, but you want 80to allow the user to actually input something. How is this data 81actually translated from the <em>edit</em> function over to the <em>save</em> 82function, and then actually persisted in the database? If we are 83making editable content, let's say allowing the user to input the 84text in the paragraph tag, how will that be used in the editor 85when the user opens up saved content and wants to change it?</p><p>This is where attributes come in.</p><p>It's an odd name in my opinion, but the attributes are how we 86describe the metadata and content associated with an individual 87block.</p><p>Attributes are defined within our <strong>index.js</strong> file (if you're using 88the code generated using the WordPress generator). This is an object 89that is passed in to the <em>registerBlockType</em> function.</p><pre><code class="language-javascript"><span class="token keyword">
89import</span> <span class="token punctuation">{</span>registerBlockType<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/blocks'</span><span class="token punctuation">;</span> 90<span class="token keyword">import</span> <span class="token string">'./style.scss'</span><span class="token punctuation">;</span> 91<span class="token keyword">import</span> Edit <span class="token keyword">from</span> <span class="token string">'./edit'</span><span class="token punctuation">;</span> 92<span class="token keyword">import</span> Save <span class="token keyword">from</span> <span class="token string">'./save'</span><span class="token punctuation">;</span> 93 94<span class="token function">registerBlockType</span><span class="token punctuation">(</span><span class="token string">'create-block/simple'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> 95 <span class="token literal-property property">edit</span><span class="token operator">:</span> Edit<span class="token punctuation">,</span> 96 <span class="token literal-property property">save</span><span class="token operator">:</span> Save<span class="token punctuation">,</span> 97 <span class="token literal-property property">attributes</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span> 98<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 99</code></pre><p>For this example, we will do a simple attribute. We will dive deeper 100into different ways of storing data within attributes in a later post. 101Let's add a <em>text</em> property, with a type of <em>string</em> to our <em>attributes</em>.</p><pre><code class="language-javascript"><span class="token literal-property property">attributes</span><span class="token operator">:</span> <span class="token punctuation">{</span> 102 <span class="token literal-property property">text</span><span class="token operator">:</span> <span class="token punctuation">{</span> 103 <span class="token literal-property property">type</span><span class="token operator">:</span> <span class="token string">'string'</span> 104 <span class="token punctuation">}</span> 105<span class="token punctuation">}</span> 106</code></pre><p>Now that we have our attribute, let's change the <em>edit</em> function to 107allow the user to input some text. We will use the <strong>TextControl</strong> 108component to do so. We will also destructure a couple of items 109from the properties that are passed into the <em>edit</em> function. We 110will need the <em>attributes</em> and the <em>setAttributes</em>.</p><p>The <em>attributes</em> gives us access to the content that is currenly 111saved to the database. The <em>setAttributes</em> function allows us 112to update that data.</p><pre><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> useBlockProps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/block-editor'</span><span class="token punctuation">;</span> 113<span class="token keyword">import</span> <span class="token punctuation">{</span> TextControl <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/components'</span><span class="token punctuation">;</span> 114<span class="token keyword">import</span> <span class="token string">'./editor.scss'</span><span class="token punctuation">;</span> 115 116<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">Edit</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>attributes<span class="token punctuation">,</span> setAttributes<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 117 <span class="token keyword">return</span> <span class="token punctuation">(</span> 118 <span class="token operator"><</span>p <span class="token punctuation">{</span><span class="token operator">...</span><span class="token function">useBlockProps</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">></span> 119 <span class="token operator"><</span>TextControl 120 label<span class="token operator">=</span><span class="token string">"Write your text"</span> 121 value<span class="token operator">=</span><span class="token punctuation">{</span>attributes<span class="token punctuation">.</span>text<span class="token punctuation">}</span> 122 onChange<span class="token operator">=</span><span class="token punctuation">{</span><span class="token parameter">value</span> <span class="token operator">=></span> <span class="token function">setAttributes</span><span class="token punctuation">(</span><span class="token punctuation">{</span><span class="token literal-property property">text</span><span class="token operator">:</span> value<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">/</span><span class="token operator">></span> 123 <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> 124 <span class="token punctuation">)</span><span class="token punctuation">;</span> 125<span class="token punctuation">}</span> 126</code></pre><p>Save your work, and update your post. I've entered "hello world" 127into my newly updated block.</p><p><img src="/images/simple-editor-block-with-input.png" alt="Updated block with text input"></p><p>Let's publish the work and check what's in the database. Here's where 128things get strange. We already stated that the <em>save</em> function is responsible 129for saving the content to the database, and the <em>edit</em> function is for 130the presentation in the editor. You'd expect the database to look exactly 131the same, wouldn't you? You'd be wrong.</p><pre><code class="language-html"><span class="token comment"><!-- wp:create-block/simple {"text":"hello world"} --></span> 132<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>wp-block-create-block-simple<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
132This is the saved text!<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> 133<span class="token comment"><!-- /wp:create-block/simple --></span> 134</code></pre><p>The content within the paragraph tag is still the same, as you'd expect. 135However, you can now see a JSON object that represents the attributes of 136this block.</p><p>If you reload the editor in your browser, you'll see that your text 137remains. It works by pulling this text off of the attributes object. 138Pretty cool, huh?</p><h3 id="displaying-attribute-data-on-the-front-end">Displaying Attribute Data on the Front-End</h3> 139<p>Let's revisit our <em>save</em> function and update it so that it will now 140display to readers the text that we allowed our editor to add to it.</p><p>All we need to do, is destructure the <em>attributes</em> from the 141parameter that is passed by WordPress into the <em>save</em> function. 142Then, we can simply output the <em>text attribute</em> into the 143paragraph.</p><pre><code class="language-javascript"><span class="token keyword">import</span> <span class="token punctuation">{</span> useBlockProps <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@wordpress/block-editor'</span><span class="token punctuation">;</span> 144 145<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token keyword">function</span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span>attributes<span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span> 146 <span class="token keyword">return</span> <span class="token punctuation">(</span> 147 <span class="token operator"><</span>p <span class="token punctuation">{</span><span class="token operator">...</span>useBlockProps<span class="token punctuation">.</span><span class="token function">save</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">}</span><span class="token operator">></span> 148 <span class="token punctuation">{</span>attributes<span class="token punctuation">.</span>text<span class="token punctuation">}</span> 149 <span class="token operator"><</span><span class="token operator">/</span>p<span class="token operator">></span> 150 <span class="token punctuation">)</span><span class="token punctuation">;</span> 151<span class="token punctuation">}</span> 152</code></pre><p>And here is how it persists in the database after it is 153re-published:</p><pre><code class="language-html"><span class="token comment"><!-- wp:create-block/simple {"text":"hello world"} --></span> 154<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>p</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>wp-block-create-block-simple<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>hello world<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>p</span><span class="token punctuation">></span></span> 155<span class="token comment"><!-- /wp:create-block/simple --></span> 156</code></pre><p>As you can see, the attribute still exists within the 157attribute object in the initial comment, so that the 158editor can easily fetch it. The same text now also exists 159on the paragraph tag, allowing the front-end to render 160the text properly.</p><p>That's it! That's the basics of using attributes within a 161custom Gutenberg block! </p>`;export{n as default};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.