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) || !empty($view->style_plugin->definition['even empty']) ? $view->style_plugin->render($view->result) : '';
),
);
- drupal_alter('views_admin_links', $vars['admin_links_raw']);
+ 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.
'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.
$inline = FALSE;
$vars['fields'] = array(); // ensure it's at least an empty array.
foreach ($view->field as $id => $field) {
- if (empty($field->options['exclude'])) {
+ // 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 = $view->field[$id]->theme($vars['row']);
+ $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};
}
$inline = $object->inline;
- $object->handler = $view->field[$id];
+ $object->handler = &$view->field[$id];
+ $object->element_type = $object->handler->element_type();
+
$object->class = views_css_safe($id);
$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);
}
/**
*
* 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 pickedup.
+ * preprocess should get picked up.
*/
function template_preprocess_views_view_field(&$vars) {
- $vars['output'] = $vars['field']->render($vars['row']);
+ $vars['output'] = $vars['field']->advanced_render($vars['row']);
}
/**
// 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.
- $result = $vars['rows'];
+ // 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;
$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 && empty($fields[$field]->options['exclude'])) {
$label = check_plain(!empty($fields[$field]) ? $fields[$field]->label() : '');
- if (empty($options['info'][$field]['sortable'])) {
+ 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]) && empty($fields[$field]->options['exclude'])) {
- $field_output = $fields[$field]->theme($row);
+ $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');
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) {
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');
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
$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($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(