first import

This commit is contained in:
Bachir Soussi Chiadmi
2015-04-08 11:40:19 +02:00
commit 1bc61b12ad
8435 changed files with 1582817 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
<?php
/**
* @file
* Provides a simple time-based caching option for panel panes.
*/
// Plugin definition
$plugin = array(
'title' => t("Simple cache"),
'description' => t('Simple caching is a time-based cache. This is a hard limit, and once cached it will remain that way until the time limit expires.'),
'cache get' => 'panels_simple_cache_get_cache',
'cache set' => 'panels_simple_cache_set_cache',
'cache clear' => 'panels_simple_cache_clear_cache',
'settings form' => 'panels_simple_cache_settings_form',
'settings form submit' => 'panels_simple_cache_settings_form_submit',
'defaults' => array(
'lifetime' => 15,
'granularity' => 'none',
),
);
/**
* Get cached content.
*/
function panels_simple_cache_get_cache($conf, $display, $args, $contexts, $pane = NULL) {
$cid = panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane);
$cache = cache_get($cid, 'cache');
if (!$cache) {
return FALSE;
}
if ((time() - $cache->created) > $conf['lifetime']) {
return FALSE;
}
return $cache->data;
}
/**
* Set cached content.
*/
function panels_simple_cache_set_cache($conf, $content, $display, $args, $contexts, $pane = NULL) {
$cid = panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane);
cache_set($cid, $content);
}
/**
* Clear cached content.
*
* Cache clears are always for an entire display, regardless of arguments.
*/
function panels_simple_cache_clear_cache($display) {
$cid = 'panels_simple_cache';
// This is used in case this is an in-code display, which means did will be something like 'new-1'.
if (isset($display->owner) && isset($display->owner->id)) {
$cid .= ':' . $display->owner->id;
}
$cid .= ':' . $display->did;
cache_clear_all($cid, 'cache', TRUE);
}
/**
* Figure out an id for our cache based upon input and settings.
*/
function panels_simple_cache_get_id($conf, $display, $args, $contexts, $pane) {
$id = 'panels_simple_cache';
// If the panel is stored in the database it'll have a numeric did value.
if (is_numeric($display->did)) {
$id .= ':' . $display->did;
}
// Exported panels won't have a numeric did but may have a usable cache_key.
elseif (!empty($display->cache_key)) {
$id .= ':' . str_replace('panel_context:', '', $display->cache_key);
}
// Alternatively use the css_id.
elseif (!empty($display->css_id)) {
$id .= ':' . $display->css_id;
}
// Failover to just appending the did, which may be the completely unusable
// string 'new'.
else {
$id .= ':' . $display->did;
}
if ($pane) {
$id .= ':' . $pane->pid;
}
if (user_access('view pane admin links')) {
$id .= ':admin';
}
switch ($conf['granularity']) {
case 'args':
foreach ($args as $arg) {
$id .= ':' . $arg;
}
break;
case 'context':
if (!is_array($contexts)) {
$contexts = array($contexts);
}
foreach ($contexts as $context) {
if (isset($context->argument)) {
$id .= ':' . $context->argument;
}
}
}
if (module_exists('locale')) {
global $language;
$id .= ':' . $language->language;
}
if(!empty($pane->configuration['use_pager']) && !empty($_GET['page'])) {
$id .= ':p' . check_plain($_GET['page']);
}
return $id;
}
function panels_simple_cache_settings_form($conf, $display, $pid) {
$options = drupal_map_assoc(array(15, 30, 60, 120, 180, 240, 300, 600, 900, 1200, 1800, 3600, 7200, 14400, 28800, 43200, 86400, 172800, 259200, 345600, 604800), 'format_interval');
$form['lifetime'] = array(
'#title' => t('Lifetime'),
'#type' => 'select',
'#options' => $options,
'#default_value' => $conf['lifetime'],
);
$form['granularity'] = array(
'#title' => t('Granularity'),
'#type' => 'select',
'#options' => array(
'args' => t('Arguments'),
'context' => t('Context'),
'none' => t('None'),
),
'#description' => t('If "arguments" are selected, this content will be cached per individual argument to the entire display; if "contexts" are selected, this content will be cached per unique context in the pane or display; if "neither" there will be only one cache for this pane.'),
'#default_value' => $conf['granularity'],
);
return $form;
}

View File

@@ -0,0 +1,5 @@
<?php
$plugin = array(
'renderer' => 'panels_renderer_editor',
);

View File

@@ -0,0 +1,32 @@
<?php
/**
* @file
* Contains the simple display renderer.
*/
/**
* The simple display renderer renders a display normally, except each pane
* is already rendered content, rather than a pane containing CTools content
* to be rendered. Styles are not supported.
*/
class panels_renderer_simple extends panels_renderer_standard {
function render_regions() {
$this->rendered['regions'] = array();
foreach ($this->display->content as $region_id => $content) {
if (is_array($content)) {
$content = implode('', $content);
}
$this->rendered['regions'][$region_id] = $content;
}
return $this->rendered['regions'];
}
function render_panes() {
// NOP
}
function prepare($external_settings = NULL) {
$this->prep_run = TRUE;
}
}

View File

@@ -0,0 +1,633 @@
<?php
/**
* The standard render pipeline for a Panels display object.
*
* Given a fully-loaded panels_display object, this class will turn its
* combination of layout, panes, and styles into HTML, invoking caching
* appropriately along the way. Interacting with the renderer externally is
* very simple - just pass it the display object and call the render() method:
*
* @code
* // given that $display is a fully loaded Panels display object
* $renderer = panels_get_renderer_handler('standard', $display)
* $html_output = $renderer->render();
* @endcode
*
* Internally, the render pipeline is divided into two phases, prepare and
* render:
* - The prepare phase transforms the skeletal data on the provided
* display object into a structure that is expected by the render phase.
* It is divided into a series of discrete sub-methods and operates
* primarily by passing parameters, all with the intention of making
* subclassing easier.
* - The render phase relies primarily on data stored in the renderer object's
* properties, presumably set in the prepare phase. It iterates through the
* rendering of each pane, pane styling, placement in panel regions, region
* styling, and finally the arrangement of rendered regions in the layout.
* Caching, if in use, is triggered per pane, or on the entire display.
*
* In short: prepare builds conf, render renders conf. Subclasses should respect
* this separation of responsibilities by adhering to these loose guidelines,
* given a loaded display object:
* - If your renderer needs to modify the datastructure representing what is
* to be rendered (panes and their conf, styles, caching, etc.), it should
* use the prepare phase.
* - If your renderer needs to modify the manner in which that renderable
* datastructure data is rendered, it should use the render phase.
*
* In the vast majority of use cases, this standard renderer will be sufficient
* and need not be switched out/subclassed; style and/or layout plugins can
* accommodate nearly every use case. If you think you might need a custom
* renderer, consider the following criteria/examples:
* - Some additional markup needs to be added to EVERY SINGLE panel.
* - Given a full display object, just render one pane.
* - Show a Panels admin interface.
*
* The system is almost functionally identical to the old procedural approach,
* with some exceptions (@see panels_renderer_legacy for details). The approach
* here differs primarily in its friendliness to tweaking in subclasses.
*/
class panels_renderer_standard {
/**
* The fully-loaded Panels display object that is to be rendered. "Fully
* loaded" is defined as:
* 1. Having been produced by panels_load_displays(), whether or this page
* request or at some time in the past and the object was exported.
* 2. Having had some external code attach context data ($display->context),
* in the exact form expected by panes. Context matching is delicate,
* typically relying on exact string matches, so special attention must
* be taken.
*
* @var panels_display
*/
var $display;
/**
* An associative array of loaded plugins. Used primarily as a central
* location for storing plugins that require additional loading beyond
* reading the plugin definition, which is already statically cached by
* ctools_get_plugins(). An example is layout plugins, which can optionally
* have a callback that determines the set of panel regions available at
* runtime.
*
* @var array
*/
var $plugins = array();
/**
* A multilevel array of rendered data. The first level of the array
* indicates the type of rendered data, typically with up to three keys:
* 'layout', 'regions', and 'panes'. The relevant rendered data is stored as
* the value for each of these keys as it is generated:
* - 'panes' are an associative array of rendered output, keyed on pane id.
* - 'regions' are an associative array of rendered output, keyed on region
* name.
* - 'layout' is the whole of the rendered output.
*
* @var array
*/
var $rendered = array();
/**
* A multilevel array of data prepared for rendering. The first level of the
* array indicates the type of prepared data. The standard renderer populates
* and uses two top-level keys, 'panes' and 'regions':
* - 'panes' are an associative array of pane objects to be rendered, keyed
* on pane id and sorted into proper rendering order.
* - 'regions' are an associative array of regions, keyed on region name,
* each of which is itself an indexed array of pane ids in the order in
* which those panes appear in that region.
*
* @var array
*/
var $prepared = array();
/**
* Boolean state variable, indicating whether or not the prepare() method has
* been run.
*
* This state is checked in panels_renderer_standard::render_layout() to
* determine whether the prepare method should be automatically triggered.
*
* @var bool
*/
var $prep_run = FALSE;
/**
* The plugin that defines this handler.
*/
var $plugin = FALSE;
/**
* TRUE if this renderer is rendering in administrative mode
* which will allow layouts to have extra functionality.
*
* @var bool
*/
var $admin = FALSE;
/**
* Where to add standard meta information. There are three possibilities:
* - standard: Put the meta information in the normal location. Default.
* - inline: Put the meta information directly inline. This will
* not work for javascript.
*
* @var string
*/
var $meta_location = 'standard';
/**
* Include rendered HTML prior to the layout.
*
* @var string
*/
var $prefix = '';
/**
* Include rendered HTML after the layout.
*
* @var string
*/
var $suffix = '';
/**
* Receive and store the display object to be rendered.
*
* This is a psuedo-constructor that should typically be called immediately
* after object construction.
*
* @param array $plugin
* The definition of the renderer plugin.
* @param panels_display $display
* The panels display object to be rendered.
*/
function init($plugin, &$display) {
$this->plugin = $plugin;
$layout = panels_get_layout($display->layout);
$this->display = &$display;
$this->plugins['layout'] = $layout;
if (!isset($layout['regions'])) {
$this->plugins['layout']['regions'] = panels_get_regions($layout, $display);
}
if (empty($this->plugins['layout'])) {
watchdog('panels', "Layout: @layout couldn't been found, maybe the theme is disabled.", array('@layout' => $display->layout));
}
}
/**
* Prepare the attached display for rendering.
*
* This is the outermost prepare method. It calls several sub-methods as part
* of the overall preparation process. This compartmentalization is intended
* to ease the task of modifying renderer behavior in child classes.
*
* If you override this method, it is important that you either call this
* method via parent::prepare(), or manually set $this->prep_run = TRUE.
*
* @param mixed $external_settings
* An optional parameter allowing external code to pass in additional
* settings for use in the preparation process. Not used in the default
* renderer, but included for interface consistency.
*/
function prepare($external_settings = NULL) {
$this->prepare_panes($this->display->content);
$this->prepare_regions($this->display->panels, $this->display->panel_settings);
$this->prep_run = TRUE;
}
/**
* Prepare the list of panes to be rendered, accounting for visibility/access
* settings and rendering order.
*
* This method represents the standard approach for determining the list of
* panes to be rendered that is compatible with all parts of the Panels
* architecture. It first applies visibility & access checks, then sorts panes
* into their proper rendering order, and returns the result as an array.
*
* Inheriting classes should override this method if that renderer needs to
* regularly make additions to the set of panes that will be rendered.
*
* @param array $panes
* An associative array of pane data (stdClass objects), keyed on pane id.
* @return array
* An associative array of panes to be rendered, keyed on pane id and sorted
* into proper rendering order.
*/
function prepare_panes($panes) {
ctools_include('content');
// Use local variables as writing to them is very slightly faster
$first = $normal = $last = array();
// Prepare the list of panes to be rendered
foreach ($panes as $pid => $pane) {
if (empty($this->admin)) {
// TODO remove in 7.x and ensure the upgrade path weeds out any stragglers; it's been long enough
$pane->shown = !empty($pane->shown); // guarantee this field exists.
// If this pane is not visible to the user, skip out and do the next one
if (!$pane->shown || !panels_pane_access($pane, $this->display)) {
continue;
}
}
// If the pane's subtype is unique, get it so that
// hook_ctools_content_subtype_alter() and/or
// hook_ctools_block_info() will be called.
if ($pane->type != $pane->subtype) {
$content_type = ctools_content_get_subtype($pane->type, $pane->subtype);
}
else {
$content_type = ctools_get_content_type($pane->type);
}
// If this pane wants to render last, add it to the $last array. We allow
// this because some panes need to be rendered after other panes,
// primarily so they can do things like the leftovers of forms.
if (!empty($content_type['render last'])) {
$last[$pid] = $pane;
}
// If it wants to render first, add it to the $first array. This is used
// by panes that need to do some processing before other panes are
// rendered.
else if (!empty($content_type['render first'])) {
$first[$pid] = $pane;
}
// Otherwise, render it in the normal order.
else {
$normal[$pid] = $pane;
}
}
$this->prepared['panes'] = $first + $normal + $last;
// Allow other modules the alter the prepared panes array.
drupal_alter('panels_panes_prepared', $this->prepared['panes'], $this);
return $this->prepared['panes'];
}
/**
* Prepare the list of regions to be rendered.
*
* This method is primarily about properly initializing the style plugin that
* will be used to render the region. This is crucial as regions cannot be
* rendered without a style plugin (in keeping with Panels' philosophy of
* hardcoding none of its output), but for most regions no style has been
* explicitly set. The logic here is what accommodates that situation:
* - If a region has had its style explicitly set, then we fetch that plugin
* and continue.
* - If the region has no explicit style, but a style was set at the display
* level, then inherit the style from the display.
* - If neither the region nor the dispay have explicitly set styles, then
* fall back to the hardcoded 'default' style, a very minimal style.
*
* The other important task accomplished by this method is ensuring that even
* regions without any panes are still properly prepared for the rendering
* process. This is essential because the way Panels loads display objects
* (@see panels_load_displays) results only in a list of regions that
* contain panes - not necessarily all the regions defined by the layout
* plugin, which can only be determined by asking the plugin at runtime. This
* method consults that retrieved list of regions and prepares all of those,
* ensuring none are inadvertently skipped.
*
* @param array $region_pane_list
* An associative array of pane ids, keyed on the region to which those pids
* are assigned. In the default case, this is $display->panels.
* @param array $settings
* All known region style settings, including both the top-level display's
* settings (if any) and all region-specific settings (if any).
* @return array
* An array of regions prepared for rendering.
*/
function prepare_regions($region_pane_list, $settings) {
// Initialize defaults to be used for regions without their own explicit
// settings. Use display settings if they exist, else hardcoded defaults.
$default = array(
'style' => panels_get_style(!empty($settings['style']) ? $settings['style'] : 'default'),
'style settings' => isset($settings['style_settings']['default']) ? $settings['style_settings']['default'] : array(),
);
$regions = array();
if (empty($settings)) {
// No display/panel region settings exist, init all with the defaults.
foreach ($this->plugins['layout']['regions'] as $region_id => $title) {
// Ensure this region has at least an empty panes array.
$panes = !empty($region_pane_list[$region_id]) ? $region_pane_list[$region_id] : array();
$regions[$region_id] = $default;
$regions[$region_id]['pids'] = $panes;
}
}
else {
// Some settings exist; iterate through each region and set individually.
foreach ($this->plugins['layout']['regions'] as $region_id => $title) {
// Ensure this region has at least an empty panes array.
$panes = !empty($region_pane_list[$region_id]) ? $region_pane_list[$region_id] : array();
if (empty($settings[$region_id]['style']) || $settings[$region_id]['style'] == -1) {
$regions[$region_id] = $default;
}
else {
$regions[$region_id]['style'] = panels_get_style($settings[$region_id]['style']);
$regions[$region_id]['style settings'] = isset($settings['style_settings'][$region_id]) ? $settings['style_settings'][$region_id] : array();
}
$regions[$region_id]['pids'] = $panes;
}
}
$this->prepared['regions'] = $regions;
return $this->prepared['regions'];
}
/**
* Build inner content, then hand off to layout-specified theme function for
* final render step.
*
* This is the outermost method in the Panels render pipeline. It calls the
* inner methods, which return a content array, which is in turn passed to the
* theme function specified in the layout plugin.
*
* @return string
* Themed & rendered HTML output.
*/
function render() {
// Let the display refer back to the renderer.
$this->display->renderer_handler = $this;
// Attach out-of-band data first.
$this->add_meta();
if (empty($this->display->cache['method']) || !empty($this->display->skip_cache)) {
return $this->render_layout();
}
else {
$cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context);
if ($cache === FALSE) {
$cache = new panels_cache_object();
$cache->set_content($this->render_layout());
panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context);
}
return $cache->content;
}
}
/**
* Perform display/layout-level render operations.
*
* This method triggers all the inner pane/region rendering processes, passes
* that to the layout plugin's theme callback, and returns the rendered HTML.
*
* If display-level caching is enabled and that cache is warm, this method
* will not be called.
*
* @return string
* The HTML string representing the entire rendered, themed panel.
*/
function render_layout() {
if (empty($this->prep_run)) {
$this->prepare();
}
$this->render_panes();
$this->render_regions();
if ($this->admin && !empty($this->plugins['layout']['admin theme'])) {
$theme = $this->plugins['layout']['admin theme'];
}
else {
$theme = $this->plugins['layout']['theme'];
}
$this->rendered['layout'] = theme($theme, array('css_id' => check_plain($this->display->css_id), 'content' => $this->rendered['regions'], 'settings' => $this->display->layout_settings, 'display' => $this->display, 'layout' => $this->plugins['layout'], 'renderer' => $this));
return $this->prefix . $this->rendered['layout'] . $this->suffix;
}
/**
* Attach out-of-band page metadata (e.g., CSS and JS).
*
* This must be done before render, because panels-within-panels must have
* their CSS added in the right order: inner content before outer content.
*/
function add_meta() {
if (!empty($this->plugins['layout']['css'])) {
if (file_exists(path_to_theme() . '/' . $this->plugins['layout']['css'])) {
$this->add_css(path_to_theme() . '/' . $this->plugins['layout']['css']);
}
else {
$this->add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['css']);
}
}
if ($this->admin && isset($this->plugins['layout']['admin css'])) {
$this->add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['admin css']);
}
}
/**
* Add CSS information to the renderer.
*
* To facilitate previews over Views, CSS can now be added in a manner
* that does not necessarily mean just using drupal_add_css. Therefore,
* during the panel rendering process, this method can be used to add
* css and make certain that ti gets to the proper location.
*
* The arguments should exactly match drupal_add_css().
*
* @see drupal_add_css
*/
function add_css($filename) {
switch ($this->meta_location) {
case 'standard':
drupal_add_css($filename);
break;
case 'inline':
$url = base_path() . $filename;
$this->prefix .= '<link type="text/css" rel="stylesheet" href="' . file_create_url($url) . '" />'."\n";
break;
}
}
/**
* Render all prepared panes, first by dispatching to their plugin's render
* callback, then handing that output off to the pane's style plugin.
*
* @return array
* The array of rendered panes, keyed on pane pid.
*/
function render_panes() {
ctools_include('content');
// First, render all the panes into little boxes.
$this->rendered['panes'] = array();
foreach ($this->prepared['panes'] as $pid => $pane) {
$content = $this->render_pane($pane);
if ($content) {
$this->rendered['panes'][$pid] = $content;
}
}
return $this->rendered['panes'];
}
/**
* Render a pane using its designated style.
*
* This method also manages 'title pane' functionality, where the title from
* an individual pane can be bubbled up to take over the title for the entire
* display.
*
* @param stdClass $pane
* A Panels pane object, as loaded from the database.
*/
function render_pane(&$pane) {
$content = $this->render_pane_content($pane);
if ($this->display->hide_title == PANELS_TITLE_PANE && !empty($this->display->title_pane) && $this->display->title_pane == $pane->pid) {
// If the user selected to override the title with nothing, and selected
// this as the title pane, assume the user actually wanted the original
// title to bubble up to the top but not actually be used on the pane.
if (empty($content->title) && !empty($content->original_title)) {
$this->display->stored_pane_title = $content->original_title;
}
else {
$this->display->stored_pane_title = !empty($content->title) ? $content->title : '';
}
}
if (!empty($content->content)) {
if (!empty($pane->style['style'])) {
$style = panels_get_style($pane->style['style']);
if (isset($style) && isset($style['render pane'])) {
$output = theme($style['render pane'], array('content' => $content, 'pane' => $pane, 'display' => $this->display, 'style' => $style, 'settings' => $pane->style['settings']));
// This could be null if no theme function existed.
if (isset($output)) {
return $output;
}
}
}
// fallback
return theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $this->display));
}
}
/**
* Render the interior contents of a single pane.
*
* This method retrieves pane content and produces a ready-to-render content
* object. It also manages pane-specific caching.
*
* @param stdClass $pane
* A Panels pane object, as loaded from the database.
* @return stdClass $content
* A renderable object, containing a subject, content, etc. Based on the
* renderable objects used by the block system.
*/
function render_pane_content(&$pane) {
ctools_include('context');
// TODO finally safe to remove this check?
if (!is_array($this->display->context)) {
watchdog('panels', 'renderer::render_pane_content() hit with a non-array for the context', $this->display, WATCHDOG_DEBUG);
$this->display->context = array();
}
$content = FALSE;
$caching = !empty($pane->cache['method']) && empty($this->display->skip_cache);
if ($caching && ($cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context, $pane))) {
$content = $cache->content;
}
else {
if ($caching) {
// This is created before rendering so that calls to drupal_add_js
// and drupal_add_css will be captured.
$cache = new panels_cache_object();
}
$content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $this->display->args, $this->display->context);
if (empty($content)) {
return;
}
foreach (module_implements('panels_pane_content_alter') as $module) {
$function = $module . '_panels_pane_content_alter';
$function($content, $pane, $this->display->args, $this->display->context, $this, $this->display);
}
if ($caching && isset($cache)) {
$cache->set_content($content);
panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context, $pane);
$content = $cache->content;
}
}
// Pass long the css_id that is usually available.
if (!empty($pane->css['css_id'])) {
$content->css_id = check_plain($pane->css['css_id']);
}
// Pass long the css_class that is usually available.
if (!empty($pane->css['css_class'])) {
$content->css_class = check_plain($pane->css['css_class']);
}
return $content;
}
/**
* Render all prepared regions, placing already-rendered panes into their
* appropriate positions therein.
*
* @return array
* An array of rendered panel regions, keyed on the region name.
*/
function render_regions() {
$this->rendered['regions'] = array();
// Loop through all panel regions, put all panes that belong to the current
// region in an array, then render the region. Primarily this ensures that
// the panes are arranged in the proper order.
$content = array();
foreach ($this->prepared['regions'] as $region_id => $conf) {
$region_panes = array();
foreach ($conf['pids'] as $pid) {
// Only include panes for region rendering if they had some output.
if (!empty($this->rendered['panes'][$pid])) {
$region_panes[$pid] = $this->rendered['panes'][$pid];
}
}
$this->rendered['regions'][$region_id] = $this->render_region($region_id, $region_panes);
}
return $this->rendered['regions'];
}
/**
* Render a single panel region.
*
* Primarily just a passthrough to the panel region rendering callback
* specified by the style plugin that is attached to the current panel region.
*
* @param $region_id
* The ID of the panel region being rendered
* @param $panes
* An array of panes that are assigned to the panel that's being rendered.
*
* @return string
* The rendered, HTML string output of the passed-in panel region.
*/
function render_region($region_id, $panes) {
$style = $this->prepared['regions'][$region_id]['style'];
$style_settings = $this->prepared['regions'][$region_id]['style settings'];
// Retrieve the pid (can be a panel page id, a mini panel id, etc.), this
// might be used (or even necessary) for some panel display styles.
// TODO: Got to fix this to use panel page name instead of pid, since pid is
// no longer guaranteed. This needs an API to be able to set the final id.
$owner_id = 0;
if (isset($this->display->owner) && is_object($this->display->owner) && isset($this->display->owner->id)) {
$owner_id = $this->display->owner->id;
}
$output = theme($style['render region'], array('display' => $this->display, 'owner_id' => $owner_id, 'panes' => $panes, 'settings' => $style_settings, 'region_id' => $region_id, 'style' => $style));
return $output;
}
}

View File

@@ -0,0 +1,8 @@
<?php
/**
* Create a simple renderer plugin that renders a layout but the content is
* already rendered, not in panes.
*/
$plugin = array(
'renderer' => 'panels_renderer_simple',
);

View File

@@ -0,0 +1,5 @@
<?php
$plugin = array(
'renderer' => 'panels_renderer_standard',
);

View File

@@ -0,0 +1,23 @@
<?php
$plugin = array(
'schema' => 'panels_layout',
'access' => 'administer panels layouts',
'menu' => array(
'menu prefix' => 'admin/structure/panels',
'menu item' => 'layouts',
'menu title' => 'Layouts',
'menu description' => 'Add, edit or delete custom content layouts.',
),
'title singular' => t('layout'),
'title singular proper' => t('Layout'),
'title plural' => t('layouts'),
'title plural proper' => t('Layouts'),
'handler' => array(
'class' => 'panels_layouts_ui',
),
);

View File

@@ -0,0 +1,245 @@
<?php
/**
* @file
* Contains the administrative UI for reusable layouts.
*/
class panels_layouts_ui extends ctools_export_ui {
var $lipsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam egestas congue nibh, vel dictum ante posuere vitae. Cras gravida massa tempor metus eleifend sed elementum tortor scelerisque. Vivamus egestas, tortor quis luctus tristique, sem velit adipiscing risus, et tempus enim felis in massa. Morbi viverra, nisl quis rhoncus imperdiet, turpis massa vestibulum turpis, egestas faucibus nibh metus vel nunc. In hac habitasse platea dictumst. Nunc sit amet nisi quis ipsum tincidunt semper. Donec ac urna enim, et placerat arcu. Morbi eu laoreet justo. Nullam nec velit eu neque mattis pulvinar sed non libero. Sed sed vulputate erat. Fusce sit amet dui nibh.";
function hook_menu(&$items) {
// During updates, this can run before our schema is set up, so our
// plugin can be empty.
if (empty($this->plugin['menu']['items']['add'])) {
return;
}
// Change the item to a tab on the Panels page.
$this->plugin['menu']['items']['list callback']['type'] = MENU_LOCAL_TASK;
// Establish a base for adding plugins
$base = $this->plugin['menu']['items']['add'];
// Remove the default 'add' menu item.
unset($this->plugin['menu']['items']['add']);
ctools_include('plugins', 'panels');
$this->builders = panels_get_layout_builders();
asort($this->builders);
foreach ($this->builders as $name => $builder) {
// Create a new menu item for the builder
$item = $base;
$item['title'] = !empty($builder['builder tab title']) ? $builder['builder tab title'] : 'Add ' . $builder['title'];
$item['page arguments'][] = $name;
$item['path'] = 'add-' . $name;
$this->plugin['menu']['items']['add ' . $name] = $item;
}
parent::hook_menu($items);
}
function edit_form(&$form, &$form_state) {
ctools_include('plugins', 'panels');
// If the plugin is not set, then it should be provided as an argument:
if (!isset($form_state['item']->plugin)) {
$form_state['item']->plugin = $form_state['function args'][2];
}
parent::edit_form($form, $form_state);
$form['category'] = array(
'#type' => 'textfield',
'#title' => t('Category'),
'#description' => t('What category this layout should appear in. If left blank the category will be "Miscellaneous".'),
'#default_value' => $form_state['item']->category,
);
ctools_include('context');
ctools_include('display-edit', 'panels');
ctools_include('content');
// Provide actual layout admin UI here.
// Create a display for editing:
$cache_key = 'builder-' . $form_state['item']->name;
// Load the display being edited from cache, if possible.
if (!empty($_POST) && is_object($cache = panels_edit_cache_get($cache_key))) {
$display = &$cache->display;
}
else {
$content_types = ctools_content_get_available_types();
panels_cache_clear('display', $cache_key);
$cache = new stdClass();
$display = panels_new_display();
$display->did = $form_state['item']->name;
$display->layout = $form_state['item']->plugin;
$display->layout_settings = $form_state['item']->settings;
$display->cache_key = $cache_key;
$display->editing_layout = TRUE;
$cache->display = $display;
$cache->content_types = $content_types;
$cache->display_title = FALSE;
panels_edit_cache_set($cache);
}
// Set up lipsum content in all of the existing panel regions:
$display->content = array();
$display->panels = array();
$custom = ctools_get_content_type('custom');
$layout = panels_get_layout($display->layout);
$regions = panels_get_regions($layout, $display);
foreach ($regions as $id => $title) {
$pane = panels_new_pane('custom', 'custom');
$pane->pid = $id;
$pane->panel = $id;
$pane->configuration = ctools_content_get_defaults($custom, 'custom');
$pane->configuration['title'] = 'Lorem Ipsum';
$pane->configuration['body'] = $this->lipsum;
$display->content[$id] = $pane;
$display->panels[$id] = array($id);
}
$form_state['display'] = &$display;
// Tell the Panels form not to display buttons.
$form_state['no buttons'] = TRUE;
$form_state['no display settings'] = TRUE;
$form_state['cache_key'] = $cache_key;
$form_state['content_types'] = $cache->content_types;
$form_state['display_title'] = FALSE;
$form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display);
$form_state['renderer']->cache = &$cache;
$form = panels_edit_display_form($form, $form_state);
// If we leave the standard submit handler, it'll try to reconcile
// content from the input, but we've not exposed that to the user. This
// makes previews work with the content we forced in.
$form['preview']['button']['#submit'] = array('panels_edit_display_form_preview');
}
function edit_form_submit(&$form, &$form_state) {
parent::edit_form_submit($form, $form_state);
// While we short circuited the main submit hook, we need to keep this one.
panels_edit_display_settings_form_submit($form, $form_state);
$form_state['item']->settings = $form_state['display']->layout_settings;
}
function edit_form_validate(&$form, &$form_state) {
parent::edit_form_validate($form, $form_state);
// While we short circuited the main validate hook, we need to keep this one.
panels_edit_display_settings_form_validate($form, $form_state);
}
function list_form(&$form, &$form_state) {
ctools_include('plugins', 'panels');
$this->builders = panels_get_layout_builders();
parent::list_form($form, $form_state);
$categories = $plugins = array('all' => t('- All -'));
foreach ($this->items as $item) {
$categories[$item->category] = $item->category ? $item->category : t('Miscellaneous');
}
$form['top row']['category'] = array(
'#type' => 'select',
'#title' => t('Category'),
'#options' => $categories,
'#default_value' => 'all',
'#weight' => -10,
);
foreach ($this->builders as $name => $plugin) {
$plugins[$name] = $plugin['title'];
}
$form['top row']['plugin'] = array(
'#type' => 'select',
'#title' => t('Type'),
'#options' => $plugins,
'#default_value' => 'all',
'#weight' => -9,
);
}
function list_filter($form_state, $item) {
if ($form_state['values']['category'] != 'all' && $form_state['values']['category'] != $item->category) {
return TRUE;
}
if ($form_state['values']['plugin'] != 'all' && $form_state['values']['plugin'] != $item->plugin) {
return TRUE;
}
return parent::list_filter($form_state, $item);
}
function list_sort_options() {
return array(
'disabled' => t('Enabled, title'),
'title' => t('Title'),
'name' => t('Name'),
'category' => t('Category'),
'storage' => t('Storage'),
'plugin' => t('Type'),
);
}
function list_build_row($item, &$form_state, $operations) {
// Set up sorting
switch ($form_state['values']['order']) {
case 'disabled':
$this->sorts[$item->name] = empty($item->disabled) . $item->admin_title;
break;
case 'title':
$this->sorts[$item->name] = $item->admin_title;
break;
case 'name':
$this->sorts[$item->name] = $item->name;
break;
case 'category':
$this->sorts[$item->name] = ($item->category ? $item->category : t('Miscellaneous')) . $item->admin_title;
break;
case 'plugin':
$this->sorts[$item->name] = $item->plugin;
break;
case 'storage':
$this->sorts[$item->name] = $item->type . $item->admin_title;
break;
}
$type = !empty($this->builders[$item->plugin]) ? $this->builders[$item->plugin]['title'] : t('Broken/missing plugin');
$category = $item->category ? check_plain($item->category) : t('Miscellaneous');
$ops = theme('links__ctools_dropbutton', array('links' => $operations, 'attributes' => array('class' => array('links', 'inline'))));
$this->rows[$item->name] = array(
'data' => array(
array('data' => check_plain($type), 'class' => array('ctools-export-ui-type')),
array('data' => check_plain($item->name), 'class' => array('ctools-export-ui-name')),
array('data' => check_plain($item->admin_title), 'class' => array('ctools-export-ui-title')),
array('data' => $category, 'class' => array('ctools-export-ui-category')),
array('data' => $ops, 'class' => array('ctools-export-ui-operations')),
),
'title' => check_plain($item->admin_description),
'class' => array(!empty($item->disabled) ? 'ctools-export-ui-disabled' : 'ctools-export-ui-enabled'),
);
}
function list_table_header() {
return array(
array('data' => t('Type'), 'class' => array('ctools-export-ui-type')),
array('data' => t('Name'), 'class' => array('ctools-export-ui-name')),
array('data' => t('Title'), 'class' => array('ctools-export-ui-title')),
array('data' => t('Category'), 'class' => array('ctools-export-ui-category')),
array('data' => t('Operations'), 'class' => array('ctools-export-ui-operations')),
);
}
}

View File

@@ -0,0 +1,87 @@
#panels-dnd-main .panel-flexible-edit-layout div.panels-display .pane-add-link,
.panel-flexible-edit-layout .panel-pane {
display: none;
}
.panel-flexible-edit-layout div.panels-display h2.label {
padding-right: 0;
}
.panel-flexible-edit-layout .panels-flexible-column-inside {
/* margin: 5px; */
border: 1px dotted green;
}
.panels-flexible-column-inside {
/* overflow: hidden; */
}
.panel-flexible-edit-layout .panels-flexible-column > .flexible-title {
color: green;
}
.panel-flexible-edit-layout .panels-flexible-row-inside {
margin: 5px;
border: 1px dotted blue;
}
.panel-flexible-edit-layout .panels-flexible-row > .flexible-title {
color: blue;
}
.panel-flexible-no-edit-layout .flexible-layout-only {
display: none;
}
.panel-flexible-edit-layout .flexible-title {
text-align: center;
width: 5em;
margin-left: auto;
margin-right: auto;
}
.panel-flexible-no-edit-layout .panels-flexible-splitter {
display: none;
}
.panels-flexible-splitter span {
display: none;
}
.panels-flexible-splitter {
width: 11px;
float: left;
margin-left: -7px;
margin-right: -6px;
cursor: e-resize; /* in case col-resize isn't supported */
cursor: col-resize;
height: 30px;
position: relative;
z-index: 1;
background: url(grippie-vertical.png) center center no-repeat #eee;
border: 1px solid #ccc;
}
.flexible-splitting {
border: 2px dotted yellow !important;
margin: -2px !important;
}
.flexible-splitter-hover-box {
position: absolute;
z-index: 1000;
background: white;
color: black;
border: 1px solid black;
width: 60px;
height: 2em;
text-align: center;
line-height: 2em;
}
#panels-edit-display .panel-pane,
#panels-edit-display .helperclass {
margin: .5em;
}

View File

@@ -0,0 +1,424 @@
(function ($) {
Drupal.flexible = Drupal.flexible || {};
Drupal.flexible.splitters = [];
/**
* Fix the height of all splitters to be the same as the items they are
* splitting.
*/
Drupal.flexible.fixHeight = function() {
for (i in Drupal.flexible.splitters) {
Drupal.flexible.splitters[i].fixHeight();
}
}
Drupal.behaviors.flexibleAdmin = {
attach: function(context) {
// Show/hide layout manager button
$('input#panels-flexible-toggle-layout:not(.panels-flexible-processed)', context)
.addClass('panels-flexible-processed')
.click(function() {
$('.panel-flexible-admin')
.toggleClass('panel-flexible-no-edit-layout')
.toggleClass('panel-flexible-edit-layout');
if ($('.panel-flexible-admin').hasClass('panel-flexible-edit-layout')) {
$(this).val(Drupal.t('Hide layout designer'));
Drupal.flexible.fixHeight();
}
else {
$(this).val(Drupal.t('Show layout designer'));
}
return false;
});
// Window splitter behavior.
$('div.panels-flexible-splitter:not(.panels-splitter-processed)')
.addClass('panels-splitter-processed')
.each(function() {
Drupal.flexible.splitters.push(new Drupal.flexible.splitter($(this)));
});
Drupal.flexible.fixHeight();
}
};
Drupal.flexible.splitter = function($splitter) {
var splitter = this;
this.fixHeight = function() {
// Set the splitter height to the shorter of the two:
$splitter.height(Math.max(this.left.outerHeight(), this.right.outerHeight()));
}
function splitterStart(event) {
// Bind motion events.
$(document)
.bind("mousemove", splitterMove)
.bind("mouseup", splitterEnd);
// Calculate some data about our split regions:
splitter.getSizes();
// The X coordinate where we clicked.
splitter.startX = event.pageX;
// The current sizes of the left/right panes.
splitter.currentLeft = parseFloat(splitter.left_width) * parseFloat(splitter.left_scale);
splitter.currentRight = parseFloat(splitter.right_width) * parseFloat(splitter.right_scale);
// The starting sizes of the left right panes.
splitter.startLeft = splitter.currentLeft;
splitter.startRight = splitter.currentRight;
if (splitter.left_width_type == splitter.right_width_type) {
// If they're the same type, add the two together so we know how
// much space we have for splitting.
splitter.max = splitter.startLeft + splitter.startRight;
// calculate unit size and min/max width.
if (splitter.left_width_type == '%') {
splitter.left_total = splitter.left.width() / (splitter.left_width / 100);
// One pixel is equivalent to what percentage of the total?
splitter.left_unit = (1 / splitter.left_total) * 100;
splitter.left_min = 5; // minimum % we'll use.
}
else {
splitter.left_unit = 1;
splitter.left_min = 25; // minimum pixels we'll use.
}
if (splitter.right_width_type == '%') {
splitter.right_total = splitter.right.width() / (splitter.right_width / 100);
// One pixel is equivalent to what percentage of the total?
splitter.right_unit = (1 / splitter.right_total) * 100;
splitter.right_min = 5; // minimum % we'll use.
}
else {
splitter.right_unit = 1;
splitter.right_min = 25; // minimum pixels we'll use.
}
}
else {
// Figure out the parent blob's width and set the max to that
splitter.parent = $splitter.parent().parent();
if (splitter.left_width_type != 'px') {
// Only the 'px' side can resize.
splitter.left_unit = 0;
splitter.right_unit = 1;
splitter.right_min = 25;
splitter.right_padding = parseInt(splitter.parent.css('padding-right'));
splitter.right_parent = parseInt(splitter.right.parent().css('margin-right'));
splitter.max = splitter.right.width() + splitter.left.parent().width() -
(splitter.left.siblings(':not(.panels-flexible-splitter)').length * 25) - 25;
}
else {
splitter.right_unit = 0;
splitter.left_unit = 1;
splitter.left_min = 25;
splitter.left_padding = parseInt(splitter.parent.css('padding-left'));
splitter.left_parent = parseInt(splitter.left.parent().css('margin-left'));
if (splitter.right_id) {
splitter.max = splitter.left.width() + splitter.right.parent().width() -
(splitter.right.siblings(':not(.panels-flexible-splitter)').length * 25) - 25;
}
else {
var subtract = 0;
splitter.left.siblings(':not(.panels-flexible-splitter)').each(function() { subtract += $(this).width()});
splitter.max = splitter.left.parent().width() - subtract;
}
}
}
var offset = $(splitter.splitter).offset();
// Create boxes to display widths left and right of the mouse pointer.
// Create left box only if left box is mobile.
if (splitter.left_unit) {
splitter.left_box = $('<div class="flexible-splitter-hover-box">&nbsp;</div>');
$('body').append(splitter.left_box);
splitter.left_box.css('top', offset.top);
splitter.left_box.css('left', event.pageX - 65);
if (splitter.left_width_type == '%') {
var left = splitter.currentLeft / splitter.left_scale;
splitter.left_box.html(left.toFixed(2) + splitter.left_width_type);
}
else {
// make sure pixel values are always whole integers.
splitter.currentLeft = parseInt(splitter.currentLeft);
splitter.left_box.html(splitter.currentLeft + splitter.left_width_type);
}
}
// Create the right box if the right side is mobile.
if (splitter.right_unit) {
splitter.right_box = $('<div class="flexible-splitter-hover-box"></div>');
$('body').append(splitter.right_box);
splitter.right_box.css('top', offset.top);
splitter.right_box.css('left', event.pageX + 5);
if (splitter.right_width_type == '%') {
var right = splitter.currentRight / splitter.right_scale;
splitter.right_box.html(right.toFixed(2) + splitter.right_width_type);
}
else {
// make sure pixel values are always whole integers.
splitter.currentRight = parseInt(splitter.currentRight);
splitter.right_box.html(splitter.currentRight + splitter.right_width_type);
}
}
return false;
};
function splitterMove(event) {
var diff = splitter.startX - event.pageX;
var moved = 0;
if (event.keyCode == 37) diff = 10;
if (event.keyCode == 39) diff = -10;
// Bah, javascript has no logical xor operator
if ((splitter.left_unit && !splitter.right_unit) ||
(!splitter.left_unit && splitter.right_unit)) {
// This happens when one side is fixed and the other side is fluid. The
// fixed side actually adjusts while the fluid side does not. However,
// in order to move the fluid side we have to adjust the padding
// on our parent object.
if (splitter.left_unit) {
// Only the left box is allowed to move.
splitter.currentLeft = splitter.startLeft - diff;
if (splitter.currentLeft < splitter.left_min) {
splitter.currentLeft = splitter.left_min;
}
if (splitter.currentLeft > splitter.max) {
splitter.currentLeft = splitter.max;
}
// If the shift key is pressed, go with 1% or 10px boundaries.
if (event.shiftKey) {
splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10;
}
moved = (splitter.startLeft - splitter.currentLeft);
}
else {
// Only the left box is allowed to move.
splitter.currentRight = splitter.startRight + diff;
if (splitter.currentRight < splitter.right_min) {
splitter.currentRight = splitter.right_min;
}
if (splitter.currentRight > splitter.max) {
splitter.currentRight = splitter.max;
}
// If the shift key is pressed, go with 1% or 10px boundaries.
if (event.shiftKey) {
splitter.currentRight = parseInt(splitter.currentRight / 10) * 10;
}
moved = (splitter.currentRight - splitter.startRight);
}
}
else {
// If they are both the same type, do this..
// Adjust the left side by the amount we moved.
var left = -1 * diff * splitter.left_unit;
splitter.currentLeft = splitter.startLeft + left;
if (splitter.currentLeft < splitter.left_min) {
splitter.currentLeft = splitter.left_min;
}
if (splitter.currentLeft > splitter.max - splitter.right_min) {
splitter.currentLeft = splitter.max - splitter.right_min;
}
// If the shift key is pressed, go with 1% or 10px boundaries.
if (event.shiftKey) {
if (splitter.left_width_type == '%') {
splitter.currentLeft = parseInt(splitter.currentLeft / splitter.left_scale) * splitter.left_scale;
}
else {
splitter.currentLeft = parseInt(splitter.currentLeft / 10) * 10;
}
}
// Now automatically make the right side to be the other half.
splitter.currentRight = splitter.max - splitter.currentLeft;
// recalculate how far we've moved into pixels so we can adjust our visible
// boxes.
moved = (splitter.startLeft - splitter.currentLeft) / splitter.left_unit;
}
if (splitter.left_unit) {
splitter.left_box.css('left', splitter.startX - 65 - moved);
if (splitter.left_width_type == '%') {
var left = splitter.currentLeft / splitter.left_scale;
splitter.left_box.html(left.toFixed(2) + splitter.left_width_type);
}
else {
splitter.left_box.html(parseInt(splitter.currentLeft) + splitter.left_width_type);
}
// Finally actually move the left side
splitter.left.css('width', splitter.currentLeft + splitter.left_width_type);
}
else {
// if not moving the left side, adjust the parent padding instead.
splitter.parent.css('padding-right', (splitter.right_padding + moved) + 'px');
splitter.right.parent().css('margin-right', (splitter.right_parent - moved) + 'px');
}
if (splitter.right_unit) {
splitter.right_box.css('left', splitter.startX + 5 - moved);
if (splitter.right_width_type == '%') {
var right = splitter.currentRight / splitter.right_scale;
splitter.right_box.html(right.toFixed(2) + splitter.right_width_type);
}
else {
splitter.right_box.html(parseInt(splitter.currentRight) + splitter.right_width_type);
}
// Finally actually move the right side
splitter.right.css('width', splitter.currentRight + splitter.right_width_type);
}
else {
// if not moving the right side, adjust the parent padding instead.
splitter.parent.css('padding-left', (splitter.left_padding - moved) + 'px');
splitter.left.parent().css('margin-left', (splitter.left_parent + moved) + 'px');
if (jQuery.browser.msie) {
splitter.left.parent().css('left', splitter.currentLeft);
}
}
return false;
};
function splitterKeyPress(event) {
splitterStart(event);
splitterMove(event);
splitterEnd(event);
};
function splitterEnd(event) {
if (splitter.left_unit) {
splitter.left_box.remove();
}
if (splitter.right_unit) {
splitter.right_box.remove();
}
splitter.left.css("-webkit-user-select", "text"); // let Safari select text again
splitter.right.css("-webkit-user-select", "text"); // let Safari select text again
if (splitter.left_unit) {
splitter.left_width = splitter.currentLeft / parseFloat(splitter.left_scale);
}
if (splitter.right_unit) {
splitter.right_width = splitter.currentRight / parseFloat(splitter.right_scale);
}
splitter.putSizes();
Drupal.flexible.fixHeight();
$(document)
.unbind("mousemove", splitterMove)
.unbind("mouseup", splitterEnd);
// Store the data on the server.
Drupal.ajax['flexible-splitter-ajax'].options.data = {
'left': splitter.left_id,
'left_width': splitter.left_width,
'right': splitter.right_id,
'right_width': splitter.right_width
};
$('.panel-flexible-edit-layout').trigger('UpdateFlexibleSplitter');
};
this.getSizes = function() {
splitter.left_width = $splitter.children('.panels-flexible-splitter-left-width').html();
splitter.left_scale = $splitter.children('.panels-flexible-splitter-left-scale').html();
splitter.left_width_type = $splitter.children('.panels-flexible-splitter-left-width-type').html();
splitter.right_width = $splitter.children('.panels-flexible-splitter-right-width').html();
splitter.right_scale = $splitter.children('.panels-flexible-splitter-right-scale').html();
splitter.right_width_type = $splitter.children('.panels-flexible-splitter-right-width-type').html();
};
this.putSizes = function() {
$(splitter.left_class + '-width').html(splitter.left_width);
if (splitter.left_class != splitter.right_class) {
$(splitter.right_class + '-width').html(splitter.right_width);
}
}
splitter.splitter = $splitter;
splitter.left_class = $splitter.children('.panels-flexible-splitter-left').html();
splitter.left_id = $splitter.children('.panels-flexible-splitter-left-id').html();
splitter.left = $(splitter.left_class);
splitter.right_class = $splitter.children('.panels-flexible-splitter-right').html();
splitter.right_id = $splitter.children('.panels-flexible-splitter-right-id').html();
splitter.right = $(splitter.right_class);
$splitter
.bind("mousedown", splitterStart)
.bind("keydown", splitterKeyPress);
};
$(function() {
/**
* Provide an AJAX response command to allow the server to request
* height fixing.
*/
Drupal.ajax.prototype.commands.flexible_fix_height = function(ajax, command, status) {
Drupal.flexible.fixHeight();
};
/**
* Provide an AJAX response command to allow the server to change width on existing splitters.
*/
Drupal.ajax.prototype.commands.flexible_set_width = function(ajax, command, status) {
$(command.selector).html(command.width);
};
/**
* Provide an AJAX response command to fix the first/last bits of a
* group.
*/
Drupal.ajax.prototype.commands.flexible_fix_firstlast = function(ajax, data, status) {
$(data.selector + ' > div > .' + data.base)
.removeClass(data.base + '-first')
.removeClass(data.base + '-last');
$(data.selector + ' > div > .' + data.base + ':first')
.addClass(data.base + '-first');
$(data.selector + ' > div > .' + data.base + ':last')
.addClass(data.base + '-last');
};
// Create a generic ajax callback for use with the splitters which
// background AJAX to store their data.
var element_settings = {
url: Drupal.settings.flexible.resize,
event: 'UpdateFlexibleSplitter',
keypress: false,
// No throbber at all.
progress: { 'type': 'none' }
};
Drupal.ajax['flexible-splitter-ajax'] = new Drupal.ajax('flexible-splitter-ajax', $('.panel-flexible-admin').get(0), element_settings);
// Prevent ajax goo from doing odd things to our layout.
Drupal.ajax['flexible-splitter-ajax'].beforeSend = function() { };
Drupal.ajax['flexible-splitter-ajax'].beforeSerialize = function() { };
});
})(jQuery);

View File

@@ -0,0 +1,4 @@
.panel-flexible .panel-separator {
margin: 0 0 1em 0;
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

View File

@@ -0,0 +1,22 @@
.panel-1col {
/* overflow: hidden; */
}
.panel-2col .panel-col-first .inside {
margin: 0;
}
.panel-1col .panel-col {
width: 100%;
}
#panels-edit-display .panel-pane,
#panels-edit-display .helperclass {
margin: .5em;
}
.panel-2col .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,14 @@
<?php
/**
* implementation of hook_panels_layouts()
*/
// Plugin definition
$plugin = array(
'title' => t('Single column'),
'category' => t('Columns: 1'),
'icon' => 'onecol.png',
'theme' => 'panels_onecol',
'css' => 'onecol.css',
'regions' => array('middle' => t('Middle column')),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 B

View File

@@ -0,0 +1,19 @@
<?php
/**
* @file
* Template for a 3 column panel layout.
*
* This template provides a very simple "one column" panel display layout.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* $content['middle']: The only panel in the layout.
*/
?>
<div class="panel-display panel-1col clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<div class="panel-panel panel-col">
<div><?php print $content['middle']; ?></div>
</div>
</div>

View File

@@ -0,0 +1,29 @@
<?php
/**
* @file
* Template for the 1 column panel layout.
*
* This template provides a three column 25%-50%-25% panel display layout.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['left']: Content in the left column.
* - $content['middle']: Content in the middle column.
* - $content['right']: Content in the right column.
*/
?>
<div class="panel-display panel-3col clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-panel panel-col">
<div class="inside"><?php print $content['middle']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
.panel-3col {
/* overflow: hidden; */
}
.panel-3col .panel-col-first {
float: left;
width: 25%;
}
.panel-3col .panel-col-first .inside {
margin: 0 .5em 1em 0;
}
.panel-3col .panel-col {
float: left;
width: 50%;
}
.panel-3col .panel-col .inside {
margin: 0 .5em 1em .5em;
}
.panel-3col .panel-col-last {
float: left;
width: 25%;
}
.panel-3col .panel-col-last .inside {
margin: 0 0 1em .5em;
}
.panel-3col .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,20 @@
<?php
/**
* implementation of hook_panels_layouts
*/
// Plugin definition
$plugin = array(
'title' => t('Three column 25/50/25'),
'category' => t('Columns: 3'),
'icon' => 'threecol_25_50_25.png',
'theme' => 'panels_threecol_25_50_25',
'theme arguments' => array('id', 'content'),
'css' => 'threecol_25_50_25.css',
'regions' => array(
'left' => t('Left side'),
'middle' => t('Middle column'),
'right' => t('Right side')
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 B

View File

@@ -0,0 +1,46 @@
<?php
/**
* @file
* Template for a 3 column panel layout.
*
* This template provides a three column 25%-50%-25% panel display layout, with
* additional areas for the top and the bottom.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['top']: Content in the top row.
* - $content['left']: Content in the left column.
* - $content['middle']: Content in the middle column.
* - $content['right']: Content in the right column.
* - $content['bottom']: Content in the bottom row.
*/
?>
<div class="panel-display panel-3col-stacked clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<?php if ($content['top']): ?>
<div class="panel-panel panel-col-top">
<div class="inside"><?php print $content['top']; ?></div>
</div>
<?php endif ?>
<div class="center-wrapper">
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-panel panel-col">
<div class="inside"><?php print $content['middle']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>
<?php if ($content['bottom']): ?>
<div class="panel-panel panel-col-bottom">
<div class="inside"><?php print $content['bottom']; ?></div>
</div>
<?php endif ?>
</div>

View File

@@ -0,0 +1,45 @@
.panel-3col-stacked {
/* overflow: hidden; */
}
.panel-3col-stacked .panel-col-top,
.panel-3col-stacked .panel-col-bottom {
width: 100%;
clear: both;
}
.panel-3col-stacked .panel-col-top .inside {
margin-bottom: .5em;
}
.panel-3col-stacked .panel-col-first {
float: left;
width: 25%;
}
.panel-3col-stacked .panel-col .inside {
margin: 0 .5em 1em .5em;
}
.panel-3col-stacked .panel-col {
float: left;
width: 50%;
}
.panel-3col-stacked .panel-col .inside {
margin: 0 .5em 1em .5em;
}
.panel-3col-stacked .panel-col-last {
float: left;
width: 25%;
}
.panel-3col-stacked .panel-col-last .inside {
margin: 0 0 1em .5em;
}
.panel-3col-stacked .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,17 @@
<?php
// Plugin definition
$plugin = array(
'title' => t('Three column 25/50/25 stacked'),
'category' => t('Columns: 3'),
'icon' => 'threecol_25_50_25_stacked.png',
'theme' => 'panels_threecol_25_50_25_stacked',
'css' => 'threecol_25_50_25_stacked.css',
'regions' => array(
'top' => t('Top'),
'left' => t('Left side'),
'middle' => t('Middle column'),
'right' => t('Right side'),
'bottom' => t('Bottom'),
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,31 @@
<?php
/**
* @file
* Template for a 3 column panel layout.
*
* This template provides a three column panel display layout, with
* each column roughly equal in width.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['left']: Content in the left column.
* - $content['middle']: Content in the middle column.
* - $content['right']: Content in the right column.
*/
?>
<div class="panel-display panel-3col-33 clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-panel panel-col">
<div class="inside"><?php print $content['middle']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>

View File

@@ -0,0 +1,35 @@
.panel-3col-33 {
/* overflow: hidden; */
}
.panel-3col-33 .panel-col-first {
float: left;
width: 33%;
}
.panel-3col-33 .panel-col-first .inside {
margin: 0 .5em 1em 0;
}
.panel-3col-33 .panel-col {
float: left;
width: 33%;
}
.panel-3col-33 .panel-col .inside {
margin: 0 .5em 1em .5em;
}
.panel-3col-33 .panel-col-last {
float: left;
width: 33%;
}
.panel-3col-33 .panel-col-last .inside {
margin: 0 0 1em .5em;
}
.panel-3col-33 .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,15 @@
<?php
// Plugin definition
$plugin = array(
'title' => t('Three column 33/34/33'),
'category' => t('Columns: 3'),
'icon' => 'threecol_33_34_33.png',
'theme' => 'panels_threecol_33_34_33',
'css' => 'threecol_33_34_33.css',
'regions' => array(
'left' => t('Left side'),
'middle' => t('Middle column'),
'right' => t('Right side')
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

View File

@@ -0,0 +1,46 @@
<?php
/**
* @file
* Template for a 3 column panel layout.
*
* This template provides a three column 25%-50%-25% panel display layout, with
* additional areas for the top and the bottom.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['top']: Content in the top row.
* - $content['left']: Content in the left column.
* - $content['middle']: Content in the middle column.
* - $content['right']: Content in the right column.
* - $content['bottom']: Content in the bottom row.
*/
?>
<div class="panel-display panel-3col-33-stacked clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<?php if ($content['top']): ?>
<div class="panel-panel panel-col-top">
<div class="inside"><?php print $content['top']; ?></div>
</div>
<?php endif ?>
<div class="center-wrapper">
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-panel panel-col">
<div class="inside"><?php print $content['middle']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>
<?php if ($content['bottom']): ?>
<div class="panel-panel panel-col-bottom">
<div class="inside"><?php print $content['bottom']; ?></div>
</div>
<?php endif ?>
</div>

View File

@@ -0,0 +1,45 @@
.panel-3col-33-stacked {
/* overflow: hidden; */
}
.panel-3col-33-stacked .panel-col-top,
.panel-3col-33-stacked .panel-col-bottom {
width: 100%;
clear: both;
}
.panel-3col-33-stacked .panel-col-top .inside {
margin-bottom: 1em;
}
.panel-3col-33-stacked .panel-col-first {
float: left;
width: 33%;
}
.panel-3col-33-stacked .panel-col-first .inside {
margin: 0 .5em 1em 0;
}
.panel-3col-33-stacked .panel-col {
float: left;
width: 33%;
}
.panel-3col-33-stacked .panel-col .inside {
margin: 0 .5em 1em .5em;
}
.panel-3col-33-stacked .panel-col-last {
float: left;
width: 33%;
}
.panel-3col-33-stacked .panel-col-last .inside {
margin: 0 0 1em .5em;
}
.panel-3col-33-stacked .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,17 @@
<?php
// Plugin definition
$plugin = array(
'title' => t('Three column 33/34/33 stacked'),
'category' => t('Columns: 3'),
'icon' => 'threecol_33_34_33_stacked.png',
'theme' => 'panels_threecol_33_34_33_stacked',
'css' => 'threecol_33_34_33_stacked.css',
'regions' => array(
'top' => t('Top'),
'left' => t('Left side'),
'middle' => t('Middle column'),
'right' => t('Right side'),
'bottom' => t('Bottom')
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,25 @@
<?php
/**
* @file
* Template for a 2 column panel layout.
*
* This template provides a two column panel display layout, with
* each column roughly equal in width.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['left']: Content in the left column.
* - $content['right']: Content in the right column.
*/
?>
<div class="panel-display panel-2col clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
.panel-2col {
/* overflow: hidden; */
}
.panel-2col .panel-col-first {
float: left;
width: 50%;
}
* html .panel-2col .panel-col-first {
width: 49.9%;
}
.panel-2col .panel-col-first .inside {
margin: 0 .5em 1em 0;
}
.panel-2col .panel-col-last {
float: left;
width: 50%;
}
* html .panel-2col .panel-col-last {
width: 49.9%;
}
.panel-2col .panel-col-last .inside {
margin: 0 0 1em .5em;
}
#panels-edit-display .panel-pane,
#panels-edit-display .helperclass {
margin: .5em;
}
.panel-2col .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,14 @@
<?php
// Plugin definition
$plugin = array(
'title' => t('Two column'),
'category' => t('Columns: 2'),
'icon' => 'twocol.png',
'theme' => 'panels_twocol',
'css' => 'twocol.css',
'regions' => array(
'left' => t('Left side'),
'right' => t('Right side')
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

View File

@@ -0,0 +1,53 @@
<?php
/**
* @file
* Template for a 2 column panel layout.
*
* This template provides a two column panel display layout, with
* each column roughly equal in width. It is 5 rows high; the top
* middle and bottom rows contain 1 column, while the second
* and fourth rows contain 2 columns.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['top']: Content in the top row.
* - $content['left_above']: Content in the left column in row 2.
* - $content['right_above']: Content in the right column in row 2.
* - $content['middle']: Content in the middle row.
* - $content['left_below']: Content in the left column in row 4.
* - $content['right_below']: Content in the right column in row 4.
* - $content['right']: Content in the right column.
* - $content['bottom']: Content in the bottom row.
*/
?>
<div class="panel-display panel-2col-bricks clearfix" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<div class="panel-panel panel-col-top">
<div class="inside"><?php print $content['top']; ?></div>
</div>
<div class="center-wrapper">
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left_above']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right_above']; ?></div>
</div>
</div>
<div class="panel-panel panel-col-middle">
<div class="inside"><?php print $content['middle']; ?></div>
</div>
<div class="center-wrapper">
<div class="panel-panel panel-col-first">
<div class="inside"><?php print $content['left_below']; ?></div>
</div>
<div class="panel-panel panel-col-last">
<div class="inside"><?php print $content['right_below']; ?></div>
</div>
</div>
<div class="panel-panel panel-col-bottom">
<div class="inside"><?php print $content['bottom']; ?></div>
</div>
</div>

View File

@@ -0,0 +1,46 @@
.panel-2col-bricks {
/* overflow: hidden; */
margin-top: 0;
padding-top: 0;
}
.panel-2col-bricks .panel-col-top,
.panel-2col-bricks .panel-col-middle,
.panel-2col-bricks .panel-col-bottom {
width: 99.9%;
clear: both;
}
.panel-2col-bricks .panel-col-top .inside,
.panel-2col-bricks .panel-col-middle .inside {
margin-bottom: .5em;
}
.panel-2col-bricks .panel-col-first {
float: left;
width: 50%;
}
* html .panel-2col-bricks .panel-col-first {
width: 49.9%;
}
.panel-2col-bricks .panel-col-first .inside {
margin: 0 .5em .5em 0;
}
.panel-2col-bricks .panel-col-last {
float: left;
width: 50%;
}
* html .panel-2col-bricks .panel-col-last {
width: 49.9%;
}
.panel-2col-bricks .panel-col-last .inside {
margin: 0 0 .5em .5em;
}
.panel-2col-bricks .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,25 @@
<?php
/**
* @file
* Implementation for the two column bricked layout
*/
// Plugin definition
$plugin = array(
'title' => t('Two column bricks'),
'category' => t('Columns: 2'),
'icon' => 'twocol_bricks.png',
'theme' => 'panels_twocol_bricks',
'css' => 'twocol_bricks.css',
'regions' => array(
'top' => t('Top'),
'left_above' => t('Left above'),
'right_above' => t('Right above'),
'middle' => t('Middle'),
'left_below' => t('Left below'),
'right_below' => t('Right below'),
'bottom' => t('Bottom'),
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 B

View File

@@ -0,0 +1,40 @@
<?php
/**
* @file
* Template for a 2 column panel layout.
*
* This template provides a two column panel display layout, with
* additional areas for the top and the bottom.
*
* Variables:
* - $id: An optional CSS id to use for the layout.
* - $content: An array of content, each item in the array is keyed to one
* panel of the layout. This layout supports the following sections:
* - $content['top']: Content in the top row.
* - $content['left']: Content in the left column.
* - $content['right']: Content in the right column.
* - $content['bottom']: Content in the bottom row.
*/
?>
<div class="panel-2col-stacked clearfix panel-display" <?php if (!empty($css_id)) { print "id=\"$css_id\""; } ?>>
<?php if ($content['top']): ?>
<div class="panel-col-top panel-panel">
<div class="inside"><?php print $content['top']; ?></div>
</div>
<?php endif; ?>
<div class="center-wrapper">
<div class="panel-col-first panel-panel">
<div class="inside"><?php print $content['left']; ?></div>
</div>
<div class="panel-col-last panel-panel">
<div class="inside"><?php print $content['right']; ?></div>
</div>
</div>
<?php if ($content['bottom']): ?>
<div class="panel-col-bottom panel-panel">
<div class="inside"><?php print $content['bottom']; ?></div>
</div>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,41 @@
.panel-2col-stacked {
/* overflow: hidden; */
margin-top: 0;
padding-top: 0;
}
.panel-2col-stacked .panel-col-top,
.panel-2col-stacked .panel-col-bottom {
width: 99.9%;
clear: both;
}
.panel-2col-stacked .panel-col-top .inside {
margin-bottom: .5em;
}
.panel-2col-stacked .panel-col-first {
float: left;
width: 50%;
}
* html .panel-2col-stacked .panel-col-first {
width: 49.9%;
}
.panel-2col-stacked .panel-col-first .inside {
margin: 0 .5em 1em 0;
}
.panel-2col-stacked .panel-col-last {
float: left;
width: 49.9%;
}
.panel-2col-stacked .panel-col-last .inside {
margin: 0 0 1em .5em;
}
.panel-2col-stacked .panel-separator {
margin: 0 0 1em 0;
}

View File

@@ -0,0 +1,16 @@
<?php
// Plugin definition
$plugin = array(
'title' => t('Two column stacked'),
'category' => t('Columns: 2'),
'icon' => 'twocol_stacked.png',
'theme' => 'panels_twocol_stacked',
'css' => 'twocol_stacked.css',
'regions' => array(
'top' => t('Top'),
'left' => t('Left side'),
'right' => t('Right side'),
'bottom' => t('Bottom')
),
);

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,277 @@
<?php
/**
* @file
* A page creation wizard to quickly create simple landing pages.
*
* This wizard strips out a lot of features that are not normally needed for
* simple landing pages, such as access control, tabs, contexts, and the
* selection of a variant. It will just assume you want a panel and let you
* select the layout right away. This is 2 fewer forms than the standard
* add page process and it will point you at the finished page rather than
* sending you directly to the edit UI when finished.
*
* It also will auto-enable IPE if it can.
*/
$plugin = array(
'title' => t('Landing page'),
'page title' => t('Landing page wizard'),
'description' => t('Landing pages are simple pages that have a path, possibly a visible menu entry, and a panel layout with simple content.'),
'type' => 'panels',
'form info' => array(
'order' => array(
'basic' => t('Basic settings'),
'content' => t('Content'),
),
'forms' => array(
'basic' => array(
'form id' => 'panels_landing_page_basic',
),
'content' => array(
'form id' => 'panels_landing_page_content',
),
),
),
'default cache' => 'panels_landing_page_new_page',
'finish' => 'panels_landing_page_finish',
);
/**
* Provide defaults for a new cache.
*
* The cache will store all our temporary data; it isn't really a page
* in itself, but it does contain everything we need to make one at the end.
*/
function panels_landing_page_new_page(&$cache) {
$cache->name = '';
$cache->admin_title = '';
$cache->admin_description = '';
$cache->path = '';
$cache->menu_entry = FALSE;
$cache->menu = array(
'type' => 'none',
'title' => '',
'weight' => 0,
'name' => 'navigation',
'parent' => array(
'type' => 'none',
'title' => '',
'weight' => 0,
'name' => 'navigation',
),
);
$cache->display = panels_new_display();
$cache->display->layout = 'flexible';
}
/**
* First page of our page creator wizard.
*/
function panels_landing_page_basic($form, &$form_state) {
$cache = &$form_state['wizard cache'];
ctools_include('dependent');
$form['admin_title'] = array(
'#type' => 'textfield',
'#title' => t('Administrative title'),
'#description' => t('The name of this page. This will appear in the administrative interface to easily identify it.'),
'#default_value' => $cache->admin_title,
'#required' => TRUE,
);
$form['name'] = array(
'#type' => 'machine_name',
'#title' => t('Machine name'),
'#machine_name' => array(
'exists' => 'page_manager_page_load',
'source' => array('admin_title'),
),
'#description' => t('The machine readable name of this page. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'),
'#default_value' => $cache->name,
);
$form['admin_description'] = array(
'#type' => 'textarea',
'#title' => t('Administrative description'),
'#description' => t('A description of what this page is, does or is for, for administrative use.'),
'#default_value' => $cache->admin_description,
);
// path
$form['path'] = array(
'#type' => 'textfield',
'#title' => t('Path'),
'#default_value' => $cache->path,
'#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q='),
'#required' => TRUE,
);
$form['menu_entry'] = array(
'#type' => 'checkbox',
'#default_value' => $cache->menu_entry,
'#title' => t('Add a visible menu entry for this page'),
);
$form['menu']['#tree'] = TRUE;
$form['menu']['title'] = array(
'#title' => t('Menu title'),
'#type' => 'textfield',
'#default_value' => $cache->menu['title'],
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-menu-entry' => array(1)),
);
// Only display the menu selector if menu module is enabled.
if (module_exists('menu')) {
$form['menu']['name'] = array(
'#title' => t('Menu'),
'#type' => 'select',
'#options' => menu_get_menus(),
'#default_value' => $cache->menu['name'],
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-menu-entry' => array(1)),
);
}
else {
$form['menu']['name'] = array(
'#type' => 'value',
'#value' => $cache->menu['name'],
);
$form['menu']['markup'] = array(
'#value' => t('Menu selection requires the activation of menu module.'),
);
}
$form['menu']['weight'] = array(
'#title' => t('Weight'),
'#type' => 'textfield',
'#default_value' => isset($cache->menu['weight']) ? $cache->menu['weight'] : 0,
'#description' => t('The lower the weight the higher/further left it will appear.'),
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-menu-entry' => array(1)),
);
ctools_include('page-wizard', 'panels');
panels_page_wizard_add_layout($form, $form_state);
// Ensure all 'page' features are loaded.
$page_task = page_manager_get_task('page');
return $form;
}
/**
* Submit function to store the form data in our cache.
*/
function panels_landing_page_basic_validate(&$form, &$form_state) {
// Validate that the name is ok.
$test = page_manager_page_load($form_state['values']['name']);
if ($test) {
form_error($form['name'], t('That name is used by another page: @page', array('@page' => $test->admin_title)));
}
// Ensure name fits the rules:
if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) {
form_error($form['name'], t('Page name must be alphanumeric or underscores only.'));
}
// Validate that the path is ok.
if (preg_match('/[%!\?#&]/', $form_state['values']['path'])) {
form_error($form['path'], t('%, !, ?, #, or & cannot appear in the path.'));
}
// Check to see if something is already using the path
$result = db_query("SELECT * FROM {menu_router} WHERE path = :path", array(':path' => $form_state['values']['path']))->fetch();
if ($result) {
form_error($form['path'], t('That path is already in use. This system cannot override existing paths.'));
return;
}
// Ensure the path is not already an alias to something else.
$alias = db_query('SELECT alias, source FROM {url_alias} WHERE alias = :path', array(':path' => $form_state['values']['path']))->fetchObject();
if ($alias) {
form_error($form['path'], t('That path is currently assigned to be an alias for @alias. This system cannot override existing aliases.', array('@alias' => $alias->src)));
}
}
/**
* Submit function to store the form data in our cache.
*/
function panels_landing_page_basic_submit(&$form, &$form_state) {
$cache = &$form_state['wizard cache'];
$cache->name = $form_state['values']['name'];
$cache->admin_title = $form_state['values']['admin_title'];
$cache->admin_description = $form_state['values']['admin_description'];
$cache->path = $form_state['values']['path'];
$cache->menu_entry = $form_state['values']['menu_entry'];
$cache->menu['title'] = $form_state['values']['menu']['title'];
$cache->menu['weight'] = $form_state['values']['menu']['weight'];
$cache->menu['name'] = $form_state['values']['menu']['name'];
$cache->menu['type'] = $cache->menu_entry ? 'normal' : 'none';
$cache->display->layout = $form_state['values']['layout'];
$cache->display->title = $form_state['values']['admin_title'];
}
/**
* Second page of our wizard. This one provides a layout and lets the
* user add content.
*/
function panels_landing_page_content($form, &$form_state) {
ctools_include('page-wizard', 'panels');
panels_page_wizard_add_content($form, $form_state);
return $form;
}
/**
* Submit function to store the form data in our cache.
*/
function panels_landing_page_submit(&$form, &$form_state) {
panels_page_wizard_add_content_submit($form, $form_state);
}
/**
* Finish callback for the wizard.
*
* When the wizard is finished, this callback will create the actual
* page, save it, and redirect the user to view the new work.
*/
function panels_landing_page_finish(&$form_state) {
$cache = &$form_state['wizard cache'];
// Ensure all 'page' features are loaded.
$page_task = page_manager_get_task('page');
// Assemble a new page subtask.
$subtask = page_manager_page_new();
$subtask->name = $cache->name;
$subtask->path = $cache->path;
$subtask->admin_title = $cache->admin_title;
$subtask->admin_description = $cache->admin_description;
$subtask->path = $cache->path;
$subtask->menu = $cache->menu;
// Create the the panel context variant configured with our display
$plugin = page_manager_get_task_handler('panel_context');
// Create a new handler.
$handler = page_manager_new_task_handler($plugin);
$handler->conf['title'] = t('Landing page');
$handler->conf['display'] = $cache->display;
$handler->conf['pipeline'] = 'ipe';
// Assemble a new $page cache and assign it our page subtask and task
// handler.
$page = new stdClass();
page_manager_page_new_page_cache($subtask, $page);
page_manager_handler_add_to_page($page, $handler);
// Save it
page_manager_save_page_cache($page);
// Send us to the new page immediately.
$form_state['redirect'] = url($cache->path);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,11 @@
%style {
margin-bottom: 10px;
color: %text;
background-color: %background;
}
%style h2 {
color: %header-text;
background-color: %header-background;
}

View File

@@ -0,0 +1,16 @@
<?php
/**
* @file
*
* Display the box for rounded corners.
*
* - $pane: The pane being rendered
* - $display: The display being rendered
* - $content: An object containing the content and title
* - $output: The result of theme('panels_pane')
* - $classes: The classes that must be applied to the top divs.
*/
?>
<div class="<?php print $classes ?>">
<?php print $output; ?>
</div>

View File

@@ -0,0 +1,93 @@
<?php
/**
* @file
* Definition of the style base for the rounded shadow box.
*
* This box is colorable, has rounded corners and a drop shadow.
*/
$plugin = array(
'category' => t('Basic styles'),
'title' => t('Plain'),
'description' => t('A plain box with an optional border. You may set the color of the text and the border.'),
'module' => 'panels',
'type' => 'pane',
'css' => 'pane-plain-box.css',
'icon' => 'icon.png',
'defaults' => array('font' => array(), 'header_font' => array(), 'border' => array(), 'header_border' => array(), 'padding' => array()),
'palette' => array(
'background' => array(
'label' => t('Background'),
'default_value' => '#FFFFFF',
),
'text' => array(
'label' => t('Text'),
'default_value' => '#000000',
),
'border' => array(
'label' => t('Border'),
'default_value' => '#000000',
),
'header-background' => array(
'label' => t('Header background'),
'default_value' => '#FFFFFF',
),
'header-text' => array(
'label' => t('Header text'),
'default_value' => '#000000',
),
'header-border' => array(
'label' => t('Header border'),
'default_value' => '#000000',
),
),
// This just uses theme_panels_pane because all we need is the class.
// 'theme' => 'pane_plain_box',
// 'preview' => 'panels_stylizer_pane_preview',
'settings form' => 'panels_pane_plain_box_style_settings',
'settings form submit' => 'panels_pane_plain_box_style_settings_submit',
'build' => 'panels_pane_plain_box_style_base_build',
);
function panels_pane_plain_box_style_settings(&$form, &$form_state) {
$form['font'] = array();
ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']);
$form['border'] = array();
ctools_stylizer_border_selector_form($form['border'], $form_state, t('Border'), $form_state['settings']['border']);
$form['padding'] = array();
ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']);
$form['header_font'] = array();
ctools_stylizer_font_selector_form($form['header_font'], $form_state, t('Header font'), $form_state['settings']['header_font']);
$form['header_border'] = array();
ctools_stylizer_border_selector_form($form['header_border'], $form_state, t('Header border'), $form_state['settings']['header_border']);
}
function panels_pane_plain_box_style_settings_submit(&$form, &$form_state) {
ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']);
ctools_stylizer_font_selector_form_submit($form['header_font'], $form_state, $form_state['values']['header_font'], $form_state['settings']['header_font']);
ctools_stylizer_border_selector_form_submit($form['header_border'], $form_state, $form_state['values']['header_border'], $form_state['settings']['header_border']);
ctools_stylizer_border_selector_form_submit($form['border'], $form_state, $form_state['values']['border'], $form_state['settings']['border']);
ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']);
}
function panels_pane_plain_box_style_base_build($plugin, $settings, &$css, $replacements) {
ctools_stylizer_font_apply_style($css, '%style', $settings['font']);
ctools_stylizer_border_apply_style($css, '%style', $settings['border'], '%border');
ctools_stylizer_font_apply_style($css, '%style .pane-title', $settings['header_font']);
ctools_stylizer_border_apply_style($css, '%style .pane-title', $settings['header_border'], '%header-border', 'bottom');
ctools_stylizer_padding_apply_style($css, '%style .pane-title, %style .pane-content', $settings['padding']);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,105 @@
/* Show only to IE7 */
*:first-child+html .rounded-shadow-background,
/* Show only to IE6 */
* html .rounded-shadow-background {
margin: 0 -10px 0 0 !important;
padding: 10px 0 5px 0 !important;
}
.rounded-shadow-top-edge, .rounded-shadow-bottom-edge, .rounded-shadow-left-edge, .rounded-shadow-right-edge, .rounded-shadow-wrap-corner {
position: relative;
/* hasLayout -1 ? For IE only */
zoom: 1;
}
%style {
padding-top: 10px;
margin-bottom: 30px;
color: %text;
}
%style h2 {
color: %header-text;
}
%style .rounded-shadow-background {
margin: 10px;
background: %background url(rounded-shadow-background.png) repeat;
}
%style .rounded-shadow-wrap-corner {
margin: -10px;
}
%style .rounded-shadow-top-edge {
top: -10px;
background: url(rounded-shadow-top-edge.png) repeat-x 0 top;
font-size: 1px;
}
%style .rounded-shadow-bottom-edge {
bottom: -10px;
background: url(rounded-shadow-bottom-edge.png) repeat-x 0 bottom;
font-size: 1px;
}
%style .rounded-shadow-left-edge {
background: url(rounded-shadow-left-edge.png) repeat-y 0 0;
}
%style .rounded-shadow-right-edge {
background: url(rounded-shadow-right-edge.png) repeat-y right 0;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-top-edge,
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge {
height: 19px;
margin: -10px 19px;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-left,
%style .rounded-shadow-wrap-corner .rounded-shadow-right {
position: absolute;
top: 0;
height: 19px;
width: 19px;
margin: 0 -19px;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-left {
background-image: url(rounded-shadow-top-left-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-right {
right: 0;
background-image: url(rounded-shadow-top-right-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-left {
background-image: url(rounded-shadow-bottom-left-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-right {
right: 0;
background-image: url(rounded-shadow-bottom-right-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-right-edge {
padding: 3px 19px;
}
%style .panel-pane {
position: relative; top: -6px;
}
/*
%style div.admin-links {
margin-top: -19px;
margin-left: -12px;
}
%style .panel-separator {
background: url(rounded-shadow-bottom-edge.png) repeat-x 0 center;
font-size: 1px;
height: 30px;
}
*/

View File

@@ -0,0 +1,31 @@
<?php
/**
* @file
*
* Display the box for rounded corners.
*
* - $output: The content of the box.
* - $classes: The classes that must be applied to the top divs.
* - $pane: The pane being rendered
* - $display: The display being rendered
* - $content: The content being rendered (will be already in $output)
*/
?>
<div class="rounded-shadow <?php print $classes ?>">
<div class="rounded-shadow-background">
<div class="rounded-shadow-wrap-corner">
<div class="rounded-shadow-top-edge">
<div class="rounded-shadow-left"></div>
<div class="rounded-shadow-right"></div>
</div>
<div class="rounded-shadow-left-edge">
<div class="rounded-shadow-right-edge clearfix">
<?php print $output; ?>
</div>
</div>
<div class="rounded-shadow-bottom-edge">
<div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,99 @@
<?php
/**
* @file
* Definition of the style base for the rounded shadow box.
*
* This box is colorable, has rounded corners and a drop shadow.
*/
$plugin = array(
'category' => t('Basic styles'),
'title' => t('Rounded shadow box'),
'module' => 'panels',
'type' => 'pane',
'css' => 'pane-rounded-shadow.css',
'icon' => 'icon.png',
'defaults' => array('header_font' => array(), 'text_font' => array(), 'padding' => array(), 'header_border' => array()),
'palette' => array(
'background' => array(
'label' => t('Background'),
'default_value' => '#FFFFFF',
),
'text' => array(
'label' => t('Text'),
'default_value' => '#000000',
),
'header-text' => array(
'label' => t('Header text'),
'default_value' => '#000000',
),
'header-border' => array(
'label' => t('Header border'),
'default_value' => '#000000',
),
),
'actions' => array(
array('load', 'box', 'box-color.png'),
array('colorize', 'background'),
array('load', 'shadow', 'box-shadow.png'),
array('merge_from', 'box'),
array('slice', 'rounded-shadow-top-left-corner.png', 17, 49, 19, 19),
array('slice', 'rounded-shadow-top-right-corner.png', 473, 49, 19, 19),
array('slice', 'rounded-shadow-bottom-left-corner.png', 17, 442, 19, 19),
array('slice', 'rounded-shadow-bottom-right-corner.png', 473, 442, 19, 19),
array('slice', 'rounded-shadow-left-edge.png', 17, 60, 10, 10),
array('slice', 'rounded-shadow-right-edge.png', 474, 60, 18, 10),
array('slice', 'rounded-shadow-top-edge.png', 28, 49, 10, 10),
array('slice', 'rounded-shadow-bottom-edge.png', 28, 443, 10, 18),
array('slice', 'rounded-shadow-background.png', 150, 150, 1, 1),
),
'theme' => 'pane_rounded_shadow',
'build' => 'panels_rounded_shadow_style_base_build',
// 'preview' => 'panels_stylizer_pane_preview',
'settings form' => 'panels_pane_rounded_shadow_style_settings',
'settings form submit' => 'panels_pane_rounded_shadow_style_settings_submit',
'build' => 'panels_pane_rounded_shadow_style_base_build',
);
function template_preprocess_pane_rounded_shadow(&$vars) {
$vars['classes_array'][] = $vars['content']->css_class;
$vars['content']->css_class = '';
$vars['output'] = theme('panels_pane', $vars);
}
function panels_pane_rounded_shadow_style_settings(&$form, &$form_state) {
$form['header_font'] = array();
ctools_stylizer_font_selector_form($form['header_font'], $form_state, t('Header font'), $form_state['settings']['header_font']);
$form['header_border'] = array();
ctools_stylizer_border_selector_form($form['header_border'], $form_state, t('Header border'), $form_state['settings']['header_border']);
$form['text_font'] = array();
ctools_stylizer_font_selector_form($form['text_font'], $form_state, t('Text font'), $form_state['settings']['text_font']);
$form['padding'] = array();
ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']);
}
function panels_pane_rounded_shadow_style_settings_submit(&$form, &$form_state) {
ctools_stylizer_font_selector_form_submit($form['header_font'], $form_state, $form_state['values']['header_font'], $form_state['settings']['header_font']);
ctools_stylizer_font_selector_form_submit($form['text_font'], $form_state, $form_state['values']['text_font'], $form_state['settings']['text_font']);
ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']);
ctools_stylizer_border_selector_form_submit($form['header_border'], $form_state, $form_state['values']['header_border'], $form_state['settings']['header_border']);
}
function panels_pane_rounded_shadow_style_base_build($plugin, $settings, &$css, $replacements) {
ctools_stylizer_font_apply_style($css, '%style .pane-title', $settings['header_font']);
ctools_stylizer_border_apply_style($css, '%style .pane-title', $settings['header_border'], '%header-border', 'bottom');
ctools_stylizer_font_apply_style($css, '%style .pane-content', $settings['text_font']);
ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1,6 @@
%style {
padding-top: 10px;
margin-bottom: 10px;
color: %text;
background-color: %background;
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* @file
*
* Display the box for rounded corners.
*
* - $content: The content of the box.
* - $classes: The classes that must be applied to the top divs.
*/
?>
<div class="rounded-shadow <?php print $class ?>">
<div class="rounded-shadow-background">
<div class="rounded-shadow-wrap-corner">
<div class="rounded-shadow-top-edge">
<div class="rounded-shadow-left"></div>
<div class="rounded-shadow-right"></div>
</div>
<div class="rounded-shadow-left-edge">
<div class="rounded-shadow-right-edge clearfix">
<?php print $content; ?>
</div>
</div>
<div class="rounded-shadow-bottom-edge">
<div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,65 @@
<?php
/**
* @file
* Definition of the style base for the rounded shadow box.
*
* This box is colorable, has rounded corners and a drop shadow.
*/
$plugin = array(
'category' => t('Basic styles'),
'title' => t('Plain'),
'description' => t('A plain box with an optional border. You may set the color of the text and the border.'),
'module' => 'panels',
'type' => 'region',
'css' => 'region-plain-box.css',
'icon' => 'icon.png',
'defaults' => array('font' => array(), 'border' => array(), 'padding' => array()),
'palette' => array(
'background' => array(
'label' => t('Background'),
'default_value' => '#FFFFFF',
),
'text' => array(
'label' => t('Text'),
'default_value' => '#000000',
),
'border' => array(
'label' => t('Border'),
'default_value' => '#000000',
),
),
'theme' => 'region_plain_box',
// 'preview' => 'panels_stylizer_region_preview',
'settings form' => 'panels_region_plain_box_style_settings',
'settings form submit' => 'panels_region_plain_box_style_settings_submit',
'build' => 'panels_region_plain_box_style_base_build',
);
function panels_region_plain_box_style_settings(&$form, &$form_state) {
$form['font'] = array();
ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']);
$form['border'] = array();
ctools_stylizer_border_selector_form($form['border'], $form_state, t('Border'), $form_state['settings']['border']);
$form['padding'] = array();
ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']);
}
function panels_region_plain_box_style_settings_submit(&$form, &$form_state) {
ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']);
ctools_stylizer_border_selector_form_submit($form['border'], $form_state, $form_state['values']['border'], $form_state['settings']['border']);
ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']);
}
function panels_region_plain_box_style_base_build($plugin, $settings, &$css, $replacements) {
ctools_stylizer_font_apply_style($css, '%style', $settings['font']);
ctools_stylizer_border_apply_style($css, '%style', $settings['border'], '%border');
ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@@ -0,0 +1,97 @@
/* Show only to IE7 */
*:first-child+html .rounded-shadow-background,
/* Show only to IE6 */
* html .rounded-shadow-background {
margin: 0 -10px 0 0 !important;
padding: 10px 0 5px 0 !important;
}
.rounded-shadow-top-edge, .rounded-shadow-bottom-edge, .rounded-shadow-left-edge, .rounded-shadow-right-edge, .rounded-shadow-wrap-corner {
position: relative;
/* hasLayout -1 ? For IE only */
zoom: 1;
}
%style {
padding-top: 10px;
margin-bottom: 30px;
color: %text;
}
%style .rounded-shadow-background {
margin: 10px;
background: %background url(rounded-shadow-background.png) repeat;
}
%style .rounded-shadow-wrap-corner {
margin: -10px;
}
%style .rounded-shadow-top-edge {
top: -10px;
background: url(rounded-shadow-top-edge.png) repeat-x 0 top;
font-size: 1px;
}
%style .rounded-shadow-bottom-edge {
bottom: -10px;
background: url(rounded-shadow-bottom-edge.png) repeat-x 0 bottom;
font-size: 1px;
}
%style .rounded-shadow-left-edge {
background: url(rounded-shadow-left-edge.png) repeat-y 0 0;
}
%style .rounded-shadow-right-edge {
background: url(rounded-shadow-right-edge.png) repeat-y right 0;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-top-edge,
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge {
height: 19px;
margin: -10px 19px;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-left,
%style .rounded-shadow-wrap-corner .rounded-shadow-right {
position: absolute;
top: 0;
height: 19px;
width: 19px;
margin: 0 -19px;
}
%style .rounded-shadow-wrap-corner .rounded-shadow-left {
background-image: url(rounded-shadow-top-left-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-right {
right: 0;
background-image: url(rounded-shadow-top-right-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-left {
background-image: url(rounded-shadow-bottom-left-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-bottom-edge .rounded-shadow-right {
right: 0;
background-image: url(rounded-shadow-bottom-right-corner.png);
}
%style .rounded-shadow-wrap-corner .rounded-shadow-right-edge {
padding: 3px 19px;
}
/*
%style div.admin-links {
margin-top: -19px;
margin-left: -12px;
}
%style .panel-separator {
background: url(rounded-shadow-bottom-edge.png) repeat-x 0 center;
font-size: 1px;
height: 30px;
}
*/

View File

@@ -0,0 +1,28 @@
<?php
/**
* @file
*
* Display the box for rounded corners.
*
* - $content: The content of the box.
* - $classes: The classes that must be applied to the top divs.
*/
?>
<div class="rounded-shadow <?php print $class ?>">
<div class="rounded-shadow-background">
<div class="rounded-shadow-wrap-corner">
<div class="rounded-shadow-top-edge">
<div class="rounded-shadow-left"></div>
<div class="rounded-shadow-right"></div>
</div>
<div class="rounded-shadow-left-edge">
<div class="rounded-shadow-right-edge clearfix">
<?php print $content; ?>
</div>
</div>
<div class="rounded-shadow-bottom-edge">
<div class="rounded-shadow-left"></div><div class="rounded-shadow-right"></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,71 @@
<?php
/**
* @file
* Definition of the style base for the rounded shadow box.
*
* This box is colorable, has rounded corners and a drop shadow.
*/
$plugin = array(
'category' => t('Basic styles'),
'title' => t('Rounded shadow box'),
'module' => 'panels',
'type' => 'region',
'css' => 'region-rounded-shadow.css',
'icon' => 'icon.png',
'defaults' => array('font' => array(), 'padding' => array()),
'palette' => array(
'background' => array(
'label' => t('Background'),
'default_value' => '#FFFFFF',
),
'text' => array(
'label' => t('Text color'),
'default_value' => '#000000',
),
),
'actions' => array(
array('load', 'box', 'box-color.png'),
array('colorize', 'background'),
array('load', 'shadow', 'box-shadow.png'),
array('merge_from', 'box'),
array('slice', 'rounded-shadow-top-left-corner.png', 17, 49, 19, 19),
array('slice', 'rounded-shadow-top-right-corner.png', 473, 49, 19, 19),
array('slice', 'rounded-shadow-bottom-left-corner.png', 17, 442, 19, 19),
array('slice', 'rounded-shadow-bottom-right-corner.png', 473, 442, 19, 19),
array('slice', 'rounded-shadow-left-edge.png', 17, 60, 10, 10),
array('slice', 'rounded-shadow-right-edge.png', 474, 60, 18, 10),
array('slice', 'rounded-shadow-top-edge.png', 28, 49, 10, 10),
array('slice', 'rounded-shadow-bottom-edge.png', 28, 443, 10, 18),
array('slice', 'rounded-shadow-background.png', 150, 150, 1, 1),
),
'theme' => 'region_rounded_shadow',
'build' => 'panels_rounded_shadow_style_base_build',
// 'preview' => 'panels_stylizer_region_preview',
'settings form' => 'panels_region_rounded_shadow_style_settings',
'settings form submit' => 'panels_region_rounded_shadow_style_settings_submit',
'build' => 'panels_region_rounded_shadow_style_base_build',
);
function panels_region_rounded_shadow_style_settings(&$form, &$form_state) {
$form['font'] = array();
ctools_stylizer_font_selector_form($form['font'], $form_state, t('Font'), $form_state['settings']['font']);
$form['padding'] = array();
ctools_stylizer_padding_selector_form($form['padding'], $form_state, t('Padding'), $form_state['settings']['padding']);
}
function panels_region_rounded_shadow_style_settings_submit(&$form, &$form_state) {
ctools_stylizer_font_selector_form_submit($form['font'], $form_state, $form_state['values']['font'], $form_state['settings']['font']);
ctools_stylizer_padding_selector_form_submit($form['padding'], $form_state, $form_state['values']['padding'], $form_state['settings']['padding']);
}
function panels_region_rounded_shadow_style_base_build($plugin, $settings, &$css, $replacements) {
ctools_stylizer_font_apply_style($css, '%style', $settings['font']);
ctools_stylizer_padding_apply_style($css, '%style', $settings['padding']);
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* @file
* Definition of the 'block' panel style.
*/
// Plugin definition
$plugin = array(
'title' => t('System block'),
'description' => t('Display the pane as a system block; this is more restrictive than the default.'),
'render pane' => 'panels_block_style_render_pane',
'weight' => -10,
);
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_block_style_render_pane($vars) {
$content = $vars['content'];
$pane = $vars['pane'];
if (empty($content->content)) {
return;
}
$block = clone($content);
if (!empty($block->title)) {
$block->subject = $block->title;
}
if (!isset($block->subject)) {
$block->subject = '';
}
$block->region = $pane->panel;
if (!isset($block->module)) {
$block->module = $block->type;
}
if (!isset($block->delta)) {
$block->delta = $block->subtype;
}
$build = $block->content;
if (is_string($build)) {
$build = array('#markup' => $build);
}
$build['#block'] = $block;
$build['#theme_wrappers'][] = 'block';
// If using per pane classes, $block->css_class will need to be added in your
// preprocess or template, along with any other Panels specific field you
// might want to utilize.
return drupal_render($build);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

View File

@@ -0,0 +1,20 @@
<?php
/**
* @file
*
* Display the box for rounded corners.
*
* - $content: The content of the box.
*/
?>
<div class="rounded-corner">
<div class="wrap-corner">
<div class="t-edge"><div class="l"></div><div class="r"></div></div>
<div class="l-edge">
<div class="r-edge clearfix">
<?php print $content; ?>
</div>
</div>
<div class="b-edge"><div class="l"></div><div class="r"></div></div>
</div>
</div>

View File

@@ -0,0 +1,205 @@
<?php
/**
* @file
* Definition of the 'rounded_corners' panel style.
*/
// Plugin definition
$plugin = array(
'title' => t('Rounded corners'),
'description' => t('Presents the panes or panels with a rounded corner box around them'),
'render region' => 'panels_rounded_corners_style_render_region',
'render pane' => 'panels_rounded_corners_style_render_pane',
'settings form' => 'panels_rounded_corners_style_settings_form',
'hook theme' => array(
'panels_rounded_corners_box' => array(
'variables' => array('content' => NULL),
'path' => panels_get_path('plugins/styles/corners'),
'template' => 'panels-rounded-corners-box',
),
),
);
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_rounded_corners_style_render_region($vars) {
$display = $vars['display'];
$region_id = $vars['region_id'];
$panes = $vars['panes'];
$settings = $vars['settings'];
$output = '';
// Determine where to put the box. If empty or 'pane' around each pane. If
// 'panel' then just around the whole panel.
$where = empty($settings['corner_location']) ? 'pane' : $settings['corner_location'];
$print_separator = FALSE;
foreach ($panes as $pane_id => $pane) {
// Add the separator if we've already displayed a pane.
if ($print_separator) {
$output .= '<div class="panel-separator">&nbsp;</div>';
}
if ($where == 'pane') {
$output .= theme('panels_rounded_corners_box', array('content' => $pane));
}
else {
$output .= $pane;
$print_separator = TRUE;
}
}
if ($where == 'panel') {
$output = theme('panels_rounded_corners_box', array('content' => $output));
}
panels_add_rounded_corners_css($display, $where);
return $output;
}
function panels_add_rounded_corners_css($display, $where) {
static $displays_used = array();
if (empty($displays_used[$display->css_id])) {
panels_rounded_corners_css($display, $where);
$displays_used[$display->css_id] = TRUE;
}
}
/**
* Render callback for a single pane.
*/
function theme_panels_rounded_corners_style_render_pane($vars) {
$content = $vars['content'];
$pane = $vars['pane'];
$display = $vars['display'];
if (empty($content->content)) {
return;
}
$output = theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display));
// Just stick a box around the standard theme_panels_pane.
$output = theme('panels_rounded_corners_box', array('content' => $output));
panels_add_rounded_corners_css($display, 'pane');
return $output;
}
/**
* Settings form callback.
*/
function panels_rounded_corners_style_settings_form($style_settings) {
$form['corner_location'] = array(
'#type' => 'select',
'#title' => t('Box around'),
'#options' => array(
'pane' => t('Each pane'),
'panel' => t('Each region'),
),
'#default_value' => (isset($style_settings['corner_location'])) ? $style_settings['corner_location'] : 'ul',
'#description' => t('Choose whether to include the box around each pane (piece of content) or region (each column or region)'),
);
return $form;
}
/**
* Generates the dynamic CSS.
*
* @param $display
* A Panels display object.
*/
function panels_rounded_corners_css($display) {
$idstr = empty($display->css_id) ? '.rounded-corner' : "#$display->css_id";
$css_id = 'rounded-corner:' . $idstr;
ctools_include('css');
$filename = ctools_css_retrieve($css_id);
if (!$filename) {
$filename = ctools_css_store($css_id, _panels_rounded_corners_css($idstr), FALSE);
}
drupal_add_css($filename, array('preprocess' => TRUE));
}
/**
* Generates the dynamic CSS.
*/
function _panels_rounded_corners_css($idstr) {
$url = panels_get_path('plugins/styles/corners', TRUE);
$css = <<<EOF
.t-edge, .b-edge, .l-edge, .r-edge, .wrap-corner {
position: relative;
/* hasLayout -1 ? For IE only */
zoom: 1;
}
$idstr .t-edge {
background: url($url/shadow-t.png) repeat-x 0 top;
font-size: 1px;
}
$idstr .b-edge {
background: url($url/shadow-b.png) repeat-x 0 bottom;
font-size: 1px;
}
$idstr .l-edge {
background: url($url/shadow-l.png) repeat-y 0 0;
}
$idstr .r-edge {
background: url($url/shadow-r.png) repeat-y right 0;
}
$idstr .wrap-corner {
background: #fff !important;
}
$idstr .wrap-corner .t-edge, $idstr .wrap-corner .b-edge {
height: 11px;
}
$idstr .wrap-corner .l, $idstr .wrap-corner .r {
position: absolute;
top: 0;
height: 11px;
width: 11px;
background-image: url($url/corner-bits.png);
}
$idstr .wrap-corner .l {
left: 0;
}
$idstr .wrap-corner .r {
right: 0;
background-position: -11px 0;
}
$idstr .wrap-corner .b-edge .l {
background-position: 0 -11px;
}
$idstr .wrap-corner .b-edge .r {
background-position: -11px -11px;
}
$idstr .wrap-corner .r-edge {
padding: 5px 24px;
}
$idstr div.admin-links {
margin-top: -14px;
margin-left: -12px;
}
$idstr .panel-separator {
background: url($url/shadow-b.png) repeat-x 0 center;
font-size: 1px;
height: 30px;
}
$idstr .rounded-corner {
margin-bottom: 1em;
}
EOF;
return $css;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

View File

@@ -0,0 +1,27 @@
<?php
/**
* @file
* Definition of the 'default' panel style.
*/
// Plugin definition
$plugin = array(
'title' => t('No style'),
'description' => t('The default panel rendering style; displays each pane with a separator.'),
'render region' => 'panels_default_style_render_region',
);
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_default_style_render_region($vars) {
$output = '';
// $output .= '<div class="region region-' . $vars['region_id'] . '">';
$output .= implode('<div class="panel-separator"></div>', $vars['panes']);
// $output .= '</div>';
return $output;
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* @file
* Definition of the 'list' panel style.
*/
// Plugin definition
$plugin = array(
'title' => t('List'),
'description' => t('Presents the panes in the form of an HTML list.'),
'render region' => 'panels_list_style_render_region',
'settings form' => 'panels_list_style_settings_form',
'settings validate' => 'panels_list_style_settings_validate',
);
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_list_style_render_region($vars) {
$display = $vars['display'];
$region_id = $vars['region_id'];
$panes = $vars['panes'];
$settings = $vars['settings'];
$items = array();
foreach ($panes as $pane_id => $item) {
$items[] = $item;
}
if (empty($settings['list_type'])) {
$settings['list_type'] = 'ul';
}
return theme('item_list', array('items' => $items, 'type' => $settings['list_type']));
}
/**
* Settings form callback.
*/
function panels_list_style_settings_form($style_settings) {
$form['list_type'] = array(
'#type' => 'select',
'#title' => t('List type'),
'#options' => array(
'ul' => t('Unordered'),
'ol' => t('Ordered'),
),
'#default_value' => (isset($style_settings['list_type'])) ? $style_settings['list_type'] : 'ul',
);
return $form;
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* @file
* Definition of the 'naked' panel style.
*/
// Plugin definition
$plugin = array(
'title' => t('No markup at all'),
'description' => t('Display the pane or region with no markup, not even a title.'),
'render region' => 'panels_naked_style_render_region',
'render pane' => 'panels_naked_style_render_pane',
'weight' => -5,
);
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_naked_style_render_region($vars) {
return implode($vars['panes']);
}
/**
* Render callback.
*
* @ingroup themeable
*/
function theme_panels_naked_style_render_pane($vars) {
return render($vars['content']->content);
}

View File

@@ -0,0 +1,375 @@
<?php
/**
* @file
* Definition of the 'stylizer' panel style.
*/
if (module_exists('stylizer')) {
// Plugin definition
$plugin = array(
'title' => t('Custom style'),
'weight' => -10,
'description' => t('Allows choice of a stylizer style'),
'render pane' => 'panels_stylizer_stylizer_style_render_pane',
'pane settings form' => 'panels_stylizer_stylizer_style_settings_form',
'render region' => 'panels_stylizer_stylizer_style_render_region',
'settings form' => 'panels_stylizer_stylizer_style_settings_form',
// We offer substyles so provide callbacks to do so.
'get child' => 'panels_stylizer_get_substyle',
'get children' => 'panels_stylizer_get_substyles',
// Set up an AJAX callback for the style
'ajax' => array(
'custom' => 'panels_stylizer_pane_add_style',
),
// 'settings validate' => 'panels_stylizer_stylizer_style_settings_validate',
);
}
/**
* Merge the main stylizer plugin with a style to create a sub plugin.
*
* This is used for both panels_stylizer_get_substyle and
* panels_stylizer_get_substyles.
*/
function panels_stylizer_merge_plugin($plugin, $style) {
$plugin['name'] = 'stylizer:' . $style->name;
$plugin['title'] = check_plain($style->admin_title);
$plugin['description'] = check_plain($style->admin_description);
$plugin['style'] = $style;
$plugin['weight'] = 0;
ctools_include('stylizer');
$base = ctools_get_style_base($style->settings['style_base']);
if ($base['type'] == 'pane') {
unset($plugin['render region']);
}
else {
unset($plugin['render pane']);
}
unset($plugin['settings form']);
unset($plugin['pane settings form']);
return $plugin;
}
/**
* Callback to provide a single stored stylizer style.
*/
function panels_stylizer_get_substyle($plugin, $style_name, $substyle_name) {
// Do not worry about caching; Panels is handling that for us.
ctools_include('export');
$item = ctools_export_crud_load('stylizer', $substyle_name);
if ($item) {
return panels_stylizer_merge_plugin($plugin, $item);
}
}
/**
* Callback to provide all stored stylizer styles.
*/
function panels_stylizer_get_substyles($plugin, $style_name) {
$styles[$style_name] = $plugin;
ctools_include('export');
ctools_include('stylizer');
$items = ctools_export_crud_load_all('stylizer');
foreach ($items as $name => $item) {
$base = ctools_get_style_base($item->settings['style_base']);
if ($base && $base['module'] == 'panels') {
$styles['stylizer:' . $name] = panels_stylizer_merge_plugin($plugin, $item);
}
}
return $styles;
}
/**
* Get style settings for a stylizer style.
*
* Because style settings can come from a couple of different places,
* depending on if it's a custom style in the panel or a custom style
* in the database, we have a tricky way of looking for this info.
*/
function _panels_stylizer_get_style($plugin, $style_settings) {
if (!empty($plugin['style'])) {
return $plugin['style']->settings;
}
if (empty($style_settings)) {
return array();
}
if ($style_settings['style'] == '$') {
return $style_settings['settings'];
}
ctools_include('export');
$style = ctools_export_crud_load('stylizer', $style_settings['style']);
if ($style) {
return $style->settings;
}
}
/**
* Region render theme.
*/
function theme_panels_stylizer_stylizer_style_render_region($vars) {
$display = $vars['display'];
$panes = $vars['panes'];
$style_settings = $vars['settings'];
$region_id = $vars['region_id'];
$plugin = $vars['style'];
$output = '';
foreach ($panes as $pane_id => $pane_output) {
$output .= $pane_output;
}
$settings = _panels_stylizer_get_style($plugin, $style_settings);
if (!empty($settings)) {
ctools_include('stylizer');
$plugin = ctools_get_style_base($settings['style_base']);
ctools_stylizer_add_css($plugin, $settings);
return theme($plugin['theme'], array('settings' => $settings, 'class' => ctools_stylizer_get_css_class($plugin, $settings), 'content' => $output));
}
else {
// if the style is gone, just display the output.
return $output;
}
}
/**
* Pane render theme
*/
function theme_panels_stylizer_stylizer_style_render_pane($vars) {
$content = $vars['content'];
$pane = $vars['pane'];
$display = $vars['display'];
$plugin = $vars['style'];
$settings = _panels_stylizer_get_style($plugin, $vars['settings']);
if ($settings) {
ctools_include('stylizer');
$plugin = ctools_get_style_base($settings['style_base']);
if (empty($content->css_class)) {
$content->css_class = ctools_stylizer_get_css_class($plugin, $settings);
}
else {
$content->css_class .= ' ' . ctools_stylizer_get_css_class($plugin, $settings);
}
ctools_stylizer_add_css($plugin, $settings);
if (isset($plugin['theme'])) {
return theme($plugin['theme'], array('settings' => $settings, 'content' => $content, 'pane' => $pane, 'display' => $display));
}
}
// if the style is gone or has no theme of its own, just display the output.
return theme('panels_pane', array('content' => $content, 'pane' => $pane, 'display' => $display));
}
/**
* Settings form callback.
*/
function panels_stylizer_stylizer_style_settings_form($style_settings, $display, $pid, $type, $form_state) {
// Just redirect this to the custom style settings ajax.
panels_stylizer_pane_add_style($form_state['renderer'], array(), $style_settings, $type, $pid);
print ajax_render($form_state['renderer']->commands);
ajax_footer();
exit;
}
/**
* Allow on-the-fly creation of styles in panes.
*/
function panels_stylizer_pane_add_style(&$renderer, $plugin, &$conf, $type, $pid, $step = NULL) {
if (!user_access('administer panels styles')) {
return;
}
// Reset the $_POST['ajax_html_ids'] values to preserve
// proper IDs on form elements when auto-submit is used.
$_POST['ajax_html_ids'] = array();
ctools_include('stylizer');
$js = FALSE;
$path = $renderer->get_url('style', 'custom', $type, $pid, '%step');
$info = array(
'module' => 'panels',
'type' => $type,
'path' => $path,
'modal' => t('Create custom style'),
'owner form' => 'panels_stylizer_edit_pane_style_form',
'owner form validate' => 'panels_stylizer_edit_pane_style_form_validate',
'owner form submit' => 'panels_stylizer_edit_pane_style_form_submit',
'owner settings' => array('preconfigured' => FALSE, 'name' => '', 'admin_title' => '', 'admin_description' => ''),
'cache' => &$renderer->cache,
'conf' => &$conf,
'pid' => $pid,
);
if (!empty($conf['settings'])) {
$info['settings'] = $conf['settings'];
}
$output = ctools_stylizer_edit_style($info, TRUE, $step);
if (!empty($info['complete'])) {
if (!empty($info['owner settings']['preconfigured'])) {
ctools_include('export');
$style = ctools_export_crud_new('stylizer');
$style->name = $info['settings']['name'];
$style->admin_title = $info['owner settings']['admin_title'];
$style->admin_description = $info['owner settings']['admin_description'];
$style->settings = $info['settings'];
ctools_export_crud_save('stylizer', $style);
$conf['style'] = $info['settings']['name'];
if (isset($conf['settings'])) {
unset($conf['settings']);
}
}
else {
$conf['style'] = '$';
$conf['settings'] = $info['settings'];
}
// Be sure to unset the temporary if the style was just changed.
if (isset($renderer->cache->style)) {
unset($renderer->cache->style);
}
// $conf was a reference so it should just modify.
panels_edit_cache_set($renderer->cache);
$renderer->commands[] = ctools_modal_command_dismiss();
if ($type == 'pane') {
$renderer->command_update_pane($pid);
}
else if ($type == 'region') {
$renderer->command_update_region_links($pid);
}
else {
$renderer->command_update_display_links();
}
}
else {
$renderer->commands = $output;
}
}
/**
* The form for determining if a pane should create a local style or a
* preconfigured style.
*/
function panels_stylizer_edit_pane_style_form(&$form, &$form_state) {
if (!user_access('administer panels styles') || !module_exists('stylizer')) {
return;
}
ctools_include('dependent');
$settings = $form_state['owner info']['owner settings'];
$form['panels']['admin_title'] = array(
'#type' => 'textfield',
'#title' => t('Administrative title'),
'#description' => t('The name of this style. This will appear in the administrative interface to easily identify it.'),
'#default_value' => $settings['admin_title'],
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-preconfigured' => array(1)),
);
$form['panels']['name'] = array(
'#type' => 'textfield',
'#title' => t('Machine name'),
'#description' => t('The machine readable name of this page. It must be unique, and it must contain only alphanumeric characters and underscores. Once created, you will not be able to change this value!'),
'#default_value' => $settings['name'],
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-preconfigured' => array(1)),
);
$form['panels']['admin_description'] = array(
'#type' => 'textarea',
'#title' => t('Administrative description'),
'#description' => t('A description of what this style is, does or is for, for administrative use.'),
'#default_value' => $settings['admin_description'],
'#process' => array('ctools_dependent_process'),
'#dependency' => array('edit-preconfigured' => array(1)),
);
// Add the checkbox, set the weight early
$form['panels']['preconfigured'] = array(
'#type' => 'checkbox',
'#title' => t('Make this style available to other regions or panes'),
'#default_value' => $settings['name'],
'#weight' => -1,
);
}
/**
* Validate to see if we need to check the preconfigured values.
*/
function panels_stylizer_edit_pane_style_form_validate(&$form, &$form_state) {
if (!user_access('administer panels styles')) {
return;
}
// Only validate if preconfigured is checked.
if ($form_state['values']['preconfigured'] && !empty($form_state['clicked_button']['#wizard type'])) {
if (empty($form_state['values']['admin_title'])) {
form_error($form['panels']['admin_title'], t('You must choose an administrative title.'));
}
// If this is new, make sure the name is unique:
if ($form_state['op'] == 'add') {
if (empty($form_state['values']['name'])) {
form_error($form['panels']['name'], t('You must choose a machine name.'));
}
ctools_include('export');
$test = ctools_export_crud_load('stylizer', $form_state['values']['name']);
if ($test) {
form_error($form['panels']['name'], t('That name is used by another style: @page', array('@page' => $test->admin_title)));
}
// Ensure name fits the rules:
if (preg_match('/[^a-zA-Z0-9_]/', $form_state['values']['name'])) {
form_error($form['panels']['name'], t('Name must be alphanumeric or underscores only.'));
}
}
}
}
/**
* Store the preconfigured values.
*/
function panels_stylizer_edit_pane_style_form_submit(&$form, &$form_state) {
if (!user_access('administer panels styles')) {
return;
}
// Only validate if preconfigured is checked.
if ($form_state['values']['preconfigured'] && !empty($form_state['clicked_button']['#wizard type'])) {
$form_state['owner info']['owner settings']['admin_title'] = $form_state['values']['admin_title'];
$form_state['owner info']['owner settings']['admin_description'] = $form_state['values']['admin_description'];
// Clean up preview files before we set the name
ctools_stylizer_cleanup_style($form_state['plugin'], $form_state['settings']);
$form_state['settings']['name'] = $form_state['values']['name'];
$form_state['name'] = $form_state['values']['name'];
$form_state['owner info']['owner settings']['preconfigured'] = $form_state['values']['preconfigured'];
}
}

View File

@@ -0,0 +1,911 @@
<?php
/**
* @file
*
* This is the task handler plugin to handle attaching a panel to any
* task that advertises itself as a 'context' type, which all of the
* basic page tasks provided by page_manager.module do by default.
*/
// Plugin definition
$plugin = array(
// is a 'context' handler type, meaning it supports the API of the
// context handlers provided by ctools context plugins.
'handler type' => 'context',
'visible' => TRUE, // may be added up front.
// Administrative fields.
'title' => t('Panel'),
'admin summary' =>'panels_panel_context_admin_summary',
'admin title' => 'panels_panel_context_title',
'operations' => array(
'settings' => array(
'title' => t('General'),
'description' => t('Change general settings about this variant.'),
'form' => 'panels_panel_context_edit_settings',
),
'criteria' => array(
'title' => t('Selection rules'),
'description' => t('Control the criteria used to decide whether or not this variant is used.'),
'ajax' => FALSE,
'form' => array(
'order' => array(
'form' => t('Selection rules'),
),
'forms' => array(
'form' => array(
'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
'form id' => 'ctools_context_handler_edit_criteria',
),
),
),
),
'context' => array(
'title' => t('Contexts'),
'ajax' => FALSE,
'description' => t('Add additional context objects to this variant that can be used by the content.'),
'form' => array(
'order' => array(
'form' => t('Context'),
),
'forms' => array(
'form' => array(
'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
'form id' => 'ctools_context_handler_edit_context',
),
),
),
),
'layout' => array(
'title' => t('Layout'),
'description' => t('Change the layout of this panel.'),
// No AJAX so we get our CSS loaded.
'ajax' => FALSE,
'form' => array(
'order' => array(
'choose' => t('Change layout'),
'move' => t('Move content from old layout'),
),
'forms' => array(
'choose' => array(
'form id' => 'panels_panel_context_edit_layout',
),
'move' => array(
'include' => array(
drupal_get_path('module', 'panels') . '/includes/display-layout.inc',
),
'form id' => 'panels_panel_context_edit_move',
'submit' => 'panels_change_layout_submit',
),
),
),
),
'content' => array(
'title' => t('Content'),
'description' => t('Add content items and change their location with a drag and drop interface.'),
'ajax' => FALSE,
'form' => array(
'order' => array(
'form' => t('Content'),
),
'forms' => array(
'form' => array(
'include' => array(
drupal_get_path('module', 'panels') . '/includes/display-edit.inc',
),
'form id' => 'panels_panel_context_edit_content',
'no blocks' => TRUE,
),
),
),
),
'preview' => array(
'title' => t('Preview'),
'description' => t('Get a preview of what this variant will look like.'),
'form' => 'panels_panel_context_edit_preview',
'ajax' => FALSE,
'silent' => TRUE,
'form info' => array('finish text' => t('Preview')),
'no update and save' => TRUE,
),
),
'tab operation' => 'panels_panel_context_tab_operation',
// Callback to render the data.
'render' => 'panels_panel_context_render',
// Callback to return addressable data
'addressable callback' => 'panels_panel_context_get_addressable',
// Various callbacks for operations performed on the handler to ensure
// related data is updated properly.
'save' => 'panels_panel_context_save',
'delete' => 'panels_panel_context_delete',
'export' => 'panels_panel_context_export',
'clone' => 'panels_panel_context_clone',
'add features' => array(
'criteria' => t('Selection rules'),
'context' => t('Contexts'),
),
// Where to go when finished.
'add finish' => 'content',
'required forms' => array(
'choose' => t('Choose layout'),
'settings' => t('Panel settings'),
'content' => t('Panel content'),
),
'edit forms' => array(
'content' => t('Panel content'),
'criteria' => t('Selection rules'),
'settings' => t('General'),
'context' => t('Contexts'),
'layout' => t('Change layout'),
'move' => '', // no title makes it a 'hidden' edit form.
),
'forms' => array(
'settings' => array(
'form id' => 'panels_panel_context_edit_settings',
),
'choose' => array(
'form id' => 'panels_panel_context_edit_choose',
'no back validate' => TRUE,
),
'layout' => array(
'no return' => TRUE,
'form id' => 'panels_panel_context_edit_layout',
),
'move' => array(
'include' => array(
drupal_get_path('module', 'panels') . '/includes/display-layout.inc',
),
'form id' => 'panels_panel_context_edit_move',
'submit' => 'panels_change_layout_submit',
),
'content' => array(
'include' => array(
drupal_get_path('module', 'panels') . '/includes/display-edit.inc',
),
'form id' => 'panels_panel_context_edit_content',
'no blocks' => TRUE,
),
'context' => array(
'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
'form id' => 'ctools_context_handler_edit_context',
),
'criteria' => array(
'include' => drupal_get_path('module', 'ctools') . '/includes/context-task-handler.inc',
'form id' => 'ctools_context_handler_edit_criteria',
),
),
'default conf' => array(
'title' => t('Panel'),
'no_blocks' => FALSE,
'pipeline' => variable_get('panels_renderer_default', 'standard'),
'body_classes_to_remove' => '',
'body_classes_to_add' => '',
'css_id' => '',
'css' => '',
'contexts' => array(),
'relationships' => array(),
),
);
/**
* Provide the operation trail for the 'Edit panel' link.
*
* When editing the panel, go directly to the content tab.
*/
function panels_panel_context_tab_operation($handler, $contexts, $args) {
return array('handlers', $handler->name, 'content');
}
/**
* Get the display for a task handler.
*
* There are three methods that the display can be found.
* - In the database. $handler->conf['did'] will be set in this case,
* and $handler->conf['display'] won't be.
* - In $handler->conf['display'], with $handler->conf['did'] empty. This
* will be true for a default/imported task handler as well as a handler
* that has just been created but has not yet been saved.
* - in $handler->conf['display'] with $handler->conf['did' populated. This
* simply means that the display has been modified and is awaiting
* save. The modified one should always be used for editing purposes.
* - If none of the above is true, then a new display needs to be created
* for the handler and pla
*/
function &panels_panel_context_get_display(&$handler) {
if (isset($handler->conf['display'])) {
return $handler->conf['display'];
}
if (isset($handler->conf['did'])) {
$handler->conf['display'] = panels_load_display($handler->conf['did']);
// Check for a valid display. If no valid display can be loaded, something
// is wrong and we'll create a new one.
if (!empty($handler->conf['display'])) {
return $handler->conf['display'];
}
}
$handler->conf['display'] = panels_new_display();
return $handler->conf['display'];
}
/**
* Build the cache key so that the editor and IPE can properly find
* everything needed for this display.
*/
function panels_panel_context_cache_key($task_name, $handler_id, $args) {
$arguments = array();
foreach ($args as $arg) {
// Sadly things like panels everywhere actually use non-string arguments
// and they basically can't be represented here. Luckily, PE also does
// not use a system where this matters, so replace its args with a 0
// for a placeholder.
if (is_string($arg)) {
$arguments[] = $arg;
}
else {
$arguments[] = '0';
}
}
$cache_key = 'panel_context:' . $task_name . '::' . $handler_id . '::' . implode('\\', $arguments) . '::';
return $cache_key;
}
/**
* Check selection rules and, if passed, render the contexts.
*/
function panels_panel_context_render($handler, $base_contexts, $args, $test = TRUE) {
// Go through arguments and see if they match.
ctools_include('context');
ctools_include('context-task-handler');
ctools_include('plugins', 'panels');
// Add my contexts
$contexts = ctools_context_handler_get_handler_contexts($base_contexts, $handler);
// Test.
if ($test && !ctools_context_handler_select($handler, $contexts)) {
return;
}
if (isset($handler->handler)) {
ctools_context_handler_pre_render($handler, $contexts, $args);
}
// Load the display
$display = panels_panel_context_get_display($handler);
$display->context = $contexts;
$display->args = $args;
$display->css_id = $handler->conf['css_id'];
$task_name = page_manager_make_task_name($handler->task, $handler->subtask);
$display->cache_key = panels_panel_context_cache_key($task_name, $handler->name, $args);
// Check to see if there is any CSS.
if (!empty($handler->conf['css'])) {
ctools_include('css');
$css_id = 'panel_context:' . $handler->name;
$filename = ctools_css_retrieve($css_id);
if (!$filename) {
$filename = ctools_css_store($css_id, $handler->conf['css']);
}
drupal_add_css($filename);
}
// With an argument, this actually sets the display.
panels_get_current_page_display($display);
$renderer = panels_get_renderer($handler->conf['pipeline'], $display);
// If the IPE is enabled, but the user does not have access to edit
// load the standard renderer instead.
$parents = class_parents($renderer);
if (!empty($parents['panels_renderer_editor']) && !user_access('user page manager') && !user_access('use ipe with page manager')) {
$renderer = panels_get_renderer_handler('standard', $display);
}
// Remove and add body element classes
$panel_body_css = &drupal_static('panel_body_css');
if (isset($handler->conf['body_classes_to_remove']) && !isset($panel_body_css['body_classes_to_remove'])) {
$panel_body_css['body_classes_to_remove'] = $handler->conf['body_classes_to_remove'];
}
if (isset($handler->conf['body_classes_to_add']) && !isset($panel_body_css['body_classes_to_add'])) {
$panel_body_css['body_classes_to_add'] = $handler->conf['body_classes_to_add'];
}
$info = array(
'content' => panels_render_display($display, $renderer),
'no_blocks' => !empty($handler->conf['no_blocks']),
);
$info['title'] = $display->get_title();
return $info;
}
/**
* Callback to allow the handler to react to being saved.
*
* When a handler with a display is saved, two things have to happen.
* First, we have to save the display so that it becomes a real display,
* not the fake one we started with. Second, we have to cache
* any CSS that the display is using. This CSS can get re-cached
* later if the file disappears, but it's imperative that we do it here
* to make sure that old, dirty CSS cache gets removed.
*/
function panels_panel_context_save(&$handler, $update) {
// Only save the display if we believe it has been modified.
if (isset($handler->conf['display'])) {
panels_save_display($handler->conf['display']);
$handler->conf['did'] = $handler->conf['display']->did;
unset($handler->conf['display']);
}
// Delete any previous CSS cache file.
ctools_include('css');
ctools_css_clear('panel_context:' . $handler->name);
if (isset($page->conf['temp_layout'])) {
unset($page->conf['temp_layout']);
}
}
/**
* Special handling for exporting a panel task handler.
*
* When a panel is exported, we need to export the display separately
* rather than just letting its object be unpacked, which does not work
* very well.
*/
function panels_panel_context_export(&$handler, $indent) {
$display = panels_panel_context_get_display($handler);
foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
if (isset($handler->conf[$item])) {
unset($handler->conf[$item]);
}
}
$output = panels_export_display($display, $indent);
$output .= $indent . '$handler->conf[\'display\'] = $display' . ";\n";
return $output;
}
/**
* When a handler is cloned, we have to clone the display.
*/
function panels_panel_context_clone(&$handler) {
$old_display = panels_panel_context_get_display($handler);
$code = panels_export_display($old_display);
eval($code);
foreach (array('display', 'did', 'css_cache', 'temp_layout') as $item) {
if (isset($handler->conf[$item])) {
unset($handler->conf[$item]);
}
}
$display->did = 'new';
$handler->conf['display'] = $display;
}
/**
* Callback to delete the display when a handler is deleted.
*/
function panels_panel_context_delete(&$handler) {
if (!empty($handler->conf['did'])) {
panels_delete_display($handler->conf['did']);
}
}
/**
* Set up a title for the panel based upon the selection rules.
*/
function panels_panel_context_title($handler, $task, $subtask) {
if (isset($handler->conf['title'])) {
return check_plain($handler->conf['title']);
}
else {
return t('Panel');
}
}
/**
* Provide a nice little summary of what's in a panel.
*
* The task handler manager provides a summary of a given handler in a
* collapsible div. This callback provides that. For a Panel, we
* provide a summary of the layout type and content on one side, and
* a summary of the contexts in use on the other.
*/
function panels_panel_context_admin_summary($handler, $task, $subtask, $page, $show_title = TRUE) {
$task_name = page_manager_make_task_name($task['name'], $subtask['name']);
$output = '';
$display = panels_panel_context_get_display($handler);
ctools_include('plugins', 'panels');
ctools_include('context');
ctools_include('context-task-handler');
// Get the operations
$operations = page_manager_get_operations($page);
// Get operations for just this handler.
$operations = $operations['handlers']['children'][$handler->name]['children']['actions']['children'];
$args = array('handlers', $handler->name, 'actions');
$rendered_operations = page_manager_render_operations($page, $operations, array(), array('class' => array('actions')), 'actions', $args);
$layout = panels_get_layout($display->layout);
$plugin = page_manager_get_task_handler($handler->handler);
$object = ctools_context_handler_get_task_object($task, $subtask, $handler);
$display->context = ctools_context_load_contexts($object, TRUE);
$access = ctools_access_group_summary(!empty($handler->conf['access']) ? $handler->conf['access'] : array(), $display->context);
if ($access) {
$access = t('This panel will be selected if @conditions.', array('@conditions' => $access));
}
else {
$access = t('This panel will always be selected.');
}
$rows = array();
$type = $handler->type == t('Default') ? t('In code') : $handler->type;
$rows[] = array(
array('class' => t('page-summary-label'), 'data' => t('Storage')),
array('class' => t('page-summary-data'), 'data' => $type),
array('class' => t('page-summary-operation'), 'data' => ''),
);
if (!empty($handler->disabled)) {
$link = l(t('Enable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'enable')));
$text = t('Disabled');
}
else {
$link = l(t('Disable'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'actions', 'disable')));
$text = t('Enabled');
}
$rows[] = array(
array('class' => t('page-summary-label'), 'data' => t('Status')),
array('class' => t('page-summary-data'), 'data' => $text),
array('class' => t('page-summary-operation'), 'data' => $link),
);
$link = l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'criteria')));
$rows[] = array(
array('class' => t('page-summary-label'), 'data' => t('Selection rule')),
array('class' => t('page-summary-data'), 'data' => $access),
array('class' => t('page-summary-operation'), 'data' => $link),
);
$link = l(t('Change layout'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'layout')));
$link .= '<br />' . l(t('Edit content'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content')));
$link .= '<br />' . l(t('Preview'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'preview')));
$rows[] = array(
array('class' => t('page-summary-label'), 'data' => t('Layout')),
array('class' => t('page-summary-data'), 'data' => check_plain($layout['title'])),
array('class' => t('page-summary-operation'), 'data' => $link),
);
$content_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'content'))) . ']';
$context_link = ' [' . l(t('Edit'), page_manager_edit_url($task_name, array('handlers', $handler->name, 'context'))) . ']';
$info = theme('table', array('rows' => $rows, 'attributes' => array('class' => 'page-manager-handler-summary')));
$title = $handler->conf['title'];
if ($title != t('Panel')) {
$title = t('Panel: @title', array('@title' => $title));
}
$output .= '<div class="clearfix">';
if ($show_title) {
$output .= '<div class="handler-title clearfix">';
$output .= '<div class="actions handler-actions">' . $rendered_operations['actions'] . '</div>';
$output .= '<span class="title-label">' . $title . '</span>';
}
$output .= '</div>';
$output .= $info;
$output .= '</div>';
/*
$output .= '<div class="right-container">';
$output .= '<h3 class="context-title">' . t('Contexts') . $context_link . '</h3>';
$output .= $contexts;
$output .= '</div>';
$output .= '<div class="left-container">';
// $output .= $icon;
$output .= '<h3 class="handler-title">' . t('Content') . $content_link . '</h3>';
$output .= $content;
$output .= '</div>';
*/
return $output;
}
// --------------------------------------------------------------------------
// Forms
/**
* General notes about forms: The handler is automatically cached by the form
* wizard, so anything we store on $form_state['handler'] anywhere will get
* saved and appear on the next form. The cache is a 'working' cache and
* if the user hits cancel on any page of the multi-page wizard, all
* changes since the last 'update/finish' click will be flushed away.
*
* Many of the Panels forms call through to the real Panels cousins. These
* forms are smart enough to know that they're being wrapped in another
* form and act appropriately. Some of them are so smart that we just let
* their submit and validate handlers do the work rather than writing
* additional ones here.
*/
/**
* Choose a layout for this panel.
*
* This is only called during 'add', when we know that there isn't a
* previous layout to choose from. a different, only slightly different
* variant is called to change a pre-existing layout.
*/
function panels_panel_context_edit_choose($form, &$form_state) {
ctools_include('common', 'panels');
ctools_include('display-layout', 'panels');
ctools_include('plugins', 'panels');
// @todo -- figure out where/how to deal with this.
$form_state['allowed_layouts'] = 'panels_page';
$form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
// Tell the Panels form not to display buttons.
$form_state['no buttons'] = TRUE;
// Change the #id of the form so the CSS applies properly.
$form['#id'] = 'panels-choose-layout';
$form = panels_choose_layout($form, $form_state);
return $form;
}
/**
* Validate that a layout was chosen.
*/
function panels_panel_context_edit_choose_validate(&$form, &$form_state) {
if (empty($form_state['values']['layout'])) {
form_error($form['layout'], t('You must select a layout.'));
}
}
/**
* A layout has been selected, set it up.
*/
function panels_panel_context_edit_choose_submit(&$form, &$form_state) {
$form_state['display']->layout = $form_state['values']['layout'];
$form_state['handler']->conf['display'] = $form_state['display'];
if (isset($form_state['page']->display_cache[$form_state['handler_id']])) {
$form_state['page']->display_cache[$form_state['handler_id']]->display = $form_state['display'];
}
}
/**
* Change the layout for this panel.
*
* This form is only used if a layout already exists and the user wants
* to change to a different one. The submit handler changes the next form
* to the move content form, which is 'hidden' so it won't be accessed
* directly.
*/
function panels_panel_context_edit_layout($form, &$form_state) {
ctools_include('common', 'panels');
ctools_include('display-layout', 'panels');
ctools_include('plugins', 'panels');
// @todo -- figure out where/how to deal with this.
$form_state['allowed_layouts'] = 'panels_page';
$form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
// Tell the Panels form not to display buttons.
$form_state['no buttons'] = TRUE;
// Change the #id of the form so the CSS applies properly.
$form['#id'] = 'panels-choose-layout';
$form = panels_choose_layout($form, $form_state);
return $form;
}
/**
* Validate that a layout was chosen.
*/
function panels_panel_context_edit_layout_validate(&$form, &$form_state) {
$display = &panels_panel_context_get_display($form_state['handler']);
if (empty($form_state['values']['layout'])) {
form_error($form['layout'], t('You must select a layout.'));
}
if ($form_state['values']['layout'] == $display->layout) {
form_error($form['layout'], t('You must select a different layout if you wish to change layouts.'));
}
}
/**
* A layout has been selected, set it up.
*/
function panels_panel_context_edit_layout_submit(&$form, &$form_state) {
$display = &panels_panel_context_get_display($form_state['handler']);
if ($form_state['values']['layout'] != $display->layout) {
$form_state['handler']->conf['temp_layout'] = $form_state['values']['layout'];
}
}
/**
* When a layout is changed, the user is given the opportunity to move content.
*/
function panels_panel_context_edit_move($form, &$form_state) {
$form_state['display'] = &panels_panel_context_get_display($form_state['handler']);
$form_state['layout'] = $form_state['handler']->conf['temp_layout'];
$form_state['cache_key'] = panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array());
ctools_include('common', 'panels');
ctools_include('display-layout', 'panels');
ctools_include('plugins', 'panels');
// Tell the Panels form not to display buttons.
$form_state['no buttons'] = TRUE;
// Change the #id of the form so the CSS applies properly.
$form = panels_change_layout($form, $form_state);
// Change the 'back' button to just go directly to the previous form
// $task_id = $form_state['task']['name'];
// $handler_id = $form_state['handler']->handler;
// $name = $form_state['handler']->name;
// This form is outside the normal wizard list, so we need to specify the
// previous/next forms.
$form['buttons']['previous']['#next'] = 'layout';
$form['buttons']['next']['#next'] = 'content';
$form_state['form_info']['return path'] = page_manager_edit_url($form_state['page']->task_name, array('handlers', $form_state['handler_id'], 'content'));
return $form;
}
/**
* Present the panels drag & drop editor to edit the display attached
* to the task handler.
*/
function panels_panel_context_edit_content($form, &$form_state) {
ctools_include('ajax');
ctools_include('plugins', 'panels');
ctools_include('common', 'panels');
ctools_include('context');
ctools_include('context-task-handler');
$cache = panels_edit_cache_get(panels_panel_context_cache_key($form_state['task_name'], $form_state['handler_id'], array()));
$form_state['renderer'] = panels_get_renderer_handler('editor', $cache->display);
$form_state['renderer']->cache = &$cache;
$form_state['display'] = &$cache->display;
$form_state['content_types'] = $cache->content_types;
// Tell the Panels form not to display buttons.
$form_state['no buttons'] = TRUE;
$form_state['display_title'] = !empty($cache->display_title);
$form_state['no preview'] = TRUE;
$form_state['page']->display_cache[$form_state['handler_id']] = $cache;
$form = panels_edit_display_form($form, $form_state);
if (!isset($form_state['type']) || $form_state['type'] != 'add' && !empty($form_state['handler_id']) && !empty($form['buttons'])) {
$form['buttons']['preview'] = $form['buttons']['return'];
$form['buttons']['preview']['#value'] = t('Update and preview');
}
return $form;
}
/**
* Validate changes to the panel content form.
*/
function panels_panel_context_edit_content_validate(&$form, &$form_state) {
panels_edit_display_form_validate($form, $form_state);
}
function panels_panel_context_edit_content_submit(&$form, &$form_state) {
panels_edit_display_form_submit($form, $form_state);
$handler = &$form_state['handler'];
// update the cached display:
$display = $form_state['page']->display_cache[$form_state['handler_id']]->display;
$handler->conf['display'] = $display;
unset($form_state['page']->display_cache[$form_state['handler_id']]);
if ($form_state['clicked_button']['#value'] == t('Update and preview')) {
$form_state['new trail'] = array('handlers', $form_state['handler_id'], 'preview');
}
}
/**
* General settings for the panel
*/
function panels_panel_context_edit_settings($form, &$form_state) {
$conf = $form_state['handler']->conf;
$form['conf']['title'] = array(
'#type' => 'textfield',
'#default_value' => $conf['title'],
'#title' => t('Administrative title'),
'#description' => t('Administrative title of this variant.'),
);
$form['conf']['no_blocks'] = array(
'#type' => 'checkbox',
'#default_value' => $conf['no_blocks'],
'#title' => t('Disable Drupal blocks/regions'),
'#description' => t('Check this to have the page disable all regions displayed in the theme. Note that some themes support this setting better than others. If in doubt, try with stock themes to see.'),
);
$form['conf']['body_classes_to_remove'] = array(
'#type' => 'textfield',
'#size' => 128,
'#default_value' => $conf['body_classes_to_remove'],
'#title' => t('Remove body CSS classes'),
'#description' => t('The CSS classes to remove from the body element of this page. Separated by a space. For example: no-sidebars one-sidebar sidebar-first sidebar-second two-sidebars.'),
);
$form['conf']['body_classes_to_add'] = array(
'#type' => 'textfield',
'#size' => 128,
'#default_value' => $conf['body_classes_to_add'],
'#title' => t('Add body CSS classes'),
'#description' => t('The CSS classes to add to the body element of this page. Separated by a space. For example: no-sidebars one-sidebar sidebar-first sidebar-second two-sidebars.'),
);
ctools_include('plugins', 'panels');
$pipelines = panels_get_renderer_pipelines();
// Handle backward compatibility with the IPE checkbox.
if (empty($conf['pipeline'])) {
$conf['pipeline'] = !empty($conf['use_ipe']) ? 'ipe' : 'standard';
}
// If there are no pipelines, that probably means we're operating in
// legacy mode.
if (empty($pipelines)) {
// We retain the original pipeline so we don't wreck things by installing
// old modules.
$form['conf']['pipeline'] = array(
'#type' => 'value',
'#value' => $conf['pipeline'],
);
}
else {
$options = array();
foreach ($pipelines as $name => $pipeline) {
$options[$name] = check_plain($pipeline->admin_title) . '<div class="description">' . check_plain($pipeline->admin_description) . '</div>';
}
$form['conf']['pipeline'] = array(
'#type' => 'radios',
'#options' => $options,
'#title' => t('Renderer'),
'#default_value' => $conf['pipeline'],
);
}
$form['conf']['css_id'] = array(
'#type' => 'textfield',
'#size' => 35,
'#default_value' => $conf['css_id'],
'#title' => t('CSS ID'),
'#description' => t('The CSS ID to apply to this page'),
);
$form['conf']['css'] = array(
'#type' => 'textarea',
'#title' => t('CSS code'),
'#description' => t('Enter well-formed CSS code here; this code will be embedded into the page, and should only be used for minor adjustments; it is usually better to try to put CSS for the page into the theme if possible. This CSS will be filtered for safety so some CSS may not work.'),
'#default_value' => $conf['css'],
);
return $form;
}
/**
* Submit handler for general settings form.
*/
function panels_panel_context_edit_settings_submit(&$form, &$form_state) {
$form_state['handler']->conf['no_blocks'] = $form_state['values']['no_blocks'];
$form_state['handler']->conf['body_classes_to_remove'] = $form_state['values']['body_classes_to_remove'];
$form_state['handler']->conf['body_classes_to_add'] = $form_state['values']['body_classes_to_add'];
$form_state['handler']->conf['pipeline'] = $form_state['values']['pipeline'];
$form_state['handler']->conf['css_id'] = $form_state['values']['css_id'];
$form_state['handler']->conf['css'] = $form_state['values']['css'];
$form_state['handler']->conf['title'] = $form_state['values']['title'];
// Unset the old checkbox so we don't store needless data.
if (isset($form_state['handler']->conf['use_ipe'])) {
unset($form_state['handler']->conf['use_ipe']);
}
}
/**
* Form to show a nice preview.
*/
function panels_panel_context_edit_preview($form, &$form_state) {
ctools_include('context');
ctools_include('context-task-handler');
$contexts = ctools_context_handler_get_all_contexts($form_state['task'], $form_state['subtask'], $form_state['handler']);
$form['preview'] = array();
ctools_context_replace_form($form['preview'], $contexts);
// automatically preview if there are no argument placeholders.
if (empty($form['preview'])) {
$display = panels_panel_context_get_display($form_state['handler']);
$display->context = $contexts;
$display->skip_cache = TRUE;
$output = panels_render_display($display);
if (isset($form['buttons'])) {
unset($form['buttons']);
}
}
else {
$form['preview']['#tree'] = TRUE;
$form_state['contexts'] = $contexts;
}
if (!empty($output)) {
$form['output'] = array(
'#markup' => $output,
);
}
$form_state['do not cache'] = TRUE;
return $form;
}
/**
* Display a preview upon submit if arguments were needed.
*/
function panels_panel_context_edit_preview_submit(&$form, &$form_state) {
$display = panels_panel_context_get_display($form_state['handler']);
$display->context = ctools_context_replace_placeholders($form_state['contexts'], $form_state['values']['preview']);
$form_state['content'] = panels_render_display($display);
$form_state['redirect'] = FALSE;
$form_state['rerender'] = TRUE;
}
function panels_panel_context_get_addressable($task, $subtask_name, $handler, $address, $contexts, $arguments, $type) {
// Load the display
$display = panels_panel_context_get_display($handler);
$display->context = $contexts;
$display->args = $arguments;
$display->css_id = $handler->conf['css_id'];
$display->cache_key = panels_panel_context_cache_key($task->name, $handler->name, $arguments);
$renderer = panels_get_renderer($handler->conf['pipeline'], $display);
if ($type == 'content') {
$renderer->prepare();
$pid = array_shift($address);
if (!empty($renderer->prepared['panes'][$pid])) {
return $renderer->render_pane($renderer->prepared['panes'][$pid]);
}
}
}

View File

@@ -0,0 +1,27 @@
<?php
/**
* Implementation of hook_views_plugins
*/
function panels_views_plugins() {
$plugins = array(
'row' => array(
'panels_fields' => array(
'title' => t('Panel fields'),
'help' => t('Displays the fields in a panel rather than using a template.'),
'handler' => 'panels_views_plugin_row_fields',
'path' => drupal_get_path('module', 'panels') . '/plugins/views',
'theme' => 'views_view_fields',
'theme path' => drupal_get_path('module', 'views') . '/theme',
'register theme' => FALSE,
'uses fields' => TRUE,
'uses options' => TRUE,
'type' => 'normal',
'help topic' => 'style-row-panels-fields',
'parent' => 'fields',
),
),
);
return $plugins;
}

View File

@@ -0,0 +1,163 @@
<?php
/**
* @file
* Contains the base row style plugin.
*/
/**
* The basic 'fields' row plugin
*
* This displays fields one after another, giving options for inline
* or not.
*
* @ingroup views_row_plugins
*/
class panels_views_plugin_row_fields extends views_plugin_row_fields {
function option_definition() {
$options = parent::option_definition();
$options['layout'] = array('default' => 'twocol');
$options['regions'] = array('default' => array());
return $options;
}
/**
* Provide a form for setting options.
*/
function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
ctools_include('plugins', 'panels');
$layouts = panels_get_layouts();
$options = array();
foreach ($layouts as $name => $layout) {
if (empty($layout['builder'])) {
$options[$name] = $layout['title'];
}
if ($name == $this->options['layout']) {
$current_layout = $layout;
}
}
$form['layout'] = array(
'#prefix' => '<div class="container-inline">',
'#type' => 'select',
'#options' => $options,
'#title' => t('Panel layout'),
'#default_value' => $this->options['layout'],
);
$form['change'] = array(
'#type' => 'submit',
'#value' => t('Change'),
'#submit' => array('panels_change_layout_button'),
'#suffix' => '</div>',
);
if (!empty($current_layout)) {
$fields = $this->display->handler->get_field_labels();
$regions = panels_get_regions($current_layout, panels_new_display());
foreach ($fields as $id => $title) {
$form['regions'][$id] = array(
'#type' => 'select',
'#title' => $title,
'#options' => $regions,
);
if (!empty($this->options['regions'][$id]) && !empty($regions[$this->options['regions'][$id]])) {
$form['regions'][$id]['#default_value'] = $this->options['regions'][$id];
}
}
}
}
/**
* Perform any necessary changes to the form values prior to storage.
* There is no need for this function to actually store the data.
*/
function options_submit(&$form, &$form_state) {
$form_state['values']['row_options']['inline'] = array_filter($form_state['values']['row_options']['inline']);
}
/**
* Render a row object. This usually passes through to a theme template
* of some form, but not always.
*/
function render($row) {
ctools_include('plugins', 'panels');
$layout = panels_get_layout($this->options['layout']);
if (!$layout) {
// Fall back to normal behavior if the layout is somehow invalid. This
// can happen if the layout was removed, for example.
return theme($this->theme_functions(), array('view' => view, 'options' => $this->options, 'row' => $row, 'field_alias' => $this->field_alias));
}
// Store a backup copy of the array because we're going to be screwing
// with this a lot.
$fields = $this->view->field;
unset($this->view->field);
$meta = 'standard';
// This row style gets run many times; only run this code once.
if (empty($this->region_fields)) {
$this->region_fields = array();
$regions = panels_get_regions($layout, panels_new_display());
// Ensure each region has an empty array.
foreach ($regions as $region_id => $name) {
if (empty($default_region)) {
$default_region = $region_id;
}
$this->region_fields[$region_id] = array();
}
// Go through all our fields and place them in regions according to the
// settings.
foreach ($fields as $id => $field) {
$region_id = ''; // ensure we don't accidentlly use the last field's region.
if (!empty($this->options['regions'][$id]) && !empty($regions[$this->options['regions'][$id]])) {
$region_id = $this->options['regions'][$id];
}
else {
// Fallback to putting unknown fields into the first region.
$region_id = $default_region;
}
// Ensure this works in PHP4 by keeping the reference.
$this->region_fields[$region_id][$id] = &$fields[$id];
}
// We don't need to set 'inline' for every record, so we do it inside
// this loop. We do need to set inline if we are in the live preview
// so that the CSS will get transmitted via javascript:
$meta = !empty($this->view->live_preview) ? 'inline' : 'standard';
}
// Now that we have distributed our fields, go through the regions and
// render them into the content array.
foreach ($this->region_fields as $region_id => $fields) {
$this->view->field = $fields;
$content[$region_id] = theme($this->theme_functions(), array('view' => $this->view, 'options' => $this->options, 'row' => $row));
}
// Restore our $fields array.
$this->view->field = $fields;
// Now that we have a rendered content array, render it.
return panels_print_layout($layout, $content, $meta);
}
}
/**
* Override handler for views_ui_edit_display_form
*/
function panels_change_layout_button($form, &$form_state) {
$display = &$form_state['view']->display[$form_state['display_id']];
$display->handler->options_submit($form, $form_state);
views_ui_cache_set($form_state['view']);
$form_state['rerender'] = TRUE;
$form_state['rebuild'] = TRUE;
}