WordPress Developer Blog https://developer.wordpress.org/news A site for plugin and theme developers, freelancers, and agency developers Thu, 20 Mar 2025 18:05:39 +0000 en-US hourly 1 https://wordpress.org/?v=6.8-alpha-59827 https://s.w.org/favicon.ico?2 WordPress Developer Blog https://developer.wordpress.org/news 32 32 208500394 What’s new for developers? (March 2025) https://developer.wordpress.org/news/2025/03/whats-new-for-developers-march-2025/ https://developer.wordpress.org/news/2025/03/whats-new-for-developers-march-2025/#respond Thu, 20 Mar 2025 16:34:47 +0000 https://developer.wordpress.org/news/?p=5091 March means a lot of things to a lot of people. Almost every tradition has a holiday this time of year that celebrates the start of spring, fresh air, new growth and longer days. 

For millions of basketball fans like me, it’s the best month of the year for basketball. That’s because, in the US and Canada,  March Madness brings the national college tournament and its concurrent excitement of buzzer-beaters, upsets, and championship dreams.

There’s also a lot to get excited about in the WordPress world this month.

WordPress 6.8 is less than a month away, bringing a bucketful (pun intended! It’s March!) of improvements from recent Gutenberg updates.  March brings lots of things to test, contribute to, and prepare for what’s ahead.

Highlights

WordPress 6.8 and Gutenberg 20.3 and 20.4

The next version of WordPress is 6.8, and it is scheduled for release on April 15th, 2025. This update will include enhancements from Gutenberg versions 19.4 through 20.4.

With just about four weeks until launch, there’s plenty to test! If you have time to contribute, now is the perfect opportunity. Stay informed by following developer notes for 6.8, and keep an eye out for the 6.8 Field Guide, which the release squad aims to publish alongside RC 1, on March 25.

Recently published developer notes for 6.8:

While 6.8 is mostly a polish and bug-fix release, you will still find meaningful updates. If you’re a plugin developer, or you otherwise work in the WordPress ecosystem, it’s time to test your products for compatibility.

Themes

Here are some notable changes to blocks your users might appreciate:

Block Library

The latest improvements to Gutenberg bring more flexibility and feature enhancements across various blocks. The Query block now includes an option to ignore sticky post behavior, giving users more control over content display. Social links have been expanded with the addition of Discord, making it easier to link to the platform. The Featured Image block now uses the resolution tool component for better image handling. Additionally, the RSS block receives support for border and spacing adjustments, enhancing layout customization.

  • Query block: Add option to ignore sticky posts behavior. (69057)
  • Added Discord in social links. (68848)
  • Featured Image block: Use resolution tool component. (68471)
  • RSS: Border & Spacing support. (66411)

Global Styles

Several refinements have been made to improve the usability and customization options in Gutenberg. The Clear button for box shadows is now disabled when no shadow is applied, preventing unnecessary interactions. Duotone settings have been enhanced with a reset button and improved toggle rendering in the FiltersPanel for a smoother user experience. Similarly, a reset button has been added to the Shadow panel, making it easier to revert changes. Additionally, theme developers now have the ability to set the :focus-visible pseudo-selector in theme.json, improving accessibility and styling control.

  • Disable Clear button if there’s no shadow. (69092)
  • Duotone Settings: Add reset button and improve toggle rendering in FiltersPanel. (68672)
  • Shadow Panel: Add reset button. (68981)
  • Allow :Focus-visible pseudo-selector to be set in theme.json. (68521)

Post Editor

Several improvements have been made to enhance the editor’s usability and stability. Loading states have been added to the Page Attributes Parent and Post Author Combobox components for a smoother experience. Error handling is now improved with clear messages when loading a post fails. The default rendering mode for Pages is now conditionally enabled, and users’ Show Template preferences will persist between sessions. Additionally, the starter content modal has been restored, and the Post Template Panel popover now appears on the left side of the sidebar for better consistency.

  • Editor: Add loading state to the ‘PageAttributesParent’ component. (69062)
  • Editor: Add loading state to the ‘PostAuthorCombobox’ component. (68991)
  • Editor: Display error message when loading current post fails. (68999)
  • Editor: Conditionally enable the new default rendering mode for Pages. (69160)
  • Editor: Persist user’s ‘Show Template’ preference. (69286)
  • Editor: Restore starter content modal. (69081)
  • Post Template Panel: Display popover on the left side of the sidebar. (69134)

Block Editor

Several refinements have been made to improve block interactions and usability. The Quick Inserter now restores pattern search and insertion for easier access. Keyboard shortcuts for block deletion have been updated to use Shift + Backspace. The Post Navigation Link now supports all non-interactive formats, while the Pullquote block gains a missing alignment style. The Query Loop block introduces menu_order as a sorting option, and block actions now include a convenient cut functionality within the settings menu.

  • Quick Inserter: Restore pattern search and insertion. (69028)
  • Update keyboard shortcuts to use primaryShift+backspace for block deletion. (69074)
  • Post Navigation Link: Enable all non-interactive formats. (69325)
  • Pullquote: Adding missing alignment style. (68121)
  • Query Loop: Add menu_order as sorting option. (68781)
  • Block Action: Implement cut functionality in block actions and settings menu. (68554)

Components

Enhancements to UI controls improve usability and feedback. The BorderControl now always displays the Reset button for quicker adjustments, while the ComboboxControl gains an isLoading prop, allowing a loading spinner to provide better visual feedback when fetching options.

  • BorderControl: Always show the Reset button. (69066)
  • ComboboxControl: Add an isLoading prop to show a loading spinner. (68990)

Design Tools

Customization options have been expanded across multiple blocks. The Archives and Categories blocks now support color customization, allowing for better visual styling. Additionally, the Post Comments Count block gains border support, providing more design flexibility.

  • Archives: Add Color Support. (68685)
  • Categories: Add Color Support. (68686)

Post Comments Count: Add Border Support. (68223)

Resources

Props to @marybaum and @greenshady for reviewing this article and offering feedback.

]]>
https://developer.wordpress.org/news/2025/03/whats-new-for-developers-march-2025/feed/ 0 5091
Customize WordPress embeds to match your theme https://developer.wordpress.org/news/2025/02/customize-wordpress-embeds-to-match-your-theme/ https://developer.wordpress.org/news/2025/02/customize-wordpress-embeds-to-match-your-theme/#respond Thu, 27 Feb 2025 08:25:37 +0000 https://developer.wordpress.org/news/?p=5044 Have you ever thought about customizing your WordPress embeds?

Not that there’s anything wrong with the defaults. WordPress gives you a neutral, adaptable design that fits seamlessly into almost any layout. This is why many leave the default unchanged.

However, with a little effort, you can make your embeds reflect your brand, match your site’s design, and even display extra information—beyond the title and excerpt.

In this article, you’ll see several ways to tailor both the look and content of your WordPress embeds. Let’s dive in!

What are embeds?

Embeds let you include external content in your posts, including videos, polls, social media posts, and even content from other WordPress sites.

The YouTube videos you see on different websites are almost certainly embeds, except for a few that use custom players. Likewise, just as you can include YouTube videos on your website, others can embed your WordPress posts on theirs.

If a service is supported, you can embed a resource simply by pasting a URL into the Embed Block. If it’s not, you’ll have to use the Custom HTML Block to insert the embed code. The embed code nearly always contains an iframe tag.

In both cases, the front-end displays an iframe pointing to a simplified, embed-friendly version of the content at the canonical URL.

For example, the canonical URL of this article is the one in your browser’s address bar. If you append /embed/ to the URL, you’ll see how this post looks when embedded.

Essentially, a WordPress /embed/ endpoint serves a slightly different view of the same post.

YouTube works the same way, where you have the main, canonical video URL, such as https://www.youtube.com/watch?v=KLybH5YvIPQ, and the embed version at https://www.youtube.com/embed/KLybH5YvIPQ. Both load the same video, but they use different templates.

A brief history of embeds in WordPress

Since version 2.9, WordPress has used the oEmbed protocol to make embedding content from various services easy. This functionality improved further in version 4.0 with the addition of live previews for embeds in the editor.

With version 4.4, WordPress became an oEmbed provider, allowing other sites to embed posts from WordPress. Version 4.5 further improved embed templating.

Version 5.0 introduced the Block Editor, which came with a dedicated Embed block. Since then, WordPress has continued to add and remove services and make behind-the-scenes tweaks.

The default view

Before you start customizing embeds, let’s break down the default layout.

The WordPress embed looks like a card component that renders the post’s title and excerpt in the main area.

On one side of the embed footer, you’ll find the site’s icon and name. If no site icon is set, the WordPress logo appears as a fallback.

On the other side, if discussions are enabled, the comment count appears alongside a share button. Clicking the share button opens an overlay containing the post’s URL and HTML embed code.

The excerpt is either one you added manually, or auto-generated. If it’s auto-generated, it’s limited by word count and followed by a “Continue reading” call to action.

If the post has a featured image, it can appear above the title as a large image or below it as a floated image, depending on the image’s aspect ratio.

Lastly, when a nonexistent URL is embedded, the embed displays a 404 not-found error with a relevant title and message.

Tweaking the styles

Now that you’ve seen the variety of ways WordPress renders embeds, let’s start adding some personality with custom styles.

First, create a dedicated CSS file, assets/css/embed.css, in your theme’s folder. Then enqueue the file using the enqueue_embed_scripts hook by adding the following code to your functions.php:

function devblog_embed_enqueue_style() {
	wp_enqueue_style(
		'devblog-embed',
		get_theme_file_uri( 'assets/css/embed.css' ),
		array( 'wp-embed-template' )
	);
}

add_action( 'enqueue_embed_scripts', 'devblog_embed_enqueue_style' );

If adding code to your theme’s functions.php file doesn’t fit your project, feel free to include it in a custom plugin or code snippet plugin that works best for you.

By specifying wp-embed-template as a dependency, you ensure your styles load after the defaults, making it easier to override them without resorting to excessive CSS specificity.

Now, add this code to the CSS file to subtly adjust the spacing and apply a soft background to the footer:

.wp-embed-featured-image.rectangular {
	margin: -25px -25px 25px;
}

/* This specificity is needed to overwrite the defaults. */
p.wp-embed-heading {
	/* CSS logical properties are not used by the default embed stylesheet. */
	margin-bottom: 10px;
}

.wp-embed-footer {
	margin: 25px -25px -25px;
	padding: 25px;
	background: #fafafa;
}

Use inline styles

If you only need to change one thing and prefer not to create a separate CSS file, you can use inline styles:

function devblog_embed_inline_style() {
	wp_add_inline_style(
		'wp-embed-template',
		<<<CSS
		.wp-embed-featured-image.rectangular {
			margin: -25px -25px 25px;
		}
		CSS
	);
}

add_action( 'embed_head', 'devblog_embed_inline_style' );

For inline styles, you must use the embed_head hook, because the enqueue_embed_scripts hook loads too late in the process.

Enforce consistent image format

Beyond adding your own styles, you can modify lots more. For instance, if you don’t want to display images in two different ways (above the title and floated), you can enforce a single option.

Suppose you want images to always appear above the title. You can override determined image shape using the embed_thumbnail_image_shape filter:

function devblog_embed_enforce_rectangular_image_shape() {
    return 'rectangular';
}

add_filter( 'embed_thumbnail_image_shape', 'devblog_embed_enforce_rectangular_image_shape' );

This change has a downside: square images that were previously floated may take up too much space, making your embed too tall. That’s why WordPress displays images in two ways by default.

You can address this by enforcing a specific image size for embeds. First, check whether you’ve already registered an appropriate image size (one that’s narrow in height).

If not, register a new image size and enforce it with the embed_thumbnail_image_size filter:

function devblog_register_embed_narrow_image_size() {
	add_image_size( 'devblog-embed-narrow', 640, 360, true );
}

add_action( 'after_setup_theme', 'devblog_register_embed_narrow_image_size' );

function devblog_embed_enforce_embed_narrow_thumbnail_image_size() {
	return 'devblog-embed-narrow';
}

add_filter( 'embed_thumbnail_image_size', 'devblog_embed_enforce_embed_narrow_thumbnail_image_size' );

When you register a new image size, you must regenerate the images, since WordPress by default doesn’t dynamically create them. You can regenerate the images with WP CLI or with a plugin.

Altering the excerpt conditionally

While WordPress provides filters for image size and shape, there isn’t a dedicated filter for every aspect. For example, there’s no embed-specific filter for the title or excerpt length.

However, you can shorten the excerpt specifically for embeds by using the excerpt_length filter along with the is_embed function:

function devblog_embed_shorter_excerpt_length( $length ) {
	return is_embed() ? 25 : $length;
}

add_filter( 'excerpt_length', 'devblog_embed_shorter_excerpt_length' );

This is a minor change, but it might be exactly what you need.

Remove or change the excerpt call to action

Besides adjusting the length of the excerpt, you can also remove the “Continue reading” call to action at the end. Because WordPress appends that CTA using a filter, you can remove it with one line of code:

remove_filter( 'excerpt_more', 'wp_embed_excerpt_more', 20 );

If you’d rather change the text instead of removing it, hook into excerpt_more and use the HTML API to set it to “Keep exploring”:

function devblog_embed_excerpt_call_to_action( $more_string ) {
	if ( ! is_embed() ) {
		return $more_string;
	}

	$processor = new WP_HTML_Tag_Processor( $more_string );

	if ( $processor->next_tag( 'a' ) ) {
		$processor->next_token();
		$processor->set_modifiable_text(
			__( 'Keep exploring', 'devblog' )
		);
	}

	return $processor->get_updated_html();
}

add_filter( 'excerpt_more', 'devblog_embed_excerpt_call_to_action', 21 );

Changing the site’s title

Another area you can customize is the site’s title and its logo.

Suppose you don’t have a logo for your personal blog and want to display the site title without the WordPress fallback logo. In that case, hook into embed_site_title_html:

function devblog_embed_only_site_title() {
	return sprintf(
		'<div class="wp-embed-site-title">%s</div>',
		esc_html( get_bloginfo( 'name' ) )
	);
}

add_filter( 'embed_site_title_html', 'devblog_embed_only_site_title' );

Adding extra content

Besides styling the embed and modifying its elements, you can also add extra pieces of content.

You can use two hooks for this: one immediately after the excerpt (embed_content), and another in the row that contains the comment and share icons (embed_content_meta).

Add the published date

You might choose to display the publication date only for posts, since pages are fairly static.

Since every post type uses the same embed template, use a conditional tag to append the date with the embed_content action:

function devblog_embed_post_posted_on() {
	if ( ! is_single() ) {
		return;
	}

	$time = sprintf(
		'<time datetime="%1$s">%2$s</time>',
		esc_attr( get_the_date( DATE_W3C ) ),
		esc_html( get_the_date() )
	);

	printf(
		'<p class="wp-embed-posted-on">%s</p>',
		sprintf(
			/* translators: %s: Publish date. */
			esc_html__( 'Posted on %s', 'devblog' ),
			$time // phpcs:ignore WordPress.Security.EscapeOutput
		)
	);
}

add_action( 'embed_content', 'devblog_embed_post_posted_on' );

Then, add these styles to previously created CSS file to create spacing between the post date and the excerpt:

/* This specificity is needed to overwrite the defaults. */
p.wp-embed-posted-on {
	margin-top: 10px;
}

Add a like button

There are not many examples of extending the row with the comment and share icons, but here’s one idea: if your website includes a feature for liking posts, you could add a like button to the embed.

You can hook into the action embed_content_meta to render the markup:

function devblog_embed_like_button() {
	if ( is_404() ) {
		return;
	}
	?>
	<div class="wp-embed-like">
		<button class="wp-embed-like-button"
				aria-label="<?php esc_attr_e( 'Like', 'devblog' ); ?>">
			<span class="dashicons dashicons-heart"></span>
		</button>
	</div>
	<?php
}

add_action( 'embed_content_meta', 'devblog_embed_like_button', 9 );

This HTML follows a structure similar to the sharing button that WordPress already gives you in embeds.

Likewise, to stay as close as possible to the existing WordPress code, you can add these styles:

.wp-embed-like {
	display: inline;
	margin-right: 10px;
}

.wp-embed-like-button {
	margin: -8px 0 0;
	padding: 0;
	background: transparent;
	border: none;
	cursor: pointer;
	outline: none;
}

.wp-embed-like-button .dashicons {
	padding: 4px;
	top: 8px;
}

.wp-embed-like-button:focus .dashicons,
.wp-embed-like-button:focus .dashicons {
	box-shadow: 0 0 0 2px #2271b1;
	outline: 2px solid transparent;
	border-radius: 100%;
}

.wp-embed-like-button:hover .dashicons-heart {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='0' fill='none' width='20' height='20'/%3E%3Cg%3E%3Cpath fill='%232271b1' d='M10 17.12c3.33-1.4 5.74-3.79 7.04-6.21 1.28-2.41 1.46-4.81.32-6.25-1.03-1.29-2.37-1.78-3.73-1.74s-2.68.63-3.63 1.46c-.95-.83-2.27-1.42-3.63-1.46s-2.7.45-3.73 1.74c-1.14 1.44-.96 3.84.34 6.25 1.28 2.42 3.69 4.81 7.02 6.21z'/%3E%3C/g%3E%3C/svg%3E");
}

.dashicons-heart {
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Crect x='0' fill='none' width='20' height='20'/%3E%3Cg%3E%3Cpath fill='%238c8f94' d='M10 17.12c3.33-1.4 5.74-3.79 7.04-6.21 1.28-2.41 1.46-4.81.32-6.25-1.03-1.29-2.37-1.78-3.73-1.74s-2.68.63-3.63 1.46c-.95-.83-2.27-1.42-3.63-1.46s-2.7.45-3.73 1.74c-1.14 1.44-.96 3.84.34 6.25 1.28 2.42 3.69 4.81 7.02 6.21z'/%3E%3C/g%3E%3C/svg%3E");
}

This is not the most modern CSS, but it aligns with the styles WordPress core uses for embeds.

Implementing actual Like button functionality goes beyond this article, but here’s how you would style the button.

Removing existing elements

Beyond adding elements, you can also remove existing ones you don’t need.

For example, here’s how you can remove the comment and share buttons that WordPress adds with the embed_content_meta action:

remove_action( 'embed_content_meta', 'print_embed_comments_button' );

remove_action( 'embed_content_meta', 'print_embed_sharing_button' );

If you remove the share button, you should also remove the corresponding markup for the sharing dialog. These two elements go together, but they are added using separate hooks:

remove_action( 'embed_footer', 'print_embed_sharing_dialog' );

Custom embeds

What if you’d rather build a custom embed from scratch, and the available hooks and filters aren’t enough?

In that situation, you can create a custom template. That gives you complete control over the output and structure, allowing you to design an embed layout that perfectly fits your needs.

Remember—your embeds will appear on other websites. Make practical design choices, so they integrate well with various styles. Sometimes, a modern and fresh look is all you need.

Template files

Where do you find the template files related to embeds? If your website uses the default embeds, you won’t find them in your theme folder.

Theme-compat files

The template files for embeds are in the /wp-includes/theme-compat/ folder of your WordPress installation. They include:

  • embed-404.php
  • embed-content.php
  • embed.php
  • footer-embed.php
  • header-embed.php

To override any of these, copy the ones you need into your theme folder and edit them. Theme files take priority over the theme-compat files, which serve as fallbacks.

Template hierarchy

By default, every post type (post, page) shares the same template file, embed.php.

You’ve already seen how to use conditional tags for code specific to certain post types. However, sometimes you might need a dedicated template for a specific post type.

For example, you can create an embed-page.php template file specifically for pages, or an embed-product.php template file for a custom post type called product.

A good example of a post-type-specific embed template is the plugin embed on WordPress.org.

The embed-plugin.php includes information specific to plugins, such as the author, rating, and “tested up to” version. These are details that wouldn’t make sense for regular posts or pages.

Site Editor and Block Themes support

Right now, the Editor doesn’t really support editing embeds.

Even if you’re working with a block theme that uses HTML files for the templates, you still need to add PHP files for custom embed templates.

Load templates files from a plugin

But you’re not restricted to storing your embed template files in your theme folder.

If you want to reuse a template across multiple projects, you can move it into a plugin and load it from there.

To get started, create a simple plugin with the following file structure:

/plugins/devblog-embed-template/
├── index.php
└── templates/
    └── embed.php

In the index.php file, add the necessary plugin header and use the embed_template filter to change the location of the template:

<?php
/**
 * Plugin Name: Developer Blog Embed Template
 */

function devblog_embed_template() {
	return plugin_dir_path( __FILE__ ) . 'templates/embed.php';
}

add_filter( 'embed_template', 'devblog_embed_template' );

Finally, add your custom embed template code to the templates/embed.php file.

This is the simplest approach, but it isn’t the most foolproof and doesn’t support post-type–specific files.

For more flexibility, modify the plugin as follows:

function devblog_embed_template( $template_path, $type, $template_candidates ) {
	foreach ( $template_candidates as $template_candidate ) {
		$local_template_path = plugin_dir_path( __FILE__ ) . 'templates/' . $template_candidate;

		if ( file_exists( $local_template_path ) ) {
			return $local_template_path;
		}
	}

	return $template_path;
}

add_filter( 'embed_template', 'devblog_embed_template', 10, 3 );

With this approach, you can also create post-type–specific template files in your plugin, such as /templates/embed-page.php.

WordPress will check your plugin’s folder first; if no matching file is found there, it will fall back to the theme, and then ultimately to the default files in theme-compat if needed.

Have fun!

Now that you’ve seen all the ways you can customize WordPress embeds, it’s time to put these ideas into action. Treat this as your invitation to experiment, using the suggestions in this article as a starting point.

And if you’ve ever felt the current default embed design could use a refresh, the code could stand an update, or Site Editor integration might be more seamless, now is a great time to get involved.

Even sharing feedback and ideas can spark meaningful change.

Props to @marybaum and @areziaal for reviewing the draft and offering feedback.

]]>
https://developer.wordpress.org/news/2025/02/customize-wordpress-embeds-to-match-your-theme/feed/ 0 5044
What’s new for developers? (February 2025) https://developer.wordpress.org/news/2025/02/whats-new-for-developers-february-2025/ https://developer.wordpress.org/news/2025/02/whats-new-for-developers-february-2025/#respond Wed, 12 Feb 2025 17:03:34 +0000 https://developer.wordpress.org/news/?p=4995 As we get closer to the end of winter here in Canada I can’t help but to think forward to longer days, warmer temperatures and what we’re going to grow in the garden this year. The shift of seasons brings about a renewed sense of possibilities, and just as the world around us changes, so does the WordPress ecosystem. There’s plenty happening for developers this month including a birthday and a few releases with plenty of enhancements.

Speaking of exciting events, WordCamp Asia is just around the corner! The schedule looks fantastic and is filled with some great speakers. If you’re going, I hope you have an amazing time soaking in all the knowledge, idea sharing and celebrating WordPress at one of the largest community events of the year!

Highlights

The road to 6.8 and 6.7.2 RC1

Scheduled to release on April 15th, WordPress 6.8 aims to enhance data views, query loops and block interactions. This release will also include new APIs to enhance extensibility and the integration of speculative loading aims to improve site performance. Read about this and more in the Roadmap to 6.8 post.

In release news, WordPress 6.7.2 is now available, the final release landed on February 11, 2025. Some of the key changes are as follows:

  • Playwright was updated to the latest version (#62843)
  • Schema version used throughout Twenty Twenty-Five was updated (#62455)
  • Filters can now correctly check if the context is a WP_Post of type wp_navigation and limit the insertion of hooked blocks. (#62639)
  • Changes were made to ensure that uppercase tag names, specifically those starting with “D” and preceded by whitespace, are correctly matched by the tag processor in WordPress (#62522)
  • Fixes were made to ensure meta boxes are saved even if none of their areas are present in the post editor’s UI. (#67503)
  • Changes to meta boxes to ensure combinations of meta boxes and device previews don’t cause conflicts. (#68902)

Happy birthday, Gutenberg!

Eight years ago, on February 3, 2017, the initial commit was made that introduced the world to Gutenberg, the revolutionary block editor that transformed how we write with and develop for WordPress. 

Over those eight years Gutenberg has evolved, becoming much more than a post editor. With features like full-site editing, block patterns and global styles, the editor has grown a whole new area in the ecosystem with an ever-growing list of third party blocks and themes.

With Gutenberg and the support from contributors all around the community, the future looks bright. Here’s to eight fantastic years of innovation, and many more to come!

Learn more about contributing to Gutenberg.

Plugins & tools

Gutenberg 20.1 and 20.2

The two latest releases of Gutenberg introduce enhancements for both developers and users. What’s new in Gutenberg 20.1 and 20.2 highlights changes to preview pages in data views, color picker and clear control changes, and more. Some of the key changes are:

  • Details block now support allowedBlocks attributes providing developers a method to customizing available innerblocks. (#68489)
  • A new default rendering mode was made available to post type supports. (#68549)
  • A new field has been added allowing UI changes to data views and content preview field for posts and pages. (#67278)
  • Upgrade Playwright to v1.49. (#68504)

Themes

Notable Block Updates

The following are notable changes to blocks from the point of view of a user:

  • Navigation block now provides an option for users to clear a selection in the color picker. (#68454)
  • Navigation block in the editor list view now displays the menu name alongside the block name. (#68446)
  • Page List block now includes color support. (#66430)
  • Social links block now provides an option for users to clear a selection in the color picker. (#68564)
  • Post Comment Link block now displays border and shadow options by default. (#68506)
  • Query Total block now displays border and shadow options by default. (#68507)

Resources

Developer Blog

And last, but not least, here’s the latest right here on the Developer Blog, if you’re ready to dive into customizing block categories:

Props to @marybaum and @greenshady for reviewing this article and offering feedback.

]]>
https://developer.wordpress.org/news/2025/02/whats-new-for-developers-february-2025/feed/ 0 4995
One hook to rule them all: The many faces of block categories https://developer.wordpress.org/news/2025/01/one-hook-to-rule-them-all-the-many-faces-of-block-categories/ https://developer.wordpress.org/news/2025/01/one-hook-to-rule-them-all-the-many-faces-of-block-categories/#comments Tue, 21 Jan 2025 21:16:25 +0000 https://developer.wordpress.org/news/?p=4897 You’ve probably noticed that WordPress blocks come organized in categories. But did you know you don’t have to live with those categories? You can change them around, to make them work for you.

You can rename them. Reorder them. Add completely new categories, including new categories for your custom blocks. And probably do things you or I haven’t even thought of yet.

And you can do all of that with one hook: block_categories_all

The hook is a versatile tool that allows developers to customize the way block categories are organized. Throughout this article you will learn how to use this hook and build functions to add, reorder and rename single or multiple block categories.

Before you dive in it’s important to note that each function accepts a single parameter which is expected to be an array of existing block categories. This is defined as $categories throughout this article.

Adding categories

If you build custom blocks, you might want to put them in some custom categories. You could also have other uses for custom categories—maybe you’re building some sections that have custom styling. Whatever your reasons, here are three approaches:

Creating a new category

Here’s how you can use array_merge to add a new category named Custom Blocks to the end of the existing categories array.

add_filter( 'block_categories_all', 'add_block_category', 10, 2 );

function add_block_category( $categories ) {
    $custom_category = array(
        array(
            'slug'  => 'custom-blocks',
            'title' => __( 'Custom Blocks', 'your-text-domain' ),
            'icon'  => null,
        ),
    );

    return array_merge( $categories, $custom_category );
}

Start by creating a function that accepts a single parameter—remember, it’s expecting the list of existing $categories. Inside the function create a variable named $custom_category and assign an array with these key-value pairs:

  • slug — a unique identifier for the category
  • title — the display name of the category
  • icon — a Dashicon or custom SVG

Note: to my knowledge we’re not using or showing the icon anywhere so in this example you can set this as null.

Then you’ll use the array_merge function to combine $custom_category with the existing $category list. You can position your new category before or after $categories based on the order that you pass each variable into the array_merge.

Positioning a new category

Here’s how to use array_splice to add a new category named Custom Blocks to $categories in the second position (index 1).

add_filter( 'block_categories_all', 'add_order_block_category', 10, 2 );

function add_order_block_category( $categories ) {
    $custom_category = array(
        'slug'     => 'custom-blocks',
        'title'    => __( 'Custom Blocks', 'your-text-domain' ),
        'icon'     => null,
        'position' => 1,
    );

    // Extract position from the custom category array.
    $position = $custom_category['position'];

    // Remove position from the custom category array.
    unset( $custom_category['position'] );

    // Insert the custom category at the desired position.
    array_splice( $categories, $position, 0, array( $custom_category ) );

    return $categories;
}

Start by creating a function and a new category array, much like you did in the previous example. But this time you will add a key for position letting the value specify where you want your new category to live inside $categories.

Then you will extract the position and set it as a variable to use in an array_splice, but before that, use unset to pull the position out of the array—you don’t need it.

Finally, use an array_splice function, which accepts 4 parameters:

  1. Array: the array you want to modify
  2. Offset: the position where you wish to insert
  3. Length: specify the number of items to remove after the offset
  4. Replacement: an array of elements to add in the specified position

In your array_splice, pass in $categories, the position you specified in your new category array, a length (in this case 0 as we do not want to remove anything), then your new category array.

Adding and positioning multiple new categories

Now let’s add and position some categories all at once. Here’s how you can insert two custom categories into $categories at positions two and four.

add_filter( 'block_categories_all', 'add_order_multiple_block_categories', 10, 2 );

function add_order_multiple_block_categories( $categories ) {
    $custom_categories = array(
        array(
            'slug'     => 'custom-category-1',
            'title'    => __( 'Custom Category 1', 'your-text-domain' ),
            'icon'     => null,
            'position' => 1,
        ),
        array(
            'slug'     => 'custom-category-2',
            'title'    => __( 'Custom Category 2', 'your-text-domain' ),
            'icon'     => null,
            'position' => 3,
        ),
    );

    $added_categories = array();

    // Prepare an associative array with positions as keys.
    foreach ( $custom_categories as $custom_category ) {
        $position = $custom_category['position'];
        unset( $custom_category['position'] );
        $added_categories[ $position ] = $custom_category;
    }

    // Sort the categories to insert by their positions/key.
    ksort( $added_categories );

    // Insert the sorted categories into the existing categories array.
    foreach ( $added_categories as $position => $custom_category ) {
        array_splice( $categories, $position, 0, array( $custom_category ) );
    }

    return $categories;
}

Create a function. Inside, create an array of new categories named $custom_categories, including the desired position for each item. Create an empty array to store data in the next step, name this $added_categories.

Next, iterate through $custom_categories to extract and unset the position and store it in $added_categories with the new position as its key. Then add a ksort function to make sure the categories that were stored in $added_categories are sorted by their keys.

Finally add foreach and iterate over the $added_categories and use an array_slice to insert each category into the desired position. Finally, reindex the categories using array_values to ensure things are in the correct order in the new category list.

Reordering categories

You can also use the block_categories_all hook to reorder the existing list of categories in the block editor. Whether you want to move a single category or rearrange multiple, here are some ways to get more control over both.

Reordering a single category

Here’s how to reorder the Design category in the existing array by removing it and reinserting it in the second position using array_splice PHP function.

add_filter( 'block_categories_all', 'reorder_design_category', 10, 2 );

function reorder_design_category( $categories ) {
    $design_category = null;
    $new_position    = 1;

    // Remove the design category from the existing categories.
    foreach ( $categories as $key => $category ) {
        if ( 'design' === $category['slug'] ) {
            $design_category = $category;
            unset( $categories[ $key ] );
            break;
        }
    }

    // If the design category exists, insert it at the new position.
    if ( $design_category ) {
        array_splice( $categories, $new_position, 0, array( $design_category ) );
    }

    // Reindex the array.
    return array_values( $categories );
}

Start by setting two variables inside your function, one named $design_category set as null that you’ll use later to store the design category, or whichever category you wish to move, and another named $position that specifies the position you want to move the category into. Then, add a foreach that will iterate through the existing categories to find a match for the category slug, store it in $design_category, and use unset to remove it from the existing list.

Now check if any data was stored in your variable and use array_splice to insert the category into the desired position, just as you did in the new category functions above. Finally, re-index the categories using array_values to ensure things are in the correct order.

Reordering multiple categories

Here’s how to reorder both the Design and Text categories to positions one and four by removing and reinserting them using array_splice.

<?php
add_filter( 'block_categories_all', 'reorder_multiple_categories', 10, 2 );

function reorder_multiple_categories( $categories ) {
    $reorder_categories = array(
        'design' => 0,
        'text'   => 3,
    );

    $moved_categories = array();

    // Iterate through the existing categories and add/remove the ones to be reordered.
    foreach ( $categories as $key => $category ) {
        if ( array_key_exists( $category['slug'], $reorder_categories ) ) {
            $moved_categories[ $reorder_categories[ $category['slug'] ] ] = $category;
            unset( $categories[ $key ] );
        }
    }

    // Sort the moved categories by their new positions.
    ksort( $moved_categories );

    // Insert the moved categories at their new positions.
    foreach ( $moved_categories as $position => $category ) {
        array_splice( $categories, $position, 0, array( $category ) );
    }

    // Reindex the array.
    $categories = array_values( $categories );

    return $categories;
}

Start by creating an associative array named $reorder_categories inside your function. The keys can be of the categories you want to reorder, and the value is their new position. You will also need to create an empty array to store data in the next step, name this $moved_categories.

When the check finds a match, the function adds the category to $moved_categories, in the position you specified as its key. The unset function drops the category from $categories.

Now add a ksort function to, well, sort the categories by their keys. 

Add a foreach to iterate over the $moved_categories, using array_splice to insert each category into its proper position. Finally, re-index the categories with array_values, so things are in the right order in the new $categories list.

Renaming categories

You can also use block_categories_all to rename the list of categories in the block editor. Want to rename one category? Want to rename them all? Here are some approaches that will give you control over the whole thing..

Renaming one category

Maybe you’d like to rename the Text category to Text Elements.

add_filter( 'block_categories_all', 'rename_text_category', 10, 2 );

function rename_text_category( $categories ) {
    foreach ( $categories as &$category ) {
        if ( $category['slug'] === 'text' ) {
            $category['title'] = __( 'Text Elements', 'your-text-domain' );
        }
    }

    return $categories;
}

Start by using a foreach. Iterate through $categories, looking for a category with a slug equal to text. If text exists, rename the category title to Text Elements.

Renaming multiple categories

Or maybe you really wanted to rename the Text and Media categories to Text Elements and Media and Text Elements.

add_filter( 'block_categories_all', 'rename_multiple_categories', 10, 2 );

function rename_multiple_categories( $categories ) {
    foreach ( $categories as &$category ) {
        if ( $category['slug'] === 'text' ) {
            $category['title'] = __( 'Text Elements', 'your-text-domain' );
        }
        if ( $category['slug'] === 'media' ) {
            $category['title'] = __( 'Media and Text Elements', 'your-text-domain' );
        }
    }

    return $categories;
}

To rename multiple categories in one function, follow the same steps as you did for renaming a single category. Only add as many checks for the category slug as you need.

Bringing it all together

Finally. Here you have it all— complete control over the names and position of existing categories, and the power to add new ones.

add_filter( 'block_categories_all', 'modify_block_categories', 10, 2 );

function modify_block_categories( $categories ) {
    $new_category_order = array(
        array(
            'slug'     => 'media',
            'title'    => __( 'Media and Text Elements', 'your-text-domain' ),
            'position' => 0,
        ),
        array(
            'slug'     => 'custom-blocks',
            'title'    => __( 'Custom Blocks', 'your-text-domain' ),
            'position' => 1,
        ),
        array(
            'slug'     => 'text',
            'title'    => __( 'Text Elements', 'your-text-domain' ),
            'position' => 2,
        ),
        array(
            'slug'     => 'embed',
            'position' => 3,
        ),
        array(
            'slug'     => 'design',
            'position' => 4,
        ),
    );

    // Create an associative array of block categories with the slug as the key.
    $current_block_categories = array_column( $categories, 'title', 'slug' );

    // Check if the new category order has a title set, otherwise use the default title.
    foreach ( $new_category_order as &$new_category ) {
        $new_category['title'] = $new_category['title'] ?? $current_block_categories[ $new_category['slug'] ] ?? __( 'Untitled', 'your-text-domain' );
    }

    // Create an array of slugs from the new category order.
    $new_category_slugs = array_column( $new_category_order, 'slug' );

    // Filter out the remaining block categories that are not in the new order.
    $remaining_categories = array_filter( $categories, function ( $category ) use ( $new_category_slugs ) {
        return ! in_array( $category['slug'], $new_category_slugs, true );
    } );

    // Merge the new category order with the remaining categories.
    return array_merge( $new_category_order, $remaining_categories );
}

Start by defining an array of categories you want to add, reorder or rename named $new_category_order. Now, the slug is required to identify each entry. The title and position are optional based on what you want to modify.

First, update any category titles by using array_column to create an associative array named $current_block_categories from $categories, using the category slug as the key. Then use a foreach to iterate through $new_category_order, checking whether or not a new title is set for any of the items in the array and updating them if necessary. If no new title is set, it will be extracted from $current_block_categories based on the slug. If for whatever reason no slug is found, then Untitled will be used.

Now build an associative array of categories by iterating over $new_category_order, checking for any categories with a new position, then adding it as the key in an array named $moved_categories

Then use ksort to sort the $moved_categories based on their position. Add a foreach and iterate over the $moved_categories and use an array_slice to insert each category into position.

Now that the new titles and positions are handled it’s time to filter out the remaining categories so you can bring everything back together. First, create an array of slugs named $new_category_order from array_column. Then create a variable named $remaining_categories that uses an array_filter to remove any items from $categories whose slugs do not exist in $new_category_order.

Finally, use an array_merge to combine the new category order with the $remaining_categories to return a full list of modified Block Categories.

Conclusion

The block_categories_all hook lets you make block categories work any way you need them to—for your project and for your users, and all the content they’ll create.

And, really, these functions are just the beginning. How are you going to use them? Do you have others, or can you see creative twists on them? Leave a comment!

Props to @psykro and @marybaum for reviewing this article and offering feedback.

]]>
https://developer.wordpress.org/news/2025/01/one-hook-to-rule-them-all-the-many-faces-of-block-categories/feed/ 2 4897
What’s new for developers? (January 2025) https://developer.wordpress.org/news/2025/01/whats-new-for-developers-january-2025/ https://developer.wordpress.org/news/2025/01/whats-new-for-developers-january-2025/#respond Fri, 10 Jan 2025 16:47:05 +0000 https://developer.wordpress.org/news/?p=4887 I hope everyone had a wonderful holiday break and is coming back into 2025 with new ideas to continue propelling WordPress forward. 

Last year, we saw the introduction of a lot of fun features for extenders. I’m partial to the Block Bindings API, but features like Data Views, section styles, and block hooks are pretty exciting too. There are far too many to list here, so just check out past editions of the monthly roundup to catch up on anything you may have missed.

Just because many of us were on holiday break doesn’t mean that WordPress development completely ground to a halt. Since the last monthly update, contributors released both version 19.9 and 20.0 of the Gutenberg plugin.

Highlights

State of the Word 2024

State of the Word 2024 was held in Tokyo, Japan, celebrating WordPress’s continued growth and global reach. The event highlighted key achievements in the past year. Some of those include nearly half a billion Core downloads each year, an uptick in plugin activity, and the introduction of APIs like Interactivity and Block Bindings. The event also celebrated Japan’s connection to WordPress, including the first person to localize the platform and the history of Wapuu, WordPress’s mascot.

Check out the State of the Word 2024 playlist on YouTube, which includes all sessions and discussions.

New Query Total block

Gutenberg 19.9 introduced a new Query Total block, which has two settings for displaying query results:

  • Total results: Outputs the total number of posts found (e.g., “12 results found”).
  • Range display: Outputs the current range of the total posts found (e.g., “Displaying 1 – 10 of 12”).

This block will give you more flexibility when displaying query-related information in your theme designs.

Stylebook added for classic themes

A scaled-down stylebook screen for classic themes was introduced in Gutenberg 19.9, continuing to bridge the gap between classic and block themes. The screen is currently static and only shows colors, typography, and block styles, but could offer user interaction in the future, maybe as part of a theme opt-in.

Plugins and tools

Stabilization of experimental block supports keys reverted

Gutenberg 19.8 initially stabilized several experimental block support keys. However, those changes were reverted in Gutenberg 20.0. The reasons cited were that the approach taken to stabilize them also needed time to be stabilized itself and more time was needed to communicate the changes with third-party extenders.

Create Block updates

The Create Block script received two nice feature updates:

Multisite support added for wp-env

The wp-env tool now supports WordPress multisite. You can set env.development.multisite to true in your .wp-env.json file to enable it. Check out the documentation to learn how to set environment variables.

Block Hooks updates

As of Gutenberg 20.0, block hooks are applied in the editor and front end to two new areas:

New filter hook for nav link post statuses

By default, navigation links are only allowed if they have the publish post status. With the new render_block_core_navigation_link_allowed_post_status hook, it is now possible to add multiple post statuses to an allowed list for rendering on the front end with a custom filter.

Presets support added to BoxControl component

Support for presets with the BoxControl component was added in Gutenberg 20.0. When presets are provided, a button to switch between a preset and a custom value is shown. Currently, a range control is always used for presets, but a future iteration should allow for a select dropdown for longer presets.

WordPress Playground

Several major updates landed for Playground in the last month:

  • CORS Proxy is enabled for all network requests. This gives WordPress running inside Playground more access to cross-origin resources. However, some limitations still apply to allowed headers and download sizes.
  • The experimental Data Liberation importer is now available in the importWxr step when using the importer.data-liberation option. The new importer will rewrite links to the imported content, download assets through the CORS proxy, and parallelize downloads while communicating the live progress.
  • WP-Cron has been re-enabled for Playground, which had been previously disabled.
  • The SQLite Database Integration plugin was released for testing the integration of WordPress with SQLite.
  • The Playground tester was used to compare the error rate of the top 1,000 WordPress.org plugins. The number has improved from 2023-2024, with the failure rate dropping from 7% to 5%.
  • WordPress Playground for developers workshop is now available on WordPress TV.

Themes

Notable block updates

When using the featured image option for the Cover block, Gutenberg 19.9 now lets you also set the resolution of the image. This will allow you to use a resolution that fits your designs.

Also since Gutenberg 19.9, you can set the Separator block to be a <div> instead of the default <hr> (horizontal rule) element. <hr> is a semantic element meant to denote a thematic break in an HTML document, which is read out by screen readers. This is often what you need and was the original intent of the Separator block. But the introduction of the <div> option lets you use the block as a design token only.

A change in Gutenberg 19.9 moves the CSS variable definition for the Image blocks lightbox overlay from an inline <style> tag to a data-wp-bind--style directive. I haven’t noticed any negative effects from my custom lightbox styles, but it’s always worth testing to ensure it works.

Deeply nested Post Template blocks

The Post Template block now defines the Query block as its ancestor rather than parent. This allows you to deeply nest Post Template within other blocks, such as Group and Column, for more flexible and unique designs.

Border support added to more blocks

Several blocks now support the border design tools over the last couple of Gutenberg releases:

Editor and user-facing updates

A couple of noteworthy user-facing changes landed in Gutenberg 19.9:

  • The Replace button for changing a Query block’s pattern has been renamed to Change design. The same PR swaps the popup modal with a dropdown to show the patterns.
  • The hardcoded RichText formats list for navigation menu items has been removed. Previously, only bold, italic, image, and strikethrough text were allowed. Now, users can use any non-interactive formats for menu items.

Resources

WordPress News

The WordPress News blog features posts covering the latest WordPress releases and several new articles dropped in the past month:

Developer Hours 

Two developer-focused live shows have run since the last monthly roundup. Catch up with them here:

You can catch past recordings of all Developer Hours on WordPress.tv, and there is a wide range of content on the official WordPress.org YouTube channel.

Hallway Hangouts

Two Hallway Hangouts, which are community discussions about WordPress features, occurred over the past month:

Developer Blog

And, of course, some new content landed right here on the Developer Blog in December, including two new code snippets:

Props to @bph for co-wrangling these resources and @ndiego and @psykro for reviewing.

]]>
https://developer.wordpress.org/news/2025/01/whats-new-for-developers-january-2025/feed/ 0 4887
Mastering light and dark mode styling in block themes https://developer.wordpress.org/news/2024/12/mastering-light-and-dark-mode-styling-in-block-themes/ https://developer.wordpress.org/news/2024/12/mastering-light-and-dark-mode-styling-in-block-themes/#comments Thu, 19 Dec 2024 16:21:02 +0000 https://developer.wordpress.org/news/?p=4865 One of the challenges I’ve wanted to tackle for a while is creating themes with both light and dark modes. There are many methods that developers have used to do this throughout the years, some more complicated than others. But I laid out a few ground rules for myself when stepping into this challenge:

  • The solution must respect the site visitor’s operating system preferences.
  • The theme user shouldn’t have to take any steps to make it work.
  • The code must live in theme.json as much as possible (a tiny bit of extra CSS is required).

Basically, I wanted to take the laziest path as I could to making dark mode a reality. I also wanted to do this in a way that used modern CSS features while respecting the Global Styles Engine in WordPress.

In this tutorial, I’ll walk through the solution that I came up with and have been using extensively over the past few months. There are some limitations, which I’ll get to, but I believe this is the solution that is the most forward looking.

Setup

For this tutorial, I chose to make a child theme of the Twenty Twenty-Four theme and worked with the parent theme’s default color scheme. You can see the result in these screenshots:

To follow along, make a new child theme named tt4-dark-mode with the following files in it:

  • style.css
  • functions.php
  • theme.json
  • /assets/editor.css

As usual, add your basic file header setup to your style.css file before activating the theme:

/*!
 * Theme Name:        TT4: Dark Mode
 * Description:       Exploring dark mode with Twenty Twenty-Four.
 * Version:           1.0.0
 * Tags:              block-patterns, block-styles, editor-style, full-site-editing, wide-blocks
 * Template:          twentytwentyfour
 * Text Domain:       tt4-dark-mode
 * Tested up to:      6.7
 * Requires at least: 6.6
 */

Using modern CSS features

For this tutorial, you’ll use two CSS features that do not have 100% browser support at the moment, but they are in wide use:

  • color-scheme: CSS property that lets you define what color scheme an element can be safely rendered in. This property has over 95% browser support, so it’s relatively safe to use.
  • light-dark(): CSS color function for defining both light and dark colors. The output color is based on the user’s operating system preferences. It is meant to be used in conjunction with the color-scheme property. It currently has over 86% browser support and can be safely used if supporting modern browsers.

The color-scheme property and light-dark() function are the foundation of the method used in this tutorial. They are both baseline CSS standards in 2024, so the challenge is making them work with WordPress standards.

Enabling the light/dark mode color scheme

For the browser to automatically switch to light or dark mode based on user preferences, you must set the color-scheme property. While this can be set on individual elements, you should target :root for the entire page. color-scheme supports several values, but light dark is the value that tells the browser to determine which scheme to use for light/dark switching.

There is no standard for setting this property via theme.json, but you can use the styles.css field to define custom CSS:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"styles": {
		"css": ":root { color-scheme: light dark; }"
	}
}

One potential issue to watch out for is that the styles.css property can be overwritten in a style variation or child theme’s theme.json by accident. The value from the parent theme.json is not merged. If this could be a problem for your project, try an alternative solution:

Alternative method: Using a stylesheet

I prefer the theme.json method above because it doesn’t require any additional code. But if you want or need to set the color scheme via a stylesheet, you can do so by adding this CSS to your style.css file:

:root {
	color-scheme: light dark;
}

And, of course, you need to ensure that style.css is included in both the front end and editor. Do this by adding this snippet to your functions.php file:

add_action( 'wp_enqueue_scripts', 'tt4_dark_mode_enqueue_assets' );

function tt4_dark_mode_enqueue_assets() {
	wp_enqueue_style( 'tt4-dark-mode', get_stylesheet_uri() );
}

add_action( 'after_setup_theme', 'tt4_dark_mode_theme_setup' );

function tt4_dark_mode_theme_setup() {
	add_editor_style( get_stylesheet_uri() );
}

Designing in two colors using CSS standards

At this point, you’ve got the basic setup out of the way. The hard part of building light and dark color schemes is not in the code itself. It’s in the design—i.e., picking the right colors. That’s more of an art than simply flipping colors around, which won’t look great. And it’s also outside the scope of this tutorial.

I’ll assume you already have your complete light and dark color schemes defined for your own projects. For this tutorial, I’ve already done the work of creating a dark color scheme for Twenty Twenty-Four’s existing default light palette.

What’s important is how to define those colors in theme.json. Do you remember the light-dark() CSS function covered earlier? You’ll use it to define both the light and dark values for each of the colors defined in your theme’s palette.

Here’s an example of what white (#ffffff) and black (#000000) looks like when used with light-dark():

light-dark( #ffffff, #000000 );

This tells the browser to use #ffffff when the user prefers a light scheme and #000000 when they prefer a dark scheme. Any CSS color value is valid here, so the values really depend on your theme’s design.

Now open your theme.json file that you’ve already been working in and add a new settings.color.palette section and define these colors. Your full theme.json file should now look like this:

{
	"$schema": "https://schemas.wp.org/trunk/theme.json",
	"version": 3,
	"settings": {
		"color": {
			"palette": [
				{
					"color": "light-dark(#f9f9f9, #1c1c1c)",
					"name": "Base",
					"slug": "base"
				},
				{
					"color": "light-dark(#ffffff, #111111)",
					"name": "Base / Two",
					"slug": "base-2"
				},
				{
					"color": "light-dark(#111111, #ffffff)",
					"name": "Contrast",
					"slug": "contrast"
				},
				{
					"color": "light-dark(#636363, #888888)",
					"name": "Contrast / Two",
					"slug": "contrast-2"
				},
				{
					"color": "light-dark(#A4A4A4, #3d3d3d)",
					"name": "Contrast / Three",
					"slug": "contrast-3"
				},
				{
					"color": "light-dark(#cfcabe, #60544c)",
					"name": "Accent",
					"slug": "accent"
				},
				{
					"color": "light-dark(#c2a990, #9d7359)",
					"name": "Accent / Two",
					"slug": "accent-2"
				},
				{
					"color": "#d8613c",
					"name": "Accent / Three",
					"slug": "accent-3"
				},
				{
					"color": "light-dark(#b1c5a4, #465a3b)",
					"name": "Accent / Four",
					"slug": "accent-4"
				},
				{
					"color": "light-dark(#b5bdbc, #4d5757)",
					"name": "Accent / Five",
					"slug": "accent-5"
				}
			]
		}
	},
	"styles": {
		"css": ":root { color-scheme: light dark; }"
	}
}

As you can see, almost all of the color definitions have both light and dark hex color codes. I didn’t set one of the colors (accent-three) because it works well in both light and dark mode. That was a bit of a happy accident, but it illustrates that how you define colors is specific to your design.

To test, switch your computer’s display mode between light and dark (there will be different settings based on your operating system).

Small editor fix

The implementation you’ve learned thus far works in both the editor canvas and on the front end. But the dark colors are not reflected in the various color indicators in the editor UI when in dark mode. To fix this, you’ll need a few lines of CSS using the same color-scheme definition you used before.

Create a new file named /assets/editor.css in your theme and add this CSS in it:

.component-color-indicator,
.block-editor-color-gradient-control,
.components-circular-option-picker__option {
	color-scheme: light dark;
}

This tells the various color indicators and controls in the UI to use the preferred light or dark scheme.

Now enqueue this stylesheet in the editor:

add_action( 'enqueue_block_editor_assets', 'tt4_dark_mode_editor_assets' );

function tt4_dark_mode_editor_assets() {
	wp_enqueue_style(
		'tt4-dark-mode-editor',
		get_theme_file_uri( 'assets/editor.css' )
	);
}

Current limitations of this method

One of the major downsides of using light-dark() is that users can overwrite the individual colors in your theme-defined palette via the Styles panel in the Site Editor:

This is problematic because WordPress doesn’t currently have a UI-based method of defining both the light and dark hex codes. When a user overwrites an individual color, their custom color will be used regardless of the mode. 

For distributed themes or sites where the client has access to edit styles, I have yet to find a solution. My initial idea was to disable this functionality, but that is not a supported WordPress feature at this time.

Despite this limitation, this is still a path worth exploring further. color-scheme and light-dark() are already a part of the CSS standard, so it makes sense for WordPress to officially adopt it as part of the UI going forward. 

It’s even possible to make a button to switch between light and dark, but let’s save that for a tutorial on another day. I’d like to see what you come up with in the meantime.

Props to @ndiego and @welcher for feedback and review on this post.

]]>
https://developer.wordpress.org/news/2024/12/mastering-light-and-dark-mode-styling-in-block-themes/feed/ 7 4865
Snippet: How to register a block variation but hide it from the inserter https://developer.wordpress.org/news/snippets/snippet-how-to-register-a-block-variation-but-hide-it-from-the-inserter/ https://developer.wordpress.org/news/snippets/snippet-how-to-register-a-block-variation-but-hide-it-from-the-inserter/#respond Wed, 18 Dec 2024 15:26:33 +0000 https://developer.wordpress.org/news/?post_type=snippets&p=4857 When defining a custom block, the inserter property in block.json can be used to control if the block is available to be inserted by the user or if it can only be added programmatically.

In some cases, a custom block is overkill, and a block variation is a better solution. For example, a user in the outreach channel wanted to add an attribute to a block that was only used in a template and, based on the existence of that attribute, add some custom functionality.

This is a perfect scenario to use a block variation. The issue was that they couldn’t hide the variation from the inserter.

After some digging, it is possible to hide the block by setting the scope property to block in registerBlockVariation. The following code registers the paragraph-red block variation for the Paragraph block, but it’s not available to users in the Editor.

import { registerBlockVariation } from '@wordpress/blocks';

registerBlockVariation( 'core/paragraph', {
	name: 'paragraph-red',
	title: 'Red Paragraph',
	attributes: {
		textColor: 'vivid-red',
	},
	isActive: [ 'textColor' ],
	scope: [ 'block' ],
} );

This value is used for blocks like the Columns and Query blocks to filter specific block variations. These variations are passed to the experimental BlockVariationPickercomponent which handles displaying the variations and allows users to choose one of them. For variations of other blocks, the scope property is a great workaround to hide them from the inserter.

Relevant links

Props to @ndiego and @greenshady for reviewing this snippet

]]>
https://developer.wordpress.org/news/snippets/snippet-how-to-register-a-block-variation-but-hide-it-from-the-inserter/feed/ 0 4857
Snippet: How to filter the output of a block binding https://developer.wordpress.org/news/snippets/how-to-filter-the-output-of-a-block-binding/ https://developer.wordpress.org/news/snippets/how-to-filter-the-output-of-a-block-binding/#comments Tue, 17 Dec 2024 20:18:35 +0000 https://developer.wordpress.org/news/?post_type=snippets&p=4850 WordPress Block Bindings API provides a powerful way to connect block content with dynamic data sources. While bindings themselves are useful, sometimes you need to modify their output. Using the block_bindings_source_value filter, you can transform the data before it’s displayed on the front end.

Consider a scenario where you have a custom post type called book and need to store the price for each book as post meta. The price will be stored in US dollars, but you want to give users the ability to view prices in different currencies. By adding a query parameter to the URL (like ?currency=EUR), users can dynamically switch between US dollars, Euros, and British pounds. Let’s walk through how to implement this using block bindings.

First, register the post meta using register_post_meta() to make it available to blocks in the Editor:

add_action( 'init', function() {
    register_post_meta(
        'book',
        'book_price',
        array(
            'show_in_rest'      => true,
            'single'            => true,
            'type'              => 'string',
            'label'             => __( 'Book Price', 'text-domain' ),
            'description'       => __( 'Book price in USD', 'text-domain' ),
            'sanitize_callback' => 'wp_strip_all_tags',
        )
    );
} );

Next, you can use the block_bindings_source_value filter to intercept the price value when it’s displayed and convert it based on a query parameter. For instance, a URL with ?currency=GBP will automatically display the price in British pounds. The binding can be added to any block that supports content, like a Paragraph block, using the core/post-meta source.

add_filter( 'block_bindings_source_value', function( $value, $source, $args ) {
    // Only process if the source and key are correct.
    if ( 'core/post-meta' !== $source || 'book_price' !== $args['key'] ) {
        return $value;
    }

    // Get currency from query parameter (e.g., ?currency=EUR).
    $currency = isset( $_GET['currency'] ) ? sanitize_text_field( wp_unslash( $_GET['currency'] ) ) : 'USD';
    
    // Base price in USD.
    $price = floatval( $value );
    
    // Conversion rates (you might want to use a real API for live rates).
    $conversion_rates = array(
        'EUR' => 0.92, // 1 USD = 0.92 EUR
        'GBP' => 0.79, // 1 USD = 0.79 GBP
        'USD' => 1.00,
    );
    
    // Convert price.
    $converted_price = $price * ( isset( $conversion_rates[ $currency ] ) ? $conversion_rates[ $currency ] : 1 );
    
    // Format price with currency symbol.
    $currency_symbols = array(
        'EUR' => '€',
        'GBP' => '£',
        'USD' => '$',
    );
    
    $symbol = isset( $currency_symbols[ $currency ] ) ? $currency_symbols[ $currency ] : '$';
    
    // Format the price with 2 decimal places.
    return sprintf( '%s%.2f', $symbol, $converted_price );
}, 10, 3 );

Here’s a quick demonstration of how to use this new functionality:

This approach gives you a flexible way to modify block binding output based on user input or other parameters. While this example uses hardcoded conversion rates, you could easily extend it to use a currency conversion API for live rates.

If you are interested in learning more about the Block Bindings API, here are several articles to get you started:

Props to @greenshady, @welcher, and @santosguillamot for reviewing this post.

]]>
https://developer.wordpress.org/news/snippets/how-to-filter-the-output-of-a-block-binding/feed/ 2 4850
Developer Hours: Improve your workflows with WordPress development tools https://developer.wordpress.org/news/videos/developer-hours-improve-your-workflows-with-wordpress-development-tools/ https://developer.wordpress.org/news/videos/developer-hours-improve-your-workflows-with-wordpress-development-tools/#respond Wed, 11 Dec 2024 07:30:09 +0000 https://developer.wordpress.org/news/?post_type=dev-blog-videos&p=4835

In this session of the Developer Hours, the presenters took a deep dive into the advanced usage of tools like create-block and wp-scripts, along with a few others. They focused on solving common challenges and showcasing techniques that went beyond the basics, even for developers already familiar with these tools.

The session featured practical examples and insights to help participants work more efficiently, especially when building blocks, block themes, and Editor extensions. While the discussion covered more advanced implementations, it remained accessible to developers of all experience levels, with plenty of resources provided.

They highlighted WP Scripts’ features, such as targeting specific files, customizing output directories, and enabling fast refresh with hot module replacement. Ryan demonstrated creating custom templates for blocks and plugins, emphasizing efficiency and personalization. They also addressed common issues like SASS warnings and the need for Windows testers. Nick introduced Create Block templates for scaffolding blocks and plugins, encouraging community feedback to improve these tools. They concluded by inviting further discussion on potential enhancements and best practices.

Relevant links

Transcript

Nick Diego 0:00
All right, welcome everybody to another session of developer hours. This is actually our second to last session of 2024, and what we’re going to be talking about today, it’s going to be kind of a meandering discussion on developer tools and how you can kind of optimize them to improve your own workflows. What we’re going to be talking about today, you know, we’ve kind of covered in previous developer hour sessions in various forms, and they’re kind of the kind of the core fundamentals of our workflow. But we’re going to try to hopefully highlight some more interesting aspects of the tools, and hopefully you’ll find something useful that will help you improve your workflows, building blocks, block themes, editor extensions, that sort of thing. So my name is Nick Diego, and I’m a full time contributor to WordPress sponsored by automatic and I’m joined by my colleague, Ryan. Ryan, would you like to introduce

Ryan Welcher 0:53
yourself sure my name is Ryan welcher. I’m also a full time Developer Advocate sponsored by Automattic. And, yeah, happy to be here.

Nick Diego 1:02
Yeah, excited. Give me a phone. And I think that it’s one of these things where it’s, it’s we also want to hear from you if you’ve been using these tools as we go through the presentation, if you have questions, if you have things like, Oh, you could do it this way. Even better. You know, please use the chat. Please, please engage. You know, we want to try to all learn from one another in this session today, before we begin, we always kind of run through a couple of announcements. The first one being, and this is a bit old news. Happened a few weeks ago, but WordPress 6.7 is out. If you’re not familiar with what came in the release, there’s a great overview here. Hopefully everyone is up to speed on the WordPress 6.7 release, but a lot of cool things that are included there that will help you build better with WordPress. I kind of missed this step here. I want to share with you all a link to a resources document, so every all the links that I’m going to share after this are also included in this document. It saves you a little bit of effort having rather than having to copy and paste from chat all the time, I’m just going to paste that link here, and you can check out the Google Doc, and it has all the resources that we’re going to be referring to today. Next up, in terms of announcements, we always like to spotlight a article series called what’s new for developers. It comes out every month on the 10th on the WordPress developer blog. The last edition was for November. We’re currently working on the next edition. Ryan is doing most of that work, which will be coming out next week, on December 10, and that will be the last edition of the year. This. This series kind of covers all the latest things that are happening, both in WordPress core and in Gutenberg, and it’s a great way for you to just to kind of catch up and stay up to date on what’s coming and WordPress, from a developer’s perspective, next is, I wanted to showcase that we have our final session already scheduled. It’s the it’s going to be about WordPress playground. So you may have heard about WordPress playground. We have done a presentation from developer hours back, I think it was in May, around playground templates. But this is going to be a really fun session that kind of does a recap of all the enhancements to WordPress playground in 2024 and there were a ton, I mean, WordPress playground just increased massively in this year. So much new functionality, so many different ways to use it, and that’s what the session is going to be all about. So we hope you guys will all join us then and then finally, all these sessions are recorded. So if you have to leave halfway through, whatever these sessions are recorded. They are on YouTube in a playlist. I’m going to share that playlist right now, and so you’ll always be able to watch these after the fact. And I think Ryan already handled that form. So perfect. Thank you. Thank you for that. So what we’re going to do is there’s a couple developer tool there’s a lot of developer tools out in the world. We’re going to really focus on ones that are specific to WordPress, and kind of the big two are going to be the WP scripts package and the Create block tool. You may have heard about these. Maybe use them already. We’re going to try to dive into some more unique features of each and we’re going to start with WP scripts. So I’m going to pass it off to Ryan, who’s going to kind of lead this discussion, and then we’ll go from there. All right, Ryan, you’re up.

Ryan Welcher 4:27
Thank you. Nick, yeah, so WP scripts, if you’ve built a block, if you’ve built any modern JavaScript in WordPress, it’s about WordPress five you’ve, you’ve played with this, the WP scripts package, or the scripts package, as we call it. It handles all of the building for Gutenberg itself. The Gutenberg Project handles that using scripts. And yes, there’s a lot of this. There’s there’s far too much for me to be able to go into in in depth for everything, because there’s just so much that this package can. I can do. But I think what I wanted to do is kind of focus on some,

Unknown Speaker 5:05
some sort of

Ryan Welcher 5:09
easy ways to get started with it. That’s not what that’s not the right way of saying that. But let me share my screen, and then and then we will go from there. Which desktop am I sharing here?

Unknown Speaker 5:22
Gonna share this desktop. Sorry, move this up.

Ryan Welcher 5:30
So if you’ve ever worked with Webpack, you know that it can be fun. Webpack is notoriously hard to configure, and so a lot of times when you’re using the scripts package to build blocks to build your custom grabs JavaScript to build whatever it is you need, the tendency is, is to say, Okay, well, I have to add a new thing, or I want to change something, and I so I have to go and and create my own web pack configuration and get into the source Code and all that stuff. But I that’s not always the case. There’s a lot of times where you don’t need to change a thing with sort of the way the scripts works. Rather you just add some flags or add some configuration items that the package actually supports by itself. So I put together this repo that we can follow along with here and it it. This repo is a bit it’s a bit like the way I’m talking right now. It’s kind of all over the place. There’s a lot of different things going on here, but basically it’s going to show us some of the more common flags, some of the more you know, a bit more developer ones, things that that make our lives easier and and then there’s actually a crate block template associated with with with this as well, that where you can scaffold out a plug in that handles multiple blocks. Sorry, zoom in. Is that better? Sorry, I’m getting request.

Nick Diego 6:54
Maybe one more. Yeah.

Ryan Welcher 6:57
Okay, perfect. So, yeah. So let’s just, I’m just I’m just going to go through this. First of all, this is how I react anytime anyone says to me, I would like to to configure a web pack and so, but you may not necessarily have to. So there’s a there’s a couple of things that you can do if you just need to target a file, if you just need to say, I want to build this particular file. Maybe you’re not building a block. Maybe you’re building a low an extension. Maybe you’re building something that’s not even, you know, a custom editor screen or something, and you just want to target an index file for JavaScript. You can do that just by passing the file that you want to build. And so you don’t need to change anything nice and easy. You just set that up in your start command or your build command, or whichever command that you want to use. So, so that’s that’s a really quick and easy way of like not having to to to customize anything. You can also do the same approach with multiple files. So if you have more than one file that you want to, you know, build, you can pass them all in in a list like this. Just keep in mind that this will generate one output file. But again, don’t need to to to configure word or WordPress web pack in any way. The next part is, this is where it gets a lot like you’re going to want to do more complicated things. So for example, if we want to customize the location of our source file. So in a standard build, I have to zoom this way into let me know if this looks okay, but looks pretty good. Okay. So in a standard sort of build, for a block, you would have your source files inside a file called inside a directory called SRC. That’s that’s just the default way of doing things. But if you wanted to do something slightly different, like, for example, have blocks and some other JavaScript. So you may want to, you know, the SRC directory might not make a lot of sense, and it does get a little bit more complicated when you have nested blocks. So if you have more than one block sitting inside of your directory, it makes sense to kind of split out some of your JavaScript files. So you can do that by passing this flag called web pack. Source director, I’m going to actually see if I can get into this file like this. Does that give me a bit more space that looks a little bit nicer? There. There we go. Okay. So this allows you to say, hey web pack or hey scripts, this is where my source files are living. And it’s just by simply adding the flag to your command and then adding whatever the name of the block is, and it’s relative to to wherever you’re calling that from. Sometimes you want to change where it gets output to by by default, it’s a build directory and but if you want to change that to dist or public or whatever it is that you want to do, it’s quite simple to do that and and it everything just works. It just works and just puts it in places where you want to go. If you want to copy all the PHP files from your source directory to your build directory, you’ll you’ll want to pass this flag, which is the web. Copy PHP flag. You’ll you’ll see this with dynamic blocks, because dynamic blocks has a render dot php file associated with it. So this is just going to automatically copy any PHP that’s in your source into your build these ones. These ones are a bit more developery. So if you want to analyze your web pack bundle, so where you can actually see how big the different chunks are and and all of that, you can actually just pass that with this. Maybe I can show these.

Speaker 1 10:31
Can I show these? If I could show these? Stand by one second. Just do this.

Ryan Welcher 10:40
So if I go in here and I go scripts, I’m just going to bear with me one second. Sorry. So if I, if I go in here and I, I’ve set up a few of these commands, just for sort of examples. You can see in my package js on sorry, I don’t usually live this zoomed in. I have this analyze command. So what I’m doing is I’m going to run this, and we we can see what that looks like. NPM run analyze. What this should do is kick open. So this is actually showing me and it’s, it’s it’s zoomable, and you can get information about each, each part of your bundle, and where it’s lo located. This becomes really important when you’re doing a lot more advanced things, when you have some huge files, maybe you’re you’re importing packages and stuff that. So this just gives you a sense of, like, how big things are. You’re not going to use it all the time, but it’s something that’s just there and it’s available, which is really cool. What was the next I’m sorry, so the the dev tool. So I don’t have an example for this, because this changes how your source maps are generated. So if you need to make changes around the way that source maps are working inside your project, you do have access to that which is what’s going to this one is no external so if you’re familiar with the dependency extraction plug in, in the scripts package, what it does is it, it’s, it’s the magic glue that that makes it so you don’t have to import every single package to your project. It converts your import statements like these ones. It converts these, these import statements into accessing these the same items, but on the WordPress global, which is great, because you’re you’re you’re not importing all these JavaScript functions and growing and growing and growing your bundles. This flag turns that off, basically. So if this, if you run this with this in place, it will require that you need to have all those things installed. So where does it? Where does this become important and practical? I’ve literally never used this and except for preparation of this presentation, but the place where you would probably want to use this is, let’s say you wanted to have, let’s say you you wanted to have a Block Editor inside the a label project, for example. So you would want to turn the scripts, the the dependency extraction plug in off, because that’s not going to work there. It will be no WP global in that context. So this is a way of using this sort of outside of the WordPress space, if you need to experimental modules this. This is a experimental flag that is being used for the the interactivity API. You need it for, for the interactivity API, and what it’s going to do is compile your JavaScript as a JavaScript module, as opposed to the way it’s doing it normally. And this one is, it’s so hot, I love it. It’s literally called hot. And it’s enables fast refresh, which is basically like you don’t have to Reno reload your page. It does it all for you. So I have that set up when I’m going to show you all hopefully works

Nick Diego 13:48
while you’re while you’re pulling that up. I just want to stress to everybody that everything that Ryan’s been talking about it is a single flag like it is a single flag in your scripts that you’re you’re running, and there’s no other setup required. So, like, it looks very complicated, perhaps, but it’s just a single flag you’re adding.

Ryan Welcher 14:09
This is true. I probably should have been a bit more clear about that. So there are a couple. So this is where we’re getting into, the place where there might be some things we have to do. And, yeah, Anton, it does work. Well, it works. It works in the script, but you need to have some things set up, yeah, and basically, so this should, if I’ve set this up correctly, I’m sorry I was gonna hide this. Should be able to get some some stuff happening here, so you should be able to see that this is saying script examples. Oh, my goodness.

Unknown Speaker 14:45
Okay, it’s if I change this,

Ryan Welcher 14:49
see it just updated. I’ll zoom that in a little bit. But this is very, very cool, so now I can. So as I’m saving this, this is just being updated, and it’s not just for text. I. Can actually just drop in some expected controls here in the side as well. And if I look, look over here. I select this, select, select this.

Unknown Speaker 15:08
Where did it go?

Ryan Welcher 15:10
Block. Sorry. I see I have my content panel here now so I can update the content. They update the content. Save that. You can see that this just gets replaced. So this is really, really, really cool. It gets really it gets very powerful when you’re doing very, very complicated things where you have say, like, you have multiple steps, like you have to select your block, then you have to come down here and select your control and have your control open up. You don’t have to do that every single time. That’s where we’re hot module replacement or fast refresh becomes super important. Now there are some caveats around this that you have to be aware of. The first thing is you do have to have the version, the latest version of Gutenberg, installed, and you have to have script debug constant set to true. So if you’re running, if you’re running like WP EV script debug will be set to true. If you’re not and you’re running anything else, you have to mainly go into your WP config, and you have to make sure that that’s set. Now, the other thing that you have to keep in mind is that URLs your if your development URL is not local host, you’re going to have to make some changes to the web pack config, because by default, so it so under the hood, it’s using the this thing called dev server. And dev server has a a sorry, I linked to the wrong one. It has a property called allowed host, and basically allows you to set auto all or some string of whatever you want. So Auto is what is being used, and there’s some security reasons for that. It’s because the hosts are vulnerable the DS binding attacks and things like that. But if it sets auto, it will only look for like, local host or host or some other sort of, like, very specific names. So if you’re using something else, if you have, like my site dot Dev, or you have map set up with a custom URL, or you’re using certain other local development environments that that have their own custom dot what, whatever is right, you’re going to need to make a change to the to the web pack configuration. Sorry, lost my train of thought there. And it’s, it’s a fairly straight forward one. Now we’re kind of into the the you have to customize things way now, but the way we do it is actually fairly, fairly painless, because there is a default config that’s provided to us by the package. So what we can do is, all we have to do is just change the pieces that we want. So we don’t have to come in and figure out what plugins and what entry points and what all all these things. All we do is take the default config and then we’re going to we’re going to export an object, and we’re going to use the spread syntax to take everything that’s in the default config, and then, and then we’re going to override it with things that we want. So there is a dev server option or sorry, property. And so what we’re going to say is, okay, we’re going to take the dev server, we’re going to take everything that’s already in dev server, but we’re going to just override this allowed host things. So I set mine to all. Now this is important to understand that this is technically a bit of a security issue. This is just going to work everywhere, but you can also set it to like a URL at some of that. So if you’re doing this, be sure you’re not deploying this or just Just be careful with it. But this is how I do it locally, and it works. It works across the board. I’m gonna pause. Is there any questions about any of this stuff?

Nick Diego 18:50
I’ve went through a lot, yeah. And there’s one question about some SAS error logs that show up, but we’ll talk about that later, because I ran into it as well. There’s one about from Elliot, saying, presume that updates attributes under the hood as well. I guess while you’re doing hot refreshing,

Speaker 1 19:10
presume like block Elliot a little bit. Yeah. So I’m not really sure what that Oh, props. But props,

Ryan Welcher 19:20
yeah, so when it’s it’s essentially just, like, just so, so the fast refresh is basically just, like reloading the whole page, but it’s just, it’s just reloading the JavaScript portion. So I haven’t put it through, like, some serious paces around, like, finding out what its limitations are. Like, if your server side stuff, it’s most likely not going to get there, like, if you have something in PHP that that’s being in queued, and then you make that change, you’re going to have to refresh that page. But if you’re just just working in JavaScript, it’s able to just just replace that particular section. So for the most part, the props would be fine. Everything would be okay there, but it. If there’s a thing that you have to get it from the server that’s not like a REST API thing, I think you think you will have to reload, but it reloads really, really fast, and in fact, in some cases, it does actually reload the whole page. So it’s, it’s

Unknown Speaker 20:13
pretty great. There

Ryan Welcher 20:13
was a question about, do any of these tools have type script support? Yeah, script supports. It can process TypeScript files, but it doesn’t do it. Let me rephrase that. It has TypeScript support in the sense that it knows that what TypeScript is, but it doesn’t do the TypeScript processing for you. If that makes sense, you will have to probably add that in TypeScript support in WordPress development is it’s, it’s tricky right now, because a lot of the types are up to date, both of the project and then, like, fully type. So that’s kind of a, that’s kind of a, it’s a, it’s a deeper topic. I would love to see more support for it. I know there are people who are putting in concerted efforts to move all the packages to use TypeScript, and that’s great, so that will make things better for us. But yeah, so, so yes, with asterisk, let’s put it that way. Okay, so the last real thing that I have, yep, there was

Nick Diego 21:15
one question here that you might have. So what is the best practice to add an assets folder to your builds. I’m updating default config. But maybe you know of a better way to achieve that

Ryan Welcher 21:27
an assets folder to your builds. Like to copy assets around over is, is that the question? Imagine they’re using a custom web pack to handle right? Okay, so you want to have something like fonts that get just moved into a build. You’re there, you’ll have to add a plug in for that. There’s a copy. There’s, there is a copy plug. In fact, we want to get into it there. There is there. You can look at what’s being done. Yeah, I think you’ll need to do it with a custom config at this point, because you’ll need to target what those things are now there, if you wanted to look at so, there is plugins, so 100 So There, there is some stuff that you can do. If you look in the advanced usage section of the documentation for scripts, you can see that they you know, you can get it into the weeds a bit more. And there is support for fonts and there is support for stuff like that. So you some of this might help get you where you need to be cool. I move on, though, because I think I’m taking more time than I should be. So the place where you absolutely have to, and probably the most common reason why you would have to update, sorry, you would have to provide a custom web pack config, is when you have multiple entry points that you want to have as discrete files. So in in this example. And this is a very common example, you want to have a plug in that registers one or more blocks and but you also want to be able to generate a JavaScript file that that stores your your variations and your slots and maybe your custom admin screens, or whatever it is. So this, this is the, probably the best way to do this. So what we’re going to do is we’re going to import the default config again, we’re going to spread the default config across our object. Then we’re going to add an entry property, and then we’re going to this is very important. We have to to spread the entry property, but call it as a function. The reason being, is scripts has got this amazing little built in functionality that it can detect any blocks that you have in your source directory and build those out, which is really, really cool. It means you don’t have to go and update your your your entry points. Every time you want to add new block, you just add a new block as long as it’s got block dot JSON it, scripts will find it and be like, oh, there’s a block and build it. So that’s what this does. So if we add this, you’re golden, and then after that, you can just add as many more slots as you want. So I actually have an example of that in here, and that’s what that’s what this template does. This template is going to build out. So my web pack config, sorry, this, I’m going to move my move this over. So my webpa config has got everything I need. This is going to build one or more blocks out. I’ve got my JavaScript in a completely different folder, and so I this is kind of putting together all the pieces. Like, for example, in my start, I’ve got my start, I’m copying any PHP files from my blocks, and I’m also telling, oh, my Webpack sourced or is actually in blocks. It’s not in source anymore. So this is that’s building all that stuff out. It’s managing a lot of different things. For example, there’s this really cool new register block, meta. Data Collection, which is going to increase performance for registering multiple blocks. And it’s all, it’s all in place there, and, yeah, and so that this is available as a create block template, which Nick, Nick’s going to talk about next but, and it’s, it’s on NPM, and it’s also part of this, this repo. So if you want to check it out, you can it also does some really neat things, like, anyways, I won’t get into it, but there’s this has got almost everything that we’ve talked about today. It’s got the hot module, it’s got the Analyze, but you can go in and add your own stuff to it, and that is available. Like I said on

Unknown Speaker 25:41
where is the, sorry, I

Nick Diego 25:45
have your repo link if you wanted to paste that,

Speaker 1 25:47
yeah, where did I put the I put the, oh, it’s down here. Sorry. So,

Ryan Welcher 25:52
so the Nick said, talk about create block, but when, when, and if you you want to use it, you can, actually, you can get it right here, so you can target NPM packages and do it that way. But anyway, I’m gonna stop let people ask questions if there are any. Hopefully I haven’t glazed you all over the speed at which I was talking. But yeah, and if you have any questions about this after the fact, which I always have when I ever edit these things, just reach out to me. I’m on WordPress, Slack, I’m on X I’m on blue sky, and threads, I’m everywhere. So just reach out and I can answer what I can

Nick Diego 26:29
Yeah, I think part of this is, I mean, we could talk about this topic, these topics for like, you know, four days. And so I think a lot the main point of this session is to, like, provide a taste of different ways of doing things, and then also hopefully further discussion. So like Ryan said, reaching out to us, talk to the fact or, you know, in the chat, wherever we really want to try to show what’s possible, and then hopefully generate a discussion from that. Because there’s also areas where, as you start using some of these tools, you might have a specific build process that isn’t supported, like the the gentleman mentioned about, you know, the having us you wanting to pull over SVG files and which would require a more complicated web pack, but maybe that’s something that we could incorporate into WP scripts in the future. So the more we talk about this, the more we look at different use cases, the more that we can consider improvements in WP scripts that will cover all these things. So I wanted to talk about create block, which is a very cool tool, which, if you haven’t used before, I encourage you to do so. So I’m going to share my screen, and we will talk a little bit about create block, and specifically about creating templates, because I think that this is an area that is I will need to start using myself, and it’s amazing how much time it saves and speeding up workflows. Before I get into what you see here, I want to share a documentation article, and we’ll take a look at that here. So create block is a tool that allows you to scaffold a block, individual block, block, plug in very quickly. It is the way that we recommend that anybody starting out building a block builds blocks. I mean, you can do it by hand, but this is the best way for you to get started in a very quick fashion, straight out of the box. I zoom in a little bit here. You can just run this MPX create block, latest to do list, and it will just scaffold a really stock block that you can then use as an starting point to build out whatever you want. The create block tool includes a number of built in templates that will allow you to it will scaffold the block in different ways. You can create a dynamic block or a static block. Won’t get too much into the differences there, but hopefully you’re familiar with those terms and has a lot that it can do just in and of itself. But one of the benefits of the Create block package is you can actually create your own templates. And this is where I think that, again, I only just started using this after being, you know, prodded by Ryan. Ryan has a great article on how to create external project templates, so I’m going to share that here in the chat. And he’s also given many talks about this, I believe it word camp Canada as well. The chat window is not appearing. So this is Ryan’s article on the Developer blog on how to create external templates. So let me kind of paint you a picture around why, if you build a lot of blocks, if you build editor extensions, you probably want to start building, sorry, building your own templates. So I built a lot of extensions, and I built a lot of blocks in my life. And every time I go to do it, it’s a copy and paste process, you know, I’ll, maybe, I’ll scaffold a simple one with create block, and then I’ll look at some. My old projects, and I’ll, like, copy over any custom web pack config that I have, or copy over just the file structure and how I like to have things put together, which you can definitely do. And it actually doesn’t take that much time. So it’s very tempting just to, like, keep doing that, but what you can do with the template is you can actually build out a scaffold that matches your own personal preferences. So let me give you a quick example. So I have a plug in called The icon block, which is not an advertisement for but I have a very specific way that I like to have my output files. So in my build folder, I have a style dot CSS and editor dot css by default, if you use the Create block package, it will generate a style dot CSS and a style dash index dot CSS, which one is designed for the editor and one is designed for both the front end. And I just, I always found that a little confusing, and I don’t, and I wanted it to be this way in my own projects, right? So whenever I would use the Create block, I’d have to go in and I change the file names and in, but not also there are others. So I’ll in my source folder. You can see here that I have index and editor dot CSS. So what I wanted to do is, and you can you don’t need to necessarily need a web pack. I don’t think for this, but I just have a custom web pack config where I’m just mapping the SAS files to the output files for style and editor. So every time I want to go create a new project, I copy over this web pack. And I also like to use the Remove, remove empty scripts plug in that just removes the empty JavaScript files that ended up getting created. So I just have, like, this little setup that I use all the time. But what if you can just create a template? So whenever I scaffold at a new block, this my personalized way of doing it was just already, already there. Similarly, there are scenarios when I want to create a Block Editor extension plug in, where I want to use WP scripts, and I’m not necessarily building a block, or maybe it’s a combination of a block plus some block variations and some slot fill and some other stuff and that project. But because it includes multiple things, blocks and additional JavaScript, you can use great block for but then you got to start adding all your own stuff into it. But you can build a template that will scaffold that entire project with all the stuff that you need already to go. So what I did is, ahead of this presentation, is I put together a little library. Let me back out here one more a little library called Create block templates. And this is designed for my personal use. You are more than welcome to take it, iterate on it, copy it, whatever. But I made it personally because it’s personal to me. So for example, if I have one actually let me back up and we explain how these templates work. So these templates are use must, must files, and so let’s take a look at the first one, which is a dynamic block. So if I want to scaffold a dynamic block, instead of using the default create block dynamic template, I’m going to use my own. We’ll start by looking at this index file. This index file very dissimilar to what we saw with web pack, where you have that module export, where it’s exporting an object. We’re doing the exact same thing here. And what I’ve done is I’ve passed a whole bunch of default values. You can see, like, I’ve passed my name, I’ve passed the plug in, default plug in, Uri, and, you know, custom title, custom description. I’ve included some things that I like. I copied this from Ryan, this prettier config. I also have some custom scripts. So I like to customize my scripts a little bit. So I have one that not only links JavaScript, but then there’s one that also fixes all the errors that it can so I have, like, a custom script that I add to every single one of my projects. I can define those custom scripts here. I also have another custom script that’s using CLI to generate the pot file of the translation file for the plug in I’ve included that here. This is something like I just always add to every project, but here you can generate a scaffold that will do it all right. Off the bat, I’ve included NPM dev dependencies for that thing in web pack that allows you to remove the empty scripts. Basically, you’re defining all the custom stuff that you want. You also need to define the path to the plug in files and then the path to the block file. Files, because we’re working with the Create block package. This entire thing is designed to build blocks, but you can do blocks, and like you can build blocks, plus you can scaffold plug ins that maybe have a block but also have a whole bunch of other stuff. So you have your block template, your block files, and then you have your plug in template files. So let’s back out and look at those files.

Nick Diego 35:25
Now this is also custom, because in the documentation, you’ll see that your two folders are plug in and block. So we go back here and see that it’s plug in and block. Normally, this SRC is block. But I to me personally, it made more sense, because these are all the files in your source folder. I just called it a source because it made more sense to me. Again, this is how you can customize things to for your own needs. So inside of source, this is going to be all those files that pertain to the block. If you ignore the little mustache at the end, it’s the files that are very familiar. You have your edit.js, s, your editor, dot, sess, so on so forth, and your render, dot, PHP, because this is a dynamic block. Before we look at these files, I want to back out and take a look at the plug in folder. Here we have some more custom, custom stuff, a custom read me, both in Markdown and text. We have that custom web pack config. Here you can see this looks very similar to that icon block example that I showed you before. I have those defined entry points recently in work in WP scripts, it generates RTL style style sheets, which is great. That’s a huge, great addition to WP scripts. But in this case, I wanted to disable that. So I’m disabling the RTL CSS plug in that generates those right to left style sheets. And then I’m also using that remove NP scripts plug in as well. So again, all custom but when you include it in your scaffold, it will generate that for you. Backing out here, I have a custom Git ignore, a custom editor config, and then here this little dollar sign slug. This slug is actually going to come from the index file, so I’ve defined my slug here, so it’s called dynamic block. So when this plug in is scaffolded, this log will be replaced with whatever slug is provided. In this case, dynamic block. And here we have our PHP file. Now, again, this is something that I like. I have a specific setup, or how I like to set up my plug in, you know, the main plug in folder, I like to use name spacing. So you can use name spacing. There’s a way for you to transform the slug into using Pascal case. So that’s what we’re doing here. And these little, what do you call them? Brackets. This is what’s dynamically inserting the content that’s in that index file. The defaults. It’s inserting them into your files here. So here, this title will be input, the plug in Uri, the description, the version, the author, text domain, so on and so forth. This is all getting dynamically updated whenever you scaffold the block. Plug in and see here, yeah, I’m registering the block. I have my name spacing, you know, so on and so forth. And again, you can customize this however you want. You could also build a really, this is a very basic block. It’s just a default block, but with some additional setup, you could basically completely customize this. So let’s say that you wanted to create a template that scaffolded block variations, or block bindings, or, you know, you can get really specific with this. You can build an entire, basically an entire plug in, in these mustache files, when you run it, it will scaffold the whole thing. And then you can make your minor tweaks here and there. So you can really go as far as you want. This is just a very simple example where all I’m doing is registering the block. I have this in my mind, where I build a lot of editor extensions. And so a lot of those editor extensions are modifying blocks, you know, adding attributes, whatnot. It’d be really cool to have a template that had, like, all those functions in there, and then all I would need to go in is, you know, change the block that I’m actually modifying, you know, change the attributes, so on and so forth. So you can really go pretty far with this. Now, let’s go back to the plug in files, or, sorry, the block files, and we’ll just take a look at what this looks like. It’s a very similar we have our editor file, or edit file, which is the file this editing the plug in in the editor, and you can see here, everywhere you see these brackets, this is worth inserting that content from the main file index. And now you if you look closely at this, you’ll notice that this is a different index file than what’s in. Included it with w the just the default create block tool, the way that it handles things like the registered block type, pulling things from metadata that I did I just like to do in my blocks, which is definitely possible. That’s how I’ve set it up here. Again. This is just tailoring it to my own personal preferences. And as opposed to using the default that comes with the Create block tour. So how do you use this? Okay, so once you’ve created these templates, in my case, I have, this is a repo, and there’s a couple there’s another example in here. There’s the editor extension example, but we don’t need to go it’s very similar to what we have. What I just showed you. This repo lives in my local computer, so if we come over here, we can see that I have this folder called WP projects. It’s a bunch of random things. And here’s that repo, and it has the templates that I’ve built. So let’s say that I want to use this template, and I have a local site for developer hours, and it’s over here in plugins. So what I want to do is I want to scaffold my block using the Create block package from my templates that I’ve created. In this case, let’s create a dynamic block. So there are different, couple different ways you could do this. I could in my terminal. I could start inside of the templates folder. Then I can use a new flag called Target dir, target directory, and then I can target this plugins directory, and I that will scaffold the block there. I could also, in my terminal, navigate to the plugins folder inside of this local site and then target the template from this WP Projects folder, so you can do whatever you want, like you can do how you want to target it. It doesn’t matter. I’m going to use the new template directory flag, because this is brand new. Ryan was brought this to life, and it’s really cool, and it just shows you a way that you can basically scaffold your blocks from anywhere. Because before you had to be in the in the directory where you wanted the block to be scaffolded, now you can scaffold the block from anywhere by passing that target directory. There’s a couple things to know, and this side we right before this session, we were kind of practicing with this. You do need to be pretty precise around where you’re targeting things, but as that would make sense, right? Because I was not precise and ended up installing plug ins in random places that they should not have been. So let me pull up my notes here, and we can start this. So when you create a when you scout the block using create block. Zoom in a little bit here. You’re going to use MPX at WordPress slash create block. Now this is this you can do at latest if you want. But this is pulling from the Create block package. The next thing you need to do is you need to pass a slug. So this is there. There’s a there’s a way to do this automatically, and we’ll walk you through some steps on staff capital demo block. But in this case, we’re going to do is we’re going to create a slug for the name of our plugin that we’re creating. So let’s just call it my dynamic block. Okay. Next we’re going to use the template flag, because we want to use the template that I created. We use template right now. We are inside of this create block Templates folder. So in my terminal, I’m inside of this create block Templates folder. What I need to do is, I’m going to do I need to target templates,

Speaker 1 44:12
dynamic block. Okay,

Nick Diego 44:17
let me just do this first, and we’ll see what happens. I’m

Unknown Speaker 44:24
buttons, oops,

Nick Diego 44:27
I don’t think I do any of the dot here, yeah,

Ryan Welcher 44:30
because it’s a local path, so it has to know where to look from, where it’s being called,

Nick Diego 44:36
all right? So you can see here that it’s scaffolding my block, and this is just using the Create block tool and my template to scaffold the blocks. And you can see here that I had that custom web pack config in the Read Me. Can zoom in. It has my name, all the stuff that I made custom to this i. It’s building out the node modules. It’s going to build the plot, build the block, and you have the complete block here. Now let’s take that and instead of just scaffolding in the directory that we’re in, we’re going to use target Dir. Then we’re going to copy this plugins folder, get the path of the plugin folder. Now, when you do this, note that we are currently in the Create block Templates folder, so we need to be able to get out and get to the right place. So we need to back out twice, because I’m here, I need to back up once, twice, and then studios here, see if this works. There you go. Oh, and I did it wrong. So see, alright, see, this is why, why we, why we do these things, because we learn what we’re doing wrong. So what I, instead, I did is I built it out into this folder, but I did not specify a the folder for the block itself. And this is actually one of the cool things that ran and I were discussing. Because if we look at this, my slug is my dynamic block, but you can actually specify the name of the folder to be anything you want. So let me change this, and we’re going to call it my cool plugin, and we’re just going to delete the extra stuff that I don’t need here. This stuff we don’t need, all right. So now I’ve specified a folder inside of the the plug in folder. Now we have my cool plugin right here, and we have the block being scaffolded behind the scenes, and the name of the block. For the actual name of the file is my dynamic block, all the slug and everything inside of that is going to be my name dynamic block. But using the target dir, we can specify a custom folder if we want. Now to prove that this actually works, let’s open this up.

Nick Diego 47:33
Sorry, it’s on a different screen. Gonna pull this over. I’m

Nick Diego 47:44
and look at that. It didn’t work. Okay? So there’s, there’s something broken in there that okay. And the reason why I think this is broken, and I know this is broken, is because I was scaffolding a plug in, and I did not make the name of the folder the same. So I was showing you how cool it is to be able to change the name of this. And I think if we go back here and we just change this back, we should be okay. No, I

Nick Diego 48:26
all right, my dynamic block is deactivated.

Unknown Speaker 48:31
Just try refreshing again. It might just be that it got deleted, blew up. I

Nick Diego 48:49
All right, what we’re going to do is we’re just going to delete this, and then we’re going to come over here and we’re just going to copy this over. I’m

Ryan Welcher 49:15
just a question in the chat about being able to modify other values by with like on the fly, and the answer is yes, just have to pass. I’m just looking for the scripts. Documentation.

Unknown Speaker 49:33
Great, block documentation.

Ryan Welcher 49:37
It there are, there’s, there’s a number of flags. Now it’s not, as robust as the as what Nick is doing, but there are a number of of options that you can pass. I’m just going to link them in the chat here, specifically things like title and variant, which is something short, description, title, category, whether or not it has scripts to. Associated with it, whether or not it has WP and V associated with it, the name space things, things like that. Sorry to continue. No, they’re

Nick Diego 50:07
just a ton of flags you could add to that. So, like, for example, like in my example here, if I wanted to enable env, I think it’s just what WP and V, you can just enable WP and V, just like that, by adding a flag, and it will just add it to the scaffold. So, like my template does not preclude any additional flags that you add. So you could just build a very simple template for your own specifications and then use all the available tags that are there and then customize it further. So I think I just had a mix up with my local site. So after refreshing it, everything is working now. So this is my scaffold the block, my dynamic block, save it, and then on the front end, we have, you know, the two two options there. But again, it’s very just a very simple block. But under the hood, the scaffolded files and everything are kind of my own personal preference on how I like things built. And if you are somebody who’s building a lot of blocks, or you’re running a company that you’re doing building your own scaffolds, building your own templates, I if you’re not already doing side I highly encourage you to do so, because it really allows you to standardize the way that you build build blocks, and also speeds things up, and then you can always add more functionality to them along the way. And again, it doesn’t preclude, preclude those existing flags that exist in the Create block package. We are running a bit out of time. But one of the things that I wanted to share, which I mentioned earlier, is that these tools, while gray and they can do a lot of amazing things, they can’t do everything. And it’s important to hear from the community development community around what things you would like to see added or improved. So I wanted to draw attention. I’m going to stop sharing real quick. I wanted to just draw attention to a PR that Greg, who’s actually in our chat, has been working on, and this is to improve WP script specific. So this is a cool PR about how to automatically detect entry points for default JavaScript and CSS files in your projects. This basically makes the idea is to make WP scripts a little bit more intelligent around how it handles all this stuff, and it’s currently a draft PR. But if you’re interested in this sort of thing, please take a look, provide some feedback. I think that’d be very helpful. And if you have other ideas on how we can improve these tools, let us know, or open an issue in the Gutenberg repository. There’s so many cool things that we could do now. Thank you, Ivan, for reminding me about this issue that you were having, so I haven’t run into this too maybe somebody who’s smarter than me can help me figure it out. So if I go to how Okay, so if I’m in my dynamic block and I do NPM run build,

Speaker 1 53:13
you’re not sharing Justin, oh, I’m sorry. I Yeah.

Ryan Welcher 53:23
Also, I want to mention that if you are a Windows user, we need testers for creative block and for scripts, because there are things that only happen in Windows land. So if you know that would be a great way of contributing and just letting us know if all these tools are actually working the way they’re expected. So

Nick Diego 53:43
absolutely. So this is the issue that I have been running into as well, which I believe I’ve been as we’re running into too if you define your own entry points, like I’m doing here for style and editor, you get this legacy JavaScript API notice. And I don’t really know how to solve it. I haven’t honestly looked into how to solve it, but I have noticed it popping up. Now, everything still gets generated as expected. You still get your files, but it is a bit of a scary notice, and this only started happening at least to me in the last month or so. So have you run into this? Ryan, or

Ryan Welcher 54:26
Yep, yeah, I’ve seen it. It looks like a dependency issue. Most likely, updating the SAS dependencies in scripts will probably make this go away. That’s a guess, just based on the the the the output message, I love Greg. I think, I think Greg said something similar, maybe in chat. So I wouldn’t worry about it. This is definitely just like a plumbing thing that that, that that the team, the development team, needs to to to address not anything that you’re doing wrong. It’s just the way that it’s building,

Nick Diego 54:58
yeah. And if you look. At this article. It seems to indicate that, you know, they’re just trying to be very proactive to let people know about it and everything. So, all right, all right. Does anybody have any last minute questions before we kind of close down the show here? I know we kind of reached, breezed through a lot. Yeah, we did. So

Ryan Welcher 55:28
did, did? Did you mention Nick, sorry, I got caught from chat, but did? Someone was asking about the flags that could pass to scripts on on the fly. Did you happen to mention that if you use those flags, they will override the values provided by the template, regardless of what’s in the template. I don’t know if you mentioned that. So if you have a name space, that’s like, my fun name space, and then you use that template with the namespace flag and change it, it’ll change it for the template, like it won’t use that default value. I didn’t know if I was saying it. If it wasn’t, I apologize. But I just wanted to get that out of my head.

Nick Diego 56:01
No, that’s great. I did not. I did mention that you can use flags with templates, but that is important to note that the flag takes precedent over the template. So just note that whenever you guys are are doing that sort of thing, but I usually I really like combining, like, if you don’t want your template to include everything, and you’re very used to using the flags already. Keep your keep your template simple and use the flags, you know, it’s but again, I think that the really, the cool thing about this is how customizable it is. And it really comes down to your own personal preference on how you want to set things up. Yeah. And I will admit it does take a little bit to kind of build it the way you want, you know, figuring out what pieces you want to replace and you know how you want to structure everything. The mustache files, I’ll admit, were a little bit intimidating for me at first. I’m like, What is this thing? But it’s just normal files with it,

Ryan Welcher 56:56
yeah, the the one thing about is that there are some conditionals that you can use inside those files. So there’s a, this is a bit more of an advanced approach. But if you have files that you don’t want to output based on your variant, which is a way of defining multiple sort of flavors of your template, you can actually wrap it in conditional SO, SO files don’t so parts of files don’t get output. The and things of that is, I it’s in the article that I wrote on the developed blog, if you want to take a look at that, but it allows you to do some really like out of the box, things like not render any block files at all, just render a single JavaScript file, because that’s all you want. Or, you know, you can do all kinds of stuff with it.

Nick Diego 57:38
Yeah, and I want to share, Ryan, you have a cool repo with more examples that are more complicated than mine. So it’s that has things that use those conditionals, use the variants. I didn’t use any of the variants in my examples, just to keep things simple, but you can definitely do that. Scott asks, will be likely to see any official package of block templates. No, not necessarily. However, the Create block package itself includes templates. So whenever you pass that flag is dynamic that is actually rendering a template that is defined to render a default block template. We also have one for interactivity API. I think you just just flag interactive. Is that right?

Ryan Welcher 58:26
Well, you passed the template, so the template, they’re also on on let me see if I can grab it. Here. They’re all stored in the on NPM. So the other thing about both templates is that you can actually host them on NPM, and then just access them directly. So there’s an out WordPress, create block tutorial, and then there’s an out WordPress, sorry, I have to find it here,

Speaker 1 58:51
and I don’t know my where’s the interactivity?

Unknown Speaker 59:00
Oh my gosh, while

Nick Diego 59:02
you’re looking for that, fill us creep theme script in the future, I’m not sure. I think I

Ryan Welcher 59:10
don’t want to add a hackathon two years ago that hasn’t gone anywhere, but hopefully we’ll get there, there. Oh

Nick Diego 59:17
yeah, share your thing.

Unknown Speaker 59:20
Oh sure, yeah. Here I’ll share

Ryan Welcher 59:23
with the thing is, we do have the, we have the Create theme block, right? Or the plug in. I mean, sorry, that handles a lot of that, that stuff. So this is the interactivity API block example. So the way that you call it is you would just pass template and then the NPM package name, so which is, this is a really great way of of of distributing templates. So,

Nick Diego 59:53
absolutely, yeah, yeah, and that’s how you have your templates. I think,

Ryan Welcher 59:57
yeah, I have three. My Block developer cookbook. I have them all on an NPM as well, which makes it just makes a lot easier. You don’t have to distribute all your code, but you can, yeah, so you can share these. The The thing about the the official block templates, is that the Create block package has two templates that are built into it. One, sort of like an ES, ES, next, like advanced jobs or not, advanced modern JavaScript ones sort of like a vanilla JavaScript version, and they they covered, like, the majority of use cases that the community needs. Um, because it the like, what’s great about a template is that it’s really customizable, but there’s not, not everyone’s going to need the same style of of of customization. I mean, the only variant that I can see maybe getting added is one that just does something like a variations file or a slots file, or like an admin screen file, one that doesn’t necessarily do a block, but then we’re kind of pushing the limits of what create block was meant for anyways. But, yeah, yeah, but, but you’re welcome to create your own and go wild with what it does. So I

Nick Diego 1:01:07
do before we drop off, I do want to mention one thing that folks are talking about of. I have an example in the repo of a editor extension template. The editor extension template is not a block, right? It’s just an extending a block. But it’s using the Create block package. So by default, it will always generate a block dot JSON file. So basically it, like, does everything I want. It just gives me an extra block that JSON file, which I will just remove and keep on going, you know, keep on developing. But it would be kind of interesting if there was a, you know, create plug in tool, something like that, where you or a tool that’s a bit more abstracted, where you could say, I don’t, I’m not building a block, but I want all the other stuff, you know. But you know, all my other custom stuff that we currently have, so that’s that would be very interesting. So because I do think that I find myself building more plug ins that are not blocks, like we did the interactivity API was just introduced, and using the interactivity API and block variations, you can build a really cool plug in that does a lot of things that you would previous have to use a block for. But if we could have a way of scaffolding that without having to, you know, create a block, that’d be pretty cool. And I think you can get pretty close with the Create block package, but it’s still going to get you that block dot JSON

Unknown Speaker 1:02:35
file. Maybe

Ryan Welcher 1:02:36
we just need a, need a flag that’s like No, like no, emit JSON or something, or or, or something on the template level, that just removes it. Or you could just, you know, add something in your scripts and POST call that that deletes blockchain. Yeah, yeah, yeah. Block binding stuff too. Like, we’re going to get to the point where there’s less and less need for custom blocks. I mean, there always will be need for custom blocks. But a lot of, a lot of what custom blocks are solving are, like, I want to connect post meta to a thing, or, like, you know, a lot of these, a lot of these custom blocks are built because core doesn’t support what you’re looking for, but we’re getting closer to where it does support. And custom blocks are becoming less and less they go to, yeah,

Nick Diego 1:03:16
absolutely. But this is great discussion, everyone. Thank you for commenting on this, because coming up with a solution that tackles all these use cases is something that would be great for us to have, and what we come up with will really rely on the input from you all and what you need. So alright, we’re five minutes over. Thank you all for coming again. The next session will be on the 17th, and we’re gonna be talking all about playground, and a lot of cool things that you can do with playground for plug in, theme developers. So hope you all will attend that one if you’d like to continue the discussion. Ryan and I are both on X make blue sky. All the things I do want to highlight if you’re interested in this conversation in a more like centralized place, there’s the outreach channel in WordPress slack, that’s a great place to have some of these discussions and kind of keep them in one place. But wherever you find us, feel free to reach out. Thank you all so much for coming, and we hope to see you on the next one. The recording of this session will be up later today. Thanks again.

Unknown Speaker 1:04:20
Thanks everyone.

Unknown Speaker 1:04:20
Great chat. Bye.

Props to @ndiego and @welcher for presenting and reviewing

]]>
https://developer.wordpress.org/news/videos/developer-hours-improve-your-workflows-with-wordpress-development-tools/feed/ 0 4835
What’s New for Developers? (December 2024) https://developer.wordpress.org/news/2024/12/whats-new-for-developers-december-2024/ https://developer.wordpress.org/news/2024/12/whats-new-for-developers-december-2024/#respond Tue, 10 Dec 2024 15:16:36 +0000 https://developer.wordpress.org/news/?p=4831 Welcome to the last edition of What’s New for Developers for 2024! This post provides a summary of developer-related changes in the last month, including updates to the Gutenberg project, WordPress Core, and other areas.

Before diving into changes, WordPress 6.7 was released on November 12, so be sure to update your sites if you haven’t already!

Highlights

Style book updates

The style book in the Site Editor has received significant updates, integrating global styles controls and the style book preview directly into the Styles panel. By default, the preview displays the Site view, but users can easily switch to the Style book for a comprehensive block overview. Additionally, a new landing page has been added to the style book tabs, showcasing common theme blocks for a more streamlined and intuitive editing experience.

Filter the block editor rendering mode

As of WordPress 6.7, there was no way to programmatically set the default rendering mode of the Editor. With Gutenberg 19.8, it is now possible to control the rendering mode either via one of the new filters or during post type registration with the new default_rendering_mode property.

WordPress Playground

The Playground app now offers the Pull Request (PR) testers for WordPress Core and Gutenberg in the interface. It’s a more streamlined way to test contributor work before it’s merged into the next release, and should make contributing to the project by testing, providing feedback and filing bug reports much easier. 

Plugins and tools

Stabilizing experimental supports keys

Plugin authors and theme builders might appreciate the stabilization of the __experimentalBorder support and a few other common experimental block support flags.

DataViews and DataForm updates

The DataViews and DataForm components continue to be iterated on to include a new API, better extensibility support for retrieving information, and some documentation updates.

Updates to core blocks

Several core blocks have been updated to enhance functionality and add support for existing features.

Notable bugs fixes

While many bugs have been addressed in the last month, there are a few that bear mentioning for extenders.

Themes

Gutenberg 19.7 introduces a convenient workflow improvement: you can now set an image as the post’s featured image directly from an Image block. In the Image block’s Options dropdown, you’ll find a Set featured image option. Selecting it updates the post’s featured image with the image from the block. This feature is available in both the Post Editor and Site Editor.

A new category for starter patterns

An update in Gutenberg 19.7 makes starter patterns more accessible by adding a dedicated Starter Content category in the pattern inserter. Previously, these patterns were only available through a modal when creating a new page, disappearing once the modal was closed. The long-term goal is to replace the modal entirely, opening the inserter directly to the Starter Content category for a more seamless and intuitive workflow.

Resources

WordPress News

The WordPress News blog features posts covering the latest WordPress releases, and Make WordPress Core has started the planning for WordPress 6.8 and the remainder of 2025.

Developer Hours and WordPress YouTube

It’s been a busy few weeks for Developer Hours and live streams. Check out the recordings below:

Recordings of all past Developer Hours sessions are available on WordPress.tv, and there is a wide range of content on the official WordPres.org YouTube channel.

Hallway Hangouts

Two Hallway Hangouts, which are community discussions about WordPress features, occurred over the past month:

Developer Blog

Be sure to check out the latest tutorials on the Developer Blog if you haven’t done so yet. Stay tuned for more content showcasing the exciting new features released in WordPress 6.7.

You can subscribe to the Developer Blog and get every new post delivered straight to your inbox.

Props to @ndiego and @bph for co-wrangling the resources in this post, writing portions of it, and reviewing the final draft.

]]>
https://developer.wordpress.org/news/2024/12/whats-new-for-developers-december-2024/feed/ 0 4831