I have a ctools plugin aka. content-type aka. panel pane. How does one render it programmatically ?

  • +1, very interesting question. I'm wondering though, can a ctools plugin be rendered outside of a page manager page? Since that would be void of a context, does rendering e content type still make sense?
    – Letharion
    Jul 9, 2012 at 12:04
  • Using contexts is not mandatory. Also , forcing a context manually is always an option. Like here - gist.github.com/3076130
    – roGi
    Jul 9, 2012 at 12:14

4 Answers 4


ctools_content_render() is the solution.

  • 2
    Can you provide an example of how this would work? I'm reading the docs and trying things but not getting anywhere Nov 13, 2012 at 9:33
  • Depending on where you call ctools_content_render(), you may also need to bring the ctools code into scope, otherwise you'll get fatal errors. This can be achieved with "module_load_include("inc", "ctools", "includes/content");"
    – alexkb
    Mar 24, 2014 at 5:32
  • Do not forget to include ctools_include('content'); before ctools_content_render(), because in other case you will get fatal error. Jul 7, 2015 at 12:12

There is a great and simple example on how to do this in the ctools_ajax_sample module (in the CTools suite).

As it has been pointed out, the key is to use the function ctools_content_render().

The example shows how to populate the arguments of the function, although you obviously have to customize it according to your needs.

This thread in Drupal Groups gives more insight on how to load the right context.

File ctools/ctools_ajax_sample/ctools_ajax_sample.module

function ctools_ajax_simple_form() {
  $node = node_load(1);
  $context = ctools_context_create('node', $node);
  $context = array('context_node_1' => $context);
  return ctools_content_render('node_comment_form', 'node_comment_form', ctools_ajax_simple_form_pane(), array(), array(), $context);

function ctools_ajax_simple_form_pane() {
  $configuration = array(
    'anon_links' => 0,
    'context' => 'context_node_1',
    'override_title' => 0,
    'override_title_text' => '',
  return $configuration;

If you load the required file, all you really need to do, is to call the render function (hook_content_type_render) which will return a standard class object, much like hook_block_view does.
All you need from there is a theme function, unless you just want to render the raw output directly.

In code it could look something like this:

function render_ctools_content($subtype, $conf, $panel_args, $context, $function, $file, $theme = TRUE) {
  require_once $file;
  $pane = new stdClass();
  if (function_exists($function)) {
    $pane = $function($subtype, $conf, $panel_args, $context); // hook_content_type_render
  if ($theme) {
    return theme('module_ctools_content', array('pane' => $pane));
  return $pane->content;
  • 1
    thank's for your reply. Calling the render func directly is, of course, the obvious choice. But this solution feels more like a hack. I am looking for something along the lines of "ctools_render_ctype('ctype_name')" :)
    – roGi
    Jul 9, 2012 at 13:35
  • @roGi That function doesn't exist, what I've shown above is the gist of how it would look like, but it probably won't be feasible to make something as simple as you suggest, since ctools content types aren't that simple.
    – googletorp
    Jul 9, 2012 at 13:56

I was able to pull a panelized page in panopoly using the following code:

module_load_include('inc', 'page_manager', 'plugins/tasks/node_view');
$node = node_load($nid);
$render = page_manager_node_view_page($node);
echo drupal_render($render);
  • By including plugin file with module_load_include() you may break ctools plugins loading process. CTools uses require_once method, so if file was included previously by thirdparty script it will be not possible to include it by ctools (and parse $plugin array). So as a resullt your pane will not work in other places. Jul 6, 2015 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.