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 |
1 | 15 | + 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 |
1 | 29 | + 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 |
2 | 30 | + 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 |
3 | 31 | + 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 |
4 | 32 | + 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 |
5 | 33 | + 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 |
6 | 34 | + 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 |
7 | 35 | + 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 |
8 | 36 | + 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 |
9 | 37 | + 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 |
10 | 38 | + 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 |
11 | 39 | + 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 . ' ' . $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 |
1 | 860 | + 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 |
1 | 127 | + 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 |
1 | 28 | + 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 |
1 | 12 | + 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 |
1 | 112 | + 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 |
1 | 130 | + 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 |
1 | 115 | + 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 |
1 | 179 | + 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 |
1 | 276 | + 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 |
2 | 277 | + 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 |
3 | 278 | + 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 |
4 | 279 | + 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 |
5 | 280 | + 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 |
1 | 28 | + 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 |
1 | 31 | + 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 |
1 | 24 | + 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 |
1 | 26 | + 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 |
1 | 50 | + 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 |
1 | 43 | + 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 |
2 | 44 | + 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 |
3 | 45 | + 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 |
1 | 54 | + 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 |
1 | 54 | + 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 |
1 | 29 | + 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 |
1 | 47 | + 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 |
1 | 46 | + 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 |
1 | 24 | + 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 |
1 | 16 | + 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 |
1 | 14 | + native |