Make WordPress Core

Updates from John Blackbourn Toggle Comment Threads | Keyboard Shortcuts

  • 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?


    • 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:

      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:

      There is also a resource available to download other packages for different services other than the built-in ones:

      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 |

    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 |

    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


    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:

    	get_theme_file_uri( 'js/my-script.js' ),
    	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


    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


    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:

    • 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)?

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

      `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

    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.


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


    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.

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

    • 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?

  • John Blackbourn 12:06 pm on October 1, 2015 Permalink

    Request for feedback: Your HTTPS configurations 

    An ongoing goal of WordPress is to improve the way it works for sites that use HTTPS, and more specifically sites that run a mixture of schemes (for example, HTTPS in the admin area but HTTP 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.

    • petermolnar 12:18 pm on October 1, 2015 Permalink | Log in to Reply

      I have no idea what reasoning could justify https only for the backend.

      Anyway: use // for urls, for _every_ in-site url, including css, js, any link instead of http:// or https:// prefixes. That will help avoiding mixed content issues because it get interpretered by the browser according to the url.

      Apart from that… use https w/ http2 everywhere, not just for the backend.

      • Bjørn Johansen 12:53 pm on October 1, 2015 Permalink | Log in to Reply

        The protocol relative URL is now an anti-pattern. Ref.: http://www.paulirish.com/2010/the-protocol-relative-url/

      • Ipstenu (Mika Epstein) 1:51 pm on October 1, 2015 Permalink | Log in to Reply


        1) IE 6 doesn’t support SNI, so you don’t want to lock out people yet

        2) Caching (caching https is not easy for the common man… yet)

        • Jon Brown 2:22 pm on October 1, 2015 Permalink | Log in to Reply

          IE6 rightly gets most of the bad press, but I have seen SNi fail on oild OSX / Safari as well.

        • petermolnar 2:47 pm on October 1, 2015 Permalink | Log in to Reply

          IE6 – meh
          caching – fair point, but mixed content is a lot worse.

          • Ipstenu (Mika Epstein) 3:27 pm on October 1, 2015 Permalink | Log in to Reply

            Read https://en.wikipedia.org/wiki/Server_Name_Indication#Implementation – There’s a lot more than just IE 6. Old Safari too. Not everyone can upgrade to El Capitan.

            • pepe 7:27 am on October 6, 2015 Permalink

              According to Wikipedia, Safari has had SNI since 3.0, released with OS X 10.5.6. That’s an OS that was current 8 years ago (10.5 was released in October 2007). The only people who really could not upgrade to that line are those still using very ancient PowerPC based systems.

            • jeffmcneill 9:49 am on October 6, 2015 Permalink

              The big problems we saw last Jan. is that ~5% of customers were coming with too old of an Android browser that doesn’t support SNI. Also older Blackberry. It would affect 7-8% of customers, so decided to hold off for a year. IE6 had zero customers, though some amount of traffic.

            • Ipstenu (Mika Epstein) 4:56 am on October 7, 2015 Permalink

              @pputzer – I know that’s 8 years ago. The reality though is that by forcing HTTPS we force SNI for many users. That means the users who will be most adversely impacted by the change are the ones with the least ability to fix it.

              THAT is shitty UX.

              People don’t have the money to buy new computers every 5 years. People use the web on shitty mobile nokia phones. It’s one thing to say “You can’t shop here because we cant’ make a secure connection.” It’s another thing entirely to kick them out of 25% of the internet.

              So yeah. I’m gonna fight this one for everyone’s grandparents.

    • John Huebner 12:22 pm on October 1, 2015 Permalink | Log in to Reply

      On the hosting provider I use if I set up SSL then on a site then the entire site is severed on HTTPS, no choice. Once done you cannot access the site by HTTP.

      I have had serious problems setting up WP with SSL. If I set up SSL first then the site breaks because it attempts to redirect to HTTP while the server is redirecting to HTTPS and I can’t login to change it. If I change WP first then the site breaks attempting to redirect to HTTPS that does not exist while I’m setting up the SSL.

      I think that the above comment by @petermolnar might help solve this situation.

      • petermolnar 12:33 pm on October 1, 2015 Permalink | Log in to Reply

        You could; at least it _can_ be set up like that, that’s a choice of the provider if it redirects to https.

      • Ipstenu (Mika Epstein) 3:28 pm on October 1, 2015 Permalink | Log in to Reply

        I want to say this is a hosting issue, but it highlights a major concern. Not all hosting platforms are created equal :/ And telling the end user “its your host” is a terrible idea.

        • John Huebner 1:38 am on October 2, 2015 Permalink | Log in to Reply

          Thank you for that. The company I work for uses a particular host for all the sites we build. I can’t simply decide to use another one and I doubt I’m going to convince the hosting provider that they need to change the way they do things.

    • AdamConway 12:29 pm on October 1, 2015 Permalink | Log in to Reply

      Couldn’t agree more with @petermolnar. Apart from the fact that I don’t see good arguments for not simply hosting the whole site on SSL (if you have part of it there), there is a solution to this built in to URI syntax standards, so why not just use it? I can’t see a downside with that! It might not solve issues where you have mutliple domains with SSL only on some, but relative links (relative to site root at least) are the only real solution to that.

      I use a very simple solution of allowing HTTP to the server but then redirecting to HTTPS in apache (mod rewrite) before it gets anywhere near wordpress, and haven’t had any issues with that. The early sites which were set up with http we had to do database rewrites to fix.

    • thomaswm 12:30 pm on October 1, 2015 Permalink | Log in to Reply

      We operate a multisite network with subdirectory configuration. Every site gets a domain mapped to them using the Domain Mapping plugin. We have a wildcard SSL certificate for the main site’s domain, but we do not have any certificate for the other sites’ domains.

      We have a custom plugin in place to make certain sites available under a subdomain of our main site’s domain via HTTPS so they can use our wildcard SSL cert. This would lead to scheme-related problems, but we use the “WordPress HTTPS” plugin to rewrite the URLs of embedded media.

      Also, one of our most used themes has its own way of dealing with mixed content: It uses the “the_content” filter, look for URLs which point to the current website and runs them through the function “wp_make_link_relative”.

      You see that this is all quite hacky and I’m not really happy about that, but it works after all. 😉

    • Mark Wilkinson 12:39 pm on October 1, 2015 Permalink | Log in to Reply

      I run a similar setup to @thomaswm. I have a multisite installation install on my domain and this domain has a wildcard SSL certificate. Most of the actual sites in the multisite are mapped to a domain name which does not have a certificate and therefore I want the backend to happen over the sites sub domain URL. This can then use the wildcard SSL of the main domain.

      I have had issues in that the domain mapping plugin re-writes all the admin links to mapped-domain.com/wp-admin rather than using subdomain.domain.com/wp-admin, but have over come this with a plugin.

      I am sure there are going to be more issues crop-up with this setup though. Hope this is the sort of thing you where after.

    • CotswoldPhoto 12:40 pm on October 1, 2015 Permalink | Log in to Reply

      I have to wonder how many sites will NOT be https soon. With Let’s Encrypt nearly ready to launch its free service, due week of 16 November 2015 https://letsencrypt.org/2015/08/07/updated-lets-encrypt-launch-schedule.html https is going to blossom.

      • Ipstenu (Mika Epstein) 2:11 pm on October 1, 2015 Permalink | Log in to Reply

        Please note: LetsEncrypt has pushed back the date at least 3 times already, and they’re not going to be world-wide usable right away. At best we can say that this might be usable for the general public by next summer (2016).

        Also remember getting the cert is problem #1. Problem #2 is the common human ADDING the cert to their servers. Shared hosts may have problems.

        • DS2014 2:00 am on November 17, 2015 Permalink | Log in to Reply

          Good news: I’m excited to let you know that my domain was whitelisted by LetsEncrypt, and I can now use an ACME client to obtain a certificate for it. Running into Problem #2 as I haven’t yet figured out the instructions to actually get the cert and add it. Best I can figure, first I need to install Git. By chance, any idea where I could find out how to do it step-by-step?

    • Gregory Karpinsky (@tivnet) 12:49 pm on October 1, 2015 Permalink | Log in to Reply

      After several unsuccessful attempts to have regular pages HTTP, admin and WooCommerce checkout HTTPS – we gave up and made https the whole site.
      If was really impossible to track all redirects, and also to fight WC bugs with their “force SSL on checkout”.
      From now on, any serious e-commerce site we’ll do on https from the very beginning.

    • Patrick Steil 12:56 pm on October 1, 2015 Permalink | Log in to Reply

      Two points to add here:

      1. Google wants “SSL everywhere” so I think you all shouldn’t worry too much about supporting http on front or back and https on the other. Should be all or nothing.

      2. Every site out there can get a FREE SSL certificate for any domain they want by using CloudFlare as their web site firewall / front end. We are using this on our WPMS and it is working very well!

    • Dave McHale 1:03 pm on October 1, 2015 Permalink | Log in to Reply

      Considering that Symantec recommended Always-On SSL as far back as 2011, I wonder how much longer it will take for most administrators to finally realize that there isn’t a good reason to NOT supply https for all connections. http://www.symantec.com/page.jsp?id=always-on-ssl

      Google and many other vendors have also repeatedly stated that secure connections do not have a measurable performance hit (MaxCDN source: https://www.maxcdn.com/blog/ssl-performance-myth/ ) I just don’t see any valid arguments against it nowadays.

      While WordPress obviously needs to support numerous configurations, it would be nice to see a push towards encouraging “best practices” moving into the future. I think this means “make my whole site use https” is the primary DECISION users should be making in the admin area. Is it turned on, or turned off? Less granular OPTIONS.

    • Bjørn Johansen 1:11 pm on October 1, 2015 Permalink | Log in to Reply

      If you’re behind a reverse proxy that handles, and terminates, HTTPS for you – with the connection between the reverse proxythe result of the protocol between the reverse proxy and WordPress

      If you’re behind a reverse proxy or load balancer that handles and terminates HTTPS for you – like CloudFlare, Sucuri, Big-IP and many more – and the connection between the reverse proxy and WordPress is plain HTTP, WordPress gets confused.

      The reverse proxy should, and usually does, set a HTTP header explaining the situation. I believe the de-facto standard for this is to set the header “X-Forwarded-Proto” to “https” (even though I’ve seen many others variant as well: E.g. the header “WL-Proxy-SSL” to “true” on Big-IP).

      This is an issue that can easily be solved in the web server config, or by adding the following code to wp-config.php:
      if ( isset( $_SERVER[‘HTTP_X_FORWARDED_PROTO’] ) && ‘https’ == $_SERVER[‘HTTP_X_FORWARDED_PROTO’] ) {
      $_SERVER[‘HTTPS’] = ‘on’;

      Maybe this should be considered as an addition to the is_ssl() function?

      • J.D. Grimes 1:37 pm on October 1, 2015 Permalink | Log in to Reply

        Yes, I use CloudFlare on my sites, and having to add this code to wp-config.php is a pain. It would be a nice enhancement if that was handled automatically. The only reason that might not be feasible is that the HTTP_X_FORWARDED_PROTO header, being client-supplied, isn’t trustworthy.

      • Jon Brown 2:29 pm on October 1, 2015 Permalink | Log in to Reply

        This is the unusual case I was going to share. I setup cloudflare + self signed ssl on several of my personal sites, it can work, but can be flaky. I’ve used that same snippet.

        Beyond that it gets weird as well when I want to ssl a few front end form pages (I use the WordPress https plugin).

        Fwiw, I’m more worried at the moment about supporting http2, but this is still important.

      • webaware 11:35 pm on October 1, 2015 Permalink | Log in to Reply

        This can’t be handled “automatically” because that header (and its friends) cannot be trusted; you need to know that a) your website uses such a configuration, and b) which one. See this comment on #31288 for more details.

        At the very least, you need to select this as an option. Pasting that code into wp-config.php is the simplest and fastest fix, or you can use a plugin (there’s a couple, including my SSL Insecure Content Fixer).

    • Ipstenu (Mika Epstein) 1:48 pm on October 1, 2015 Permalink | Log in to Reply

      Multisite – https backend, one site on the network is https front end.

      And Multisite is a good warning spot for HTTPS everywhere since if you have subdomains, you have to either have a multi-subdomain cert or you have to make one per subdomain. And no, HTTPS Everywhere is NOT going to make multi-subdomains right away. They’ve outright said that, so please keep in mind the biggest hurdle with HTTPS will be getting certs installed :/ The common man does not find this easy. Hell, I’m a professional and I hate it.

      As soon as HTTPS everywhere is out, my stand-alone sites will be going to https all around, but Multisite I have to test and figure out.

      • webaware 11:22 pm on October 1, 2015 Permalink | Log in to Reply

        +1 same scenario, plus multi-network multisite. I have CloudFlare providing SSL to the networks with wildcard so it’s not a problem at present, but it’s not ideal and looks unprofessional (have you looked at the certs? nasty!) However, it’s a simple free solution to that problem if CloudFlare is suitable for the network. Individual sites can then be configured with their own certs.

        Talking with clients about SSL certs, single site certs are confusing enough for many. Multisite with subdomains, or even single site with a mobile subdomain, gets messy and/or expensive fast. Throw in some mixed content errors and clients start pulling hair — theirs, yours, passers by.

    • ottok 2:27 pm on October 1, 2015 Permalink | Log in to Reply

      We force admin https for our users always. If the site does not have its own SSL certificate, it will fall back to our generic wildcard certificate, so the whole admin will be at a different domain. This is possible with our custom plugin: https://wordpress.org/plugins/https-domain-alias/ This plugin would solve at least all the current unencrypted password transmissions in all official hosting environments (not self hosted).

    • Brandon Kraft 3:14 pm on October 1, 2015 Permalink | Log in to Reply

      I have a multinetwork multisite site. 99% of domain mapping takes place via separate networks on the install. The rest of the domain mapping is secondary domains that redirect to the primary.

      The main network is a subdomain multisite site with HTTPS on a wildcard cert. None of the other networks have SSL.

      With regard to SSL, the most noticeable pain point is the WP Multi Network plugin has a link to each network’s dashboard that uses `network_admin_url`, which is uses `network_site_url()` with the `admin` flag for scheme, which returns of the HTTP/HTTPS scheme of the *current network* not anything specific to that network.

      I just traced back the code; haven’t opened a ticket yet or explored the best way to check if a particular network should have a particular scheme.

    • Aaron D. Campbell 3:26 pm on October 1, 2015 Permalink | Log in to Reply

      I have a multisite install for some of my personal sites (read that as “I haven’t had time to invest in solving all the idiosyncrasies with the setup”). The plan was to use aarondcampbell.com as the main site with a wildcard SSL. I then wanted to use subdomains over SSL for admin for the sites (geekreprieve.aarondcampbell.com/wp/wp-admin), and mapped domains for the front end (geekreprieve.com).

      I tried to use Mercator, but it ended up still requiring some code to filter ‘upload_dir’ to use the proper front-end URL rather than the current URL when you add media to a post. Ultimately, it was far more difficult to set up than I had expected, and it still has it’s quirks that I just haven’t had time to fix up (like the main site front end being accessible via both http and https).

      @johnbillion I’m happy to give you access to poke around (or give you the code or whatever) if you think it would be helpful.

    • DuzAwe 3:58 pm on October 1, 2015 Permalink | Log in to Reply

      Using LetsEncrypt and cloudflare to provide SSL for live and test sites currently. Nothing fancy

    • xwolf 4:38 pm on October 1, 2015 Permalink | Log in to Reply

      I am hosting a multisite network at our university in which all plain HTTP requests are redirect towards HTTPS. We dont make a mix of HTTP and HTTPS, cause there is no need for HTTP and we made the experience, that on mixed installation several themes and plugins use absolute pathes based on HTTP for generating media files or other things.
      Therfor all multisite instances are SSL only.
      We did this by changing the siteurl and all other settings to SSL.
      For redirection from HTTP to HTTPS we are using Server directions and RewriteRules in .htaccess for the main hostname of the site an its potential cname aliases.

      We set the main university site http://www.fau.de to SSL-only in October 2014. We got no problem report or issue about it. Our website-statistics show that only 0.23 % of 65.827.341 pageviews last month were made bei IE6-Browsers. IE8 got 1.21 %. Thats not enought to take care about this old trash.

      • war59312 11:27 pm on October 1, 2015 Permalink | Log in to Reply

        Should use:

        Content-Security-Policy “upgrade-insecure-requests”

        Force SSL without an insecure redirect needed. And will NOT break http paths. 🙂

    • jancbeck 4:40 pm on October 1, 2015 Permalink | Log in to Reply

      I have a multisite installation where I host sites of my friends. I’m using WPMU domain mapping to give each of them their own non-https domain. It’s a multisite subdirectory setup but the domain mapping works with subdomains too, so it’s kinda mixed (shop.mydomain.com and mydomain.com/shop are both possible).
      My host comes with one free HTTPS domain that I already use for other projects so I installed the whole multisite into a ‘/wp/’ subdirectory. It doesn’t really matter for the frontend URLs, because they are mapped anyways. It’s just so the admin area is available at https://mydomain.com/wp/wp-admin/
      I also use Jetpacks CDN (Photon).

      This runs pretty stable for a about a year now. The most common problem is related to the subdirectory install. However one current problem related to HTTPS is that the “link modal” in the editor will add the https protocol to the content and clicking these links on the non-https frontend will result in a browser error message.

    • dmori 6:05 pm on October 1, 2015 Permalink | Log in to Reply

      I have a situation with http in admin but https on front page login form. I noticed that you cannot load customizer and page if they are different (i.e. http/https mix).

      It would be good if you could make the wp-login page use https only – rather than force all admin. This way logging into site would be secure.

      If there was a way to make have all wp-login pages use https (without users needing an SSL for their site) would be great. I don’t know if this could ever be possible, but this would have an immediately positive effect for all wordpress websites.

      I know this is for top level devlopers – but please remember not all wordpress users have the knowledge and experience you do. We want to make it as accessible to as many people as possible.

    • Mike Nelson 6:11 pm on October 1, 2015 Permalink | Log in to Reply

      We have an event registration plugin, where many users want to only make certain frontend pages (relating to event registration) SSL.
      Specifically, an issue many users encounter is the following: when someone goes to register for an event, one payment option is to go to Paypal and then return to the site’s “Thank You” page. However, on certain browsers when a user is redirected from an SSL Paypal page to a non-SSL “Thank You” page, they will get a scary warning “You are visiting an unencrypted page etc etc… are you sure you want to do this?”.
      Us technical people think “yeah that warning makes sense, they entered their credit card data onto a secure Paypal page, and now they’re returning to a non-secure page on WordPress which doesn’t need to be secure anyways because no sensitive data will be exchanged on this page, so that’s a-ok” but many of our site admins using the plugin don’t understand that, and many of their clients signing up for events don’t understand that either. So the solution most of our plugin users want is to ONLY have the frontend “Thank You” page to be SSL, so that users won’t get the browser warning I just mentioned, but otherwise they want to keep everything else non-SSL.
      We used to recommend the WP HTTPS plugin https://wordpress.org/plugins/wordpress-https/ but it’s recently not getting much support

      • Ipstenu (Mika Epstein) 9:02 pm on October 1, 2015 Permalink | Log in to Reply

        FWIW, WordPress-Https still works. And it’s good for when you have to enforce things like “Damn it, why did you enqueue with http!?!”

        I’ll make a post on make/plugins to remind people though…

    • war59312 11:19 pm on October 1, 2015 Permalink | Log in to Reply

      We force SSL using Strict-Transport-Security and Content-Security-Policy. 100% SSL. A+ Rating on ssllabs.com.

      We follow security guide @ bettercrypto.org as well.

      Along with a few other security methods, such as Content Security Policy (CSP), X-Frame-Options (Frame-Options), X-XSS-Protection, X-Content-Type-Options, X-WebKit-CSP, and X-Permitted-Cross-Domain-Policies.

      Even though we don’t store any Personally identifiable information (PII).

      I want my users, clients, staff, partners, etc. to know they are protected to the very best of my ability.

      Personally, I believe all of these should be the default and required (by LAW). Even more so if you do make use of PII.

      Think it would be wise for WordPress to enable as many as these security settings as possible by default.

      • war59312 11:24 pm on October 1, 2015 Permalink | Log in to Reply

        wordpress.org should make use of all of these features.

        Please enable Strict-Transport-Security and Content-Security-Policy. Takes a few seconds really. 😉

        Your already “forcing” SSL, so how about do it correctly!! Please!!

        • war59312 11:26 pm on October 1, 2015 Permalink | Log in to Reply

          That is:

          Content-Security-Policy “upgrade-insecure-requests”

        • vhmark 1:48 am on October 2, 2015 Permalink | Log in to Reply

          In our case we’re https to the load balancer, http between the LB and the web servers, and the LB does NOT pass through any $_SERVER variables to indicate this.


          • Requests come from the client to the load balancer as https, but are translated to http from the the LB to the web server.
          • Unfortunately the LB does not tell the server it is working over https, so the is_ssl() function returns the wrong result.
          • The practical result is that you can see the site, see the login page, but cannot login.
          • Forcing SSL gets around the problem.

          $_SERVER[‘HTTPS’] = ‘on’;
          $_SERVER[‘SERVER_PORT’] = 443;

      • vhmark 1:42 am on October 2, 2015 Permalink | Log in to Reply

        Our is all https back + front-end mutisite subfolders. The twist is that to cut down on mixed content errors we built a search-replace-on-submit of post+comment content for a whitelist of sites.

    • Henry Wright 8:43 am on October 2, 2015 Permalink | Log in to Reply

      I try to use HTTPS everywhere, always.

    • mydiskdriveonline 4:21 pm on October 2, 2015 Permalink | Log in to Reply

      I have a multisite/subdomian install with a couple mapped domains at Dreamhost.

      I rewrite the root site and mapped domains to https in apache virtual hosts:

      RewriteCond %{HTTP_HOST} =myrootsite.com [NC]
      RewriteRule ^(.*) https://myrootsite.com$1 [R=301,NE]
      RewriteCond %{HTTP_HOST} =mappeddomain.com [NC]
      RewriteRule ^(.*) https://mappeddomain.com$1 [R=301,NE]

      I pull out the ServerAlias’s(mapped domains) that Dreamhost groups in with the “mirrored” rootdomain from and give them each their own so they can each get a cert.

      So my root site uses a regular cert, not a wildcard(cant afford it). mapped domains each have there own cert, the rest of the subdomains do not use https.

      Issues I have are:

      Network admin get_site_url(); for sites defaults to https. Is there a way to force it to use http:// all the time?

      To fix the Networked sites upgrader i use:
      add_filter(‘https_ssl_verify’, ‘__return_false’);
      add_filter(‘https_local_ssl_verify’, ‘__return_false’);

      I also do a search and replace in post_content and make my urls relative instead of absolute (ie. remove https://mysite.com/files/ and replace with /files/) every week or so.

      I know I’m beating a dead horse but I really wish WordPress used relative urls.

    • jwz 5:49 pm on October 2, 2015 Permalink | Log in to Reply

      I recently switched my site to be SSL-only. But before that, I had it configured so that admin URLs were HTTPS and non-admin URLs were forced to be HTTP. I did this because my SSL cert was self-signed, since I was the only one using it. I didn’t want normal blog readers to ever be hit with the “unsigned cert” warning.

      Here’s how I accomplished that:

      RewriteEngine On
      RewriteBase /blog/

      1. These URLs require SSL. All others require non-SSL.

      RewriteRule ^wp-(admin|login|register|signup) – [E=NEEDSSL:1]

      1. This URL can be either SSL or non-SSL. Leave it alone.

      RewriteRule ^wp-admin/admin-ajax\.php$ – [QSA,L]

      1. This Facebook query-string can be either SSL or non-SSL. Leave it alone.

      RewriteCond %{QUERY_STRING} (^xd_receiver) [NC]
      RewriteRule .? – [QSA,L]

      1. NEEDSSL && !SSL: turn it on.

      RewriteCond %{HTTPS} !=on [NC]
      RewriteCond %{ENV:NEEDSSL} =1
      RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]

      1. SSL && !NEEDSSL: turn it off. Except on staging server.

      RewriteCond %{HTTP_HOST} !=staging.jwz.org [NC]
      RewriteCond %{HTTPS} =on [NC]
      RewriteCond %{ENV:NEEDSSL} !=1
      RewriteRule .? http://%{HTTP_HOST}%{REQUEST_URI} [R=301,QSA,L]

    • Jeremy Felt 7:39 pm on October 2, 2015 Permalink | Log in to Reply

      I wrote up some of the workings around our config here: https://jeremyfelt.com/2015/04/24/a-method-for-managing-mixed-httphttps-sites-in-multisite/

      In a nutshell:

      • We get individual certs from InCommon.org as domains are created. We’ll request multi-domain certs when we want to support www as well. Each unique, non-www domain gets some kind of cert.
      • Sites are sometimes briefly accessible via HTTP on the admin and front-end while we wait for a cert request to be fulfilled.
      • Once a cert is available, all admin requests for that domain are forced HTTPS.
      • Recently, we’ve started forcing all front-end requests for new domains to HTTPS, though there are some domains that still support HTTP requests.

      We’re usually on the latest Nginx mainline release and the following config is included for each site: https://github.com/washingtonstateuniversity/WSU-Web-Provisioner/blob/master/provision/salt/config/nginx/wsuwp-ssl-common.conf

      We’ll be switching to HTTP/2 next week. 🙂

    • David Smith 8:57 pm on October 2, 2015 Permalink | Log in to Reply

      Substantially all of our sites are behind an F5 LTM appliance (actually, a cluster of them…) for SSL offloading.

      There’s an iRule (F5’s scripting language) that redirects all port-80/non-SSL requests to port 443, and the sites have https:// in the WordPress database site_url. Couple different wildcard certs for various third-level and fourth-level domain names, nothing too fancy there. The F5 proxies requests to the backend Apache server (or, in my case, to a Varnish cache server, which in turn talks to WordPress), and everything behind the F5 is non-SSL. (Authentication isn’t an issue, it’s handled external to WordPress via Shibboleth, and that IS encrypted even on our internal network.)

      One thing I’ve done, that looks kinda strange but works just fine: Apache is perfectly happy to respond to “SSL” requests over port 80, if you tell it to. You just specify a second ServerName parameter in the configuration, like so:


      ServerName yoursite.name.org
      ServerName https://yoursite.name.org:443
      (whatever other stuff you normally do here)


      If you forget that, or have a sticky keyboard that keeps typing ’43’ instead of ‘443’, you’ll notice immediately because most of your JavaScript and CSS won’t load. 🙂

    • Peter Wilson 9:41 pm on October 4, 2015 Permalink | Log in to Reply

      I’m not sure it’s unusual, my set up is:

      • wildcard certificate
      • admin over https with FORCE_SSL_ADMIN set to true
      • front end is http only, any https requests redirect with a 301 as canonical URLs are (or were) inconsistent

      I started with SSL everywhere but experimented to see if Google preferred performance or SSL, removing the SSL handshake improved my rankings.

    • kirrus 9:28 am on October 5, 2015 Permalink | Log in to Reply

      Typically, HTTP on backend, apache running either mod_php or php-fpm. Varnish performing reverse proxy duties, then HTTPS from an nginx or pound terminator. Slowly becoming more nginx, thanks to requests for HTTP2 / SPDY support.

      So far, it’s proved difficult to get running smoothly with no issues.

    • Primoz Cigler 4:34 pm on October 5, 2015 Permalink | Log in to Reply

      Our production: we have use a cloudflare’s HTTPS in front of our VM with nginx + php-fpm. So while cloudflare actually talks to our server over regular HTTP, the site looks like HTTPS externally.

      In order to make that work properly, we had to set the $_SERVER[‘HTTPS’] = ‘on’; which is probably an ugly hack.

    • pepe 7:40 am on October 6, 2015 Permalink | Log in to Reply

      As for curious SSL configurations and bugs, I’ve got a story to tell:

      A friend and I are running a closed multisite network consisting of unrelated sites (while multisite makes some things easier, for this scenario, I’d opt for independent installations if I had to set it up again today). It’s a subdirectory install mapped completely via the Domain Mapping plugin (i.e. even the admin access is on the mapped domain).

      For a long time, we had served both SSL and non-SSL on the frontend, but forced the backend to always be SSL. That made for some problems, because the post URLs used by the backend were always `https://` (e.g. inserted images, internal links). To overcome this, I added custom code to the theme of my personal blog that filtered the various links to change them to relative URLs (for images) or `http://` (for post URLs). At a first glance, this worked fine.

      However, at first apparently unrelated, I noticed that I couldn’t preview posts anymore, starting around WP 3.9 or 4.0. I assumed some change in core was the reason. Draft preview worked for pages and custom post types, just not for posts. I tracked the error down to an empty user object in core, but couldn’t find a reason for it.

      A few weeks ago, we decided to move to SSL all the time. With this, I removed my filters for the backend URLs and – voilà – post previews do work again. I’m still not sure what the connection is, but I am sure that there is one.

    • Alex Phelps 6:53 am on October 8, 2015 Permalink | Log in to Reply

      We run a closed multisite with ~1000 sites (~1500 domains) where we force all admin to be on the network domain on HTTPS and the mapped domain for the site frontend can be on either HTTP or HTTPS. By default, all of our sites load the frontend on HTTP. For SSL, we normally recommend using Cloudflare’s Free SSL service since it doesnt require a certificate on our servers, we support both Flexibile and Full SSL.

      Technical Setup:

      • Hosted on AWS
      • Varnish + Nginx servers out in front caching all requests with Varnish (port 80) and Nginx to terminate SSL and cache SSL requests.
      • Internal requests between caching servers and WordPress app servers on port 443 (but not strict on the ssl certificate)
      • WordPress App servers running Nginx + HHVM and failover to PHP-FPM.
      • Small internal app to distribute SSL certificates to all caching servers to manage SSL configurations on them.

      We ran into a few issues with the WP Admin bar on the frontend not referencing the correct domain protocol for the backend and also some interesting redirect scenarios when switching from the frontend to the backend with mapped domains.

    • fiskius 10:31 am on October 29, 2015 Permalink | Log in to Reply

      I run a number of wordpress sites on different domains, but only the web host provides a certificate for the original server site, which I use using the WordPress HTTPS plugin (https://wordpress.org/plugins/wordpress-https)

      so, my site: http://www.example.com
      my admin: https://server.host.com/~username/wp-admin/

      This works fine EXCEPT the theme page and live previews are blank, non of them load at all. As soon as I switch the plugin off, they load. So I’d like to get around this bug! Looks like someone had a similar issuer, but not sure how to apply this patch (https://wordpress.org/support/topic/add-theme-issue-with-fix)

      I appreciate people’s comments that everyone should go for fully SSL, but its too costly for me currently. Looks like Letsencrpyt is good, but I doubt I’d be able to run the commands on my web hosts server.

compose new post
next post/next comment
previous post/previous comment
show/hide comments
go to top
go to login
show/hide help
shift + esc
Skip to toolbar