Using Custom Bulk Actions

Sorry it’s been such a long time since my last blogblog (versus network, site)!

I’m happy to tell you that in WordPress 4.7, developers can register their own bulk actions on list table screens.

custom-bulk-action-screenshot

Let’s walk through the steps required to add one.

An option in the dropdown

To add an option in the Bulk Actions dropdown HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. element, register a callback on the bulk_actions-{screen_id} filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output. that adds the new option onto the array. Replace {screen_id} with the ID of the admin screen to offer the bulk action on.

To add a bulk action “Email to Eric,” we could use the following code:

add_filter( 'bulk_actions-edit-post', 'register_my_bulk_actions' );

function register_my_bulk_actions($bulk_actions) {
  $bulk_actions['email_to_eric'] = __( 'Email to Eric', 'email_to_eric');
  return $bulk_actions;
}

Handling the form submission

To handle a bulk action form submission, register a callback on the handle_bulk_actions-{screen_id} filter for the corresponding screen. The filter expects the redirect URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org to be modified, so be sure to modify the passed $redirect_url. This allows us to carry success or failure state into the next request to display a notice to the user. The other callback arguments will differ depending on the screen here to include contextually relevant data.

To add a bulk action handler for emailing the selected posts, we could use the following code:

add_filter( 'handle_bulk_actions-edit-post', 'my_bulk_action_handler', 10, 3 );

function my_bulk_action_handler( $redirect_to, $doaction, $post_ids ) {
  if ( $doaction !== 'email_to_eric' ) {
    return $redirect_to;
  }
  foreach ( $post_ids as $post_id ) {
    // Perform action for each post.
  }
  $redirect_to = add_query_arg( 'bulk_emailed_posts', count( $post_ids ), $redirect_to );
  return $redirect_to;
}

Showing notices

We could use the existing notice hooksHooks In WordPress theme and development, hooks are functions that can be applied to an action or a Filter in WordPress. Actions are functions performed when a certain event occurs in WordPress. Filters allow you to modify certain functions. Arguments used to hook both filters and actions look the same. to let the user know what happened, depending on the state we set in the URL:

add_action( 'admin_notices', 'my_bulk_action_admin_notice' );

function my_bulk_action_admin_notice() {
  if ( ! empty( $_REQUEST['bulk_emailed_posts'] ) ) {
    $emailed_count = intval( $_REQUEST['bulk_emailed_posts'] );
    printf( '<div id="message" class="updated fade">' .
      _n( 'Emailed %s post to Eric.',
        'Emailed %s posts to Eric.',
        $emailed_count,
        'email_to_eric'
      ) . '</div>', $emailed_count );
  }
}

For the curious, see the related changeset and Trac ticket.

#4-7

A data schema for meta

register_meta() is a tiny function, which lets you register a sanitization and authorization callback for post metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress., term meta, user meta or comment meta.

We’re going to expand the utility of this function to describe the data type of the field. This will be useful for the REST APIREST API The REST API is an acronym for the RESTful Application Program Interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. It is how the front end of an application (think “phone app” or “website”) can communicate with the data store (think “database” or “file system”) https://developer.wordpress.org/rest-api/. as well as the Fields APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways..

This discussion has started in #35658, but I’d like to share the latest thoughts for general feedback.

Imagine a “movie” custom post typeCustom Post Type WordPress can hold and display many different types of content. A single item of such a content is generally called a post, although post is also a specific post type. Custom Post Types gives your site the ability to have templated posts, to simplify the concept. which has a “star-rating” post meta field, which should accept the value 1, 2, 3, 4 and 5. REST API clients like the iOSiOS The operating system used on iPhones and iPads. app would want to know this information, so they can offer appropriate UIUI User interface for their users. Ditto for the Fields API.

Here are some loose thoughts on what that API might look like.

Here is a post meta field for “mood” that accepts any string. The value would fit in a single row. There would only be one row per post, as it is not “repeatable.” Repeatable might be a default.

<?php 
register_meta( 'post', 'mood', array( 'schema' => array( 
		'type' => 'string',
		'repeatable' => false
	)
) );

Here is a field that consists of an array of URLs. The value would fit in a single row, perhaps in JSONJSON JSON, or JavaScript Object Notation, is a minimal, readable format for structuring data. It is used primarily to transmit data between a server and web application, as an alternative to XML. format, i.e. ['some.url/','some.other/url'], and is limited to one row per post.

<?php 
register_meta( 'post', 'related_content', array(
	'schema' => array( 
		'type' => 'array',
		'items' => array(
			'type' => 'url',
		),
		'repeatable' => false
	)
) );

Here is a field that consists of an album as it relates to an artist and includes a number of properties. The value would fit in a single row, and multiple rows can exist for a single artist.

<?php 
register_meta( 'post', 'album', array(
	'object_subtype' => 'artist',
	'schema' => array( 
		'type' => 'object',
		'properties' => array(
			'name' => array(
				'type' => 'string'
			),
			'cover' => array(
				'type' => 'wp-image'
			),
			'genre' => array(
				'type' => 'string',
				'options' => array( 'Rock', 'R&B', 'Shoegaze' ),
			),
			'release-date' => array(
				'type' => 'date'
			)
		)
		'repeatable' => true
	)
) );

What do you think?

#fields-api, #options-meta, #rest-api

A specification for the Fields API

specification defines how a part of the web platform works. For example, CSS is a spec, which browsers look to when implementing their layout engines.

A feature is drafted in spec, which serves as a prop to push forward discussion on how the feature should work. The spec author focuses on understanding and explaining the theoretical, and typically is not the implementer. An implementer might try to get a feature working, realize the spec is too vague or problematic, and give feedback to the author.

The Fields API is an opportunity for immense growth in the project. It is also a large problem space that needs a lot of discussion leading to agreement on what a coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. implementation should look like.

Let’s try writing a spec to push this effort forward. To start, I’ve talked to Scott about how the Fields API implementation works and made a spec. Comments are welcome — this is a draft and intended to spark conversation!

We’ll walk through the spec together at the next Fields APIAPI An API or Application Programming Interface is a software intermediary that allows programs to interact with each other and share data in limited, clearly defined ways. meeting, Monday 20:00 UTC 2016 in Slack #core-fields.

#feature-plugins, #fields-api

PHP Unit Test Meeting on Feb. 26th

We met last week to discuss PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher unit testing, and will meet again on February 26th 7PM UTC in #core on SlackSlack Slack is a Collaborative Group Chat Platform https://slack.com/. The WordPress community has its own Slack Channel at https://make.wordpress.org/chat/. to continue the conversation.

Our general goal here is to make writing unit tests easier through documentation. If you’re interested, join!

PHP Unit Test Discussion (Feb. 12) Recap

We had a lively discussion about our PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher unit tests today.

Our goal here is to make writing unit tests a straight-forward, understandable experience by updating the PHP Unit Test handbook page.

During the meeting, we landed on some practical changes for the handbook page we can make soon.

  • VVV has out-of-the-box support for running WP PHP unit tests. We should suggest using it without giving it an obvious endorsement, as it is not officially endorsed by the project.
  • Getting phpunit running with MAMP (the application) is hard. We should link to Boone’s tutorial on the topic.

The rest of the meeting moved towards outlining our current approach to unit tests, especially in structure. We should discuss if these are best practices, and develop agreed upon standards for the project.

  • Our tests are organized into folders based on component. (browse the phpunit/tests folder)
  • There are a good number of top-level test files in the /tests folder. New tests should not go in these files.
  • We should consider migrating top-level test files into their respective component folders.
  • Tests for a specific function should go inside a single file within a component directory.
  • Generally the test file path has taken the form /tests/phpunit/tests/{component}/{functionInCamelCase}.php
  • Generally a file’s test class has taken the form Tests_{Component}_{FunctionInCamelCase}
  • Test method names should take the format test_{{description_of_what_is_expected}}. For example, test_termmeta_cache_should_be_primed_by_default.

Please leave a comment here if you have any thoughts.

I’ll schedule a meeting next week to continue our discussion.

Thanks to everyone who attended, this was a great meeting.

PHP Unit Test Documentation Meeting

Writing unit tests is absolutely necessary when modifying functionality in WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress.. Unit tests assure us that our code does what we expect it to do, and that changes we make don’t produce collateral damage.

How do you write these oh-so-important unit tests? Well, we have documentation on the topic, but it just reads “TODO”. Let’s do!

We’ll meet in #core on Friday, February 12th 7pm UTC for a working session to discuss and document PHPPHP The web scripting language in which WordPress is primarily architected. WordPress requires PHP 5.6.20 or higher unit testunit test Code written to test a small piece of code or functionality within a larger application. Everything from themes to WordPress core have a series of unit tests. Also see regression. authoring practices. Come!

Documenting JavaScript in Core

We had a lively session on JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. in WordPress coreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. at the Community Summit last week. Topics were varied, but I’d like to sum up a few threads that point towards an actionable goal: better documentation in JavaScript.

New Feature JavaScript is complex

WordPress’ internal JavaScript “libraries” are hard to understand, if not impenetrable for many core developers. For example, the 8000+ lines of codeLines of Code Lines of code. This is sometimes used as a poor metric for developer productivity, but can also have other uses. that power the 3.5+ media experience. The JSJS JavaScript, a web scripting language typically executed in the browser. Often used for advanced user interfaces and behaviors. here hasn’t been written for other developers to consume, so architectural decisions end up being expressed only in code, often without documentation.

As feature development has become much more JavaScript-driven, we should do whatever we can to make our code comprehensible for fellow core developers. Comprehensible code takes many shapes, but one that everyone can agree on is documentation. Up until now, JavaScript documentation has been an afterthought. We need to make an about-face in this respect.

Adopting JSDoc

Core is adopting the JSDoc standard. Last year, WordPress standardized PHP inline documentation. Inline documentation surfaces relevant information to developers about code. This is very helpful (necessary?) when you’re wondering what arguments are to be passed into a class constructor that’s seven levels deep in inheritance (!).

Picking a documentation standard also makes parsing code possible, to extract this structured data. Our bespoke PHP parser feeds inline documentation into the new WP code reference. Choosing a JS documentation standard makes an auto-generated Javascript code reference a possibility later down the line.

@kpdesign, @adamsilverstein, @drewapicture and I have been drafting a page on JavaScript Inline Documentation Standards, which will land in the core contributor handbook very soon.

Let us rally around JS documentation, and get a DocBlockdocblock (phpdoc, xref, inline docs) on every JavaScript function. Consider this your battle cry.

Supplemental Documentation

Aside from inline docsinline docs (phpdoc, docblock, xref), we need a place for high-level architectural explanation of our JavaScript to live, probably in the core contributor handbook.  Many at the summit noted that with a few key insights, internal libraries are much easier grokked. @gcorne and I started on documentation for media. We’ll see how this goes.

Also, insightful tidbits which would have no place in inline documentation could be answered here, to answer questions like why and when we provide no-js fallbacks.

Follow-up Meeting

We will discuss JSDoc in the weekly Inline Docs meeting in the #docs channel on November 12, 2014 20:00. Join us!

Media Grid Update

Media Grid started as a standalone plugin by Shaun Andrews, which was a reimagining of the UIUI User interface as an alternative to the traditional post list view in the Media Library. The argument was that images are the ubiquitous media type in most users’ libraries, so we should provide an interface to browse media visually.

I joined the project in late April, attempting to integrate existing Media modal code. This work was merged into the standalone pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party, and into trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running "trunk", then you are on the latest revision.(see #24716) in early June. In the process, I created documentation for the Media code, which is the most comprehensive resource for untangling the Backbone wires in media.

Questions were raised about what problem the grid was solving, so in order to get a more hands-on understanding of user engagement with the Media Library, Jerry Bates performed user interviews. These confirmed our assumption that images are the pervasive media type, but also surfaced the fact that users identify media in different ways – some by the thumbnail, some by what post a media item is uploaded to, some by title.

After a good amount of UXUX User experience/UI chatter in weekly meetings, we decided we could serve users better by making a few changes to the original implementation merged into trunk. We’ve landed on mock-ups for a quick pivot, which I’m working on implementing . I’ll be dropping diffs for y’all JavascriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. Jedis to peruse on #24716, feedback welcome and appreciated. I hope to have merge-ables by Monday morning, and then to progress to user testing.

#4-0, #media

Media Component Weekly Meeting Agenda

There will be Media component office hours June 13, 2014 1700 UTC  (and every Friday) in #wordpress-dev.

Proposed agenda items:

  • Media Grid (#24716) check-in. @jerrysarcastic posted about the user interviews he did. We should talk about UIUI User interface feedback specifically and where we should go from there.
  • Splitting up JavascriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com/. files for media (#28510). Not sure this will happen in 4.0 but I’d like to get a solid approach to this together soon.

If you have anything you’d like to discuss specific in the Media component (specific tickets you care about or more abstract discussions), please add it to the comments.

Media component office hours

Weekly office hours (bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. scrubbing and feature development chat) for the Media component will start tomorrow, combining with Media Grid’s weekly meeting.

I’ve heard the Media component is “where tickets on tracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. go to die,” let’s see what we can do to thwart that status quo.

Our Media Grid meetings have been held every Friday at 1700 UTC in #wordpress-ui. We’ll keep the same time, but move the meeting into #wordpress-dev.

#media