New Functions, Hooks, and Behaviour for Theme Developers in WordPress 4.7

WordPress 4.7 introduces some new goodies for theme developers. These changes make powerful new functionality available to themes and plugins. It would be great to see theme developers testing this functionality and providing feedback here in the comments or on the individual tickets linked below.

The get_theme_file_uri() Function, and Friends

#18302

The get_template_part() function, introduced way back in WordPress 3.0, is a fundamental one to theme developers and child theming. The function looks in the child themeChild theme A Child Theme is a customized theme based upon a Parent Theme. It’s considered best practice to create a child theme if you want to modify the CSS of your theme. https://developer.wordpress.org/themes/advanced-topics/child-themes/. for the specified file, and falls back to the parent theme if the file doesn’t exist. This allows a template part to be easily overridden by a child theme, simply by means of the file existing.

The new get_theme_file_uri() function introduced in WordPress 4.7 enables this child theme behaviour for theme file URLs, for example when a CSSCSS Cascading Style Sheets. or JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. file is enqueued. Here’s an example of its use:

wp_enqueue_script( 'my-script', get_theme_file_uri( 'js/my-script.js' ) );

The above code enqueues the URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org of the js/my-script.js file from the child theme if it exists, falling back to the URL of the file in the parent theme. Now your parent theme can enable each of its enqueued assets to easily be overridden by a child theme. And of course, if no child theme is in use then the function simply uses the parent theme URL, just like get_template_part().

The companion function get_theme_file_path() has also been introduced. This is the file path equivalent of get_theme_file_uri(). One use case for this function is if you like to dynamically generate the version parameter for your enqueued assets based on the last modified timestamp of the file (using filemtime()). You can continue to do so by using this function:

wp_enqueue_script(
	'my-script',
	get_theme_file_uri( 'js/my-script.js' ),
	array(),
	filemtime( get_theme_file_path( 'js/my-script.js' ) )
);

Finally, get_parent_theme_file_uri() and get_parent_theme_file_path() are also introduced, which specifically reference the file URL or file path to the file in the parent theme (and regardless of whether or not the file exists). For consistency, these functions can be used as replacements for when you may have otherwise used get_template_directory_uri() and get_template_directory() respectively.

The {$type}_template_hierarchy FilterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.

#14310

This new dynamically-named filter allows the complete template hierarchy of a given request type to be filtered by a pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party or theme. Although it’s technically possible for the template hierarchy to be filtered using the existing template_include filter, this new filter allows it to be done in a much more clean, simple, and future-proof way, and without the need to reimplement the entire hierarchy logic within the filter’s callback function.

The filter names available by default are:

  • embed_template_hierarchy
  • 404_template_hierarchy
  • search_template_hierarchy
  • frontpage_template_hierarchy
  • home_template_hierarchy
  • taxonomy_template_hierarchy
  • attachment_template_hierarchy
  • single_template_hierarchy
  • page_template_hierarchy
  • singular_template_hierarchy
  • category_template_hierarchy
  • tag_template_hierarchy
  • author_template_hierarchy
  • date_template_hierarchy
  • archive_template_hierarchy
  • paged_template_hierarchy
  • index_template_hierarchy

Here’s an example of the usage of this new filter to add a year-based file to the top of the hierarchy for date archives:

add_filter( 'date_template_hierarchy', function( array $templates ) {
	$year = get_query_var( 'year' );
	array_unshift( $templates, "year-{$year}.php" );
	return $templates;
} );

Here’s a slightly more complex example of adding a file to the hierarchy for a categoryCategory The 'category' taxonomy lets you group posts / content together that share a common bond. Categories are pre-defined and broad ranging. archive based on the value of its term metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. field:

add_filter( 'category_template_hierarchy', function( array $templates ) {
	$format = get_term_meta( get_queried_object_id(), 'format', true );
	if ( $format ) {
		$new = "category-format-{$format}.php";
		$pos = array_search( 'category.php', $templates );
		array_splice( $templates, $pos, 0, $new );
	}
	return $templates;
} );

More usage examples can be seen in the comment thread on the ticketticket Created for both bug reports and feature development on the bug tracker.: #14310.

This filter also allows debugging plugins to access and display the complete template hierarchy for each request, so you can see which files WordPress is looking for in your theme. The latest version of Query Monitor already supports this functionality.

It’s important to remember that the consistency of the template hierarchy in WordPress is what makes standardised theme structures possible. It’s highly recommended that you do not remove templates from the candidate hierarchy using these new filters, unless you’re absolutely certain of what you’re doing.

Simpler Template Names for Content with Non-ASCII Slugs

#37655

Given a post or term with a non-ASCII name, such as hello-world-😀, the URL-encoded form of the name is used in the template hierarchy. For example, on the single post view the hierarchy looked like this prior to WordPress 4.7:

  • single-post-hello-world-%f0%9f%98%80.php
  • single-post.php
  • single.php
  • singular.php
  • index.php

This isn’t very user-friendly, so WordPress 4.7 adds a new, higher priority template to the hierarchy which uses the non-encoded form of the name:

  • single-post-hello-world-😀.php
  • single-post-hello-world-%f0%9f%98%80.php
  • single-post.php
  • single.php
  • singular.php
  • index.php

This makes it much clearer what a template file refers to when building templates for specific posts or terms that include non-ASCII characters in their name.

#4-7, #dev-notes

HTTPS discussion meeting this Wednesday

In recent releases of WordPress there have been various improvements made to support for sites running on HTTPSHTTPS HTTPS is an acronym for Hyper Text Transfer Protocol Secure. HTTPS is the secure version of HTTP, the protocol over which data is sent between your browser and the website that you are connected to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications between your browser and the website are encrypted. This is especially helpful for protecting sensitive data like banking information.. While support is currently very good, it’s still too easy to end up with mixed content on a site (HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. content embedded within an HTTPS page), and especially so when migrating an existing site from HTTP to HTTPS. There will be a discussion meeting in the #core-http SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. channel on Wednesday, January 27, 2016 at 2000 UTC. This is one hour before the regular weekly meeting in #core. I’d like to discuss three topics:

  1. Implementing an (opt-in) method of forcing a site to use HTTPS.
    • What should this cover? (Embedded content, enqueued scripts/styles, links, redirects)
    • How should it be implemented? (eg. filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output./constant/automatic)
  2. Defaulting to HTTPS for new installs when it’s available.
    • Only applies when setting up a site over HTTP and it’s available over HTTPS.
    • Need to communicate clearly to the user what this implies, with option to toggle.
  3. Aiding in switching an existing site from HTTP to HTTPS.
    • Migrating existing embedded content.
    • Should this be a feature pluginFeature Plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins.?
If you’re interested in helping out with any of the above, or with HTTPS improvements in general, join us on Wednesday. Further reading: the https tag on Core Trac.

#https, #meeting

Additional labels for custom post types and custom taxonomies

In WordPress 4.3 and 4.4, additional labels have been made available for custom post types and custom taxonomies. These get passed in via the labels argument when using register_post_type() and register_taxonomy().

New post type labels in 4.3:

  • featured_image – Overrides the “Featured ImageFeatured image A featured image is the main image used on your blog archive page and is pulled when the post or page is shared on social media. The image can be used to display in widget areas on your site or in a summary list of posts.” phrase for this post type. See #19257.
  • set_featured_image – Overrides the “Set featured image” phrase for this post type. See #19257.
  • remove_featured_image – Overrides the “Remove featured image” phrase for this post type. See #19257.
  • use_featured_image – Overrides the “Use as featured image” phrase for this post type. See #19257.

New post type labels in 4.4:

  • archives – The post type archive label used in nav menus. Default “Post Archives”. See #16075.
  • insert_into_item – Overrides the “Insert into post”/”Insert into page” phrase (used when inserting media into a post). See #33616.
  • uploaded_to_this_item – Overrides the “Uploaded to this post”/”Uploaded to this page” phrase (used when viewing media attached to a post). See #33616.
  • filter_items_list – Screen reader text for the filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. links heading on the post type listing screen. Default “Filter posts list”/”Filter pages list”. See #32147.
  • items_list_navigation – Screen reader text for the pagination heading on the post type listing screen. Default “Posts list navigation”/”Pages list navigation”. See #32147.
  • items_list – Screen reader text for the items list heading on the post type listing screen. Default “Posts list”/”Pages list”. See #32147.

New taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. labels in 4.3:

  • no_terms – Used when indicating that there are no terms in the given taxonomy associated with an object. Default “No tags”/”No categories”. See #32150.

New taxonomy labels in 4.4:

  • items_list_navigation – Screen reader text for the pagination heading on the term listing screen. Default “Tags list navigation”/”Categories list navigation”. See #32147.
  • items_list – Screen reader text for the items list heading on the term listing screen. Default “Tags list”/”Categories list”. See #32147.

See the documentation for get_post_type_labels() and get_taxonomy_labels() for the full list of available labels.

Tweaks to user searching and management

A few improvements have been made to user searching and user management in WordPress 4.3 and the upcoming 4.4. Here’s an overview:

  • 4.3: Performing a search on the Users screen now searches the user’s username, email address, display name, nicename, and URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org, instead of just their username and nicename. See #27304
  • 4.4: Performing a search on the Networknetwork (versus site, blog) Adminadmin (and super admin) -> Users screen previously required the use of a * wildcard character at the beginning and/or end of the search term, otherwise the search required an exact match. This is no longer the case, so finding users on Multisitemultisite Used to describe a WordPress installation with a network of multiple blogs, grouped by sites. This installation type has shared users tables, and creates separate database tables for each blog (wp_posts becomes wp_0_posts). See also network, blog, site is no longer frustrating and inexplicably dysfunctional. This, combined with the changes in 4.3, means searching for a phrase such as “@gmail.com” now works as you would expect. See #32913
  • 4.4: It’s now possible to filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. the Users screen by users who have no role (in addition to being able to filter the screen by individual roles), if there are such users. See #22993
  • 4.4: Users with multiple roles (it’s possible to programatically give a user multiple roles, although this isn’t possible via the UIUI User interface) are now shown as having multiple roles on the Users screen. This helps avoid obfuscation of a user’s roles. If your pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party facilitates the assignment of multiple roles to an individual user, you should test it against trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision. and look at using the new get_role_list filter introduced in [34963] if necessary. See #22959

Any other improvements you think could be made? Leave a comment.

#4-3, #4-4

add_rewrite_rule() accepts an array of query vars in WordPress 4.4

A small change to add_rewrite_rule() in [34708] means that in the upcoming WordPress 4.4 an array can be passed as the second parameter instead of a query string.

Previously:

add_rewrite_rule( 'foo/([^/]+)/bar/([^/]+)/?$', 'index.php?post_type=foo&name=$matches[1]&taxonomy=bar&term=$matches[2]' );

Now:

add_rewrite_rule( 'foo/([^/]+)/bar/([^/]+)/?$', array(
	'post_type' => 'foo',
	'name'      => '$matches[1]',
	'taxonomy'  => 'bar',
	'term'      => '$matches[2]',
) );

While this isn’t the biggest change in the world, it makes this parameter much easier on the eyes.

(Note that your $matches variables need to remain in single quotes!)

#dev-notes

single-{post_type}-{post_name}.php: New theme template in WordPress 4.4

A new theme template has been added to the theme hierarchy as of r34800: single-{post_type}-{post_name}.php.  This template follows the rules of is_single() and is used for a single post or custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept.. It’s most useful for targeting a specific post in a custom post type, and brings consistency to the templates available for pages and taxonomies. It comes in the hierarchy before single.php and single-{post_type}.php.

Don’t forget, too, that in WordPress 4.3 singular.php was introduced and the hierarchy of attachment templates was fixed.

#dev-notes, #templates, #themes

Request for feedback: Your HTTPS configurations

An ongoing goal of WordPress is to improve the way it works for sites that use HTTPSHTTPS HTTPS is an acronym for Hyper Text Transfer Protocol Secure. HTTPS is the secure version of HTTP, the protocol over which data is sent between your browser and the website that you are connected to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications between your browser and the website are encrypted. This is especially helpful for protecting sensitive data like banking information., and more specifically sites that run a mixture of schemes (for example, HTTPS in the adminadmin (and super admin) area but HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. on the front end).

One of the most visible bugs currently is that media in an HTTPS admin area is served over HTTP unless the ‘WordPress Address’ setting (siteurl) also uses HTTPS, which means that the FORCE_SSL_ADMIN constant isn’t a complete drop-in solution to securing your admin area.

Addressing all the possible configurations of HTTPS is difficult, so I’d like to put out a request for anyone who’s using a particularly interesting HTTPS configuration on your site to let us know what your setup is.

Of particular interest would be a site that’s using different domain names for HTTPS and HTTP, different domain names for the admin area and front end, different ports anywhere, self-signed certs for the admin area, HTTPS admin areas with additional access restrictions, multisites with and without domain mapping that use a mixture of HTTPS and HTTP, etc.

If your site has an interesting HTTPS configuration, and of course if it suffers from scheme related bugs as a result, please let us know in the comments below.

#https

Enforcing the show_ui argument for post types

Since [34177], the show_ui argument for post types is now enforced to correct unexpected behaviour whereby the post type listing screen and post editing screen for post types with show_ui set to false were still accessible via a manually entered URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org.

There’s a small chance this may have an effect on your pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party or website if it’s relying on the fact that these screens were accessible. If this is the case, you should correct the arguments for your post type by setting show_ui to true, and then setting show_in_menu, show_in_nav_menus, and show_in_admin_bar to false, as appropriate.

#4-4, #dev-notes, #post-types

Site icon and image cropping controls

A couple of weeks later than intended, a brief update on the site icon functionality which has been touted as a potential feature for 4.3. The site icon functionality aims to provide an adminadmin (and super admin) UIUI User interface (via the CustomizerCustomizer Tool built into WordPress core that hooks into most modern themes. You can use it to preview and modify many of your site’s appearance settings., at least initially) for users to upload an icon which is then output as a favicon and associated touch icons, while also allowing themes or plugins to re-use the icon in other places as they see fit.

The existing headerHeader The header of your site is typically the first thing people will experience. The masthead or header art located across the top of your page is part of the look and feel of your website. It can influence a visitor’s opinion about your content and you/ your organization’s brand. It may also look different on different screen sizes. image control in the Customizer (and its corresponding functionality on the old custom-header screen) provides a means for uploading a header image and then cropping it to the desired size. Unfortunately this control is fairly tightly coupled with the header image functionality, and therefore extending it for use with the site icon control has meant duplicating a lot of code.

It’s looking more and more like #29211 should be tackled before the site icon functionality, in order to avoid this duplication and in order to allow other controls to provide a croppable image upload (such as for background images in #32403).

Due to my limited availability to work on the site icon feature in the coming weeks, I think it would be worthwhile instead focusing on #29211 and the introduction of an abstracted control that supports image cropping, which can then be used for the site icon and custom background controls.

The current non-working site icon feature pluginFeature Plugin A plugin that was created with the intention of eventually being proposed for inclusion in WordPress Core. See Features as Plugins. can be found in this repo on GitHub. It uses considerable code from the custom header image control. If someone wants to take that and run with it that would be great, or if someone wants to tackle #29211 instead, that would be great too.

Reminder: Term splitting in 4.2

Here’s a quick reminder to pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party authors. Beginning in WordPress 4.2, shared taxonomyTaxonomy A taxonomy is a way to group things together. In WordPress, some common taxonomies are category, link, tag, or post format. https://codex.wordpress.org/Taxonomies#Default_Taxonomies. terms will get split into separate terms when one of the terms gets updated.

What does this mean for you? If your plugin is independently storing term IDs in post metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress., user meta, or options, then it’s likely you’ll need to update your plugin to prevent problems when a shared term gets split.

Boone Gorges has posted a complete guide to preparing for term taxonomy splitting. Take a read if you’re a plugin author and you think a plugin of yours may be affected.

#4-2, #dev-notes