Newer
Older
<?php
/**
* Legacy render pipeline for a panels display.
*
* This render pipeline mirrors the old procedural system exactly, and plugins
* written for the legacy system will work exactly as they did before with this
* renderer.
*
* Most plugins will work with the newer renderer. These are the exceptions:
* - Style plugins that implement panel styling no longer need to call
* panels_render_pane() on all contained panes; rendered pane HTML is now
* passed in directly.
* - Cache plugins are now triggered on rendered HTML, rather than on
* unrendered datastructures.
*
* If your site relies on any of these plugin behaviors, you will need to use
* this renderer instead of the new panels_renderer_default() until those
* plugins are updated.
*/
class panels_renderer_legacy {
var $display;
var $plugins = array();
function build(&$display) {
$layout = panels_get_layout($display->layout);
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
$this->display = &$display;
$this->plugins['layout'] = $layout;
}
/**
* Builds inner content, then hands 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() {
if (!empty($this->plugins['layout']['css'])) {
if (file_exists(path_to_theme() . '/' . $this->plugins['layout']['css'])) {
drupal_add_css(path_to_theme() . '/' . $this->plugins['layout']['css']);
}
else {
drupal_add_css($this->plugins['layout']['path'] . '/' . $this->plugins['layout']['css']);
}
}
// This now comes after the CSS is added, because panels-within-panels must
// have their CSS added in the right order; inner content before outer content.
if (empty($this->display->cache['method'])) {
$content = $this->render_regions();
}
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_regions());
panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context);
}
$content = $cache->content;
}
$output = theme($this->plugins['layout']['theme'], check_plain($this->display->css_id), $content, $this->display->layout_settings, $this->display);
return $output;
}
/**
* Render all panes in the attached display into their panel regions, then
* render those regions.
*
* @return array $content
* An array of rendered panel regions, keyed on the region name.
*/
function render_regions() {
ctools_include('content');
// First, render all the panes into little boxes. We do this here because
// some panes request to be rendered after other panes (primarily so they
// can do the leftovers of forms).
$panes = array();
$later = array();
foreach ($this->display->content as $pid => $pane) {
$pane->shown = !empty($pane->shown); // guarantee this field exists.
// If the user can't see this pane, do not render it.
if (!$pane->shown || !panels_pane_access($pane, $this->display)) {
continue;
}
// If this pane wants to render last, add it to the $later array.
$content_type = ctools_get_content_type($pane->type);
if (!empty($content_type['render last'])) {
$later[$pid] = $pane;
continue;
}
$panes[$pid] = $this->render_pane($pane);
}
foreach ($later as $pid => $pane) {
$panes[$pid] = $this->render_pane($pane);
}
// Loop through all panels, put all panes that belong to the current panel
// in an array, then render the panel. Primarily this ensures that the
// panes are in the proper order.
$content = array();
foreach ($this->display->panels as $panel_name => $pids) {
$panel_panes = array();
foreach ($pids as $pid) {
if (!empty($panes[$pid])) {
$panel_panes[$pid] = $panes[$pid];
}
}
$content[$panel_name] = $this->render_region($panel_name, $panel_panes);
}
// Prevent notices by making sure that all panels at least have an entry:
$panels = panels_get_panels($this->plugins['layout'], $this->display);
foreach ($panels as $id => $panel) {
if (!isset($content[$id])) {
$content[$id] = NULL;
}
}
return $content;
}
/**
* Render the 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.
*/
function render_pane($pane) {
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
ctools_include('context');
if (!is_array($this->display->context)) {
$this->display->context = array();
}
$content = FALSE;
$caching = !empty($pane->cache['method']) ? TRUE : FALSE;
if ($caching && ($cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context, $pane))) {
$content = $cache->content;
}
else {
$content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $this->display->args, $this->display->context);
foreach (module_implements('panels_pane_content_alter') as $module) {
$function = $module . '_panels_pane_content_alter';
$function($content, $pane, $this->display->args, $this->display->context);
}
if ($caching) {
$cache = new panels_cache_object();
$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 = $pane->css['css_id'];
}
// Pass long the css_class that is usually available.
if (!empty($pane->css['css_class'])) {
$content->css_class = $pane->css['css_class'];
}
// Check the style attached to the region in which this pane appears
// to see if it needs legacy pane data or not.
foreach ($this->display->panels as $panel_name => $pids) {
if (in_array($pane->pid, $pids)) {
$containing_region = $panel_name;
}
}
list($style, ) = panels_get_panel_style_and_settings($this->display->panel_settings, $containing_region);
if (version_compare($style['version'], 2.0, '>=')) {
$content = panels_render_pane($content, $pane, $this->display);
}
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
return $content;
}
/**
* 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_name
* 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
* The rendered HTML for the passed-in panel region.
*/
function render_region($region_name, $panes) {
list($style, $style_settings) = panels_get_panel_style_and_settings($this->display->panel_settings, $region_name);
// 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.
$owner_id = 0;
if (isset($this->display->owner) && is_object($this->display->owner) && isset($this->display->owner->id)) {
$owner_id = $this->display->owner->id;
}
return theme($style['render panel'], $this->display, $owner_id, $panes, $style_settings, $region_name);
}
}