Make WordPress Core

Tagged: 3.5-field-guide Toggle Comment Threads | Keyboard Shortcuts

  • Helen Hou-Sandi 11:55 pm on December 12, 2012 Permalink
    Tags: 3.5-field-guide   

    Attachment editing: now with full post edit UI! 

    While perhaps not often used, the same interface in the now-old upload/insert media modal was available as an admin screen by going to the Media Library and then clicking on Edit for an item. With the move away from that interface in the modal, we thought it’d be a good time to treat attachments as what they are: a post type. Some changes users will see are the ability to turn on discussion/comment meta boxes as well as being able to edit the slug for attached items; that is, items that have a post_parent.

    Edit Media Screen in 3.5

    What this means for developers is that you can now do familiar things like adding meta boxes or perhaps even utilize those fancy new edit screen hooks for editing media library items. There’s also the attachment_submitbox_misc_actions hook for the Publish meta box. Taxonomies will now come with their native meta box UIs if you so choose – for built-in taxonomies, it’s as easy as:

    register_taxonomy_for_object_type( 'category', 'attachment' );

    Seriously: that’s it. The screenshot above shows just that.

    One thing you may notice is that what’s known as the “Description”, which in reality is the post_content, uses a textarea with quicktags enabled. The decision was made to go this route in core for a couple reasons: to keep it lightweight while still making it a bit better (after all, it was just a plain textarea before), and to prevent attachment-ception as a default possibility. If you as a developer want to enable attachments in your attachments, have at it.

    attachment_fields_to_edit comes with backwards compatibility and will continue to work – fields added that way will appear below the Description field. However, you may very well find that it makes sense to change the placement of those fields on this screen for sensible editing and structure. There are JS methods for adding to the modal moving forward, but while those guides are worked on and you’ve got some already-existing things to support, the following will help you through.

    Previously, you may have done something like checking the IFRAME_REQUEST constant to determine whether or not something should show on the attachment edit screen or in the Thickbox. Since the new media modal is not an iframe, that won’t work anymore. To help with that, we’ve added some new arguments, or flags if you will, to allow you to specify whether or not an added field should appear on this edit screen or in the new media modal: #22759.

    This example shows how to add a field that appears in the modal but not in the edit screen. For the other way around, you would set show_in_modal to false. Both args default to true, and there’s no real reason to set both to false, so you’ll only use one or no flags for a given field.

    add_filter( 'attachment_fields_to_edit', 'myprefix_attachment_fields_to_edit', 10, 2 );
    function myprefix_attachment_fields_to_edit( $fields, $post ) {
            $fields['test-media-item'] = array(
                    'label' => 'More Media Management',
                    'input' => 'html',
                    'html' => '<a href="#">Link One</a>
    <a href="#">Link Two</a>',
                    'show_in_edit' => false,
            return $fields;

    For the low-down on how this came together over the course of 3.5, check out #21391. The possibilities are exciting! Document/asset management with taxonomies, adding that method for detaching or reassigning the post parent for a media item – what else might you come up with?

  • Andrew Nacin 6:14 am on December 12, 2012 Permalink
    Tags: , 3.5-field-guide, sql,   

    PHP Warning: Missing argument 2 for wpdb::prepare() 

    Hello plugin or theme author! You possibly found this post after searching the Internet for the error above: “PHP Warning: Missing argument 2 for wpdb::prepare().”

    So, this is a new warning in 3.5. No sites are broken, everything is fine as before. But, this is indeed something you need to look at, because you may be exposing your users to a possible SQL injection vulnerability. Now that’s no fun!

    First, if you’re a user and you want to get rid of these errors, you should turn off the displaying of errors in PHP. There are many ways to do this, such as in php.ini, .htaccess, etc. For this, you can just put this in wp-config.php. (Note that hiding errors on production sites is good practice anyway.)

    <a href='https://profiles.wordpress.org/ini_set' class='mention'>@ini_set</a>('display_errors', 0);

    If you’re a user, you can stop here. (If you need more help, please don’t comment here, try the helpful Support Forums.) Just be sure to send a link to this post to the developer of the theme or plugin referenced in the error.

    Now, developers: Here’s how $wpdb->prepare() is supposed to work:

    $wpdb->prepare( "SELECT * FROM table WHERE ID = %d AND name = %s", $id, $name );

    See how $id โ€” an integer, presumably โ€” was passed as the second argument? That corresponds to the first placeholder, %d. Then, $name (a string) was passed as the third argument, thus the second placeholder, %s. This makes sure your query is safe, and prevents something like little bobby tables. (Note: the comic is wrong, don’t sanitize โ€” always prepare your queries.)

    The problem is, a number of people were calling $wpdb->prepare() with only one argument, like so:

    $wpdb->prepare( "SELECT COUNT(*) FROM table" );

    See, there’s no parameter (%d, %s, or for floats, %f) in this query. This happens to work fine, but the prepare call isn’t doing anything. You should instead the query directly, as there are no inputs.

    But here’s where the problem lies:

    $wpdb->prepare( "SELECT * FROM table WHERE id = $id" );

    See the problem? That query isn’t secure! You may think you are “preparing” this query, but you’re not โ€” you’re passing $id directly into the query, unprepared. And this, right here, is why $wpdb->prepare() now issues a warning if it isn’t called with more than one argument. Because you can’t prepare a query without more than one argument. Here’s a correct example:

    $wpdb->prepare( "SELECT * FROM table WHERE id = %d", $id );

    This wasn’t a decision done lightly. We don’t like shoving PHP warnings into the faces of users and developers. But given the potential security risks, we wanted everyone to immediately look at how they are running queries. And, of course, always prepare them properly.

    For more: wpdb Codex reference, #22262, and [22429].

    • Samuel Wood (Otto) 6:17 am on December 12, 2012 Permalink | Log in to Reply

      Dangit. Stole my ottopress post for tomorrow. Now I have to come up with fresh, original content. ๐Ÿ˜‰

    • Emil Uzelac 6:23 am on December 12, 2012 Permalink | Log in to Reply

      Good one, just submitted this https://wordpress.org/support/topic/warning-missing-argument-2-for-wpdbprepare-3 15 minutes ago. Let me link to this post as well, to help author out :)


    • chacha102 6:30 am on December 12, 2012 Permalink | Log in to Reply

      Because you canโ€™t prepare a query with more than one argument. Hereโ€™s a correct example:

      I think you mean, you can’t prepare a query without more than one argument.

    • Brian Layman 6:56 am on December 12, 2012 Permalink | Log in to Reply

      Interesting.. So the rule of “Always use prepare on queries” is simply wrong.
      It should be “Always use prepare on queries that built with variable arguments.”

      I’d always thought it did further sanitization of the query string itself, but I suppose that would be really hard to do without blocking some valid query people would inevitably want.

      • Samuel Wood (Otto) 6:58 am on December 12, 2012 Permalink | Log in to Reply

        The *vast* majority of problems with this I’ve seen today had variable arguments, but were putting them directly in the strings, like the third code example there. Which basically means that prepare did nothing to protect them.

        Previously, prepare(‘string’) returned ‘string’. Now it returns ‘string’ and a warning that you are doing-it-wrong. :)

      • chacha102 7:03 am on December 12, 2012 Permalink | Log in to Reply

        If you check out the source code for wpdb::prepare it really isn’t that interesting.

    • Vitor Carvalho 11:17 am on December 12, 2012 Permalink | Log in to Reply

      Fantastic explanation Nacin ๐Ÿ˜‰

    • Joost de Valk 2:14 pm on December 12, 2012 Permalink | Log in to Reply

      Had to chuckle a bit when I found this:

      Missing argument 2 for wpdb::prepare(), called in /home/example/public_html/wp-content/plugins/akismet/admin.php

    • rfair404 2:14 pm on December 12, 2012 Permalink | Log in to Reply

      Thanks Nacin, I started seeing these notices in the last few weeks on several plugins that I use. glad to know what’s going on here.

    • a6april 3:18 pm on December 12, 2012 Permalink | Log in to Reply

      Thanks Huge Andrew, I had no idea! I am always glad to learn something everyday! I appreciate the quick followup and all of the responses. Have a great day all!

    • Josh 4:31 pm on December 12, 2012 Permalink | Log in to Reply

      Extremely useful… and “juicy”! Thanks Andrew! Saved me tons of time. Nice to know you guys are on top of security. Thanks again!

    • nomadentech 11:29 am on December 13, 2012 Permalink | Log in to Reply

      This is works perfectly, i think similar error will found in another plugins, so we dont need to fear for updating WordPress core. ๐Ÿ˜€
      Thank you,


    • properwp 6:01 pm on December 13, 2012 Permalink | Log in to Reply

      Thank you very much! We’re using a modified version of a clunky plugin in the repo and we keep finding new, wonderful problems. Another one of those “probably should have started from scratch” situations!

    • Mark de Scande BlogLines 8:04 pm on December 13, 2012 Permalink | Log in to Reply

      The only thing here is that it should have been noted some were or it was and i did not see it or i did not read i had the same problem on my Wife site SuperBlogs.co.za but on BlogLines.co.za it all was perfect on SB i just added some dirty code to make it go away


      But thx for posting it here for us all to see

    • Nashwan Doaqan 5:32 pm on December 14, 2012 Permalink | Log in to Reply

      Thank You Andrew Nacin , I see many plugins have this PHP warning .
      I hope a good life for all plugins authors ๐Ÿ˜€

    • DigiproveDevelopment 12:51 pm on December 15, 2012 Permalink | Log in to Reply

      Correction: some sites WERE broken because the warning messages screwed up the buffer and prevented normal operation.

      Am I the only one who thinks it was the wrong decision for WordPress team to decide that warnings will be spouted out for a situation where previously there was not even a Notice-level message? Like many authors I turn on notice-level messages when testing. And the underlying change caused so much difficulty because of a widespread but incorrect assumption that wpdb->prepare did actually do something with standalone sql strings when it fact what it did was – nothing.

      Suggest that:
      a) WordPress automatic upgrade process at least gives a warning to users who are using plugins not marked as being compatible with new release (e.g. like Firefox does).

      b) More use is made of notice-level messages fo situations like this so that sites don’t actually break when WordPress changes

      c) All registered plugin developers are warned by email of situations identified in beta testing which require action

  • Justin Sternberg 5:43 pm on December 11, 2012 Permalink
    Tags: , 3.5-field-guide, admin columns, register_taxonomy,   

    WordPress 3.5 admin columns for custom taxonomies 

    WordPress 3.5 is here!! If you haven’t played with it yet, go get it!
    I’m proud to be listed as a contributor on this release and want to highlight a new feature geared towards developers that I helped work on. If you have checked the register_taxonomy() codex page recently, you may have noticed a new optional argument, ‘show_admin_column.’

    From the codex:

    (boolean) (optional) Whether to allow automatic creation of taxonomy columns on associated post-types.
    Default: false

    As stated, this new argument allows easy registration of taxonomy columns on post (and custom post type) list table screens much like the default tags’ and categories’ columns.

    'show_admin_column' in action

    This should make plugin and theme developers happy as they’ll no longer need to build these columns manually.

    The new argument in action:

    // hook into the init action and call create_activity_taxonomies when it fires
    add_action( 'init', 'create_activity_taxonomies' );
    // create taxonomy, "fitness-type" for the post type "activity"
    function create_activity_taxonomies() {
    	// Add new taxonomy, make it hierarchical (like categories)
    	$labels = array(
    		'name' => _x( 'Fitness Types', 'taxonomy general name' ),
    		'singular_name' => _x( 'Fitness Type', 'taxonomy singular name' ),
    		'search_items' => __( 'Search Fitness Types' ),
    		'all_items' => __( 'All Fitness Types' ),
    		'parent_item' => __( 'Parent Fitness Type' ),
    		'parent_item_colon' => __( 'Parent Fitness Type:' ),
    		'edit_item' => __( 'Edit Fitness Type' ),
    		'update_item' => __( 'Update Fitness Type' ),
    		'add_new_item' => __( 'Add New Fitness Type' ),
    		'new_item_name' => __( 'New Fitness Type Name' ),
    		'menu_name' => __( 'Fitness Type' ),
    	register_taxonomy( 'fitness-type', array( 'activity' ), array(
    		'hierarchical' => true,
    		'labels' => $labels,
    		'show_ui' => true,
    		'show_admin_column' => true,
    		'query_var' => true,
    		'rewrite' => array( 'slug' => 'fitness-type' ),
    	) );

    Another key addition is the “manage_taxonomies_for_{$post_type}_columns” filter. This allows developers to add a taxonomy column to a post type outside of the register_taxonomy() function:


    add_filter( 'manage_taxonomies_for_activity_columns', 'activity_type_columns' );
    function activity_type_columns( $taxonomies ) {
    	$taxonomies[] = 'activity-type';
    	return $taxonomies;
    • Jon Brown 3:10 am on December 12, 2012 Permalink | Log in to Reply

      Cool addition, I had no idea this was coming, thanks for highlighting it.

      • Justin Sternberg 3:38 am on December 12, 2012 Permalink | Log in to Reply

        It’s been a bit under the radar with all the amazing new features dropped in 3.5, but I’m glad to give it a bit of a push. :)

    • Frank Bรผltge 7:19 am on December 12, 2012 Permalink | Log in to Reply

      Very usefull; time to dont use the custom class for doing this. Thanks.

    • cdils 2:21 pm on December 12, 2012 Permalink | Log in to Reply

      Yes! Thank you for highlighting this. Was just winging these columns this week with some Yoast code. Digging this!

    • Lisa Sabin-Wilson 3:22 pm on December 12, 2012 Permalink | Log in to Reply

      This is really good stuff Justin! show_admin_column makes life a bit easier and cleaner.

    • cdils 4:07 pm on December 12, 2012 Permalink | Log in to Reply

      Was playing with this and thought I’d share…If you want to add more than one taxonomy column, add another line with syntax:

      $taxonomies[] = ‘second-taxonomy’;

      Where {$post_type} is your CPT name

      /**Add columns to CPT admin page */
      add_filter( ‘manage_taxonomies_for_{$post_type}_columns’, ‘{$post_type}_type_columns’ );
      function {$post_type}_type_columns( $taxonomies ) {
      $taxonomies[] = ‘first-taxonomy’;
      $taxonomies[] = ‘second-taxonomy’;
      return $taxonomies;

      Thanks again, Justin. Awesome stuff. Is there a filter for includling a custom field as a column?

      • Justin Sternberg 4:30 pm on December 12, 2012 Permalink | Log in to Reply

        No there is not. Post meta can take on many forms, so to try to pin down a specific column use-case would undoubtably rule out a large portion of users. But honestly building custom columns for simple forms of post-meta is not too difficult.

    • mor10 4:30 pm on December 12, 2012 Permalink | Log in to Reply

      Excellent! The old way was so verbose and clunky. This looks much cleaner and more approachable.

    • Alex Mills (Viper007Bond) 8:39 pm on December 12, 2012 Permalink | Log in to Reply

      This is great, thanks! Time to rip a bunch of manually added columns out of my plugins that use custom taxonomies!

    • RiccardoB. 9:09 pm on December 15, 2012 Permalink | Log in to Reply

      Less code, same result. Useful!

    • Maor Chasen 9:38 am on December 20, 2012 Permalink | Log in to Reply

      Lovely! Can’t wait to give it a spin!

  • Mike Schroder 1:04 am on December 6, 2012 Permalink
    Tags: 3.5-field-guide   

    WP_Image_Editor is incoming! 

    In WordPress 3.5, GD has been abstracted out of core’s image manipulation functions.
    What does that mean for you, you ask?

    What’s cool?

    • We add support for Imagick by default, giving better image quality to those who have it available on their host. This is particularly important if you’re using images with extended color profiles, since GD discards them outright.
      • Imagick support requires Imagick 2.2.0+ compiled against Imagemagick 6.2.9+, for full support. If the required functions aren’t available, WordPress will default back to GD.
    • You can create your own image manipulation engine, or extend ours in plugins to easily add additional functionality to WordPress.

    Watch out for:

    Any function or filter that receives or returns a GD Image Resource should be avoided if possible, since 3.5 represents core’s move away from GD’s direct use.

    Deprecated Filters

    Several filters have been deprecated, and will no longer function as they did previously. This includes any filter that expected to receive a GD Image Resource, as we can’t pass a GD Image Resource to it if another backend is being used. Instead, new filters are introduced that expect a WP_Image_Editor object.

    It’s worth noting that if you’re using these filters, your plugin shouldn’t create a fatal error – it just won’t modify core’s functionality like it used to, and will fail silently.

    Deprecated Filters

    • image_save_pre is now image_editor_save_pre
    • wp_save_image_file is now wp_save_image_editor_file
    • image_edit_before_change is now wp_image_editor_before_change

    While jpeg_quality is backward compatible in 3.5, if you want to change compression quality globally, you should use wp_editor_set_quality in the future, since it applies to other editors and formats that support quality setting as well (like PNG with Imagick). To change the quality on a single image you’re editing, see WP_Image_Editor::set_quality().

    New Filters

    • wp_image_editors – modify array to re-order or add additional editor/engine classes.
    • image_editor_default_mime_type – string; set default mime-type for WP_Image_Editor.

    Deprecated Functions

    • wp_load_image() – use wp_get_image_editor() to load files instead.
    • image_resize() – use WP_Image_Editor::resize()
    • gd_edit_image_support() – use wp_image_editor_supports()

    Need to Deprecate

    There isn’t yet an alternative for load_image_to_edit(). This is because there is work towards creating an image container for a future version of WordPress. In the meantime, while decidedly not ideal, I’d suggest doing what core does: wp_get_image_editor( _load_image_to_edit_path( $post_id ) );

    How do I use it?

    A complete tutorial on the use of WP_Image_Editor is forthcoming, but this should get you started:

    $image = wp_get_image_editor( 'cool_image.jpg' );
    if ( ! is_wp_error( $image ) ) {
    	$image->rotate( 90 );
    	$image->resize( 300, 300, true );
    	$image->save( 'new_image.jpg' );

    You can see full class documentation by taking a look at:

    Known issue

    #22663 – Non-Square Rotates (non 90*x), followed by a crop, can cause improper results.

  • Helen Hou-Sandi 4:50 am on December 1, 2012 Permalink
    Tags: 3.5-field-guide   

    More hooks on the edit screen: edit_form_after_title and edit_form_after_editor 

    In 3.5, we’ve introduced two new hooks for the add/edit post screen: edit_form_after_title and edit_form_after_editor. Previously, there was the edit_form_advanced hook (or edit_page_form for pages), which appeared between the normal and advanced sections of metaboxes below the editor. Now you’ll be able to use edit_form_after_title and edit_form_after_editor, both of which are available even if the post type doesn’t support the title or editor.

    While lots of things are appropriate in the various metabox areas, sometimes your customizations to the screen might need to go elsewhere. TinyMCE is a prime example, as it doesn’t like being moved in the DOM, such as in a draggable metabox. Core itself is now using edit_form_after_title on attachment editing to display the image and some fields for editing.

    Example Code:

    add_action( 'edit_form_after_title', 'myprefix_edit_form_after_title' );
    function myprefix_edit_form_after_title() {
    	echo '<h2>This is edit_form_after_title!</h2>';
    add_action( 'edit_form_after_editor', 'myprefix_edit_form_after_editor' );
    function myprefix_edit_form_after_editor() {
    	echo '<h2>This is edit_form_after_editor!</h2>';
    add_action( 'edit_form_advanced', 'myprefix_edit_form_advanced' );
    function myprefix_edit_form_advanced() {
    	echo '<h2>This is ye olde edit_form_advanced!</h2>';


    Edit Form Hooks in 3.5

    • Md Mahmudur Rahman 9:45 pm on December 2, 2012 Permalink | Log in to Reply

      This is great. I was looking for ‘edit_form_after_title’ as a requirement. Now I can do this using this hook. Great.

    • Maor Chasen 6:26 pm on December 3, 2012 Permalink | Log in to Reply

      Good stuff! Thanks a lot for sharing this!

    • Schwarttzy 4:10 pm on December 14, 2012 Permalink | Log in to Reply

      Not… quite so sure what to make of this… is it meant just for static text or will I be able to interact with the poster/pager helping them further customize the theme?

      • Helen Hou-Sandi 5:56 pm on December 14, 2012 Permalink | Log in to Reply

        Most of the screen is a form, including the locations of those hooks, so you can add form elements and they will be sent with the $_POST data when you save/publish/update a post. You’d handle that the same way you’d handle data from a typical metabox, using the save_post action with appropriate checks and validation/sanitization.

  • Matt Wiebe 9:47 pm on November 30, 2012 Permalink
    Tags: 3.5-field-guide   

    New Color Picker in WP 3.5 

    You may have noticed that WordPress 3.5 is sporting a new color picker. We originally developed it for the Custom Colors feature on WordPress.com. We offered it to WordPress Core, and 4 months, eleventy million tests and iterations later, there’s a shiny new, HiDPI-ready, CSS gradient-based color picker called Iris in your WordPress. But how do you use it?

    The easiest way possible is in the Customizer. Keep registering your color controls the same way you always have and they’ll now sport a slick new Iris-based color picker interface. Otto’s great Theme Customizer tutorial shows you how to register controls, including a color control, so I won’t repeat that information here.

    Want to use the new color picker somewhere else? Here’s a quick guide:

    1. Enqueue the ‘wp-color-picker’ script and style

    add_action( 'admin_enqueue_scripts', 'mw_enqueue_color_picker' );
    function mw_enqueue_color_picker( $hook_suffix ) {
    	// first check that $hook_suffix is appropriate for your admin page
    	wp_enqueue_style( 'wp-color-picker' );
    	wp_enqueue_script( 'my-script-handle', plugins_url('my-script.js', __FILE__ ), array( 'wp-color-picker' ), false, true );

    My plugin now has a my-script.js file that has declared wp-color-picker as a dependency. We can now use the wpColorPicker jQuery method inside it.

    2. Add an input to your admin page

    I’m not going to tell you how to code an admin page. Somewhere on it, you’ll want:

    <input type="text" value="#bada55" class="my-color-field" />

    You can also prime a default color for the field if you want:

    <input type="text" value="#bada55" class="my-color-field" data-default-color="#effeff" />

    3. Call ‘wpColorPicker’ from your script

    Remember that we enqueued my-script.js above? Open it up, and be prepared for some long coding:


    What, you wanted more? There’s a lot more you can do, but that will get the job done for most cases. (Note that only IE8 and up are supported. IE7 and under will fail gracefully, leaving you with a perfectly usable text input.)

    4. Advanced usage

    wpColorPicker supports a few options. You can supply an options object when calling it:

    var myOptions = {
    	// you can declare a default color here,
    	// or in the data-default-color attribute on the input
    	defaultColor: false,
    	// a callback to fire whenever the color changes to a valid color
    	change: function(event, ui){},
    	// a callback to fire when the input is emptied or an invalid color
    	clear: function() {},
    	// hide the color picker controls on load
    	hide: true,
    	// show a group of common colors beneath the square
    	// or, supply an array of colors to customize further
    	palettes: true

    5. More advanced usage

    wpColorPicker is set of UI controls wrapped around the underlying Iris color picker. We did things this way so that, if a better color picker comes along, we can more easily swap it out. But, if you want to just play with Iris itself, just declare iris as your script dependency instead. I’m not going to document the options here, but Iris’s GitHub repo should see some actual docs in the future.

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