Posted by & filed under WordPress.

Stuck in the tree is powered by WordPress and we make heavy use of custom post types combined with custom post meta to create powerful yet easy to use features. One of these is our Bingo reviews, powered by a custom post type, reviews are updated regularly. They also come in multiple forms from mini (skeleton) review for sites just launching, or where one of our reviewers has only had limited time, to full blown review. To help navigate this content on the backend we have added and modified the “view bingo sites” page within WordPress admin.

By default a custom post type, view page looks just like the post/page views however each post type (including post and pages) can have additional columns added to it.

Adding a column is not to complicated but does require some additional code.

function bingo_sites_new_columns( $columns ) {
    $columns['site_launched']  = 'Launch Date';
    $columns['use_new_template']    = 'New Template';
    $columns['show_modal']    = 'Cross Promote';
    $columns['ad_post_id']    = 'Featured Site';
    $columns['rating']   = 'Rating';
    $columns['site_logo'] = 'Logo';
    return $columns;
}
add_filter('manage_bingo-sites_posts_columns', 'bingo_sites_new_columns');

In this example we are adding some new columns each column is given a key and a name, and is added in by the filter manage_post_columns, because we only want to effect the Bing Sites port type we use a modified version of that filter manage_bingo-sites_posts_columns

Adding the columns themselves is easy, but we need to populate them as well:

function bingo_sites_new_content( $column_name, $post_id ) {

	switch ($column_name) {
		case 'site_launched':
			$site_launched = get_post_meta( $post_id, 'site_launched', true );
			if($site_launched){
				echo date( 'F Y',$site_launched);
			}
			else{
				echo 'not set';
			}
			break;


		case 'use_new_template':
		$use_new_template = get_post_meta( $post_id, 'use_new_template', true );

			if ($use_new_template == '1') {
			echo '<span class="dashicons dashicons-yes" style="color: #00ff00"></span>' ;
			} else {
			echo'<span class="dashicons dashicons-no " style="color: #ff0000"></span>' ;
			}
			break;


		case 'rating':
			echo get_post_meta( $post_id, 'rating', true );
			break;

		case 'site_logo':
			$site_logo = get_post_meta( $post_id, 'site_logo', true );
		echo	wp_get_attachment_image( $site_logo, [120,55], false, false );
			break;

		case 'show_modal':
			$show_modal = get_post_meta( $post_id, 'show_modal', true );
			if ($show_modal == '1') {
					echo '<span class="dashicons dashicons-yes" style="color: #00ff00"></span>' ;
					} else {
					echo'<span class="dashicons dashicons-no " style="color: #ff0000"></span>' ;
					}
			break;

		case 'ad_post_id':
			$ad_post_id = get_post_meta( $post_id, 'ad_post_id', true );
			if(isset($ad_post_id) && is_numeric($ad_post_id))
			{
				echo get_the_title( $ad_post_id );
			}
			break;

		default:
			break;
	}
}
add_action( 'manage_bingo-sites_posts_custom_column', 'bingo_sites_new_content', 10, 2 );

In this case we are looking for the key, and returning what ever value we want in the column based on the postID. Again because we are targeting only a specific post type we use manage_bingo-sites_posts_custom_column for all post types we would use manage_custom_column

The result means we have a lot of additional columns and this generally breaks the layout, for columns we know we do not wish to ever include we can use the unset function inside a function calling the manage_bingo-sites_posts_columns filter and remove existing columns, or simply deslect them from screen options.

The ability to see this content is really useful, and by including things like the logo we can quickly find content by its brand, which is how most of our reviewers recognise a site. Tell them a name and they will look at your blankly show them the logo they know it instantly.

For certain fields it’s useful if we are able to sort, this is a little more tricky. The first step is to define which additional columns should be sortable.

function bingo_site_columns_sortable($cols) {
    $cols['rating'] = 'Rating';
		$cols['site_launched'] = 'Site Launched';
		$cols['use_new_template'] = 'Use New Template';
		$cols['show_modal'] = 'Cross Promote';
    return $cols;
}
add_filter("manage_edit-bingo-sites_sortable_columns", "bingo_site_columns_sortable");

The second step is to then provide a way for WordPress to know how to sort the content in those columns.

function bingo_site_sort_by( $vars ) {

	if(isset( $vars['orderby'])){
		switch ($vars['orderby']) {
			case 'Rating':
				$vars = array_merge(
					$vars,
					array(
						'meta_key' => 'rating',
						'orderby' => 'meta_value_num'
					)
				);
				break;
			case 'Site Launched':
					$vars = array_merge(
						$vars,
						array(
							'meta_key' => 'site_launched',
							'orderby' => 'meta_value meta_value_num'
						)
			);
			break;
					case 'Use New Template':
						$vars = array_merge(
							$vars,
							array(
								'meta_key' => 'use_new_template',
								'orderby' => 'meta_value meta_value_num'
							)
						);
						break;
						case 'Cross Promote':
							$vars = array_merge(
								$vars,
								array(
									'meta_key' => 'show_modal',
									'orderby' => 'meta_value meta_value_num'
								)
							);
							break;
			default:
				break;
		}
	}
		return $vars;
}
function bingo_site_load()
{
	add_filter( 'request', 'bingo_site_sort_by' );
}

add_action( 'load-edit.php', 'bingo_site_load' );

The main filter used to modify the sort is the request filter, this is a broad filter used all over the place, so we put it inside a function, which is then loaded only on the edit.php page. So limiting it to just when we are using it. We are then again using a switch statement to check which column is being sorted. Note it’s sorted by NAME not key this caught us out initially and caused much head scratching. However the result is sortable columns.