Newer
Older
Earl Miles
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
<?php
// $Id$
/**
* @file
*
* Contains Panels display rendering functions.
*/
/**
* Render a display by loading the content into an appropriate
* array and then passing through to panels_render_layout.
*
* if $incoming_content is NULL, default content will be applied. Use
* an empty string to indicate no content.
* @render
* @ingroup hook_invocations
*/
function _panels_render_display(&$display) {
$layout = panels_get_layout($display->layout);
if (!$layout) {
return NULL;
}
// TODO: This may not be necessary now. Check this.
panels_sanitize_display($display);
$output = '';
// Let modules act just prior to render.
foreach (module_implements('panels_pre_render') as $module) {
$function = $module . '_panels_pre_render';
$output .= $function($display);
}
$output .= panels_render_layout($layout, $display, $display->css_id, $display->layout_settings);
// Let modules act just after render.
foreach (module_implements('panels_post_render') as $module) {
$function = $module . '_panels_post_render';
$output .= $function($display);
}
return $output;
}
/**
* For external use: Given a layout ID and a $content array, return the
* panel display. The content array is filled in based upon the content
* available in the layout. If it's a two column with a content
* array defined like array('left' => t('Left side'), 'right' =>
* t('Right side')), then the $content array should be array('left' =>
* $output_left, 'right' => $output_right)
* @render
*/
function _panels_print_layout($id, $content) {
$layout = panels_get_layout($id);
if (!$layout) {
return;
}
return panels_render_layout($layout, $content);
}
/**
* Given a full layout structure and a content array, render a panel display.
* @render
*/
function panels_render_layout($layout, $content, $css_id = NULL, $settings = array()) {
if (!empty($layout['css'])) {
if (file_exists(path_to_theme() . '/' . $layout['css'])) {
drupal_add_css(path_to_theme() . '/' . $layout['css']);
}
else {
drupal_add_css($layout['path'] . '/' . $layout['css']);
Earl Miles
committed
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
144
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
179
180
181
182
183
184
185
186
187
188
189
190
191
}
}
$display = NULL;
// 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 $content is an object, it's a $display and we have to render its panes.
if (is_object($content)) {
$display = $content;
if (empty($display->cache['method'])) {
$content = panels_render_panes($display);
}
else {
$cache = panels_get_cached_content($display, $display->args, $display->context);
if ($cache === FALSE) {
$cache = new panels_cache_object();
$cache->set_content(panels_render_panes($display));
panels_set_cached_content($cache, $display, $display->args, $display->context);
}
$content = $cache->content;
}
}
$output = theme($layout['theme'], check_plain($css_id), $content, $settings, $display);
return $output;
}
/**
* Render all the panes in a display into a $content array to be used by
* the display theme function.
*/
function panels_render_panes($display) {
// Safety check.
if (empty($display->content)) {
return array();
}
// 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 ($display->content as $pid => $pane) {
$pane->shown = isset($pane->shown) ? $pane->shown : TRUE;
// TODO Really ought to design a method for creating a quick-access set of content_type (and other plugin) data to help optimize render performance
// If the user can't see this pane, do not render it.
if (!$pane->shown || !panels_pane_access($pane, $display)) {
continue;
}
// If this pane wants to render last, add it to the $later array.
$content_type = panels_get_content_type($pane->type);
if (!empty($content_type['render last'])) {
$later[$pid] = $pane;
continue;
}
$panes[$pid] = panels_render_pane_content($display, $pane);
}
foreach ($later as $pid => $pane) {
$panes[$pid] = panels_render_pane_content($display, $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 ($display->panels as $panel_name => $pids) {
$panel = array();
foreach ($pids as $pid) {
if (!empty($panes[$pid])) {
$panel[$pid] = $panes[$pid];
}
}
$content[$panel_name] = panels_render_panel($display, $panel_name, $panel);
}
return $content;
}
/**
* Render a single pane, identifying its context, and put it into
* the $panes array.
*/
function panels_render_pane_content(&$display, &$pane) {
if (empty($pane->context)) {
$pane->context = panels_pane_select_context($pane, $display->context);
if ($pane->context === FALSE) {
return FALSE;
}
}
$content = panels_get_pane_content($display, $pane, $display->args, $pane->context, $display->incoming_content);
$keywords = !empty($display->keywords) ? $display->keywords : array();
// Override the title if configured to
if (!empty($pane->configuration['override_title'])) {
// Give previous title as an available substitution here.
$keywords['%title'] = $content->title;
$content->title = $pane->configuration['override_title_text'];
}
// Pass long the css_id that is usually available.
if (!empty($pane->configuration['css_id'])) {
$content->css_id = $pane->configuration['css_id'];
}
// Pass long the css_class that is usually available.
if (!empty($pane->configuration['css_class'])) {
$content->css_class = $pane->configuration['css_class'];
}
if (!empty($content->title)) {
// Perform substitutions
if (!empty($keywords)) {
$content->title = strtr($content->title, $keywords);
}
Earl Miles
committed
// Sterilize the title
$content->title = filter_xss_admin($content->title);
Earl Miles
committed
// If a link is specified, populate.
if (!empty($content->title_link)) {
if (!is_array($content->title_link)) {
$url = array('href' => $content->title_link);
}
else {
$url = $content->title_link;
}
// set defaults so we don't bring up notices
$url += array('href' => '', 'attributes' => NULL, 'query' => NULL, 'fragment' => NULL, 'absolute' => NULL);
$content->title = l($content->title,
$url['href'],
$url['attributes'],
$url['query'],
$url['fragment'],
$url['absolute'], TRUE);
Earl Miles
committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
}
}
return $content;
}
/**
* Render a pane using the appropriate style.
*
* $content
* The already rendered content via panels_render_pane_content()
* $pane
* The $pane information from the display
* $display
* The display.
*/
function panels_render_pane($content, $pane, $display) {
if (!empty($pane->configuration['style'])) {
$style = panels_get_style($pane->configuration['style']);
if (isset($style)) {
$output = theme($style['render pane'], $content, $pane, $display);
// This could be null if no theme function existed.
if (isset($output)) {
return $output;
}
}
}
// fallback
return theme('panels_pane', $content, $pane, $display);
}
/**
* Given a display and the id of a panel, get the style in which to render
* that panel.
*/
function panels_get_panel_style_and_settings($panel_settings, $panel) {
if (empty($panel_settings)) {
return array(panels_get_style('default'), array());
}
if (empty($panel_settings['individual']) || empty($panel_settings['panel'][$panel]['style'])) {
$style = panels_get_style($panel_settings['style']);
$style_settings = $panel_settings['style_settings']['default'];
}
else {
$style = panels_get_style($panel_settings['panel'][$panel]['style']);
$style_settings = $panel_settings['style_settings'][$panel];
}
return array($style, $style_settings);
}
/**
* Render a panel, by storing the content of each pane in an appropriate array
* and then passing through to the theme function that will render the panel
* in the configured panel style.
*
* @param $display
* A display object.
* @param $panel
* The ID of the panel being rendered
* @param $panes
* An array of panes that are assigned to the panel that's being rendered.
*
* @return
* The rendered HTML for a panel.
* @render
*/
function panels_render_panel($display, $panel, $panes) {
list($style, $style_settings) = panels_get_panel_style_and_settings($display->panel_settings, $panel);
// 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($display->owner) && is_object($display->owner) && isset($display->owner->id)) {
$owner_id = $display->owner->id;
}
return theme($style['render panel'], $display, $owner_id, $panes, $style_settings, $panel);
}
/**
* @file panels.theme.inc
* Core theme functions for Panels.
*/
/**
* Render a panel pane like a block.
*
* A panel pane can have the following fields:
*
* $pane->type -- the content type inside this pane
* $pane->subtype -- The subtype, if applicable. If a view it will be the
* view name; if a node it will be the nid, etc.
* $content->title -- The title of the content
* $content->content -- The actual content
* $content->links -- Any links associated with the content
* $content->more -- An optional 'more' link (destination only)
* $content->admin_links -- Administrative links associated with the content
* $content->feeds -- Any feed icons or associated with the content
* $content->subject -- A legacy setting for block compatibility
* $content->module -- A legacy setting for block compatibility
* $content->delta -- A legacy setting for block compatibility
*/
function theme_panels_pane($content, $pane, $display) {
if (!empty($content->content)) {
$idstr = $classstr = '';
if (!empty($content->css_id)) {
$idstr = ' id="' . $content->css_id . '"';
}
if (!empty($content->css_class)) {
$classstr = ' ' . $content->css_class;
}
$output = "<div class=\"panel-pane$classstr\"$idstr>\n";
if (user_access('view pane admin links') && !empty($content->admin_links)) {
$output .= "<div class=\"admin-links panel-hide\">" . theme('links', $content->admin_links) . "</div>\n";
}
if (!empty($content->title)) {
$output .= "<h2 class=\"title\">$content->title</h2>\n";
}
if (!empty($content->feeds)) {
$output .= "<div class=\"feed\">" . implode(' ', $content->feeds) . "</div>\n";
}
$output .= "<div class=\"content\">$content->content</div>\n";
if (!empty($content->links)) {
$output .= "<div class=\"links\">" . theme('links', $content->links) . "</div>\n";
}
if (!empty($content->more)) {
if (empty($content->more['title'])) {
$content->more['title'] = t('more');
}
$output .= "<div class=\"more-link\">" . l($content->more['title'], $content->more['href']) . "</div>\n";
}
$output .= "</div>\n";
return $output;
}
}