How to create CRM page controllers that extend BaseViewController.
Overview
Every CRM page registered via `la24_endpoints` must be backed by a controller class that extends `BaseViewController`. This base class handles template loading, asset enqueueing, and hook registration within the CRM lifecycle.

BaseViewController API
| Method | When to override | Purpose |
|---|---|---|
| `content()` | Always | Renders the page HTML |
| `hook_footer()` | When enqueuing scripts | Enqueues JS/CSS and localizes script data |
Both methods are called automatically by LA24Core when the endpoint is active. Always call `parent::hook_footer()` when overriding `hook_footer()`.
Minimal Controller
php
<?php
namespace MyPlugin\Controllers;
use LoyalAxis\abstracts\BaseViewController;
defined( 'ABSPATH' ) || exit;
class MyCrmPage extends BaseViewController {
public function content() {
echo '<div class="la24-panel-content"><p>Hello from My CRM Page.</p></div>';
}
}
Access Control Pattern
Check the auto-generated endpoint capability at the top of `content()`:
php
public function content() {
if ( ! la24_user_can( get_current_user_id(), 'la24_mycrmpage_access' ) ) {
la24_get_template( 'AccessDenied.php' );
return;
}
// Render page content here
}
The capability name follows the pattern `la24_{endpoint_key_lowercase}_access`. For example, endpoint key `MyCrmPage` → capability `la24_mycrmpage_access`.
Enqueueing Scripts and Localizing Data
Override `hook_footer()` to enqueue JavaScript and pass PHP data to the front-end:
php
public function hook_footer() {
parent::hook_footer();
wp_enqueue_script(
'my-crm-page',
MY_CRM_EXT_URL . 'assets/my-crm-page.js',
array( 'jquery' ),
'1.0.0',
true
);
wp_localize_script( 'my-crm-page', 'MyCrmData', array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce( 'my_crm_nonce' ),
'userId' => get_current_user_id(),
) );
}
The localized data is available in JavaScript as `window.MyCrmData`.
Rendering Templates
Use `la24_get_template()` to load PHP template files and pass variables to them:
php
public function content() {
if ( ! la24_user_can( get_current_user_id(), 'la24_mycrmpage_access' ) ) {
la24_get_template( 'AccessDenied.php' );
return;
}
la24_get_template( 'my-crm-page.php', array(
'user_id' => get_current_user_id(),
), MY_CRM_EXT_PATH . 'templates/' );
}
`la24_get_template( $template, $args, $path )`:
- `$template` — template filename
- `$args` — associative array of variables extracted into template scope
- `$path` — directory containing the template (defaults to LA24Core's own templates dir)
Template File Structure
`templates/my-crm-page.php`:
php
<?php defined( 'ABSPATH' ) || exit; ?>
<div class="la24-panel-content">
<div class="container-fluid">
<h4><?php esc_html_e( 'CRM Dashboard', 'my-crm-ext' ); ?></h4>
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-body">
<?php echo esc_html__( 'Welcome to your custom CRM page.', 'my-crm-ext' ); ?>
</div>
</div>
</div>
</div>
</div>
</div>
Variables passed via `$args` are available directly in the template scope (e.g., `$user_id`).
