7 * An array of preprocessors to fill variables for templates and helper
8 * functions to make theming easier.
12 * Provide a full array of possible themes to try for a given hook.
15 * The hook to use. This is the base theme/template name.
17 * The view being rendered.
19 * The display being rendered, if applicable.
21 function _views_theme_functions($hook, $view, $display = NULL
) {
25 $themes[] = $hook .
'__' .
$view->name .
'__' .
$display->id
;
26 $themes[] = $hook .
'__' .
$display->id
;
27 if ($display->id
!= $display->display_plugin
) {
28 $themes[] = $hook .
'__' .
$view->name .
'__' .
$display->display_plugin
;
29 $themes[] = $hook .
'__' .
$display->display_plugin
;
32 $themes[] = $hook .
'__' .
$view->name
;
39 * Preprocess the primary theme implementation for a view.
41 function template_preprocess_views_view(&$vars) {
42 $view = $vars['view'];
44 $vars['rows'] = $view->style_handler
->render($view->result
);
45 $vars['css_name'] = views_css_safe($view->name
);
46 $vars['name'] = $view->name
;
47 $vars['display_id'] = $view->current_display
;
50 $vars['empty'] = $view->display_handler
->render_empty();
51 if (!$view->display_handler
->get_option('header_empty')) {
54 if (!$view->display_handler
->get_option('footer_empty')) {
63 $vars['exposed'] = !empty($view->exposed_widgets
) ?
$view->exposed_widgets
: '';
64 if (!isset($vars['header'])) {
65 $vars['header'] = $view->display_handler
->render_header();
67 if (!isset($vars['footer'])) {
68 $vars['footer'] = $view->display_handler
->render_footer();
70 $vars['more'] = $view->display_handler
->render_more_link();
71 $vars['feed_icon'] = !empty($view->feed_icon
) ?
$view->feed_icon
: '';
73 $vars['attachment_before'] = !empty($view->attachment_before
) ?
$view->attachment_before
: '';
74 $vars['attachment_after'] = !empty($view->attachment_after
) ?
$view->attachment_after
: '';
77 if (!empty($view->pager
['use_pager'])) {
78 $pager_type = $view->pager
['use_pager'] == 'mini' ?
'views_mini_pager' : 'pager';
79 $vars['pager'] = theme($pager_type, $view->exposed_input
, $view->pager
['items_per_page'], $view->pager
['element']);
82 // if administrator, add some links. These used to be tabs, but this is better.
83 if (user_access('administer views')) {
84 $vars['admin_links_raw'] = array(
87 'alt' => t("Edit this view"),
88 'href' => "admin/build/views/edit/$view->name",
89 'fragment' => 'views-tab-' .
$view->current_display
,
90 'query' => drupal_get_destination(),
93 'title' => t('Export'),
94 'alt' => t("Export this view"),
95 'href' => "admin/build/views/export/$view->name",
98 'title' => t('Clone'),
99 'alt' => t("Create a copy of this view"),
100 'href' => "admin/build/views/clone/$view->name",
103 $vars['admin_links'] = theme('links', $vars['admin_links_raw']);
106 $vars['admin_links'] = '';
107 $vars['admin_links_raw'] = array();
110 // If using AJAX, send identifying data about this view.
111 if ($view->use_ajax
) {
114 'ajax_path' => url('views/ajax'),
115 'ajaxViews' => array(
117 'view_name' => $view->name
,
118 'view_display_id' => $view->current_display
,
119 'view_args' => implode('/', $view->args
),
120 'view_path' => $_GET['q'],
126 drupal_add_js($settings, 'setting');
127 views_add_js('ajax_view');
132 * Preprocess theme function to print a single record from a row, with fields
134 function template_preprocess_views_view_fields(&$vars) {
135 $view = $vars['view'];
137 // Loop through the fields for this view.
138 foreach ($view->field as
$id => $field) {
139 if (!empty($field['handler']) && is_object($field['handler'])) {
140 $object = new
stdClass();
142 $object->content
= $field['handler']->theme($vars['row']);
143 if (isset($field['handler']->field_alias
) && isset($vars['row']->{$field['handler']->field_alias
})) {
144 $object->raw
= $vars['row']->{$field['handler']->field_alias
};
147 $object->raw
= NULL
; // make sure it exists to reduce NOTICE
150 $object->handler
= $field['handler'];
151 $object->class = views_css_safe($id);
152 $object->label
= check_plain($field['handler']->label());
153 $vars['fields'][$id] = $object;
160 * Display a single views field.
162 * Interesting bits of info:
163 * $field->field_alias says what the raw value in $row will be. Reach it like
164 * this: @code { $row->{$field->field_alias} @endcode
166 function theme_views_view_field($view, $field, $row) {
167 return $field->render($row);
171 * Preprocess theme function to print a single record from a row, with fields
173 function template_preprocess_views_view_summary(&$vars) {
174 $view = $vars['view'];
175 $argument = $view->argument
[$view->build_info
['summary_level']]['handler'];
177 foreach ($vars['rows'] as
$id => $row) {
178 $vars['rows'][$id]->link = $argument->summary_name($row);
179 $vars['rows'][$id]->url
= $argument->summary_link($row, $view->get_url());
180 $vars['rows'][$id]->count = intval($row->{$argument->count_alias
});
185 * Display a view as a table style.
187 function template_preprocess_views_view_table(&$vars) {
188 $view = $vars['view'];
189 $result = $view->result
;
190 $options = $view->style_handler
->options
;
191 $handler = $view->style_handler
;
193 $fields = $view->field
;
194 $columns = $handler->sanitize_columns($options['columns'], $fields);
196 $active = !empty($handler->active
) ?
$handler->active
: '';
197 $order = !empty($handler->order
) ?
$handler->order
: 'asc';
199 $query = tablesort_get_querystring();
201 $query = '&' .
$query;
204 foreach ($columns as
$field => $column) {
205 // render the header labels
206 if ($field == $column) {
207 $label = check_plain(!empty($fields[$field]['handler']) ?
$fields[$field]['handler']->label() : '');
208 if (empty($options['info'][$field]['sortable'])) {
209 $vars['header'][$field] = $label;
212 // @todo -- make this a setting
215 if ($active == $field && $order == 'asc') {
219 $image = theme('tablesort_indicator', $initial);
220 $title = t('sort by @s', array('@s' => $label));
221 $link_options = array(
223 'attributes' => array('title' => $title),
224 'query' => 'order=' .
urlencode($field) .
'&sort=' .
$initial .
$query,
226 $vars['header'][$field] = l($label .
$image, $_GET['q'], $link_options);
230 // Create a second variable so we can easily find what fields we have and what the
231 // CSS classes should be.
232 $vars['fields'][$field] = views_css_safe($field);
233 if ($active == $field) {
234 $vars['fields'][$field] .
= ' active';
237 // Render each field into its appropriate column.
238 foreach ($result as
$num => $row) {
239 if (!empty($fields[$field]['handler']) && is_object($fields[$field]['handler'])) {
240 $handler = &$fields[$field]['handler'];
241 $field_output = $handler->theme($row);
243 // Don't bother with separators and stuff if the field does not show up.
244 if (!$field_output) {
248 // Place the field into the column, along with an optional separator.
249 if (isset($vars['rows'][$num][$column])) {
250 if (!empty($options['info'][$column]['separator'])) {
251 $vars['rows'][$num][$column] .
= $options['info'][$column]['separator'];
255 $vars['rows'][$num][$column] = '';
258 $vars['rows'][$num][$column] .
= $field_output;
266 * Display a view as a grid style.
268 function template_preprocess_views_view_grid(&$vars) {
269 $view = $vars['view'];
270 $result = $view->result
;
271 $options = $view->style_handler
->options
;
272 $handler = $view->style_handler
;
274 $columns = $options['columns'];
278 if ($options['alignment'] == 'horizontal') {
280 foreach ($vars['rows'] as
$count => $item) {
282 if (($count + 1) %
$columns == 0) {
292 $num_rows = floor(count($vars['rows']) / $columns);
293 // The remainders are the 'odd' columns that are slightly longer.
294 $remainders = count($vars['rows']) %
$columns;
297 foreach ($vars['rows'] as
$count => $item) {
298 $rows[$row][$col] = $item;
301 if (!$remainders && $row == $num_rows) {
305 else if ($remainders && $row == $num_rows + 1) {
312 $vars['rows'] = $rows;
316 * Preprocess an RSS feed
318 function template_preprocess_views_view_rss(&$vars) {
322 $view = &$vars['view'];
323 $options = &$vars['options'];
324 $items = &$vars['rows'];
326 $style = &$view->style_handler
;
328 if (!empty($options['mission_description'])) {
329 $description = variable_get('site_mission', '');
332 $description = $options['description'];
335 // Figure out which display which has a path we're using for this feed. If there isn't
336 // one, use the global $base_url
337 $link_display = $view->display_handler
->get_link_display();
340 // Compare the link to the default home page; if it's the default home page, just use $base_url.
341 if (empty($vars['link'])) {
342 $vars['link'] = $base_url;
345 $vars['namespaces'] = drupal_attributes($style->namespaces
);
346 $vars['channel'] = format_rss_channel($view->get_title(), $vars['link'], $description, $items, $language->language
);
348 drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
352 * Default theme function for all filter forms.
354 function template_preprocess_views_exposed_form(&$vars) {
355 views_add_css('views');
356 $form = &$vars['form'];
358 // Put all single checkboxes together in the last spot.
361 if (!empty($form['q'])) {
362 $vars['q'] = drupal_render($form['q']);
365 $vars['widgets'] = array();
366 foreach ($form['#info'] as
$id => $info) {
367 // Set aside checkboxes.
368 if (isset($form[$info['value']]['#type']) && $form[$info['value']]['#type'] == 'checkbox') {
369 $checkboxes .
= drupal_render($form[$info['value']]);
372 $widget = new stdClass
;
373 // set up defaults so that there's always something there.
374 $widget->label
= $widget->operator
= $widget->widget
= NULL
;
376 if (!empty($info['label'])) {
377 $widget->label
= $info['label'];
379 if (!empty($info['operator'])) {
380 $widget->operator
= drupal_render($form[$info['operator']]);
382 $widget->widget
= drupal_render($form[$info['value']]);
383 $vars['widgets'][$id] = $widget;
386 // Wrap up all the checkboxes we set aside into a widget.
388 $widget = new stdClass
;
389 // set up defaults so that there's always something there.
390 $widget->label
= $widget->operator
= $widget->widget
= NULL
;
391 $widget->widget
= $checkboxes;
392 $vars['widgets']['checkboxes'] = $widget;
395 // Don't render these:
396 unset($form['form_id']);
397 unset($form['form_build_id']);
398 unset($form['form_token']);
400 // This includes the submit button.
401 $vars['button'] = drupal_render($form);
404 function theme_views_mini_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) {
405 global $pager_page_array, $pager_total;
407 // Calculate various markers within this pager piece:
408 // Middle is used to "center" pages around the current page.
409 $pager_middle = ceil($quantity / 2);
410 // current is the page we are currently paged to
411 $pager_current = $pager_page_array[$element] + 1;
412 // max is the maximum page number
413 $pager_max = $pager_total[$element];
414 // End of marker calculations.
417 $li_previous = theme('pager_previous', (isset($tags[1]) ?
$tags[1] : t('‹‹')), $limit, $element, 1, $parameters);
418 $li_next = theme('pager_next', (isset($tags[3]) ?
$tags[3] : t('››')), $limit, $element, 1, $parameters);
420 if ($pager_total[$element] > 1) {
422 'class' => 'pager-previous',
423 'data' => $li_previous,
427 'class' => 'pager-current',
428 'data' => t('@current of @max', array('@current' => $pager_current, '@max' => $pager_max)),
432 'class' => 'pager-next',
435 return theme('item_list', $items, NULL
, 'ul', array('class' => 'pager'));
440 * @defgroup views_templates Views' template files
442 * All views templates can be overridden with a variety of names, using
443 * the view, the display ID of the view, the display type of the view,
444 * or some combination thereof.
446 * For each view, there will be a minimum of two templates used. The first
447 * is used for all views: views-view.tpl.php.
449 * The second template is determined by the style selected for the view. Note
450 * that certain aspects of the view can also change which style is used; for
451 * example, arguments which provide a summary view might change the style to
452 * one of the special summary styles.
454 * The default style for all views is views-view-unformatted.tpl.php
456 * Many styles will then farm out the actual display of each row to a row
457 * style; the default row style is views-view-fields.tpl.php.
459 * Here is an example of all the templates that will be tried in the following
462 * View, named foobar. Style: unformatted. Row style: Fields. Display: Page.
464 * - views-view--page--foobar.tpl.php
465 * - views-view--page.tpl.php
466 * - views-view--foobar.tpl.php
467 * - views-view.tpl.php
469 * - views-view-unformatted--page--foobar.tpl.php
470 * - views-view-unformatted--page.tpl.php
471 * - views-view-unformatted--foobar.tpl.php
472 * - views-view-unformatted.tpl.php
474 * - views-view-fields--page--foobar.tpl.php
475 * - views-view-fields--page.tpl.php
476 * - views-view-fields--foobar.tpl.php
477 * - views-view-fields.tpl.php
479 * Important! When adding a new template to your theme, be sure to flush the
480 * theme registry cache! Simply visit admin/build/themes.
482 * @see _views_theme_functions