Skip to content

Instantly share code, notes, and snippets.

@tripflex
Created March 5, 2019 23:08
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tripflex/5ccb97ac0b76d355bceff5111803d7ea to your computer and use it in GitHub Desktop.
Save tripflex/5ccb97ac0b76d355bceff5111803d7ea to your computer and use it in GitHub Desktop.
Split string based on number of words, returning before and after (similar to wp_trim_words -- but passed words after instead of discarding)
<?php
if( ! function_exists( 'smyles_wp_split_words' ) ){
/**
* Split a string based on word count
*
* This is similar to WordPress wp_trim_words function, but instead of just trimming after a certain amount of
* words, this function returns an array with 'before' and 'after' keys -- providing you the string of text up
* to the number of words (in before key), and the words after (in the after key). After key will be empty string
* if there are less words in the passed string than number of words to split on.
*
*
* @param string $text
* @param int $num_words
*
* @return array Array with `before` and `after` keys. The `before` key contains all words up to $num_words, the
* `after` key contains the words after $num_words (or empty string if passed string has less words
* than passed in $text)
*
*/
function smyles_wp_split_words( $text, $num_words = 55 ) {
$text = wp_strip_all_tags( $text );
/*
* translators: If your word count is based on single characters (e.g. East Asian characters),
* enter 'characters_excluding_spaces' or 'characters_including_spaces'. Otherwise, enter 'words'.
* Do not translate into your own language.
*/
if ( strpos( _x( 'words', 'Word count type. Do not translate!' ), 'characters' ) === 0 && preg_match( '/^utf\-?8$/i', get_option( 'blog_charset' ) ) ) {
$text = trim( preg_replace( "/[\n\r\t ]+/", ' ', $text ), ' ' );
preg_match_all( '/./u', $text, $words_array_matches );
$words_array = $words_array_matches[0];
$sep = '';
} else {
$words_array = preg_split( "/[\n\r\t ]+/", $text, -1, PREG_SPLIT_NO_EMPTY );
$sep = ' ';
}
if ( count( $words_array ) > $num_words ) {
$before = implode( $sep, array_slice( $words_array, 0, $num_words ) );
$after = implode( $sep, array_slice( $words_array, $num_words, count( $words_array ) - 1 ) );
} else {
$before = implode( $sep, $words_array );
}
$results = array(
'before' => $before,
'after' => isset( $after ) ? $after : ''
);
return $results;
}
}
@trondhuso
Copy link

Wouldn't it be just easier to to return $text in 'before' rather than implode it? if I understand this function correctly, before shall return the string as it was before the function created an excerpt. Just a note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment