Content made of blocks
Since WordPress 5.0, content has been written in the block editor (originally code-named Gutenberg). Instead of one big text box, a post is a sequence of blocks: a paragraph, a heading, an image, a list, a button, a quote, columns. Each block has its own settings, and you can move, copy or style them independently.
The editor screen
When you open a post or page, you see:
- the top toolbar: the block inserter (the + button), undo and redo, the List View button, Preview, Save draft and Publish;
- the canvas, where you write;
- the settings sidebar on the right, with two tabs: the post (or page) settings, such as status, categories and featured image, and the block settings for whichever block is selected.
Press **Ctrl+Shift+, ** (Windows) or Cmd+Shift+, (Mac) to show or hide the sidebar, and use Ctrl+Alt+H or Cmd+Option+H to see all keyboard shortcuts.
Adding blocks quickly
Three ways to add a block:
- Click the + inserter and browse or search.
- In an empty paragraph, type / followed by a name:
/heading,/image,/list,/button. - Use Markdown-style shortcuts: start a line with
##for a heading,-for a list,>for a quote.
Pressing Enter at the end of a paragraph starts a new paragraph block. Pasting text from a document usually converts headings and lists into the right blocks automatically.
Arranging blocks
Select a block and its toolbar appears above it, with buttons to move it up or down, change it into another block type, and format text. For layout:
- Group wraps blocks so they can share a background colour, padding or width. Its variations Row and Stack arrange the inner blocks horizontally or vertically.
- Columns places blocks side by side and stacks them on phones.
- Cover places text over an image or colour.
Nested layouts can be hard to click into, so open the List View: a tree of every block in the document, where you can select, rename and drag them.
How blocks are saved
What you build visually is saved as ordinary HTML in the post's post_content, with comment delimiters that tell WordPress which block each part is. Here is a post created directly with block markup:
<?php
$content = <<<HTML
<!-- wp:heading -->
<h2 class="wp-block-heading">Opening hours</h2>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p>We are open <strong>Monday to Saturday</strong>.</p>
<!-- /wp:paragraph -->
<!-- wp:list -->
<ul class="wp-block-list"><!-- wp:list-item --><li>9am to 6pm</li><!-- /wp:list-item --></ul>
<!-- /wp:list -->
<!-- wp:buttons -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="/contact/">Contact us</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons -->
HTML;
$id = wp_insert_post( [ 'post_title' => 'Visit us', 'post_content' => $content, 'post_status' => 'publish' ] );
foreach ( parse_blocks( get_post( $id )->post_content ) as $block ) {
if ( $block['blockName'] ) {
echo $block['blockName'], " (", count( $block['innerBlocks'] ), " inner)\n";
}
}core/heading (0 inner)
core/paragraph (0 inner)
core/list (1 inner)
core/buttons (1 inner)parse_blocks() reads the comments and gives back the structure: four top-level blocks, with a list item inside the list and a button inside the buttons block. A comment can also carry settings as JSON, such as <!-- wp:heading {"level":3} --> for an h3.
This design has a big advantage: the content is plain HTML. If the editor ever disappeared, or the content is read by another system, it still makes sense.
What visitors get
When the page is shown, WordPress renders each block. Static blocks like these output their saved HTML; dynamic blocks, such as Latest Posts, are built fresh by PHP on every view. Here is the text of the post's content area as a visitor receives it (the theme wraps it in an element with the class wp-block-post-content):
GET /visit-us/Opening hours
We are open Monday to Saturday.
9am to 6pm
Contact usThe rest of the page, the header, title, comments and footer, comes from the theme's templates, which are made of blocks too. You will build those yourself in the block themes section.
Reusing content: patterns
A pattern is a ready-made group of blocks, such as a pricing table or a call to action. Themes and the official Pattern Directory provide many; insert them from the Patterns tab of the inserter.
You can also save your own: select blocks, open the block's Options menu (three dots) and choose Create pattern. Patterns can be:
- synced: stored once; edit it anywhere and every copy updates. Use this for a newsletter sign-up box that appears on many pages.
- not synced: a starting point that you can change freely after inserting.
Synced patterns are posts of the type wp_block, inserted into content with a reference block:
<?php
$pattern = wp_insert_post( [
'post_type' => 'wp_block',
'post_title' => 'Newsletter box',
'post_status' => 'publish',
'post_content' => '<!-- wp:paragraph --><p>Get our monthly tips by email.</p><!-- /wp:paragraph -->',
] );
echo do_blocks( "<!-- wp:block {\"ref\":$pattern} /-->" ), "\n";<p class="wp-block-paragraph">Get our monthly tips by email.</p>do_blocks() is what WordPress runs to render block content. The reference block wp:block was replaced by the pattern's content.
Common mistakes
- Pressing Enter for spacing. Empty paragraphs are fragile; use the Spacer block or block spacing settings.
- Using bold text instead of headings. Headings give the page structure for readers, screen readers and search engines.
- Copying the same box into many pages instead of making a synced pattern.
- Editing the HTML by hand and breaking the block comments, which makes the editor show "This block contains unexpected or invalid content".
Exercise
Write a short post with a heading, two paragraphs, an image block and a button, then group the button and the second paragraph in a Group with a background colour. Open the Code editor (Options menu → Code editor) and find the wp:group comment.
Show one possible answer
Select the paragraph and the button (Shift+click in List View), then choose Group from the toolbar and pick a background colour under Styles. In the code editor you will find something like <!-- wp:group {"backgroundColor":"accent-1","layout":{"type":"constrained"}} --> wrapping a div that contains the paragraph and button blocks. Switch back with Exit code editor.
Key points
- Every piece of content is a block: paragraphs, headings, images, lists, buttons, columns, groups and many more.
- Type / in an empty block to search for a block, and use the List View to see and select nested blocks.
- Blocks are saved as normal HTML wrapped in comments such as <!-- wp:paragraph -->, which WordPress parses when it shows the page.
- Synced patterns let you reuse a block design in many places and update every copy at once.