View source
<?php
define('SMART_TRIM_NEVER', 0);
define('SMART_TRIM_ALWAYS', 1);
define('SMART_TRIM_IFNEEDED', 2);
function smart_trim_field_formatter_info() {
return array(
'smart_trim_format' => array(
'label' => t('Smart trimmed'),
'field types' => array(
'text',
'text_long',
'text_with_summary',
),
'settings' => array(
'trim_length' => 300,
'trim_type' => 'chars',
'trim_suffix' => '...',
'trim_link' => FALSE,
'more_link' => SMART_TRIM_NEVER,
'more_text' => 'Read more',
'summary_handler' => 'full',
'trim_options' => array(),
'trim_preserve_tags' => '',
),
),
);
}
function smart_trim_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
$settings = $display['settings'];
switch ($display['type']) {
case 'smart_trim_format':
foreach ($items as $delta => $item) {
$break_pos = strpos($item['value'], '<!--break-->');
$has_summary_or_break = !empty($item['summary']) || $break_pos !== FALSE;
$honor_trim = empty($settings['summary_handler']) || $settings['summary_handler'] != 'full' ? TRUE : FALSE;
if (!empty($settings['summary_handler']) && $settings['summary_handler'] != 'ignore' && $has_summary_or_break) {
if (empty($item['summary'])) {
$output = check_markup(substr($item['value'], 0, $break_pos), $item['format'], $langcode, FALSE);
}
else {
$output = _text_sanitize($instance, $langcode, $item, 'summary');
}
}
else {
$output = _text_sanitize($instance, $langcode, $item, 'value');
}
if (!empty($settings['trim_options'])) {
if (!empty($settings['trim_options']['text'])) {
$preserve_tags = !empty($settings['trim_preserve_tags']) ? $settings['trim_preserve_tags'] : '';
$output = strip_tags(str_replace('<', ' <', $output), $preserve_tags);
$output = preg_replace('/\\n|\\r|\\t/m', ' ', $output);
$output = str_replace(' ', ' ', $output);
$output = str_replace(" ", ' ', $output);
$output = trim(preg_replace('/\\s\\s+/', ' ', $output));
}
}
$shortened = FALSE;
if ($honor_trim || $has_summary_or_break === FALSE) {
if ($settings['trim_type'] == 'words') {
if ($settings['trim_length'] < str_word_count($output)) {
$words = preg_split('/\\s/', $output, NULL, PREG_SPLIT_NO_EMPTY);
$output2 = implode(" ", array_slice($words, 0, $settings['trim_length']));
$output2 = _filter_htmlcorrector($output2);
}
else {
$output2 = $output;
}
}
else {
if (module_exists('views')) {
$output2 = views_trim_text(array(
'max_length' => $settings['trim_length'],
'word_boundary' => TRUE,
'ellipsis' => FALSE,
'html' => TRUE,
), $output);
}
else {
$output2 = text_summary($output, $instance['settings']['text_processing'] ? $item['format'] : NULL, $settings['trim_length']);
}
}
if (drupal_strlen(drupal_html_to_text($output)) != drupal_strlen(drupal_html_to_text($output2))) {
$shortened = TRUE;
}
$output = $output2;
}
$extension = '';
if ($shortened) {
$extension = filter_xss($settings['trim_suffix']);
}
if (substr($output, -1, 1) == '.' && substr($extension, 0, 1) == '.') {
$extension = substr($extension, 1);
}
$needs_more = FALSE;
switch ($settings['more_link']) {
case SMART_TRIM_ALWAYS:
$needs_more = TRUE;
break;
case SMART_TRIM_IFNEEDED:
if ($shortened) {
$needs_more = TRUE;
}
else {
if (!empty($item['summary']) && $settings['summary_handler'] != 'ignore') {
$summary_output = _text_sanitize($instance, $langcode, $item, 'summary');
$full_output = _text_sanitize($instance, $langcode, $item, 'value');
if (strcmp($summary_output, $full_output) != 0) {
$needs_more = TRUE;
}
}
}
break;
}
$uri = entity_uri($entity_type, $entity);
if ($uri && $needs_more) {
$extension .= l(t('@more_text', array(
'@more_text' => $settings['more_text'],
)), $uri['path'], array(
'html' => TRUE,
'attributes' => array(
'class' => array(
'more-link',
),
),
));
}
$output_appended = preg_replace('#^(.*)(\\s?)(</[^>]+>)$#Us', '$1' . $extension . '$3', $output);
if ($output_appended == $output) {
$output_appended = $output . $extension;
}
if (!empty($settings['trim_link']) && !empty($uri['path'])) {
$output_appended = strip_tags($output_appended);
$output = l($output_appended, $uri['path']);
$element[$delta] = array(
'#markup' => $output,
);
return $element;
}
$element[$delta] = array(
'#markup' => $output_appended,
);
}
break;
}
return $element;
}
function smart_trim_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
$settings = $instance['display'][$view_mode]['settings'];
$element = array();
$element['trim_link'] = array(
'#title' => t('Link text to'),
'#type' => 'select',
'#default_value' => $settings['trim_link'],
'#description' => t('Linking text to content will strip tags entirely from the trimmed text.'),
'#options' => array(
0 => t('Nothing'),
1 => t('Content'),
),
);
$element['trim_length'] = array(
'#title' => t('Trim length'),
'#type' => 'textfield',
'#size' => 10,
'#default_value' => $settings['trim_length'],
'#element_validate' => array(
'_element_validate_integer_positive',
),
'#required' => TRUE,
);
$element['trim_type'] = array(
'#title' => t('Trim units'),
'#type' => 'select',
'#options' => array(
'chars' => t("Characters"),
'words' => t("Words"),
),
'#default_value' => $settings['trim_type'],
);
$element['trim_suffix'] = array(
'#title' => t('Suffix'),
'#type' => 'textfield',
'#size' => 10,
'#default_value' => $settings['trim_suffix'],
);
$element['more_link'] = array(
'#title' => t('Display more link?'),
'#type' => 'select',
'#options' => array(
SMART_TRIM_NEVER => t('Never'),
SMART_TRIM_ALWAYS => t('Always'),
SMART_TRIM_IFNEEDED => t('If needed (when using a summary or trimmed text)'),
),
'#default_value' => $settings['more_link'],
'#description' => t('Displays a link to the entity (if one exists)'),
);
$element['more_text'] = array(
'#title' => t('More link text'),
'#type' => 'textfield',
'#size' => 20,
'#default_value' => $settings['more_text'],
'#description' => t('If displaying more link, enter the text for the link.'),
'#states' => array(
'invisible' => array(
':input[name="fields[body][settings_edit_form][settings][more_link]"]' => array(
'value' => SMART_TRIM_NEVER,
),
),
),
);
if ($field['type'] == 'text_with_summary') {
$element['summary_handler'] = array(
'#title' => t('Summary'),
'#type' => 'select',
'#options' => array(
'full' => t("Use summary if present, and do not trim"),
'trim' => t("Use summary if present, honor trim settings"),
'ignore' => t("Do not use summary"),
),
'#default_value' => $settings['summary_handler'],
);
}
$element['trim_options'] = array(
'#title' => t('Additional options'),
'#type' => 'checkboxes',
'#options' => array(
'text' => t('Strip HTML'),
),
'#default_value' => empty($settings['trim_options']) ? array() : $settings['trim_options'],
);
$element['trim_preserve_tags'] = array(
'#title' => t('Tags to preserve'),
'#description' => t('Which tags to preserve if "Strip HTML" is chosen above. Format as "<p><a>" to preserve p and a tags.'),
'#type' => 'textfield',
'#default_value' => $settings['trim_preserve_tags'],
);
return $element;
}
function smart_trim_field_formatter_settings_summary($field, $instance, $view_mode) {
$display = $instance['display'][$view_mode];
$settings = $display['settings'];
$summary = intval($settings['trim_length']) . ' ' . ($settings['trim_type'] == 'chars' ? t('characters') : t('words'));
if (drupal_strlen(trim($settings['trim_suffix']))) {
$summary .= " " . t("with suffix");
}
switch ($settings['more_link']) {
case SMART_TRIM_ALWAYS:
$summary .= ', ' . t('with more link (always)');
break;
case SMART_TRIM_IFNEEDED:
$summary .= ', ' . t('with more link (if needed)');
break;
}
if (isset($settings['trim_link'])) {
$summary .= $settings['trim_link'] == 1 ? ' ' . t('linked to content') : '';
}
return $summary;
}
function smart_trim_help($path, $arg) {
if ($path == 'admin/help#smart_trim') {
return '<p>' . t('This module creates a new text field formatter. There are no global configuration options.') . '</p>';
}
}