Created
March 5, 2019 23:08
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.