MODX Quick Tip: Dynamic Resource List TV

Dec 17, 2016

Use Case

Recently I came across a requirement for a MODX TV that lists the children of the Resource currently being edited in the manager. Within days, someone commented on this post asking for the same thing!

One Solution

When the TVs render in the manager, the $resource ID isn't necessarily available in the execution context of a Snippet. Furthermore, I like to avoid using @EVAL and instead bind the TV options to a Chunk using @CHUNK.

Bob Ray's suggestion in the forums sounded solid (as Bob's suggestions often do) so this is some Plugin code that executes OnDocFormPrerender:


// Escape early if wrong event is enabled
if ($modx->context->get('key') !== 'mgr') return;

switch ($modx->event->name) {
    // Enable this event in Plugin properties
    case 'OnDocFormPrerender':
        if (!is_object($resource)) { // prevents bad error when user doesn't have perms to resource
            $modx->log(modX::LOG_LEVEL_ERROR, '[currentResourceListOptions Plugin] No Resource object on line: ' . __LINE__);
            return;
        }
        if ($resource instanceof modResource) {
            // Used in currentResourceListOptions Snippet
            $current_mgr_res_id = $resource->get('id');
            $_SESSION['current_mgr_res_id'] = $current_mgr_res_id;
        }
        break;
    default:
        break;
}

A Snippet "consumes" the session variable and runs the SQL query:


// Session var set in Plugin
$current_mgr_res_id = (int) $_SESSION['current_mgr_res_id'];
if (!$current_mgr_res_id) return '';
$query = $modx->query("SELECT pagetitle, id FROM modx_site_content WHERE parent = $current_mgr_res_id");
$results = $query->fetchAll(PDO::FETCH_ASSOC);
// I think there's some syntax to get SQL to return a formatted string without the following?
$list_options = array();
foreach($results as $result) {
    $list_options[] = $result['pagetitle'] . '==' . $result['id'];
}
$list_options = implode('||', $list_options);
return $list_options;

The Snippet is called from a Chunk, which also populates a default list option:


Default (Homepage)==[[++site_start]]||[[currentResourceListOptions]]

Finally, in the TV input options field, we bind the Chunk (assuming the Chunk name is "resource_list_options":


@CHUNK resource_list_options

That should do it. Yay for MODX!