' . t('About') . '';
$output .= '
' . t('The Text module allows you to create short and long text fields with optional summaries. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them. For more information, see the online documentation for the Text module.', [':field' => \Drupal::url('help.page', ['name' => 'field']), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#', ':text_documentation' => 'https://www.drupal.org/documentation/modules/text']) . '
';
$output .= '' . t('Uses') . '
';
$output .= '';
$output .= '- ' . t('Managing and displaying text fields') . '
';
$output .= '- ' . t('The settings and display of the text field can be configured separately. See the Field UI help for more information on how to manage fields and their display.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? \Drupal::url('help.page', ['name' => 'field_ui']) : '#']) . '
';
$output .= '- ' . t('Creating short text fields') . '
';
$output .= '- ' . t('If you choose Text (plain) or Text (formatted) as the field type on the Manage fields page, then a field with a single row is displayed. You can change the maximum text length in the Field settings when you set up the field.') . '
';
$output .= '- ' . t('Creating long text fields') . '
';
$output .= '- ' . t('If you choose Text (plain, long), Text (formatted, long), or Text (formatted, long, with summary) on the Manage fields page, then users can insert text of unlimited length. On the Manage form display page, you can set the number of rows that are displayed to users.') . '
';
$output .= '- ' . t('Trimming the text length') . '
';
$output .= '- ' . t('On the Manage display page you can choose to display a trimmed version of the text, and if so, where to cut off the text.') . '
';
$output .= '- ' . t('Displaying summaries instead of trimmed text') . '
';
$output .= '- ' . t('As an alternative to using a trimmed version of the text, you can enter a separate summary by choosing the Text (formatted, long, with summary) field type on the Manage fields page. Even when Summary input is enabled, and summaries are provided, you can display trimmed text nonetheless by choosing the appropriate format on the Manage display page.') . '
';
$output .= '- ' . t('Using text formats and editors') . '
';
$output .= '- ' . t('If you choose Text (plain) or Text (plain, long) you restrict the input to Plain text only. If you choose Text (formatted), Text (formatted, long), or Text (formatted, long with summary) you allow users to write formatted text. Which options are available to individual users depends on the settings on the Text formats and editors page.', [':formats' => \Drupal::url('filter.admin_overview')]) . '
';
$output .= '
';
return $output;
}
}
/**
* Generates a trimmed, formatted version of a text field value.
*
* If the end of the summary is not indicated using the delimiter
* then we generate the summary automatically, trying to end it at a sensible
* place such as the end of a paragraph, a line break, or the end of a sentence
* (in that order of preference).
*
* @param $text
* The content for which a summary will be generated.
* @param $format
* The format of the content. If the line break filter is present then we
* treat newlines embedded in $text as line breaks. If the htmlcorrector
* filter is present, it will be run on the generated summary (if different
* from the incoming $text).
* @param $size
* The desired character length of the summary. If omitted, the default value
* will be used. Ignored if the special delimiter is present in $text.
*
* @return
* The generated summary.
*/
function text_summary($text, $format = NULL, $size = NULL) {
if (!isset($size)) {
$size = \Drupal::config('text.settings')->get('default_summary_length');
}
// Find where the delimiter is in the body
$delimiter = strpos($text, '');
// If the size is zero, and there is no delimiter, the entire body is the summary.
if ($size == 0 && $delimiter === FALSE) {
return $text;
}
// If a valid delimiter has been specified, use it to chop off the summary.
if ($delimiter !== FALSE) {
return substr($text, 0, $delimiter);
}
// Retrieve the filters of the specified text format, if any.
if (isset($format)) {
$filters = FilterFormat::load($format)->filters();
// If the specified format does not exist, return nothing. $text is already
// filtered text, but the remainder of this function will not be able to
// ensure a sane and secure summary.
if (!$filters) {
return '';
}
}
// If we have a short body, the entire body is the summary.
if (Unicode::strlen($text) <= $size) {
return $text;
}
// If the delimiter has not been specified, try to split at paragraph or
// sentence boundaries.
// The summary may not be longer than maximum length specified. Initial slice.
$summary = Unicode::truncate($text, $size);
// Store the actual length of the UTF8 string -- which might not be the same
// as $size.
$max_rpos = strlen($summary);
// How much to cut off the end of the summary so that it doesn't end in the
// middle of a paragraph, sentence, or word.
// Initialize it to maximum in order to find the minimum.
$min_rpos = $max_rpos;
// Store the reverse of the summary. We use strpos on the reversed needle and
// haystack for speed and convenience.
$reversed = strrev($summary);
// Build an array of arrays of break points grouped by preference.
$break_points = [];
// A paragraph near the end of sliced summary is most preferable.
$break_points[] = ['' => 0];
// If no complete paragraph then treat line breaks as paragraphs.
$line_breaks = ['
' => 6, '
' => 4];
// Newline only indicates a line break if line break converter
// filter is present.
if (isset($format) && $filters->has('filter_autop') && $filters->get('filter_autop')->status) {
$line_breaks["\n"] = 1;
}
$break_points[] = $line_breaks;
// If the first paragraph is too long, split at the end of a sentence.
$break_points[] = ['. ' => 1, '! ' => 1, '? ' => 1, '。' => 0, '؟ ' => 1];
// Iterate over the groups of break points until a break point is found.
foreach ($break_points as $points) {
// Look for each break point, starting at the end of the summary.
foreach ($points as $point => $offset) {
// The summary is already reversed, but the break point isn't.
$rpos = strpos($reversed, strrev($point));
if ($rpos !== FALSE) {
$min_rpos = min($rpos + $offset, $min_rpos);
}
}
// If a break point was found in this group, slice and stop searching.
if ($min_rpos !== $max_rpos) {
// Don't slice with length 0. Length must be <0 to slice from RHS.
$summary = ($min_rpos === 0) ? $summary : substr($summary, 0, 0 - $min_rpos);
break;
}
}
// If the htmlcorrector filter is present, apply it to the generated summary.
if (isset($format) && $filters->has('filter_htmlcorrector') && $filters->get('filter_htmlcorrector')->status) {
$summary = Html::normalize($summary);
}
return $summary;
}