diff --git a/handlers/views_handler_field.inc b/handlers/views_handler_field.inc index 65210d9..f88b33d 100644 --- a/handlers/views_handler_field.inc +++ b/handlers/views_handler_field.inc @@ -30,6 +30,21 @@ define('VIEWS_HANDLER_RENDER_TEXT_PHASE_COMPLETELY', 1); define('VIEWS_HANDLER_RENDER_TEXT_PHASE_EMPTY', 2); /** + * Remove punctuation. + */ +define('VIEWS_HANDLER_PUNCTUATION_REMOVE', 0); + +/** + * Replace punctuation with the separator. + */ +define('VIEWS_HANDLER_PUNCTUATION_REPLACE', 1); + +/** + * Leave punctuation as it is. + */ +define('VIEWS_HANDLER_PUNCTUATION_DO_NOTHING', 2); + +/** * Base field handler that has no options and renders an unformatted field. * * Definition terms: @@ -331,6 +346,28 @@ class views_handler_field extends views_handler { if (!empty($this->options['alter']['trim_whitespace'])) { $value = trim($value); } + if (!empty($this->options['alter']['replace_punctuation'])) { + $actions = array(); + $punctuation = views_punctuation_chars(); + foreach ($punctuation as $name => $details) { + $action = $this->options['alter']['punctuation'][$name]; + switch ($action) { + case VIEWS_HANDLER_PUNCTUATION_REMOVE: + $actions[$details['value']] = ''; + break; + case VIEWS_HANDLER_PUNCTUATION_REPLACE: + $actions[$details['value']] = $this->options['alter']['separator']; + break; + case VIEWS_HANDLER_PUNCTUATION_DO_NOTHING: + // Literally do nothing. + break; + } + } + $value = strtr($value, $actions); + } + if (!empty($this->options['alter']['to_lowercase'])) { + $value = strtolower($value); + } } return $value; @@ -405,6 +442,10 @@ class views_handler_field extends views_handler { 'replace_spaces' => array('default' => FALSE, 'bool' => TRUE), 'path_case' => array('default' => 'none', 'translatable' => FALSE), 'trim_whitespace' => array('default' => FALSE, 'bool' => TRUE), + 'replace_punctuation' => array('default' => FALSE, 'bool' => TRUE), + 'separator' => array('default' => '-', 'translatable' => FALSE), + 'punctuation' => array('default' => '', 'translatable' => FALSE), + 'to_lowercase' => array('default' => FALSE, 'bool' => TRUE), 'alt' => array('default' => '', 'translatable' => TRUE), 'rel' => array('default' => ''), 'link_class' => array('default' => ''), @@ -945,6 +986,63 @@ If you would like to have the characters \'[\' and \']\' please use the html ent '#default_value' => $this->options['alter']['trim_whitespace'], ); + $form['alter']['replace_punctuation'] = array( + '#type' => 'checkbox', + '#title' => t('Replace punctuation'), + '#description' => t('If checked, punctuation will be replaced.'), + '#default_value' => $this->options['alter']['replace_punctuation'], + ); + + $form['alter']['separator'] = array( + '#type' => 'textfield', + '#title' => t('Separator'), + '#description' => t('This character will replace any spaces and punctuation characters.'), + '#default_value' => $this->options['alter']['separator'], + '#size' => 1, + '#maxlength' => 1, + '#dependency' => array( + 'edit-options-alter-replace-punctuation' => array(1), + ), + ); + + $form['alter']['punctuation'] = array( + '#type' => 'fieldset', + '#title' => t('Punctuation'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#dependency' => array( + 'edit-options-alter-replace-punctuation' => array(1), + ), + ); + + $punctuation = views_punctuation_chars(); + foreach ($punctuation as $name => $details) { + $details['default'] = VIEWS_HANDLER_PUNCTUATION_REMOVE; + if ($details['value'] == $this->options['alter']['replace_punctuation']) { + $details['default'] = VIEWS_HANDLER_PUNCTUATION_REPLACE; + } + if ($name == 'space') { + $details['default'] = VIEWS_HANDLER_PUNCTUATION_REPLACE; + } + $form['alter']['punctuation'][$name] = array( + '#type' => 'select', + '#title' => $details['name'] . ' (' . check_plain($details['value']) . ')', + '#default_value' => $this->options['alter']['punctuation'][$name], + '#options' => array( + VIEWS_HANDLER_PUNCTUATION_REMOVE => t('Remove'), + VIEWS_HANDLER_PUNCTUATION_REPLACE => t('Replace by separator'), + VIEWS_HANDLER_PUNCTUATION_DO_NOTHING => t('No action (do not replace)'), + ), + ); + } + + $form['alter']['to_lowercase'] = array( + '#type' => 'checkbox', + '#title' => t('Convert to lowercase'), + '#description' => t('If checked, the output will be converted to lowercase.'), + '#default_value' => $this->options['alter']['to_lowercase'], + ); + $form['alter']['nl2br'] = array( '#type' => 'checkbox', '#title' => t('Convert newlines to HTML <br> tags'), @@ -1136,6 +1234,30 @@ If you would like to have the characters \'[\' and \']\' please use the html ent $value = trim($value); } + if (!empty($this->options['alter']['replace_punctuation'])) { + $actions = array(); + $punctuation = views_punctuation_chars(); + foreach ($punctuation as $name => $details) { + $action = $this->options['alter']['punctuation'][$name]; + switch ($action) { + case VIEWS_HANDLER_PUNCTUATION_REMOVE: + $actions[$details['value']] = ''; + break; + case VIEWS_HANDLER_PUNCTUATION_REPLACE: + $actions[$details['value']] = $this->options['alter']['separator']; + break; + case VIEWS_HANDLER_PUNCTUATION_DO_NOTHING: + // Literally do nothing. + break; + } + } + $value = strtr($value, $actions); + } + + if (!empty($this->options['alter']['to_lowercase'])) { + $value = strtolower($value); + } + // Check if there should be no further rewrite for empty values. $no_rewrite_for_empty = $this->options['hide_alter_empty'] && $this->is_value_empty($this->original_value, $this->options['empty_zero']); diff --git a/tests/styles/views_plugin_style_jump_menu.test b/tests/styles/views_plugin_style_jump_menu.test index dd4eca0..41eac5f 100644 --- a/tests/styles/views_plugin_style_jump_menu.test +++ b/tests/styles/views_plugin_style_jump_menu.test @@ -120,6 +120,9 @@ class viewsPluginStyleJumpMenuTest extends ViewsSqlTest { $handler->display->display_options['fields']['nothing']['alter']['external'] = 0; $handler->display->display_options['fields']['nothing']['alter']['replace_spaces'] = 0; $handler->display->display_options['fields']['nothing']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['nothing']['alter']['separator'] = '-'; + $handler->display->display_options['fields']['nothing']['alter']['replace_punctuation'] = 0; + $handler->display->display_options['fields']['nothing']['alter']['to_lowercase'] = 0; $handler->display->display_options['fields']['nothing']['alter']['nl2br'] = 0; $handler->display->display_options['fields']['nothing']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['nothing']['alter']['ellipsis'] = 1; diff --git a/tests/user/views_user.test b/tests/user/views_user.test index 52c5026..3fa3186 100644 --- a/tests/user/views_user.test +++ b/tests/user/views_user.test @@ -102,6 +102,9 @@ class ViewsUserTestCase extends ViewsSqlTest { $handler->display->display_options['fields']['name']['alter']['external'] = 0; $handler->display->display_options['fields']['name']['alter']['replace_spaces'] = 0; $handler->display->display_options['fields']['name']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['name']['alter']['replace_punctuation'] = 0; + $handler->display->display_options['fields']['name']['alter']['separator'] = '-'; + $handler->display->display_options['fields']['name']['alter']['to_lowercase'] = 0; $handler->display->display_options['fields']['name']['alter']['nl2br'] = 0; $handler->display->display_options['fields']['name']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['name']['alter']['ellipsis'] = 1; @@ -125,6 +128,9 @@ class ViewsUserTestCase extends ViewsSqlTest { $handler->display->display_options['fields']['uid']['alter']['external'] = 0; $handler->display->display_options['fields']['uid']['alter']['replace_spaces'] = 0; $handler->display->display_options['fields']['uid']['alter']['trim_whitespace'] = 0; + $handler->display->display_options['fields']['uid']['alter']['replace_punctuation'] = 0; + $handler->display->display_options['fields']['uid']['alter']['separator'] = '-'; + $handler->display->display_options['fields']['uid']['alter']['to_lowercase'] = 0; $handler->display->display_options['fields']['uid']['alter']['nl2br'] = 0; $handler->display->display_options['fields']['uid']['alter']['word_boundary'] = 1; $handler->display->display_options['fields']['uid']['alter']['ellipsis'] = 1; diff --git a/views.module b/views.module index 9cdcfb5..2bcaf80 100644 --- a/views.module +++ b/views.module @@ -2453,6 +2453,70 @@ function views_trim_text($alter, $value) { } /** + * Return an array of arrays for punctuation values. + * + * Returns an array of arrays for punctuation values keyed by a name, including + * the value and a textual description. + * Can and should be expanded to include "all" non text punctuation values. + * + * @return + * An array of arrays for punctuation values keyed by a name, including the + * value and a textual description. + */ +function views_punctuation_chars() { + $punctuation = &drupal_static(__FUNCTION__); + + if (!isset($punctuation)) { + $cid = 'views:punctuation:' . $GLOBALS['language']->language; + if ($cache = cache_get($cid)) { + $punctuation = $cache->data; + } + else { + $punctuation = array(); + $punctuation['space'] = array('value' => ' ', 'name' => t('Space')); + $punctuation['double_quotes'] = array('value' => '"', 'name' => t('Double quotation marks')); + $punctuation['quotes'] = array('value' => '\'', 'name' => t("Single quotation marks (apostrophe)")); + $punctuation['backtick'] = array('value' => '`', 'name' => t('Back tick')); + $punctuation['comma'] = array('value' => ',', 'name' => t('Comma')); + $punctuation['period'] = array('value' => '.', 'name' => t('Period')); + $punctuation['hyphen'] = array('value' => '-', 'name' => t('Hyphen')); + $punctuation['underscore'] = array('value' => '_', 'name' => t('Underscore')); + $punctuation['colon'] = array('value' => ':', 'name' => t('Colon')); + $punctuation['semicolon'] = array('value' => ';', 'name' => t('Semicolon')); + $punctuation['pipe'] = array('value' => '|', 'name' => t('Vertical bar (pipe)')); + $punctuation['left_curly'] = array('value' => '{', 'name' => t('Left curly bracket')); + $punctuation['left_square'] = array('value' => '[', 'name' => t('Left square bracket')); + $punctuation['right_curly'] = array('value' => '}', 'name' => t('Right curly bracket')); + $punctuation['right_square'] = array('value' => ']', 'name' => t('Right square bracket')); + $punctuation['plus'] = array('value' => '+', 'name' => t('Plus sign')); + $punctuation['equal'] = array('value' => '=', 'name' => t('Equal sign')); + $punctuation['asterisk'] = array('value' => '*', 'name' => t('Asterisk')); + $punctuation['ampersand'] = array('value' => '&', 'name' => t('Ampersand')); + $punctuation['percent'] = array('value' => '%', 'name' => t('Percent sign')); + $punctuation['caret'] = array('value' => '^', 'name' => t('Caret')); + $punctuation['dollar'] = array('value' => '$', 'name' => t('Dollar sign')); + $punctuation['hash'] = array('value' => '#', 'name' => t('Number sign (pound sign, hash)')); + $punctuation['at'] = array('value' => '@', 'name' => t('At sign')); + $punctuation['exclamation'] = array('value' => '!', 'name' => t('Exclamation mark')); + $punctuation['tilde'] = array('value' => '~', 'name' => t('Tilde')); + $punctuation['left_parenthesis'] = array('value' => '(', 'name' => t('Left parenthesis')); + $punctuation['right_parenthesis'] = array('value' => ')', 'name' => t('Right parenthesis')); + $punctuation['question_mark'] = array('value' => '?', 'name' => t('Question mark')); + $punctuation['less_than'] = array('value' => '<', 'name' => t('Less-than sign')); + $punctuation['greater_than'] = array('value' => '>', 'name' => t('Greater-than sign')); + $punctuation['slash'] = array('value' => '/', 'name' => t('Slash')); + $punctuation['back_slash'] = array('value' => '\\', 'name' => t('Backslash')); + + // Allow modules to alter the punctuation list and cache the result. + drupal_alter('views_punctuation_chars', $punctuation); + cache_set($cid, $punctuation); + } + } + + return $punctuation; +} + +/** * Adds one to each key of the array. * * For example array(0 => 'foo') would be array(1 => 'foo').