function render_pane_content(&$pane) { $content = parent::render_pane_content($pane); // Ensure that empty panes have some content. if (empty($content->content)) { // Get the administrative title. $content_type = ctools_get_content_type($pane->type); $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context); $content->content = t('Placeholder for empty "@title"', array('@title' => $title)); $pane->IPE_empty = TRUE; } return $content; }
/** * Prepare the list of panes to be rendered, accounting for visibility/access * settings and rendering order. * * This method represents the standard approach for determining the list of * panes to be rendered that is compatible with all parts of the Panels * architecture. It first applies visibility checks, then sorts panes into * their proper rendering order, and returns the result as an array. * * Inheriting classes should override this method if that renderer needs to * regularly make additions to the set of panes that will be rendered. * * @param array $panes * An associative array of pane data (stdClass objects), keyed on pane id. * @return array * An associative array of panes to be rendered, keyed on pane id and sorted * into proper rendering order. */ function prepare_panes($panes) { // Override parent::prepare_panes, so that any access-controls are not // applied to ESI panes. This ensures that panes are al ctools_include('content'); // Use local variables as writing to them is very slightly faster $first = $normal = $last = array(); // Prepare the list of panes to be rendered foreach ($panes as $pid => $pane) { if (empty($this->admin)) { // TODO remove in 7.x and ensure the upgrade path weeds out any stragglers; it's been long enough $pane->shown = !empty($pane->shown); // guarantee this field exists. // If this pane is not displayed, skip out and do the next one. // Do not handle user-access controls here for ESI panes (handle in the // ESI rendering). if (!$this->pane_should_be_rendered($pane)) { continue; } } $content_type = ctools_get_content_type($pane->type); // If this pane wants to render last, add it to the $last array. We allow // this because some panes need to be rendered after other panes, // primarily so they can do things like the leftovers of forms. if (!empty($content_type['render last'])) { $last[$pid] = $pane; } else { if (!empty($content_type['render first'])) { $first[$pid] = $pane; } else { $normal[$pid] = $pane; } } } $this->prepared['panes'] = $first + $normal + $last; return $this->prepared['panes']; }
function render_pane_content(&$pane) { if (!empty($pane->shown) && panels_pane_access($pane, $this->display)) { $content = parent::render_pane_content($pane); } // Ensure that empty panes have some content. if (empty($content) || empty($content->content)) { if (empty($content)) { $content = new stdClass(); } // Get the administrative title. $content_type = ctools_get_content_type($pane->type); $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context); $content->content = t('Placeholder for empty or inaccessible "@title"', array('@title' => html_entity_decode($title, ENT_QUOTES))); // Add these to prevent notices. $content->type = 'panels_ipe'; $content->subtype = 'panels_ipe'; $pane->IPE_empty = TRUE; } return $content; }
/** * Prepare the list of panes to be rendered, accounting for visibility/access * settings and rendering order. * * This method represents the standard approach for determining the list of * panes to be rendered that is compatible with all parts of the Panels * architecture. It first applies visibility & access checks, then sorts panes * into their proper rendering order, and returns the result as an array. * * Inheriting classes should override this method if that renderer needs to * regularly make additions to the set of panes that will be rendered. * * @param array $panes * An associative array of pane data (stdClass objects), keyed on pane id. * @return array * An associative array of panes to be rendered, keyed on pane id and sorted * into proper rendering order. */ function prepare_panes($panes) { ctools_include('content'); // Use local variables as writing to them is very slightly faster $first = $normal = $last = array(); // Prepare the list of panes to be rendered foreach ($panes as $pid => $pane) { if (empty($this->admin)) { // TODO remove in 7.x and ensure the upgrade path weeds out any stragglers; it's been long enough $pane->shown = !empty($pane->shown); // guarantee this field exists. // If this pane is not visible to the user, skip out and do the next one if (!$pane->shown || !panels_pane_access($pane, $this->display)) { continue; } } $content_type = ctools_get_content_type($pane->type); // If this pane wants to render last, add it to the $last array. We allow // this because some panes need to be rendered after other panes, // primarily so they can do things like the leftovers of forms. if (!empty($content_type['render last'])) { $last[$pid] = $pane; } else { if (!empty($content_type['render first'])) { $first[$pid] = $pane; } else { $normal[$pid] = $pane; } } } $this->prepared['panes'] = $first + $normal + $last; return $this->prepared['panes']; }
/** * AJAX entry point to edit a pane. */ function ajax_edit_pane($pid = NULL, $step = NULL) { if (empty($this->cache->display->content[$pid])) { ctools_modal_render(t('Error'), t('Invalid pane id.')); } $pane = &$this->cache->display->content[$pid]; $content_type = ctools_get_content_type($pane->type); $subtype = ctools_content_get_subtype($content_type, $pane->subtype); $form_state = array( 'display' => &$this->cache->display, 'contexts' => $this->cache->display->context, 'pane' => &$pane, 'display cache' => &$this->cache, 'ajax' => TRUE, 'modal' => TRUE, 'modal return' => TRUE, 'commands' => array(), ); $form_info = array( 'path' => $this->get_url('edit-pane', $pid, '%step'), 'show cancel' => TRUE, 'next callback' => 'panels_ajax_edit_pane_next', 'finish callback' => 'panels_ajax_edit_pane_finish', 'cancel callback' => 'panels_ajax_edit_pane_cancel', ); $output = ctools_content_form('edit', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $pane->configuration, $step); // If $rc is FALSE, there was no actual form. if ($output === FALSE || !empty($form_state['cancel'])) { // Dismiss the modal. $this->commands[] = ctools_modal_command_dismiss(); } else if (!empty($form_state['complete'])) { panels_edit_cache_set($this->cache); $this->command_update_pane($pid); $this->commands[] = ctools_modal_command_dismiss(); } else { // This overwrites any previous commands. $this->commands = ctools_modal_form_render($form_state, $output); } }
function render_pane_content(&$pane) { $content = parent::render_pane_content($pane); // Ensure that empty panes have some content. if (empty($content) || !is_object($content) || empty($content->content)) { if (!is_object($content)) { $content = new StdClass(); } // Get the administrative title. $content_type = ctools_get_content_type($pane->type); $title = ctools_content_admin_title($content_type, $pane->subtype, $pane->configuration, $this->display->context); $content->content = t('Placeholder for empty "@title"', array('@title' => $title)); // Add these to prevent notices. $content->type = 'panels_ipe'; $content->subtype = 'panels_ipe'; $pane->IPE_empty = TRUE; } return $content; }
function edit_form(&$form, &$form_state) { ctools_include('plugins', 'panels'); // If the plugin is not set, then it should be provided as an argument: if (!isset($form_state['item']->plugin)) { $form_state['item']->plugin = $form_state['function args'][2]; } parent::edit_form($form, $form_state); $form['category'] = array('#type' => 'textfield', '#title' => t('Category'), '#description' => t('What category this layout should appear in. If left blank the category will be "Miscellaneous".'), '#default_value' => $form_state['item']->category); ctools_include('context'); ctools_include('display-edit', 'panels'); ctools_include('content'); // Provide actual layout admin UI here. // Create a display for editing: $cache_key = 'builder-' . $form_state['item']->name; // Load the display being edited from cache, if possible. if (!empty($_POST) && is_object($cache = panels_edit_cache_get($cache_key))) { $display =& $cache->display; } else { $content_types = ctools_content_get_available_types(); panels_cache_clear('display', $cache_key); $cache = new stdClass(); $display = panels_new_display(); $display->did = $form_state['item']->name; $display->layout = $form_state['item']->plugin; $display->layout_settings = $form_state['item']->settings; $display->cache_key = $cache_key; $display->editing_layout = TRUE; $cache->display = $display; $cache->content_types = $content_types; $cache->display_title = FALSE; panels_edit_cache_set($cache); } // Set up lipsum content in all of the existing panel regions: $display->content = array(); $display->panels = array(); $custom = ctools_get_content_type('custom'); $layout = panels_get_layout($display->layout); $regions = panels_get_regions($layout, $display); foreach ($regions as $id => $title) { $pane = panels_new_pane('custom', 'custom'); $pane->pid = $id; $pane->panel = $id; $pane->configuration = ctools_content_get_defaults($custom, 'custom'); $pane->configuration['title'] = 'Lorem Ipsum'; $pane->configuration['body'] = $this->lipsum; $display->content[$id] = $pane; $display->panels[$id] = array($id); } $form_state['display'] =& $display; // Tell the Panels form not to display buttons. $form_state['no buttons'] = TRUE; $form_state['no display settings'] = TRUE; $form_state['cache_key'] = $cache_key; $form_state['content_types'] = $cache->content_types; $form_state['display_title'] = FALSE; $form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display); $form_state['renderer']->cache =& $cache; $form = panels_edit_display_form($form, $form_state); // If we leave the standard submit handler, it'll try to reconcile // content from the input, but we've not exposed that to the user. This // makes previews work with the content we forced in. $form['preview']['button']['#submit'] = array('panels_edit_display_form_preview'); }
/** * Render all panes in the attached display into their panel regions, then * render those regions. * * @return array $content * An array of rendered panel regions, keyed on the region name. */ function render_regions() { ctools_include('content'); // First, render all the panes into little boxes. We do this here because // some panes request to be rendered after other panes (primarily so they // can do the leftovers of forms). $panes = $first = $normal = $last = array(); foreach ($this->display->content as $pid => $pane) { $pane->shown = !empty($pane->shown); // guarantee this field exists. // If the user can't see this pane, do not render it. if (!$pane->shown || !panels_pane_access($pane, $this->display)) { continue; } $content_type = ctools_get_content_type($pane->type); // If this pane wants to render last, add it to the $last array. We allow // this because some panes need to be rendered after other panes, // primarily so they can do things like the leftovers of forms. if (!empty($content_type['render last'])) { $last[$pid] = $pane; } else { if (!empty($content_type['render first'])) { $first[$pid] = $pane; } else { $normal[$pid] = $pane; } } } foreach ($first + $normal + $last as $pid => $pane) { $panes[$pid] = $this->render_pane($pane); } // Loop through all panels, put all panes that belong to the current panel // in an array, then render the panel. Primarily this ensures that the // panes are in the proper order. $content = array(); foreach ($this->display->panels as $panel_name => $pids) { $panel_panes = array(); foreach ($pids as $pid) { if (!empty($panes[$pid])) { $panel_panes[$pid] = $panes[$pid]; } } $content[$panel_name] = $this->render_region($panel_name, $panel_panes); } // Prevent notices by making sure that all panels at least have an entry: $panels = panels_get_regions($this->plugins['layout'], $this->display); foreach ($panels as $id => $panel) { if (!isset($content[$id])) { $content[$id] = NULL; } } return $content; }
/** * AJAX entry point to edit a pane. */ function ajax_edit_pane($pid = NULL, $step = NULL) { if (empty($this->cache->display->content[$pid])) { ctools_modal_render(t('Error'), t('Invalid pane id.')); } $pane =& $this->cache->display->content[$pid]; // Check if we should skip pane translation. if (_mlpanels_pane_skip($pane->type, $pane->subtype)) { // Pass to default renderer. return parent::ajax_edit_pane($pid, $step); } $content_type = ctools_get_content_type($pane->type); $subtype = ctools_content_get_subtype($content_type, $pane->subtype); $settings = _mlpanels_settings(); if (empty($step)) { $messages[] = t('You can translate settings for different languages, but you must set %renderer as display renderer in order to see result.', array('%renderer' => t('Multilingual Standard'))); } if ($settings['show_types']) { $messages[] = t('Pane type to disable %type', array('%type' => $pane->type . '::' . $pane->subtype)); } // Get language. $path = explode('/', $_GET['q']); $tmp = explode('_', end($path)); if ($tmp[0] == 'mlpanels') { $conf_lng = $tmp[1]; } if (empty($conf_lng)) { $conf_lng = LANGUAGE_NONE; } // Prepare language dependent config. if (!empty($pane->configuration['mlpanels'])) { $ml_config = $pane->configuration['mlpanels']; $ml_config[LANGUAGE_NONE] = $pane->configuration; unset($ml_config[LANGUAGE_NONE]['mlpanels']); } else { $ml_config[LANGUAGE_NONE] = $pane->configuration; } if (!empty($ml_config[$conf_lng])) { $configuration = $ml_config[$conf_lng]; } else { $messages[] = t('No configuration exists for this language yet, using default.'); $configuration = $ml_config[LANGUAGE_NONE]; } // Safety check. if (isset($configuration['mlpanels'])) { unset($configuration['mlpanels']); } // Change finish button text. $finish_text = t('Finish'); if ($conf_lng != LANGUAGE_NONE) { if (_mlpanels_settings('keep_window')) { $finish_text = t('Save Translation and Continue'); } else { $finish_text = t('Save Translation and Finish'); } } $form_state = array('display' => &$this->cache->display, 'contexts' => $this->cache->display->context, 'pane' => &$pane, 'display cache' => &$this->cache, 'ajax' => TRUE, 'modal' => TRUE, 'modal return' => TRUE, 'commands' => array()); $form_info = array('path' => $this->get_url('edit-pane', $pid, '%step', 'mlpanels_' . $conf_lng), 'show cancel' => TRUE, 'finish text' => $finish_text, 'next callback' => 'panels_ajax_edit_pane_next', 'finish callback' => 'panels_ajax_edit_pane_finish', 'cancel callback' => 'panels_ajax_edit_pane_cancel'); // This is used to get our form in form alter. if ($conf_lng != LANGUAGE_NONE) { $form_info['untranslate text'] = t('Remove Translation'); $form_info['untranslate hidden'] = empty($ml_config[$conf_lng]); } // Building form. $output = ctools_content_form('edit', $form_info, $form_state, $content_type, $pane->subtype, $subtype, $configuration, $step); // Add language links to the form. $languages = array(LANGUAGE_NONE => (object) array('name' => t('Default'), 'language' => LANGUAGE_NONE)) + language_list(); foreach ($languages as $lng) { $class = array('ctools-use-modal'); $class[] = $lng->language; if (empty($ml_config[$lng->language])) { $class[] = 'empty'; } if ($conf_lng == $lng->language) { $class[] = 'current'; } $links[] = l($lng->name, $this->get_url('edit-pane', $pid, $form_state['step'], 'mlpanels_' . $lng->language), array('attributes' => array('class' => $class), 'html' => TRUE)); } $output['mlpanels'] = array('#markup' => theme('item_list', array('items' => $links, 'attributes' => array('class' => array('mlpanels_lnd_list'))))); $output['mlpanels_messages'] = array('#markup' => '<div class="message-target"></div>'); // If $rc is FALSE, there was no actual form. if ($output === FALSE || !empty($form_state['cancel'])) { // Dismiss the modal. $this->commands[] = ctools_modal_command_dismiss(); } elseif (!empty($form_state['clicked_button']) && $form_state['clicked_button']['#wizard type'] == 'untranslate') { // Unset surrent translation. unset($ml_config[$conf_lng]); // Update pane configuration. $form_state['pane']->configuration = array('mlpanels' => $ml_config) + $ml_config[LANGUAGE_NONE]; // References get blown away with AJAX caching. This will fix that. $this->cache->display->content[$pid] = $form_state['pane']; panels_edit_cache_set($this->cache); $this->command_update_pane($pid); if (_mlpanels_settings('keep_window') && $conf_lng != LANGUAGE_NONE) { drupal_set_message(t('Translation removed.')); $this->commands[] = ajax_command_remove('#modal-content .messages'); $this->commands[] = ajax_command_html('#modal-content .message-target', theme('status_messages')); $this->commands[] = ajax_command_invoke('#modal-content input.pane-untranslate', 'hide'); $this->commands[] = ajax_command_invoke('.mlpanels_lnd_list a.' . $conf_lng, 'addClass', array('empty')); } else { $this->commands[] = ctools_modal_command_dismiss(); } } elseif (!empty($form_state['complete'])) { // Save our settings for selected language. $ml_config[$conf_lng] = $configuration; // Update pane configuration. $form_state['pane']->configuration = array('mlpanels' => $ml_config) + $ml_config[LANGUAGE_NONE]; // References get blown away with AJAX caching. This will fix that. $this->cache->display->content[$pid] = $form_state['pane']; panels_edit_cache_set($this->cache); $this->command_update_pane($pid); if (_mlpanels_settings('keep_window') && $conf_lng != LANGUAGE_NONE) { drupal_set_message(t('Translation updated.')); $this->commands[] = ajax_command_remove('#modal-content .messages'); $this->commands[] = ajax_command_html('#modal-content .message-target', theme('status_messages')); $this->commands[] = ajax_command_invoke('#modal-content input.pane-untranslate', 'show'); $this->commands[] = ajax_command_invoke('.mlpanels_lnd_list a.' . $conf_lng, 'removeClass', array('empty')); } else { $this->commands[] = ctools_modal_command_dismiss(); } } else { // Show messages. if ($settings['show_messages']) { if (isset($messages)) { foreach ($messages as $msg) { drupal_set_message($msg); } } } // This overwrites any previous commands. $this->commands = ctools_modal_form_render($form_state, $output); array_unshift($this->commands, array('command' => 'mlpanels_ckefix')); } }