Customer Story: A Minimalist Dashboard for WPCD WooCommerce Subscribers

This is an article written by a customer of ours, Abhijeet Deshpande.

Abhijeet really went to town on WPCD, completely customizing the WPCD console to suit his requirements. This article discusses everything he did, the obstacles he encountered and provides a roadmap and ideas that you can consider if you ever decide to make substantial UI related changes to your WPCD installations.

We really appreciate the work Abhijeet has done in creating this article.


The past few weeks, I have been exploring WPCD’s features to sell cloud servers and apps. A key challenge for me was to customize the dashboard for server and site subscribers. Speaking of which, you may visit WPCD’s roadmap on Trello to upvote the request for a native WPCD frontend dashboard. Meanwhile, WPCD’s awesome support folks requested to share some of the experiences on how I went about simplifying the cloud server dashboard to look like this.

As you can see, it is nothing fancy, but proves to be useful for my scenario. So, if you are interested in something similar, please continue reading. My test environment had an up-to-date and a fully functional WordPress site with the following components:

  • WPCD Plugin (version 4.6.6) and related dependencies
  • WooCommerce and WooCommerce Subscriptions plugins
  • WPCD Addon – Sell Server Subscriptions With WooCommerce (version 1.4.2 )
  • WPCD Addon – Sell WordPress Site Subscriptions With WooCommerce (version 1.1.1)
  • Advanced Access Manager or AAM Plugin. Note: You may use any plugin to grant additional capabilities to an existing user-role. I suggest AAM since it also helps with certain tasks of controlling access to the dashboard as we will see.
  • Code Snippets Plugin: For some tasks, I borrowed custom code snippets from Stackxchange and adapted these to my needs. Note: I am not a PHP ninja and so, if you are one, you are welcome to suggest improvements, optimizations, or standardization.
    • Role Based Access Control (RBAC): I prefer to perform checks based on user-roles, instead of capabilities (traditional WordPress method). Therefore, I added the following function as a snippet (credits: Jeff Starr 2019, wp-mix.com). We will call this elsewhere later.
function check_user_role($roles, $user_id = null) {
			if ($user_id) $user = get_userdata($user_id);
			else $user = wp_get_current_user();
			if (empty($user)) return false;
			foreach ($user->roles as $role) {
			if (in_array($role, $roles)) {
				return true;
			}
			}
			return false;
		}
  • A user account (so I could switch users to see the changes made to the dashboard) who owns at least one server and few apps. The user-role of Subscriber should be modified with the addition of following two capabilities:
    • wpcd_manage_servers
    • wpcd_manage_apps

Note: Although the official guide recommends adding these capabilities to the Subscriber user-role, to keep this exercise simple, I edited the Customer user-role.

Minimalist Hosting Dashboard

Part I – WPCD Server and App Listing Screens

Out of the box, WPCD offers a WordPressy backend – which is good, especially since it is all so familiar. However, for a full SaaS-like experience, you’d probably want to look up more options. So, when I read this article about building a custom dashboard, I got intrigued and took WP Frontend Admin plugin for a spin.

Now, this is something I really like about using WPCD – you can extend your hosting site’s features and style with plugins and themes of choice. For this minimalist attempt, native Gutenberg blocks suit my design needs just fine. You could, if your so prefer, use popular design tools such as Oxygen, Elementor, Live Canvas, Kadence, and so on for your hosting site.

Coming back to our discussion, WP Frontend Admin works perfect, is supported well, and within no time I had a fully-functional and shiny frontend dashboard. But. It outputs everything along with the metaboxes and widgets as-is from the backend screen to the frontend. Everything, except the WP Admin navigation menu. In other words, customers see information they can do without. Don’t get me wrong. The default WPCD admin screens are helpful for a WPCD site administrator. Just not for Woo customers. To explain better, please consider what a Woo server or site subscriber sees when they access the default dashboard.

For reasons discussed below, I would like to disable / remove / hide the items tagged and numbered in red on these screens. You may assess your own business context and prefer a more or, a less restrictive dashboard design. Each section includes the respective how-to as well. As you’d notice, some tasks leverage the popular AAM plugin while others rely on custom code snippets.

Removing admin Columns and Sort-Filters (items numbered 1-5)

  • Server Group Data: To be able to offer taxonomy management to customers, I’d need to add the “wpcd_manage_groups” capability to the user-role of Customers. Then, I need to restrict them so they can view and manage only those taxonomies they create themselves and not all taxonomies that exist on the site (for instance, taxonomies created by administrators). I did not have the time for such assessment. Hence, I choose to disable this.
  • Local Status Data: The customer can view overall Server Health as a separate column on the dashboard. Local Status, on the other hand, as this article explains, refers to a connection test with a cloud provider’s API.  Well, if a cloud provider API goes down for whatsoever reason, it is likely an issue I would like to get hands on with.
  • Server Owners Data: At this time, my Woo customers are individuals. Therefore, they would be the only owner and hence this data is not required.

The code snippets below is what I used to remove these items from server as well as App CPT screens. In my test setup, I am checking for WP Administrator and WPCDAdmin user roles and excluding these. You may choose a more, or a less restrictive user-role array.

// Remove WPCD Server Group Admin Coloum
add_filter( 'manage_wpcd_app_server_posts_columns', 'remove_server_group_column', 99, 1 );
function remove_server_group_column( $columns ) {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
  		unset( $columns['wpcd_server_group'] );
		unset( $columns['wpcd_local_status'] );
	}
	return ($columns);
}
// Remove WPCD App Group Admin Column
add_filter( 'manage_wpcd_app_posts_columns', 'remove_app_group_column', 99, 1 );
function remove_app_group_column( $columns ) {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
		unset( $columns['wpcd_app_group'] );
	}
	return $columns;
}

To remove the dropdown filters I’d prefer to use a standard hook. However, I could not figure out a way to do so after reviewing WPCD plugin files. Hence the CSS below.

// Remove WPCD Dropdown Filters from it's Screens
add_action('admin_head', 'wpcd_hide_dropdowns');
function wpcd_hide_dropdowns() {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	echo '<style type="text/css">#filter-by-wpcd_app_server_group { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpcd_app_group { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-app_type { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpcd_server_owner { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpcd_app_owner { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpapp_page_cache_status { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpapp_object_cache_status { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpapp_php_version { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#filter-by-wpcd_server_current_state { display: none; visibility: hidden; }</style>';
	}
}

Removing Post Row Actions (item number 6)

Unlike all other points in this article, this one tries to address a gap that could potentially break a business workflow for Woo subscribers.

Perhaps it is safe to assume that buyers should be able to trash their assets directly from a screen with a list of servers or apps they own. But in the context of WooCommerce Subscriptions, offering such post row actions (or Bulk Edit options) poses a peculiar problem. Consider a scenario when a customer trashes a server or app for which there’s an active WooCommerce Subscription on their account. What happens to that subscription?

Therefore, until WPCD releases a fix that ties in the Woo Subscription status with post row actions or offers a configurable option to unset (not hide with CSS) such post row actions, I find it worth to remove these manually from a customer’s dashboard.

// Remove WPCD CPT Row Actions of Quick Edit, Trash, Logs, and Install WordPress for Non Admin Users
add_filter( 'post_row_actions', 'remove_quick_edit_trash', 999 );
function remove_quick_edit_trash( $actions = array() ) {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	if ( isset( $actions['inline hide-if-no-js'] ) ) {
        unset( $actions['inline hide-if-no-js'] );
    }
	if ( isset( $actions['trash'] ) ) {
        unset( $actions['trash'] );
    }
    if ( isset( $actions['wpcd_remove_site'] ) ) {
        unset( $actions['wpcd_remove_site'] );
    }
	    if ( isset( $actions['wpcd_show_old_logs'] ) ) {
        unset( $actions['wpcd_show_old_logs'] );
    }
	    if ( isset( $actions['wpcd_install_app'] ) ) {
        unset( $actions['wpcd_install_app'] );
    }
	}
	return $actions;
}

Although ideally this should be considered as a fix,  and not an enhancement request, but if you are interested, here are the respective Trello records – Delete Server Link and Delete Site Link.

Exception to Removing Post Row Action: Contributions welcome

The snippet above removes post row actions for all customers. So, if a server subscriber creates apps on their server, they are unable to delete their own apps, which obviously are not linked with a Woo subscription and hence this is not a desirable outcome. In other words, the exception is to retain these post row action links if the current logged-in user, owner of the app, and the owner of the parent server are all the same. I believe WPCD will factor this exception in as part of the associated fix or feature requests on Trello. Meanwhile, you are welcome to contribute a snippet to handle this exception. We can add it inline with credits to you.

Removing WP Screen Options and Help Tabs, and Footer (items numbered 7-9)

There’s no functional reason to remove the footer. It is a styling choice. On the other hand, I want to standardize the dashboard for all my customers to a single-column view without any sidebar metaboxes or widgets. After doing so, there’s no utility to retain item number 7 (visible on the top right corner of every WP Dashboard). Therefore, let us further declutter the dashboard by removing the unnecessary WP Screen Options and Help tabs.

// Remove WordPress Screen and Help Options
add_filter('screen_options_show_screen', 'remove_wordpress_screen_options');
add_filter( 'contextual_help', 'remove_wordpress_help_tab', 999, 3 );
function remove_wordpress_screen_options() { 
	if (!check_user_role(array('administrator'))) {
	return false;
}
	return true; 
}
function remove_wordpress_help_tab($old_help, $screen_id, $screen){
	if (!check_user_role(array('administrator'))) {
	$screen->remove_help_tabs();
	}
	return $old_help;
}
// Remove WordPress Footer from Dashboard
add_filter( 'admin_footer_text', '__return_empty_string', 11 ); 
add_filter( 'update_footer', '__return_empty_string', 11 );

Removing WP Dashboard Menu and Navigation Bar (items numbered 10 and 11)

Although removing the navigation bar is a style choice, the Dashboard menu (with the WordPress Welcome Screen) or the Edit Profile screen has no utility in my context. The only thing I want a customer to see, when accessing the backend, is the cloud server management dashboard. In fact, if someone types in the https://www.domain.com/wp-admin/ in their browser, they should be redirected to a page I want them to go to.

Restrict WordPress Links from Admin Bar and WordPress Dashboard with AAM Plugin

Instead of using a string of snippets to restrict the backend dashboard and to enforce URL redirections, it is far easier to use the lightweight and modular AAM plugin – you can toggle off modues that you do not want to use.

After you have installed and set up the Advanced Access Manager modules to suit your site requirements, navigate to its Backend Menu tab and choose the Customer user-role to restrict everything else but the WPCloud Deploy menu. Further, I restrict the customer user-role to only access WPCD’s server and app dashboard sub-menus and block others (such as logs, taxonomies, etc.). You may repeat this restriction process for other user roles available on your site.

Similarly, if you like, you can restrict access to the WP Admin Toolbar too. I prefer to retain the one sub-menu item of Visit Site and remove all others.

Once you are satisfied with all the restrictions for all the user-roles, head over to and configure the AAM tabs labelled Access Denied Redirect and URI Access to define the redirection rules. This is an optional step but might prove helpful to improve the UX. So, if someone familiar with WordPress types in https://www.domain.com/wp-admin, https://www.domain.com/wp-admin/index.php, or https://www.domain.com/wp-admin/profile.php, instead of being show an “access denied” page, they can be redirected to, say, the WooCommerce My Account Dashboard.

Next, while AAM plugin restricts user-roles from accessing the Dashboard Menu (with WP Welcome Message and other widgets), it does not remove the menu from the navigation bar. To do so, I use the following snippet.

// Remove WordPress Dashboard Menu Items
add_action( 'admin_menu', 'remove_admin_menus' );
function remove_admin_menus(){
	if (!check_user_role(array('administrator'))) {
	remove_menu_page ( 'index.php' );
	}
}

Now, if you prefer to make the WPCD dashboard full-width, use this styling snippet to hide the standard WP main navigation bar and to adjust the margins.

// Remove WordPress Collapse Menu Item and Toolbar
add_action('admin_head', 'wordpress_hide_leftnavmenucolumn');
function wordpress_hide_leftnavmenucolumn() {
	if (!check_user_role(array('administrator', 'wpcdadmin'))) {
	echo '<style type="text/css">#wpadminbar { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#adminmenuback { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#collapse-menu { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#adminmenuwrap { display: none; visibility: hidden; }</style>';
	echo '<style type="text/css">#wpbody { margin-left: -5%; margin-right: 5%; }</style>';
	}
}

Adding WPCD Navigation Buttons for Customers

One thing you might notice after applying the last styling snippet (titled “Code Snippet 6: Custom Dashboard – Custom Styles Set 2 for WPCD Dashboard”) is that customers now have no option to navigate. Of course, it is because we removed this menu for them. So, to solve this problem, I created two custom butttons that help a customer navigate between servers and app dashboards and to go back to the WooCommerce My Account Dashboard. Here’s the code snippet to do so.

// Add Admin Panel Navigation Buttons
add_action('admin_notices', 'cloud_panel_navigation');
function cloud_panel_navigation() {
    global $pagenow;
    if (( $pagenow == 'edit.php' ) && ($_GET['post_type'] == 'wpcd_app_server')) {
        echo '<button type="button" style="margin-top:8px; margin-right:16px; background-color: white"><p><a href="https://www.domain.com/wp-admin/edit.php?post_type=wpcd_app">Manage Sites</a></p></button>';
		echo '<button type="button"><p><a href="https://www.domain.com/my-account">My Account Dashboard</a></p></button>';
    }
    if (( $pagenow == 'edit.php' ) && ($_GET['post_type'] == 'wpcd_app')) {
        echo '<button type="button" style="margin-top:8px; margin-right:16px; background-color: white"><p><a href="https://www.domain.com/wp-admin/edit.php?post_type=wpcd_app_server">Manage Servers</p></button>';
		echo '<button type="button"><p><a href="https://www.domain.com/my-account">My Account Dashboard</a></p></button>';
    }

}

Note: In the snippet above, please substitute the string www.domain.com with your own domain name.

Once you apply this snippet and login with a customer-role user account, you will notice these two buttons placed top left of the dashboard – usually a location for admin notices.

Part II – WPCD Server and App Management Screens

Well done, if you are still reading this! We have covered bulk of the modifications, including some (items numbered 7 through 11 above) that are common to both parts of this article. Now, let us clean up the main dashboards for servers and apps. To begin with, this is what a default screen looks like to a WooCommerce server or site subscriber.

I do not see a reason to display the metaboxes and widgets to Woo customers. Again, these are indeed helpful to a site admin. Just not to a customer who buys servers or sites. To remove the metaboxes and widgets, there are two options. You could use the AAM plugin or code snippets. Please note that the Advanced Access Manager will merely hide these from view. Therefore, in this case, I prefer to use custom code snippets.

// Remove WPCD Auto-Generated Server and App Group Metaboxes for Non Admin User Roles
add_action('admin_menu', 'remove_server_and_app_group_metaboxes', 999);
function remove_server_and_app_group_metaboxes() {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	$args = array(
       'public'   => true,
       '_builtin' => false
    );
    $custom_post_types = array( 'wpcd_app_server', 'wpcd_app' );
    foreach ($custom_post_types as $i => $wpcd_post_type) {
        $taxonomy_objects = get_object_taxonomies( $wpcd_post_type, 'object' );
        foreach ($taxonomy_objects as $j => $tax_obj) {
            if($tax_obj->hierarchical){
                $div_id = $tax_obj->name . 'div';
            } else {
                $div_id = 'tagsdiv-' . $tax_obj->name;
            }
            remove_meta_box($div_id, $wpcd_post_type, 'side');
        }
    }
	}
}

// Remove WPCD Server Metaboxes for Non Admin User Roles
add_action( 'admin_head' , 'remove_server_metaboxes' );
function remove_server_metaboxes() {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	$cpt_types = array( 'wpcd_app_server' );
	remove_meta_box( 'wpcd_change_server_owner', $cpt_types, 'side' );
	remove_meta_box( 'wpcd_server_delete_protection_metabox', $cpt_types, 'side' );
	remove_meta_box( 'wpcd_assign_teams', $wpcd_cpt_types, 'side' );
	remove_meta_box( 'wpcd_labels_notes', $cpt_types, 'normal' );
	remove_meta_box( 'wpcd_email_notification_addresses', $cpt_types, 'normal' );
	}
}

// Remove WPCD App Metaboxes for Non Admin User Roles
add_action( 'admin_head' , 'remove_app_metaboxes' );
function remove_app_metaboxes() {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	$cpt_types = array( 'wpcd_app' );	
	remove_meta_box( 'wpcd_change_app_owner', $cpt_types, 'side' );
	remove_meta_box( 'wpcd_app_delete_protection_metabox', $cpt_types, 'side' );
	remove_meta_box( 'wpcd_template_flags', $cpt_types, 'side' );
	remove_meta_box( 'wpcd_labels_notes', $cpt_types, 'normal' );
	remove_meta_box( 'wpcd_email_notification_addresses', $cpt_types, 'normal' );
	}
}

// Remove WordPress Publish Metabox from WPCD CPT Screens
add_action( 'admin_menu', 'remove_publish_metabox' );
function remove_publish_metabox() {
	if (!check_user_role(array('administrator','wpcdadmin'))) {
	$wpcd_cpt_types = array( 'wpcd_app_server', 'wpcd_app' );
    remove_meta_box( 'submitdiv', $wpcd_cpt_types, 'side' );
}
}

Finally, after we have cleaned up all the metaboxes and widgets, there’s no utility to keep these screens to a 2-column layout. Therefore, let us collapse the dashboard to a single-column with this snippet.

// Make WPCD Dashboard Single Coloumn
add_filter( "get_user_option_screen_layout_wpcd_app_server", 'single_coloumn_dashboard', 10, 3 );
add_filter( "get_user_option_screen_layout_wpcd_app", 'single_coloumn_dashboard', 10, 3 );
function single_coloumn_dashboard( $result, $option, $user ){
	if (!check_user_role(array('administrator','wpcdadmin'))) {
		return '1';
		}
	else {
		return '2';
	}
}

Now that we have applied all the custom code snippets and restrictions via AAM, the servers and apps management dashboard for customers should look like the following image.

So, that’s it. While we look forward to a native WPCD frontend dashboard, I hope you enjoyed looking at some ideas to create a minimalist WPCD backend dashboard for WooCommerce server and site subscribers. If you have tried something similar, I’d be happy to hear from you.

About the author

Abhijeet Deshpande loves to create with WordPress and other open source software. In a previous life, he grew up with 28.8 kbps modems, worked as a datacenter capacity planner, IAM specialist, and as an IT Project Management Professional (PMP). You may write to him at [email protected]

Automatic Notification Of New Articles

Sign up to get automatic notifications of new articles.  This is a different list than our standard list - you only get new articles within 24 hours of publication.  No other emails will be sent unless you sign up for our general list as well.