Usage
nebula()->excerpt($options)
Parameters
$options
(Optional) (Array) An array of options.
Default: See below
Parameter Notes
id
An ID to pull the text from. This can be passed as a string or int. A WP_Post object could also be passed here instead.
Default: Current post ID
text
The text to shorten. If an ID is passed this uses that post’s excerpt or content.
Default: Post excerpt/content
characters
The maximum number of characters.
Default: false
words
The maximum length of the text in words.
Default: 55
length
Used for dynamic length by passing “dynamic”, otherwise an alias of “words”.
Default: false
min
The minimum length of a dynamic sentence.
Default: 0
ellipsis
Whether or not to add an ellipsis to shorten text.
Default: false
url
The URL to link to. If the “more” option is set (including default value), the link uses the permalink of the post.
Default: Post permalink
wp_more
Listen for the <!--more-->
tag within the post. This tag can override the more parameter by using: <!--more Keep Reading-->
Default: true
more
The text that is linked to the URL after the excerpt.
Default: “Read More »”
button
Turn the “more” text into a button (rather than just a link).
Default: false
strip_shortcodes
Whether to strip WordPress shortcodes from the excerpt.
Default: true
strip_tags
Whether to strip HTML tags from the excerpt.
Default: true
wrap_links
Wrap URLs in <a>
tags.
Default: false
Examples
Inside the loop (or outside the loop for current post/page)
<?php echo nebula()->excerpt(array('length' => 20, 'ellipsis' => true)); ?>
Outside the loop
<?php echo nebula()->excerpt(array('id' => 572, 'length' => 20, 'ellipsis' => true)); ?>
Custom excerpt
<?php echo nebula()->excerpt(array('text' => 'Lorem ipsum <strong>dolor</strong> sit amet.', 'more' => 'Continue »', 'length' => 3, 'ellipsis' => true, 'strip_tags' => true)); ?>
Using an ACF field
<?php echo nebula()->excerpt(array('text' => get_field('some_text_field', 33), 'length' => 50, 'ellipsis' => false, 'more' => false)); ?>
Use as a meta description ending with a sentence
<?php echo nebula()->excerpt(array('length' => 'dynamic', 'characters' => 160, 'more' => '', 'ellipsis' => false, 'strip_tags' => true)); ?>
Source File
Located in /libs/Functions.php on line 820.
2 Hooks
Find these filters and actions in the source code below to hook into them. Use do_action() and add_filter() in your functions file or plugin.
Filters
"pre_nebula_excerpt""nebula_excerpt_defaults"
Need a new filter hook? Request one here.
Actions
This function has no action hooks available. Request one?Note: This function contains 1 to-do comment.
public function excerpt($options=array()){ $override = apply_filters('pre_nebula_excerpt', null, $options); if ( isset($override) ){return $override;} $defaults = apply_filters('nebula_excerpt_defaults', array( 'id' => false, 'text' => false, 'paragraphs' => false, //Allow paragraph tags in the excerpt //@todo "Nebula" 0: currently not working 'characters' => false, 'words' => get_theme_mod('nebula_excerpt_length', 55), 'length' => false, //Used for dynamic length, otherwise an alias of "words" 'min' => 0, //Minimum length of dynamic sentence 'ellipsis' => false, 'url' => false, 'more' => get_theme_mod('nebula_excerpt_more_text', __('Read More', 'nebula') . ' »'), 'wp_more' => true, //Listen for the WP more tag 'btn' => false, //Alias of "button" 'button' => false, 'strip_shortcodes' => true, 'strip_tags' => true, 'wrap_links' => false, 'shorten_urls' => false, //Currently only works with wrap_links )); $data = array_merge($defaults, $options); //Establish text if ( empty($data['text']) ){ if ( !empty($data['id']) ){ if ( is_object($data['id']) && get_class($data['id']) == 'WP_Post' ){ //If we already have a WP_Post class object $the_post = $data['id']; } elseif ( intval($data['id']) ){ //If an ID is passed $the_post = get_post(intval($data['id'])); } } else { $the_post = get_post(get_the_ID()); } if ( empty($the_post) ){ return false; } if ( !empty($the_post->post_excerpt) ){ $data['text'] = $the_post->post_excerpt; } else { $data['text'] = $the_post->post_content; if ( $data['wp_more'] ){ $wp_more_split = get_extended($the_post->post_content); //Split the content on the WordPress <!--more--> tag $data['text'] = $wp_more_split['main']; if ( preg_match('/<!--more(.*?)?-->/', $the_post->post_content, $matches) ){ //Get the custom <!--more Keep Reading--> text. RegEx from: https://core.trac.wordpress.org/browser/tags/4.8/src/wp-includes/post-template.php#L288 if ( !empty($matches[1]) ){ $data['more'] = strip_tags(wp_kses_no_null(trim($matches[1]))); } } } } } //Strip Newlines $data['text'] = str_replace(array("\r\n", "\r", "\n"), " ", $data['text']); //Replace newline characters (keep double quotes) $data['text'] = preg_replace('/\s+/', ' ', $data['text']); //Replace multiple spaces with single space //Strip Shortcodes if ( $data['strip_shortcodes'] ){ $data['text'] = strip_shortcodes($data['text']); } else { $data['text'] = preg_replace('~(?:\[/?)[^/\]]+/?\]~s', ' ', $data['text']); } //Strip Tags if ( $data['strip_tags'] ){ $allowable_tags = ( !empty($data['paragraphs']) )? 'p' : ''; $data['text'] = strip_tags($data['text'], $allowable_tags); } //Apply string limiters (words or characters) if ( !empty($data['characters']) && intval($data['characters']) ){ //Characters $limited = $this->string_limit_chars($data['text'], intval($data['characters'])); //Returns array: $limited['text'] is the string, $limited['is_limited'] is boolean if it was limited or not. $data['text'] = trim($limited['text']); } elseif ( (!empty($data['words']) && intval($data['words'])) || (!empty($data['length']) && intval($data['length'])) ){ //Words (or Length) $word_limit = ( !empty($data['length']) && intval($data['length']) )? intval($data['length']) : intval($data['words']); $limited = $this->string_limit_words($data['text'], $word_limit); //Returns array: $limited['text'] is the string, $limited['is_limited'] is boolean if it was limited or not. $data['text'] = trim($limited['text']); } //Apply dynamic sentence length limiter if ( $data['length'] === 'dynamic' ){ $last_punctuation = -1; foreach ( array('.', '?', '!') as $punctuation ){ if ( strrpos($data['text'] . ' ', $punctuation . ' ') ){ $this_punctuation = strrpos($data['text'] . ' ', $punctuation . ' ')+1; //Find the last punctuation (add a space to the end of the string in case it already ends at the punctuation). Add 1 to capture the punctuation, too. if ( $this_punctuation > $last_punctuation ){ $last_punctuation = $this_punctuation; } } } if ( $last_punctuation >= $data['min'] ){ $data['text'] = substr($data['text'], 0, $last_punctuation); //Remove everything after the last punctuation in the string. } } //Check here for links to wrap if ( $data['wrap_links'] ){ $data['text'] = preg_replace('/(\(?(?:(http|https|ftp):\/\/)?(?:((?:[^\W\s]|\.|-|[:]{1})+)@{1})?((?:www.)?(?:[^\W\s]|\.|-)+[\.][^\W\s]{2,4}|localhost(?=\/)|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?::(\d*))?([\/]?[^\s\?]*[\/]{1})*(?:\/?([^\s\n\?\[\]\{\}\#]*(?:(?=\.)){1}|[^\s\n\?\[\]\{\}\.\#]*)?([\.]{1}[^\s\?\#]*)?)?(?:\?{1}([^\s\n\#\[\]]*))?([\#][^\s\n]*)?\)?)(?![^<]*<\/)/i', '<a class="nebula-excerpt-url" href="$1">$1</a>', $data['text']); //Capture any URL not within < and </ using a negative lookahead (so it plays nice in case strip_tags is false) } //Shorten visible URL text if ( $data['shorten_urls'] ){ $data['text'] = preg_replace_callback('/(<a.+>)(.+)(<\/a>)/', function($matches){ $output = $matches[1]; if ( strlen($matches[2]) > 20 ){ $short_url = str_replace(array('http://', 'https://'), '', $matches[2]); $url_directories = explode('/', $short_url); $short_url = $url_directories[0]; if ( count($url_directories) > 1 ){ $short_url .= '/...'; } $output .= $short_url; } else { $output .= $matches[2]; } $output .= $matches[3]; return $output; }, $data['text']); } //Ellipsis if ( $data['ellipsis'] && !empty($limited['is_limited']) ){ $data['text'] .= '…'; } //Link if ( !empty($data['more']) ){ if ( empty($data['url']) ){ //If has "more" text, but no link URL $data['url'] = ( !empty($data['id']) )? get_permalink($data['id']) : get_permalink(get_the_id()); //Use the ID if available, or use the current ID. } //Button $btn_class = ''; if ( $data['button'] || $data['btn'] ){ $button = ( $data['button'] )? $data['button'] : $data['btn']; $btn_class = ( is_bool($button) )? 'btn btn-brand' : 'btn ' . $data['button']; $data['text'] .= '<br /><br />'; } $data['text'] .= ' <a class="nebula_excerpt ' . $btn_class . '" href="' . $data['url'] . '">' . $data['more'] . '</a>'; } return $data['text']; }
Override
To override this PHP function, use this hook in your child theme or plugin ("my_custom" can be changed):
add_filter('pre_nebula_excerpt', 'my_custom_excerpt', 10, 2); //The last integer must be 1 more than the actual parameters function my_custom_excerpt($null, $options){ //$null is required, but can be ignored //Write your own code here return true; //Return true to prevent the original function from running afterwords }
You can completely disable this PHP function with a single line actions:
add_filter('pre_nebula_excerpt', '__return_false');