Customizing Gutenberg blocks with block styles

Block styles are a simple way to get started with Gutenberg development: With a few lines of CSS, you can build something that feels like a whole new custom block.

This post was updated on January 13, 2020 to adopt the server-side registration approach described in the Block Editor handbook.


A few years ago, Matt Mullenweg urged us all to “Learn JavaScript Deeply.” Becoming more familiar and comfortable with JavaScript is increasingly important for those of us who build the web. In the world of WordPress, projects like Gutenberg have begun taking a major step into a JavaScript-powered future.

For designers and developers who are still getting used to these new languages and workflows, creating and customizing Gutenberg blocks can be somewhat intimidating. There are excellent toolkits like Create GutenBlock to help you get started, but even using those, building a block requires quite a bit of JavaScript familiarity. You also have to make sure you’ve got the right version of Node, learn some terminal commands, install some dependencies, etc. There’s quite a bit of up-front work necessary before you can jump in and start actually building something.

Despite these hurdles, we’ve seen an inspiring number of new block plugins surface lately: CoBlocks, and Atomic Blocks are great examples. They each add a variety of rich blocks, and truly enhance the site-building experience.

There’s a much simpler way to start customizing Gutenberg blocks though, and it’s something we haven’t seen utilized much at this point: block styles. They take only a few minutes to pick up, and mostly just require you to know CSS.

You’ve likely noticed block styles while using Gutenberg. The Quote, Pullquote, Separator, Table, and Button blocks ship with some alternate styles by default.

Block styles are an excellent but relatively unused area of Gutenberg customization. They’re a simple way to get started with Gutenberg development: With a few lines of CSS, you can build something that feels like a whole new custom block. Also, since they’re reusable across multiple sites, block styles help pave the way for a more flexible system of components that make up a site’s theme.

Technically, block styles are very simple. They’re composed of two things:

  • A few lines of PHP (or JavaScript) to declare the block variation and give it a custom class name.
  • CSS styles to fine-tune the appearance.

That’s it. A block style is a custom block class, with some styles applied.

Implementation

A block style can be implemented in a plugin or in a theme. For this example, I’m going to focus on making a plugin. One of the benefits of using a plugin is that it’s not tied to the user’s theme. This allows your block style to be used across any site, running any theme — as if you had built an entirely new custom block.

Block styles can be defined in JavaScript, or in PHP. To keep things simple, we’re going to focus on using the latter. This lets us set everything up with only two files:

  • index.php to set up the plugin, declare the block style, and enqueue the stylesheet
  • style.css to house the actual styles

index.php

By default, index.php just needs to initialize the plugin with a DocBloc, enqueue the CSS file, and register a new block style:

<?php
/**
 * Plugin Name: Block Styles
 */
 
/**
 * Register Custom Block Styles
 */
if ( function_exists( 'register_block_style' ) ) {
    function block_styles_register_block_styles() {
        /**
         * Register stylesheet
         */
        wp_register_style(
            'block-styles-stylesheet',
            plugins_url( 'style.css', __FILE__ ),
            array(),
            '1.1'
        );

        /**
         * Register block style
         */
        register_block_style(
            'core/paragraph',
            array(
                'name'         => 'blue-paragraph',
                'label'        => 'Blue Paragraph',
                'style_handle' => 'block-styles-stylesheet',
            )
        );
    }

    add_action( 'init', 'block_styles_register_block_styles' );
}

Let’s take a closer look at the block style registration portion:

register_block_style(
    'core/paragraph',
    array(
        'name'         => 'blue-paragraph',
        'label'        => 'Blue Paragraph',
        'style_handle' => 'block-styles-stylesheet',
    )
);

The second line tells Gutenberg which existing block to start with. In this example, we are going to create a block style for the Paragraph block. Any existing block can inherit a block style, so if you were to target a different block, you’d change core/paragraph to the name of a different block. Technically, these names are found in the Gutenberg block source code, but they’re usually easily guessable. For example: core/cover, core/separator, etc.

The name parameter on the fourth line creates the custom class that’ll be assigned to the block. In this case, I’m calling it a blue-paragraph, but it can be anything you’d like. Since this will be used for a CSS class, be sure not to use any spaces.

The label parameter corresponds to the text label for your block style. This will be shown in the interface when someone opens the “Block Styles” panel.

Finally, style_handle points WordPress to the stylesheet where it can find the CSS for your block style.

style.css

The CSS file is pretty straightforward. Use the custom class name you created in block.js (along with a is-style- prefix), and insert your styles inside:

.is-style-blue-paragraph {
// Custom CSS styles go here.
}

Your styles here will build off of the default block styles, and will be loaded in before a theme’s editor styles. So be sure to keep your selectors specific enough to override those potentially competing styles.

Block Styles Plugin Boilerplate

To help you get started, I’ve created a GitHub repository that you can clone and use to get started. It contains the three files detailed above, along with some light documentation.

https://github.com/Automattic/gutenberg-block-styles

Out of the box, the repository is a small plugin that adds a “Blue Paragraph” block style to the Paragraph block:

With a few small adjustments, it’s possible to change this into something drastically different. There’s another branch on that GitHub repository that includes a Music theme-style cover block variant:

I’ve included a third branch that adds a somewhat ridiculous animation to the text (or emoji) inside of a Cover block:

Both of these are accomplished by changing about a dozen lines of code in the repo. They took minutes to create, and work across any site that uses Gutenberg, regardless of the theme it’s using.

What will you create?

Block styles are ripe with possibility. I’d love to see a CSS Zen Garden-style plugin someday that showcases dozens of different ways to customize blocks through block styles.

In the meantime, have you built something cool using block styles? If so, I’d love to hear about it. Please share your explorations in the comments.

Tired of Vagrant? Try Laravel Valet

I’ve used Vagrant for more than a year now and although it was crashing from time to time, I always managed to get it working again. Not last week. I don’t what happened, but enough was enough – I decided to pull the plug and look for a better alternative.

I thought about switching back to MAMP, as my needs are pretty straightforward. At the same time, I was also on the lookout for something a bit more modern, something that would allow me to use a custom *.test URL like Vagrant and share my local site to the world without a headache. That’s when I found Laravel Valet (or Valet for short).

Valet is a Laravel development environment for Mac minimalists. No Vagrant, No Apache, No Nginx, No `/etc/hosts file`. You can even share your sites publicly using local tunnels.

It’s so easy I wish I’d switched to it a few months ago when it was initially released.

Don’t get me wrong – Vagrant is still great for big development environments. But for my own simple WordPress needs, Valet is the perfect tool which I would highly recommend to fellow WordPress developers.

How to install?

The official documentation and the article written by Tom McFarlin on TutsPlus are both really clear, but I’ll share my own process in case you’d like to try it.

1. Install Homebrew

Install Homebrew:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

2. Update Homebrew

Once installed, make sure you have the latest version of all the packages using brew update.

If you get an error, you probably need to update your .bash_profile. From the terminal, enter sudo nano .bash_profile. It will open the file. Add the following line to it:

export PATH="/usr/local/bin:$PATH"

Save and close (ctrl+X, Y then enter). Let’s make sure we reload the new file now with source .bash_profile in the terminal.

3. Install PHP 7.2 and MariaDB

We need to install PHP 7.2 using Homebrew:

brew install php72

We also need to install a database:

brew install mariadb

4. Install Composer

Valet requires Composer to work. If you don’t have it installed on your computer, run this in your terminal to get the latest Composer version:

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '93b54496392c062774670ac18b134c3b3a95e5a5e5c8f1a9f115f203b75bf9a129d5daa8ba6a13e2cc8a1da0806388a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer

5. Install Valet

First of all, we need to make sure we can install Valet.

From the terminal, enter sudo nano .bash_profile. Once the file is open, add a new line to it:

export PATH="$PATH:$HOME/.composer/vendor/bin"

Save and close the file (ctrl+X, Y then enter). Reload the new file with source .bash_profile in the terminal.

Now we can continue our installation:

composer global require laravel/valet

Once it’s done you will see a success message like so: Writing lock file. Generating autoload files.

Now we need to finalize the installation of Valet:

valet install

After a moment you should get a Valet installed successfully! message.

That’s it. Valet is installed and is running.

6. Using Valet

To start using Valet, you need to “park” it. Go to a folder containing all you sites, e.g. cd /Sites/, and simply type valet park. From now on, all the folders inside this Site folder will get a .test URL. So for example, a folder named MyAwesomeWordPressSite will be accessible from http://myawesomewordpresssite.test.

I downloaded the latest version of WordPress and created a new folder called… WordPress. So when I type wordpress.test in my browser I’m being redirected to my WordPress site. On the first launch, you will have to install WordPress the same way you’d do on a server.

WordPress: The first launch

First of all, we need to start the MySQL server so in your terminal just enter mysql.server start. This step is pretty much the equivalent of vagrant up. You will have to do it every time you want to work. To turn it off just enter mysql.server stop (just like vagrant halt).

Then you will need a MySQL database.

In the terminal, run: (whatever is the name of our database here)

mysql -uroot
CREATE DATABASE whatever;
exit

If you prefer a GUI, I would recommend Sequel Pro to create and manage my databases. It’s free and it has a simple interface.

Name: Valet (can be anything)
Host: 127.0.0.1
Username: root
Password: leave it blank!

Sequel Pro

Now we can proceed with the WordPress installation.

WordPress install

If you run into an error like Fatal error: Uncaught phpmailerException: Invalid address: wordpress@ we need to update the WordPress driver. In the terminal run:

sudo nano ~/.composer/vendor/laravel/valet/cli/drivers/WordPressValetDriver.php

Add within frontControllerPath:

$_SERVER['SERVER_NAME'] = $siteName.'.test';

Save and close the file (ctrl+X, Y then enter).

And that’s it… You’re done.

WordPress Trunk

You can also have a Trunk version of WordPress. Just create a new folder (still in Sites), e.g. WordPress-Trunk, and checkout WordPress.

cd /Sites/WordPress-Trunk
svn co https://develop.svn.wordpress.org/trunk/src/ .

So every time you want to update this install all you need to do is:

cd /Sites/WordPress-Trunk/src/
svn up

If you now go to http://wordpress-trunk.test, you will see an error 404 because Valet doesn’t understand it’s a WordPress site. No worries. You just need to link the src folder to Valet (where the actual WordPress site is).

cd /Sites/WordPress-Trunk/src/
valet link

Now you can access Trunk via http://src.test. As it’s not ideal as a URL let’s rename it to http://trunk-wordpress.test:

mv ~/.config/valet/Sites/src ~/.config/valet/Sites/trunk-wordpress

Et voilà! You can access you freshly downloaded WordPress Trunk install in your browser with http://trunk-wordpress.test.

Jetpack Social Menu

With the release of Jetpack 3.9 last month, we introduced a new tool available for all theme developers: Social Menus. It allows site owners to create a new menu location which is used to display links to Social Media Profiles.

Adding Support

Theme developers can add support for a Social Menu by following these three simple steps.

Step 1: Declare support in a function hooked to after_setup_theme.

add_theme_support( 'jetpack-social-menu' );

Step 2: Create a new function to avoid fatal errors if Jetpack isn’t activated.

function themename_social_menu() {
	if ( ! function_exists( 'jetpack_social_menu' ) ) {
		return;
	} else {
		jetpack_social_menu();
	}
}

Step 3: Use the function created in step 2 to output the menu where you would like it displayed in the theme.

themename_social_menu();

Styling

Once you’ve created a menu, Jetpack will automatically enqueue a basic stylesheet to style each one of the menu items, thanks to Genericons. You don’t have to do anything else!

Working with the Eventbrite API Plugin

Eventbrite and WordPress are the perfect fit, but until now, integrating the two has not been for the faint of heart. In early 2014, Eventbrite announced its new upcoming REST API, and this became the perfect opportunity to give theme developers an easy-to-use set of tools for working with Eventbrite events: the Eventbrite API plugin.

The plugin gives theme developers three ways to interact with the Eventbrite API:

  • Theme support
  • The Eventbrite_Query class
  • Helper functions

Theme Support

While the Eventbrite API plugin can display events in any theme, events look their best if the theme declares support and provides tailored templates. This simple process guarantees that events fit perfectly with the theme design, and adding support should take no more than ten minutes.

  1. Add a support declaration, hooked to after_setup_theme. There are no arguments, and usually this can be added to a theme’s existing setup function.
    function themeslug_setup() {
    
    	...
    
    	/**
    	 * Add theme support for the Eventbrite API plugin.
    	 * See: https://wordpress.org/plugins/eventbrite-api/
    	 */
    	add_theme_support( 'eventbrite' );
    }
    add_action( 'after_setup_theme', 'themeslug_setup' );
    
  2. Create an eventbrite folder in your theme, and copy over the plugin’s main template files (tmpl/eventbrite-index.php and tmpl/eventbrite-single.php).
  3. Compare the markup in eventbrite-index.php to your own index.php and adjust as necessary. Also, verify that your markup for archive titles matches the Eventbrite template’s page title. The Eventbrite templates don’t use template parts for the post markup, so you may need to compare with content.php or the like. Of course, there’s no reason you couldn’t add a content-eventbrite.php to your theme, if you prefer.
  4. Repeat step 3 with eventbrite-single.php and your own single template.

That’s it! If support is declared, the plugin will use those templates if they exist, or fall back to the plugin’s templates. To see some custom templates in action, check out any of the Twenty* default themes; their templates are included in the plugin.

Eventbrite integration with Twenty Fifteen.
Eventbrite integration with Twenty Fifteen.

The Eventbrite_Query Class

It was important to us that working with the Eventbrite API plugin should be a simple and familiar process for theme developers, with a low barrier to entry. With that in mind, we developed the Eventbrite_Query class, so fetching and displaying events is as simple as making a secondary loop (in fact, the class extends WP_Query). This allows for easy creation of special-purpose loops, widgets, creative page templates – any combination of events you want to display in a theme.

<?php
	// Get the next three unpublicized events for the Apollo Planetarium.
	$events = new Eventbrite_Query( apply_filters( 'eventbrite_query_args', array(
		'display_private' => true,
		'limit' => 3,
		'venue_id' => 6955925,
	) ) );

	if ( $events->have_posts() ) :
		while ( $events->have_posts() ) : $events->the_post(); ?>

There are a few things to keep in mind while working with Eventbrite_Query loops.

  • You can continue to use familiar template tags in event loops, such as the_post_thumbnail(), the_title(), the_content(), etc. They’ve simply been filtered to provide content from the current event.
  • For technical reasons, a few template tags need their Eventbrite equivalent, such as eventbrite_is_single() and eventbrite_edit_post_link().
  • Being a secondary loop, don’t forget to add wp_reset_postdata() at the end.
  • All of the plugin’s template tags are pluggable, and filters exist at various points for further customization.

Helper Functions

If you’re happy processing your own results, and just want an easy-to-use set of tools to handle the API requests, the included helper functions are for you. Each supported API endpoint has its own helper function, and these functions in turn use the Eventbrite_Manager class for the heavy lifting. Not only does this class make the actual API requests, but also handles validation and transients, so you can concentrate on results rather than mechanics.


The Eventbrite API plugin is developed on GitHub, and issues or questions can be posted there or in the forums. Additional info and documentation can be found here.

Along with the Eventbrite Services plugin, it’s never been easier or more fun to display events in your WordPress website. Let us know what you’re doing with Eventbrite, and tell us if there’s anything the Eventbrite API plugin can do to make your Eventbrite integrations easier for you!

The Eventbrite API plugin requires the Keyring plugin for managing OAuth2 authorization to Eventbrite. If you get stuck, check out our detailed instructions for getting connected to Eventbrite.

The Power of Eventbrite on WordPress

Eventbrite is the world’s premier event-management service, and we’re happy to announce two new ways to add Eventbrite events to your self-hosted WordPress site!

We’ve offered Eventbrite integration on WordPress.com for a while, with two dedicated themes. While this made getting your events on your WordPress site easier than ever, it wasn’t available to self-hosted users, and you were limited to only the two themes. Both of these issues are solved with new additions to the WordPress.org theme and plugin repositories.


The Eventbrite Multi theme by Voce Communications.
The Eventbrite Multi theme by Voce Communications.

Originally developed by Voce Communications, the Eventbrite themes that have been available on WordPress.com are now in the WordPress.org theme repository, and the plugin that powers them is also available for download. Together, the themes and the plugin provide full-featured Eventbrite integration for single and multiple events, including a calendar view and a widget. Huge thanks to Voce for continuing to support their work in the .org space!


Automattic has also developed an Eventbrite plugin, called Eventbrite API. This plugin is designed to work with any theme, with no explicit support required. It also provides a selection of simple tools that allow theme developers to work with events as easily as custom loops, making Eventbrite theme integrations more fun to build than ever. We’ll have a post next Monday demonstrating how to take advantage of this new plugin in your themes.

Eventbrite and WordPress are a perfect match, and we now have two great plugins for bringing them together. See you at the show!

The Genericons Icon Font Story

Icon fonts are a truly great hack. They’re lightweight, scalable, and a clever way to use vector-based images on the web at a time when SVG just doesn’t have enough popular browser support to be practical. Despite starting out life as a hack, icon fonts are like the sprites of vector graphics, and I think they’re here to stay.

Enter Genericons, a new icon font made especially for blogs by Joen Asmussen with contributions from Sheri Bigelow and Takashi Irie. They were designed with simplicity in mind to keep a minimal, “generic” aesthetic so they can be used in a wide range of projects. They look sharp at small sizes because each icon has been aligned to on a 16×16 pixel grid.

Continue reading “The Genericons Icon Font Story”

Getting Excited About Edge Code

Last night Adobe’s Create The Web Tour rolled into Portland, Oregon and I attended. The night consisted of two presentations highlighting the new tools that Adobe has developed for creating the web. Of the many tools demonstrated, Edge Code really made an impression. It looks a bit like this:

edge-code

In the past, I’ve used a grip of opensource text editors. My favorite has always been Notepad++. While I am free to modify and redistribute the code under the GPL license, I never have for one very important reason: I have no idea how to. Notepad++, like many other text editors, is written in a language I do not understand. This is where Edge Code is a bit different.

Edge Code is a distribution of Brackets which is available under the MIT license and is written in html, css, and javascript. Three technolgies that I can read and write. This is pretty exciting; I’ve always wanted to be able to edit my editor and now I can!

This is only one of the many neat features of Edge Code. It also syncs with your browser so you can see your changes in real time. It understands the relationships between html and css, allowing you to edit your stylesheet directly from an html document. It’s great to see inovations like these being developed for those of use who build the web.

I’m going to install Edge Code today with the hope that I can introduce it into my daily work flow. Have you tried it yet? If so, please leave a comment and let us know what you think about it.

Work with Image Sprites? Generate CSS with SpriteCow

SpriteCow is a nifty tool that generates CSS for your image sprites. Upload a sprite, click on the desired region and — like magic — SpriteCow will generate a CSS snippet containing the background position, width, and height for that region.

At the time of this writing, SpriteCow only works in Chrome, Firefox, Opera, and IE10 (Safari is not supported).

Developer plugin v1.1: Optimize Your Theme Development Environment

The amazing Code Wranglers at Automattic recently released version 1.1.1 of the Developer Plugin, which helps you optimize your WordPress development environment (plus saves you time) by making sure you have all of the essential development plugins installed. This new version targets the people who design and develop themes — you! Read on to learn more.

Continue reading “Developer plugin v1.1: Optimize Your Theme Development Environment”

Introducing the Monster Widget

An important part of the theme development process is testing. As a member of the Theme Team at Automattic I can say that we like to test everything we can! One thing that we have observed is that widget testing can take up a lot of time. WordPress provides 13 widgets, many of which contain a form enabling us to customize each instance. Populating a sidebar with widgets can be rather time consuming especially if you have to tweak each widget’s settings.

Continue reading “Introducing the Monster Widget”

Better WordPress Theme Internationalization with Pig Latin!

During the process of creating my first public WordPress theme one thing was very important to me – I wanted the theme to be useful to as many people as possible. To reach this goal, I knew that I would need to make sure that my theme could be used in any language. Luckily, WordPress core provides a few different functions that makes this pretty easy to do. If this is a new topic for you, please read more about Internationalization for WordPress Developers in the codex.

Continue reading “Better WordPress Theme Internationalization with Pig Latin!”