Output the first paragraph in a Wordpress post - php

I want to put just the first paragraph of my posts on my index.php
in my functions.php I have
<?php
{
global $post;
$output = get_the_content();
$wanted_number_of_paragraph = 1;
$tmp = explode ('</p>', $output);
for ($i = 0; $i < $wanted_number_of_paragraph; ++$i) {
if (isset($tmp[$i]) && $tmp[$i] != '') {
$tmp_to_add[$i] = $tmp[$i];
}
}
$output = implode('</p>', $tmp_to_add) . '</p>';
echo $output;
}
?>
then in my index.php
<?php wpden_excerpt(); ?>
However it posts the entire post (including pictures) and not just the first paragraph.

I wold recommend you to use the Wordpress get_extended() function for this purpose. In your post you split the content with the "more" tag, after inside your template you can have something like:
global $post;
// gets the content of your post as an array of 2 parts
$content_parts = get_extended( $post->post_content );
and after this you can echo the part before the "more" tag like:
<?=$content_parts['main'];?>
the part after the "more" tag you can echo like:
<?=$content_parts['extended'];?>
Also, if you chose this option I'll recommend you to check the wpautop() , since you may need to wrap these 2 parts with it, for example:
<?=wpautop($content_parts['extended']);?>

Related

PHP separate paragraph

I am writing a code for wordpress to separate paragraph using PHP. The objective is to split the content of the post into an array and echo them accordingly.
Here are my code
<?php
$content = "<p>123</p> <p>456</p> <p>789</p>"
$p = explode("</p>", $content);
$i=0;
//echo first 2 elements
foreach ($p as $para) {
echo $para;
array_shift($p); //remove the first element
$i++; //increase the element count by 1
if ($i == 2){ break;} //if element has reach 2 meaning second paragraph, stop loop.
}
echo "<br>Break here<br>";
//echo the rest of the element
foreach ($p as $para) {
echo $para;
}
?>
Replace this
$content = "<p>123</p> <p>456</p> <p>789</p>"
With the following
$content = apply_filters( 'the_content', get_the_content() );
$content = str_replace( ']]>', ']]>', $content );
to retrieve the content of the post with paragraph tag.
I am able to achieve my result but I am just worry of the consequences such as system overload.
If i understand correctly, what you're trying to accomplish, is adding a couple of <br> tags after the first two paragraphs?
If so, this can be done alot simpler using the preg_replace method:
$content = "<p>123</p> <p>456</p> <p>789</p>";
echo preg_replace('/<\/p>/', '</p><br><br>', $content, 2);

Truncate WordPress post content without losing HTML formatting

I'm working on a WordPress theme where I need to truncate the post at a certain number of words. I understand how to use the_excerpt(), however this strips out all the paragraph breaks, links, etc. which is NOT the desired effect. I tried using jQuery Succinct and applying that to the_content() -- that maintained the formatting, but it cut off in the middle of a paragraph so I had an open <p> that then broke the rest of the layout. The client does not want to use the option to manually insert a "more" tag into the post.
Is there a way I can do this either via PHP or jQuery?
You have to create your own excerpt function. I have written one that keeps all html tags in tact and also cut the excerpt at the end of a sentence just after the chosen amount of words.
You need to remove the original excerpt filter first and add your new one. Add this to your functions.php
remove_filter('get_the_excerpt', 'wp_trim_excerpt');
add_filter('get_the_excerpt', 'pietergoosen_custom_wp_trim_excerpt');
Now add this below
function pietergoosen_custom_wp_trim_excerpt($pietergoosen_excerpt) {
global $post;
$raw_excerpt = $pietergoosen_excerpt;
if ( '' == $pietergoosen_excerpt ) {
$pietergoosen_excerpt = get_the_content('');
$pietergoosen_excerpt = strip_shortcodes( $pietergoosen_excerpt );
$pietergoosen_excerpt = apply_filters('the_content', $pietergoosen_excerpt);
$pietergoosen_excerpt = str_replace(']]>', ']]>', $pietergoosen_excerpt);
//Set the excerpt word count and only break after sentence is complete.
$excerpt_word_count = 75;
$excerpt_length = apply_filters('excerpt_length', $excerpt_word_count);
$tokens = array();
$excerptOutput = '';
$count = 0;
// Divide the string into tokens; HTML tags, or words, followed by any whitespace
preg_match_all('/(<[^>]+>|[^<>\s]+)\s*/u', $pietergoosen_excerpt, $tokens);
foreach ($tokens[0] as $token) {
if ($count >= $excerpt_word_count && preg_match('/[\?\.\!]\s*$/uS', $token)) {
// Limit reached, continue until ? . or ! occur at the end
$excerptOutput .= trim($token);
break;
}
// Add words to complete sentence
$count++;
// Append what's left of the token
$excerptOutput .= $token;
}
$pietergoosen_excerpt = trim(force_balance_tags($excerptOutput));
$excerpt_end = ' ' . ' » ' . sprintf(__( 'Read more about: %s »', 'pietergoosen' ), get_the_title()) . '';
$excerpt_more = apply_filters('excerpt_more', ' ' . $excerpt_end);
$pos = strrpos($pietergoosen_excerpt, '</');
if ($pos !== false)
// Inside last HTML tag
$pietergoosen_excerpt = substr_replace($pietergoosen_excerpt, $excerpt_end, $pos, 0);
else
// After the content
$pietergoosen_excerpt .= $excerpt_end;
return $pietergoosen_excerpt;
}
return apply_filters('pietergoosen_custom_wp_trim_excerpt', $pietergoosen_excerpt, $raw_excerpt);
}

Inserting content before <p> tags in PHP

Though this is Wordpress orientated, I think the basis of the PHP is more a Stackoverflow question:
I would like to add a template_part (similar to include()) before the first <p> in a post.
I can't add the template_part before the_content() because inside the the_content() is sometimes a <figure> then <p>:
<figure>....</figure>
// Want to insert here!
<p>.......</p>
<p>.......</p>
<p>.......</p>
<figure>....</figure>
<p>.......</p>
<p>.......</p>
These are the two codes I have tried using, but not sure how to make it go before the first <p>:
Method one:
$after = 1;
$content = apply_filters('the_content', $post->post_content);
if(substr_count($content, '<p>') > $after) {
$contents = explode("</p>", $content); $p_count = 0;
foreach($contents as $content){
echo $content; if($p_count == $after){
get_template_part('path/to/part');
} $p_count++;
}
}
Method two:
$paragraphAfter[1] = get_template_part('path/to/part');
$content = apply_filters( 'the_content', get_the_content() );
$content = explode("</p>", $content);
$count = count($content);
for ($i = 0; $i < $count; $i++ ) {
if ( array_key_exists($i, $paragraphAfter) ) {
echo $paragraphAfter[$i];
}
echo $content[$i] . "</p>";
}
Preferably the more efficient method, either from above or your own :]
A dirty hack could be:
function add_the_string_filter( $content ) {
$string_to_append = 'your string to add';
$content = preg_replace('/<p>/', $string_to_append . '<p>', $content , 1);
return $content;
}
add_filter( 'the_content', 'add_the_string_filter' );
The last parameter of the preg_replace is the limit, which tells to replace only the first occurence.

Return only the shortcode from post?

Is it possible to filter out only the shortcode from the post and then run the shortcode?
My page looks like this:
[summary img="images/latest.jpg"]
This here is the summary
[/summary]
Lots of text here...
And i just want to display the shortcode on a specific page.
Tried using regular expressions, but they dont seem to work:
$the_query = new WP_Query('category_name=projects&showposts=1');
//loop
while ( $the_query->have_posts() ) : $the_query->the_post();
echo '<b>';
the_title();
echo '</b>';
echo '<p>';
$string = get_the_content();
if (preg_match("[\\[[a-zA-Z]+\\][a-zA-Z ]*\\[\/[a-zA-Z]+\\]]", $string , $matches)) {
echo "Match was found <br />";
echo $matches[0];
}
echo '</p>';
endwhile;
Any idéas?
EDIT:
Found a temporary solution.
while ( $the_query->have_posts() ) : $the_query->the_post();
$content = str_replace(strip_shortcodes(get_the_content()),"",get_the_content());
echo do_shortcode($content);
endwhile;
I saw that wordpress had a function for striping shortcodes but not for strip content. So i replaced the stripped content string from the whole post to get just the shortcode. The only bad thing about this that the shortcodes have to be in the beginning of the posts.
Better answer is:
$pattern = get_shortcode_regex();
preg_match('/'.$pattern.'/s', $post->post_content, $matches);
if (is_array($matches) && $matches[2] == 'the_shortcode_name') {
$shortcode = $matches[0];
echo do_shortcode($shortcode);
}
It will search through the post content for a shortcode called “the_shortcode_name”. If it finds it, it will store the shortcode in the $matches variable. Easy to run it from there.
I've had the following problems with these answers:
regex pattern not containing all registered shortcode tags
inability to get all shortcodes from the post
.. and my solution is:
// Return all shortcodes from the post
function _get_shortcodes( $the_content ) {
$shortcode = "";
$pattern = get_shortcode_regex();
preg_match_all('/'.$pattern.'/uis', $the_content, $matches);
for ( $i=0; $i < 40; $i++ ) {
if ( isset( $matches[0][$i] ) ) {
$shortcode .= $matches[0][$i];
}
}
return $shortcode;
}
Use it like so:
<?php echo do_shortcode( _get_shortcodes( get_the_content() ) ) ?>
Search wherever your shortcode position is on your content
Example :
[my_shortcode]
[my_shortcode_2]
or
[my_shortcode_2]
[my_shortcode]
Functions.php
function get_shortcode($code,$content) {
$pattern = get_shortcode_regex();
preg_match_all('/'.$pattern.'/s',$content,$matches);
if(is_array($matches) && isset($matches[2]) && in_array($code,$matches[2])) {
$index = array_search($code,$matches[2]);
$shortcode = $matches[0][$index];;
return do_shortcode($shortcode);
} else {
return false;
}
}
Using example :
$content = $post->post_content;
$my_shortcode = get_shortcode('my_shortcode',$content);
$my_shortcode_2 = get_shortcode('my_shortcode_2',$content);
echo $my_shortcode;
if($my_shortcode){ // if shortcode#1 found so echo shortcode#2 after
echo $my_shortcode_2;
}
use this regex
preg_match('/\[summary[^\]]*](.*)\[\/summary[^\]]*]/uis', $string , $matches)
$match[1] should be your text
Edit: ok to match any combination of tags
use
/\[([^\]]+)\](.*?)\[\/\1\]/uis
but if you have nested tags you might need to parse the matches again recursively. However if it is a wordpress free text i think you might get too complex cases that a simple script can handle
You can do this using the get_shortcode_regex() function to get the regex for all registered shotcodes in your blog, apply that to the content to get an array of shortcodes found in that content, then call the appropriate callback to process the one you want.
So inside a loop somewhere it would be something like:
$pattern = get_shortcode_regex();
$matches = array();
preg_match_all("/$pattern/s", get_the_content(), $matches);
var_dump($matches); //Nested array of matches
//Do the first shortcode
echo preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $matches[0][0] );
This will execute the first shortcode found in the post, obviously in practice you want to check that you've got one!

Wordpress Archives Widget - Customize html output

I'm still pinned against wordpress it seems. I added the widget 'Archives' to my sidebar and once more, the html output is crap, it basically has this structure:
<li>text - (# of posts)</li>
I want to transform it into:
<li>text <small># of posts</small>
Unlike with plugins however, I wasn't able to find the line that creates the html output in the php pages suggested/mentioned by the wordpress community, namely functions.php, widgets.php and default-widgets.php
I've googled every possible keyword combination on the matter and I was unable to find something relevant.
All help is appreciated
Regards
G.Campos
Check out general-template.php. Two functions wp_get_archives and get_archives_link. You'd have to hack wp_get_archives to change what gets loaded in $text. The post count gets loaded into the $after variable which placed outside the link in get_archives_link. Instead of this:
$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
if ( $show_post_count )
$after = ' ('.$arcresult->posts.')' . $afterafter;
something like this:
$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
if ( $show_post_count )
$text= $text.' <small>'.$arcresult->posts.'</small>';
That's just for the Monthly archive. You'd have to make modifications on the Yearly, Weekly and Daily blocks.
Edit: Easiest way to exclude the <small> element from the link's title is to load it up in a separate variable in each block and then pass it into a modified get_archives_link. In the example above, right after $text gets loaded up just load that value into $title:
$text = sprintf(__('%1$s %2$d'), $wp_locale->get_month($arcresult->month), $arcresult->year);
$title = $text;
if ( $show_post_count )
$text= $text.' <small>'.$arcresult->posts.'</small>';
$output .= get_archives_link($url, $text, $format, $before, $after, $title);
Then modify get_archives_link:
function get_archives_link($url, $text, $format = 'html', $before = '', $after = '', $title = '') {
$text = wptexturize($text);
if($title == '')
$title = $text;
$title_text = esc_attr($title);
$url = esc_url($url);
if ('link' == $format)
$link_html = "\t<link rel='archives' title='$title_text' href='$url' />\n";
elseif ('option' == $format)
$link_html = "\t<option value='$url'>$before $text $after</option>\n";
elseif ('html' == $format)
$link_html = "\t<li>$before<a href='$url' title='$title_text'>$text</a>$after</li>\n";
else // custom
$link_html = "\t$before<a href='$url' title='$title_text'>$text</a>$after\n";
$link_html = apply_filters( "get_archives_link", $link_html );
return $link_html;
}
Add this code inside your theme functions.php file, It will wrap post archive counts inside span tag. In below code example I wrapped counts in span tag, you can add or modify it according to your requirement.
function wrap_archive_count($links) {
$links = str_replace('</a> (', '<span class="archive-count">', $links);
$links = str_replace(')', '</span></a>', $links);
return $links;
}
add_filter('get_archives_link', 'wrap_archive_count');

Categories