WordPress.org

Make WordPress Core

Updates from John Blackbourn Toggle Comment Threads | Keyboard Shortcuts

  • John Blackbourn 10:54 am on October 28, 2016 Permalink |
    Tags: ,   

    Fine grained capabilities for taxonomy terms in 4.7 

    WordPress 4.7 introduces new capabilities for individual taxonomy terms, allowing developers to implement more fine grained control over management of terms (including categories, tags, and custom taxonomy terms). The new capabilities are meta capabilities that ultimately map back to existing capabilities, so there is no change in behaviour for existing functionality and users.

    New Singular Capabilities

    • edit_term
    • delete_term
    • assign_term

    In the same way that capabilities such as edit_post and delete_user are used to check that a user can perform the action for a specific post or user, these new capabilities can be used to check that a user can perform the action for a specific term. If you’re currently checking the edit_terms, delete_terms, and assign_terms capabilities, you can switch these over to the singular form and include the term ID as the second parameter. Example:

    if ( current_user_can( 'edit_term', $term_id ) ) {
    	printf( '<a href="%s">Edit This</a>', get_edit_term_link( $term_id ) );
    }
    

    The new capabilities are meta capabilities — which means they ultimately map back to the existing manage_categories capability by default, or whichever capability has been specified in the corresponding capability arguments when registering the taxonomy. The actual required capabilities can be filtered using the map_meta_cap filter like so:

    add_filter( 'map_meta_cap', function( $required_caps, $cap, $user_id, $args ) {
    	switch ( $cap ) {
    
    		case 'delete_term':
    			$term_id = $args[0];
    			// Prevent a "protected" term from being deleted:
    			if ( get_term_meta( $term_id, 'protected', true ) ) {
    				$required_caps[] = 'do_not_allow';
    			}
    			break;
    
    		case 'edit_term':
    			// Introduce some anarchy:
    			if ( rand( 1, 6 ) == 3 ) {
    				$required_caps[] = 'do_not_allow';
    			}
    			break;
    
    	}
    
    	return $required_caps;
    }, 10, 4 );
    

    Separate Capabilities for Tags and Categories

    A related change is that the post tag taxonomy now uses separate capabilities from the category taxonomy by default (it previously used the same capabilities as the category taxonomy). This doesn’t alter existing behaviour (custom or otherwise), but it does mean that you can target capabilities for tags separately from categories. Example:

    add_filter( 'map_meta_cap', function( $required_caps, $cap, $user_id, $args ) {
    	switch ( $cap ) {
    
    		case 'manage_post_tags':
    		case 'edit_post_tags':
    		case 'delete_post_tags':
    		case 'assign_post_tags':
    			// Allow Authors to manage tags:
    			$required_caps = array(
    				'publish_posts',
    			);
    			break;
    
    	}
    
    	return $required_caps;
    }, 10, 4 );
    

    See Trac ticket #35614 for more information.

     
  • John Blackbourn 6:04 pm on October 3, 2016 Permalink |
    Tags: ,   

    Feature Project Proposal: Notifications API 

    Most of the situations where WordPress sends an outgoing email can be classified as a notification. X just happened on your website and you should be aware of it.

    Back when WordPress was a youngster, the only way to reliably notify a user was via email. In 2016 we have many more options, including push notifications to mobile platforms, desktop notifications to browsers, messages to chat apps, endless services via webhooks, SMS messages, or even notifications in the WordPress admin area. The list goes on. For many users, email is no longer the optimal delivery mechanism for ephemeral notifications.

    To that end, let’s think about replacing wp_mail() with a modern API that allows developers to route notifications to services other than email, allow them to better modify notifications and the way in which they’re formatted, and allow them to do so without stepping on each others’ toes.

    The current lack of a notifications API (or even an email sending API) can be easily summed up:

    Problem: Plugin A wants to provide HTML emails, and Plugin B wants to send emails via an email delivery service such as Mandrill. Plugin C wants to disregard emails and send Slack notifications. It’s very difficult for these to co-exist.

    Notification Destinations

    There are only two types of destination for a notification in WordPress. Most notifications are actually notifications to a user account that get delivered via email because it’s the only contact information available for every user account. The remaining notifications are explicitly notifications to an email address rather than a user account (or not yet attached to a user account), such as when a user signs up for a blog and needs to click a confirmation link before their user account gets created.

    With this in mind, you might be able to imagine a notification class in WordPress core that defaults to delivering notifications via email, but which can be extended by a plugin on a per-user and per-notification basis to deliver notifications via any of the means listed above. WordPress core would support delivery via email and provide the API that allows plugins to implement delivery via other means.

    With a well-designed API, multiple plugins can co-exist in order to deliver different notifications via different mechanisms, format email notifications as HTML, easily disable notifications, change the delivery mechanism for email notifications, or provide a UI for users to manage their notification preferences and destinations.

    Planning a Notifications API

    I’d like to begin work on a feature project with the intent of designing and implementing such an API. I’d like to get input from authors of existing plugins that provide functionality such as delivering notifications via a service other than email, that override the default email delivery mechanism, or that implement extra notifications (such as e-commerce sale notifications), in order that the API can be backwards compatible and that we can get some plugin implementations built during the API’s development.

    I already have some technical ideas regarding how the API might look, but I’m conscious that such an API needs to be well-designed before anyone jumps into writing code. Maybe we can even try some test-driven development? Who knows.

    In addition, consultation and involvement with the team that are working on the two-factor authentication feature project is important as it implements several delivery mechanisms for 2FA codes that could potentially be made simpler with a notifications API.

    Get Involved

    Feedback is most welcome in the comments. Would you like to help out? Yes? Great. Let’s plan a date and time for a meeting in Slack and go from there.

    Finally, a reminder that feature projects are not tied to a specific release of WordPress. This won’t make 4.7. It would be great if it was mature enough for 4.8, but we won’t be aiming for a particular release just yet.

     
    • lkraav 6:41 pm on October 3, 2016 Permalink | Log in to Reply

      I remember Stream just now working their Notification API full steam. Learnings and stuff available?

      https://github.com/xwp/stream/issues/762

    • Greg Ross 6:56 pm on October 3, 2016 Permalink | Log in to Reply

      I think notifications need to be thought of more holistically, it’s not just about fire and forget, there should be a notifications center and the ability to view the history of your notifications.

      It could also look at the admin notices that get displayed so that they have somewhere to live that isn’t the top of every admin page 🙂

    • Mike Schinkel 6:59 pm on October 3, 2016 Permalink | Log in to Reply

      Yes. Please!

      Are you envisioning Notification Destinations to include message queuing too, or no?

    • Chad Butler 7:02 pm on October 3, 2016 Permalink | Log in to Reply

      I think it’s a great idea, John. However, where you said “let’s think about replacing wp_mail()” I assume (hope) you mean “let’s think about replacing the use of wp_mail() for notifications.” wp_mail() is quite ubiquitous throughout the plugin universe. Replacement would have repercussions, unless of course wp_mail() were to be updated to use the new API. Maybe I’m reading it wrong, but just throwing that in if I’m not.

      • John Blackbourn 9:00 pm on October 3, 2016 Permalink | Log in to Reply

        `wp_mail()` would be updated so it becomes a wrapper for the notifications API. Core may stop using `wp_mail()` but its functionality would of course remain.

        • Stephen Harris 12:47 pm on October 4, 2016 Permalink | Log in to Reply

          Hi @johnbillion,

          I think I’ve already said I’d be interested in helping out in the past – if not, consider this registering my interest ;).

          One point of concern though: would `wp_mail()` be a wrapper for the notification API? Or would the notification API (if/when configured to do so) make use of `wp_mail()`? I ask, because the purpose of `wp_mail()` is very much tied to it’s means of delivery. There will be instances where plug-ins are using `wp_mail()`, when an alternative means of transport is not appropriate or not possible.

          This really boils down to who has final say on the means of transport, and in particular whether `wp_mail()` will continue to only trigger e-mails – you hint as much in your reply to Chad. I dare say this is will get thrashed out in the details, but something to keep in mind.

          On a related note, I’ve a long-standing, and now out-dated patch for how WordPress handles emails, and it would be great to see a greater degree of flexibility: https://core.trac.wordpress.org/ticket/29513

    • Henry Wright 7:07 pm on October 3, 2016 Permalink | Log in to Reply

      I have been hoping for something like this for some time https://wordpress.org/ideas/topic/notifications-api

    • Pascal Birchler 7:39 pm on October 3, 2016 Permalink | Log in to Reply

      I have expressed my interest in this in the past and I’d love to help shape such an API.

      As mentioned in other comments, it should be possible to queue notifications, e.g. by storing them in the database until delivered. One particular use case I’m talking about is when you want to send 1 weekly digest email instead of an email for every event. See https://wordpress.org/plugins/digest/.

    • J.D. Grimes 7:42 pm on October 3, 2016 Permalink | Log in to Reply

      I have seen this idea brought up before, and I’ve been hoping that someone would pick it up. I’ll try to contribute as I have time (which sometimes won’t be much).

      I would like to point out that your example seems to me to be a bit wrong-headed, but perhaps I am interpreting it incorrectly. The impression I get is that there would be several different classes, and plugins would choose to use whichever class they wanted based on the type of notification they want to send. In other words, this would be hard-coded. I think that this is missing a huge opportunity for giving users the option (via plugins built for that purpose) to switch from one form of notifications to another. So if I have a plugin that usually sends me emails, but I want to change that to Slack notifications instead, I should be able to do that very easily just by filtering the delivery method. Perhaps this was part of the idea, but if so it wasn’t clear to me.

      • John Blackbourn 9:05 pm on October 3, 2016 Permalink | Log in to Reply

        The aim is to build a base API that also provides an email delivery mechanism by default, and which allows plugin authors to implement delivery mechanisms for any service they desire, such as Slack. It would then be up to individual plugins to determine when to override an email with a Slack message, or this logic could be provided by a standalone plugin that includes a UI for users to choose their notification preferences.

      • FolioVision 10:32 pm on October 4, 2016 Permalink | Log in to Reply

        John, a notification API is a fabulous idea whose time has come. Thank you. On the other hand, I wholly agree with J.D. that control of where the notifications go should be in the hands of users, not plugin owners. User control of destination is very, very important to making a notifications as useful as it could be. Probably the very core of the improvement.

    • Mark Wilkinson 7:55 pm on October 3, 2016 Permalink | Log in to Reply

      This is a great idea and something I would love to see in WordPress. I am also a +1 for being able to queue notifications to. I would love to help where, how and when I can.

    • Luke Cavanagh 8:14 pm on October 3, 2016 Permalink | Log in to Reply

      This is a really awesome idea.

    • Josh Pollock 8:31 pm on October 3, 2016 Permalink | Log in to Reply

      This is a great idea. I’d love to help on this. Seriously DM me (Shelob9 in Slack) when you’re ready to get started.

      In my plugin Caldera Forms, I built infrastructure for alternative delivery of email notifications. We have only implimented it for SendGrid so far, but will be adding support for other services soon.

      The code for that is here:
      CalderaWP/Caldera-Forms/tree/master/classes/email

      Beacuse altering wp_mail() for one specific type of email is a giant pain/impossible, this system prevents sending to wp_mail() when used. Totally the kind of thing a core notifications API would be helpful for.

    • Adam Silverstein 9:08 pm on October 3, 2016 Permalink | Log in to Reply

      Exciting! I am looking forward to working on it!

    • Paul Wilde 9:26 pm on October 3, 2016 Permalink | Log in to Reply

      Laravel recently implemented support for Notifications in their latest release:
      https://laravel.com/docs/5.3/notifications

      There is also a resource available to download other packages for different services other than the built-in ones:
      http://laravel-notification-channels.com

      Laravel is obviously more mature in terms of PHP version and code-style, but there may be a few ideas of inspiration to look at.

    • Anh Tran 3:50 am on October 4, 2016 Permalink | Log in to Reply

      This is a good idea. I’d love to have a notification hub for all events fired in the system and defined by developers. Each event can have several phases that developers can hook into to do something. Also a list of supported notification media (desktop notification, email, sms, push notifications) should be provided (or easy to be included).

      This is a game changer for the system and all plugins (like e-commerce ones).

    • Russell Heimlich 4:50 am on October 4, 2016 Permalink | Log in to Reply

      I think this would be an awesome plugin and I’m all for improving `wp_mail()` to add more hooks to make it more flexible. I don’t think a notifications API should be part of core. A message sent via email is different from a message sent to Slack. I don’t think it is as easy to say all my notifications should go to Slack. There is a lot of nuance which gets complicated. Would WordPress have an option as part of core to enable Slack notifications? Functionality that relies on 3rd party APIs sounds like a burden to have to maintain in core and is better suited as a plugin so updates can be distributed more quickly instead of pushing a point release to the millions of sites running WordPress that may or may not make use of the notification channel.

      Remember when core had a list of default IM fields in the user profile? That feature was removed (https://core.trac.wordpress.org/ticket/11541) because it was decided that they couldn’t cater to everyone. @dd32 sums it up nicely
      > In my opinion, All IM fields should be striped from core. Its impossible to cater for everyone, whilst not over-doing it.
      > Every culture group and country prefer different networks, in the past, there were a limited selection so it was fine, Today, You might as well include FaceBook, Myspace, Orkut, Tagged, Bebo, Windows Live Spaces (different from MSN AFAIK?)

      I’m curious to see what comes of a feature plugin and how it might handle the issue of trying to be all things to all people. But I still don’t think it is core functionality.

      • John Blackbourn 8:17 am on October 4, 2016 Permalink | Log in to Reply

        This proposal is about building an API that allows plugins to implement any number of destinations. Core will only implement support for email.

        With this in mind, you might be able to imagine a notification class in WordPress core that defaults to delivering notifications via email, but which can be extended by a plugin on a per-user and per-notification basis to deliver notifications via any of the means listed above.

    • Ahmad Awais 6:54 am on October 4, 2016 Permalink | Log in to Reply

      Yes! Yes! THIS! 💯
      Would love to contribute! BTW nice read.

    • Paul Gibbs 8:23 am on October 4, 2016 Permalink | Log in to Reply

      Hi @johnbillion. Thanks for getting this posted; I’ve enjoyed talking with you about it previously about how BuddyPress would make use of this if it were well-architected. I’m not prepared to commit any time at this point until your techinical roadmap/architecture plans are posted, though I understand you are probably wanting unbiased approaches from others to test your implementation ideas against. Please keep communicating frequently and often, and I’ll stick my head in when things have moved on a bit.

    • Florian TIAR 8:31 am on October 4, 2016 Permalink | Log in to Reply

      This is a nice project

    • Stefan Kremer (stk_jj) 10:38 am on October 4, 2016 Permalink | Log in to Reply

      Like the idea very, very much. Already asked the core contributors in there session @ WordCamp Nuremberg about such an development. Would be a huge achievement for admins running multiple WP instances getting notifications not by mail, but forwarded to logstash/ELK-stack, graylog, … or any other logging plattform.

    • Daniele Scasciafratte 5:43 pm on October 4, 2016 Permalink | Log in to Reply

      My question is what mean Notification?
      Today there are many way to receive a notification.
      As example I love the emails like https://lwn.net/SubscriberLink/702177/e2712c9c41c0c683/ but for the user of the website maybe it’s better to have the notification in the browser using the push notification and the html5 notification API.
      As example https://wordpress.org/plugins/web-push/ this add the notification for the user with a push notification server using the notification api of the browser in pure html5 and easy to extend https://github.com/WPBP/WordPress-Plugin-Boilerplate-Powered/blob/master/plugin-name/admin/includes/PN_Extras.php#L191 for custom notification.

    • Dennis Ploetner 9:32 am on October 5, 2016 Permalink | Log in to Reply

      That’s very interesting! I would love to help here. Let’s talk about that at #wcmil, John.

    • mattyrob 1:26 pm on October 5, 2016 Permalink | Log in to Reply

      `wp_mail()` is long overdue some attention IMO. Simply the fact that is can’t currently handle Alternative Body emails with HTML and Plaintext parts is an obvious area for improvement.

      This project has the potential to bring email functionality up to date and also allow plugins to extend notifications in new and alternative directions – I’ll happily input when my time allows.

    • tristanfaganguimond 2:16 pm on October 5, 2016 Permalink | Log in to Reply

      This would be an excellent addition.

    • Steven Word 8:20 pm on October 5, 2016 Permalink | Log in to Reply

      +1 On the consideration for 2FA. There were some big concerns brought up during the 2FA discussion roundtable at the Community Summit in 2015 that may be alleviated with a Notifications API.

    • markcallen 10:34 am on October 12, 2016 Permalink | Log in to Reply

      I’m not sure a full API is required.

      I’ve brought this up recently in this ticket – https://core.trac.wordpress.org/ticket/38028.

      Notifications are almost the very definition of an ‘action’. Hooking actions is what WordPress is great at. As developers we can add as many as we like for as many services, notification types as we want. It’s backwards compatible and can fallback to wp_mail if necessary.

  • John Blackbourn 8:30 am on September 29, 2016 Permalink |
    Tags:   

    Reminder: HTTPS meeting tomorrow 

    The weekly meetings about HTTPS improvements in core will resume tomorrow at 16:00 UTC (Friday, September 30, 2016, 16:00 UTC) in the #core-http channel on Slack. See you there!

     
  • John Blackbourn 7:41 am on September 21, 2016 Permalink |
    Tags:   

    HTTPS Working Group 

    In WordPress 4.4 and 4.5, various pieces of work were done to improve HTTPS support in core, but not much has been tackled since then. To address this, I’m going to re-start the weekly chats in the #core-http channel in Slack. Fridays late afternoon UTC/GMT are good for me — does this work for other people who are interested in helping with HTTPS issues?

    Although the HTTPS improvements are always ongoing and not tied to a particular release, it would be great to get some improvements into 4.7.

    If you run a WordPress site over HTTPS only, support is very good and there are very few issues to contend with. If you’re running a multisite network on HTTPS there are a few small issues when adding new sites. However, the main HTTPS issues in core come from:

    • Enforcing the HTTPS scheme on assets (such as embedded images in post content, and enqueued JS and CSS).
    • Enforcing the HTTPS scheme on links, redirects, and canonical URLs.
    • Migrating an existing HTTP site to HTTPS.
    • Running a site that uses a mixture of HTTP and HTTPS.

    The first two points — avoiding mixed content on HTTPS sites — need to be solved via an opt-in system (either via constants or filters) because enforcing these can cause issues with sites that run proxies (for example Cloudflare’s Universal SSL). Overall though, this ought to be a fairly straight forward set of enhancements to implement.

    The third point is a potentially complex one which will need a lot of discussion and some ideas putting forward. How can core make life easier for a site owner who wishes to switch their site from HTTP to HTTPS? Should it be a case of being able to change the scheme in the URL on the General Settings screen or is there too much risk of breakage? What else can be done post-migration to aid the site owner, or will the opt-in enhancements for avoiding mixed content be enough?

    The last point is one that, going forward, should be generally discouraged, however it needs to continue to be supported for multisite networks that use domain mapping and can’t serve every domain over HTTPS.

    There’s an https keyword on Trac which has been applied to tickets that concern HTTPS issues. We’ll start going through this list in next week’s chat.

    Here’s a bunch of further considerations that need to be taken into account while working on HTTPS issues:

    • Differing schemes, domains, and ports in the siteurl and home options.
    • Domain mapping
    • force_ssl_admin() usage
    • Self signed certs
    • No public access to admin URLs
    • Different HTTPS domain on front end (!)
    • HTTP site optionally available over HTTPS

    Here’s a list of items that should be considered for enforcing over HTTPS:

    • Enqueued JS and CSS.
    • Post content, images, js, CSS, iframes,srcset, oembeds, forms.
    • How about other fields such as term descriptions, user bios, etc.
    • Force https links. Links to the current site.
    • Force https link in nav menus.
    • Force https redirects and/or canonical.
    • Force HSTS. (Probably not.)
    • Force https rest api endpoint.
    • Force https XML RPC.
    • Set https-only on cookies.

    Let me know in the comments if you’d like to help out and if Fridays are good for the meeting time!

     
    • jancbeck 9:46 am on September 21, 2016 Permalink | Log in to Reply

      > If you’re running a multisite network on HTTPS there are a few small issues when adding new sites
      As somebody who is intending to do just that in a couple of weeks, may I ask what issues these are?

    • Jeremy Felt 2:36 pm on September 21, 2016 Permalink | Log in to Reply

      16:00 UTC and later would be the best time for me, but phones make anything possible. 🙂

    • Luke Cavanagh 7:01 pm on September 21, 2016 Permalink | Log in to Reply

      I would be interested in helping.

    • thomaswm 9:40 pm on September 21, 2016 Permalink | Log in to Reply

      I’m interested in helping. Fridays should be good.

    • jpresley23 1:41 am on September 22, 2016 Permalink | Log in to Reply

      We’re making the shift from http to https. What would have really helped is saving the urls with just “//” rather than saving the protocol to the database within content. The double slash without the protocol will be interpreted with whatever protocol the site uses. Unless there is backwards compatibility break, using the double slash would be best.

      In general saving urls within the content is problematic. When a site url changes, which happens as we move content from stage to production or move from a development domain to a production domain, we have to scrub the database to find where the development urls are stored.

      • Aaron Jorbin 7:53 pm on September 22, 2016 Permalink | Log in to Reply

        • Mark-k 6:12 am on September 23, 2016 Permalink | Log in to Reply

          just because some guy says it is an anti pattern doesn’t make it one. And if china want to break into any site they will succeed. Those are bad reasons to not solve/ease the core problem by using protocol relative url. In theory a URI is an address of a resource, it should not matter at all by which protocol you want to retrieve iit. Leave the decision to the client to decide what is the best strategy to retrieve it

    • menkom 1:41 am on September 22, 2016 Permalink | Log in to Reply

      Subscribed….. this is a much needed topic of discussion and the transition of http -> https should be improved for WP users

  • John Blackbourn 1:14 am on September 9, 2016 Permalink |
    Tags: ,   

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

    WordPress 4.7 will introduce some new goodies for theme developers, and you can test them out now in trunk. 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, either in the comments here or on the individual tickets linked below.

    Note: Note that these functions and hooks are subject to further change!

    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 theme 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 CSS or JavaScript 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 URL 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 Filter

    #14310

    This new dynamically-named filter allows the complete template hierarchy of a given request type to be filtered by a plugin 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 category archive based on the value of its term meta 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 ticket: #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.

    Alert: 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.

     
    • Tran Ngoc Tuan Anh 2:25 am on September 9, 2016 Permalink | Log in to Reply

      `get_theme_file_uri()` and `get_theme_file_path()` are great! Much more convenient than `get_template_directory_uri()` and `get_template_directory()`.

    • Sami Keijonen 5:49 am on September 9, 2016 Permalink | Log in to Reply

      Looks great. But I was confused of last Non-ASCII filter.

      This explains it’s purpose to me much better:
      https://core.trac.wordpress.org/ticket/37655#comment:6

    • Nicolas Juen 7:45 am on September 9, 2016 Permalink | Log in to Reply

      This is very good, but can’t we have a filter on the folders to scan for the ressources ?
      This can be VERY interesting for making a parent framework theme and the filter can be added to the locate_Template function too.

    • ThemeZee 8:06 am on September 9, 2016 Permalink | Log in to Reply

      Allowing child themes to override JS and CSS files easily is a really really great feature, I like it.

      Why do we need get_parent_theme_file_uri() when it does basically the same as get_template_directory_uri() ? Just for consistency? So it is only a wrapper function?

      • John Blackbourn 10:01 am on September 9, 2016 Permalink | Log in to Reply

        Yep, mostly for consistency in the way you call the functions. `get_parent_theme_file_uri()` and `get_parent_theme_file_path()` accept a parameter for the file name, whereas `get_template_directory_uri()` and `get_template_directory()` don’t.

      • Justin Tadlock 12:30 pm on September 9, 2016 Permalink | Log in to Reply

        Plus, there’s an associated filter hook.

    • Omaar Osmaan 2:07 pm on September 9, 2016 Permalink | Log in to Reply

      Thanks so much for all of it- can’t wait to use the filters, and the functions in a theme/plugin! 😀

    • lkraav 8:59 am on September 13, 2016 Permalink | Log in to Reply

      I’ve been long wondering, is it possible to do cache busting in a more DRY inline manner (without noisy variable definition)?

      BEFORE
      `wp_enqueue_script( ‘my-script’, get_theme_file_uri( ‘js/my-script.js’ ), array(), filemtime( get_theme_file_path( ‘js/my-script.js’ ) ) );`

      AFTER
      `wp_enqueue_script( ‘my-script’, get_theme_file_uri( ‘js/my-script.js’ ), array(), filemtime( get_theme_file_path( SOME_MAGIC_HERE ) ) );` where this magic is some known marker/value that is automatically converted to the same value given to `get_theme_file_uri()` – in this case `js/my-script.js`

      • Pascal Birchler 1:01 pm on October 7, 2016 Permalink | Log in to Reply

        Not in core. You could pass any source to wp_enqueue_script(), not just a file in your theme. And the version can be anything as well, not just the time your file has been last modified.

        You could easily build your own wrapper function that does this though.

    • Gary Jones 6:35 am on October 7, 2016 Permalink | Log in to Reply

      @johnbillion What’s the difference in functionality and use case between `locate_template()` and `get_theme_file_path()`?

      • Pascal Birchler 12:58 pm on October 7, 2016 Permalink | Log in to Reply

        locate_template() accepts an array of template files and checks if any of them is found in the stylesheet directory, the template directory or inside wp-includes/theme-compat. It either returns the first template file that is found or loads it directly. If none is found, it returns an empty string.

        get_theme_file_path() only checks the stylesheet directory and the template directory for 1 given template file and returns the path to it. If none is passed, it returns the full path to the stylesheet directory.

  • John Blackbourn 12:38 am on January 26, 2016 Permalink
    Tags: ,   

    HTTPS discussion meeting this Wednesday 

    In recent releases of WordPress there have been various improvements made to support for sites running on HTTPS. While support is currently very good, it’s still too easy to end up with mixed content on a site (HTTP 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 Slack 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. filter/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 plugin?

    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.

     
  • John Blackbourn 5:08 pm on December 11, 2015 Permalink  

    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 Image” 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 filter 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 taxonomy 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.

     
  • John Blackbourn 11:00 am on October 12, 2015 Permalink
    Tags: ,   

    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 URL, instead of just their username and nicename. See #27304
    • 4.4: Performing a search on the Network 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 Multisite 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 filter 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 UI) are now shown as having multiple roles on the Users screen. This helps avoid obfuscation of a user’s roles. If your plugin facilitates the assignment of multiple roles to an individual user, you should test it against trunk 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.

     
    • JakePT 11:36 am on October 12, 2015 Permalink | Log in to Reply

      Does this new search also search first and last name fields individually? Be nice if it did.

      I also really want the option to not send users their passwords back. When building a site for a client, we’ll set up their account well before handing it over, to make sure permissions, white-labelling etc. are all working fine. Even then we have our own handover method and don’t need to send the WP Mail. I’m kind of shocked that this change was made, honestly. I’m sure a lot of people do the same thing.

    • sirjonathan 12:39 pm on October 12, 2015 Permalink | Log in to Reply

      How about the ability to search by meta values stored in usermeta? I’ve got a case where I’ve added a column to display a custom value but don’t currently have a way to search by that value.

    • deltafactory 1:52 pm on October 12, 2015 Permalink | Log in to Reply

      On the User list table, would it be possible to (optionally?) store per-role user counts in a transient or other cache? For large user-bases with a wide variety of roles, the slow LIKE query that drives this isn’t necessary on every page load while paging through or searching users.

    • Laurens Offereins 3:26 pm on October 12, 2015 Permalink | Log in to Reply

      Great! Any chance #32956 would make it next?

    • Justin Tadlock 9:45 pm on October 12, 2015 Permalink | Log in to Reply

      I’m just stopping by to formally say thank you for the improvements in 4.3 to user searching. You don’t know how many headaches you’ve saved me in just a short time. So, thanks.

      And, keep up the great work!

  • John Blackbourn 6:52 pm on October 7, 2015 Permalink
    Tags:   

    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!)

     
  • John Blackbourn 3:15 pm on October 7, 2015 Permalink
    Tags: , ,   

    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 type. 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.

     
    • petermolnar 3:22 pm on October 7, 2015 Permalink | Log in to Reply

      wp-config should have an option that sets the max allowed depth for template searches. As in:
      1 -> single depth, eg. single.php, {taxonomy}.php
      2 -> 2 level depth, eg. single-{post_type}.php
      3 -> unlimited depth, eg. single-{post_type}-{post_name}.php

      I wouldn’t be surprised it’d result in a measurable speed gain.

      • John Blackbourn 3:36 pm on October 7, 2015 Permalink | Log in to Reply

        That would save a maximum of about five file_exists() calls, depending on whether you’re using a child theme or not. I doubt it would have any measurable impact at all. file_exists() checks are very fast when absolute file paths are used.

        Additionally, it would introduce inconsistency to the template hierarchy, and consistency is a huge benefit of the theming system in WordPress.

    • kjbenk 4:07 pm on October 7, 2015 Permalink | Log in to Reply

      This is really cool and I can see an immediate use case for this.

    • Ravinder Kumar 5:05 pm on October 7, 2015 Permalink | Log in to Reply

      Nice addition to WordPress.
      Thanks.

    • Dinesh Kesarwani 5:28 am on October 8, 2015 Permalink | Log in to Reply

      Yes! nice addition. I also suggested similar template before some time ago. But, it was rejected.
      https://core.trac.wordpress.org/ticket/29700

    • BenRacicot 12:10 am on October 10, 2015 Permalink | Log in to Reply

      Golf clap

    • elzix 2:26 pm on November 5, 2015 Permalink | Log in to Reply

      I read in the Theme Developer Handbook and assumed single-{post_type}-{post_name}.php was in WordPress 4.3. Is there a way to add the function to my theme or must I convert my posts to pages and use ‘categories for pages’ plugin?

c
compose new post
j
next post/next comment
k
previous post/previous comment
r
reply
e
edit
o
show/hide comments
t
go to top
l
go to login
h
show/hide help
shift + esc
cancel
Skip to toolbar