How to attach node into panelized node? I've got content type which panelized using Full page override. So I would like to attach an existing node into newly created node and assign it into the region as normally you would do this at /node/%/panelizer/page_manager/content.

How this can be achieved programatically?



So far I've the following code:

&lt;?php
# Usage: drush scr panelizer-test.drush.php

# Input variables.
$content_type = 'my_content_type';
$node_title = 'Content 1';
$did = 811; // Hardcoded display id from panels_display table (e.g. bootstrap_threecol_stacked).

# Load ctools includes.
ctools_include('plugins', 'panels');
ctools_include('common', 'panelizer');
ctools_include('context');

// Find the node in order to attach it to panelizer.
$query = new EntityFieldQuery();
$entities = $query-&gt;entityCondition('entity_type', 'node')
  -&gt;propertyCondition('type', $content_type)
  -&gt;propertyCondition('title', $node_title)
  -&gt;propertyCondition('status', 1)
  -&gt;range(0,1)
  -&gt;execute();


if (!empty($entities['node'])) {
  // Load the node.
  $nid = current(array_keys($entities['node']));
  $node = node_load($nid);

  // Create an empty context object.
  $node_context = ctools_context_create('node', $node);
  $node_uuid = $node_context-&gt;data-&gt;uuid;
}

// Submit Panelizer content form (/node/%/panelizer/page_manager/content).
$new_pane = panels_new_pane('node', 'node');
$plugin = ctools_get_plugins('ctools', 'content_types', 'node');
$form_state = array(
  'contexts' =&gt; array( 'panelizer' =&gt; $node_context),
  'pane' =&gt; $new_pane,
  'plugin' =&gt; $plugin,
  'values' =&gt; array(
    'nid' =&gt; "$node_title [id: $nid]",
    'override_title' =&gt; TRUE,
    'override_title_text' =&gt; 'FOOBAR',
    'override_title_heading' =&gt; 'h2',
    'links' =&gt; FALSE,
    'build_mode' =&gt; 'teaser', // or: 'full'
    'op' =&gt; 'Finish',
  ),
  'op' =&gt; 'add',
  'subtype' =&gt; array('title' =&gt; 'Existing node'),
  'subtype_name' =&gt; 'node',
  'step' =&gt; 'form',
  'wrapper_callback' =&gt; 'ctools_wizard_wrapper',
  'conf' =&gt; array(
    'build_mode' =&gt; 'teaser',
    ),
  'no_redirect' =&gt; TRUE,
);
drupal_form_submit('ctools_node_content_type_edit_form', $form_state); // And save it.
if ($errors = form_get_errors()) print_r($errors);

// Submit Panelizer main form (/admin/structure/types/manage/%/panelizer/page_manager/content)
$display = panels_load_display($did);
$layout = ctools_get_plugins('panels', 'layouts', 'bootstrap_threecol_stacked');
$renderer = panels_get_renderer_handler('editor', $layout);
$form_state = array(
  'values' =&gt; array(
    'display_title[hide_title]' =&gt; '0',
    'display_title[title]' =&gt; '%node:title (foo-bar)',
    //'panel[pane][top]' =&gt; '12867,12868,12869,12870', // See: pids from panels_pane table
    //'panel[pane][left]' =&gt; '12860',
    'panel[pane][middle]' =&gt; "12861,12862,12863,new-$node_uuid", // We need to use new pane uuid, not node's uuid.
    //'panel[pane][right]' =&gt; '12865,12866',
    //'panel[pane][bottom]' =&gt; '',
    'op' =&gt; 'Save',
  ),
  'display' =&gt; $display,
  'renderer' =&gt; $renderer,
  'layout' =&gt; $layout,
  'no_redirect' =&gt; TRUE,
);
drupal_form_submit('panelizer_edit_content_form', $form_state); // And save it.
if ($errors = form_get_errors()) print_r($errors);
Here is a better approach by using the following function which uses modifies display in node it-self:

/**
 * Attach node into panelized node.
 *
 */
function example_attach_node_to_panelized_node($pnid, $nid, $region = 'middle') {
  $result = FALSE;
  $node = node_load($pnid);

  // Set default region based on layout.
  if (!$region) {
    switch ($node-&gt;panelizer['page_manager']-&gt;display-&gt;layout) {
      case 'landing_page':
        $region = 'primary';
        break;
      case 'sub_landing_page':
        $region = 'main';
        break;
      case 'bootstrap_threecol_stacked':
      case 'onecol':
        $region = 'middle';
        break;
    }
  }

  if (!$region) return; // Check if matching type.

  $panes = array();
  $my_block_pane_exists = FALSE;

  // Load the display.
  $display = $node-&gt;panelizer['page_manager']-&gt;display;
  $did = is_numeric($display-&gt;did) ? $display-&gt;did : example_resave_display($node);
  if ($display = panels_load_display($did)) {

    // Check if our pane is already there, if so, ignore the further processing.
    $panes = $display-&gt;content; // Get this display's panes.
    foreach ($panes as $pid =&gt; $pane) { // Loop through and add in our new pane.
      if ($pane-&gt;type == 'node' &amp;&amp; $pane-&gt;subtype == 'node' &amp;&amp; $pane-&gt;configuration['nid'] == $nid) {
        // If our node already exists we can skip this.
        $my_block_pane_exists = TRUE;
        return FALSE;
      }
    }

    // Attach our new panel.
    $uuid = ctools_uuid_generate();
    $new_pane = panels_new_pane('node', 'my_node', TRUE);
    $new_pane-&gt;uuid = $uuid;
    $new_pane-&gt;pid = "new-" . $uuid;
    $new_pane-&gt;panel = $region;
    $new_pane-&gt;shown = 1;
    $new_pane-&gt;configuration['nid'] = $nid;
    $new_pane-&gt;configuration['build_mode'] = 'teaser';
    $new_pane-&gt;configuration['link_node_title'] = FALSE;
    $new_pane-&gt;configuration['links'] = FALSE;
    $display-&gt;panels[$region][] = $new_pane-&gt;pid;
    $display-&gt;content[$new_pane-&gt;pid] = $new_pane;
    // Or: $display-&gt;add_pane($new_pane, $sourcePane-&gt;panel);

    if (!$my_block_pane_exists) {
      // Finished reordering pane's and save the panelized node.
      $node-&gt;panelizer['page_manager']-&gt;display = $display;
      $node-&gt;panelizer['page_manager']-&gt;display_is_modified = TRUE;
      $result = node_save($node);
      // Clear ctools caches.
      ctools_include('object-cache');
      ctools_object_cache_clear('panels_node_display_cache', $pnid);
    }
  }
  return $result;
}


In case the display is not initialized yet (it's in new state), you've to re-save the display in order to perform above operations.

/**
 * Re-save panelizer display.
 * See: https://www.drupal.org/node/2537006
 *
 * @param
 *   $nid (integer)
 *     panelized node id
 *
 */
function example_resave_display($node) {
  $node = is_numeric($node) ? node_load($node) : $node;
  $display = !empty($node-&gt;panelizer) ? $node-&gt;panelizer['page_manager']-&gt;display : FALSE;
  if ($display &amp;&amp; !is_numeric($display-&gt;did)) {
    $new_display = panels_save_display($display);
    $node-&gt;panelizer['page_manager']-&gt;display = $new_display;
    $node-&gt;panelizer['page_manager']-&gt;display_is_modified = TRUE;
    node_save($node);
    ctools_include('object-cache');
    ctools_object_cache_clear('panels_node_display_cache', $node-&gt;nid);
  }
  return is_numeric($new_display-&gt;did) ? $new_display-&gt;did : FALSE;
}


Sample usage:

example_resave_display(800); // Use only in case the node is new.
example_attach_node_to_panelized_node(800, 123);
example_attach_node_to_panelized_node(800, 124);


See also: Updating Panelizer content programmatically which the above functions were based on it.