Extending the Client Portal

The custom plugin example in this guide is provided as-is, and support for custom code is not something we can provide.

This functionality is included in the paid Client Portal Pro extension.

This articles gives an example of how to create a custom plugin that adds extra tabs to the Portal (and how to add content to those tabs).

If you want the files used in this example, you can download them below.

This custom plugin can be installed and activated like any other WordPress plugin, like this:

How does the plugin work?

The example plugin here works by including just these three files:

  1. my-client-portal-extension.php
  2. endpoints/class-my-client-portal-extension-endpoint.php
  3. templates/my-client-portal-extension-template.php

You can add as many files to the endpoints folder in the example plugin as needed. The Client Portal will add all endpoints (each one will define a new tab) from the endpoint folder.

After adding extra tabs using this method the rewrite rules from WordPress must be refreshed. This can be done by going to WordPress’ Permalink Settings and hitting Save Changes.

1. The main plugin file

The main plugin file has only one job: to tell Client Portal where it should locate new endpoints. We will explain what is an endpoint when presenting the endpoint file.


Plugin Name: My Client Portal Extension
Plugin URI: https://jetpackcrm.com
Description: Jetpack CRM is the simplest CRM for WordPress. Extend Client Portal with this plugin.
Version: 1.0
Author: Jetpack CRM
Author URI: https://jetpackcrm.com
Text Domain: zero-bs-crm

add_action( 'jpcrm_client_portal_register_endpoint', function( $client_portal ) {
	$client_portal->add_endpoint_class_folder( plugin_dir_path( __FILE__ ) . 'endpoints' );
} );

2. The endpoint file

An endpoint is an entity that defines all the required information needed to show a certain tab, such as the tab slug, the tab name (which will be shown in the title), among others.

The endpoint file should be a class implementing the Client_Portal_Endpoint interface. There is only one mandatory function that should be implemented: register_endpoint.

Notes about this class:

  • The filename should start with class- and end with endpoint.php.
  • The name of the class should match the name of the file like the one from this example. E.g. Other_Client_Portal_Extension should be inside a file named class-other-client-portal-extension.php.
  • The slug should be unique.
  • The name will be used as the page title.
  • Multiple endpoints can use the same template if desired.
  • The namespace has to be Automattic\JetpackCRM.


 * My Client Portal Extension Endpoint
 * @author 		Jetpack CRM
 * @package 	Endpoints/My-Client-Portal-Extension
 * @see			https://jetpackcrm.com/kb/
 * @version     1.0
namespace Automattic\JetpackCRM;

if ( ! defined( 'ZEROBSCRM_PATH' ) ) exit;

class My_Client_Portal_Extension_Endpoint extends Client_Portal_Endpoint {

	public static function register_endpoint( $endpoints, $client_portal ) {
		$new_endpoint = new My_Client_Portal_Extension_Endpoint( $client_portal );

		// Set this endpoint's default values.
		$new_endpoint->portal                       = $client_portal;
		$new_endpoint->slug                         = 'my-client-portal-extension';
		$new_endpoint->name                         = 'My Client Portal Extension';
		$new_endpoint->hide_from_menu               = false;
		$new_endpoint->menu_order                   = 999;
		$new_endpoint->icon                         = 'fa-plus';
		$new_endpoint->template_name                = 'my-client-portal-extension-template.php';
		$new_endpoint->default_template_path        = plugin_dir_path( __FILE__ ) . '../templates/';
		$new_endpoint->add_rewrite_endpoint         = true;
		$new_endpoint->should_check_user_permission = true;
		$new_endpoint->hide_from_settings_page      = false;
		// Add this endpoint to the endpoint list.
		$endpoints[] = $new_endpoint;
		return $endpoints;


3. The template file

Finally, you want to have content for your endpoint. The template file is how the content will be presented in the Client Portal.

 * My Client Portal Extension Template
 * @author 		Jetpack CRM
 * @package 	Templates/My-Client-Portal-Extension
 * @see			https://jetpackcrm.com/kb/
 * @version     1.0

if ( ! defined( 'ABSPATH' ) ) exit; // Don't allow direct access

global $zbs;
$portal = $zbs->modules->portal;

do_action( 'zbs_enqueue_scripts_and_styles' );

<div class="alignwide zbs-site-main zbs-portal-grid">
	<nav class="zbs-portal-nav">

	<div class="zbs-portal-content">
		<h2>My Client Portal Extension</h2>
		<div class='zbs-entry-content' style="position:relative;">
			This is my <b>awesome</b> Client Portal Extension!
	<div class="zbs-portal-grid-footer"><?php $portal->render->portal_footer(); ?></div>

You can view example content in any of the includes templates in the modules/portal/templates/ folder of Jetpack CRM. Make sure to copy the full template and edit as appropriate.

4. Result

The result from this example should look something like the screenshot below.

Updated on January 22, 2023

Was this article helpful?

Related Articles

Still not found an answer?
If you've searched the knowledge base and still can't find a solution, please submit a ticket.