Show a Drop-Down List for the Parent Field in NewsPublisher

One of the annoyances of the NewsPublisher extra is that if you want users to be able to set the new Resource’s parent, they have to enter the ID of the parent, which they often don’t know. In the Manager, they can select the parent in the tree, but in NewsPublisher there’s no tree to select from, and giving the users a printed list of the possible parents and their IDs is a pretty ugly solution.

Adding a drop-down list would be a nice feature for NewsPublisher, but almost everyone would want some algorithm to set the possible parents, and the algorithms would be different. Someday, NewsPublisher may have this feature, but in the meantime, there is a way to do the same thing with a Resource List TV and a Plugin.

The Method

The secret is to leave out the parent field from the &show property and provide a Resource List TV called “Parent” that takes its place. Resource list is one of the built-in TV types in MODX. After the user selects a parent by name, a plugin connected to OnDocFormSave gets the parent ID from the TV and sets the parent field when the user saves the Resource in NewsPublisher. Credit is due to MODX user David Pede for suggesting the idea of using a TV.

The technique is fairly simple, though getting the Resource List TV to select the appropriate parents can be a little tricky depending on which parents you want to choose.

Creating The TV

On the Elements Tree, Right-click on “Template Variables” and select “New Template Variable”

On the “General” tab, put Parent for both the name and the caption. Be sure to capitalize the first letter. If you enter a description, whatever you enter will be shown as hover help when the mouse is over the list. I find that annoying, but you may not. To avoid it, leave the description blank.

On the “Input Options” tab, Select “Resource List” for the Input Type. Leave the Input Options Value field blank.

If you set the Allow Blank field to Yes, you’ll see a dash at the top of the drop-down list. The user may select this, and unless you’ve included “Parent” in the &required property of the NewsPublisher tag, the Resource may be saved with no parent.

Actually, you may see that dash regardless of the Allow Blank setting, due to a bug in NewsPublisher that will be fixed in the next version.

If you set “Allow Blank” to No, there is another problem that may arise. In the Manager, when you try to save any Resource that uses a Template which has the Parent TV attached without setting that TV, you’ll get a cryptic popup error message (that doesn’t mention the TV), and you won’t be able to save the Resource until you select a value for the TV. The way to avoid this is to set a default value for the TV. Set it to the ID of any existing page. Note that the default you select will be pre-selected when NewsPublisher displays the drop-down list.

You may choose to set “Allow Blank” to Yes and live with the dash. If you include the Parent TV in the &required property in the NewsPublisher tag, NewsPublisher will prevent saving the resource without selecting a parent.

Now (still on the “Input Options” tab), it’s time to set the selection of parents that will be shown. In the “Parents” field, enter a comma-separated list (no spaces) containing the IDs of any parents you want for the list. If you set “Include Parents” to Yes, the list will contain the parents and all their children. If you set it to No, the list will include only the children. You can set the “Depth” field to specify how many levels down MODX will go in selecting the children and the “Limit” field to limit the total number of possible parents shown (the default is 0, which means no limit).

You can also set the “Where” field, which specifies criteria for the search in a the form of a JSON string. It looks daunting, but it’s not as bad as it looks. The string must begin with [{ and end with }]. Inside, there will be a comma-separated list of conditions, each of which usually takes one of these forms:

"resourceFieldName:=":"value"
"resourceFieldName:!=":"value"

The first one selects Resources where the specified field is equal to the value. The second selects Resources where the field doesn’t equal that value. For example, the following where clause will select only published resources that are not deleted and not hidden from menus and it skips the Home page:

[{"published:=":"1","deleted:=":"0","hidemenu:=":"0","pagetitle:!=":"Home"}]

This one will select only published Resources that have the Container checkbox checked:

[{"published:=":"1","isfolder:=":"1"}]

Notice that the condition (:= or :!=) is inside the quotation marks and that there is a second colon separating the field/condition from the value. The “Where” string has to be a valid JSON string, so type it carefully. If it’s invalid, you’ll usually get either one or no parents in your list. There is a JSON validator here that can help you get it right. Paste in your JSON string and click on the Process button at the lower right of the form. It will let you know if the JSON is invalid and you can edit your JSON and try again.

The fields specified in the criteria (on the left side of each entry) can be any fields of the Resource object (but unfortunately, not TVs). To see a complete list, look here.

Using the examples above, a resource has to meet all the criteria to be selected. You can use more complex criteria involving AND and OR and you can also select values that are greater than or less than the value you specify, but that’s beyond the scope of this article.

If you use a “Where” clause, you still need to specify the Parents to search under in the form field above. Unfortunately, you can’t leave the Parents field blank and you can’t use 0 to search all resources on the site.

Displaying the TV

To show the TV, just include its name in the &show property in the NewsPublisher snippet tag. By default, the list of parents will be shown as a scrollable list showing 8 parents at a time. To make it look like a standard drop-down list, put this property in the NewsPublisher snippet tag:

&listboxmax=`1`

If you like the scrollable list, you can adjust the &listboxmax property to make it longer or shorter.

Creating the Plugin

The plugin code itself is very simple. On the Elements tab, right-click on “Plugins” and select “New Plugin”. Call the plugin “NewsPublisherParent” and paste this code into the “Plugin Code” section:

<?php
/* keep this from running in the Manager */
if ($modx->context->get('key') == 'mgr') {
    return;
}

/* (optional) Don't execute for existing resources --
   Remove the following line to let users modify
   existing parents in NewsPublisher */

if (!($mode == modSystemEvent::MODE_NEW)) return;

/* get parent ID from TV */
$parentId = $resource->getTVValue('Parent');

/* save the parent id in the resource's parent field */
$resource->set('parent', $parentId);
$resource->save();

On the “System Events” tab, put a checkmark next to OnDocFormSave and click on the “Save” button at the upper right.

Wrapping Up

Once the Parent TV is created, you’ve modified the NewsPublisher Tag to include it, and you’ve created the plugin, you should be good to go. It may take a little trial-and-error to get the parents selected correctly, but once that’s done, your users should be very grateful.


For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or better yet, buy my book: MODX: The Official Guide.

Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!

Tags: , , , , , , , , , , | Posted under cPanel/Linux Hosting, DotNet/Windows Hosting | RSS 2.0

Author Spotlight

Bob Ray

Bob Ray

I am the author of MODX: The Official Guide and over 30 MODX add-on components. I host Bob's Guides, a source of valuable information for MODX users, and I've been very active in the MODX Forums with over 14,000 posts.

Leave a Reply

Your email address will not be published. Required fields are marked *


7 − = 6

You may use these HTML tags and attributes: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>