r27415 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r27414‎ | r27415 | r27416 >
Date:07:27, 12 November 2007
Author:straussd
Status:old
Tags:
Comment:
Install Panels 1.2
Modified paths:
  • /trunk/fundcore/modules/panels (added) (history)
  • /trunk/fundcore/modules/panels/API.txt (added) (history)
  • /trunk/fundcore/modules/panels/CHANGELOG.txt (added) (history)
  • /trunk/fundcore/modules/panels/INSTALL.txt (added) (history)
  • /trunk/fundcore/modules/panels/LICENSE.txt (added) (history)
  • /trunk/fundcore/modules/panels/README.txt (added) (history)
  • /trunk/fundcore/modules/panels/TODO.txt (added) (history)
  • /trunk/fundcore/modules/panels/content_types (added) (history)
  • /trunk/fundcore/modules/panels/content_types/block.inc (added) (history)
  • /trunk/fundcore/modules/panels/content_types/custom.inc (added) (history)
  • /trunk/fundcore/modules/panels/content_types/node.inc (added) (history)
  • /trunk/fundcore/modules/panels/content_types/views.inc (added) (history)
  • /trunk/fundcore/modules/panels/images (added) (history)
  • /trunk/fundcore/modules/panels/images/blank.gif (added) (history)
  • /trunk/fundcore/modules/panels/images/go-bottom.png (added) (history)
  • /trunk/fundcore/modules/panels/images/go-down.png (added) (history)
  • /trunk/fundcore/modules/panels/images/go-top.png (added) (history)
  • /trunk/fundcore/modules/panels/images/go-up.png (added) (history)
  • /trunk/fundcore/modules/panels/images/screenshot-1.jpg (added) (history)
  • /trunk/fundcore/modules/panels/images/screenshot-2.jpg (added) (history)
  • /trunk/fundcore/modules/panels/images/screenshot-3.jpg (added) (history)
  • /trunk/fundcore/modules/panels/images/screenshot-4.jpg (added) (history)
  • /trunk/fundcore/modules/panels/images/user-trash.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol.png (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol_stacked.css (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol_stacked.inc (added) (history)
  • /trunk/fundcore/modules/panels/layouts/twocol_stacked.png (added) (history)
  • /trunk/fundcore/modules/panels/panels.info (added) (history)
  • /trunk/fundcore/modules/panels/panels.install (added) (history)
  • /trunk/fundcore/modules/panels/panels.module (added) (history)
  • /trunk/fundcore/modules/panels/panels_admin.css (added) (history)

Diff [purge]

Index: trunk/fundcore/modules/panels/INSTALL.txt
@@ -0,0 +1,13 @@
 2+Simply activate the module. The tables you need will be installed.
 3+
 4+Then, go to administer >> panels
 5+
 6+Select 'add'.
 7+
 8+Choose a layout; a simple one is best if you're just exploring.
 9+
 10+Choose a URL for your new panel page. 'panel/test' is good if you're just exploring.
 11+
 12+Add some content to each of the areas.
 13+
 14+Click save, then click on the URL in the list to see what your new page looks like.
Property changes on: trunk/fundcore/modules/panels/INSTALL.txt
___________________________________________________________________
Added: svn:eol-style
115 + native
Index: trunk/fundcore/modules/panels/CHANGELOG.txt
@@ -0,0 +1,27 @@
 2+Panels 5.x-1.2
 3+ o Block visibility code used improper array_merge, causing silly errors.
 4+
 5+Panels 5.x-1.1
 6+ o #120919 (by grugnog) empty content caused array error
 7+ o #102572 (by yched, harriska2, cbutera, et al) -- missing views_load_cache when using views and panels together
 8+ o #84204 (by drewish, et al) make tables install UTF-8.
 9+ o #110771 (by Robrecht Jacques) Save panel did on creation allowing modules to interact with it
 10+ o #111646 (by Robrecht Jacques) uninstall hook
 11+ o #114772 (by Tobias Maier) allow custom content to specify CSS Info
 12+ o #120913 (by Grugnog2) provide panels_is_panel_page() function for context
 13+ o #118954 (by slantview) respect block visibility settings
 14+ o #110461 (by Robrecht Jacques) fixed improper use of drupal_goto on delete submit
 15+ o #81949 (by RobRoy) fixed another problem with arrays and empty panels
 16+ o #117581 (by pearcec) Allow node types to suppress their title.
 17+ o #89174 (by amatan) fix PHP 5 referencing error.
 18+ o #93355 (by redsky) PGSQL table support
 19+ o #119841: Force page title in case menu title has been changed
 20+ o #108616 (by joel_guesclin) Change 2col stacked CSS to be more resilient in IE.
 21+ o Can now set role-based access control on panels (also patch by stephanmaximilianhuber)
 22+ o #86630: Add option to retain title on Views.
 23+ o #110449: Respect Views access settings. Requires Views 1.6 to work.
 24+ o #100793: Respect Node access settings.
 25+ o #125440: Missing args broke Views by sending NULLs when it shouldn't send anything.
 26+
 27+Panels 5.x-1.0
 28+ Initial release under the new release system.
Property changes on: trunk/fundcore/modules/panels/CHANGELOG.txt
___________________________________________________________________
Added: svn:eol-style
129 + native
Index: trunk/fundcore/modules/panels/images/go-down.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/images/go-down.png
___________________________________________________________________
Added: svn:mime-type
230 + image/png
Index: trunk/fundcore/modules/panels/images/screenshot-4.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: trunk/fundcore/modules/panels/images/screenshot-4.jpg
___________________________________________________________________
Added: svn:mime-type
331 + image/jpeg
Index: trunk/fundcore/modules/panels/images/user-trash.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/images/user-trash.png
___________________________________________________________________
Added: svn:mime-type
432 + image/png
Index: trunk/fundcore/modules/panels/images/go-top.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/images/go-top.png
___________________________________________________________________
Added: svn:mime-type
533 + image/png
Index: trunk/fundcore/modules/panels/images/go-bottom.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/images/go-bottom.png
___________________________________________________________________
Added: svn:mime-type
634 + image/png
Index: trunk/fundcore/modules/panels/images/go-up.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/images/go-up.png
___________________________________________________________________
Added: svn:mime-type
735 + image/png
Index: trunk/fundcore/modules/panels/images/screenshot-1.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: trunk/fundcore/modules/panels/images/screenshot-1.jpg
___________________________________________________________________
Added: svn:mime-type
836 + image/jpeg
Index: trunk/fundcore/modules/panels/images/blank.gif
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: trunk/fundcore/modules/panels/images/blank.gif
___________________________________________________________________
Added: svn:mime-type
937 + application/octet-stream
Index: trunk/fundcore/modules/panels/images/screenshot-2.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: trunk/fundcore/modules/panels/images/screenshot-2.jpg
___________________________________________________________________
Added: svn:mime-type
1038 + image/jpeg
Index: trunk/fundcore/modules/panels/images/screenshot-3.jpg
Cannot display: file marked as a binary type.
svn:mime-type = image/jpeg
Property changes on: trunk/fundcore/modules/panels/images/screenshot-3.jpg
___________________________________________________________________
Added: svn:mime-type
1139 + image/jpeg
Index: trunk/fundcore/modules/panels/panels.module
@@ -0,0 +1,858 @@
 2+<?php
 3+// $Id: panels.module,v 1.10.2.9 2007/03/15 23:13:41 merlinofchaos Exp $
 4+
 5+/**
 6+ * Implementation of hook_help()
 7+ */
 8+function panels_help($section = '') {
 9+ switch ($section) {
 10+ case 'admin/build/panels':
 11+ case 'admin/build/panels/list':
 12+ return t('<p>You may peruse a list of your current panels layouts and edit them, or click add to create a new page.</p>');
 13+ case 'admin/build/panels/add':
 14+ return t('<p>Choose a layout for your new page from the list below.</p>');
 15+ }
 16+}
 17+
 18+/**
 19+ * Implementation of hook_perm()
 20+ */
 21+function panels_perm() {
 22+ return array('create panels', 'access all panels');
 23+}
 24+
 25+/**
 26+ * Determine if the specified user has access to a panel.
 27+ */
 28+function panels_access($panel, $account = NULL) {
 29+ if (!$account) {
 30+ global $user;
 31+ $account = $user;
 32+ }
 33+
 34+ // Administrator privileges
 35+ if (user_access('access all panels', $account)) {
 36+ return TRUE;
 37+ }
 38+
 39+ // All views with an empty access setting are available to all roles.
 40+ if (!$panel->access) {
 41+ return TRUE;
 42+ }
 43+
 44+ // Otherwise, check roles
 45+ static $roles = array();
 46+ if (!isset($roles[$account->uid])) {
 47+ $roles[$account->uid] = array_keys($account->roles);
 48+ }
 49+
 50+ return array_intersect($panel->access, $roles[$account->uid]);
 51+}
 52+
 53+/**
 54+ * Implementation of hook_menu()
 55+ */
 56+function panels_menu($may_cache) {
 57+ if ($may_cache) {
 58+ $access = user_access('create panels');
 59+ $items[] = array(
 60+ 'path' => 'admin/build/panels',
 61+ 'title' => t('Panels'),
 62+ 'access' => $access,
 63+ 'callback' => 'panels_list_page',
 64+ 'description' => t('Create pages on your site that are 2 or 3 columns'),
 65+ );
 66+ $items[] = array(
 67+ 'path' => 'admin/build/panels/list',
 68+ 'title' => t('List'),
 69+ 'access' => $access,
 70+ 'callback' => 'panels_list_page',
 71+ 'weight' => -10,
 72+ 'type' => MENU_DEFAULT_LOCAL_TASK,
 73+ );
 74+ $items[] = array(
 75+ 'path' => 'admin/build/panels/add',
 76+ 'title' => t('Add'),
 77+ 'access' => $access,
 78+ 'callback' => 'panels_add_page',
 79+ 'type' => MENU_LOCAL_TASK,
 80+ );
 81+ $items[] = array(
 82+ 'path' => 'admin/build/panels/add/layout',
 83+ 'title' => t('Add'),
 84+ 'access' => $access,
 85+ 'callback' => 'panels_add_layout_page',
 86+ 'type' => MENU_LOCAL_TASK,
 87+ );
 88+ $items[] = array(
 89+ 'path' => 'admin/build/panels/edit',
 90+ 'title' => t('Edit panels'),
 91+ 'access' => $access,
 92+ 'callback' => 'panels_edit_page',
 93+ 'type' => MENU_CALLBACK,
 94+ );
 95+ $items[] = array(
 96+ 'path' => 'admin/build/panels/delete',
 97+ 'title' => t('Delete panels'),
 98+ 'access' => $access,
 99+ 'callback' => 'drupal_get_form',
 100+ 'callback arguments' => array('panels_delete_confirm'),
 101+ 'type' => MENU_CALLBACK,
 102+ );
 103+
 104+ $items[] = array(
 105+ 'path' => 'panels/node/autocomplete',
 106+ 'title' => t('Autocomplete node'),
 107+ 'callback' => 'panels_node_autocomplete',
 108+ 'access' => user_access('access content'),
 109+ 'type' => MENU_CALLBACK
 110+ );
 111+
 112+ // load panels from database
 113+ $result = db_query("SELECT * FROM {panels_info}");
 114+ // FIXME: Fow now we're making these all callbacks, but we
 115+ // should steal code from Views so they can be normal, tabs,
 116+ // etc
 117+ while ($panels = db_fetch_object($result)) {
 118+ $panels->access = ($panels->access ? explode(', ', $panels->access) : array());
 119+ $items[] = array(
 120+ 'path' => $panels->path,
 121+ 'title' => filter_xss_admin($panels->title),
 122+ 'access' => panels_access($panels),
 123+ 'callback' => 'panels_panels_page',
 124+ 'callback arguments' => array($panels->did),
 125+ 'type' => MENU_CALLBACK
 126+ );
 127+ }
 128+ }
 129+ return $items;
 130+}
 131+
 132+/**
 133+ * panels path helper function
 134+ */
 135+function panels_get_file_path($module, $file, $base_path = true) {
 136+ if ($base_path) {
 137+ $output = base_path();
 138+ }
 139+ return $output . drupal_get_path('module', $module) . '/' . $file;
 140+}
 141+
 142+// ---------------------------------------------------------------------------
 143+// panels custom image button
 144+
 145+/**
 146+ * Custom form element to do our nice images.
 147+ */
 148+function panels_elements() {
 149+ $type['panels_imagebutton'] = array('#input' => TRUE, '#button_type' => 'submit',);
 150+ return $type;
 151+}
 152+
 153+/**
 154+ * Theme our image button.
 155+ */
 156+function theme_panels_imagebutton($element) {
 157+ return '<input type="image" class="form-'. $element['#button_type'] .'" name="'. $element['#name'] .'" value="'. check_plain($element['#default_value']) .'" '. drupal_attributes($element['#attributes']) . ' src="' . $element['#image'] . '" alt="' . $element['#title'] . '" title="' . $element['#title'] . "\" />\n";
 158+}
 159+
 160+function panels_imagebutton_value() {
 161+ // null function guarantees default_value doesn't get moved to #value.
 162+}
 163+
 164+/**
 165+ * Add a single button to a form.
 166+ */
 167+function panels_add_button($image, $name, $text) {
 168+ $module_path = base_path() . drupal_get_path('module', 'panels');
 169+
 170+ return array(
 171+ '#type' => 'panels_imagebutton',
 172+ '#image' => $module_path . '/images/' . $image,
 173+ '#title' => $text,
 174+ '#default_value' => $name,
 175+ );
 176+}
 177+
 178+/**
 179+ * Set a button to a blank image -- used for placeholders when buttons are
 180+ * not relevant but just removing it would be visually unappealing.
 181+ */
 182+function panels_set_blank(&$form) {
 183+ $form['#type'] = 'markup';
 184+ $form['#value'] = theme('image', drupal_get_path('module', 'panels') . '/images/blank.gif');
 185+}
 186+
 187+// ---------------------------------------------------------------------------
 188+// panels administrative pages
 189+
 190+/**
 191+ * Provide a list of panels, with links to edit or delete them.
 192+ */
 193+function panels_list_page() {
 194+ $result = db_query("SELECT * FROM {panels_info} ORDER BY title");
 195+ while ($panels = db_fetch_object($result)) {
 196+ $item = array();
 197+ $item[] = check_plain($panels->title);
 198+ $item[] = l($panels->path, $panels->path);
 199+ $item[] = implode(' | ', array(
 200+ l(t('Edit'), "admin/build/panels/edit/$panels->did"),
 201+ l(t('Delete'), "admin/build/panels/delete/$panels->did"),
 202+ ));
 203+ $items[] = $item;
 204+ }
 205+ $header = array(
 206+ t('Panel title'),
 207+ t('URL'),
 208+ t('Operations'),
 209+ );
 210+ $output = theme('table', $header, $items);
 211+ return $output;
 212+}
 213+
 214+/*
 215+ * Provide a form to confirm deletion of a panel page.
 216+ */
 217+function panels_delete_confirm($did = '') {
 218+ $panels = panels_load_panels($did);
 219+
 220+ if (!$panels) {
 221+ drupal_goto('admin/build/panels');
 222+ }
 223+
 224+ $form['did'] = array('#type' => 'value', '#value' => $panels->did);
 225+ return confirm_form( $form,
 226+ t('Are you sure you want to delete %title?', array('%title' => $panels->title)),
 227+ $_GET['destination'] ? $_GET['destination'] : 'admin/build/panels',
 228+ t('This action cannot be undone.'),
 229+ t('Delete'), t('Cancel')
 230+ );
 231+}
 232+
 233+/*
 234+ * Handle the submit button to delete a panel page.
 235+ */
 236+function panels_delete_confirm_submit($formid, $form) {
 237+ if ($form['confirm']) {
 238+ panels_delete_panels((object) $form);
 239+ return 'admin/build/panels';
 240+ }
 241+}
 242+
 243+/**
 244+ * Handle the add panels page
 245+ */
 246+function panels_add_page($layout = NULL) {
 247+ $layouts = panels_get_layouts();
 248+ drupal_add_css(drupal_get_path('module', 'panels') . '/panels_admin.css');
 249+ if (!$layout) {
 250+ foreach ($layouts as $id => $layout) {
 251+ if (!$default_id) {
 252+ // grab the first one for our default.
 253+ $default_id = $id;
 254+ }
 255+ $file = panels_get_file_path($layout['module'], $layout['icon'], false);
 256+ $output .= theme('panels_add_image', $layout[title], $id, l(theme('image', $file), $_GET['q'] . '/' . $id, NULL, NULL, NULL, NULL, TRUE));
 257+ }
 258+ return $output;
 259+ }
 260+
 261+ if (!$layouts[$layout]) {
 262+ return drupal_not_found();
 263+ }
 264+
 265+ $panels->layout = $layout;
 266+ return drupal_get_form('panels_edit_form', $panels);
 267+}
 268+
 269+function theme_panels_add_image($title, $id, $image) {
 270+ $output .= '<div class="layout-link">';
 271+ $output .= $image;
 272+ $output .= '<div>' . l($title, $_GET['q'] . '/' . $id) . '</div>';
 273+ $output .= '</div>';
 274+ return $output;
 275+}
 276+// ---------------------------------------------------------------------------
 277+// panels administrative pages
 278+
 279+function panels_edit_page($did = NULL) {
 280+ if (!$did || !($panels = panels_load_panels($did))) {
 281+ return drupal_not_found();
 282+ }
 283+ return drupal_get_form('panels_edit_form', $panels);
 284+}
 285+
 286+/**
 287+ * shortcut to ease the syntax of the various form builder tricks we use.
 288+ */
 289+function panels_form_builder(&$form, $form_id = 'panels_edit_form') {
 290+ $form['#post'] = $_POST;
 291+ $form = form_builder($form_id, $form);
 292+}
 293+
 294+/**
 295+ * Edit an already loaded panels.
 296+ */
 297+function panels_edit_form($panels) {
 298+ drupal_add_css(drupal_get_path('module', 'panels') . '/panels_admin.css');
 299+ $layouts = panels_get_layouts();
 300+ $layout = $layouts[$panels->layout];
 301+
 302+ $content_types = panels_get_content_types();
 303+
 304+ // Process all our add button stuff first so we can add stuff to the
 305+ // form semi dynamically.
 306+
 307+ $form['add'] = array(
 308+ '#type' => 'fieldset',
 309+ '#title' => t('Add content'),
 310+ '#collapsible' => false,
 311+ '#description' => t('Select an area to add content to, then select a type of content and click the appropriate button. The content will be added.'),
 312+ );
 313+
 314+ // Drop the array keys into a temporary in order to protect references.
 315+ $temp = array_keys($layout['content areas']);
 316+ $default_radio = array_shift($temp);
 317+
 318+ $form['add']['area'] = array(
 319+ '#type' => 'radios',
 320+ '#title' => t('Area'),
 321+ '#options' => $layout['content areas'],
 322+ '#prefix' => '<div class="container-inline">',
 323+ '#suffix' => '</div>',
 324+ '#default_value' => $default_radio,
 325+ );
 326+ foreach ($content_types as $id => $type) {
 327+ $function = $type['admin'];
 328+ if (function_exists($function)) {
 329+ global $form_values;
 330+ $form['add'][$id] = $function('add button', $dummy);
 331+
 332+ // $dummy needed for cause you can't have default args on a reference.
 333+ $form['add'][$id]['#parents'] = array('add', $id);
 334+ $form['add'][$id]['#tree'] = true;
 335+ panels_form_builder($form['add'][$id]);
 336+
 337+ if ($conf = $function('add', $form_values['add'][$id])) {
 338+ $add->configuration = $conf;
 339+ $add->type = $id;
 340+ $form['add']['area']['#parents'] = array('area');
 341+ panels_form_builder($form['add']['area']);
 342+ $add->area = $form_values['area'];
 343+ }
 344+ }
 345+ }
 346+
 347+ $form['layout'] = array(
 348+ '#type' => 'value',
 349+ '#value' => $panels->layout
 350+ );
 351+
 352+ $form['did'] = array(
 353+ '#type' => 'value',
 354+ '#value' => $panels->did,
 355+ );
 356+
 357+ $form['info'] = array(
 358+ '#type' => 'fieldset',
 359+ '#title' => t('General information'),
 360+ '#collapsible' => false,
 361+ );
 362+
 363+ $file = panels_get_file_path($layout['module'], $layout['icon'], false);
 364+ $icon .= theme('image', $file);
 365+ $form['info']['layout-icon'] = array(
 366+ '#value' => '<div class="layout-icon">' . $icon . '</div>',
 367+ );
 368+
 369+ $form['info']['layout-display'] = array(
 370+ '#value' => '<strong>Layout</strong>: ' . $layout['title'],
 371+ );
 372+
 373+ $form['info']['title'] = array(
 374+ '#type' => 'textfield',
 375+ '#default_value' => $panels->title,
 376+ '#title' => t('Page title'),
 377+ '#description' => t('The page title for this panels layout'),
 378+ );
 379+
 380+ $form['info']['css_id'] = array(
 381+ '#type' => 'textfield',
 382+ '#default_value' => $panels->css_id,
 383+ '#title' => t('CSS ID'),
 384+ '#description' => t('The CSS ID to apply to this page'),
 385+ );
 386+
 387+ $rids = array();
 388+ $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
 389+ while ($obj = db_fetch_object($result)) {
 390+ $rids[$obj->rid] = $obj->name;
 391+ }
 392+
 393+ $form['info']['access'] = array(
 394+ '#type' => 'checkboxes',
 395+ '#title' => t('Access'),
 396+ '#default_value' => $panels->access,
 397+ '#options' => $rids,
 398+ '#description' => t('Only the checked roles will be able to see this panel in any form; if no roles are checked, access will not be restricted.'),
 399+ );
 400+
 401+ $form['info']['path'] = array(
 402+ '#type' => 'textfield',
 403+ '#default_value' => $panels->path,
 404+ '#title' => t('Path'),
 405+ '#description' => t('The URL path to give this page, i.e, path/to/page'),
 406+ '#required' => TRUE,
 407+ );
 408+
 409+ $form['content'] = array(
 410+ '#tree' => true,
 411+ );
 412+
 413+ // Go through our content areas and display what we have.
 414+ foreach ($layout['content areas'] as $area => $title) {
 415+ $list = array();
 416+ $form['content'][$area] = array(
 417+ '#tree' => true,
 418+ );
 419+
 420+ // Construct the order, feeding it the default order for what
 421+ // we know about. When we pull it back out, it may well be
 422+ // different due to past submits.
 423+ $order = array();
 424+ if (is_array($panels->content[$area])) {
 425+ $order = array_keys($panels->content[$area]);
 426+ }
 427+ $form['content'][$area]['order'] = array(
 428+ '#type' => 'hidden',
 429+ '#default_value' => serialize($order),
 430+ '#parents' => array('content', $area, 'order'),
 431+ );
 432+
 433+ // If an add button has added an item to the area, put it in and update
 434+ // the $order.
 435+ panels_form_builder($form['content'][$area]['order']);
 436+ $order = unserialize($form['content'][$area]['order']['#value']);
 437+ if ($add->area == $area) {
 438+ // say THIS 5 times real fast
 439+ if ($panels->content[$area] && $order) {
 440+ $position = max(max(array_keys($order)), max(array_keys($panels->content[$area]))) + 1;
 441+ }
 442+ else if ($order) {
 443+ $position = max(array_keys($order)) + 1;
 444+ }
 445+ else {
 446+ $position = 0;
 447+ }
 448+
 449+ $panels->content[$area][$position] = $add;
 450+ $order[] = $position;
 451+ $form['content'][$area]['order']['#value'] = serialize($order);
 452+ }
 453+
 454+ // Go through each item in the area and render it.
 455+ $count = count($order);
 456+ foreach ($order as $position => $id) {
 457+ // place buttons to re-order content.
 458+ $form['content'][$area][$id]['buttons'] = array(
 459+ '#parents' => array('content', $area, $id, 'buttons'),
 460+ '#tree' => TRUE
 461+ );
 462+ panels_add_buttons($form['content'][$area][$id]['buttons'], $count, $position);
 463+
 464+ // figure out if one of those buttons was pressed
 465+ panels_form_builder($form['content'][$area][$id]['buttons']);
 466+ $deleted = false;
 467+ foreach ($GLOBALS['form_values']['content'][$area][$id]['buttons'] as $button => $value) {
 468+ if ($value) {
 469+ $function = 'panels_move_' . $button;
 470+ $function($order, $position);
 471+ $form['content'][$area]['order']['#value'] = serialize($order);
 472+ if ($button == 'delete')
 473+ $deleted = true;
 474+ }
 475+ }
 476+ // If a content item was deleted, it still has buttons. Get rid of them.
 477+ // It had buttons because we needed to give it buttons to see if its
 478+ // buttons were clicked.
 479+ if ($deleted) {
 480+ unset($form['content'][$area][$id]['buttons']);
 481+ }
 482+ else {
 483+ // we finally get to add the conent item's content to the form.
 484+ $area_record = $panels->content[$area][$id];
 485+ $form['content'][$area][$id]['type'] = array(
 486+ '#type' => 'hidden',
 487+ '#default_value' => $area_record->type,
 488+ '#parents' => array('content', $area, $id, 'type'),
 489+ );
 490+ // retrieve what was already there -- so we can retain edits and
 491+ // content items that were added.
 492+ panels_form_builder($form['content'][$area][$id]['type']);
 493+ $type = $form['content'][$area][$id]['type']['#value'];
 494+ $function = $content_types[$type]['admin'];
 495+ if (function_exists($function)) {
 496+ $array = array(
 497+ '#tree' => true,
 498+ '#parents' => array('content', $area, $id, 'configuration'),
 499+ );
 500+ $form['content'][$area][$id]['configuration'] = array_merge($array, $function('edit', $area_record->configuration, array('content', $area, $id, 'configuration')));
 501+ panels_form_builder($form['content'][$area][$id]['configuration']);
 502+ }
 503+ }
 504+ }
 505+ }
 506+
 507+ $form['submit'] = array(
 508+ '#type' => 'submit',
 509+ '#value' => t('Save'),
 510+ );
 511+
 512+ return $form;
 513+}
 514+
 515+/**
 516+ * Display the form to edit a panels.
 517+ */
 518+function theme_panels_edit_form($form) {
 519+ $layouts = panels_get_layouts();
 520+ $layout = $layouts[$form['layout']['#value']];
 521+
 522+ $content_types = panels_get_content_types();
 523+
 524+ $output .= drupal_render($form['info']);
 525+ foreach ($layout['content areas'] as $area => $title) {
 526+ $order = unserialize($form['content'][$area]['order']['#value']);
 527+ if (!$order) {
 528+ $area_content = t('This area has no content.');
 529+ }
 530+ else {
 531+ $area_content = '';
 532+ $count = count($order);
 533+ foreach ($order as $position => $id) {
 534+ if ($count > 1) {
 535+ if ($position == 0 ) {
 536+ panels_set_blank($form['content'][$area][$id]['buttons']['up']);
 537+ }
 538+ else if ($position == ($count - 1)) {
 539+ panels_set_blank($form['content'][$area][$id]['buttons']['down']);
 540+ }
 541+ }
 542+ $type = $form['content'][$area][$id]['type']['#value'];
 543+ $function = $content_types[$type]['admin'];
 544+ if (function_exists($function)) {
 545+ // figure out the actual values; using the global because we need it
 546+ // to be in the same format it'll be in 'submit'.
 547+ global $form_values;
 548+ $conf_form = $form_values['content'][$area][$id]['configuration'];
 549+ $conf = $function('save', $conf_form);
 550+ $fieldset = array(
 551+ '#title' => t('Configure'),
 552+ '#children' => drupal_render($form['content'][$area][$id]['configuration']),
 553+ '#collapsible' => true,
 554+ '#collapsed' => true
 555+ );
 556+ $buttons = drupal_render($form['content'][$area][$id]['buttons']);
 557+ $area_content .= $buttons . '&nbsp;' . $function('list', $conf) .
 558+ theme('fieldset', $fieldset) /* . '<br />' */;
 559+ }
 560+ }
 561+ }
 562+ $content[$area] = theme('fieldset', array('#title' => check_plain($title), '#value' => $area_content));
 563+ }
 564+
 565+ $output .= panels_get_layout($layout, $content);
 566+
 567+ $output .= drupal_render($form);
 568+ return $output;
 569+}
 570+
 571+function panels_edit_form_validate($form_id, $form_values, $form) {
 572+ $content_types = panels_get_content_types();
 573+ foreach ($form_values['content'] as $area => $content) {
 574+ foreach ($content as $id => $item) {
 575+ if (is_numeric($id)) {
 576+ $function = $content_types[$item['type']]['admin'];
 577+ if (function_exists($function)) {
 578+ $function('validate', $item['configuration'], $form['content'][$area][$id]['configuration']);
 579+ }
 580+ }
 581+ }
 582+ }
 583+}
 584+
 585+function panels_edit_form_submit($form_id, $form_values) {
 586+ $panels = (object) $form_values;
 587+ // be sure we get the order right.
 588+ foreach ($form_values['content'] as $area => $content) {
 589+ $array = array();
 590+ $order = unserialize($content['order']);
 591+ if (is_array($order)) {
 592+ foreach($order as $id) {
 593+ $array[] = $content[$id];
 594+ }
 595+ }
 596+ $panels->content[$area] = $array;
 597+ }
 598+ $panels->access = array_keys(array_filter($panels->access));
 599+ panels_save_panels($panels);
 600+ drupal_set_message(t('The panels has been saved.'));
 601+ return 'admin/build/panels';
 602+}
 603+
 604+/**
 605+ * add the buttons to a content item
 606+ */
 607+function panels_add_buttons(&$form, $count, $position) {
 608+ $form['delete'] = panels_add_button('user-trash.png', 'delete', t('Delete this item'));
 609+ // Leaving these in but commented out as I'm not convinced we don't want them.
 610+// if ($count > 2) {
 611+// $form['top'] = panels_add_button('go-top.png', 'top', t('Move item to top'));
 612+// }
 613+ if ($count > 1) {
 614+ $form['up'] = panels_add_button('go-up.png', 'up', t('Move item up'));
 615+ $form['down'] = panels_add_button('go-down.png', 'down', t('Move item down'));
 616+ }
 617+// if ($count > 2) {
 618+// $form['bottom'] = panels_add_button('go-bottom.png', 'bottom', t('Move item to bottom'));
 619+// }
 620+// if ($count > 1) {
 621+// $form['spacer'] = panels_add_blank();
 622+// }
 623+ return $form;
 624+}
 625+
 626+/**
 627+ * move an item in an array to the top
 628+ */
 629+function panels_move_top(&$array, &$position) {
 630+ $value = $array[$position];
 631+ unset($array[$position]);
 632+ array_unshift($array, $value);
 633+ // reindex the array now
 634+ $array = array_values($array);
 635+}
 636+
 637+/**
 638+ * move an item in an array to the bottom
 639+ */
 640+function panels_move_bottom(&$array, &$position) {
 641+ $value = $array[$position];
 642+ unset($array[$position]);
 643+ $array[] = $value;
 644+ // reindex the array now
 645+ $array = array_values($array);
 646+}
 647+
 648+/**
 649+ * move an item in an array up one position
 650+ */
 651+function panels_move_up(&$array, &$position) {
 652+ $value = $array[$position];
 653+ $array[$position] = $array[$position - 1];
 654+ $array[$position - 1] = $value;
 655+}
 656+
 657+/**
 658+ * move an item in an array up one position
 659+ */
 660+function panels_move_down(&$array, &$position) {
 661+ $value = $array[$position];
 662+ $array[$position] = $array[$position + 1];
 663+ $array[$position + 1] = $value;
 664+}
 665+
 666+/**
 667+ * Remove an item from an array
 668+ */
 669+function panels_move_delete(&$array, &$position) {
 670+ unset($array[$position]);
 671+ // reindex the array now
 672+ $array = array_values($array);
 673+}
 674+
 675+// ---------------------------------------------------------------------------
 676+// panels database functions
 677+
 678+function panels_load_panels($did) {
 679+ $panels = db_fetch_object(db_query("SELECT * FROM {panels_info} WHERE did = %d", $did));
 680+ if (!$panels) {
 681+ return NULL;
 682+ }
 683+ $panels->content = array();
 684+ $panels->access = ($panels->access ? explode(', ', $panels->access) : array());
 685+
 686+ $result = db_query("SELECT * FROM {panels_area} WHERE did = %d ORDER BY area, position", $did);
 687+ while ($area = db_fetch_object($result)) {
 688+ $area->configuration = unserialize($area->configuration);
 689+ $panels->content[$area->area][] = $area;
 690+ }
 691+ return $panels;
 692+}
 693+
 694+function panels_save_panels($panels) {
 695+ $panels->access = implode(', ', $panels->access);
 696+ if ($panels->did) {
 697+ db_query("UPDATE {panels_info} SET title = '%s', access = '%s', path = '%s', css_id = '%s', layout = '%s' WHERE did = %d", $panels->title, $panels->access, $panels->path, $panels->css_id, $panels->layout, $panels->did);
 698+ db_query("DELETE FROM {panels_area} WHERE did = %d", $panels->did);
 699+ }
 700+ else {
 701+ $panels->did = db_next_id("{panels_info_id}");
 702+ // Put this in the form so modules can utilize the did of a new panel.
 703+ $GLOBALS['form_values']['did'] = $panels->did;
 704+ db_query("INSERT INTO {panels_info} (did, title, access, path, css_id, layout) VALUES (%d, '%s', '%s', '%s', '%s', '%s')", $panels->did, $panels->title, $panels->access, $panels->path, $panels->css_id, $panels->layout);
 705+ }
 706+ foreach ($panels->content as $area => $info) {
 707+ foreach ($info as $position => $block) {
 708+ if (is_numeric($position)) { // don't save some random form stuff that may've been here.
 709+ $block = (object) $block;
 710+ db_query("INSERT INTO {panels_area} (did, area, type, configuration, position) VALUES(%d, '%s', '%s', '%s', %d)", $panels->did, $area, $block->type, serialize($block->configuration), $position);
 711+ }
 712+ }
 713+ }
 714+ menu_rebuild();
 715+}
 716+
 717+function panels_delete_panels($panels) {
 718+ db_query("DELETE FROM {panels_info} WHERE did = %d", $panels->did);
 719+ db_query("DELETE FROM {panels_area} WHERE did = %d", $panels->did);
 720+ menu_rebuild();
 721+}
 722+// ---------------------------------------------------------------------------
 723+// panels page
 724+
 725+/**
 726+ * Returns TRUE if the current page contains a panels layout.
 727+ * This can be checked in a theme to hide existing sidebars on panel pages, for example.
 728+ *
 729+ * @param $set (optional) used internally to set the page status
 730+ */
 731+function panels_is_panels_page($set_panels = NULL) {
 732+ static $is_panels;
 733+ if ($set_panels == TRUE) {
 734+ $is_panels = $set_panels;
 735+ }
 736+ return $is_panels;
 737+}
 738+
 739+function panels_panels_page($did) {
 740+ $panels = panels_load_panels($did);
 741+ if (!$panels) {
 742+ return drupal_not_found();
 743+ }
 744+
 745+ $layouts = panels_get_layouts();
 746+ $layout = $layouts[$panels->layout];
 747+ $layout['css_id'] = $panels->css_id;
 748+
 749+ if (!$layout) {
 750+ watchdog('panels', t('Unable to find requested layout %s', array('%s' => check_plain($panels->layout))));
 751+ return drupal_not_found();
 752+ }
 753+
 754+ panels_is_panels_page(TRUE);
 755+ $content_types = panels_get_content_types();
 756+
 757+ foreach ($panels->content as $location => $list) {
 758+ foreach ($list as $area) {
 759+ $function = $content_types[$area->type]['callback'];
 760+ if (function_exists($function)) {
 761+ $content[$area->area] .= $function($area->configuration);
 762+ }
 763+ }
 764+ }
 765+ $output = panels_get_layout($layout, $content);
 766+ drupal_set_title(filter_xss_admin($panels->title));
 767+ return $output;
 768+}
 769+
 770+function panels_get_layout($layout, $content) {
 771+ $output = theme($layout['theme'], check_plain($layout['css_id']), $content);
 772+
 773+ if ($output) {
 774+ if (file_exists(path_to_theme() . '/' . $layout['css'])) {
 775+ drupal_add_css(path_to_theme() . '/' . $layout['css']);
 776+ }
 777+ else {
 778+ drupal_add_css(drupal_get_path('module', $layout['module']) . '/' . $layout['css']);
 779+ }
 780+ }
 781+ return $output;
 782+}
 783+
 784+/**
 785+ * For external use: Given a layout ID and a $content array, return the
 786+ * finished layout.
 787+ */
 788+function panels_print_layout($id, $content) {
 789+ $layouts = panels_get_layouts();
 790+ $layout = $layouts[$id];
 791+ if (!$layout) {
 792+ return;
 793+ }
 794+
 795+ return panels_get_layout($layout, $content);
 796+}
 797+
 798+// ---------------------------------------------------------------------------
 799+// panels data loading
 800+
 801+function panels_load_includes($directory, $callback) {
 802+ // Load all our module 'on behalfs'.
 803+ $path = drupal_get_path('module', 'panels') . '/' . $directory;
 804+ $files = drupal_system_listing('.inc$', $path, 'name', 0);
 805+
 806+ foreach($files as $file) {
 807+ require_once('./' . $file->filename);
 808+ }
 809+ $output = module_invoke_all($callback);
 810+ foreach ($files as $file) {
 811+ $function = 'panels_' . $file->name . '_' . $callback;
 812+ if (function_exists($function)) {
 813+ $result = $function();
 814+ if (isset($result) && is_array($result)) {
 815+ $output = array_merge($output, $result);
 816+ }
 817+ }
 818+ }
 819+ return $output;
 820+}
 821+
 822+function panels_get_layouts() {
 823+ static $layout = NULL;
 824+ if (!$layout) {
 825+ $layouts = panels_load_includes('layouts', 'panels_layouts');
 826+ }
 827+ return $layouts;
 828+}
 829+
 830+function panels_get_content_types() {
 831+ static $layout = NULL;
 832+ if (!$layout) {
 833+ $layouts = panels_load_includes('content_types', 'panels_content_types');
 834+ }
 835+ return $layouts;
 836+}
 837+
 838+/**
 839+ * Helper function for autocompletion of node titles.
 840+ * This is mostly stolen from clipper.
 841+ */
 842+function panels_node_autocomplete($string) {
 843+ if ($string != '') { // if there are node_types passed, we'll use those in a MySQL IN query.
 844+ $result = db_query_range(db_rewrite_sql('SELECT n.title, u.name FROM {node} n INNER JOIN {users} u ON u.uid = n.uid WHERE LOWER(title) LIKE LOWER("%%%s%%")'), $string, 0, 10);
 845+ $prefix = count($array) ? implode(', ', $array) .', ' : '';
 846+
 847+ $matches = array();
 848+ while ($node = db_fetch_object($result)) {
 849+ $n = $node->title;
 850+ // Commas and quotes in terms are special cases, so encode 'em.
 851+ if (preg_match('/,/', $node->title) || preg_match('/"/', $node->title)) {
 852+ $n = '"'. preg_replace('/"/', '""', $node->title) .'"';
 853+ }
 854+ $matches[$prefix . $n] = '<span class="autocomplete_title">'. check_plain($node->title) .'</span> <span class="autocomplete_user">('. t('by %user', array('%user' => check_plain($node->name))) .')</span>';
 855+ }
 856+ print drupal_to_js($matches);
 857+ exit();
 858+ }
 859+}
Property changes on: trunk/fundcore/modules/panels/panels.module
___________________________________________________________________
Added: svn:eol-style
1860 + native
Index: trunk/fundcore/modules/panels/API.txt
@@ -0,0 +1,125 @@
 2+The API for expanding the panels module comes in two pieces. First there is the
 3+layout API, which adds to the list of layouts you need. Second is the content
 4+types API, which lets modules supply content to the panels. Natively, panels
 5+module supports the content types of 'block', which just renders the output
 6+of a block, 'node' which simply renders a node_view, 'custom' which allows the
 7+user to enter custom content with filtering, and finally 'views' because I
 8+wrote them both.
 9+
 10+Where to put your code:
 11+=======================
 12+
 13+With both types, there are two ways to implement a new type. First, you can
 14+implement the hook in your module and provide the necessary data. Or you
 15+can create a .inc file in the right format, and drop it into the proper
 16+directory in the panels module. Both are very similar, and only requires
 17+a minor naming adjustment.
 18+
 19+When using the .inc file, in place of 'hook' in the various hooks, use
 20+panels_FILENAME.
 21+
 22+Creating a new Layout Type:
 23+===========================
 24+
 25+A layout consists of 4 things:
 26+
 27+1) A bit of HTML in a theme function. I use heredoc notation to make it
 28+ extra easy to convert these to .tpl.inc files in case they are to
 29+ be overridden in php template.
 30+2) A bit of CSS to describe how the layout should be, well, laid out.
 31+3) An icon that is 50x75 which gives the user a visual indication of
 32+ what the layout looks like.
 33+4) An implementation of hook_panels_layouts() to tell panels the necessary
 34+ information.
 35+
 36+hook_panels_layouts returns an array with the following information:
 37+
 38+'module' => The module name providing this. This is necessary because it
 39+ uses drupal_get_path('module', $module) to get the proper
 40+ path for included CSS.
 41+'title' => The title of the layout presented to the user. Use t().
 42+'icon' => The filename of the icon to use when listing avialable layouts.
 43+'theme' => The theme function that contains the HTML, without the theme_
 44+ part.
 45+'css' => The CSS file.
 46+'content areas' => an array in the form of 'name' => t('Title') of content
 47+ areas supported by the layout. For example, the simple
 48+ 2 column layout uses array('left' => t('Left side'),
 49+ 'right' => t('Right side')); -- the name is the internal
 50+ identifier. Your theme function will see it as
 51+ $content['name'] (so twocol gets $content['left'] and
 52+ $content['right']).
 53+
 54+
 55+Creating a new Content Type:
 56+============================
 57+
 58+Content types require 1 hook and two callbacks. The hook defines what content
 59+types are available, the first callback displays the content in a dashboard,
 60+and the other callback does all of the administrative functions.
 61+
 62+hook_panels_content_types returns an array with the following information:
 63+'callback' => The function to display the content.
 64+'admin' => The function to administer the content.
 65+
 66+The callback function receives one argument: The $configuration array, as
 67+defined by the administrative callback.
 68+
 69+The administrative callback recieves 3 arguments:
 70+
 71+$op -- the operation to perform. See below.
 72+&$arg1 -- The first argument should be a reference and its meaning varies
 73+ based on the op.
 74+$arg2 -- The second argument is optional, not a reference, and should
 75+ default to NULL.
 76+
 77+Administrative operations:
 78+
 79+'list': $arg1 is the configuration array.
 80+ This op is called when panels lists what content is in a content
 81+ area. It generally returns something similar to this:
 82+ return '<strong>Views</strong>: ' . $view->name . ' (' . $view->description . ')';
 83+
 84+'add button': arguments not used here.
 85+ This op is called to display the 'add content type' button; it can also
 86+ display additional information (such as the list of blocks or the
 87+ autocomplete to select a node).
 88+
 89+ The actual button should look something like this:
 90+ $form['submit'] = array(
 91+ '#type' => 'button',
 92+ '#value' => t('Add view'),
 93+ );
 94+
 95+ And it's a good idea to do this, but it's not required:
 96+
 97+ $form['#prefix'] = '<div class="container-inline">';
 98+ $form['#suffix'] = '</div>';
 99+
 100+'add': $arg1 == the $configuration array
 101+ This op is called to see if your add button has been clicked. It *must*
 102+ start off by checking to see if this is true:
 103+
 104+ if ($_POST['op'] != t('Add view')) {
 105+ return;
 106+ }
 107+
 108+ If it is true, it should process that information and return a $configuration
 109+ array populated from whatever other form items were presented in 'add button'
 110+ and whatever defaults make sense.
 111+
 112+'edit': $arg1 == the $configuration array
 113+ This op is called to provide an edit form for a content type. It *must*
 114+ ensure *all* information from the conf array is available, even if it
 115+ is just hidden; panels has no way to remember this data between form
 116+ clicks, so any data not put here will be lost. No buttons need to be
 117+ added to the form.
 118+
 119+'validate': $arg1 == $form_values, $arg2 == $form
 120+ Called to validate the 'edit' form above.
 121+
 122+'save': $arg1 == $form_values
 123+ Called to convert a $form_values back into a $configuration array. All
 124+ of the default types just send $form_values back as $configuration,
 125+ but if you need to do some kind of transformation, this is where it
 126+ happens.
Property changes on: trunk/fundcore/modules/panels/API.txt
___________________________________________________________________
Added: svn:eol-style
1127 + native
Index: trunk/fundcore/modules/panels/panels.install
@@ -0,0 +1,84 @@
 2+<?php
 3+// $Id: panels.install,v 1.1.4.4 2007/04/03 16:36:05 merlinofchaos Exp $
 4+
 5+/**
 6+ * Install the panels tables
 7+ */
 8+function panels_install() {
 9+ switch ($GLOBALS['dbtype']) {
 10+ case 'pgsql':
 11+ db_query(<<<EOT
 12+ CREATE TABLE {panels_info} (
 13+ did int not null default 0 primary key,
 14+ title varchar(128),
 15+ access varchar(128),
 16+ path varchar(128),
 17+ css_id varchar(128),
 18+ layout varchar(32)
 19+ );
 20+EOT
 21+ );
 22+
 23+ db_query("CREATE SEQUENCE {panels_info}_id_seq;");
 24+
 25+ db_query(<<<EOT
 26+ CREATE TABLE {panels_area} (
 27+ did int NOT NULL DEFAULT 0,
 28+ area varchar(32),
 29+ type varchar(32),
 30+ configuration text,
 31+ position int
 32+ );
 33+EOT
 34+ );
 35+
 36+ db_query("CREATE INDEX {panels_area}_did_idx ON {panels_area} (did);");
 37+ break;
 38+ case 'mysql':
 39+ case 'mysqli':
 40+ default:
 41+ db_query(<<<EOT
 42+ create table {panels_info} (
 43+ did int(10) not null default 0 primary key,
 44+ title varchar(128),
 45+ access varchar(128),
 46+ path varchar(128),
 47+ css_id varchar(128),
 48+ layout varchar(32)
 49+ ) /*!40100 DEFAULT CHARACTER SET utf8 */
 50+EOT
 51+ );
 52+ db_query(<<<EOT
 53+ create table {panels_area} (
 54+ did int(10) not null default 0,
 55+ area varchar(32),
 56+ type varchar(32),
 57+ configuration longtext,
 58+ position int(5),
 59+ key (did)
 60+ ) /*!40100 DEFAULT CHARACTER SET utf8 */
 61+EOT
 62+ );
 63+ }
 64+}
 65+
 66+/**
 67+ * Uninstall the panels tables
 68+ */
 69+function panels_uninstall() {
 70+ switch ($GLOBALS['db_type']) {
 71+ case 'pgsql':
 72+ case 'mysql':
 73+ case 'mysqli':
 74+ default:
 75+ db_query("DROP TABLE {panels_info}");
 76+ db_query("DROP TABLE {panels_area}");
 77+ }
 78+}
 79+
 80+/**
 81+ * Update the tables to UTF-8
 82+ */
 83+function panels_update_1() {
 84+ return _system_update_utf8(array('panels_info', 'panels_area'));
 85+}
Index: trunk/fundcore/modules/panels/README.txt
@@ -0,0 +1,26 @@
 2+The panels module is the ideological son, successor to and almost complete
 3+replacement for the dashboard module. This module allows you to create pages
 4+that are divided into areas of the page. Where the dashboard module only gave
 5+four areas--top, bottom, left and right--this one is a completely flexible
 6+system that includes a couple of 2 column and 3 column layouts by default, but
 7+is also highly extensible and other layouts can be plugged in with a little HTML
 8+and CSS knowledge, with just enough PHP knowledge to be able to edit an include
 9+file without breaking it.
 10+
 11+Perhaps most importantly, unlike the dashboard module it requires no fiddling
 12+with PHP code to include the things you want; the interface lets you add blocks,
 13+nodes and custom content just by selecting and clicking.
 14+
 15+If you want to override the CSS of a panel, the easiest way is to just copy
 16+the CSS into your theme directory and tweak; panels will look there before
 17+including the CSS from the module, and if it exists, will not include the
 18+module's CSS. If you want to just change a tiny bit but keep the basic
 19+structure, just add your changes to your style.css instead.
 20+
 21+If you're having problems with IE and your panels falling below your sidebars,
 22+try setting the width of the main panel area (example, .panel-2col-stacked) to
 23+98%.
 24+
 25+If you need to check if the current page is a panels page in your theme
 26+(for example if you want to hide some existing sidebars in your theme on
 27+these pages) then you can use the panels_is_panels_page() function.
\ No newline at end of file
Property changes on: trunk/fundcore/modules/panels/README.txt
___________________________________________________________________
Added: svn:eol-style
128 + native
Index: trunk/fundcore/modules/panels/panels.info
@@ -0,0 +1,10 @@
 2+; $Id: panels.info,v 1.2 2006/10/27 16:36:18 merlinofchaos Exp $
 3+name = Panels
 4+description = Create pages that are divided into areas of the page.
 5+version = 1.1
 6+
 7+
 8+; Information added by drupal.org packaging script on 2007-04-03
 9+version = "5.x-1.2"
 10+project = "panels"
 11+
Property changes on: trunk/fundcore/modules/panels/panels.info
___________________________________________________________________
Added: svn:eol-style
112 + native
Index: trunk/fundcore/modules/panels/content_types/node.inc
@@ -0,0 +1,110 @@
 2+<?php
 3+/**
 4+ * Callback function to supply a list of content types.
 5+ */
 6+function panels_node_panels_content_types() {
 7+ $items['node'] = array(
 8+ 'callback' => 'panels_content_node',
 9+ 'admin' => 'panels_admin_node',
 10+ );
 11+ return $items;
 12+}
 13+
 14+/**
 15+ * Output function for the 'node' content type. Outputs a node
 16+ * based on the module and delta supplied in the configuration.
 17+ */
 18+function panels_content_node($conf) {
 19+ $node = node_load($conf['nid']);
 20+ if (!node_access('view', $node)) {
 21+ return;
 22+ }
 23+
 24+ if ($conf['suppress_title']) {
 25+ $node->title = '';
 26+ }
 27+
 28+ $output = node_view($node, $conf['teaser'], FALSE, $conf['links']);
 29+ return $output;
 30+}
 31+
 32+/**
 33+ * Callback to perform administrative functions on the content block
 34+ */
 35+function panels_admin_node($op, &$arg, $arg2 = NULL) {
 36+ switch ($op) {
 37+ case 'list':
 38+ $conf = $arg;
 39+ $node = node_load($conf['nid']);
 40+ return '<strong>Node</strong>: ' . check_plain($node->title);
 41+ case 'add button':
 42+ $form['nid'] = array(
 43+ '#title' => t('Enter the title or NID of a post'),
 44+ '#type' => 'textfield',
 45+ '#maxlength' => 512,
 46+ '#autocomplete_path' => 'panels/node/autocomplete',
 47+ '#weight' => -10,
 48+ );
 49+ $form['submit'] = array(
 50+ '#type' => 'button',
 51+ '#value' => t('Add post'),
 52+ );
 53+
 54+ $form['#prefix'] = '<div class="container-inline">';
 55+ $form['#suffix'] = '</div>';
 56+ return $form;
 57+ case 'add':
 58+ if ($_POST['op'] != t('Add post')) {
 59+ return;
 60+ }
 61+ $form = &$arg;
 62+ if (is_numeric($form['nid'])) {
 63+ $conf = array();
 64+ $conf['nid'] = $form['nid'];
 65+ }
 66+ else {
 67+ $conf = db_fetch_array(db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE LOWER(title) = LOWER('%s')"), $form['nid']));
 68+ if (!$conf['nid']) {
 69+ drupal_set_message(t('Unable to find "%s"', array('%s' => check_plain($form['nid']))));
 70+ return;
 71+ }
 72+ }
 73+ // default to just teaser
 74+ $conf['teaser'] = TRUE;
 75+ return $conf;
 76+ case 'edit':
 77+ $conf = &$arg;
 78+ $form['nid'] = array(
 79+ '#type' => 'hidden',
 80+ '#default_value' => $conf['nid'],
 81+ );
 82+ $form['teaser'] = array(
 83+ '#title' => t('Teaser'),
 84+ '#type' => 'checkbox',
 85+ '#default_value' => $conf['teaser'],
 86+ '#description' => t('Check here to show only the node teaser'),
 87+ );
 88+ $form['links'] = array(
 89+ '#type' => 'checkbox',
 90+ '#default_value' => $conf['links'],
 91+ '#title' => t('Display links'),
 92+ '#description' => t('Check here to display the links with the post.')
 93+ );
 94+ $form['suppress_title'] = array(
 95+ '#type' => 'checkbox',
 96+ '#default_value' => $conf['suppress_title'],
 97+ '#title' => t('Suppress node title'),
 98+ '#description' => t('Check here to suppress the node title.')
 99+ );
 100+
 101+ return $form;
 102+ case 'validate':
 103+ // This one has nothing to validate.
 104+ $form = &$arg;
 105+ return;
 106+ case 'save':
 107+ // For this one, the form values go directly into the config.
 108+ $form = &$arg;
 109+ return $form;
 110+ }
 111+}
Property changes on: trunk/fundcore/modules/panels/content_types/node.inc
___________________________________________________________________
Added: svn:eol-style
1112 + native
Index: trunk/fundcore/modules/panels/content_types/block.inc
@@ -0,0 +1,128 @@
 2+<?php
 3+/**
 4+ * Callback function to supply a list of content types.
 5+ */
 6+function panels_block_panels_content_types() {
 7+ $items['block'] = array(
 8+ 'callback' => 'panels_content_block',
 9+ 'admin' => 'panels_admin_block',
 10+ );
 11+ return $items;
 12+}
 13+
 14+/**
 15+ * Output function for the 'block' content type. Outputs a block
 16+ * based on the module and delta supplied in the configuration.
 17+ */
 18+function panels_content_block($conf) {
 19+ $block = (object) module_invoke($conf['module'], 'block', 'view', $conf['delta']);
 20+ $block->module = $conf['module'];
 21+ $block->delta = $conf['delta'];
 22+ if ($conf['override_title']) {
 23+ $block->subject = check_plain($conf['override_title_text']);
 24+ }
 25+
 26+ // Test for block visibility
 27+ $result = db_query("SELECT pages, visibility FROM {blocks} WHERE module = '%s' AND delta = %d", $block->module, $block->delta);
 28+ $block_visibility = db_fetch_object($result);
 29+
 30+ if ($block_visibility && $block_visibility->pages) {
 31+ if ($block_visibility->visibility < 2) {
 32+ $path = drupal_get_path_alias($_GET['q']);
 33+ $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($block->pages, '/')) .')$/';
 34+ $page_match = !($block->visibility xor preg_match($regexp, $path));
 35+ } else {
 36+ $page_match = drupal_eval($block->pages);
 37+ }
 38+ } else {
 39+ $page_match = TRUE;
 40+ }
 41+
 42+ if ($page_match) {
 43+ return theme('block', $block);
 44+ }
 45+}
 46+
 47+/**
 48+ * Callback to perform administrative functions on the content block
 49+ */
 50+function panels_admin_block($op, &$arg, $arg2 = NULL) {
 51+ switch ($op) {
 52+ case 'list':
 53+ $conf = $arg;
 54+ $block = module_invoke($conf['module'], 'block', 'list');
 55+ $title = $block[$conf['delta']]['info'];
 56+ if ($conf['override_title']) {
 57+ $title .= ' [' . check_plain($conf['override_title_text']) . ']';
 58+ }
 59+ return '<strong>Block</strong>: ' . $title . ' (' . $conf['module'] . '-' . $conf['delta'] . ')';
 60+ case 'add button':
 61+ foreach (module_list() as $module) {
 62+ $module_blocks = module_invoke($module, 'block', 'list');
 63+ if ($module_blocks) {
 64+ $array = array();
 65+ foreach ($module_blocks as $delta => $block) {
 66+ // strip_tags used because it goes through check_plain and that
 67+ // just looks bad.
 68+ $array["$module-$delta"] = strip_tags($block['info']);
 69+ }
 70+ $options[$module] = $array;
 71+ }
 72+ }
 73+ $form['block'] = array(
 74+ '#type' => 'select',
 75+ '#options' => $options,
 76+ '#title' => t('Block'),
 77+ );
 78+ $form['submit'] = array(
 79+ '#type' => 'button',
 80+ '#value' => t('Add block'),
 81+ );
 82+
 83+ $form['#prefix'] = '<div class="container-inline">';
 84+ $form['#suffix'] = '</div>';
 85+ return $form;
 86+ case 'add':
 87+ if ($_POST['op'] != t('Add block')) {
 88+ return;
 89+ }
 90+ $form = &$arg;
 91+ $conf = array();
 92+ list($conf['module'], $conf['delta']) = explode('-', $form['block'], 2);
 93+ // take the data given to us and return a fully formed $area object.
 94+ return $conf;
 95+ case 'edit':
 96+ $conf = &$arg;
 97+ $form['module'] = array(
 98+ '#type' => 'hidden',
 99+ '#default_value' => $conf['module'],
 100+ );
 101+ $form['delta'] = array(
 102+ '#type' => 'hidden',
 103+ '#default_value' => $conf['delta'],
 104+ );
 105+ $form['override_title'] = array(
 106+ '#type' => 'checkbox',
 107+ '#default_value' => $conf['override_title'],
 108+ '#title' => t('Override title'),
 109+ '#description' => t('If checked, the block title will be overridden with the override title text.')
 110+ );
 111+ $form['override_title_text'] = array(
 112+ '#type' => 'textfield',
 113+ '#default_value' => $conf['override_title_text'],
 114+ '#title' => t('Override title text'),
 115+ '#size' => 15,
 116+ );
 117+
 118+ return $form;
 119+ case 'validate':
 120+ // This one has nothing to validate.
 121+ $form_values = &$arg;
 122+ $form = $arg2;
 123+ return;
 124+ case 'save':
 125+ // For this one, the form values go directly into the config.
 126+ $form = &$arg;
 127+ return $form;
 128+ }
 129+}
Property changes on: trunk/fundcore/modules/panels/content_types/block.inc
___________________________________________________________________
Added: svn:eol-style
1130 + native
Index: trunk/fundcore/modules/panels/content_types/custom.inc
@@ -0,0 +1,113 @@
 2+<?php
 3+/**
 4+ * Callback function to supply a list of content types.
 5+ */
 6+function panels_custom_panels_content_types() {
 7+ $items['custom'] = array(
 8+ 'callback' => 'panels_content_custom',
 9+ 'admin' => 'panels_admin_custom',
 10+ );
 11+ return $items;
 12+}
 13+
 14+/**
 15+ * Output function for the 'custom' content type. Outputs a custom
 16+ * based on the module and delta supplied in the configuration.
 17+ */
 18+function panels_content_custom($conf) {
 19+ $title = filter_xss_admin($conf['title']);
 20+ $css_id = filter_xss_admin($conf['css_id']);
 21+ $css_class = filter_xss_admin($conf['css_class']);
 22+ $body = check_markup($conf['body'], $conf['format'], FALSE);
 23+ return theme('panels_content_custom', $title, $body, $css_id, $css_class);
 24+}
 25+
 26+function theme_panels_content_custom($title, $body, $css_id = NULL, $css_class = NULL) {
 27+ if ($css_id) {
 28+ $css_id = ' id="'. $css_id .'"';
 29+ }
 30+ if ($css_class) {
 31+ $css_class = ' '. $css_class;
 32+ }
 33+ $output = '<div class="panel-custom'. $css_class .'"'. $css_id .'>';
 34+ if ($title) {
 35+ $output .= '<h2 class="title">' . $title . '</h2>';
 36+ }
 37+ $output .= $body;
 38+ $output .= '</div>';
 39+ return $output;
 40+}
 41+/**
 42+ * Callback to perform administrative functions on the content block
 43+ */
 44+function panels_admin_custom($op, &$arg, $arg2 = NULL) {
 45+ switch ($op) {
 46+ case 'list':
 47+ $conf = $arg;
 48+ return '<strong>Custom</strong>: ' . filter_xss_admin($conf['title']);
 49+ case 'add button':
 50+ $form['title'] = array(
 51+ '#title' => t('Enter an optional title for custom content you define'),
 52+ '#type' => 'textfield',
 53+ '#maxlength' => 512,
 54+ '#weight' => -10,
 55+ );
 56+ $form['submit'] = array(
 57+ '#type' => 'button',
 58+ '#value' => t('Add custom'),
 59+ );
 60+
 61+ $form['#prefix'] = '<div class="container-inline">';
 62+ $form['#suffix'] = '</div>';
 63+ return $form;
 64+ case 'add':
 65+ if ($_POST['op'] != t('Add custom')) {
 66+ return;
 67+ }
 68+ return $arg;
 69+ case 'edit':
 70+ $conf = &$arg;
 71+ $form['title'] = array(
 72+ '#type' => 'textfield',
 73+ '#default_value' => $conf['title'],
 74+ '#title' => t('Title'),
 75+ '#description' => t('Title'),
 76+ '#size' => 15,
 77+ );
 78+ $form['body'] = array(
 79+ '#title' => t('Body'),
 80+ '#type' => 'textarea',
 81+ '#default_value' => $conf['body'],
 82+ '#rows' => 10,
 83+ '#cols' => 20,
 84+ );
 85+ $arg2[] = 'format';
 86+ $form['format'] = filter_form($conf['format'], 1, $arg2);
 87+
 88+ $form['css_id'] = array(
 89+ '#type' => 'textfield',
 90+ '#default_value' => $conf['css_id'],
 91+ '#title' => t('CSS ID'),
 92+ '#description' => t('CSS ID of this custom content.'),
 93+ '#weight' => 2,
 94+ '#size' => 15,
 95+ );
 96+ $form['css_class'] = array(
 97+ '#type' => 'textfield',
 98+ '#default_value' => $conf['css_class'],
 99+ '#title' => t('CSS class'),
 100+ '#description' => t('CSS class of this custom content.'),
 101+ '#weight' => 2,
 102+ '#size' => 15,
 103+ );
 104+ return $form;
 105+ case 'validate':
 106+ // This one has nothing to validate.
 107+ $form = &$arg;
 108+ return;
 109+ case 'save':
 110+ // For this one, the form values go directly into the config.
 111+ $form = &$arg;
 112+ return $form;
 113+ }
 114+}
Property changes on: trunk/fundcore/modules/panels/content_types/custom.inc
___________________________________________________________________
Added: svn:eol-style
1115 + native
Index: trunk/fundcore/modules/panels/content_types/views.inc
@@ -0,0 +1,177 @@
 2+<?php
 3+// Only valid if views module loaded.
 4+if (module_exists('views')) {
 5+ /**
 6+ * Callback function to supply a list of content types.
 7+ */
 8+ function panels_views_panels_content_types() {
 9+ $items['views'] = array(
 10+ 'callback' => 'panels_content_views',
 11+ 'admin' => 'panels_admin_views',
 12+ );
 13+ return $items;
 14+ }
 15+
 16+ /**
 17+ * Output function for the 'views' content type. Outputs a views
 18+ * based on the module and delta supplied in the configuration.
 19+ */
 20+ function panels_content_views($conf) {
 21+ $view = views_get_view($conf['view']);
 22+ if ($view) {
 23+ if (function_exists('views_access') && !views_access($view)) {
 24+ return NULL;
 25+ }
 26+
 27+ $arguments = explode('/', $_GET['q']);
 28+ $args = $conf['args'];
 29+
 30+ foreach ($arguments as $id => $arg) {
 31+ $args = str_replace("%$id", $arg, $args);
 32+ }
 33+
 34+ $args = preg_replace('/\\/%\d/', '', $args);
 35+ $args = $args ? explode('/', $args) : array();
 36+
 37+ if ($conf['url']) {
 38+ $view->url = $conf['url'];
 39+ }
 40+
 41+ $content = views_build_view($conf['type'], $view, $args, intval($conf['pager_id']), intval($conf['nodes_per_page']));
 42+
 43+ $title = $conf['show_title'] ? views_get_title($view, $conf['type']) : NULL;
 44+ $output = theme('panels_content_views', $content, $title);
 45+ }
 46+ return $output;
 47+ }
 48+
 49+ function theme_panels_content_views($content, $title) {
 50+ if ($title) {
 51+ $output .= '<h2 class="title">' . $title . '</h2>';
 52+ }
 53+ $output .= $content;
 54+ return $output;
 55+ }
 56+
 57+ /**
 58+ * Callback to perform administrative functions on the content views
 59+ */
 60+ function panels_admin_views($op, &$arg, $arg2 = NULL) {
 61+ switch ($op) {
 62+ case 'list':
 63+ $conf = $arg;
 64+ $view = views_get_view($conf['view']);
 65+ return '<strong>Views</strong>: ' . $view->name . ' (' . $view->description . ')';
 66+ case 'add button':
 67+ $result = db_query("SELECT name, description FROM {view_view}");
 68+ while ($view = db_fetch_object($result)) {
 69+ $views[$view->name] = $view->name . ': ' . $view->description;
 70+ }
 71+
 72+ views_load_cache();
 73+ $default_views = _views_get_default_views();
 74+ $views_status = variable_get('views_defaults', array());
 75+ foreach ($default_views as $view) {
 76+ if (!$views[$view->name] &&
 77+ ($views_status[$view->name] == 'enabled' || (!$views_status[$view->name] && !$view->disabled))) {
 78+ $views[$view->name] = check_plain($view->name . ': ' . $view->description);
 79+ }
 80+ }
 81+
 82+ ksort($views);
 83+
 84+ $form['view'] = array(
 85+ '#type' => 'select',
 86+ '#options' => $views,
 87+ '#title' => t('Choose a view from the views module'),
 88+ );
 89+ $form['submit'] = array(
 90+ '#type' => 'button',
 91+ '#value' => t('Add view'),
 92+ );
 93+
 94+ $form['#prefix'] = '<div class="container-inline">';
 95+ $form['#suffix'] = '</div>';
 96+ return $form;
 97+ case 'add':
 98+ if ($_POST['op'] != t('Add view')) {
 99+ return;
 100+ }
 101+ $conf = $arg;
 102+ $view = views_get_view($conf['view']);
 103+ if ($view->page) {
 104+ $conf['type'] = 'page';
 105+ $conf['nodes_per_page'] = $view->nodes_per_page;
 106+ }
 107+ else {
 108+ $conf['type'] = 'block';
 109+ $conf['nodes_per_page'] = $view->nodes_per_block;
 110+ }
 111+ $conf['pager_id'] = 0;
 112+ return $conf;
 113+ case 'edit':
 114+ $conf = &$arg;
 115+ $form['view'] = array(
 116+ '#type' => 'hidden',
 117+ '#default_value' => $conf['view'],
 118+ );
 119+ $form['type'] = array(
 120+ '#type' => 'select',
 121+ '#default_value' => $conf['type'],
 122+ '#title' => t('View type'),
 123+ '#description' => t('Select which type of the view to display.'),
 124+ '#options' => array('page' => t('Page'), 'block' => t('Block'), 'embed' => t('Embedded')),
 125+ );
 126+ $form['pager_id'] = array(
 127+ '#type' => 'textfield',
 128+ '#default_value' => $conf['pager_id'],
 129+ '#title' => t('Pager ID'),
 130+ '#size' => 4,
 131+ '#description' => t('Select the numeric pager ID to use, or 0 to not have use paging. Select "1" if you aren\'t sure what this means'),
 132+ );
 133+
 134+ $form['nodes_per_page'] = array(
 135+ '#type' => 'textfield',
 136+ '#default_value' => $conf['nodes_per_page'],
 137+ '#title' => t('Posts to Display'),
 138+ '#size' => 4,
 139+ '#description' => t('Select the number of posts to display, or 0 to display all results.'),
 140+ );
 141+
 142+ $form['args'] = array(
 143+ '#type' => 'textfield',
 144+ '#default_value' => $conf['args'],
 145+ '#title' => t('View arguments'),
 146+ '#size' => 12,
 147+ '#description' => t('Arguments to send to the view as if they were part of the URL in the form of arg1/arg2/arg3. You can use %0, %1, %2, etc, to use arguments from the actual URL. For example, if your panel URL is foo/bar, and someone hits foo/bar/5 use %2 to get the 5.'),
 148+ );
 149+
 150+ $form['url'] = array(
 151+ '#type' => 'textfield',
 152+ '#default_value' => $conf['url'],
 153+ '#title' => t('Override URL'),
 154+ '#size' => 12,
 155+ '#description' => t('If this is set, override the View URL; this can sometimes be useful to set to the panel URL'),
 156+ );
 157+
 158+ $form['show_title'] = array(
 159+ '#type' => 'checkbox',
 160+ '#default_value' => $conf['show_title'],
 161+ '#title' => t('Display view title'),
 162+ '#description' => t('If checked, the title of the view will be displayed.'),
 163+ );
 164+
 165+ return $form;
 166+ case 'validate':
 167+ // This one has nothing to validate.
 168+ $form_values = &$arg;
 169+ $form = $arg2;
 170+ return;
 171+ case 'save':
 172+ // For this one, the form values go directly into the config.
 173+ $form = &$arg;
 174+ return $form;
 175+ }
 176+ }
 177+
 178+}
Property changes on: trunk/fundcore/modules/panels/content_types/views.inc
___________________________________________________________________
Added: svn:eol-style
1179 + native
Index: trunk/fundcore/modules/panels/LICENSE.txt
@@ -0,0 +1,274 @@
 2+GNU GENERAL PUBLIC LICENSE
 3+
 4+ Version 2, June 1991
 5+
 6+Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
 7+Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
 8+verbatim copies of this license document, but changing it is not allowed.
 9+
 10+ Preamble
 11+
 12+The licenses for most software are designed to take away your freedom to
 13+share and change it. By contrast, the GNU General Public License is
 14+intended to guarantee your freedom to share and change free software--to
 15+make sure the software is free for all its users. This General Public License
 16+applies to most of the Free Software Foundation's software and to any other
 17+program whose authors commit to using it. (Some other Free Software
 18+Foundation software is covered by the GNU Library General Public License
 19+instead.) You can apply it to your programs, too.
 20+
 21+When we speak of free software, we are referring to freedom, not price. Our
 22+General Public Licenses are designed to make sure that you have the
 23+freedom to distribute copies of free software (and charge for this service if
 24+you wish), that you receive source code or can get it if you want it, that you
 25+can change the software or use pieces of it in new free programs; and that
 26+you know you can do these things.
 27+
 28+To protect your rights, we need to make restrictions that forbid anyone to
 29+deny you these rights or to ask you to surrender the rights. These restrictions
 30+translate to certain responsibilities for you if you distribute copies of the
 31+software, or if you modify it.
 32+
 33+For example, if you distribute copies of such a program, whether gratis or for
 34+a fee, you must give the recipients all the rights that you have. You must make
 35+sure that they, too, receive or can get the source code. And you must show
 36+them these terms so they know their rights.
 37+
 38+We protect your rights with two steps: (1) copyright the software, and (2)
 39+offer you this license which gives you legal permission to copy, distribute
 40+and/or modify the software.
 41+
 42+Also, for each author's protection and ours, we want to make certain that
 43+everyone understands that there is no warranty for this free software. If the
 44+software is modified by someone else and passed on, we want its recipients
 45+to know that what they have is not the original, so that any problems
 46+introduced by others will not reflect on the original authors' reputations.
 47+
 48+Finally, any free program is threatened constantly by software patents. We
 49+wish to avoid the danger that redistributors of a free program will individually
 50+obtain patent licenses, in effect making the program proprietary. To prevent
 51+this, we have made it clear that any patent must be licensed for everyone's
 52+free use or not licensed at all.
 53+
 54+The precise terms and conditions for copying, distribution and modification
 55+follow.
 56+
 57+ GNU GENERAL PUBLIC LICENSE
 58+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
 59+ MODIFICATION
 60+
 61+0. This License applies to any program or other work which contains a notice
 62+placed by the copyright holder saying it may be distributed under the terms
 63+of this General Public License. The "Program", below, refers to any such
 64+program or work, and a "work based on the Program" means either the
 65+Program or any derivative work under copyright law: that is to say, a work
 66+containing the Program or a portion of it, either verbatim or with
 67+modifications and/or translated into another language. (Hereinafter, translation
 68+is included without limitation in the term "modification".) Each licensee is
 69+addressed as "you".
 70+
 71+Activities other than copying, distribution and modification are not covered
 72+by this License; they are outside its scope. The act of running the Program is
 73+not restricted, and the output from the Program is covered only if its contents
 74+constitute a work based on the Program (independent of having been made
 75+by running the Program). Whether that is true depends on what the Program
 76+does.
 77+
 78+1. You may copy and distribute verbatim copies of the Program's source
 79+code as you receive it, in any medium, provided that you conspicuously and
 80+appropriately publish on each copy an appropriate copyright notice and
 81+disclaimer of warranty; keep intact all the notices that refer to this License
 82+and to the absence of any warranty; and give any other recipients of the
 83+Program a copy of this License along with the Program.
 84+
 85+You may charge a fee for the physical act of transferring a copy, and you
 86+may at your option offer warranty protection in exchange for a fee.
 87+
 88+2. You may modify your copy or copies of the Program or any portion of it,
 89+thus forming a work based on the Program, and copy and distribute such
 90+modifications or work under the terms of Section 1 above, provided that you
 91+also meet all of these conditions:
 92+
 93+a) You must cause the modified files to carry prominent notices stating that
 94+you changed the files and the date of any change.
 95+
 96+b) You must cause any work that you distribute or publish, that in whole or in
 97+part contains or is derived from the Program or any part thereof, to be
 98+licensed as a whole at no charge to all third parties under the terms of this
 99+License.
 100+
 101+c) If the modified program normally reads commands interactively when run,
 102+you must cause it, when started running for such interactive use in the most
 103+ordinary way, to print or display an announcement including an appropriate
 104+copyright notice and a notice that there is no warranty (or else, saying that
 105+you provide a warranty) and that users may redistribute the program under
 106+these conditions, and telling the user how to view a copy of this License.
 107+(Exception: if the Program itself is interactive but does not normally print such
 108+an announcement, your work based on the Program is not required to print
 109+an announcement.)
 110+
 111+These requirements apply to the modified work as a whole. If identifiable
 112+sections of that work are not derived from the Program, and can be
 113+reasonably considered independent and separate works in themselves, then
 114+this License, and its terms, do not apply to those sections when you distribute
 115+them as separate works. But when you distribute the same sections as part
 116+of a whole which is a work based on the Program, the distribution of the
 117+whole must be on the terms of this License, whose permissions for other
 118+licensees extend to the entire whole, and thus to each and every part
 119+regardless of who wrote it.
 120+
 121+Thus, it is not the intent of this section to claim rights or contest your rights to
 122+work written entirely by you; rather, the intent is to exercise the right to
 123+control the distribution of derivative or collective works based on the
 124+Program.
 125+
 126+In addition, mere aggregation of another work not based on the Program
 127+with the Program (or with a work based on the Program) on a volume of a
 128+storage or distribution medium does not bring the other work under the scope
 129+of this License.
 130+
 131+3. You may copy and distribute the Program (or a work based on it, under
 132+Section 2) in object code or executable form under the terms of Sections 1
 133+and 2 above provided that you also do one of the following:
 134+
 135+a) Accompany it with the complete corresponding machine-readable source
 136+code, which must be distributed under the terms of Sections 1 and 2 above
 137+on a medium customarily used for software interchange; or,
 138+
 139+b) Accompany it with a written offer, valid for at least three years, to give
 140+any third party, for a charge no more than your cost of physically performing
 141+source distribution, a complete machine-readable copy of the corresponding
 142+source code, to be distributed under the terms of Sections 1 and 2 above on
 143+a medium customarily used for software interchange; or,
 144+
 145+c) Accompany it with the information you received as to the offer to distribute
 146+corresponding source code. (This alternative is allowed only for
 147+noncommercial distribution and only if you received the program in object
 148+code or executable form with such an offer, in accord with Subsection b
 149+above.)
 150+
 151+The source code for a work means the preferred form of the work for
 152+making modifications to it. For an executable work, complete source code
 153+means all the source code for all modules it contains, plus any associated
 154+interface definition files, plus the scripts used to control compilation and
 155+installation of the executable. However, as a special exception, the source
 156+code distributed need not include anything that is normally distributed (in
 157+either source or binary form) with the major components (compiler, kernel,
 158+and so on) of the operating system on which the executable runs, unless that
 159+component itself accompanies the executable.
 160+
 161+If distribution of executable or object code is made by offering access to
 162+copy from a designated place, then offering equivalent access to copy the
 163+source code from the same place counts as distribution of the source code,
 164+even though third parties are not compelled to copy the source along with the
 165+object code.
 166+
 167+4. You may not copy, modify, sublicense, or distribute the Program except as
 168+expressly provided under this License. Any attempt otherwise to copy,
 169+modify, sublicense or distribute the Program is void, and will automatically
 170+terminate your rights under this License. However, parties who have received
 171+copies, or rights, from you under this License will not have their licenses
 172+terminated so long as such parties remain in full compliance.
 173+
 174+5. You are not required to accept this License, since you have not signed it.
 175+However, nothing else grants you permission to modify or distribute the
 176+Program or its derivative works. These actions are prohibited by law if you
 177+do not accept this License. Therefore, by modifying or distributing the
 178+Program (or any work based on the Program), you indicate your acceptance
 179+of this License to do so, and all its terms and conditions for copying,
 180+distributing or modifying the Program or works based on it.
 181+
 182+6. Each time you redistribute the Program (or any work based on the
 183+Program), the recipient automatically receives a license from the original
 184+licensor to copy, distribute or modify the Program subject to these terms and
 185+conditions. You may not impose any further restrictions on the recipients'
 186+exercise of the rights granted herein. You are not responsible for enforcing
 187+compliance by third parties to this License.
 188+
 189+7. If, as a consequence of a court judgment or allegation of patent
 190+infringement or for any other reason (not limited to patent issues), conditions
 191+are imposed on you (whether by court order, agreement or otherwise) that
 192+contradict the conditions of this License, they do not excuse you from the
 193+conditions of this License. If you cannot distribute so as to satisfy
 194+simultaneously your obligations under this License and any other pertinent
 195+obligations, then as a consequence you may not distribute the Program at all.
 196+For example, if a patent license would not permit royalty-free redistribution
 197+of the Program by all those who receive copies directly or indirectly through
 198+you, then the only way you could satisfy both it and this License would be to
 199+refrain entirely from distribution of the Program.
 200+
 201+If any portion of this section is held invalid or unenforceable under any
 202+particular circumstance, the balance of the section is intended to apply and
 203+the section as a whole is intended to apply in other circumstances.
 204+
 205+It is not the purpose of this section to induce you to infringe any patents or
 206+other property right claims or to contest validity of any such claims; this
 207+section has the sole purpose of protecting the integrity of the free software
 208+distribution system, which is implemented by public license practices. Many
 209+people have made generous contributions to the wide range of software
 210+distributed through that system in reliance on consistent application of that
 211+system; it is up to the author/donor to decide if he or she is willing to
 212+distribute software through any other system and a licensee cannot impose
 213+that choice.
 214+
 215+This section is intended to make thoroughly clear what is believed to be a
 216+consequence of the rest of this License.
 217+
 218+8. If the distribution and/or use of the Program is restricted in certain
 219+countries either by patents or by copyrighted interfaces, the original copyright
 220+holder who places the Program under this License may add an explicit
 221+geographical distribution limitation excluding those countries, so that
 222+distribution is permitted only in or among countries not thus excluded. In such
 223+case, this License incorporates the limitation as if written in the body of this
 224+License.
 225+
 226+9. The Free Software Foundation may publish revised and/or new versions
 227+of the General Public License from time to time. Such new versions will be
 228+similar in spirit to the present version, but may differ in detail to address new
 229+problems or concerns.
 230+
 231+Each version is given a distinguishing version number. If the Program specifies
 232+a version number of this License which applies to it and "any later version",
 233+you have the option of following the terms and conditions either of that
 234+version or of any later version published by the Free Software Foundation. If
 235+the Program does not specify a version number of this License, you may
 236+choose any version ever published by the Free Software Foundation.
 237+
 238+10. If you wish to incorporate parts of the Program into other free programs
 239+whose distribution conditions are different, write to the author to ask for
 240+permission. For software which is copyrighted by the Free Software
 241+Foundation, write to the Free Software Foundation; we sometimes make
 242+exceptions for this. Our decision will be guided by the two goals of
 243+preserving the free status of all derivatives of our free software and of
 244+promoting the sharing and reuse of software generally.
 245+
 246+ NO WARRANTY
 247+
 248+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
 249+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
 250+PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
 251+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
 252+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
 253+WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
 254+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 255+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 256+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
 257+PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
 258+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
 259+NECESSARY SERVICING, REPAIR OR CORRECTION.
 260+
 261+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
 262+AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
 263+ANY OTHER PARTY WHO MAY MODIFY AND/OR
 264+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
 265+LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
 266+SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
 267+ARISING OUT OF THE USE OR INABILITY TO USE THE
 268+PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
 269+OR DATA BEING RENDERED INACCURATE OR LOSSES
 270+SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
 271+PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
 272+IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
 273+THE POSSIBILITY OF SUCH DAMAGES.
 274+
 275+ END OF TERMS AND CONDITIONS
Property changes on: trunk/fundcore/modules/panels/LICENSE.txt
___________________________________________________________________
Added: svn:eol-style
1276 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.png
___________________________________________________________________
Added: svn:mime-type
2277 + image/png
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.png
___________________________________________________________________
Added: svn:mime-type
3278 + image/png
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.png
___________________________________________________________________
Added: svn:mime-type
4279 + image/png
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.png
___________________________________________________________________
Added: svn:mime-type
5280 + image/png
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.css
@@ -0,0 +1,26 @@
 2+/* $Id: threecol_25_50_25_stacked.css,v 1.3 2006/07/24 23:56:08 merlinofchaos Exp $ */
 3+
 4+.panel-3col-stacked {
 5+ /* border: 1px solid red; */
 6+ overflow: hidden;
 7+}
 8+.panel-3col-stacked div div {
 9+ margin: .5em;
 10+}
 11+.panel-3col-stacked .panel-col-top,
 12+.panel-3col-stacked .panel-col-bottom {
 13+ width: 100%;
 14+ clear: both;
 15+}
 16+.panel-3col-stacked .panel-col-first {
 17+ float: left;
 18+ width: 25%;
 19+}
 20+.panel-3col-stacked .panel-col {
 21+ float: left;
 22+ width: 50%;
 23+}
 24+.panel-3col-stacked .panel-col-last {
 25+ float: left;
 26+ width: 25%;
 27+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.css
___________________________________________________________________
Added: svn:eol-style
128 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.css
@@ -0,0 +1,29 @@
 2+/* $Id: threecol_33_34_33_stacked.css,v 1.4 2006/08/22 23:54:20 merlinofchaos Exp $ */
 3+
 4+.panel-3col-33-stacked {
 5+ /* border: 1px solid red; */
 6+ overflow: hidden;
 7+}
 8+.panel-3col-33-stacked div div {
 9+ margin: .5em;
 10+}
 11+.panel-3col-33-stacked .panel-col-top,
 12+.panel-3col-33-stacked .panel-col-bottom {
 13+ width: 100%;
 14+ clear: both;
 15+}
 16+.panel-3col-33-stacked .panel-col-first {
 17+ float: left;
 18+ width: 33%;
 19+}
 20+.panel-3col-33-stacked .panel-col {
 21+ float: left;
 22+ width: 34%;
 23+}
 24+.panel-3col-33-stacked .panel-col-last {
 25+ float: left;
 26+ width: 33%;
 27+}
 28+.panel-clearer {
 29+ clear: both;
 30+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.css
___________________________________________________________________
Added: svn:eol-style
131 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.css
@@ -0,0 +1,22 @@
 2+.panel-3col {
 3+ /* border: 1px solid red; */
 4+ overflow: hidden;
 5+}
 6+.panel-3col div div {
 7+ margin: .5em;
 8+}
 9+.panel-3col .panel-col-first {
 10+ float: left;
 11+ width: 25%;
 12+}
 13+.panel-3col .panel-col {
 14+ float: left;
 15+ width: 50%;
 16+}
 17+.panel-3col .panel-col-last {
 18+ float: left;
 19+ width: 25%;
 20+}
 21+.panel-clearer {
 22+ clear: both;
 23+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.css
___________________________________________________________________
Added: svn:eol-style
124 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.css
@@ -0,0 +1,24 @@
 2+/* $Id: threecol_33_34_33.css,v 1.4 2006/08/22 23:54:20 merlinofchaos Exp $ */
 3+
 4+.panel-3col-33 {
 5+ /* border: 1px solid red; */
 6+ overflow: hidden;
 7+}
 8+.panel-3col-33 div div {
 9+ margin: .5em;
 10+}
 11+.panel-3col-33 .panel-col-first {
 12+ float: left;
 13+ width: 33%;
 14+}
 15+.panel-3col-33 .panel-col {
 16+ float: left;
 17+ width: 34%;
 18+}
 19+.panel-3col-33 .panel-col-last {
 20+ float: left;
 21+ width: 33%;
 22+}
 23+.panel-clearer {
 24+ clear: both;
 25+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.css
___________________________________________________________________
Added: svn:eol-style
126 + native
Index: trunk/fundcore/modules/panels/layouts/twocol_stacked.inc
@@ -0,0 +1,48 @@
 2+<?php
 3+// $Id: twocol_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos Exp $
 4+
 5+/**
 6+ * implementation of hook_panels_layouts
 7+ */
 8+function panels_twocol_stacked_panels_layouts() {
 9+ $items['twocol_stacked'] = array(
 10+ 'module' => 'panels',
 11+ 'title' => t('Two column stacked'),
 12+ 'icon' => 'layouts/twocol_stacked.png',
 13+ 'theme' => 'panels_twocol_stacked',
 14+ 'css' => 'layouts/twocol_stacked.css',
 15+ 'content areas' => array('top' => t('Top'), 'left' => t('Left side'), 'right' => t('Right side'), 'bottom' => t('Bottom')),
 16+ );
 17+
 18+ return $items;
 19+}
 20+
 21+/**
 22+ * This function uses heredoc notation to make it easier to convert
 23+ * to a template.
 24+ */
 25+function theme_panels_twocol_stacked($id, $content) {
 26+ if ($id) {
 27+ $idstr = " id='$id'";
 28+ }
 29+
 30+ $output = <<<EOT
 31+<div class="panel-2col-stacked" $idstr>
 32+ <div class="panel-col-top">
 33+ <div>$content[top]</div>
 34+ </div>
 35+ <div class="panel-col-first">
 36+ <div>$content[left]</div>
 37+ </div>
 38+
 39+ <div class="panel-col-last">
 40+ <div>$content[right]</div>
 41+ </div>
 42+ <div class="panel-col-bottom">
 43+ <div>$content[bottom]</div>
 44+ </div>
 45+</div>
 46+<br class="panel-clearer" />
 47+EOT;
 48+ return $output;
 49+}
Property changes on: trunk/fundcore/modules/panels/layouts/twocol_stacked.inc
___________________________________________________________________
Added: svn:eol-style
150 + native
Index: trunk/fundcore/modules/panels/layouts/twocol.inc
@@ -0,0 +1,41 @@
 2+<?php
 3+// $Id: twocol.inc,v 1.6 2006/08/22 23:54:20 merlinofchaos Exp $
 4+/**
 5+ * implementation of hook_panels_layouts
 6+ */
 7+function panels_twocol_panels_layouts() {
 8+ $items['twocol'] = array(
 9+ 'module' => 'panels',
 10+ 'title' => t('Two column'),
 11+ 'icon' => 'layouts/twocol.png',
 12+ 'theme' => 'panels_twocol',
 13+ 'css' => 'layouts/twocol.css',
 14+ 'content areas' => array('left' => t('Left side'), 'right' => t('Right side')),
 15+ );
 16+
 17+ return $items;
 18+}
 19+
 20+/**
 21+ * This function uses heredoc notation to make it easier to convert
 22+ * to a template.
 23+ */
 24+function theme_panels_twocol($id, $content) {
 25+ if ($id) {
 26+ $idstr = " id='$id'";
 27+ }
 28+
 29+ $output = <<<EOT
 30+<div class="panel-2col" $idstr>
 31+ <div class="panel-col-first">
 32+ <div>$content[left]</div>
 33+ </div>
 34+
 35+ <div class="panel-col-last">
 36+ <div>$content[right]</div>
 37+ </div>
 38+</div>
 39+<br class="panel-clearer" />
 40+EOT;
 41+ return $output;
 42+}
Property changes on: trunk/fundcore/modules/panels/layouts/twocol.inc
___________________________________________________________________
Added: svn:eol-style
143 + native
Index: trunk/fundcore/modules/panels/layouts/twocol_stacked.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/twocol_stacked.png
___________________________________________________________________
Added: svn:mime-type
244 + image/png
Index: trunk/fundcore/modules/panels/layouts/twocol.png
Cannot display: file marked as a binary type.
svn:mime-type = image/png
Property changes on: trunk/fundcore/modules/panels/layouts/twocol.png
___________________________________________________________________
Added: svn:mime-type
345 + image/png
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.inc
@@ -0,0 +1,52 @@
 2+<?php
 3+// $Id: threecol_25_50_25_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos Exp $
 4+
 5+/**
 6+ * implementation of hook_panels_layouts
 7+ */
 8+function panels_threecol_25_50_25_stacked_panels_layouts() {
 9+ $items['threecol_25_50_25_stacked'] = array(
 10+ 'module' => 'panels',
 11+ 'title' => t('Three column 25/50/25 stacked'),
 12+ 'icon' => 'layouts/threecol_25_50_25_stacked.png',
 13+ 'theme' => 'panels_threecol_25_50_25_stacked',
 14+ 'css' => 'layouts/threecol_25_50_25_stacked.css',
 15+ 'content areas' => array('top' => t('Top'), 'left' => t('Left side'), 'middle' => t('Middle column'), 'right' => t('Right side'), 'bottom' => t('Bottom')),
 16+ );
 17+
 18+ return $items;
 19+}
 20+
 21+/**
 22+ * This function uses heredoc notation to make it easier to convert
 23+ * to a template.
 24+ */
 25+function theme_panels_threecol_25_50_25_stacked($id, $content) {
 26+ if ($id) {
 27+ $idstr = " id='$id'";
 28+ }
 29+
 30+ $output = <<<EOT
 31+<div class="panel-3col-stacked" $idstr>
 32+ <div class="panel-col-top">
 33+ <div>$content[top]</div>
 34+ </div>
 35+ <div class="panel-col-first">
 36+ <div>$content[left]</div>
 37+ </div>
 38+
 39+ <div class="panel-col">
 40+ <div>$content[middle]</div>
 41+ </div>
 42+
 43+ <div class="panel-col-last">
 44+ <div>$content[right]</div>
 45+ </div>
 46+ <div class="panel-col-bottom">
 47+ <div>$content[bottom]</div>
 48+ </div>
 49+</div>
 50+<br class="panel-clearer" />
 51+EOT;
 52+ return $output;
 53+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25_stacked.inc
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.inc
@@ -0,0 +1,52 @@
 2+<?php
 3+// $Id: threecol_33_34_33_stacked.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos Exp $
 4+
 5+/**
 6+ * implementation of hook_panels_layouts
 7+ */
 8+function panels_threecol_33_34_33_stacked_panels_layouts() {
 9+ $items['threecol_33_34_33_stacked'] = array(
 10+ 'module' => 'panels',
 11+ 'title' => t('Three column 33/34/33 stacked'),
 12+ 'icon' => 'layouts/threecol_33_34_33_stacked.png',
 13+ 'theme' => 'panels_threecol_33_34_33_stacked',
 14+ 'css' => 'layouts/threecol_33_34_33_stacked.css',
 15+ 'content areas' => array('top' => t('Top'), 'left' => t('Left side'), 'middle' => t('Middle column'), 'right' => t('Right side'), 'bottom' => t('Bottom')),
 16+ );
 17+
 18+ return $items;
 19+}
 20+
 21+/**
 22+ * This function uses heredoc notation to make it easier to convert
 23+ * to a template.
 24+ */
 25+function theme_panels_threecol_33_34_33_stacked($id, $content) {
 26+ if ($id) {
 27+ $idstr = " id='$id'";
 28+ }
 29+
 30+ $output = <<<EOT
 31+<div class="panel-3col-33-stacked" $idstr>
 32+ <div class="panel-col-top">
 33+ <div>$content[top]</div>
 34+ </div>
 35+ <div class="panel-col-first">
 36+ <div>$content[left]</div>
 37+ </div>
 38+
 39+ <div class="panel-col">
 40+ <div>$content[middle]</div>
 41+ </div>
 42+
 43+ <div class="panel-col-last">
 44+ <div>$content[right]</div>
 45+ </div>
 46+ <div class="panel-col-bottom">
 47+ <div>$content[bottom]</div>
 48+ </div>
 49+</div>
 50+<br class="panel-clearer" />
 51+EOT;
 52+ return $output;
 53+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33_stacked.inc
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: trunk/fundcore/modules/panels/layouts/twocol_stacked.css
@@ -0,0 +1,27 @@
 2+/* $Id: twocol_stacked.css,v 1.4.4.1 2007/03/15 20:16:53 merlinofchaos Exp $ */
 3+
 4+.panel-2col-stacked {
 5+ /* border: 1px solid red; */
 6+ overflow: hidden;
 7+}
 8+
 9+.panel-2col-stacked div > div {
 10+ margin: .5px;
 11+}
 12+
 13+.panel-2col-stacked .panel-col-top,
 14+.panel-2col-stacked .panel-col-bottom {
 15+ width: 99.9%;
 16+ clear: both;
 17+}
 18+.panel-2col-stacked .panel-col-first {
 19+ float: left;
 20+ width: 47%;
 21+}
 22+.panel-2col-stacked .panel-col-last {
 23+ float: right;
 24+ width: 47%;
 25+}
 26+.panel-clearer {
 27+ clear: both;
 28+}
Property changes on: trunk/fundcore/modules/panels/layouts/twocol_stacked.css
___________________________________________________________________
Added: svn:eol-style
129 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.inc
@@ -0,0 +1,45 @@
 2+<?php
 3+// $Id: threecol_33_34_33.inc,v 1.5 2006/08/22 23:54:20 merlinofchaos Exp $
 4+/**
 5+ * implementation of hook_panels_layouts
 6+ */
 7+function panels_threecol_33_34_33_panels_layouts() {
 8+ $items['threecol_33_34_33'] = array(
 9+ 'module' => 'panels',
 10+ 'title' => t('Three column 33/34/33'),
 11+ 'icon' => 'layouts/threecol_33_34_33.png',
 12+ 'theme' => 'panels_threecol_33_34_33',
 13+ 'css' => 'layouts/threecol_33_34_33.css',
 14+ 'content areas' => array('left' => t('Left side'), 'middle' => t('Middle column'), 'right' => t('Right side')),
 15+ );
 16+
 17+ return $items;
 18+}
 19+
 20+/**
 21+ * This function uses heredoc notation to make it easier to convert
 22+ * to a template.
 23+ */
 24+function theme_panels_threecol_33_34_33($id, $content) {
 25+ if ($id) {
 26+ $idstr = " id='$id'";
 27+ }
 28+
 29+ $output = <<<EOT
 30+<div class="panel-3col-33" $idstr>
 31+ <div class="panel-col-first">
 32+ <div>$content[left]</div>
 33+ </div>
 34+
 35+ <div class="panel-col">
 36+ <div>$content[middle]</div>
 37+ </div>
 38+
 39+ <div class="panel-col-last">
 40+ <div>$content[right]</div>
 41+ </div>
 42+</div>
 43+<br class="panel-clearer" />
 44+EOT;
 45+ return $output;
 46+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_33_34_33.inc
___________________________________________________________________
Added: svn:eol-style
147 + native
Index: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.inc
@@ -0,0 +1,44 @@
 2+<?php
 3+/**
 4+ * implementation of hook_panels_layouts
 5+ */
 6+function panels_threecol_25_50_25_panels_layouts() {
 7+ $items['threecol_25_50_25'] = array(
 8+ 'module' => 'panels',
 9+ 'title' => t('Three column 25/50/25'),
 10+ 'icon' => 'layouts/threecol_25_50_25.png',
 11+ 'theme' => 'panels_threecol_25_50_25',
 12+ 'css' => 'layouts/threecol_25_50_25.css',
 13+ 'content areas' => array('left' => t('Left side'), 'middle' => t('Middle column'), 'right' => t('Right side')),
 14+ );
 15+
 16+ return $items;
 17+}
 18+
 19+/**
 20+ * This function uses heredoc notation to make it easier to convert
 21+ * to a template.
 22+ */
 23+function theme_panels_threecol_25_50_25($id, $content) {
 24+ if ($id) {
 25+ $idstr = " id='$id'";
 26+ }
 27+
 28+ $output = <<<EOT
 29+<div class="panel-3col" $idstr>
 30+ <div class="panel-col-first">
 31+ <div>$content[left]</div>
 32+ </div>
 33+
 34+ <div class="panel-col">
 35+ <div>$content[middle]</div>
 36+ </div>
 37+
 38+ <div class="panel-col-last">
 39+ <div>$content[right]</div>
 40+ </div>
 41+</div>
 42+<br class="panel-clearer" />
 43+EOT;
 44+ return $output;
 45+}
Property changes on: trunk/fundcore/modules/panels/layouts/threecol_25_50_25.inc
___________________________________________________________________
Added: svn:eol-style
146 + native
Index: trunk/fundcore/modules/panels/layouts/twocol.css
@@ -0,0 +1,22 @@
 2+/* $Id: twocol.css,v 1.4 2006/08/22 23:54:20 merlinofchaos Exp $ */
 3+
 4+.panel-2col {
 5+ /* border: 1px solid red; */
 6+ overflow: hidden;
 7+}
 8+
 9+.panel-2col div div {
 10+ margin: .5em;
 11+}
 12+
 13+.panel-2col .panel-col-first {
 14+ float: left;
 15+ width: 50%;
 16+}
 17+.panel-2col .panel-col-last {
 18+ float: left;
 19+ width: 50%;
 20+}
 21+.panel-clearer {
 22+ clear: both;
 23+}
Property changes on: trunk/fundcore/modules/panels/layouts/twocol.css
___________________________________________________________________
Added: svn:eol-style
124 + native
Index: trunk/fundcore/modules/panels/panels_admin.css
@@ -0,0 +1,14 @@
 2+.layout-link {
 3+ float: left;
 4+ padding: 1em;
 5+ width: 125px;
 6+}
 7+
 8+.layout-link img {
 9+ margin-left: auto;
 10+ margin-right: auto;
 11+}
 12+
 13+.layout-icon {
 14+ float: right;
 15+}
\ No newline at end of file
Property changes on: trunk/fundcore/modules/panels/panels_admin.css
___________________________________________________________________
Added: svn:eol-style
116 + native
Index: trunk/fundcore/modules/panels/TODO.txt
@@ -0,0 +1,12 @@
 2+TODO:
 3+
 4+This is a brief list of the things that may still need to be done. No guarantee
 5+of them ever getting done.
 6+
 7+content type: phptemplate
 8+
 9+access control to pages
 10+access control to content types
 11+
 12+dashboard node extension
 13+
Property changes on: trunk/fundcore/modules/panels/TODO.txt
___________________________________________________________________
Added: svn:eol-style
114 + native

Status & tagging log