Shortcodes function - php

Here the problem:
I have two div #post-playlist-list and post-playlist-description
I want to use two shortcodes [texte-article] and [playlist-article]
I need a function which get all the content between[texte-article][/texte-article] to put in #post-playlist-list
and another function which get the [playlist-article][/playlist-article] content into #post-playlist-description
I began to learn at preg_replace but the syntax is not that easy to learn.
I you can help me on this, it would be great.
Ok i tried the function i don't have error but it doesn't seems to return anything
Don't i need to escape the second ] ion the Regexp? like "/[texte-article](.*)[/texte-article]/"
Here's the code in my single.php :
<div id="post-playlist-list" class="box">
<?php
$id = get_the_ID();
$post = get_post($id);
$content = apply_filters('the_content', $post->post_content);
$content = str_replace( ']]>', ']]>', $content );
echo $content;
?>
</div>
<div id="post-playlist-description" >
<?php
echo $content;
?>
</div>
Here's the code in my single.php:
function texte_article_function() {
preg_replace_callback("/\[texte-article\](.*)\[\/texte-article\]/", function($matches) {
//$matches contains an array of all matches
//$matches[0] stores the full pattern match: \[texte-article](.*)\[\/texte-article]
//$matches[1] stores the first subpattern match: (.*)
//Do whatever text parsing you need to do here and return the result.
$content = $matches[0];
return $content;
}, $postdata);
}
function playlist_article_function() {
preg_replace_callback("/\[playlist-article\](.*)\[\/playlist-article\]/", function($matches) {
//$matches contains an array of all matches
//$matches[0] stores the full pattern match: \[texte-article](.*)\[\/texte-article]
//$matches[1] stores the first subpattern match: (.*)
//Do whatever text parsing you need to do here and return the result.
$content = $matches[0];
return $content;
}, $postdata);
}
function register_shortcodes(){
add_shortcode('texte-article', 'texte_article_function');
add_shortcode('playlist-article', 'playlist_article_function');
}
add_action( 'init', 'register_shortcodes');

Thanks for all the answers :) here's the solution, using regex:
functions.php
function texte_article_function($content_texte_article) {
//Get [texte-article] content
$content_texte_article = preg_replace('#.*\[texte-article\](.*)\[\/texte-article\].*#s', '$1', $content_texte_article);
return $content_texte_article;
}
function playlist_article_function($content_playlist_article) {
//get [fap_playlist] content
$content_playlist_article = preg_replace('#.*\[playlist-article\](.*)\[\/playlist-article\].*#s', '$1', $content_playlist_article);
return $content_playlist_article;
}
Callback functions:
<?php
$id = get_the_ID();
$post = get_post($id);
$content_playlist_article = $content;
$btn_play_index_id = $content;
echo playlist_article_function($content_playlist_article);
// echo $content;
?>
<?php
$content_texte_article = $content;
echo texte_article_function($content_texte_article);
?>
If it can help someone.

Related

Add one element after first paragraph

I've the following code for adding advertisement before the_content of posts in my WordPress website.
<?php if (!empty($smof_data['ads_entry_top'])) { ?>
<div class="entry-img-300"><?php echo stripslashes($smof_data['ads_entry_top']); ?></div>
<?php } ?>
I want it to be added after the first paragraph, so wrote this function into functions.php:
add_filter( 'the_content', 'insert_after_first', 20 );
function insert_after_first( $content ) {
$content = preg_replace( "/<\/p>/", "</p>" . stripslashes($smof_data['ads_entry_top']) , $content, 1 );
return $content;
}
But it does nothing. What is wrong?
I changed my method and now add some content after first paragraph with below function and filter. I add it here maybe it helps someone:
add_filter('the_content', 'ata_the_content_filter', 10, 1);
function ata_the_content_filter($content)
{
$parags = explode('</p>', $content);
$parags[0] .= '<br>hello';// add whatever you want after first paragraph
$content_new = '';
foreach ($parags as $parag) {
$content_new .= $parag;
}
return $content_new;
}

Wordpress PHP - need to retain nextpage paginating tag in custom query

Preface: i am not a good coder.
I need to use $post->post_content to get the raw post so that i can use the EXPLODE php command. But when i do use $post->post_content, it filters out the tags that are in my post which need to be retained. here is my script. what am i doing wrong? thanks!
<?php
$content = apply_filters('the_content', $post->post_content);
$contents = array_filter(explode("</p>", $content));
foreach ($contents as $content) {
if (strpos($content, '<img') !== false ) {
echo $content;
echo "</p>after image ad";
} else {
echo $content;
echo "</p>";
}
}
?>
I'm basically trying to insert an Ad after any paragraph that only contains an image.
It seems that when you call:
$content = apply_filters('the_content', $post->post_content);
It applies autop to split the paragraphs, and also applies do_shortcode on all shortcodes.
So you'd better not to call apply_filters here, but call wpautop instead:
See: http://codex.wordpress.org/Function_Reference/wpautop
<?php
$content = wpautop( $post->post_content );
$contents = array_filter(explode("</p>", $content));
$result = '';
foreach ($contents as $content) {
$result .= $content.'</p>';
if (strpos($content, '<img') !== false ) {
$result .= "after image ad";
}
}
$content = apply_filters('the_content', $result);
echo $result;
?>

how to skip images with certain class in wordpress function

I have the following function in my theme's function page. basically what it does is look for any image in the post page and add some spans with css to dynamically create a pinterest button.
function insert_pinterest($content) {
global $post;
$posturl = urlencode(get_permalink()); //Get the post URL
$pinspan = '<span class="pinterest-button">';
$pinurlNew = '<a href="#" onclick="window.open("http://pinterest.com/pin/create/button/?url='.$posturl.'&media=';
$pindescription = '&description='.urlencode(get_the_title());
$options = '","Pinterest","scrollbars=no,menubar=no,width=600,height=380,resizable=yes,toolbar=no,location=no,status=no';
$pinfinish = '");return false;" class="pin-it"></a>';
$pinend = '</span>';
$pattern = '/<img(.*?)src="(.*?).(bmp|gif|jpeg|jpg|png)"(.*?) \/>/i';
$replacement = $pinspan.$pinurlNew.'$2.$3'.$pindescription.$options.$pinfinish.'<img$1src="$2.$3" $4 />'.$pinend;
$content = preg_replace( $pattern, $replacement, $content );
//Fix the link problem
$newpattern = '/<a(.*?)><span class="pinterest-button"><a(.*?)><\/a><img(.*?)\/><\/span><\/a>/i';
$replacement = '<span class="pinterest-button"><a$2></a><a$1><img$3\/></a></span>';
$content = preg_replace( $newpattern, $replacement, $content );
return $content;
}
add_filter( 'the_content', 'insert_pinterest' );
it does everything just fine. but is there a way to have it skip over an image with a certain class name in it like "noPin" ?
I would use preg_replace_callback to check if a matched image contains noPin.
function skipNoPin($matches){
if ( strpos($matches[0], "noPin") === false){
return $pinspan.$pinurlNew.'$matches[2].$matches[3]'.$pindescription.$options.$pinfinish.'<img$1src="$2.$3" $4 />'.$pinend;
} else {
return $matches[0]
$content = preg_replace_callback(
$pattern,
skipNoPin,
$content );
Another image attribute could conceivably contain noPin, if you are concerned about that edge case, just make the test in the if statement more specific.
You have to exclude the class noPin from the $pattern regexp :
$pattern = '/<img(.*?)src="(.*?).(bmp|gif|jpeg|jpg|png)"(.*?) \/>/i';
Has to become something like
$pattern = '/<img(.*?)src="(.*?).(bmp|gif|jpeg|jpg|png)"(.*?) (?!class="noPin") \/>/i';
Please check the regexp syntax, but the idea is to exclude class="noPin" from the searched pattern. Then your replacement will not be added to these images.

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!

Multiple excerpt lengths in wordpress

As it says in the title, I'm looking for multiple excerpt lengths in WordPress.
I understand you can do this in functions.php:
function twentyten_excerpt_length( $length ) {
return 15;
}
add_filter( 'excerpt_length', 'twentyten_excerpt_length' );
What I want to know is how you can have multiple of these each returning different numerical values so I can get short excerpts for sidebar loops, longer excerpts for featured loops, and the longest excerpt for the main article.
Something like using these in the templates:
<?php the_excerpt('length-short') ?>
<?php the_excerpt('length-medium') ?>
<?php the_excerpt('length-long') ?>
Cheers,
Dave
How about...
function excerpt($limit) {
$excerpt = explode(' ', get_the_excerpt(), $limit);
if (count($excerpt) >= $limit) {
array_pop($excerpt);
$excerpt = implode(" ", $excerpt) . '...';
} else {
$excerpt = implode(" ", $excerpt);
}
$excerpt = preg_replace('`\[[^\]]*\]`', '', $excerpt);
return $excerpt;
}
function content($limit) {
$content = explode(' ', get_the_content(), $limit);
if (count($content) >= $limit) {
array_pop($content);
$content = implode(" ", $content) . '...';
} else {
$content = implode(" ", $content);
}
$content = preg_replace('/\[.+\]/','', $content);
$content = apply_filters('the_content', $content);
$content = str_replace(']]>', ']]>', $content);
return $content;
}
then in your template code you just use..
<?php echo excerpt(25); ?>
from: http://bavotasan.com/tutorials/limiting-the-number-of-words-in-your-excerpt-or-content-in-wordpress/
As for now, you can upgrade Marty's reply:
function excerpt($limit) {
return wp_trim_words(get_the_excerpt(), $limit);
}
You can also define custom 'read more' link this way:
function custom_read_more() {
return '... <a class="read-more" href="'.get_permalink(get_the_ID()).'">more »</a>';
}
function excerpt($limit) {
return wp_trim_words(get_the_excerpt(), $limit, custom_read_more());
}
This is what I came up with.
Add this to your functions.php
class Excerpt {
// Default length (by WordPress)
public static $length = 55;
// So you can call: my_excerpt('short');
public static $types = array(
'short' => 25,
'regular' => 55,
'long' => 100
);
/**
* Sets the length for the excerpt,
* then it adds the WP filter
* And automatically calls the_excerpt();
*
* #param string $new_length
* #return void
* #author Baylor Rae'
*/
public static function length($new_length = 55) {
Excerpt::$length = $new_length;
add_filter('excerpt_length', 'Excerpt::new_length');
Excerpt::output();
}
// Tells WP the new length
public static function new_length() {
if( isset(Excerpt::$types[Excerpt::$length]) )
return Excerpt::$types[Excerpt::$length];
else
return Excerpt::$length;
}
// Echoes out the excerpt
public static function output() {
the_excerpt();
}
}
// An alias to the class
function my_excerpt($length = 55) {
Excerpt::length($length);
}
It can be used like this.
my_excerpt('short'); // calls the defined short excerpt length
my_excerpt(40); // 40 chars
This is the easiest way that I know of to add filters, that are callable from one function.
I was looking for this feature as well and most of the functions here are good and flexible.
For my own case I was looking for a solution that shows a different excerpt length only on specific pages. I'm using this:
function custom_excerpt_length( $length ) {
return (is_front_page()) ? 15 : 25;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
Paste this code inside the themes functions.php file.
You can add to your functions.php file this function
function custom_length_excerpt($word_count_limit) {
$content = wp_strip_all_tags(get_the_content() , true );
echo wp_trim_words($content, $word_count_limit);
}
Then call it in your template like this
<p><?php custom_length_excerpt(50); ?>
The wp_strip_all_tags should prevent stray html tags from breaking the page.
Documentation on functions
get_the_content
wp_trim_words
wp_strip_all_tags
Going back to Marty's reply:
I know it's been well over a year since this reply got published, but it's better late than never. For this to work with limits of over the WordPress default of 55, you need to replace this line:
$excerpt = explode(' ', get_the_excerpt(), $limit);
with this line:
$excerpt = explode(' ', get_the_content(), $limit);
Otherwise, the function only works with an already trimmed-down piece of text.
I think we can now use wp_trim_words see here.
Not sure what extra data escaping and sanitization needed to use this function, but it looks interesting.
Here an easy way to limit the content or the excerpt
$content = get_the_excerpt();
$content = strip_tags($content);
echo substr($content, 0, 255);
change get_the_excerpt() by get_the_content() if you want the contents.
Regards
I would do like this :
function _get_excerpt($limit = 100) {
return has_excerpt() ? get_the_excerpt() : wp_trim_words(strip_shortcodes(get_the_content()),$limit);
}
Usage :
echo _get_excerpt(30); // Inside the loop / query
Why ?
If has_excerpt should return given excerpt
It not, So trim words / strip shortcodes from the_content
I thing it is possible to create a short code , i did not try it but i wrote for you the main idea about its structure
function twentyten_excerpt_length($atts,$length=null){
shortcode_atts(array('exlength'=>'short'),$atts);
if(!isset($atts['exlength']) || $atts['exlength'] == 'short') {
return 15;
}elseif( $atts['exlength'] == 'medium' ){
return 30; // or any value you like
}elseif( $atts['exlength'] == 'long' ){
return 45; // or any value you like
}else{
// return nothing
}
}
add_shortcode('the_excerpt_sc','twentyten_excerpt_length');
so you can use it like so
[the_excerpt_sc exlength="medium"]
I know this is a really old thread, but I just struggled with this problem and none of the solutions I found online worked properly for me. For one thing my own "excerpt_more"-filter was always cut off.
The way I solved it is ugly as hell, but it's the only working solution I could find. The ugliness involves modifying 4 lines of WP core(!!) + the use of yet another global variable (although WP already does this so much I don't feel too bad).
I changed wp_trim_excerpt in wp-includes/formatting.php to this:
<?php
function wp_trim_excerpt($text = '') {
global $excerpt_length;
$len = $excerpt_length > 0 ? $excerpt_length : 55;
$raw_excerpt = $text;
if ( '' == $text ) {
$text = get_the_content('');
$text = strip_shortcodes( $text );
$text = apply_filters('the_content', $text);
$text = str_replace(']]>', ']]>', $text);
$excerpt_length = apply_filters('excerpt_length', $len);
$excerpt_more = apply_filters('excerpt_more', ' ' . '[…]');
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
}
$excerpt_length = null;
return apply_filters('wp_trim_excerpt', $text, $raw_excerpt);
}
The only new stuff is the $excerpt_length and $len bits.
Now if I want to change the default length I do this in my template:
<?php $excerpt_length = 10; the_excerpt() ?>
Changing core is a horrible solution so I'd love to know if someone comes up with something better.
Be careful using some of these methods. Not all of them strip the html tags out, meaning if someone inserts a link to a video (or url) in the first sentence of their post, the video (or link) will show up in the excerpt, possibly blowing up your page.
I wrote an article about using custom excerpt length in WordPress.
There area a number of ways to limit & control post excerpt length.
Limit post excerpt length or post content length using number of words.
Limiting excerpt length to a number of characters.
Limit post summary by adding ‘read more’ tag.
Enabling custom excerpt to write your own summary for each post.
Control Excerpt Length using Filters
I hope this will help you a lot.

Categories