Gridline documentation1.x
Buy Pro· 5 sites · $99/year
Developers

Adding columns

Add your own fields to the Bulk Editor with the gridline_columns filter: the column format, value types, validation and sorting.

Any product field can become a Bulk Editor column with the gridline_columns filter. Put the code in a small custom plugin or your child theme's functions.php. Columns you add get everything the built-in ones have: keyboard editing, highlighted unsaved changes, errors on their cell, Screen Options, and with Gridline Pro bulk changes, undo and CSV export.

A first column

// A "Gift wrap available" yes/no column, stored in product meta.
add_filter( 'gridline_columns', function ( $columns ) {
	$columns['gift_wrap'] = array(
		'label' => 'Gift wrap',
		'group' => 'Extras',
		'type'  => 'bool',
		'get'   => function ( WC_Product $product ) {
			return $product->get_meta( '_gift_wrap' ) ? 'yes' : 'no';
		},
		'set'   => function ( WC_Product $product, $value ) {
			$product->update_meta_data( '_gift_wrap', 'yes' === $value ? 1 : '' );
		},
	);
	return $columns;
} );

The key (gift_wrap) must be unique. The product is saved by Gridline after set runs, so don't call save() yourself.

The column format

Key Required What it is
label yes Shown in the header and in Screen Options
type yes How the value is shown and edited (see below)
get yes function ( WC_Product $product ) returning the value to edit
set yes function ( WC_Product $product, $value ) applying a new value
group no Groups related columns (default "Other")
options for select and terms value => label pairs
applies no function ( WC_Product $product ) returning false where the field doesn't exist (the cell is greyed out)
show no function ( WC_Product $product ) returning true where the field can't be edited (applies is false) but its value should still be shown, greyed out, e.g. a value worked out from other fields
hidden no true to hide the column until switched on in Screen Options
sort no Makes it sortable: an orderby value for wc_get_products() (e.g. 'title'), or array( 'meta' => '_my_key', 'num' => true )

Types

Type Value Edited with
text string a text box
longtext HTML string a larger text box over the cell
price decimal string, '' for none a text box; shown in your currency
number number as a string a text box
date Y-m-d string, '' for none a date picker
select one of the options keys a dropdown
bool 'yes' or 'no' a Yes/No dropdown
terms array of term IDs a checkbox list of the options
image attachment ID as a string, '' for none the media library
images array of attachment IDs the media library, several in order
readonly string shown, not editable

Values arrive in set as the grid sends them: strings, or arrays of IDs for terms and images. Always write them through the product's own setters or meta functions, so WooCommerce and other plugins see the change.

Refusing a value

Throw an exception with a message for the shop manager. It appears under the cell in red, and that product isn't saved:

'set' => function ( WC_Product $product, $value ) {
	$value = trim( (string) $value );
	if ( '' !== $value && ! preg_match( '/^\d{8,14}$/', $value ) ) {
		throw \Extendiment\Gridline\Columns::invalid( 'A GTIN is 8 to 14 digits.' );
	}
	$product->update_meta_data( '_gtin', $value );
},

Columns::invalid() returns an InvalidArgumentException; any InvalidArgumentException works.

Helpers

Extendiment\Gridline\Columns has the helpers the built-in columns use:

  • Columns::decimal( $value ): a number of 0 or more (or ''), as WooCommerce stores it; refuses anything else.
  • Columns::option( $value, $options ): one of the options' keys; refuses anything else.
  • Columns::bool( $value ): true for "yes", "1", "true" or "on".
  • Columns::term_options( $taxonomy ): a taxonomy's terms as ID => 'Parent › Child', ready for options.
  • Columns::term_ids( $value, $options ): the term IDs, each one of the options.
// A brand taxonomy as a terms column.
add_filter( 'gridline_columns', function ( $columns ) {
	$brands = \Extendiment\Gridline\Columns::term_options( 'product_brand' );
	$columns['brands'] = array(
		'label'   => 'Brands',
		'type'    => 'terms',
		'options' => $brands,
		'applies' => fn( $p ) => ! $p->is_type( 'variation' ),
		'get'     => fn( $p ) => wp_get_post_terms( $p->get_id(), 'product_brand', array( 'fields' => 'ids' ) ),
		'set'     => fn( $p, $v ) => wp_set_post_terms( $p->get_id(), \Extendiment\Gridline\Columns::term_ids( $v, $brands ), 'product_brand' ),
	);
	return $columns;
} );

Where the column goes

Columns appear in the array's order. Adding a key puts the column at the end; to place it elsewhere, rebuild the array:

add_filter( 'gridline_columns', function ( $columns ) {
	$at  = array_search( 'sku', array_keys( $columns ), true ) + 1;
	$new = array( 'gtin' => array( /* … */ ) );
	return array_slice( $columns, 0, $at, true ) + $new + array_slice( $columns, $at, null, true );
} );

Gridline Pro adds its columns at priority 5, so columns added at the default priority 10 come after them.

Variable products and variations

Use applies to grey out cells where a field doesn't exist, for example fn( $p ) => ! $p->is_type( 'variable' ) for a field only simple products and variations have. With Gridline Pro, variations get rows of their own, so decide whether your field applies to them too.