Symlinked Plugins in WordPress 3.9

One of the cool little features included with 3.9 is the ability to symlink plugin directories. While it has been possible to symlink plugins in the past, functions such as plugins_url() return the wrong URL, which causes breakage in most plugins.

In #16953, r27158 and the followup r27999, we corrected this with the help of a new function: wp_register_plugin_realpath(). This function is called automatically during the plugin loading phase, and registers which plugin directories are symlinked, and where they’re symlinked to. This functionality is then used by plugin_basename() (the core of plugins_url(), along with other
functions) to reverse symlinks and find the correct plugin directory.

This enhancement means that you can symlink individual plugin directories, or even the whole plugins directory itself.

For anyone who’d like to use this, keep in mind that there are a few caveats:

  • Single-file plugins are not handled by this code. Any plugins you’d like to symlink must be in subdirectories of the main plugins folder. This restriction is due to the way these paths are registered.

    You can still symlink single-file plugins, however any use of plugin_basename() will be as broken as it was before 3.9. This is not a huge issue, as the main use of this is in plugins_url(), which is not frequently used in single-file plugins.

  • Must-use plugins cannot be symlinked. For the same reasons as single-file plugins, mu-plugins are not handled.

    For anyone using the common pattern of subdirectories within mu-plugins with a common loader file, you can use wp_register_plugin_realpath() directly to ensure that your subdirectories are handled.

    The following example code demonstrates how to use the function:

    <?php
    $plugins = array(
    	'my-mu-plugin/my-mu-plugin.php',
    );
    foreach ( $plugins as $plugin ) {
    	$path = dirname( __FILE__ ) . '/' . $plugin;
    
    	// Add this line to ensure mu-plugins subdirectories can be symlinked
    	wp_register_plugin_realpath( $path );
    
    	include $path;
    }
    

    Hopefully this change is as helpful for you as it was for me! One of the great advantages to this is that plugin developers can keep their plugin separate from their WordPress installation. This is a boon for developers with multiple installs who want to test compatibility; keep in mind that you can symlink the entire plugins directory if you’re testing multiple!

    If you have any questions about this, please leave a comment on this post and we’ll be happy to help you out!

    #3-9, #dev-notes, #plugins, #symlinks

Plupload 2.x in WordPress 3.9

Plupload is the library that powers most of the file upload interfaces in WordPress, and in 3.9 we’ve updated the bundled library to version 2.1.1 (#25663). Here are some of things that have changed, which may affect WordPress plugins and themes.

If you’re using direct references to Plupload’s runtime .js files, such as plupload.html5.js, note that these files are now gone. The following script handles were removed: plupload-html5, plupload-flash, plupload-silverlight and plupload-html4. If you need to enqueue the Plupload library, just use the plupload handle.

If you’re constructing your own Plupload settings array vs. using wp_plupload_default_settings() and/or the _wpPluploadSettings object, note that some of the arguments have changed, most notably:

  • flash_swf_url should point to the new Moxie.swf file (See update)
  • Similarly, silverlight_xap_url should use the new Moxie.xap (See update)
  • The multiple_queues argument is no longer used
  • The max_file_size key has been moved to the filters array
  • The filters array now supports multiple keys, and the list of file types array has been moved to its mime_types key

To illustrate that with code:

$settings = array(
    // ...
    'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), // Unchanged
    'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), // Unchanged
    'filters' => array( 
        'max_file_size' => $max_upload_size . 'b', 
    ),
);

Plupload version 2.1.1 has also added some exciting new options and methods, which you can find in the updated documentation.

As a result of this update in WordPress 3.9 we were able to add drag and drop upload support directly to our TinyMCE editor (#19845), and we’ve also added a new boolean flag to wp_editor(), which you can use to enable drag and drop upload support in your own instance of the editor (#27465):

wp_editor( '', 'my-editor', array(
    // ...
    'drag_drop_upload' => true,
) );

If you run into any problems with this update in 3.9, please leave a comment on this post and we’ll be happy to help you out!

Update: I opened #27763 to address some of the compatibility issues around the update. We might be renaming the swf/xap files for backwards compatibility.

Update, April 13: The original swf/xap filenames were restored.

#3-9, #dev-notes, #editor, #tinymce

Last Week in WordPress Core

Howdy everyone! This is Last Week in WordPress Core for the week of March 31-April 7. I’m including all of the commits up to RC1 this week, which was released yesterday. Things are looking good, with very few remaining tickets open.

3.8.2 and 3.7.2 were also released with security fixes, and automatic updates are rolling out.

Developers, please test with your plugins and themes and let us know if you find issues.

TinyMCE: As a quick note, since I’ve seen this brought up in the forums — in this release, TinyMCE no longer uses wpdialogs. This means it now needs to be enqueued by any plugin that wants to use it. As of [28024], there is a clarified warning that will appear in the JavaScript console if you attempt to use it, and it’s not enqueued.

IE8 & wpview: Due to IE7/8 compat being necessary in TinyMCE (to resolve caret issues), IE8 and wpview are not currently the best of friends. Post RC1, fixes landed for #27546 that make wpviews degrade more gracefully.

Media:

  • Playlists: Make elements in playlists responsive and fix playlist advancement on mobile. [27894] [27895] #27625
  • Playlists: Set preload='none' for the empty <audio|video> tag. [27974] #26779
  • Playlists: Make tracks keyboard-accessible. [28023] #27644
  • A/V Shortcodes: Remove support for a caption in audio and video shortcodes. This was part of a UX iteration for the related MCE views, but these captions have since been excluded. See [27640]. [27979] #27320
  • Edit Image Modal: Make the calculation of the aspect ratio more robust. [27942] [27948] #27366
  • Do not show featured images for image attachments; remove post_supports_thumbnails() and theme_supports_thumbnails() for now. [28051] #27673

HTML5 Galleries:

  • Remove <br> elements for HTML5 galleries; see #26697. [27914] #27637
  • Twenty Thirteen and Fourteen: Update styles to support the new HTML5 line-break-less galleries. [27926] #27637

Admin:

Theme Installer:

Widgets

  • Trigger jQuery events for widget updates. widget-added when a widget is added to a sidebar and widget-updated/widget-synced for widget soft/hard updates. [27909] [27969] #19675; #27491
  • In WP_Widget, introduce is_preview() method to allow widgets to check to see if they’re currently being previewed via the customizer. [27966] #27538
  • Widget Customizer: Improve compatibility with plugin custom scripts and styles for widgets. [27907] #27619
  • Widget Customizer: Rename inject_preview_css to print_preview_css. [27968] #27534
  • Widget Customizer: Use postMessage to highlight widgets in preview or sections/controls in Customizer. [27892] [27893] #27622
  • Widget Customizer: Refactor and clean up WidgetCustomizer as wp.customize.Widgets, and make available widgets panel a Backbone view. [27985] [27986] [27988] [27995] [28034] #27690

TinyMCE

  • Update TinyMCE to 4.0.21. [27897] #24067
  • Image Details Modal Improve look-and-feel, and add a Custom Size option to the size drop-down that reveals fields for soft-resizing the inserted image. [27918] #27366
  • Image Details Modal: Move all advanced options under a single toggle, bring back the field for CSS Class, and optimize CSS for responsive layout. [27898] #27366
  • Drag and Drop Uploading: Add new argument to wp_editor() to enable. [27901] #27465
  • Gallery Views: Avoid JS errors when image attachments lack metadata. [28008] #27691
  • Return to loading /langs/[locale].js and /langs/[locale]_dlg.js from PHP to prevent errors with missing translation files when requireLangPack() is used without its second argument. Back to using ISO 639-1 (two letter) locales. #24067; [27922] #27610
  • Clarify error when wpdialogs is not enqueued. Add wp_enqueue_editor action fired when scripts and styles for the editor are being enqueued. [28024] #16284
  • Update translatable strings. [27927] #27453, #24067
  • Tighten up toolbar and tab styles. [27978] [27983] #27279
  • Expose toolbar keyboard shortcut in Help documentation for TinyMCE, and clean up TinyMCE help dialog, removing duplicated text and leaving only Keyboard Shortcuts. [28029] #27024; [28032] #27100

Database:

  • Fall back from ext/mysqli to ext/mysql if the connection fails. This allows us to avoid breaking a site that works under ext/mysql but is misconfigured for ext/mysqli. [27935] #21663
  • Add $allow_bail argument to wpdb::check_connection() to match the connect method. [27925] #27240
  • Don’t pass a second argument to mysqli_fetch_field(). [28002] #27693
  • Rename USE_EXT_MYSQL to WP_USE_EXT_MYSQL. [28022] #21663

Internals:

  • Updates: Record Plugin & Theme update statistics like we do for Core updates. [27905] [27906] #27633
  • Pingbacks: Forward pingback IP during verification. [27872] #27613
  • Dashicons: [27989] [28005] [28013] #26936
    • New icons: .dashicons-external, .dashicons-editor-contract and .dashicons-universal-access-alt.
    • Updated icons: .dashicons-code, .dashicons-universal-access, .dashicons-arrow-x-alt and .dashicons-arrow-x-alt2.
    • Restores .dashicons-post-trash as an alias for .dashicons-trash, which is the new one.
    • Use new icons in Widget Customizer.
  • Don’t try to resolve symlinks for single-file plugins. plugins_url() should not be used in this context anyway. [27999] #16953
  • Remove old links_recently_updated_* DB options that never had a UI. [27916] #27649
  • Deprecate wpmu_current_site(). [28009] #27702

Many thanks to @adamsilverstein, @andykeith, @avryl, @azaozz, @bramd, @chiragswadia, @davidmarichal, @dd32, @dpe415, @duck_, @DrewAPicture, @DrProtocols, @ehg, @eightface, @empireoflight, @gcorne, @helen, @jackreichert, @jdgrimes, @jeremyfelt, @jesin, @joedolson, @johnbillion, @jorbin, @jond3r, @kovshenin, @kpdesign, @leewillis77, @markjaquith, @matveb, @mcsf, @melchoyce, @michael-arestad, @nacin, @Nessworthy, @norcross, @obenland, @ocean90, @pento, @plocha, @rachelbaker, @rmccue, @sdasse, @SergeyBiryukov, @siobhan, @sonjanyc, @tellyworth, Tom Adams, @vancoder, @westonruter, and @wonderboymusic for their help this week!

For the complete list of commits to trunk, check out the log on Trac. Since we’re getting very close to release, the best way to help is to test! Let us know if you run into problems in the Alpha/Beta forums or on trac.

#3-9, #week-in-core

MySQL in WordPress 3.9

In WordPress 3.9, we added an extra layer to WPDB, causing it to switch to using the mysqli PHP library, when using PHP 5.5 or higher.

For plugin developers, this means that you absolutely shouldn’t be using PHP’s mysql_*() functions any more – you can use the equivalent WPDB functions instead.

mysql_query()

There are a few different options for replacing the query functions, depending on what you want to do:

As a drop in replacement to run a query that you don’t expect a return value from (i.e., an INSERT, UPDATE or DELETE query), use $wpdb->query(). This will always return the number of rows effected by the query.

Alternatively, $wpdb->insert(), $wpdb->update(), $wpdb->delete() and $wpdb->replace() are all helper functions that will automatically escape your data, then generate and run the queries for you. Ideally, you should never need to write an SQL statement!

mysql_fetch_*()

If you have a SELECT query, for which you’d normally do a mysql_query() followed by a mysql_fetch_*(), WPDB lets you combine this into one function call.

To get all of the results from a query that returns more than one row, use $wpdb->get_results() to return an array of objects containing your data.

There are also some shortcut functions for common usage:

If you only need a single row from your query, $wpdb->get_row() will return just the data object from that row.

If you only need a single column from a single row, $wpdb->get_var() will return only that field.

And if you need a single column, $wpdb->get_col() will return an array of all the data from that column.

mysql_real_escape_string()

For a drop in replacement, you can use esc_sql(). That said, we strongly recommend switching to $wpdb->prepare(), instead. We have a pretty thorough tutorial available for $wpdb->prepare().

mysql_insert_id()

If you need to get the Insert ID from the last query, $wpdb->insert_id is where you need to look.

Updating your plugin to use WPDB will also future proof it for if we make changes to how WordPress connects to the database – we’ll always maintain backwards compatibility with the current WPDB interface.

For more reading, check the WPDB Codex page, and #21663.

If you’re using MySQL in a way that I haven’t covered here, please post it in the comments, we’d be happy to help you out!

#3-9, #database, #dev-notes, #mysql, #wpdb

Last Weeks in WordPress Core

Hi! This is a late Last Week in WordPress Core for the two weeks of March 17-30. Lots going on as we approach RC.

Beta 3 is out, and you can check out the release post here. There are a few big things that have landed that are included. In particular, please test video and audio playlists by uploading more than one file of either, and check to see if you see any oddities in quote formatting, as much of wptexturize() was revamped.

Admin:

  • Theme Installer: Restore the feature filter, improve responsiveness, update router, make ‘Upload Theme’ button more consistent with the admin, and avoid theme-count causing filters to jump. [27636] #27055
  • Theme Installer: Bring keyboard accessibility to the theme install screen and theme action buttons. [27804] #27521
  • Dashboard: Restore the update message in the dashboard that was removed in 3.8. [27711] #26664
  • Distraction Free Writing: Allow the fullscreen editor’s content area to be responsive. [27821] #27569
  • Accessibility: Better focus styles for form elements in the admin. [27741] #27173

Widget Customizer:

  • Restore highlighting of widgets in preview. [27584] [27702] #27358
  • Use WP_Error for errors, and add handling for when user is missing cap to change widgets or is logged out. [27652] #27419

Themes:

  • Introduce HTML5 caption support: When supported by a theme via add_theme_support( 'html5', 'caption' ), use figure and figcaption instead of div and p. With HTML5 captions, no longer include extra 10 pixels within inline styles. img_caption_shortcode_width is skipped when the theme supports HTML5 captions. [27668] #26642 #9066
  • On attachment pages for audio and video, add support for players. [27622] #27243
  • Default Themes: Improve accessibility for keyboard and voice-over interactions. [27594] #27147 [27606] [27607] #24839
  • Default Themes: Update editor styles for A/V and Galleries. [27638] [27637] [27641] #27462
  • Default Themes: Enable thumbnail support for attachment:audio and attachment:video. Check for theme OR post type support when determining whether to enable Featured Image UI in the admin. [27657] #27460

Media

  • There is no more video-playlist shortcode. To use video, it is now [playlist type='video' ...]. Core playlist styles removed; the style attribute is still supported, defaulting to light. [27785] [27812] #27552
  • Only enqueue the media modal image editor within the admin. [27625] #21811
  • Support a caption attribute for audio and video shortcodes. [27640] #27320
  • Create a new file, media-audiovideo.js, to house all of the audio and video JS code in core, and improve UX. [27608] [27631] #27437
  • With Plupload, switch to urlstream upload method when the flash runtime is used in non IE browsers. This ensures cookies are sent but limits the maximum file size that flash can handle. By default only IE9 and older use flash, so it would only affect things if a plugin disables the html5 runtime. [27662]
  • Provide a metabox to edit audio metadata (initially from ID3) on the “Edit Media” page. [27862] [27862] [27864] [27869] #27574.

TinyMCE:

  • Update TinyMCE to 4.0.20. [27603] #24067
  • Update tests. It’s now possible to run most TinyMCE tests directly from the cli using PhantomJS. [27679] [27680] #27014
  • Playlist Preview: Support playlist views in TinyMCE. [27640] #27320
  • Edit Image Modal: Bring back some of the advanced settings. [27797] #27366

Internals

  • Masonry: Update Masonry v2/v3 shim from upstream. [27779] [27780] [27781] #27510
  • Texturize: Massive performance improvements (~600% faster); better handling of braces, nbsp, double, and weird spaces; 136 new unit tests. [27839] [27844] #22692
  • Cookie Session Checks:: Only show test cookie warnings on submit as caching/proxies may intercept the test cookie for GET requests. Introduce a new string for when headers are sent and link them to a new Cookies page on the codex. [27859] #27373
  • Object Cache:: Introduce pre_update_option filter, available in update_option(). Allows filtering of any option before its value is (maybe) serialized and updated. [27815] #27504
  • wpautop: Remove select and input from wpautop()‘s HTML blocks list. [27761] #22230
  • Heartbeat: Hooks should always receive unslashed data. This affects the privileged hooks; the unprivileged hooks already did so. [27576] #27260
  • Customizer: Use esc_url_raw to escape customizer URL settings to prevent double encoding. [27574] #26569
  • Template: Encode spaces in get_template_directory_uri() and get_stylesheet_directory_uri(). [27710] #21969
  • Filesystem: Fix getchmod() for direct and ssh2 transports, for directories. [27566] #26598
  • Text/i18n Cleanup: Many text changes and updates. Check out all of them in the full log on Trac.
  • i18n: In is_serialized(), use substr() rather than array access, for compatibility with multibyte overloading. [27565] #18007
  • Postmeta: Return false from metadata_exists() if the get_$type_metadata filter returns a false value. [27562] #22746
  • Pagination: Introduce before_page_number and after_page_number arguments for paginate_links(). [27600] #24709
  • E-mail: Always decode special characters for email subjects. [27801] #25346
  • WP Class: Add post_parent to the private query vars list. Fixes detached media queries. [27782] #27532.
  • Post: Use wp_parse_id_list() when parsing exclude_tree in get_pages(). Ensure a URL string, array with string as value, and array with array as value for exclude_tree can be used to specify multiple IDs. [27767] #9153

WP_Query

Multisite:

  • Introduce a ms_site_not_found filter to replace NOBLOGREDIRECT. Bail if there’s no site. [27663] #21143; #27003
  • In multisite load, cache the main site lookup query. [27664] #27003
  • Ensure the $path is trailing-slashed in domain_exists(). [27717] #20589

For the complete list of commits to trunk, check out the log on Trac. Interested in helping close out the release? Write or test a patch for 3.9.

Thanks to @adamsilverstein, @adelval, @afercia, @aliso, @aubreypwd, @avryl, @azaozz, @barry, @bcworkz, @celloexpressions, @cgaffga, @Chouby, @chriseverson, @chrisguitarguy, @cramdesign, @danielbachhuber, @dannydehaan, @DavidAnderson, @DrewAPicture, @drozdz, @dustyf, @eatingrules, @ehg, @eightface, @ejdanderson, @eliorivero, @empireoflight, @ericlewis, @ericmann, @ethitter, @fahmiadib, @frank-klein, @gcorne, @grahamarmfield, @GregLone, @hakre, @helen, @jackreichert, @janw.oostendorp, @jartes, @jbkkd, @jdgrimes, @jeremyfelt, @joedolson, @johnbillion, @jorbin, @kawauso, @kovshenin, @kpdesign, @kwight, @lancewillett, @lkwdwrd, @markjaquith, @mattheu, @mattonomics, @matveb, @mauryaratan, @mcsf, @melchoyce, @MikeHansenMe, @miqrogroove, @mordauk, @nacin, @Nao, @Nessworthy, @nofearinc, @obenland, @ocean90, @paulwilde, @pavelevap, @pbearne, @philiparthurmoore, @prettyboymp, @raamdev, @rachelbaker, @ramonchiara, @roothorick, @ryelle, @sabreuse, @sandyr, @SergeyBiryukov, @shahpranaf, @siobhyb, @spmlucas, @stevenkword, @tbrams, @tlovett1, @TobiasBg, @tomauger, @Toru, @vanillalounge, @westonruter, @wonderboymusic, @xknown, and @yoavf for their efforts!

#3-9, #week-in-core

Agenda for the April 2 meeting

Please suggest items for the April 2 developer meeting. So far:

  • The wpdialog TinyMCE plugin and the enqueuing of jQuery UI Dialog ( #16284)
  • Transient/cache suspensions during widget previews ( #27538)
  • Any other show-stoppers or critical issues
  • Timing of Release Candidate 1
  • April 16 is our target release date of 3.9

#3-9, #agenda

Masonry in WordPress 3.9

If you use Masonry in your themes or plugins, here’s what you should know about the 3.9 update.

In WordPress 3.9 we’ve updated Masonry to v3, which no longer requires jQuery. The new script handle is masonry. Some of you have been using that very same handle with your own bundled copies of jQuery Masonry v2, this has potential to break in fairly rare cases:

  • You’re using Masonry v2 options or methods that are deprecated in v3
  • You’re dumping your Masonry init code inside the bundled library itself
  • You’re using v2 class names in CSS such as .masonry-brick and .masonry
  • You’re relying on a declared jquery dependency for masonry, even if you bundled v3

The older jquery-masonry handle is now the official v2/v3 shim, which provides (some) backwards compatible options, methods and classes. If you were using core’s jquery-masonry in your theme or plugin, you should be fine. It’s also the handle you’ll want to use to be compatible with both 3.8 and 3.9+. A short Masonry v2 to v3 upgrade guide could be found here.

Whatever you’re doing with Masonry in WordPress, we urge you to test your themes and plugins now. Get the latest beta and head over to #27510 to let us know if you’ve stumbled across any compatibility issues.

#3-9, #dev-notes, #themes

TinyMCE 4.0 requires text/css for editor style files

As of TinyMCE 4.0, the visual editor iframe now has an HTML5 document type (<!DOCTYPE html>). In this scenario, CSS files must be served with the text/css content type. A server will serve a *.css file with the proper content type, but if you’re using a PHP file for an editor style file, you need to be the one to do it. It’s as simple as leading with:

<?php
header( 'Content-Type: text/css; charset=UTF-8' );

So if you’re doing something particularly crazy with the editor and your styles aren’t loading in WordPress 3.9, you may just need a content type. Also, Chrome (and probably other browsers) throw a console warning when this happens.

(via #27288)

#3-9, #dev-notes, #editor, #tinymce

Last Week in WordPress Core

Hey Everyone! This is Last Week in WordPress Core for the week of March 10–16. It’s been a busy week after Beta 1. Here are some highlights from the week:

  • Appearance: Bring the theme browsing experience from 3.8 to the theme installer. [27499] #27055
  • Customizer: Add header image uploads with cropping to the customizer. [27497] #21785
  • Plugin Management: Restyle the plugin install details modal to match the rest of the admin. [27559] #26952
  • Edit Post: Correct the “View Post” button link when changing a post slug. [27508] #16477
  • Admin Colors: Revert [27203], fix color scheme stylesheets. Restores [27111]. [27515] #27175; see #20729.
  • Editor: figcaption should not be treated as a block-level element by wpautop(). [27527] #25646
  • TinyMCE: add internal command and shortcut (Alt+Shift+X) for toggling <code>. Define a button that can be added to any toolbar as wp_code. [27545] #6331
  • Permalink Settings: Don’t show “update your .htaccess now” if nothing needs to change. [27549] #19268.
  • Query: In WP_Query::get_queried_object(), account for pre_get_posts by checking for tag when tag_id isn’t present. Tags still need to be rolled up into tax_query.  [27511] #27362
  • Filesystem: Update request_filesystem_credentials() to handle the correct ssh value of FS_METHOD. [27546] #27265

Widget Customizer:

  • Move widget area sections to bottom, as a theme can have a lot of widget areas and we don’t want to bury other sections. [27541] #27401
  • Introduce a customizer processing state to prevent saves while updates are occurring. [27540] #27390
  • Make temp hooks permanent. New hooks are: dynamic_sidebar_before, dynamic_sidebar_after, dynamic_sidebar_has_widgets and is_active_sidebar. [27543] #25368

Media:

  • Start embedding functional audio/video players in the editor, instead of placeholders. [27528] was reverted in [27530] but added back this week in [27615]. Whitelist media types by browser. [27539] [27542]. See also [27534] [27535] [27536] [27537] [27538] and others. Everything is contained in #27389.
  • The Image Editor should apply changes to custom image sizes by checking registered image sizes. [27522] #19889
  • Remove Qik from the oEmbed provider list as it’s shutting down. [27526] #27302
  • Smooth out some display and race condition issues with the media modal loading spinner. [27516] #24859

XML-RPC:

  • Avoid saving slashed data in XML-RPC’s wp.setOptions. [27551] #22936
  • Allow query strings for servers in IXR_Client and WP_HTTP_IXR_Client. [27552] #26947
  • Include sticky in the struct returned from metaWeblog.getRecentPosts. Using wp.getPosts is preferred and non-WP XML-RPC APIs are no longer actively maintained. This is simply for parity with existing MW methods. [27553] #26679
  • In wp.editPost, Remove all terms in a taxonomy when an empty array is explicitly passed. [27554] #26686

For the complete list of commits to trunk, check out the log on Trac.

Interested in joining in? Write or test a patch for 3.9. The goals for this week — besides releasing Beta 2 — are two-fold:

Thanks to @aubreypwd, @avryl, @azaozz, @bravokeyl, @cfinke, @danielbachhuber, @DrewAPicture, @ehg, @enej, @ericmann, @gcorne, @helen, @jayjdk, @jnielsendotnet, @johnpbloch, @joostdevalk, @jstraitiff, @JustinSainton, @kadamwhite, @klihelp, @kovshenin, @ldebrouwer, @mattonomics, @matveb, @mauryaratan, @maxcutler, @mcsf, @MikeHansenMe, @nacin, @nendeb55, @ocean90, @oso96_2000, @Otto42, @paulwilde, @pento, @rodrigosprimo, @SergeyBiryukov, @soulseekah, @tlovett1, @westonruter, @wonderboymusic, and @wpsmith for their help this week!

#3-9, #week-in-core

Last Week in WordPress Core

Hi there! Welcome to Last Week in WordPress Core for the week of March 3–9. By now, you’ve heard that WordPress 3.9 Beta 1 is available! Thank you for your hard work this last week. Now we’re done adding new enhancements, and on to bugs. Your help is appreciated as we continue to test and squash bugs on the way to a stable RC.

There are a couple important things that landed on Monday that are not covered in this post, but shipped in beta. Namely, please test the Theme Install screen refresh and the ability to crop headers from within the Customizer.

Admin:

  • Widgets: Add widget management to the customizer. This brings in the Widget Customizer plugin. [27419] #27112
  • Admin Menu: Introduce a .dashicons-before CSS class and use it in the admin menu. Lets you use a Dashicon before an element without copying the entire .dashicons styling to your :before styling. [27418] [27425] [27444] [27482] #26630
  • Editor: Show “View Post” for any post the author can read. This expands it to private posts and matches the logic in the toolbar. [27483] #27059

Media:

  • First pass at bringing the Image Editor into the media modal. Please test me! [27445] #21811
  • First pass adding a loading indicator to the Media Library. [27438] #24859
  • Allow $crop in add_image_size() and set_post_thumbnail_size() to receive crop anchors (top, left, right, bottom, center). [27472] #19393.
  • Add subtitle support to Video editing in the Media Modal. [27481] #27016
  • Do not output default gallery styles if the theme has opted into HTML5 galleries. [27396] #27045; see #26697
  • Add a class attribute to the caption shortcode to allow additional classes to be specified. [27404] #25295
  • Add playlist_styles and wp_playlist_scripts filters to allow users to roll their own playlist themes. [27486] #26631 & [27488] #26631

TinyMCE:

  • Update TinyMCE to 4.0.18. [27387] #24067
  • Add TinyMCE placeholders for audio and video shortcodes and provide a UI to both edit shortcode attributes and replace the src media file in an audio or video shortcode. Also, a flurry of improvements and fixes to them, visible in the full changelog. [27411] #27016
  • Add a Ctrl+K shortcut to open the linking dialog, which is the “de-facto standard”. [27449] #27305
  • Add the <hr> plugin and button to the toolbar. [27428] #27159
  • With drag-and-drop uploading, support multiple editor instances, limit to IE10+, and other small fixes. [27378] [27372] [27464] #19845
  • When parsing a caption shortcode, recreate missing width attributes using the image tag’s width. [27426] #23103
  • Restore the “link” button state to disabled by default and enabled when text or image is selected. Remove the (recently added) default link plugin; not needed. [27447] #27309

Templates:

  • Add has-post-thumbnail as a post class. [27429] #18804
  • Rename the new page_templates filter to theme_page_templates, and pass it a post object for proper context. [27470] [27471] #13265
  • Introduce get_the_permalink() as an alias for get_permalink(). This better aligns it with other the_* and get_the_* function pairs. [27409] #24164
  • Let get_the_date() accept a post object. [27380] #13771
  • Add the ability to short-circuit wp_nav_menu() via the pre_wp_nav_menu hook. [27386] #23627
  • Better plural handling for labels in wp_generate_tag_cloud() / wp_tag_cloud(). [27376] #27262, see #7989, #14424

Multisite:

  • Incremental improvements and bug fixes with the multisite load process. Please test your networks! [27406] [27439] [27407] #27003
  • Fix bulk activation of network-only plugins. [27413] #26487

Query:

  • Add has_password and post_password query variables to WP_Query. has_password true means posts with passwords, false means posts without. post_password can query for posts with a particular password. [27395] #20308
  • Allow a posts_per_rss query variable to be set to override the posts_per_rss option. [27456] [27455] #25380
  • Allow get_page_by_path() and get_page_by_title() to accept an array of post types. [27423] #24763

Internals:

  • Allow for custom authentication handlers for all requests. Turn the logic used by wp_get_current_user() into a determine_current_user filter. [27484] #26706
  • Allow the role attribute in kses for all elements. [27388] #24098
  • Add a pre_set_theme_mod_$name filter to set_theme_mod(), modeled after pre_update_option_$option in update_option(). [27393] [27402] #14721.
  • Improve HHVM compatibility by eliminating some of our last remaining create_function() calls and making OBJECT a case sensitive constant. [27373] [27374] [27465] #14424 [27377] #27231
  • Pass $reassign parameter to delete_user and deleted_user actions. [27462] [27466] #23057
  • Bail early from shortcode functions if no delimiter is present. It’s the little things; performance results on-ticket. [27394] #23855
  • Update PHPMailer to 5.2.7 from 5.2.4. Includes two trivial modifications for WordPress (no impact to plugin developers); see the commit message. [27385] #25560
  • Use SSL when linking to WordPress.org. [27469] #27115

For the complete list of commits to trunk, check out the log on Trac. Interested in joining in? Write or test a patch for 3.9.

Thanks to @adamsilverstein, @akeda, @avryl, @bassgang, @bigdawggi, @bobbravo2, @bpetty, @bradt, @celloexpressions, @coffee2code, @danielbachhuber, @dd32, @DJPaul, @DrewAPicture, @empireoflight, @ericlewis, @ericmann, @frank-klein, @gcorne, @genkisan, @gradyetc, @hakre, @Hanni, @Jayjdk, @jenmylo, @johnregan3, @jorbin, @JoshuaAbenazer, @kadamwhite, @kasparsd, @Kopepasah, @kovshenin, @kpdesign, @lpointet, @markjaquith, @mcadwell, @melchoyce, @michael-arestad, @mikecorkum, @mordauk, @nacin, @obenland, @Otto42, @pavelevap, @Rarst, @rhyswynne, @ricardocorreia, @rmccue, @robmiller, @seanchayes, @SergeyBiryukov, @shaunandrews, @simonwheatley, @sirzooro, @tanner-m, @TobiasBg, @tomauger, @topher1kenobe, @topquarky, @toszcze, @westonruter, @wokamoto, @wonderboymusic, @zbtirrell, and @zodiac1978 for their efforts this week!

#3-9, #week-in-core