ClassExtender Class Tutorial

If you use this extra and like it, please consider donating. The suggested donation for this extra is $10.00, but any amount you want to give is fine (really). For a one-time donation of $50.00 you can use all of my non-premium extras with a clear conscience.

ClassExtender 2.3.3 for MODX Revolution has been completely refactored, with new features and much easier ways to perform each action. It is fully MODX 3 compatible

What does ClassExtender Do?

ClassExtender makes it easy create custom database tables and their corresponding xPDO-friendly classes. The two main classes it is designed to create are extended versions of the modUser and modResource objects in MODX, but ClassExtender can create any custom class and a DB table to go with it.

Sometimes you need extra fields that are not included in standard MODX objects like modUser, modUserProfile or modResource. You also need a database table to store the extra data.

As of version 2.3.3-pl, ClassExtender can produce a schema, database tables, and class files for any custom MODX object. And it can handle multiple objects in a single schema, and produce class files and DB tables for all of them.

The extended classes will be xPDO-friendly, which makes it easy to update them in the database, search for your extended data, and display it. There is also an autoloader for you custom classes.

There is a detailed tutorial on creating custom classes and DB tables to store their data on this page this page. If you are new to creating custom classes and schemas, you may want to run through that tutorial before reading the rest of this page. The information below will make a lot more sense to you once you've followed the steps on that page.

If you are upgrading from a version older than ClassExtender 2.0, see this page.

Installing ClassExtender

Go to System -> Package Management on the main menu in the MODX Manager and click on the "Download Extras" button. That will take you to the Revolution Repository. Put ClassExtender in the search box and press Enter. Click on the "Download" button, and once the package is downloaded, click on the "Back to Package Manager" button. That should bring you back to your Package Management grid. Click on the "Install" button next to ClassExtender in the grid. The ClassExtender package should now be installed.

New or Updated Features

  • Simpler operations for creating tables and classes
  • Simplified process to create schemas from existing DB tables
  • Ability to handle multiple tables when creating schemas
  • Ability to handle multiple classes inside a schema
  • Fast autoloader for custom classes
  • Automatic configuration of autoloader
  • Preserves enabled status for plugins during upgrades
  • Leaves DB tables in place on uninstall
  • Improves error handling and error messages
  • Many added lexicon strings for internationalization


Here are some things to keep in mind as you create your classes and tables with ClassExtender:

  • All class names must contain the word "Data" so the autoloader can find them (example: UserData)
  • Table names should contain the word "data" (example: ext_user_data)
  • Table names must be in "snake case" (see previous list item)
  • Use a singular noun for table names and class names
  • Use a different table prefix than your MODX table prefix.
  • Table prefixes should be in lowercase and end with an underscore (ext_)
  • Class names must be in PascalCase (example:UserData)
  • If you create the database table(s) first (rather than the schema), MODX will derive the class names from the table names by removing the prefix and underscores, and converting what's left to PascalCase (see this page for details
  • If you create the DB tables first, and all your custom tables have the same prefix, MODX will put all the classes in one schema, but will create separate class files for each object.
  • If a table already exists, ClassExtender will leave it alone.

It's important to make sure your table prefix is different from the MODX table prefix. Otherwise, MODX will create a schema containing every MODX class!

If your table prefix's first letter comes before the first letter of your MODX prefix, your custom tables will appear at the top in PhpMyAdmin.

Why Extend modUser and modResource?

You probably know the answer to this question, otherwise you wouldn't be here. If not, you can see these pages:

Why Extend modUser

Why Extend modResource

Two Approaches to Extending MODX objects

With ClassExtender, we're not using the word "Extend" in its usual PHP meaning, though the results are almost the same (more on this in a bit).

The modUser object (combined with the modUserProfile object) has many fields, but it may not contain fields you need (for example, fields like height, weight, or age). You want to add extra fields for the object, and save them in the DB, without changing any original MODX object. We might want to do the same thing with modResource.

There are two ways to reach our goal: the traditional approach, and the ClassExtender approach. With either approach, you get to save, search, and sort the data quickly and efficiently. Either one is far superior to storing resource data in TVs, or storing user data in the `extended` field of the user profile. We'll discuss the two methods in the two sections below.

The Traditional Approach

The traditional method of extending modUser is documented here, and the traditional method of extending modResource is documented here.

You don't need to consult those pages to use ClassExtender, but doing so may help you understand what it's doing, though ClassExtender takes a slightly different approach. It will also give you an appreciation of how much time and trouble ClassExtender is saving you, by creating the tables and classes and autoloading the classes.

The methods described in the two links just above actually extend the modUser and modResource objects in the strict PHP sense of the word. A new class extends the MODX object. The new object inherits the fields of the modUser object, and adds some of its own.

The resulting new objects have a new class key, but the added fields are stored in a separate, custom database table. The advantage of this method is that once you have either object, you can get its extra field data by calling $object->getOne('Data'). The downside is that your objects may not play nice with other custom objects that extend modUser or modResource, and you have to selectively use the alternate class keys in some situations.

The ClassExtender Approach

ClassExtender basically does the opposite of the traditional method. It doesn't really extend the modUser or modResource objects, though the result is the same. With ClassExtender, the new class object (UserData or ResourceData) holds the extra fields (as it does in the traditional approach), but it is a primary object that stands alone and no class keys are changed. In other words, the modUser and modResource class keys remains as modUser and modResource.

Our two new classes (UserData and ResourceData) extend XPDOSimpleObject, and they inherit fields and methods from it. They have no class key because all they hold is data.

The id field is inherited, and so are the methods you need to use the objects (for example, save(), load(), duplicate(), get(), set(), etc.).

This approach makes the transition to MODX 3 simpler because there are no custom class keys to deal with.

If you have the UserData object you can call $object->getOne('User') to get the related modUser object, or $object->getOne('Profile') to get the related modUserProfile object.

Similarly, if you have the ResourceData object, you can call $object->getOne('Resource') to get the related resource.

You can get the UserData or ResourceData objects directly given the ID of the user or resource like this:

$userDataObject = $modx->getObject('UserData', array('userdata_id' => $userId));

$resourceDataObject = $modx->getObject('ResourceData', array('resourcedata_id' => $resourceId));

(This is similar to the way the modUserProfile object contains the user's ID in its internalKey field.)

Using the Traditional Approach with ClassExtender

If you prefer, you can use the traditional method with ClassExtender simply by using the traditional schemas found at the links above in the "Traditional Approach" section. Put the traditional schema in the "MyExtUserSchema" or "MyExtResourceSchema" chunk. Double check to make sure that the exact spelling of classes in the schema (including all aliases) and code are consistent. You might want to change the class names to Pascal case, to make them consistent with PHP conventions for naming classes.

If you are using the ClassExtender approach described above, it's *very* strongly recommended that you not change any of the values in the ClassExtender forms or snippet tags used to extend the modUser and modResource objects, unless you have a very good reason to do so.

What Happens when you Submit the ClassExtender "Extend ModUser or Extend ModResource Forms?

Once you submit either form, ClassExtender will call the xPDO method parseSchema() to create the class and map files. Then, it will call the createObjectContainer()method to create the custom database tables.

ClassExtender will also create modExtensionPackage and modNamespace records for the package. These will be loaded automatically on every page request (including Manager requests). ClassExtender will also remove any extendeduser or extendedresource record from the extension_packages System Setting, which is now deprecated.

Finally, ClassExtender will activate the related plugin. The plugin will put the extra fields at the bottom of the Create/Edit User or Create/Edit Resource panel, fill them with the DB values (if any), and save them to the DB when you click on the "Save" button.

Once the class and map files have been created and the data is in the extra fields in the custom database table, getting the data in those extra fields is quite easy (more on this in a bit).

Extending modUser Steps

Here are the basic steps necessary to extend the modUser object. You shouldn't need to modify any fields in the form:

  1. Modify the "MyExtUserSchema" chunk to meet your needs. Usually, all you really need to change are the "fields" of the UserData object in the schema.
  2. View the "Extend modUser" resource.
  3. Click on Submit.
  4. Modify the "MyExtraUserFields" chunk to display your extra fields. Be sure to use the exact fields names specified in your schema.
  5. If necessary, modify the "ExtraUserFields" plugin to deal with fields that require special handling.

Once you've completed the steps above, you should see your extra fields on the Create/Edit User panel, and they should be saved to the ext_user_data table in the database. Any placeholders require no prefix (unlike earlier versions of ClassExtender).

Extending modResource Steps

Here are the basic steps necessary to extend the modResource object. You shouldn't need to modify any fields in the form:

  1. Modify the MyExtResourceSchema chunk to meet your needs. Usually all you need to modify are the "fields" of the ResourceData object in the schema.
  2. View the "Extend modResource" resource.
  3. Click on Submit.
  4. Modify the MyExtraResourceFields chunk to display your extra fields. Be sure to use the exact field names specified in your schema.
  5. If necessary, modify the ExtraResourceFields plugin to deal with fields that require special handling (see the plugin for an example).

Once you've completed the steps above, you should see your extra fields on the Create/Edit Resource panel, and they should be saved to the ext_resource_data table in the database. Any placeholders require no prefix (unlike earlier versions of ClassExtender).

Important: Make sure none of the names of your extra fields match existing fields in the modUser, modUserProfile, or modResource objects.

See this page to see the built-in fields.

Other Custom Classes

If you want to create custom Classes other than the UserData and ResourceData classes described above, and DB tables to store their data, see this page for a detailed tutorial.

The Schema

The recommended method for adding creating your custom classes is to create a specification for their extra fields. The specification is called a "schema" and is written in Extensible Markup Language (XML). XML is similar to HTML, but not the same. HTML is a "Markup" language that controls how a web page is displayed. XML, is strictly a "Data" language, which describes the structure of a set of data.

There are two example schema chunks in the package: "ExtUserSchema" and "ExtResourceSchema". You should never modify them! Instead, Modify the "MyExtUserSchema" and "MyExtResourceSchema" chunks. These are the chunks that are actually used by ClassExtender, and they will not be modified in future upgrades. The chunk without the "My" prefix are there for reference only, they won't be used by ClassExtender.

The chunks starting with "My" are created on a new install and filled with content from the matching chunk without the "My" prefix. ClassExtender will never modify the "My" chunks. They are there for you to modify to meet your needs, rather than having to create a new chunks from scratch.

Important! To repeat: When you edit the schema, edit the schema chunk beginning with "My" in the Manager, *not the file*. The file will be overwritten with the content of that chunk whenever you submit the form.

In MODX 3, it's recommended that you use MODX 2 style class names in your schema chunk. ClassExtender will convert them automatically for MODX 3, though you may want to check the schema file itself in the core/components/model/schema/ file to make sure it has converted all your classes correctly. Usually, this is only necessary if you are using ClassExtender to extend MODX objects other than modResource and modUser (e.g., classes for elements, processors, or controllers) *and* those classes require a database table (which they rarely do).

The resourcedata_id or userdata_id field in the table will contain the ID of the user or resource that table row is related to.

If you don't like the results, after submitting one of the two forms, just drop the ext_user_data and/or ext_resource_data table in the DB, edit your schema chunk, and submit the form again. New class and map files and a new table will be created. Important: Make very sure that the table is what you want and the schema is correct before using the table to store real data.

Remember that MODX ignores all schemas during its normal operation. That means changing a schema will have no effect until you regenerate the class and map files.

For more information about schemas, see this page of the MODX docs: Defining a Schema

Creating a Schema and Classes from an Existing Database Table

As of version 2.3.3 of ClassExtender, this is now much easier. If you have an existing table, or prefer to create one rather than creating a schema, you can use the CreateSchema snippet in the ClassExtender package to create the schema, the use the ClassExtender snippet to create the classes. For a detailed example of this method, see this page.

Using Your Extended Classes

The packages for either extended class are registered in the extension_packages table in the database and a namespace with the appropriate paths is created in the MODX namespaces table. They will be available on every page load (including Manager pages). Since the autoloader include the classes, and their metadata you shouldn't need to call addPackage() or loadClass() for them. You just need to "require" the autoloader.

Important: ClassExtender will provide an autoloader for your files, but it will only work if your custom class names contain the word "Data"' (e.g. UserData, or ResourceData), so it's important to always append Data to the class name.

Loading the Autoloader

You can include the autoloader in any plugin or snippet with this code:

require_once(MODX_CORE_PATH . 'components/classextender/model/ce_autoload.php');

As an alternative, for MODX 3 and beyond only, you can create a bootstrap.php file in the core/components/classextender/ directory, put the above code in the file, and remove any code that includes the autoloader from the snippets or plugins. MODX will load the autoloader for you on every page load. This feature may, or may not, be added to MODX 2 at some point.

Once you have run ClassExtender for an extended class, you can get the user or resource data from the extended table with xPDO anywhere in MODX (see below). The only situation where you would need to load the class or package explicitly might be for part of a CMP (e.g., a connector or processor) or code to be run outside of MODX where there is no request. In those cases, you should call addPackage(), loadClass(), or $modx->getService() as appropriate.

For details on using your custom classes, see the Example snippets below.

Extended Class File Locations

Extending modUser and modResource create two separate packages. The class files are placed in a directory with the same name as the package under the core/components/classextender/model/ directory.

The directories the autoloader will look in are entered automatically in the ce_autoload_directories System Setting, which is empty on install, and updated automatically when you run the ClassExtender snippet. This only applies to MODX 2. In MODX 3, the System Setting is ignored, since the namespace provides the path.

ClassExtender and MODX 3

ClassExtender is fully MODX 3 compatible. MODX 3 uses the package name (by default: extendeduser and extendedresource) as a namespace for the classes created by ClassExtender.

ClassExtender will automatically add the namespace to the classes and will translate a MODX 2 style schema to a MODX 3 style schema when you create the classes in MODX 3. It's recommended that you use a MODX 2 style schema even in MODX 3 to avoid having to figure out which parts of the schema require a fully qualified class name. You may want to check the final schema if you're extending something exotic like a processor, mailer class, or a transport package class. If it needs correction, modify the chunk, not the file.

Important: If you have set up your classes in MODX 2 and upgraded your site to MODX 3. You should submit the forms on the "Extend modUser" and/or "Extend modResource" pages to update your class and map files. That should be all you need to do to make the transition (assuming that the "My" chunks containing the schemas exist and are correct).

In MODX 3, your package name (e.g. extendeduser) will be used as a namespace. So, for example, your fully qualified class name would be extendeduser\UserData. If you don't specify the full class name (or add a use use statement -- see below), MODX won't find the class, and the autoloader won't be able to find the file.

You could add namespace extendeduser; at the top of your script, but then that namespace will be applied to any MODX classes that appear in the script. The best way to avoid this, is to leave out the namespace and add a use statement, like this:

  use extendeduser\UserData;
  $quote = $modx->newObject('UserData');

That won't affect any other classes in the script.

If you are writing your own snippets, be sure to check out the example snippets (which will run in either MODX 2 or MODX 3) to see the use of the MODX and ClassExtender prefixes used to let them run in MODX 3.

The Examples — Overview

The snippets and chunks included with ClassExtender that work with the extended modUser and modResource objects are not finished code. They are minimally styled and will probably not do exactly what you want. You can borrow from them to meet your needs. Create your own snippets and chunks, so they won't be overwritten by upgrades to ClassExtender. Use the "My..." prefix to make them easier to find.

modUser Examples

The extended user class examples are something I did for a client. The client needed extra fields for firstName, lastName, title, registrationDate, and company. The registrationDate field is not shown on the form. It's set to today's date. The MyExtraUserFields chunk contains the HTML to show the fields on the Create/Edit User panel. The chunk will not be modified during future upgrades of ClassExtender.

The "ExtraUserFields" plugin displays those fields on the Create/Edit user panel and saves the values to the custom table in the database. The plugin will be enabled automatically when you extend the modUser object. It uses the fields in the "MyExtraUserFields" chunk. That chunk will not be modified in upgrades to ClassExtender.

modResource Examples

The Resource examples are for an imaginary site where each resource represents an animal (at, say, a shelter, pet shop, or veterinary clinic). There are extra fields for the name, color, breed, and age of the animal. The MyExtraResourceFields chunk contains the HTML to show the fields on the Create/Edit Resource panel. It will not be modified during future upgrades of ClassExtender.

The "ExtraResourceFields" plugin displays the fields on the Create/Edit Resource panel and saves the values to the custom table in the database. The plugin will be enabled automatically when you extend the modResource object.

Example Utility Details

There are several example utility snippets included with ClassExtender. They may do what you want, or you may need to modify them.

The simplest of the utilities are SetUserPlaceholders and SetResourcePlaceholders. These simply set placeholders on a web page for the extra fields, as well as the native MODX fields. Both take a property (&userId or &resourceId) that lets you select the user or resource to get the fields for. If those are omitted, the current user or current resource is assumed.

SetUserPlaceholders will set placeholders for all fields of the User object (except sensitive fields like password), the User Profile object, and the extended fields from ClassExtender. It will not set placeholders for the traditional user profile extended fields, since you should replace those with fields in your custom table.

SetResourcePlaceholders will set placeholders for all resource fields and all extended fields from ClassExtender. It will not set placeholders for TVs, but you can use TV tags as you normally would.

The package also includes two snippets: GetExtUsers and GetExtResources. These operate a little like getResources, only without some of the bells and whistles. They use Tpl chunks to display sorted, aggregated Users or Resources based on some search criteria. You can specify the Tpl chunks, sorting, and selection criteria in the properties of the snippet tag. The placeholders should match the field names of your custom fields.

Where Property Examples

/* Get all active users with the first name 'Bob' in the
    custom fields, sorted by last name: */


/* Get all Users with the first name Bob or Susan,
   sorted by last name: */


/* Get all published resources where the breed is
   'poodle', sorted by pagetitle */


The content of the &where property just as it does is for other xPDO-based snippets like getResources or PdoResources. There are some examples here.

With the GetExtUsers snippet, you can use the username, active, and all fields in the Profile and Data tables as placeholders in the Tpl chunks.

With the GetExtResources snippet, you can use all standard resource fields and all fields in the Data tables as placeholders in the Tpl chunks.

The GetExtResources snippet will not select or display Template Variables (TVs), though you can use standard TV tags to display them.

Adding generic TV capability would have made the snippet quite slow and would defeat the purpose of moving TV data into the extra fields. If you absolutely need TVs, it will be much more efficient to modify the GetExtResources snippet code to display the particular TVs you need, and searching or sorting by TVs is a bad idea to begin with.

Similarly, the GetExtUsers snippet will not handle the traditional user extended fields, since performance will be much better if you make them custom Data fields using ClassExtender.

More Utility Snippets

There are three other utility snippets: ExtUserUpdateProfile, ExtUserRegisterPosthook, and UserSearchForm. The first is used to extend the UpdateProfile snippet (part of the Login package) to display and update the extra user fields. In simple cases, you should be able to just: 1) add the custom fields to the loggedInChunkTpl chunk used on the Update Profile page and 2) specify that chunk in the &loggedInChunk property.

Important: Make sure the resources are published, otherwise the user will end up at your error page. You may want to protect some of them with ACL entries.

Be sure the ExtUserUpdateProfile tag is above the UpdateProfile tag and that both snippets are called uncached (with the exclamation point). If any form fields require special handling (e.g., date fields), you'll have to modify the snippet to deal with them (make a copy and edit the copy).

When you are testing the Update Profile form, you may see some odd behavior if either your browser, or a password manager like LastPass, is trying to be helpful by filling in the forms for you. This generally won't affect real users.

The second snippet (ExtUserRegisterPosthook) is very similar. It saves the custom fields to the database when a user registers. Add your custom fields to the registration form.

Because of the way the Register snippet is written and the way it handles posthooks, there is no way to introduce a CSS file in the process. As a result, you either need to include the CSS file in the page template, or use inline style information (as done in the example, though it's not valid HTML code).

Note: The activation property works the opposite of the way you might expect it to. If it's 1 (true), the created user's `modUser` record will be saved as inactive, and the user will have to respond to an email (sent automatically) to become an active user, or the active field will have to be set manually.

There is also an optional &usernameField property in case you use a custom field for the username.

The third snippet (UserSearchForm) serves as an example of how to search for users using the custom fields. You will have to modify it to meet your needs.

Uninstalling ClassExtender Warnings

Important: Even though ClassExtender only needs to be run once to create the class and map files for the extended classes, DO NOT uninstall it unless you will not be using any of the extended classes. The class and map files, all chunks (including the 'My..." chunks), and the namespace, will be removed during the uninstall.

If you want to save the chunks or the class files, rename the chunks and move them out of the ClassExtender folder. Move the class files outside of the core/components/classextender directory.

To prevent the possible loss of critical data, the custom database tables are not removed. You can delete them manually in PhpMyAdmin.

When you uninstall ClassExtender, you may see some error messages. This is normal. There may also be some spurious error messages in the MODX Error Log. As long as the process is completed, you can ignore them.

During the uninstall, ClassExtender will remove its various components and namespace, and de-register the extension package(s). When the uninstall is finished, there should be no trace of ClassExtender left on your site, except for any custom database tables.


If your extra fields fail to show up in the Create/Edit User or Resource forms in the Manager, make sure the appropriate plugin in the ClassExtender category is enabled.

If you end up at the home page or your error page when using one of the utility snippets, it usually means that you do not have the view_unpublished permission. The resources should remain unpublished or hidden by ACL entries, so that bad actors can't create classes on the site. Right after installation, you might have to clear the site cache. Also, make sure the resource is not hidden by some ACL entry for the context the resource is in (e.g., 'web').

If the fields are not saved to the database when updating a user or resource, make sure the field names specified in your MyExtraUserFields or MyExtraResourceFields match those specified in your schema chunk and in the database.

Make sure the names of your classes include the word "Data", so the autoloader can find them.

One confusing aspect of the utility snippets is that you can often view them and get them to do what you want when viewing them from the Manager, where you're logged in as an admin. However, when you are vising the front-end of the site as the (anonymous) user or another user, you may not see them and will be forwarded to your error page or the login page, because you are no longer you. Publishing them will solve this, though you can also just log in to the front end as yourself. A number of the snippets should not be left in a published state unless they are protected from the public users.

ClassExtender System Settings

ClassExtender has only one System Setting. You shouldn't need to modify this setting, because its value is managed automatically by ClassExtender. This setting is ignored in MODX 3.

Setting Description Default
ce_autoload_directories Comma-separated list of directories holding class files; set automatically


ClassExtender Snippet Properties

Note: The properties do not show up on the Properties tab of the snippet. The properties should never be set there, because the snippet is used for extending both modUser and modResource, and any other classes you create with ClassExtender. Just set them with properties in the snippet tag, as in the ClassExtender example resources.

Property Description Default
package Lowercase name of the package being created (e.g., extendeduser, extendedresource) (empty)
tablePrefix Prefix for table ext_
schemaTpl Name of the Tpl chunk to use for the schema (empty)
dirPermission Directory Permission 0755
cssFile Path to CSS file to load (empty)

GetExtUsers Snippet Properties

Property Description Default
extUserInnerTpl Name of inner Tpl chunk to use for user listing extUserInnerTpl
extUserOuterTpl Name of outer Tpl chunk to use for user listing extUserOuterTpl
extUserRowTpl Name of row Tpl chunk to use for user listing -- displays individual user data extUserRowTpl
User Data Class Class for user object (e.g., UserData) UserData
where JSON string containing query criteria (empty)
sortby Field to sort by (e.g., username, Profile.fullname, Data.lastname) username
sortdir Direction to sort in (ASC, DESC) ASC
limit Number of users to retrieve null
offset Offset of first user to retrieve null
cssFile Path to CSS file to load (empty)

The &cssFile properties for all the example snippets are empty by default so that you can use your site's default CSS file for the styling to speed up page loading. You can see the default CSS file path on the example pages. You may want to copy it, include it in your snippet calls, and modify it during development.

The optional offset and limit properties are for when you have a very large number of users and want to retrieve them in batches with $modx->runSnippet('getExtUsers', $properties). The $properties variable will hold an array of property keys and values. By default (without these two properties), all users that match your criteria will be retrieved.

GetExtResources Snippet Properties

Property Description Default
extResourceInnerTpl Name of inner Tpl chunk ExtResourceInnerTpl
extResourceOuterTpl Name of outer Tpl chunk ExtResourceOuterTpl
extResourceRowTpl Name of row Tpl chunk ExtResourceRowTpl
ResourceDataClass Name of extended resource class ResourceData
sortby Field to sort by (e.g., pagetitle, Data.somefield) pagetitle
sortdir Direction to sort in (ASC, DESC) ASC
where JSON string with search criteria (empty)
cssFile Path to CSS file to load (empty)

SetUserPlaceholders Snippet Properties

Property Description Default
userId User ID empty (defaults to current user)
prefix Prefix for placeholders (empty)
cssFile Path to CSS file to load (empty)

SetResourcePlaceholders Snippet Properties

Property Description Default
resourceId ID of resource to set placeholders from empty (defaults to current resource)
prefix Prefix for placeholders (empty)
cssFile Path to CSS file to load (empty)

UserSearchForm Snippet Properties

Property Description Default
extFormTpl Tpl chunk to use for user search form ExtUserSearchFormTpl
cssFile Path to CSS file to load (empty)


I want to acknowledge the generous support provided by Jean Kindem Design in the initial stages of developing this extra.


My book, MODX: The Official Guide - Digital Edition is now available here. The paper version of the book may still be available from Amazon.

If you have the book and would like to download the code, you can find it here.

If you have the book and would like to see the updates and corrections page, you can find it here.

MODX: The Official Guide is 772 pages long and goes far beyond this web site in explaining beginning and advanced MODX techniques. It includes detailed information on:

  • Installing MODX
  • How MODX Works
  • Working with MODX resources and Elements
  • Using Git with MODX
  • Using common MODX add-on components like SPForm, Login, getResources, and FormIt
  • MODX security Permissions
  • Customizing the MODX Manager
  • Using Form Customization
  • Creating Transport Packages
  • MODX and xPDO object methods
  • MODX System Events
  • Using PHP with MODX

Go here for more information about the book.

Thank you for visiting

  —  Bob Ray