---
title: Adding Tabs to SureCarts Dashboard
date: 2025-03-11T12:23:16Z
modified: 2026-09-22T19:51:44Z
permalink: "https://techarticles.co.uk/adding-tabs-to-surecarts-dashboard/"
type: post
status: publish
excerpt: ""
wpid: 4620
categories:
  - Blog
  - Coding
  - SureCart
  - Wordpress
timestamp: 2026-09-22T19:51:44Z
tags:
  - Blog
  - Coding
  - SureCart
  - Wordpress
---

At the time of writing and the time of embarking on this project, there was NO documented way to add additional tabs and content to the [SureCart](https://ta0.uk/surecart) Dashboard. It had been done by the excellent [SurelyWP](https://ta0.uk/surelywp) team, but it wasn’t documented. I have added this here as I hope my plea for a unified, easy hook and filter solution that is direct from SureCart is responded to and we don’t risk an unruly mess of custom templates! – If this changes, I will update this header – Until we can all use this and if we follow the rules and use the “framework” we wont break other peoples stuff

## So, on to the good stuff: how to add those tabs to the dashboard.

WordPress comes with functionality to allow this to happen; it’s just not currently enabled in the dashboard template. Thankfully, we have the ability to switch a template, too, and that’s what we are going to do. We are going to switch the default or the SurelyWP template with one of our own. We are going to use [Hooks ](https://developer.wordpress.org/plugins/hooks/)& [Filters.](https://developer.wordpress.org/plugins/hooks/filters/) These are common developer tools, and SureCart already comes with a few of these, just not for this particular item.

So I’ve taken the default Surecart template and added some filters to it that allow anyone to hook right in using a customised action hook with a prefix of `rup_sc_dashextender_`This is totally reusable, and it doesn’t matter how many people are using it and the namespace as long as it’s running this template and you’re not using the same “content” or function names. This is why I use the prefix rup\_xxxx\_xxxx in most cases.

Checking my SurelyWP plugins, I could see this is how Nelson and his team had done it this way too it makes sense its WordPress naive, so to be backwards compatible and not break my own surely plugins, after all I use support port for surecart on [Reallyusefulplugins.com](https://reallyusefulplugins.com/), I have added there hooks and filters in so if you’ve got an addon for SurelyWP and it uses there custom filters it will work with this template too (I hope, I can’t possibly test them all) but this is a public repo so you can just test your code and push me a change. If it doesn’t break the filter(s) and hook(s) it will be committed. This is community spirit for users, not gatekeeping or my code first (although my code needs to be the template running for this to work)

So the first thing i did was check what template is loading using this [plugin](https://en-gb.wordpress.org/plugins/show-current-template/). This will be useful if your using this framework and your changes are not showing if it doesn’t show the frameworks my-surecart-dashboard.php we are not successfully changing the template so how do we do that?

![Code editor displaying "Template: my-surecart-dashboard.php" with a database label "DB: local".](https://techarticles.co.uk/wp-content/uploads/2025/03/template-selector-sc-dashboard.png)

## Dashboard

Firstly note we want “Larry” & “Joe” to be able to both use this framework and that is difficult if we are all using different files, so we need to conditionally loading our files. The way we do that is by keeping everything within our namespace and globally declaring a statement as true in this case the below will not run at all if someone else has already run and included the template file we wil just be able to “hook in” to what they’ve loaded but if we are first or the only it will load ours.

So in our main plugin file or a subfile we would add the following, the location on line 12 can be changes this isn’t important whats important is we are only chaning the template once and we are all just using what is there and we are NOT changing the template file unless its in the main repo, for this to work we all need to be able to understand what to inspect.

```
<span class="line"><span style="color: #F97583">if</span><span style="color: #E1E4E8"> ( </span><span style="color: #F97583">!</span><span style="color: #E1E4E8"> </span><span style="color: #79B8FF">defined</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'RUPDASHEXTENDERSC_TEMPLATE_LOADED'</span><span style="color: #E1E4E8"> ) ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">define</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'RUPDASHEXTENDERSC_TEMPLATE_LOADED'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">true</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #6A737D">/**</span></span>
<span class="line"><span style="color: #6A737D">     * Override the SureCart dashboard template.</span></span>
<span class="line"><span style="color: #6A737D">     *</span></span>
<span class="line"><span style="color: #6A737D">     * </span><span style="color: #F97583">@param</span><span style="color: #6A737D"> </span><span style="color: #F97583">string</span><span style="color: #6A737D"> $template The original template file.</span></span>
<span class="line"><span style="color: #6A737D">     * </span><span style="color: #F97583">@return</span><span style="color: #6A737D"> </span><span style="color: #F97583">string</span><span style="color: #6A737D"> The modified template file if condition is met.</span></span>
<span class="line"><span style="color: #6A737D">     */</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">override_surecart_dashboard_template</span><span style="color: #E1E4E8">( $template ) {</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #6A737D">// Adjust 'customer-dashboard' to match your dashboard page's slug if needed.</span></span>
<span class="line"><span style="color: #E1E4E8">        $custom_template </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">plugin_dir_path</span><span style="color: #E1E4E8">( </span><span style="color: #79B8FF">__FILE__</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'templates/my-surecart-dashboard.php'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #F97583">if</span><span style="color: #E1E4E8"> ( </span><span style="color: #79B8FF">file_exists</span><span style="color: #E1E4E8">( $custom_template ) ) {</span></span>
<span class="line"><span style="color: #E1E4E8">            </span><span style="color: #F97583">return</span><span style="color: #E1E4E8"> $custom_template;</span></span>
<span class="line"><span style="color: #E1E4E8">        }</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #F97583">return</span><span style="color: #E1E4E8"> $template;</span></span>
<span class="line"><span style="color: #E1E4E8">    }</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #B392F0">add_filter</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'template_include'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">__NAMESPACE__</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</span><span style="color: #79B8FF">\\</span><span style="color: #9ECBFF">override_surecart_dashboard_template'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">9999</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
<span class="line"></span>
```PHP

The above will run once and give us the access we need to add our content

So now Larry and Joe can both load the file if needed without causing issues, the next thing they need to do is add there custom tab in my example we are going to load a normal guttenberg page called _dashboard-content_

So elsewhere in my plugin or snippet where I want to add a tab and content I can now be sure the custom template is avaliable to me and I can check that in testing using the plugin above and the response (or viewing that template in the file system)

So now we need to add our tab thats easy our template has a new filter in it so we will just use that

```
<span class="line"><span style="color: #B392F0">add_filter</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_navigation'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_navigation_custom_content'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">3</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_navigation_custom_content</span><span style="color: #E1E4E8">( $navigation, $data, $controller ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    $navigation[</span><span style="color: #9ECBFF">'custom_content'</span><span style="color: #E1E4E8">] </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> [</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'name'</span><span style="color: #E1E4E8">      </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Custom Content XXX'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ),</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'icon_name'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'my-custom-icon'</span><span style="color: #E1E4E8">, </span><span style="color: #6A737D">// Use your desired icon name (make sure your CSS targets this)</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'href'</span><span style="color: #E1E4E8">      </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">add_query_arg</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'sc-page'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'custom_content'</span><span style="color: #E1E4E8">, </span><span style="color: #B392F0">get_permalink</span><span style="color: #E1E4E8">() ),</span></span>
<span class="line"><span style="color: #E1E4E8">    ];</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #F97583">return</span><span style="color: #E1E4E8"> $navigation;</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
```PHP

So in this our adding our custom tab and its name and the sc-page and the content

Now we need to add our content to that tab and below is how we do that using add action

**Shortcode:**

```
<span class="line"><span style="color: #B392F0">add_action</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_dashboard_right_custom_content'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_tab_content_custom'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">2</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_tab_content_custom</span><span style="color: #E1E4E8">( $controller, $data ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #6A737D">// Retrieve the page by its slug (for example, 'custom-content-page')</span></span>
<span class="line"><span style="color: #E1E4E8">    $page </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">get_page_by_path</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'dashboard-content'</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #E1E4E8">    </span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #F97583">if</span><span style="color: #E1E4E8"> ( $page ) {</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">do_shortcode</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'[big_red]'</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #E1E4E8">    } </span><span style="color: #F97583">else</span><span style="color: #E1E4E8"> {</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<h2>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Content Not Found'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</h2>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<p>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Please create a page with the slug "custom-content-page" to manage your custom content.'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</p>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    }</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
<span class="line"></span>
```PHP

**A Page (dashboad-content)**

```
<span class="line"><span style="color: #B392F0">add_action</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_dashboard_right_custom_content'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_tab_content_custom'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">2</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_tab_content_custom</span><span style="color: #E1E4E8">( $controller, $data ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #6A737D">// Retrieve the page by its slug (for example, 'custom-content-page')</span></span>
<span class="line"><span style="color: #E1E4E8">    $page </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">get_page_by_path</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'dashboard-content'</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #E1E4E8">    </span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #F97583">if</span><span style="color: #E1E4E8"> ( $page ) {</span></span>
<span class="line"><span style="color: #E1E4E8">        $content </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">apply_filters</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'the_content'</span><span style="color: #E1E4E8">, $page</span><span style="color: #F97583">-></span><span style="color: #E1E4E8">post_content );</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> $content </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    } </span><span style="color: #F97583">else</span><span style="color: #E1E4E8"> {</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<h2>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Content Not Found'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</h2>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<p>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Please create a page with the slug "custom-content-page" to manage your custom content.'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</p>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    }</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
<span class="line"></span>
```PHP

### Key Points to understand

1. **Consistency is Crucial:**
    
    
    - **Filter and Action Names:** The names (like `rup_sc_dashextender_surecart_navigation` and `rup_sc_dashextender_dashboard_right`) must be consistent between the template and your custom functions. Any deviation will mean your custom code won’t be recognized. – See the naming convention this only works if we are consistant and all don’t edit the template!ThiThis It
    - **Parameter Consistency:** Ensure that the number and order of parameters in your custom functions match those expected by the hooks.
2. **Naming Conventions:**
    
    
    - Were using a reusable framework, don’t adjust filters or actions they will stop others from working so please use the `rup_sc_dashextender` naming convention and load the default template it should work for _**everyone!**_
    - The keys in the navigation array (`name`, `icon_name`, `href`) are expected to be in the correct format so that the dashboard template can properly render the custom tab.
3. **Consistency:**
    When customizing your dashboard, consistency in the identifiers is key. For example, in your code the identifier is **custom\_content**. Here’s what needs to stay consistent:

- **Navigation Key:**
    In your navigation array, you’re adding a key named `'custom_content'`. This key must match the identifier used in the query parameter (set by `add_query_arg( 'sc-page', 'custom_content', get_permalink() )`)
- **Action Hook Suffix:**
    The custom action hook is named `rup_sc_dashextender_surecart_dashboard_right_custom_content`. Notice that the ending **custom\_content** matches the navigation key. This pairing ensures that when the user clicks the tab (which sets `sc-page=custom_content`), the correct action hook is triggered to load the corresponding content.
- **Overall Identifier:**
    Using the same identifier **custom\_content** in both the filter (navigation creation) and the action (content display) ties the two together. If you change one side (e.g., the navigation key), you must update the corresponding query parameter and action hook name so that they all refer to the same identifier.

**What Stays the Same:**

- **Filter Name:**
    The filter hook used in the template (e.g., `apply_filters( 'rup_sc_dashextender_surecart_navigation', ... )`) must match exactly with the filter name used when you add your custom function via `add_filter()`.
    **Example:**

**Just like that we have a working dashboard link and it can load our shortcode, our page or some hardcoded html!**

![](https://i.ytimg.com/vi/elghOh5ReuU/maxresdefault.jpg)

I have copied and pasted below some information from the docs for this repo to assist you with doing this and understaning this but until there is an offical solution this is the best methodology that allows us all to play nice in my opinion.

**Below is the documentation**

### Navigation Customization


```
// In our dashboard template:
$data['navigation'] = apply_filters( 'rup_sc_dashextender_surecart_navigation', $data['navigation'], $data, $controller );
```

This needs to be consistent to hook into the filters there are no changes needed to the enclosed template it just works.

**Hooking in**

**Parameters Order and Count:**
When you hook into this filter, ensure that the number and order of parameters match the original declaration. In this case, the parameters are the navigation array, the data array, and the controller object.

**Example:**

```
<span class="line"><span style="color: #B392F0">add_filter</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_navigation'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_navigation'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">3</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_navigation</span><span style="color: #E1E4E8">( $navigation, $data, $controller ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #6A737D">// Add your custom tab.</span></span>
<span class="line"><span style="color: #E1E4E8">    $navigation[</span><span style="color: #9ECBFF">'custom_tab'</span><span style="color: #E1E4E8">] </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> [</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'name'</span><span style="color: #E1E4E8">      </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Custom Tab'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ),</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'icon_name'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'custom-icon'</span><span style="color: #E1E4E8">,</span></span>
<span class="line"><span style="color: #E1E4E8">        </span><span style="color: #9ECBFF">'href'</span><span style="color: #E1E4E8">      </span><span style="color: #F97583">=></span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">add_query_arg</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'sc-page'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'custom_tab'</span><span style="color: #E1E4E8">, </span><span style="color: #B392F0">get_permalink</span><span style="color: #E1E4E8">() ),</span></span>
<span class="line"><span style="color: #E1E4E8">    ];</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #F97583">return</span><span style="color: #E1E4E8"> $navigation;</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
```PHP

**Navigation Array Structure:**
The custom tab you add should have specific keys:

- `name`: The display name of the tab.
- `icon_name`: The identifier for the icon.
- `href`: The URL (often including a query parameter) that points to your custom content.

These keys are expected by the dashboard template for consistent rendering.

### Loading Custom Content

The dashboard template checks the URL for the query parameter (e.g., `?sc-page=custom_tab`) and loads content accordingly. You have three common options to render this content:

#### Option 1: Custom HTML Output

- **Action Hook Name:**
    You need to use the same action hook (e.g., `rup_sc_dashextender_surecart_dashboard_right`) provided by the dashboard template.
- **Direct Output:**
    Your function directly echoes HTML content.

```
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #B392F0">add_action</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_dashboard_right'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_tab_content_html'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">2</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_tab_content_html</span><span style="color: #E1E4E8">( $controller, $data ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<h2>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Custom HTML Content'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</h2>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<p>This is hard-coded content for the custom tab.</p>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
```PHP

#### Option 2: Loading a WordPress Page

- **Page Slug:**
    A page with a specific slug (e.g., `dashboard-content`) should exist. The function retrieves this page and processes its content.
- **Consistency in Slug:**
    The slug used in `get_page_by_path( 'dashboard-content' )` must match the actual page slug.

```
<span class="line"><span style="color: #B392F0">add_action</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_dashboard_right'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_tab_content_page'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">2</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_tab_content_page</span><span style="color: #E1E4E8">( $controller, $data ) {</span></span>
<span class="line"><span style="color: #E1E4E8">$page </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">get_page_by_path</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'dashboard-content'</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">if</span><span style="color: #E1E4E8"> ( $page ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    $content </span><span style="color: #F97583">=</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">apply_filters</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'the_content'</span><span style="color: #E1E4E8">, $page</span><span style="color: #F97583">-></span><span style="color: #E1E4E8">post_content );</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> $content;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">} </span><span style="color: #F97583">else</span><span style="color: #E1E4E8"> {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<h2>'</span><span style="color: #E1E4E8"> </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">__</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'Content Not Found'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my-surecart-dashboard'</span><span style="color: #E1E4E8"> ) </span><span style="color: #F97583">.</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</h2>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<p>Please create a page with the slug "dashboard-content".</p>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
```PHP

- Option 3: Rendering a Shortcode (preferred & easiest option)
- **Shortcode Usage:**
    You can render content through a shortcode using `do_shortcode()`. Make sure the shortcode exists and is properly registered.

**Example:**

```
<span class="line"><span style="color: #B392F0">add_action</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'rup_sc_dashextender_surecart_dashboard_right'</span><span style="color: #E1E4E8">, </span><span style="color: #9ECBFF">'my_custom_dashboard_tab_content_shortcode'</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">10</span><span style="color: #E1E4E8">, </span><span style="color: #79B8FF">2</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #F97583">function</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">my_custom_dashboard_tab_content_shortcode</span><span style="color: #E1E4E8">( $controller, $data ) {</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'<div class="my-custom-tab-content">'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #B392F0">do_shortcode</span><span style="color: #E1E4E8">( </span><span style="color: #9ECBFF">'[my_shortcode]'</span><span style="color: #E1E4E8"> );</span></span>
<span class="line"><span style="color: #E1E4E8">    </span><span style="color: #79B8FF">echo</span><span style="color: #E1E4E8"> </span><span style="color: #9ECBFF">'</div>'</span><span style="color: #E1E4E8">;</span></span>
<span class="line"><span style="color: #E1E4E8">}</span></span>
<span class="line"></span>
```PHP

### Key Points to understand

1. **Consistency is Crucial:**
    
    
    - **Filter and Action Names:** The names (like `rup_sc_dashextender_surecart_navigation` and `rup_sc_dashextender_dashboard_right`) must be consistent between the template and your custom functions. Any deviation will mean your custom code won’t be recognized.
    - **Parameter Consistency:** Ensure that the number and order of parameters in your custom functions match those expected by the hooks.
2. **Naming Conventions:**
    
    
    - Were using a reusable framework, don’t adjust filters or actions they will stop others from working so please use the `rup_sc_dashextender` naming convention and load the default template it should work for everyone!
    - The keys in the navigation array (`name`, `icon_name`, `href`) are expected to be in the correct format so that the dashboard template can properly render the custom tab.
3. **Consistency:**
    When customizing your dashboard, consistency in the identifiers is key. For example, in your code the identifier is **custom\_content**. Here’s what needs to stay consistent:

- **Navigation Key:**
    In your navigation array, you’re adding a key named `'custom_content'`. This key must match the identifier used in the query parameter (set by `add_query_arg( 'sc-page', 'custom_content', get_permalink() )`).
- **Action Hook Suffix:**
    The custom action hook is named `rup_sc_dashextender_surecart_dashboard_right_custom_content`. Notice that the ending **custom\_content** matches the navigation key. This pairing ensures that when the user clicks the tab (which sets `sc-page=custom_content`), the correct action hook is triggered to load the corresponding content.
- **Overall Identifier:**
    Using the same identifier **custom\_content** in both the filter (navigation creation) and the action (content display) ties the two together. If you change one side (e.g., the navigation key), you must update the corresponding query parameter and action hook name so that they all refer to the same identifier.

This consistency is what allows the system to correctly match the navigation item with its intended content area.

4. **Content Loading Options:**
    
    
    - **Direct HTML:** Best when content is static and doesn’t need to be edited.
    - **WordPress Page:** Ideal for content that you want site editors to manage.
    - **Shortcode Rendering:** Good for dynamic or reusable content and the best option for plugin developers, you could use if statements or other options to only render the types of pages you need.