Sheetline documentation1.x
Developers

Hooks for add-ons

The PHP filters and actions around post types, listing and saving, and the JavaScript API for adding buttons and behaviour to the grid.

Beyond columns, Sheetline has hooks for code that adds Bulk Editors, changes how posts are listed and saved, or adds to the Bulk Editor screen. Sheetline Pro is built entirely on them.

More post types

sheetline_post_types lists the post types that get a Bulk Editor (posts and pages by default). Each one gets its own screen under its menu, with a column for each of its taxonomies:

add_filter( 'sheetline_post_types', function ( $types ) {
	$types[] = 'book';
	return $types;
} );

Only types with an admin screen (show_ui) count; attachments never do. Sheetline Pro adds the custom post types chosen in its settings this way.

Checking a post before it's saved

sheetline_check runs once a post's changes are recorded and before it's saved. Return errors by column key; any error stops that post being saved, and the message appears on the cell.

// Posts in "News" need a title of 70 characters or fewer.
add_filter( 'sheetline_check', function ( $errors, $draft, $changed ) {
	if ( in_array( 'title', $changed, true )
		&& has_category( 'news', $draft->post )
		&& mb_strlen( (string) $draft->get( 'post_title' ) ) > 70 ) {
		$errors['title'] = 'News titles are 70 characters at most.';
	}
	return $errors;
}, 10, 3 );

After a save

sheetline_save_result filters what a save sends back to the grid. Its second argument lists every cell that changed as [ post ID, column key, old value, new value ], and the third is the post type, which makes it a good place to log changes:

add_filter( 'sheetline_save_result', function ( $result, $changed, $post_type ) {
	foreach ( $changed as list( $id, $key, $old, $new ) ) {
		error_log( sprintf( 'Bulk Editor: %s %d %s %s → %s', $post_type, $id, $key, wp_json_encode( $old ), wp_json_encode( $new ) ) );
	}
	return $result;
}, 10, 3 );

Request parameters and queries

  • sheetline_list_args gets the arguments for a page of posts and the REST request, so you can read your own (sanitized) query parameters.
  • sheetline_query_args gets the WP_Query arguments built from them (and the grid's arguments, and the post type), to change the query.

The Bulk Editor screen

  • sheetline_editor_load fires when a Bulk Editor loads, with the screen and the post type. Enqueue your script there, with sheetline as a dependency:

    add_action( 'sheetline_editor_load', function ( $screen, $post_type ) {
    	add_action( 'admin_enqueue_scripts', function () {
    		wp_enqueue_script( 'my-grid', plugins_url( 'my-grid.js', __FILE__ ), array( 'sheetline', 'wp-hooks' ), '1.0', true );
    	} );
    }, 10, 2 );
    
  • sheetline_page_actions prints next to the screen's title, with the post type; use page-title-action buttons there.

  • sheetline_loaded fires once Sheetline has loaded (on plugins_loaded). Hook an add-on's setup to it; SHEETLINE_VERSION is defined from then on.

The grid's JavaScript

The grid sets window.sheetline and starts once the page is ready, after every script in the footer has run, so your script can add its wp.hooks first. Give your hooks your own namespace.

Hook Gets Use it to
sheetline.init (action) the API run once before the first load
sheetline.query (filter) query parameters, state add parameters to the posts request (read them with sheetline_list_args)
sheetline.filters (filter) elements, state add controls after the Filter button
sheetline.bulkActions (filter) elements, state add buttons to the left of the filters
sheetline.selectable (filter) false return true to show a checkbox column; selected post IDs are in state.selected
sheetline.rowClass (filter) class names, row add classes to a row
sheetline.rowActions (filter) elements, row add links under a post's title
sheetline.savedNotice (filter) HTML parts, result add to the notice after a save (escape text with sheetline.escape())
sheetline.loaded (action) state react after a page of posts loads
// A button that shows how many posts are on the page.
wp.hooks.addFilter( 'sheetline.bulkActions', 'my-grid', ( nodes, state ) => nodes.concat(
	window.sheetline.el( 'button', {
		type: 'button',
		class: 'button',
		text: 'Count',
		onclick: () => window.sheetline.notice( 'info', window.sheetline.escape( state.rows.length + ' posts on this page' ) ),
	} )
) );

window.sheetline also has api( path, options ) for Sheetline's REST routes, setValue( row, key, value ) to make an unsaved change, query() for the current search and filters, rowById(), render(), load(), go( changes ) (change filters or page and reload, after asking about unsaved changes), pickImages() for the media library, and more; the plugin's README lists them all.

REST API

sheetline/v1/posts lists (GET, with post_type and the grid's parameters) and saves (POST, post_type and changes as [ { id, key, value } ]) for users who can edit posts of that type. Sheetline Pro adds its routes to the same namespace.