5.x-2.x branch
This module provides the "panel" node type. Panel nodes are useful to add additional content to the content area on a per-node base.
| Name | Description |
|---|---|
| panels_node_access | Implementation of hook_access(). |
| panels_node_add | |
| panels_node_admin | Page callback for the very short admin page. |
| panels_node_context_edit | Edit contexts of a panel node. |
| panels_node_context_form | The form to edit the context settings of a panel node. |
| panels_node_context_form_submit | Process submission of the panel node edit form. |
| panels_node_delete | Implementation of hook_delete(). |
| panels_node_edit_content | Pass through to the panels content editor. |
| panels_node_edit_layout | Pass through to the panels layout editor. |
| panels_node_edit_layout_settings | Pass through to the panels layout settings editor. |
| panels_node_form | Implementation of hook_form(). |
| panels_node_insert | Implementation of hook_insert(). |
| panels_node_load | Implementation of hook_load(). |
| panels_node_menu | Implementation of hook_menu(). |
| panels_node_node_info | Implementation of hook_node_info(). |
| panels_node_perm | Implementation of hook_perm(). |
| panels_node_save | Save a panel node. |
| panels_node_settings | Settings for panel nodes. |
| panels_node_update | Implementation of hook_update(). |
| panels_node_validate | Implementation of hook_validate(). |
| panels_node_view | Implementation of hook_view(). |
- <?php
-
-
- /**
- * @file panels_node.module
- *
- * This module provides the "panel" node type.
- * Panel nodes are useful to add additional content to the content area
- * on a per-node base.
- */
-
- // ---------------------------------------------------------------------------
- // General Drupal hooks
-
- /**
- * Implementation of hook_perm().
- */
- function panels_node_perm() {
- return array('create panel-nodes', 'edit own panel-nodes', 'administer panel-nodes');
- }
-
- /**
- * Implementation of hook_menu().
- */
- function panels_node_menu($may_cache) {
- if ($may_cache) {
- $items[] = array(
- 'path' => 'node/add/panel',
- 'title' => t('Panel'),
- 'access' => user_access('create panel-nodes'),
- 'type' => MENU_NORMAL_ITEM,
- );
- $items[] = array(
- 'path' => 'admin/panels/panel-nodes',
- 'title' => t('Panel nodes'),
- 'access' => user_access('create panel-nodes') && user_access('access administration pages'),
- 'type' => MENU_NORMAL_ITEM,
- 'callback' => 'panels_node_admin',
- 'description' => t('Information about panel nodes.'),
- );
-
- $items[] = array(
- 'path' => 'admin/panels/panel-nodes/information',
- 'title' => t('Information'),
- 'access' => user_access('create panel-nodes') && user_access('access administration pages'),
- 'type' => MENU_DEFAULT_LOCAL_TASK,
- );
-
- $items[] = array(
- 'path' => 'admin/panels/panel-nodes/settings',
- 'title' => t('Settings'),
- 'description' => t('Configure panel node content availability.'),
- 'access' => user_access('administer panel-nodes'),
- 'callback' => 'panels_node_settings',
- 'type' => MENU_LOCAL_TASK,
- );
- }
- else {
- if (arg(0) == 'node' && is_numeric(arg(1))) {
- $node = node_load(arg(1));
- if ($node && $node->type == 'panel' && node_access('update', $node)) {
- $base = 'node/' . arg(1) . '/panel_';
- $items[] = array(
- 'path' => $base . 'layout',
- 'title' => t('Panel layout'),
- 'access' => TRUE,
- 'callback' => 'panels_node_edit_layout',
- 'callback arguments' => array($node),
- 'weight' => 2,
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items[] = array(
- 'path' => $base . 'settings',
- 'title' => t('Panel layout settings'),
- 'access' => TRUE,
- 'callback' => 'panels_node_edit_layout_settings',
- 'callback arguments' => array($node),
- 'weight' => 2,
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items[] = array(
- 'path' => $base . 'content',
- 'title' => t('Panel content'),
- 'access' => TRUE,
- 'callback' => 'panels_node_edit_content',
- 'callback arguments' => array($node),
- 'weight' => 3,
- 'type' => MENU_LOCAL_TASK,
- );
-
- $items[] = array(
- 'path' => $base . 'context',
- 'title' => t('Context'),
- 'access' => TRUE,
- 'callback' => 'panels_node_context_edit',
- 'callback arguments' => array($node),
- 'weight' => 4,
- 'type' => MENU_LOCAL_TASK,
- );
- }
- }
- // Hard override of node/add
- if (arg(0) == 'node' && arg(1) == 'add' && arg(2) == 'panel' && arg(3) == NULL) {
- $items[] = array(
- 'path' => 'node/add/panel',
- 'title' => t('Panel'),
- 'access' => user_access('create panel-nodes'),
- 'callback' => 'panels_node_add',
- 'type' => MENU_NORMAL_ITEM,
- );
- }
- }
- return $items;
- }
-
- /**
- * Page callback for the very short admin page.
- */
- function panels_node_admin() {
- $output = '<p>';
- $output .= t('Panel nodes do not have a normal administrative UI, such as panels pages or mini panels. With this module, a new node type is created: a "panel" node. These are nodes that have panel layouts, but do not have the breadth of features that panel pages do; these features are sacrificed so that you gain all the capabilities of nodes.');
- $output .= '</p><p>';
- $output .= t('You may create a !panel_node using the normal !create_content menu, and you can administer your panel nodes under the normal !administer_nodes menu (administrative permission required).', array(
- '!panel_node' => l(t('panel node'), 'node/add/panel'),
- '!create_content' => l(t('create content'), 'node/add'),
- '!administer_nodes' => l(t('administer nodes'), 'admin/content/node'),
- ));
- $output .= '</p><p>';
- $output .= t('On the !settings page, you may control which panes may be added to panel nodes; this can be very valuable to limit what content is available if your users who can create panel nodes are not administrators.', array(
- '!settings' => l(t('settings'), 'admin/panels/panel-nodes/settings'),
- ));
- $output .= '</p>';
- return $output;
- }
-
- // ---------------------------------------------------------------------------
- // Node hooks
-
- /**
- * Implementation of hook_node_info().
- */
- function panels_node_node_info() {
- return array(
- 'panel' => array(
- 'name' => t('Panel'),
- 'module' => 'panels_node',
- 'body_label' => t('Teaser'),
- 'description' => t("A panel a page layout broken up into rows and columns."),
- ),
- );
- }
-
- /**
- * Implementation of hook_access().
- */
- function panels_node_access($op, $node = NULL) {
- if (user_access('administer panel-nodes')) {
- return TRUE;
- }
-
- if ($op == 'create' && user_access('create panel-nodes')) {
- return TRUE;
- }
-
- if ($op == 'update' && $node->uid == $user->uid && user_access('edit own panel-nodes')) {
- return TRUE;
- }
- }
-
- function panels_node_add() {
- $output = '';
-
- panels_load_include('plugins');
- // If no layout selected, present a list of choices.
- foreach (panels_get_layouts() as $id => $layout) {
- $output .= panels_print_layout_link($id, $layout, $_GET['q'] . '/' . $id);
- }
- return $output;
- }
-
- /**
- * Implementation of hook_form().
- */
- function panels_node_form(&$node, &$param) {
- $form['panels_node']['#tree'] = TRUE;
- if (!$node->nid) {
- // Grab our selected layout from the $node, If it doesn't exist, try arg(3)
- // and if that doesn't work present them with a list to pick from.
- $panel_layout = $node->panel_layout ? $node->panel_layout : arg(3);
-
- panels_load_include('plugins');
- $layout = panels_get_layout($panel_layout);
- if (empty($layout)) {
- return drupal_not_found();
- }
- $form['panels_node']['layout'] = array(
- '#type' => 'value',
- '#value' => $panel_layout,
- );
- }
-
- $type = node_get_types('type', $node);
-
- $form['title'] = array(
- '#type' => 'textfield',
- '#title' => check_plain($type->title_label),
- '#required' => TRUE,
- '#default_value' => $node->title,
- );
-
- if (!empty($type->body_label)) {
- $form['body'] = array(
- '#type' => 'textarea',
- '#title' => check_plain($type->body_label),
- '#rows' => 10,
- '#required' => TRUE,
- '#description' => t('The teaser is a piece of text to describe when the panel is listed (such as when promoted to front page); the actual content will only be displayed on the full node view.'),
- '#default_value' => $node->body,
- );
- }
-
- // drupal_set_message('<pre>' . check_plain(var_export($node, true)) . '</pre>');
- $css_id = '';
- if (!empty($node->panels_node['css_id'])) {
- $css_id = $node->panels_node['css_id'];
- }
-
- $form['panels_node']['css_id'] = array(
- '#type' => 'textfield',
- '#title' => t('CSS ID'),
- '#size' => 30,
- '#description' => t('An ID that can be used by CSS to style the panel.'),
- '#default_value' => $css_id,
- );
- return $form;
- }
-
- /**
- * Implementation of hook_validate().
- */
- function panels_node_validate($node) {
- if (!$node->nid && empty($node->panels_node['layout'])) {
- form_set_error('', t('Please select a layout.'));
- }
- }
-
- /**
- * Implementation of hook_load().
- *
- * Panels does not use revisions for nodes because that would open us up
- * to have completely separate displays, and we'd have to copy them,
- * and that's going to be a LOT of data.
- */
- function panels_node_load($node) {
- // We shortcut this because only in some really drastic corruption circumstance will this
- // not work.
- $additions['panels_node'] = db_fetch_array(db_query("SELECT * FROM {panels_node} WHERE nid = %d", $node->nid));
-
- $additions['panels_node']['contexts'] = (!empty($additions['panels_node']['contexts'])) ? unserialize($additions['panels_node']['contexts']) : array();
- $additions['panels_node']['relationships'] = (!empty($additions['panels_node']['relationships'])) ? unserialize($additions['panels_node']['relationships']) : array();
- return $additions;
- }
-
- /**
- * Implementation of hook_insert().
- */
- function panels_node_insert(&$node) {
- // Create a new display and record that.
- $display = panels_new_display();
- $display->layout = $node->panels_node['layout'];
- panels_save_display($display);
- $css_id = $node->panels_node['css_id'];
-
- db_query("INSERT INTO {panels_node} (nid, did, css_id) VALUES (%d, %d, '%s')", $node->nid, $display->did, $node->panels_node['css_id']);
-
- $node->panels_node['did'] = $display->did;
- }
-
- /**
- * Implementation of hook_delete().
- */
- function panels_node_delete(&$node) {
- db_query("DELETE FROM {panels_node} WHERE nid = %d", $node->nid);
- if (!empty($node->panels_node['did'])) {
- panels_delete_display($node->panels_node['did']);
- }
- }
-
- /**
- * Implementation of hook_update().
- */
- function panels_node_update($node) {
- db_query("UPDATE {panels_node} SET css_id = '%s' WHERE nid = %d", $node->panels_node['css_id'], $node->nid);
- }
-
- /**
- * Implementation of hook_view().
- */
- function panels_node_view($node, $teaser = FALSE, $page = FALSE) {
- panels_load_include('plugins');
- if ($teaser) {
- // Do the standard view for teaser.
- $node = node_prepare($node, $teaser);
- }
- else {
- $display = panels_load_display($node->panels_node['did']);
- $display->css_id = $node->panels_node['css_id'];
- // TODO: Find a way to make sure this can't node_view.
- $display->context = array('panel-node' => panels_context_create('node', $node));
-
- // Load additional contexts.
- $panel_node = (object)$node->panels_node;
- $display->context += panels_context_load_contexts($panel_node);
-
- $node->content['body'] = array(
- '#value' => panels_render_display($display),
- '#weight' => 0,
- );
- }
-
- return $node;
- }
-
- /**
- * Save a panel node.
- *
- * While panels_node_update() is run when a panel node is edited, this function
- * must be run to update the enhanced panel node configuration, f.e. contexts,
- * which are not edited on the regular node edit page.
- *
- * @see panels_node_update(), panels_node_context_form_submit()
- */
- function panels_node_save($panel_node) {
- db_query("UPDATE {panels_node} SET contexts = '%s', relationships = '%s' WHERE nid = %d", serialize($panel_node->contexts), serialize($panel_node->relationships), $panel_node->nid);
- }
-
- // ---------------------------------------------------------------------------
- // Administrative pages
-
- /**
- * Settings for panel nodes.
- */
- function panels_node_settings() {
- panels_load_include('common');
- return drupal_get_form('panels_common_settings', 'panels_node');
- }
-
- // ---------------------------------------------------------------------------
- // Meat of the Panels API; almost completely passing through to panels.module
-
- /**
- * Pass through to the panels layout editor.
- */
- function panels_node_edit_layout($node) {
- panels_load_include('plugins');
- $display = panels_load_display($node->panels_node['did']);
- $display->context = array('panel-node' => panels_context_create('node', $node));
- return panels_edit_layout($display, t('Save'), "node/$node->nid/panel_layout");
- }
-
- /**
- * Pass through to the panels layout settings editor.
- */
- function panels_node_edit_layout_settings($node) {
- panels_load_include('plugins');
- $display = panels_load_display($node->panels_node['did']);
- return panels_edit_layout_settings($display, t('Save'), "node/$node->nid/panel_settings");
- }
-
- /**
- * Pass through to the panels content editor.
- */
- function panels_node_edit_content($node) {
- panels_load_include('plugins');
- $display = panels_load_display($node->panels_node['did']);
- $display->context = array('panel-node' => panels_context_create('node', $node));
- $display->context['panel-node']->identifier = $node->title;
-
- // Load additional contexts.
- $panel_node = (object)$node->panels_node;
- $display->context += panels_context_load_contexts($panel_node);
-
- panels_load_include('common');
- $content_types = panels_common_get_allowed_types('panels_node', $display->context);
-
- // Print this with theme('page') so that blocks are disabled while editing a display.
- // This is important because negative margins in common block layouts (i.e, Garland)
- // messes up the drag & drop.
- print theme('page', panels_edit($display, "node/$node->nid/panel_content", $content_types), FALSE);
- }
-
- /**
- * Edit contexts of a panel node.
- *
- * FIXME: panels_node_edit_context() already defined in arguments/node_edit.inc.
- */
- function panels_node_context_edit($node) {
- panels_load_include('plugins');
-
- $panel_node = (object)$node->panels_node;
- $panel_node->nid = $node->nid;
-
- $cache = panels_common_cache_get('panel_object:panel_node', $panel_node->did);
- if (!$cache) {
- panels_common_cache_set('panel_object:panel_node', $panel_node->did, $panel_node);
- }
- else {
- $panel_node = $cache;
- }
-
- drupal_set_title(check_plain($node->title));
- return drupal_get_form('panels_node_context_form', $panel_node);
- }
-
- /**
- * The form to edit the context settings of a panel node.
- */
- function panels_node_context_form($panel_node) {
- drupal_add_css(panels_get_path('css/panels_admin.css'));
-
- $form['panel_node'] = array(
- '#type' => 'value',
- '#value' => $panel_node,
- );
-
- $form['right'] = array(
- '#prefix' => '<div class="right-container">',
- '#suffix' => '</div>',
- );
-
- $form['left'] = array(
- '#prefix' => '<div class="left-container">',
- '#suffix' => '</div>',
- );
-
- panels_load_include('common');
- // FIXME: Common panels forms are based on $object->name instead of did.
- $panel_node->name = $panel_node->did;
-
- $settings = panels_common_add_context_form('panel_node', $form, $form['right']['contexts_table'], $panel_node);
- $settings += panels_common_add_relationship_form('panel_node', $form, $form['left']['relationships_table'], $panel_node);
- panels_common_add_context_js($settings);
-
- $label = t('Save');
- $form['submit'] = array(
- '#type' => 'submit',
- '#value' => $label,
- );
-
- return $form;
- }
-
- /**
- * Process submission of the panel node edit form.
- */
- function panels_node_context_form_submit($form_id, $form_values) {
- $panel_node = $form_values['panel_node'];
-
- // Organize these from the common form.
- panels_common_save_context('context', $panel_node->contexts, $form_values);
- panels_common_save_context('relationship', $panel_node->relationships, $form_values);
-
- drupal_set_message(t('Your changes have been saved.'));
- panels_node_save($panel_node);
- panels_common_cache_clear('panel_object:panel_node', $panel_node->did);
- }
-
-