Deactivate blocks for specific post types

In my project I use WordPress as a backend for a native app, I have implemented two custom post types. For booth post types only a limited set of blocks should be available. That’s simply due to the fact, that not all contents can be rendered/used in the app.

Filter allowed blocks

We can use the filter allowed_block_types to allow only a limited set of blocks that can be used or allow/disallow all of them. If you just want to allow some blocks for a specific post type, use the filter like this:

function cpt_allowed_blocks( $allowed_block_types, $post ) {
	if ( 'my_post_type' === $post->post_type ) {
		return array(
	return $allowed_block_types;
add_action( 'allowed_block_types', 'cpt_allowed_blocks', 10, 2 );

In the callback function we first check, if we are currently editing our custom post type. If we do, we return an array with only the block included we want allow in our post type. If not, we return the original value.

This original value can either be an array or a boolean. If you return true, all blocks are allowed. If you return false no blocks are allowed.

Bonus: Set a blocks template for a post type

If you limit the blocks you want to allow, you probably want to ensure a specific layout in your post type. You can help with that by adding some blocks by default, every time an entry for that post type is created. This can be done when registering the post type:

function cpt_register_post_type() {
			'label'                 => __( 'My Post Type', 'text_domain' ),
			'supports'              => array( 'title', 'editor' ),
			'public'                => true,
			'show_ui'               => true,
			// ... other settings
			'has_archive'           => true,
			'show_in_rest'          => true,
			'template'              => array(
						'placeholder' => __( 'Lorem ...', 'text_domain' ),
add_action( 'init', 'cpt_register_post_type' );

With the template parameter, you can define a number of blocks to include every time a post type entry is created. Each block is represented by an array. For many blocks you can also set options. In this example we add a paragraph with a placeholder text (not content) and an image with no options. This image block will be in it’s “edit state”, just as if you have added it to a post yourself:


When working with custom post types, you can easily limit the blocks that are allowed to be used. Adding a template with some default blocks for new entries really increase the usability of your custom post types a lot.

Change the default email “from name” and “from email”

In WordPress, emails are sent from different places. Most typically are mails sent by a form plugin. In probably most of them you can set the “from name” and “form email”. But there are also mails that are sent from WordPress core. One example of such an email is the “Password Recovery Mail”. Also some other plugins might send emails either to a user or to the admin.

Change the default “from” values

If an email is sent and the name and email address are not set explicitly, WordPress will always use “WordPress” and “wordpress@your-domain.tld” as the defaults. Unfortunately there is no setting in the dashboard to change those default.

Overwrite the values using filters

There are two filter you can use to overwrite the name and the email address. Simply put the following into a (mu-)plugin and activate it:

// Change the "from name"
function wp_email_set_from_name( $from_name ) {
	return 'Your Name';
add_filter( 'wp_mail_from_name', 'wp_email_set_from_name' );
// Change the "from email"
function wp_email_set_from_email( $from_email ) {
	return 'your-name@your-domain.tld';
add_filter( 'wp_mail_from', 'wp_email_set_from_email' );

This will overwrite the two values. But it will overwrite it for any email. That’s probably not what you want. Unfortunately the filters are only called, when the default values have already been set. So we cannot simply check if explicit values have been used while sending an email. But we can still check for those default values and only set you own values, if they match the defaults:

// Change the default "from name"
function wp_email_set_from_name( $from_name ) {
	if ( 'WordPress' === $from_name ) {
		return 'Your Name';
	return $from_name;
add_filter( 'wp_mail_from_name', 'wp_email_set_from_name' );
// Change the default "from email"
function wp_email_set_from_email( $from_email ) {
	if ( false !== strpos( $from_email, 'wordpress@' ) ) {
		return 'your-name@your-domain.tld';
	return $from_email;
add_filter( 'wp_mail_from', 'wp_email_set_from_email' );

This should now only set new values, if they are the default values. You can still set another name or email address e.g. in a form plugin.


Overwriting the default name and email address for sent emails can be done with some filters. But be careful not to overwrite them for any case, but only in those cases, where the defaults are used, not when another name and email address have been set already.

Create users in WordPress using the REST API

For a current project, we use WordPress as the backend for a native mobile app. The app is developed by another company. I’m responsible for the WordPress part. The content for the app is being created using multiple custom post types and custom taxonomies, as well as some special blocks for a better editing experience. The app can be used without any registration. But some features need a registration, such as synchronizing results on multiple devices or comparing results with other users.

Preparing the server to accept requests

In order to make requests to the server, some response headers have to be set, especially for the iOS version. I first tried to set them using the server configuration, just to realize, that WordPress sets some response headers as well, which resulted in some duplicate headers with the same key, but different values. After some debugging I’ve found some hooks I could use:

function app_rest_headers_allowed_cors_headers( $allow_headers ) {
	return array(
add_filter( 'rest_allowed_cors_headers', 'app_rest_headers_allowed_cors_headers' );

For another hook there was no filter, so I had to explicitly call the PHP header() function for this one:

function app_rest_headers_pre_serve_request( $value ) {
	header( 'Access-Control-Allow-Origin: *', true );
	return $value;
add_filter( 'rest_pre_serve_request', 'app_rest_headers_pre_serve_request', 11 );

After this small preparation, we can try to create a user with the users endpoint, but this is not going to work. Why not? Well, simply because you cannot create a user for a WordPress site using the REST API without authorization. If that would be possible, that wouldn’t really be good, because otherwise anyone could register a user on an WordPress site.

Authenticate a user with the REST API

So how to we authenticate against the REST API? There are different ways. A very new one is just around the corner and it’s going to be the first one to be integrated into Core: Application Passwords.

There is currently a proposol to integrate the feature project into the upcoming WordPress 5.6. If you want to use it already, you can install the plugin Application Passwords.

Create an app user for the user management

By default, only admin users can manager users. But you probably don’t want to allow an app to have every capability an admin has on a WordPress site. Therefore it’s better to create a special user that only has those capabilitites managing users. You can do that by using a plugin like Members, create a role and a user with PHP code or you use the WP-CLI:

wp role create app App --clone=subscriber
wp cap add app create_users
wp user create app-rest-user --role=app

The user needs to have at least the create_users capability to create users and you should also add the read capability, so you can login with the new user and set the application password (this is why we clone the “subscriber” role in the example above). Alternatively you can set the application password for a user with an admin user.

Get the application password for the new user

After you have created the user, login with that user and navigate to the profile settings (or edit it’s profile with an admin user). Here you find a new profile field to create application passwords. Choose a name and hit “Add new”:

This will open a modal with the generated password. You have to copy that password from the modal, as you cannot get it’s plain text after closing the modal.

Now we have everything we need for your API call to create users.

Create your first user

Depending on which system you use to make calls against the WordPress REST API, you workflow looks different. I’ll just use a plain curl call from the terminal to demonstrate the request:

curl --user "app-rest-user:younfj4FX6nnDGuv9EwRkDrK" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"username":"jane","password":"secret","email":""}' \

If you have set up everything correct, you should get a JSON response with the data of the new user.


Managing users is possible with some setup work and (currently) some external authentication plugins, but with the new applications password feature it will become a lot easier. In a similar way you can make any other call to the REST API that needs an authorized user. For better security, it’s best to create a specific user for such calls (unless you want to create content assigned to a specific user).

Deactivate individual block styles

In my last blog post I’ve showed you how to deactivate page templates in a child theme and this week I have another tip on how to deactivate some of the things that might come with a parent theme or a plugin. Today I will write about block styles. They are normally defined by Core or the theme, but sometimes they are introduced by plugins.

Deactivate them using a dequeue hook

Block styles are defined using a JavsScript file. That file must be enqueued into the page. This is where we can use a hook to dequeue that file. It could look like this:

function dibs_dequeue_assets() {
	wp_dequeue_script( 'editorskit-editor' );
add_action( 'enqueue_block_editor_assets', 'dibs_dequeue_assets', 11 );

This example would remove the main editor JavaScript file, which will not only disable block styles, but all JavaScript code of that plugin. So this is only a good solution, if there is a separate file just with the registrations of block styles.

Deactivate specific block styles

If you just want to remove specific block styles from the backend, you have to use some JavaScript code yourself. So first we have to enqueue a JavaScript file we can then use:

function dibs_enqueue_assets() {
		plugins_url( 'remove-block-styles.js', __FILE__ ),
		array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
		filemtime( plugin_dir_path( __FILE__ ) . 'remove-block-styles.js' ),
add_action( 'enqueue_block_editor_assets', 'dibs_enqueue_assets', 11 );

The enqueued file need the dependencies wp-blocks, wp-dom-ready and wp-edit-post to work properly. After we have enqueued the file, we can use it to unregister some block styles:

wp.domReady( function() {
} );

After the editor has loaded, we will use wp.blocks.unregisterBlockStyle() with the first parameter set to the slug of the block we want to unregister a block style for. The second parameter is the slug of the block style. In this example we would remove the same two block styles from the core/image and from the core/cover block.

This approach is likely the one you want to use, as you don’t want to remove the complete JavaScript as in the first snippet, but only the block styles. And of those you might want to remove only a few.


If a theme or plugin introduces block styles, you don’t want to use, you can use a small JavaScript file to remove them. You just have to be aware, that even if you remove the block styles from being selected for new blocks, the previously selected block styles are still attached to block with the corresponding CSS file. So if you want to remove the block styles from the front end as well, you either have to remove the CSS classes on the old blocks or remove/overwrite the CSS parts in your (child) theme.

Deactivate or replace a page templates in a child theme

This week one of my colleagues was working on a new project, where a page template in the parent theme was broken. There was a better similar page template to use instead, but there might still be the chance that someone would use this broken page template, when creating a new page. So I had the idea to find out, how to deactivate a page template from the dropdown.

Deactivate a page template

In a child theme, it is quite easy to create a new page template or to overwrite a page template, by copying it over from the parent theme. But how can you prevent a page template from showing up in the dropdown? Fortunately, there is almost always a hook for that. If you want to deactivate a page template, use this filter:

function child_theme_disable_page_template( $post_templates, $theme, $post, $post_type ) {
	unset( $post_templates['page-templates/tpl-hero-light.php'] );
	return $post_templates;
add_filter( 'theme_templates', 'child_theme_disable_page_template', 10, 4 );

The filter theme_templates will get an array with all templates, using the relative path as the key and the (translated) name as a value. It could look like this:

$post_templates = array(
	'page-templates/tpl-fullscreen-light.php'  => 'Fullscreen, light header',
	'page-templates/tpl-fullscreen.php'        => 'Fullscreen',
	'page-templates/tpl-fullwidth-notitle.php' => 'Full Width, no page title',
	'page-templates/tpl-fullwidth.php'         => 'Full Width',
	'page-templates/tpl-hero-light.php'        => 'Hero, light header',
	'page-templates/tpl-hero.php'              => 'Hero',

The array contains page templates from both the parent theme and the child theme. If both have a page template with the same path, only one of it will be included in the array.

Replace a page template

So now you know how to avoid someone from using a page template you don’t want them to use. But what about all the pages that already have that page template selected? You could do a search/replace in the database, replacing all postmeta with the key _wp_page_template and replace it with a new value. But maybe you want to keep the information in the database intakt. Then you can use a variety of hooks to overwrite the path. This is one of the filters you can use:

function child_theme_overwrite_page_template( $template ) {
	if ( get_parent_theme_file_path( '/page-templates/tpl-hero-light.php' ) === $template ) {
		return get_theme_file_path( '/page-templates/tpl-hero.php' );
	return $template;
add_filter( 'template_include', 'child_theme_overwrite_page_template' );

In this example, any page that would use the page-templates/tpl-hero-light.php page template from the parent theme will now be using the page-templates/tpl-hero.php page template from the child theme.


While it’s very easy to add or overwrite page templates in a child theme, deactivating one in a child theme is not as easy. But as WordPress usually has a hook for anything you want to customize, even this task is not that hard.

Manually update or downgrade plugins and themes with WordPress 5.5

The lastest WordPress major release 5.5 was released mid August. There have been some nice new features. But one of these new features has not been mentioned in many posts about the new release. It’s the possibility to replace an installed plugin or theme using a zip file.

Some previous ways to replace an installed plugin or theme

In WordPress, it’s really easy to update a plugin or theme to the newest version (at least for all plugins available on But downgrading a plugin or theme to an old version or updating premium versions is not that easy.

Using the WP-CLI

If you use the WP-CLI, you can use the install command for plugins or themes to install a specific version. If that plugin or theme is already installed, you simply force install it:

wp plugin install gutenberg --version=8.9.0 --force

This will overwrite the current version with the given version. This is only possible if that version is available through the plugin or theme directory.

Uploading the old version using SFTP/FTPS/FTP

If you don’t have access to the server though SSH and/or can’t use the WP-CLI on the server, you can use a file transfer client to delete the old version and replace it with a different one. This approach has the bis drawback, that you first have to manually delete the old version and then upload the new one. Depending on how large the plugin is and how many files it has, this can take some time and your site might be broken while you are replacing the plugin. You could minimize that time by uploading the old version to a different folder and then rename the current version (or delete it) and rename the old version to the correct folder name. But still this way is not really ideal.

Deactivate and uninstalling the current version

Some of you might think that you can simply deactivate and uninstall the current version and then you install the old version. This can be really risky. Many plugins delete their settings when they are deactivated/uninstalled, some even the data created by those plugins. So this way should really be avoided.

Replace the current version with the new WordPress 5.5 feature

When you’ve updated to WordPress 5.5, you have a very new way. To use it, you simply have to upload the old version as a zip file. You can get an old version either from you backup or from the plugin or theme directory.

Download an old version of a plugin

For a plugin that’s very easy. Just navigate to the plugin page on the plugin directory and click on the “Advanched View” link on the right:

Here you scroll all the way to the bottom, where you can find a dropdown with previous version. These are all versions the plugin authors have tagged/released:

Select the version you want to have and click on the download button. This should get you a zip file with that specific version. If you can’t find that dropdown, then unfortunately the developers have never tagged a specific version.

Upload the old version and replace the current version

Now you can upload that version. This works just as installing a plugin or theme for the first time. So in your dashboard you navigate to “Plugins | Add New” and then click on the “Upload Plugin” button next to the headline. Then you use the file upload form and click “Install Now” to upload the zip file. This will then show you a screen like this:

You will be presented with a page showing you the current version of the plugin and the uploaded version. For both you will see which version of WordPress and PHP they require. If you want to continue, click on the blue “Replace current with uploaded” button.


Sometimes even the smaller features of a release can make a huge difference for users. Downgrading plugins or themes was not an easy task in the past. But when your site crashed after an update, there is a big need to get back to an old version. This new feature will come in very handy for those cases. But it will also help you if the premium plugins or theme you are using does not integrate into the update mechanism of WordPress.

Order post type navigation by name

On many client projects, there is a need to create custom post types. I usually create them using the wp scaffold post-type command from the WP-CLI. This will create the necessary PHP functions with the most common definitions and a large array where you can set nice labels. But in the most basic way, registering a post type could looks like this:

function optn_register_post_type() {
			'label'       => __( 'Sponsor', 'optn' ),
			'public'      => true,
			'has_archive' => true,
			'show_ui'     => true,
add_action( 'init', 'optn_register_post_type' );
Read more →

Organizing WordCamps in times of a world wide pandemic

Around two weeks ago, the Global Leads, the Local Lead and the Mentor of WordCamp Europe 2021 took the hard decision to postpone the in-person event in 2021 in Porto for another year and organize the next edition of WCEU online again. After the great success of this year’s event, the new organizing team will have the chance to organize an even bigger event in 2021, giving them more time focusing on the special needs for an online event. The Call for organizers ended just around a week ago. I’m wishing the new organizing team all the best – which I will not be a part of.

Read more →

Use startup tasks as a replacement for file watchers in PhpStorm

Last week I started with a new project and developed a theme using Underscores as the base theme. I always use the “sassified” version and create it with the WP-CLI scaffold command. When I inspected the files, I could see some new files in the directory. But one of the files that is included for quite some time is the package.json file, defining various npm tasks, of which some are responsible to compile Sass files or watch for file changes on those files.

Using file watchers from PhpStorm

In the past I have usually used the file watchers from PhpStorm. In a blog post from January 2018, I’ve explained how to set such a file watcher up to compile Sass files. This is a good way when you don’t have any other mechanism to compile those files bundled with the software/theme/plugin. But if you develop something that has a compilation task defined in the projects, things can get more complicated, especially when you work in a team with members of that team using different operation systems and default Sass compilers. In the past a Ruby compiler was the recommended option, but as of March 2019, this option has been depecated. Now it’s recommended to use either Dart Sass or Lib Sass to compile your files. I’ve tried out Dart Sass, as it was the only compiler that was producing the exact same CSS files on Windows, Linux and Mac in my tests.

So why not just use one of the new compilers in combination with a PhpStorm file watcher? There are two reasons. First, those file watchers are not easy to set up, especially when the folder structure is different to the default structure. This is the case for Underscores, where the style.scss files it stored in the sass sub folder, but the compiled style.css file is in the root folder. The seconds reason is the possibility of additional compilation tasks defined in the package.json file. A common example for that is a PostCSS plugin like the Autoprefixer. Those compilers would not run on the Sass file watcher in PhpStorm.

Running a watcher from the package.json file

You can run an npm (or similar) task in PhpStorm in two ways. You either start a terminal and run the command there (which will exit, as soon as you close the terminal) or you run it using “Task | Run Gulp/Grunt/npm Task” from the menu bar.

Screenshot of the "Run npm Task" window

From here you simply double click one of the tasks and it will run in a new task window in PhpStorm. But every time you develop on that project, you have remember to start that task manually, while the file watcher was “starting” automatically. So isn’t there a better way?

Using a startup task to run the watcher

Fortunately there is a very easy way I’ve found some weeks ago. You can define startup tasks that would run every time you open a project in PhpStorm. In the settings at “Tools|Starup Tasks” you can choose from a wide variety of tasks to run. One of them is npm. So first, you just add such a startup task:

Screenshot of the "Settings | Tools | Startup Tasks" window with "npm" selected as the new type of task to add

If you have ran the npm task manually before, as described above, you can simply select it on the left. If you haven’t you simply create a new task giving it a name, selecting the package.json file and the command and script to run on startup:

Screenshot of the npm run configuration setting

Once you’ve set the startup task, simply restart PhpStorm or close and reopen the project to test the startup task. You should see the same run window opening as in the manual run.


The file watchers in PhpStorm are really useful when you work on a project that is not using any task runner. But it’s limited and the setup can be more complicated. Using the startup tasks makes it a lot easier to use the tasks bundled in a projects and ensures that you and your team are all using the same tasks. This can dramatically reduce issues like merge conflict on differently complied files and similar issues.

Cleaning up space on your development environment

Even the largest hard drive has a limit. From time to time, you have to clean up some file to be able to work on some new projects. Working on multiple WordPress projects, old and new ones, can use up a lot of storage. In a previous blog post from earlier this year, I’ve showed you how to save storage by loading images from a live website. As images and other files in the uploads folder are usually the largest parts of a WordPress website, this already helps a lot. But there is another type of files, that can easily fill up you hard drive in now time: database dumps.

Finding large database dumps

When you work on projects that have already gone live, you probably want to get the latest database from the live website and import it locally. But you might also have done some settings in your local environment, so you make a backup of the local database before replacing it with the live one. That’s already two dumps. Then you play around a bit with the content and just in case make some more backups. And as some WordPress databases easily have some hundred megabytes, your free disk space is reduced quite fast. So the first step you should take is to find all those large database dumps on your local disk. For that, you can simply run this command in the main local development folder:

find . -type f -size +10M -name "*.sql"

This command will find any SQL dump that is larger then 10 MB. You might even want to search for smaller files, if you have lots of them which sums up to some hundred megabytes in total. If you wand to see how large all of these files are, you simply extend the command and run it through the du command:

find . -type f -size +10M -name "*.sql" -exec du -h "{}" \;

Now that you have found all of these files, you can delete those you really don’t need anymore. But what about files you still might need?

Compressing all database dumps

Well, you can simply use another command and compress all of them in one go. You just have to run this command:

find . -type f -size +10M -name "*.sql" -exec gzip "{}" \;

This will compress all database dumps larger than 10 MB using the gzip command. I’ve run that command on my work laptop some days ago and was able to save more than 3.5 GB on my drive. It only took about 90 seconds to run. If I need to restore any of the compressed dumps, I would use ungzip them before and then import the dump into the database.

Find other large files

Once you’ve done with compressing all database dumps, why not search for other types of large files that can easily be compress or deleted? Some other good candidates are logfiles, like the debug.log you will find in the wp-content folder, when you’ve activated the WP_DEBUG_LOG in an installation. To find those files, either replace the search pattern or just remove it completely, to find all large files:

find . -type f -size +10M -exec du -h "{}" \;

Searching without a file extension will probably also show you a lot of media files, that are easily large as well. But then you might use the trick mentioned earlier to load those from a remote server.

Another type of files you may find are XML files. They may come from the WordPress XML Exporter, but they could also some other type of files, that needes to be left uncompressed.


Some of you may think now “Why not just compress all .sql files?”, but this can cause some issues. If you search without the size filter, you will find some files within plugins. Those files are usually used to create the necessary database tables, when installing/activating the plugin. If you compress them, the plugin can probably now longer use them. So don’t use a to low file size in the filter. On my system 1 MB was even small enough to catch all real database dump but not those special files. The same is true for some XML files mentioned earlier. And you can’t compress logfiles, if you still want to write to them. So don’t just compress every text file that is too large.


Having a lot of projects on needs a lot of disk space. Knowing how to save some of this valuable space is crucial, especially when you can’t simply upgrade the hard drive in your hardware. Compressing all those database dump quickly cleanup up a lot of disk space for me in no time and without the need to decide on every file, weather I still need it or not.