Table of Contents
Overview
The Memberpress account page is what members see after logging in-subscriptions, payments, profile details, and more. Although WordPress manages the page slug, the markup is produced by Memberpress PHP views. That's good news: you can override those views in a child theme or in a small plugin so updates don't wipe your changes.
In this guide you'll copy the account navigation template, add a new tab (e.g. "My Calendar" for an example which we actually used on a Memberpress and Gravity Forms integration), and render custom content when visitors click that tab. We'll do it the Memberpress way so it's clean and update-safe.
Where the nav template lives
If you're using ReadyLaunch, the account navigation file is located at:
plugins/memberpress/app/views/readylaunch/account/nav.phpTwo override options
Copy that file to one of the following locations:
- {your-plugin}/templates/memberpress/readylaunch/account/nav.php
- {your-child-theme}/memberpress/readylaunch/account/nav.php
If you choose a plugin folder (Option 1)
Register your template path so Memberpress looks there first. You don't need this filter if you place overrides in a theme.
add_filter('mepr_view_paths', function($paths){
  $custom_path = trailingslashit(OUTSELLERS_GF_PLUGIN_PATH) . 'templates/memberpress';
  array_unshift($paths, $custom_path);
  return $paths;
});If you choose a child theme (Option 2)
No filter is needed. Memberpress already checks your theme for overrides. A child theme is recommended so your changes survive main-theme updates.
Render content for your new action
                                Now hook into mepr_account_nav_content to output content when the user
                                visits
                                account?action=my-calendar. You can keep things simple with inline markup,
                                or include a PHP view from your plugin.
                            
my-calendar
                                
                            add_action('mepr_account_nav_content', function($action, $user){
  if ($action === 'my-calendar') {
    // Option A: include a view from your plugin
    // include OUTSELLERS_GF_PLUGIN_PATH . 'snippets/wedo-junkremoval/otslr-templates/calendar-admin-main.php';
    // Option B: inline a small template if it's simple
    echo '<section class="mepr-my-calendar-view">
      <h3>My Calendar</h3>
      <p>Welcome, ' . esc_html($user->user_login) . '. Here is your calendar.</p>
      <div id="calendar-mount"></div>
    </section>';
    // Optional: enqueue or inline scripts/styles for this tab only
    // (see the next section for patterns)
  }
}, 11, 2);That's it-clicking "My Calendar" in the account sidebar will render your content area. If you prefer separate files for clarity, go with Option A. For a small UI, Option B keeps it self-contained.
Enqueue JS/CSS or inline them
For larger UIs (calendar widgets, charts, etc.), enqueue assets only when your tab is active:
my-calendar
                                
                            add_action('wp_enqueue_scripts', function(){
  if (isset($_GET['action']) && $_GET['action'] === 'my-calendar' && is_user_logged_in()) {
    wp_enqueue_style('my-calendar-css', plugins_url('assets/css/my-calendar.css', __FILE__), [], '1.0');
    wp_enqueue_script('my-calendar-js', plugins_url('assets/js/my-calendar.js', __FILE__), ['jquery'], '1.0', true);
  }
});For smaller enhancements, it's fine to inline a bit of JS right in your rendered template. Keep performance in mind and avoid loading heavy libraries on every account page view if users won't need them.
Quick troubleshooting
- Template not loading? Confirm your override path, and if you used a
                                    plugin folder, make sure the mepr_view_pathsfilter is in place.
- Wrong tab "active" state? The second parameter in
                                    MeprAccountHelper::active_nav()must match your action:my-calendar.
- URL looks right but no content? Verify your
                                    mepr_account_nav_contentcallback checks for$action === 'my-calendar'and that the hook priority allows it to run (priority 11 is usually safe).
- ReadyLaunch disabled? Paths may differ. Inspect the plugin's
                                    app/views/folder to confirm the active template path.