if ($display) {
$themes[] = $hook . '__' . $view->name . '__' . $display->id;
$themes[] = $hook . '__' . $display->id;
+ $themes[] = $hook . '__' . preg_replace('/[^a-z0-9]/', '-', strtolower($view->tag));
if ($display->id != $display->display_plugin) {
$themes[] = $hook . '__' . $view->name . '__' . $display->display_plugin;
$themes[] = $hook . '__' . $display->display_plugin;
}
$themes[] = $hook . '__' . $view->name;
$themes[] = $hook;
-
return $themes;
}
* Preprocess the primary theme implementation for a view.
*/
function template_preprocess_views_view(&$vars) {
+ global $base_path;
+
$view = $vars['view'];
- $vars['rows'] = !empty($view->result) ? $view->style_handler->render($view->result) : '';
+ $vars['rows'] = !empty($view->result) || !empty($view->style_plugin->definition['even empty']) ? $view->style_plugin->render($view->result) : '';
$vars['css_name'] = views_css_safe($view->name);
$vars['name'] = $view->name;
$vars['attachment_after'] = !empty($view->attachment_after) ? $view->attachment_after : '';
$vars['pager'] = '';
+
+ $exposed_input = isset($view->exposed_data_raw) ? $view->exposed_data_raw : NULL;
if (!empty($view->pager['use_pager'])) {
$pager_type = ($view->pager['use_pager'] === 'mini' ? 'views_mini_pager' : 'pager');
- $vars['pager'] = theme($pager_type, $view->exposed_input, $view->pager['items_per_page'], $view->pager['element']);
+ $pager_theme = views_theme_functions($pager_type, $view, $view->display_handler->display);
+ $vars['pager'] = theme($pager_theme, $exposed_input, $view->pager['items_per_page'], $view->pager['element']);
}
// if administrator, add some links. These used to be tabs, but this is better.
- if (user_access('administer views')) {
+ if (user_access('administer views') && module_exists('views_ui') && empty($view->hide_admin_links) && !variable_get('views_no_hover_links', FALSE)) {
$vars['admin_links_raw'] = array(
array(
'title' => t('Edit'),
'href' => "admin/build/views/clone/$view->name",
),
);
+
+ drupal_alter('views_admin_links', $vars['admin_links_raw'], $view);
$vars['admin_links'] = theme('links', $vars['admin_links_raw']);
- views_add_css('views');
}
else {
$vars['admin_links'] = '';
$vars['admin_links_raw'] = array();
}
+ views_add_css('views');
+
+ // Our JavaScript needs to have some means to find the HTML belonging to this
+ // view.
+ //
+ // It is true that the DIV wrapper has classes denoting the name of the view
+ // and its display ID, but this is not enough to unequivocally match a view
+ // with its HTML, because one view may appear several times on the page. So
+ // we set up a running counter, $dom_id, to issue a "unique" identifier for
+ // each view. This identifier is written to both Drupal.settings and the DIV
+ // wrapper.
+ static $dom_id = 1;
+ $vars['dom_id'] = !empty($view->dom_id) ? $view->dom_id : $dom_id++;
// If using AJAX, send identifying data about this view.
if ($view->use_ajax) {
'view_display_id' => $view->current_display,
'view_args' => implode('/', $view->args),
'view_path' => $_GET['q'],
+ // Pass through URL to ensure we get e.g. language prefixes.
+// 'view_base_path' => isset($view->display['page']) ? substr(url($view->display['page']->display_options['path']), strlen($base_path)) : '',
+ 'view_base_path' => $view->get_path(),
+ 'view_dom_id' => $vars['dom_id'],
+ // To fit multiple views on a page, the programmer may have
+ // overridden the display's pager_element.
+ 'pager_element' => $view->pager['element'],
),
),
),
$view = $vars['view'];
// Loop through the fields for this view.
+ $inline = FALSE;
+ $vars['fields'] = array(); // ensure it's at least an empty array.
foreach ($view->field as $id => $field) {
- if (!empty($field['handler']) && is_object($field['handler'])) {
+ // render this even if set to exclude so it can be used elsewhere.
+ $field_output = $view->field[$id]->theme($vars['row']);
+ $empty = $field_output !== 0 && empty($field_output);
+ if (empty($field->options['exclude']) && (!$empty || empty($field->options['hide_empty']))) {
$object = new stdClass();
- $object->content = $field['handler']->theme($vars['row']);
- if (isset($field['handler']->field_alias) && isset($vars['row']->{$field['handler']->field_alias})) {
- $object->raw = $vars['row']->{$field['handler']->field_alias};
+ $object->content = $field_output;
+ if (isset($view->field[$id]->field_alias) && isset($vars['row']->{$view->field[$id]->field_alias})) {
+ $object->raw = $vars['row']->{$view->field[$id]->field_alias};
}
else {
$object->raw = NULL; // make sure it exists to reduce NOTICE
}
+ $object->inline = !empty($vars['options']['inline'][$id]);
+ $object->inline_html = $object->inline ? 'span' : 'div';
+ if (!empty($vars['options']['separator']) && $inline && $object->inline && $object->content) {
+ $object->separator = filter_xss_admin($vars['options']['separator']);
+ }
+
+ $inline = $object->inline;
+
+ $object->handler = &$view->field[$id];
+ $object->element_type = $object->handler->element_type();
- $object->handler = $field['handler'];
$object->class = views_css_safe($id);
- $object->label = check_plain($field['handler']->label());
+ $object->label = check_plain($view->field[$id]->label());
$vars['fields'][$id] = $object;
}
}
* this: @code { $row->{$field->field_alias} @endcode
*/
function theme_views_view_field($view, $field, $row) {
- return $field->render($row);
+ return $field->advanced_render($row);
+}
+
+/**
+ * Process a single field within a view.
+ *
+ * This preprocess function isn't normally run, as a function is used by
+ * default, for performance. However, by creating a template, this
+ * preprocess should get picked up.
+ */
+function template_preprocess_views_view_field(&$vars) {
+ $vars['output'] = $vars['field']->advanced_render($vars['row']);
}
/**
*/
function template_preprocess_views_view_summary(&$vars) {
$view = $vars['view'];
- $argument = $view->argument[$view->build_info['summary_level']]['handler'];
+ $argument = $view->argument[$view->build_info['summary_level']];
+ $url_options = array();
+
+ if (!empty($view->exposed_raw_input)) {
+ $url_options['query'] = $view->exposed_raw_input;
+ }
foreach ($vars['rows'] as $id => $row) {
$vars['rows'][$id]->link = $argument->summary_name($row);
- $vars['rows'][$id]->url = $argument->summary_link($row, $view->get_url());
+ $args = $view->args;
+ $args[$argument->position] = $argument->summary_argument($row);
+
+ $vars['rows'][$id]->url = url($view->get_url($args), $url_options);
+ $vars['rows'][$id]->count = intval($row->{$argument->count_alias});
+ }
+}
+
+/**
+ * Template preprocess theme function to print summary basically
+ * unformatted.
+ */
+function template_preprocess_views_view_summary_unformatted(&$vars) {
+ $view = $vars['view'];
+ $argument = $view->argument[$view->build_info['summary_level']];
+
+ $url_options = array();
+
+ if (!empty($view->exposed_raw_input)) {
+ $url_options['query'] = $view->exposed_raw_input;
+ }
+
+ $count = 0;
+ foreach ($vars['rows'] as $id => $row) {
+ // only false on first time:
+ if ($count++) {
+ $vars['rows'][$id]->separator = filter_xss_admin($vars['options']['separator']);
+ }
+ $vars['rows'][$id]->link = $argument->summary_name($row);
+ $args = $view->args;
+ $args[$argument->position] = $argument->summary_argument($row);
+
+ $vars['rows'][$id]->url = url($view->get_url($args), $url_options);
$vars['rows'][$id]->count = intval($row->{$argument->count_alias});
}
}
*/
function template_preprocess_views_view_table(&$vars) {
$view = $vars['view'];
- $result = $view->result;
- $options = $view->style_handler->options;
- $handler = $view->style_handler;
- $fields = $view->field;
+ // We need the raw data for this grouping, which is passed in as $vars['rows'].
+ // However, the template also needs to use for the rendered fields. We
+ // therefore swap the raw data out to a new variable and reset $vars['rows']
+ // so that it can get rebuilt.
+ // Store rows so that they may be used by further preprocess functions.
+ $result = $vars['result'] = $vars['rows'];
+ $vars['rows'] = array();
+
+ $options = $view->style_plugin->options;
+ $handler = $view->style_plugin;
+
+ $fields = &$view->field;
$columns = $handler->sanitize_columns($options['columns'], $fields);
$active = !empty($handler->active) ? $handler->active : '';
$query = '&' . $query;
}
+ // Fields must be rendered in order as of Views 2.3, so we will pre-render
+ // everything.
+ $renders = array();
+ $view->row_index = 0;
+ $keys = array_keys($view->field);
+ foreach ($result as $count => $row) {
+ foreach ($keys as $id) {
+ $renders[$count][$id] = $view->field[$id]->theme($row);
+ }
+ $view->row_index = $count;
+ }
+ unset($view->row_index);
+
foreach ($columns as $field => $column) {
// render the header labels
- if ($field == $column) {
- $label = check_plain(!empty($fields[$field]['handler']) ? $fields[$field]['handler']->label() : '');
- if (empty($options['info'][$field]['sortable'])) {
+ if ($field == $column && empty($fields[$field]->options['exclude'])) {
+ $label = check_plain(!empty($fields[$field]) ? $fields[$field]->label() : '');
+ if (empty($options['info'][$field]['sortable']) || !$fields[$field]->click_sortable()) {
$vars['header'][$field] = $label;
}
else {
$initial = 'desc';
}
- $image = theme('tablesort_indicator', $initial);
$title = t('sort by @s', array('@s' => $label));
+ if ($active == $field) {
+ $label .= theme('tablesort_indicator', $initial);
+ }
$link_options = array(
'html' => true,
'attributes' => array('title' => $title),
'query' => 'order=' . urlencode($field) . '&sort=' . $initial . $query,
);
- $vars['header'][$field] = l($label . $image, $_GET['q'], $link_options);
+ $vars['header'][$field] = l($label, $_GET['q'], $link_options);
}
}
// Render each field into its appropriate column.
foreach ($result as $num => $row) {
- if (!empty($fields[$field]['handler']) && is_object($fields[$field]['handler'])) {
- $handler = &$fields[$field]['handler'];
- $field_output = $handler->theme($row);
+ if (!empty($fields[$field]) && empty($fields[$field]->options['exclude'])) {
+ $field_output = $renders[$num][$field];
+
+ if (!isset($vars['rows'][$num][$column])) {
+ $vars['rows'][$num][$column] = '';
+ }
// Don't bother with separators and stuff if the field does not show up.
- if (!isset($field_output) && isset($vars['rows'][$num][$column])) {
+ if ($field_output === '') {
continue;
}
// Place the field into the column, along with an optional separator.
- if (isset($vars['rows'][$num][$column])) {
+ if ($vars['rows'][$num][$column] !== '') {
if (!empty($options['info'][$column]['separator'])) {
$vars['rows'][$num][$column] .= filter_xss_admin($options['info'][$column]['separator']);
}
}
- else {
- $vars['rows'][$num][$column] = '';
- }
$vars['rows'][$num][$column] .= $field_output;
}
}
}
+
+ foreach ($vars['rows'] as $num => $row) {
+ $vars['row_classes'][$num][] = ($num % 2 == 0) ? 'odd' : 'even';
+ }
+
+ $vars['row_classes'][0][] = 'views-row-first';
+ $vars['row_classes'][count($vars['row_classes']) - 1][] = 'views-row-last';
+
+ $vars['class'] = 'views-table';
+ if (!empty($options['sticky'])) {
+ drupal_add_js('misc/tableheader.js');
+ $vars['class'] .= " sticky-enabled";
+ }
}
/**
function template_preprocess_views_view_grid(&$vars) {
$view = $vars['view'];
$result = $view->result;
- $options = $view->style_handler->options;
- $handler = $view->style_handler;
+ $options = $view->style_plugin->options;
+ $handler = $view->style_plugin;
$columns = $options['columns'];
if ($options['alignment'] == 'horizontal') {
$row = array();
+ $row_count = 0;
foreach ($vars['rows'] as $count => $item) {
$row[] = $item;
+ $row_count++;
if (($count + 1) % $columns == 0) {
$rows[] = $row;
$row = array();
+ $row_count = 0;
}
}
if ($row) {
+ // Fill up the last line.
+ for ($i = 0; $i < ($columns - $row_count); $i++) {
+ $row[] = '';
+ }
$rows[] = $row;
}
}
$remainders--;
}
}
+ for ($i = 0; $i < count($rows[0]); $i++) {
+ // This should be string so that's okay :)
+ if (!isset($rows[count($rows) - 1][$i])) {
+ $rows[count($rows) - 1][$i] = '';
+ }
+ }
}
$vars['rows'] = $rows;
}
/**
+ * Display the simple view of rows one after another
+ */
+function template_preprocess_views_view_unformatted(&$vars) {
+ $view = $vars['view'];
+ $rows = $vars['rows'];
+
+ $vars['classes'] = array();
+ // Set up striping values.
+ foreach ($rows as $id => $row) {
+ $vars['classes'][$id] = 'views-row';
+ $vars['classes'][$id] .= ' views-row-' . ($id + 1);
+ $vars['classes'][$id] .= ' views-row-' . ($id % 2 ? 'even' : 'odd');
+ if ($id == 0) {
+ $vars['classes'][$id] .= ' views-row-first';
+ }
+ }
+ $vars['classes'][$id] .= ' views-row-last';
+}
+
+/**
+ * Display the view as an HTML list element
+ */
+function template_preprocess_views_view_list(&$vars) {
+ template_preprocess_views_view_unformatted($vars);
+}
+
+/**
* Preprocess an RSS feed
*/
function template_preprocess_views_view_rss(&$vars) {
$options = &$vars['options'];
$items = &$vars['rows'];
- $style = &$view->style_handler;
+ $style = &$view->style_plugin;
if (!empty($options['mission_description'])) {
$description = variable_get('site_mission', '');
else {
$description = $options['description'];
}
+ // The RSS 2.0 "spec" doesn't indicate HTML can be used in the description.
+ // We strip all HTML tags, but need to prevent double encoding from properly
+ // escaped source data (such as & becoming &amp;).
+ $vars['description'] = check_plain(decode_entities(strip_tags($description)));
+
+ if ($view->display_handler->get_option('sitename_title')) {
+ $title = variable_get('site_name', 'Drupal');
+ if ($slogan = variable_get('site_slogan', '')) {
+ $title .= ' - ' . $slogan;
+ }
+ }
+ else {
+ $title = $view->get_title();
+ }
+ $vars['title'] = check_plain($title);
// Figure out which display which has a path we're using for this feed. If there isn't
// one, use the global $base_url
- $link_display = $view->display_handler->get_link_display();
+ $link_display_id = $view->display_handler->get_link_display();
+ if ($link_display_id && !empty($view->display[$link_display_id])) {
+ $path = $view->display[$link_display_id]->handler->get_path();
+ }
+ if ($path) {
+ $path = $view->get_url(NULL, $path);
+ $url_options = array('absolute' => TRUE);
+ if (!empty($view->exposed_raw_input)) {
+ $url_options['query'] = $view->exposed_raw_input;
+ }
+
+ // Compare the link to the default home page; if it's the default home page, just use $base_url.
+ if ($path == variable_get('site_frontpage', 'node')) {
+ $path = '';
+ }
- // Compare the link to the default home page; if it's the default home page, just use $base_url.
- if (empty($vars['link'])) {
- $vars['link'] = $base_url;
+ $vars['link'] = check_url(url($path, $url_options));
}
+ $vars['langcode'] = check_plain($language->language);
$vars['namespaces'] = drupal_attributes($style->namespaces);
- $vars['channel'] = format_rss_channel($view->get_title(), $vars['link'], $description, $items, $language->language);
+ $vars['items'] = $items;
+ $vars['channel_elements'] = format_xml_elements($style->channel_elements);
drupal_set_header('Content-Type: application/rss+xml; charset=utf-8');
}
/**
+ * Default theme function for all RSS rows.
+ */
+function template_preprocess_views_view_row_rss(&$vars) {
+ $view = &$vars['view'];
+ $options = &$vars['options'];
+ $item = &$vars['row'];
+
+ $vars['title'] = check_plain($item->title);
+ $vars['link'] = check_url($item->link);
+ $vars['description'] = check_plain($item->description);
+ $vars['item_elements'] = empty($item->elements) ? '' : format_xml_elements($item->elements);
+}
+
+/**
* Default theme function for all filter forms.
*/
function template_preprocess_views_exposed_form(&$vars) {
$li_previous = theme('pager_previous', (isset($tags[1]) ? $tags[1] : t('‹‹')), $limit, $element, 1, $parameters);
+ if (empty($li_previous)) {
+ $li_previous = " ";
+ }
+
$li_next = theme('pager_next', (isset($tags[3]) ? $tags[3] : t('››')), $limit, $element, 1, $parameters);
+ if (empty($li_next)) {
+ $li_next = " ";
+ }
if ($pager_total[$element] > 1) {
$items[] = array(
*
* View, named foobar. Style: unformatted. Row style: Fields. Display: Page.
*
- * - views-view--page--foobar.tpl.php
+ * - views-view--foobar--page.tpl.php
* - views-view--page.tpl.php
* - views-view--foobar.tpl.php
* - views-view.tpl.php
*
- * - views-view-unformatted--page--foobar.tpl.php
+ * - views-view-unformatted--foobar--page.tpl.php
* - views-view-unformatted--page.tpl.php
* - views-view-unformatted--foobar.tpl.php
* - views-view-unformatted.tpl.php
*
- * - views-view-fields--page--foobar.tpl.php
+ * - views-view-fields--foobar--page.tpl.php
* - views-view-fields--page.tpl.php
* - views-view-fields--foobar.tpl.php
* - views-view-fields.tpl.php
*
* Important! When adding a new template to your theme, be sure to flush the
- * theme registry cache! Simply visit admin/build/themes.
+ * theme registry cache!
*
* @see _views_theme_functions
* @}