I needed to be able to render an individual pane from a Ctools page via AJAX after a user updated a modal form. See my previous article on how to programmatically trigger AJAX and return HTML from a URL.
At the bottom of this snippet, I’m using the preprocess hook to add the pane’s ID as a HTML data attribute for my JavaScript. This part is optional, but I figured I would include it to help.
Please note: I am loading a single pane from an existing Ctools Page. This Ctools Page must be a saved and functioning page for this to work. We’re just reaching in and loading one panels pane from what would normally be an entire page.
/** * Renders a single pane from the "test_panels_page" Ctools Page. * * @param integer $pane_id The numeric pane ID for each pane in a panels variant ctools page. (This id is in the panels_pane table.) * @param integer $uid The User ID we require for the Context. * @return string The rendered markup of the pane. */ function render_pane_render($pane_id, $uid) { // Do some bootstrapping so we can use some Panels files. module_load_include('inc', 'panels', 'plugins/task_handlers/panel_context'); module_load_include('inc', 'panels', 'includes/plugins'); // Load up an existing Ctools Page called "test_panels_page" $ctools_page = page_manager_get_page_cache('page-test_panels_page'); // Turn the result array into just the object at the first index of the array. // Load the display object. $display = panels_panel_context_get_display($handler); // Load the user object that our Page Context requires. $account = user_load($uid); // Create a basic context for the user account argument. 'entity:user', 'entity', 'user', ), $account); // Stub out some $context->argument = $uid; $context->title = $account->name; $context->id = 'argument_entity_id:user_1'; $context->original_argument = $uid; $context->plugin = "user"; $display->args[] = $account->uid; $display->context[$context->id] = $context; // Get the display's renderer object. $renderer = panels_get_renderer($handler->conf['pipeline'], $display); $renderer->prepare(); // Render an individual pane of the potential multiple panes on the ctools page. $content = $renderer->render_pane($renderer->prepared['panes'][$pane_id]); // Return the rendered markup to the calling process. return $content; } // The below is optional but nice if we want easy access to a pane's ID for AJAX. /** * Implments hook_preprocess_HOOK_ID(). */ function render_pane_preprocess_panels_pane(&$variables) { // Add the a pane's DB ID to each wrapper so we can grab it for potential AJAX pane rendering. $variables['classes_array'][] = 'pane-id'; $variables['classes_array'][] = 'pane-id-' . $variables['pane']->pid; $variables['attributes_array']['data-pane-id'] = $variables['pane']->pid; }
Software engineer by profession, embedded systems tinkerer, husband, father, fantasy novel devourer, wine lush, beer and cheese connoisseur