Custom Manager Pages


What is a CMP?

A CMP, or Custom Manager Page, is simply a custom page that a developer or user can create in MODx Revolution, that can be accessed from within the manager. It can be used to create custom administration interfaces for 3rd Party Components (3PCs), or added functionality to the Revolution core.

CMPs base their paths off of what are called 'Namespaces'. These namespaces tell MODx where to look for the custom PHP controllers to load the Custom Manager Page. The Manager will search for the controller in the path provided by the Namespace. How the CMP handles redirection from there forward is up to the developer.

Creating a Namespace

You can create a Namespace through System -> Namespaces. From there, you can give it a name and path. MODx recommends to make the Namespace name lowercase.

The following window is an example of what information makes up a Namespace:

In the path, you can also use placeholders for MODx paths:

Using modAction and modMenu

Actions (modAction) and Menus (modMenu) work together to allow CMP developers to create Manager pages that directly hook into the default Manager, without hacking the MODx core. modMenu objects are the actual menu items you see on the navigation bar in the Manager. modAction objects tell the menu items what to do, usually in the form of sending a request to a controller file.

Creating the modAction

To create a modAction, go to System -> Actions. Right-click your Namespace from the 'Actions' tree and select "Create Action Here. The following window will show something similar to the following:

There are several noteworthy fields here:

  1. Controller: This is where you'll put the name of the controller file to look for. Make sure to leave off the .php extension. For example, if in your Namespace path, there is a index.php that you'll want to use to handle your CMPs, set this field to 'index'.
  2. Namespace: This is the name of the Namespace the new action belongs to. Make sure this is set to the Namespace for your Component.
  3. Parent Controller: This is currently only for organizational purposes, and poses no programmatic change if set to something else. 
  4. Load Headers: If this is checked, MODx will load the Manager header and footer files. This is recommended unless you want to have a completely separate view for your CMP.
  5. Language Topics: A comma-separated list of Lexicon Topics to load prior to the page load. They are in the standard Lexicon loading format.
  6. Assets: A placeholder field for whatever you want to put in. It is not currently used in MODx Revolution 2.0.0.

Creating the modMenu

From there, you can create your menu item by right clicking on an already-existing menu item (MODx recommends placing custom CMP's under 'Components'), and clicking 'Place Action Here'. This will load a window where you can enter details for the new modMenu:

There are also several noteworthy fields here:

  1. Text: The Lexicon Entry key that will be the menu item's displayed value. MODx will automatically load your Namespace's "default" Lexicon Topic, should it exist; so place your Lexicon Entry in that Topic.
  2. Description: The Lexicon entry key that will be used for the menu item's description.
  3. Action: The action that connects your menu to the appropriate connector. Select the modAction you just created.
  4. Icon: This field is currently not in use in MODx Revolution 2.0.0.
  5. Parameters: Allows you to specify other GET parameters to be added to the Menu's href URL should you want to.
  6. Handler: Allows you add a Javascript handler to execute instead of the default page loading action. If this is specified, the Menu will default to that handler and ignore the HREF attribute entirely. Use this if you just want to execute a JavaScript action instead of load a page.

Returning the Page

Creating a CMP is very similar to a Snippet; you'll just return the page content using the PHP 'return' statement. MODx recommends you do not use 'echo', since this will load the page content before the headers have a chance to load.

Smarty

One way to create page content is by the use of Smarty templates. The MODx Manager is powered by Smarty, a templating engine which focuses on making it easy for developers to create their own custom templates. To use a template in the Manager, you simply use the following to output the content of your list.tpl onto the page:

return $modx->smarty->fetch( '/path/to/templates/list.tpl' );

One common use of Smarty is to assign MODx configuration settings and lexicons to a "placeholder" which can then be used in your templates. For example, in your controller file you might place the following code:

$modx->smarty->assign( '_lang', $this->modx->lexicon->fetch() );

$modx->smarty->assign() takes two parameters:

  1. $tplVar [string] - The name of the placeholder.
  2. $value [string|array] - An string or associative array of data (key => value) to load into the placeholder.

Here's an example of using placeholders:

<h2 class="modx-page-header">{$_lang.mycomponent}</h2>

This would output a standard MODx Manager page header with the content of the lexicon matching the "mycomponent" key.

Plain-Old HTML

Of course, you don't need to use Smarty if you don't want to. One could simply return the HTML code in their controller, instead of calling $modx->smarty->fetch():

$o = '<div class="test"><h2>My Component</h2></div>';

return $o;

Scripts and CSS

Since ExtJS plays an important part in the MODx Manager, you will probably need to include your own JavaScript files for your components.

The best way to include a JavaScript file on your page is to use $modx->regClientStartupScript(). This function takes two parameters:

  1. $src [string] - The path to your JavaScript file, or the content of the script to output.
  2. $plaintext [boolean] - Whether the $src content is a path to a file, or the actual script content. Defaults to false (file path).

You can also output custom CSS files in the same way. Simply use $modx->regClientCSS(), which accepts a single parameter: the path to your CSS file.

However, you don't have to use ExtJS in your Custom Manager Pages - you can use plain HTML, or another JS framework, if you like. If you do decide to use another JS framework, MODx recommends that you not set "Load Headers" to true on the modAction, since this will load the ExtJS scripts. You'll need to create your own header file and output that with your normal output.

Brief Overview of MODExt

More info on MODExt, the ExtJS integration for MODx Revolution, can be found here.

Custom Connectors

A Connector is essentially a PHP file whose main purpose is to provide a connection between an AJAX-based request, and a Processor file. Since Processors are usually involved in CRUD (create, read, update, and delete) operations on a database, they should never be accessed directly. Instead, by using a Connector as a proxy to connect to a Processor, additional authentication and security checks can be performed before allowing access to the Processor.

Unlike Controllers, which are used in the Manager to display an actual page (and belong in your component's /core/ directory), Connectors must be HTTP-accessible. Therefore, it's best to place them in your component's /assets/ directory. Now, let's take a look at the structure of a Connector file.

The first thing your Connector must do is include the MODx configuration file, as well as the main MODx Connector file.

<?php
$basePath = dirname( dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) );

require_once $basePath . '/config.core.php';
require_once MODX_CORE_PATH . 'config/' . MODX_CONFIG_KEY . '.inc.php';
require_once MODX_CONNECTORS_PATH . 'index.php';

Next, we simply have to 'handle' the, or pass the request data on to the appropriate Processor file.

$modx->request->handleRequest( array(
    'processors_path'   => $modx->getOption( 'core_path' ) . 'components/mycomponent/processors/',
    'location'          => ''
) );
?>

As you can see, handleRequest() accepts an array of options:

That's all there is to it! Your AJAX requests simply need to call your Connector file (with an 'action' parameter referring to the appropriate Processor file), and voila -- you can now use AJAX requests in your component!

Conclusion

CMPs allow developers to create custom manager interfaces for their MODx Components without hacking the core. They integrate seamlessly into the core MODx installation, and allow for entire custom applications to be built with MODx technologies.

See Also


Browse Space

- Pages
- News
- Labels
- Attachments
- Bookmarks
- Mail
- Advanced

Explore Confluence

- Popular Labels
- Notation Guide

Your Account

Log In

Other Features

Add Content