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:
my-client-portal-extension.php
endpoints/class-my-client-portal-extension-endpoint.php
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.
my-client-portal-extension.php
:
<?php /* 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 withendpoint.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 namedclass-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
.
:endpoints/class-my-client-portal-extension-endpoint.php
<?php /** * 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.
<?php /** * 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"> <?php $portal->render->portal_nav('my-client-portal-pro-extension'); ?> </nav> <div class="zbs-portal-content"> <h2>My Client Portal Extension</h2> <div class='zbs-entry-content' style="position:relative;"> <p> This is my <b>awesome</b> Client Portal Extension! </p> </div> </div> <div class="zbs-portal-grid-footer"><?php $portal->render->portal_footer(); ?></div> </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.
