? .bzr ? 357529-views_translatable-139.patch ? 635990-views_cache_respect_rewrite_substitutions-v3-3_0.patch ? 669636_0.patch ? 740686-semantic-views.patch ? 740686-semantic-views_1.patch ? 773036-bad-exposed-form-check-in-arguments.patch ? 776830-fix-use-pager-no-whitespace.patch ? 783798-fix-group_by-sort.patch ? 833790-fix-click-sort-on-formula-fields_0_0.patch ? 868990-set-use-pager-now-gone-in-views-3.patch ? 978864_add_area_item.patch ? 979046-views_access-2.patch ? 983460-table-default_sort.patch ? _983606.views_.tabs_on_export_results-D6.patch ? drupal.org files issues views_910864_0.txt ? multiple-views-pager_0.patch ? taxonomy_default_argument-2x-2-684608.patch ? views ? views-740686-semantic-views_0.patch ? views-date_now_form_validation-dev.patch ? views-links-2.patch ? modules/node/views-make-link-3.0-V2.patch Index: handlers/views_handler_field.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/handlers/views_handler_field.inc,v retrieving revision 1.14.2.46 diff -u -p -r1.14.2.46 views_handler_field.inc --- handlers/views_handler_field.inc 18 Nov 2010 23:34:47 -0000 1.14.2.46 +++ handlers/views_handler_field.inc 4 Dec 2010 00:13:44 -0000 @@ -142,9 +142,22 @@ class views_handler_field extends views_ } /** - * Return DIV or SPAN based upon the field's element type. + * Return an HTML element based upon the field's element type. */ - function element_type() { + function element_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_type'] === '0') { + return ''; + } + } + if ($this->options['element_type']) { + return check_plain($this->options['element_type']); + } + + if ($default_empty) { + return ''; + } + if (isset($this->definition['element type'])) { return $this->definition['element type']; } @@ -152,6 +165,121 @@ class views_handler_field extends views_ return 'span'; } + /** + * Return an HTML element for the label based upon the field's element type. + */ + function element_label_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_label_type'] === '0') { + return ''; + } + } + if ($this->options['element_label_type']) { + return check_plain($this->options['element_label_type']); + } + + if ($default_empty) { + return ''; + } + + return 'span'; + } + + /** + * Return an HTML element for the wrapper based upon the field's element type. + */ + function element_wrapper_type($none_supported = FALSE, $default_empty = FALSE) { + if ($none_supported) { + if ($this->options['element_wrapper_type'] === '0') { + return 0; + } + } + if ($this->options['element_wrapper_type']) { + return check_plain($this->options['element_wrapper_type']); + } + + if ($default_empty) { + return ''; + } + + return 'div'; + } + + /** + * Provide a list of elements valid for field HTML. + * + * This function can be overridden by fields that want more or fewer + * elements available, though this seems like it would be an incredibly + * rare occurence. + */ + function get_elements() { + return array( + '' => t('- Use default -'), + '0' => t('- None -'), + 'div' => t('DIV'), + 'span' => t('SPAN'), + 'h1' => t('H1'), + 'h2' => t('H2'), + 'h3' => t('H3'), + 'h4' => t('H4'), + 'h5' => t('H5'), + 'h6' => t('H6'), + 'p' => t('P'), + 'strong' => t('STRONG'), + 'em' => t('EM'), + ); + } + + /** + * Return the class of the field. + */ + function element_classes() { + $classes = $this->tokenize_value($this->options['element_class']); + return views_css_safe($classes); + } + + /** + * Replace a value with tokens from the last field. + * + * This function actually figures out which field was last and uses its + * tokens so they will all be available. + */ + function tokenize_value($value) { + if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) { + $fake_item = array( + 'alter_text' => TRUE, + 'text' => $value, + ); + + // Get tokens from the last field. + $last_field = end($this->view->field); + if (isset($last_field->last_tokens)) { + $tokens = $last_field->last_tokens; + } + else { + $tokens = $last_field->get_render_tokens($fake_item); + } + + $value = strip_tags($this->render_altered($fake_item, $tokens)); + } + + return $value; + } + + /** + * Return the class of the field's label. + */ + function element_label_classes() { + return views_css_safe($this->options['element_label_class']); + } + + /** + * Return the class of the field's wrapper. + */ + function element_wrapper_classes() { + return views_css_safe($this->options['element_wrapper_class']); + } + function option_definition() { $options = parent::option_definition(); @@ -177,6 +305,18 @@ class views_handler_field extends views_ 'html' => array('default' => FALSE), ), ); + $options['element_type'] = array('default' => ''); + $options['element_class'] = array('default' => ''); + + $options['element_label_type'] = array('default' => ''); + $options['element_label_class'] = array('default' => ''); + $options['element_label_colon'] = array('default' => TRUE); + + $options['element_wrapper_type'] = array('default' => ''); + $options['element_wrapper_class'] = array('default' => ''); + + $options['element_default_classes'] = array('default' => TRUE); + $options['empty'] = array('default' => '', 'translatable' => TRUE); $options['hide_empty'] = array('default' => FALSE); $options['empty_zero'] = array('default' => FALSE); @@ -191,17 +331,91 @@ class views_handler_field extends views_ function options_form(&$form, &$form_state) { parent::options_form($form, $form_state); + // Use prefix and suffix to fake a fieldset because we use #tree. + $form['style_prefix'] = array( + '#value' => '
', + ); + + $form['alter'] = array( + '#title' => t('Rewriting'), + '#type' => 'fieldset', ); if ($this->allow_advanced_render()) { @@ -411,6 +625,11 @@ If you would like to have the characters ); } + // Use prefix and suffix to fake a fieldset because we use #tree. + $form['empty_prefix'] = array( + '#value' => '', + ); + } /** @@ -703,6 +927,7 @@ If you would like to have the characters } } + $this->last_tokens = $tokens; return $tokens; } Index: includes/plugins.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/includes/plugins.inc,v retrieving revision 1.152.2.13 diff -u -p -r1.152.2.13 plugins.inc --- includes/plugins.inc 1 Dec 2010 00:02:05 -0000 1.152.2.13 +++ includes/plugins.inc 4 Dec 2010 00:13:45 -0000 @@ -96,6 +96,7 @@ function views_views_plugins() { 'handler' => 'views_plugin_style_default', 'theme' => 'views_view_unformatted', 'uses row plugin' => TRUE, + 'uses row class' => TRUE, 'uses grouping' => TRUE, 'uses options' => TRUE, 'type' => 'normal', @@ -107,6 +108,7 @@ function views_views_plugins() { 'handler' => 'views_plugin_style_list', 'theme' => 'views_view_list', 'uses row plugin' => TRUE, + 'uses row class' => TRUE, 'uses options' => TRUE, 'type' => 'normal', 'help topic' => 'style-list', @@ -117,6 +119,7 @@ function views_views_plugins() { 'handler' => 'views_plugin_style_grid', 'theme' => 'views_view_grid', 'uses row plugin' => TRUE, + 'uses row class' => TRUE, 'uses options' => TRUE, 'type' => 'normal', 'help topic' => 'style-grid', @@ -127,6 +130,7 @@ function views_views_plugins() { 'handler' => 'views_plugin_style_table', 'theme' => 'views_view_table', 'uses row plugin' => FALSE, + 'uses row class' => TRUE, 'uses fields' => TRUE, 'uses options' => TRUE, 'type' => 'normal', Index: plugins/views_plugin_row.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_row.inc,v retrieving revision 1.3.2.2 diff -u -p -r1.3.2.2 views_plugin_row.inc --- plugins/views_plugin_row.inc 28 Dec 2009 21:11:50 -0000 1.3.2.2 +++ plugins/views_plugin_row.inc 4 Dec 2010 00:13:45 -0000 @@ -132,7 +132,7 @@ class views_plugin_row extends views_plu * of some form, but not always. */ function render($row) { - return theme($this->theme_functions(), $this->view, $this->options, $row, $this->field_alias); + return theme($this->theme_functions(), $this->view, $this->options, $row, isset($this->field_alias) ? $this->field_alias : ''); } } Index: plugins/views_plugin_row_fields.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_row_fields.inc,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 views_plugin_row_fields.inc --- plugins/views_plugin_row_fields.inc 11 Mar 2010 00:06:14 -0000 1.1.2.2 +++ plugins/views_plugin_row_fields.inc 4 Dec 2010 00:13:45 -0000 @@ -27,6 +27,7 @@ class views_plugin_row_fields extends vi * Provide a form for setting options. */ function options_form(&$form, &$form_state) { + parent::options_form($form, $form_state); $options = $this->display->handler->get_field_labels(); if (empty($this->options['inline'])) { Index: plugins/views_plugin_style.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style.inc,v retrieving revision 1.5.2.11 diff -u -p -r1.5.2.11 views_plugin_style.inc --- plugins/views_plugin_style.inc 16 Nov 2010 01:03:44 -0000 1.5.2.11 +++ plugins/views_plugin_style.inc 4 Dec 2010 00:13:45 -0000 @@ -64,6 +64,13 @@ class views_plugin_style extends views_p } /** + * Return TRUE if this style also uses a row plugin. + */ + function uses_row_class() { + return !empty($this->definition['uses row class']); + } + + /** * Return TRUE if this style also uses fields. */ function uses_fields() { @@ -76,9 +83,58 @@ class views_plugin_style extends views_p return !empty($this->definition['uses fields']); } + /** + * Return TRUE if this style uses tokens. + * + * Used to ensure we don't fetch tokens when not needed for performance. + */ + function uses_tokens() { + if ($this->uses_row_class()) { + $class = $this->options['row_class']; + if (strpos($class, '[') !== FALSE || strpos($class, '!') !== FALSE || strpos($class, '%') !== FALSE) { + return TRUE; + } + } + } + + /** + * Return the token replaced row class for the specified row. + */ + function get_row_class($row_index) { + $class = $this->options['row_class']; + if ($this->uses_fields() && $this->view->field) { + $class = $this->tokenize_value($class, $row_index); + } + + return views_css_safe($class); + } + + /** + * Take a value and apply token replacement logic to it. + */ + function tokenize_value($value, $row_index) { + if (strpos($value, '[') !== FALSE || strpos($value, '!') !== FALSE || strpos($value, '%') !== FALSE) { + $fake_item = array( + 'alter_text' => TRUE, + 'text' => $value, + ); + + $tokens = $this->row_tokens[$row_index]; + // Grab a random field handler to perform the render. + $field = end($this->view->field); + $value = strip_tags($field->render_altered($fake_item, $tokens)); + } + + return $value; + } + function option_definition() { $options = parent::option_definition(); $options['grouping'] = array('default' => ''); + if ($this->uses_row_class()) { + $options['row_class'] = array('default' => ''); + } + return $options; } @@ -102,6 +158,19 @@ class views_plugin_style extends views_p ); } } + + if ($this->uses_row_class()) { + $form['row_class'] = array( + '#title' => t('Row class'), + '#description' => t('The class to provide on each row.'), + '#type' => 'textfield', + '#default_value' => $this->options['row_class'], + ); + + if ($this->uses_fields()) { + $form['row_class']['#description'] .= ' ' . t('You may use field tokens from as per the "Replacement patterns" used in "Rewrite the output of this field" for all fields.'); + } + } } /** @@ -221,6 +290,10 @@ class views_plugin_style extends views_p foreach ($keys as $id) { $this->rendered_fields[$count][$id] = $this->view->field[$id]->theme($row); } + + if ($this->uses_tokens()) { + $this->row_tokens[$count] = $this->view->field[$id]->get_render_tokens(array()); + } } unset($this->view->row_index); } Index: plugins/views_plugin_style_list.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/plugins/views_plugin_style_list.inc,v retrieving revision 1.1 diff -u -p -r1.1 views_plugin_style_list.inc --- plugins/views_plugin_style_list.inc 3 Sep 2008 19:21:30 -0000 1.1 +++ plugins/views_plugin_style_list.inc 4 Dec 2010 00:13:45 -0000 @@ -18,6 +18,8 @@ class views_plugin_style_list extends vi $options = parent::option_definition(); $options['type'] = array('default' => 'ul'); + $options['class'] = array('default' => ''); + $options['wrapper_class'] = array('default' => 'item-list'); return $options; } @@ -33,6 +35,20 @@ class views_plugin_style_list extends vi '#options' => array('ul' => t('Unordered list'), 'ol' => t('Ordered list')), '#default_value' => $this->options['type'], ); + $form['wrapper_class'] = array( + '#title' => t('Wrapper class'), + '#description' => t('The class to provide on the wrapper, outside the list.'), + '#type' => 'textfield', + '#size' => '30', + '#default_value' => $this->options['wrapper_class'], + ); + $form['class'] = array( + '#title' => t('List class'), + '#description' => t('The class to provide on the list element itself.'), + '#type' => 'textfield', + '#size' => '30', + '#default_value' => $this->options['class'], + ); } } Index: theme/theme.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/theme.inc,v retrieving revision 1.73.2.35 diff -u -p -r1.73.2.35 theme.inc --- theme/theme.inc 16 Nov 2010 00:23:17 -0000 1.73.2.35 +++ theme/theme.inc 4 Dec 2010 00:13:46 -0000 @@ -156,6 +156,30 @@ function template_preprocess_views_view_ $empty = $field_output !== 0 && empty($field_output); if (empty($field->options['exclude']) && (!$empty || (empty($field->options['hide_empty']) && empty($vars['options']['hide_empty'])))) { $object = new stdClass(); + $object->handler = &$view->field[$id]; + + $object->element_type = $object->handler->element_type(TRUE); + if ($object->element_type) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = 'field-content'; + } + + if ($classes = $object->handler->element_classes()) { + if ($class) { + $class .= ' '; + } + $class .= $classes; + } + + $field_output = '<' . $object->element_type . ' class="' . $class . '">' . $field_output . '' . $object->element_type . '>'; + } + + // Protect ourself somewhat for backward compatibility. This will prevent + // old templates from producing invalid HTML when no element type is selected. + if (empty($object->element_type)) { + $object->element_type = 'span'; + } $object->content = $field_output; if (isset($view->field[$id]->field_alias) && isset($vars['row']->{$view->field[$id]->field_alias})) { @@ -164,19 +188,73 @@ function template_preprocess_views_view_ 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']); } + $object->class = views_css_safe($id); + $object->inline = !empty($vars['options']['inline'][$id]); $inline = $object->inline; + $object->inline_html = $object->handler->element_wrapper_type(TRUE, TRUE); - $object->handler = &$view->field[$id]; - $object->element_type = $object->handler->element_type(); + if ($object->inline_html === '') { + $object->inline_html = $object->inline ? 'span' : 'div'; + } - $object->class = views_css_safe($id); + // Set up the wrapper HTML. + $object->wrapper_prefix = ''; + $object->wrapper_suffix = ''; + + if ($object->inline_html) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = "views-field views-field-" . $object->class; + } + + if ($classes = $object->handler->element_wrapper_classes()) { + if ($class) { + $class .= ' '; + } + $class .= ' ' . $classes; + } + + $object->wrapper_prefix = '<' . $object->inline_html; + if ($class) { + $object->wrapper_prefix .= ' class="' . $class . '"'; + } + $object->wrapper_prefix .= '>'; + $object->wrapper_suffix = '' . $object->inline_html . '>'; + } + + // Set up the label for the value and the HTML to make it easier + // on the template. $object->label = check_plain($view->field[$id]->label()); + $object->label_html = ''; + $object->element_label_type = $object->handler->element_label_type(TRUE); + if ($object->element_label_type && $object->label) { + $class = ''; + if ($object->handler->options['element_default_classes']) { + $class = 'views-label-' . $object->class; + } + + $element_label_class = $object->handler->element_label_classes(); + if ($element_label_class) { + if ($class) { + $class .= ' '; + } + + $class .= $element_label_class; + } + + $object->label_html = '<' . $object->element_label_type . ' class="' . $class . '">'; + $object->label_html .= $object->label; + if ($object->handler->options['element_label_colon']) { + $object->label_html .= ': '; + } + $object->label_html .= '' . $object->element_label_type . '>'; + } + $vars['fields'][$id] = $object; } } @@ -286,6 +364,7 @@ function template_preprocess_views_view_ // Store rows so that they may be used by further preprocess functions. $result = $vars['result'] = $vars['rows']; $vars['rows'] = array(); + $vars['field_classes'] = array(); $options = $view->style_plugin->options; $handler = $view->style_plugin; @@ -306,6 +385,13 @@ function template_preprocess_views_view_ $renders = $handler->render_fields($result); foreach ($columns as $field => $column) { + // Create a second variable so we can easily find what fields we have and what the + // CSS classes should be. + $vars['fields'][$field] = views_css_safe($field); + if ($active == $field) { + $vars['fields'][$field] .= ' active'; + } + // render the header labels if ($field == $column && empty($fields[$field]->options['exclude'])) { $label = check_plain(!empty($fields[$field]) ? $fields[$field]->label() : ''); @@ -330,13 +416,28 @@ function template_preprocess_views_view_ ); $vars['header'][$field] = l($label, $_GET['q'], $link_options); } - } - // Create a second variable so we can easily find what fields we have and what the - // CSS classes should be. - $vars['fields'][$field] = views_css_safe($field); - if ($active == $field) { - $vars['fields'][$field] .= ' active'; + $vars['header_classes'][$field] = ''; + // Set up the header label class. + if ($fields[$field]->options['element_default_classes']) { + $vars['header_classes'][$field] .= "views-field views-field-" . $vars['fields'][$field]; + } + $class = $fields[$field]->element_label_classes(); + if ($class) { + if ($vars['header_classes'][$field]) { + $vars['header_classes'][$field] .= ' '; + } + $vars['header_classes'][$field] .= $class; + } + + // Add a header label wrapper if one was selected. + if ($vars['header'][$field]) { + $element_label_type = $fields[$field]->element_label_type(TRUE, TRUE); + if ($element_label_type) { + $vars['header'][$field] = '<' . $element_label_type . '>' . $vars['header'][$field] . '' . $element_label_type . '>'; + } + } + } // Add a CSS align class to each field if one was set @@ -346,8 +447,25 @@ function template_preprocess_views_view_ // Render each field into its appropriate column. foreach ($result as $num => $row) { + // Add field classes + $vars['field_classes'][$field][$num] = ''; + if ($fields[$field]->options['element_default_classes']) { + $vars['field_classes'][$field][$num] = "views-field views-field-" . $vars['fields'][$field]; + } + if ($classes = $fields[$field]->element_classes()) { + if ($vars['field_classes'][$field][$num]) { + $vars['field_classes'][$field][$num] .= ' '; + } + + $vars['field_classes'][$field][$num] .= $classes; + } + if (!empty($fields[$field]) && empty($fields[$field]->options['exclude'])) { $field_output = $renders[$num][$field]; + $element_type = $fields[$field]->element_type(TRUE, TRUE); + if ($element_type) { + $field_output = '<' . $element_type . '>' . $field_output . '' . $element_type . '>'; + } // Don't bother with separators and stuff if the field does not show up. if (empty($field_output) && !empty($vars['rows'][$num][$column])) { @@ -372,6 +490,9 @@ function template_preprocess_views_view_ $count = 0; foreach ($vars['rows'] as $num => $row) { $vars['row_classes'][$num][] = ($count++ % 2 == 0) ? 'odd' : 'even'; + if ($row_class = $handler->get_row_class($num)) { + $vars['row_classes'][$num][] = $row_class; + } } $vars['row_classes'][0][] = 'views-row-first'; @@ -447,6 +568,27 @@ function template_preprocess_views_view_ } } } + + // Apply the row classes + foreach ($vars['rows'] as $row_number => $row) { + $row_classes = array(); + $row_classes[] = 'row-' . ($row_number + 1); + if ($row_number == 0) { + $row_classes[] = 'row-first'; + } + if (count($rows) == ($row_number + 1)) { + $row_classes[] = 'row-last'; + } + $vars['row_classes'][$row_number] = implode(' ', $row_classes); + foreach ($rows[$row_number] as $column_number => $item) { + $column_classes = array(); + $column_classes[] = 'col-'. ($column_number + 1); + if ($column_class = $view->style_plugin->get_row_class($column_number)) { + $column_classes[] = $column_class; + } + $vars['column_classes'][$row_number][$column_number] = implode(' ', $column_classes); + } + } $vars['rows'] = $rows; } @@ -470,6 +612,11 @@ function template_preprocess_views_view_ if ($id == count($rows) -1) { $row_classes[] = 'views-row-last'; } + + if ($row_class = $view->style_plugin->get_row_class($id)) { + $row_classes[] = $row_class; + } + // Flatten the classes to a string for each row for the template file. $vars['classes'][$id] = implode(' ', $row_classes); } @@ -479,6 +626,22 @@ function template_preprocess_views_view_ * Display the view as an HTML list element */ function template_preprocess_views_view_list(&$vars) { + $handler = $vars['view']->style_plugin; + + $vars['class'] = views_css_safe($handler->options['class']); + $vars['wrapper_class'] = views_css_safe($handler->options['wrapper_class']); + $vars['wrapper_prefix'] = ''; + $vars['wrapper_suffix'] = ''; + $vars['list_type_prefix'] = '<' . $handler->options['type'] . '>'; + $vars['list_type_suffix'] = '' . $handler->options['type'] . '>'; + if ($vars['wrapper_class']) { + $vars['wrapper_prefix'] = '+ | Index: theme/views-view-list.tpl.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/views/theme/views-view-list.tpl.php,v retrieving revision 1.3 diff -u -p -r1.3 views-view-list.tpl.php --- theme/views-view-list.tpl.php 30 Sep 2008 19:47:11 -0000 1.3 +++ theme/views-view-list.tpl.php 4 Dec 2010 00:13:46 -0000 @@ -9,13 +9,13 @@ * @ingroup views_templates */ ?> - | ||||
+ | @@ -32,7 +35,7 @@ $row): ?> | ||||
---|---|---|---|---|---|
+ |