get_the_content not working within shortcode - php

I have an issue with a shortcode that I'm writing for wordpress. I'm trying to use the get_the_content() function but instead of pulling the contents of the custom post type I've created it's pulling the contents of the page the shortcode is sitting on. Other functions are all working fine e.g. get_the_title() and get_the_post_thumbnail(). I pass the ID in the functions and it works great for everything else, just not get_the_content.
get_the_content($testimonial_item->ID);
The shortcode contains pagination and other elements which all work correctly, It's just this one function that causing me grief. The full code is below, any help would be greatly appreciated.
function ncweb_display_testimonial_items($atts, $content = null) {
extract( shortcode_atts( array(
'per_page' => 6
), $atts ) );
/* pagination parameters */
// check what page we are on
if ( isset ($_GET['testimonial-page'] ) ) $page = $_GET['testimonial-page']; else $page = 1;
// default number of pages
$total_pages = 1;
// portfolio offset. Used in the get_posts() query to show only portfolio for the current page
$offset = $per_page * ($page-1);
// setup the portfolio args for retrieving the total number of portfolio items
$testimonial_count_args = array(
'post_type' => 'ncweb-testimonials',
'posts_per_page' => -1
);
$testimonial_count = count(get_posts($testimonial_count_args));
// calculate the total number of pages
$total_pages = ceil($testimonial_count/$per_page);
/* end pagination parameters */
// main image query
$testimonial_args = array(
'post_type' => 'ncweb-testimonials',
'numberposts' => $per_page,
'offset' => $offset
);
$testimonial_items = get_posts($testimonial_args);
// start our output buffer
ob_start();
if($testimonial_items) :
/*** main portfolio loop ***/
$counter = 1;
echo '<div class="testimonial-items" id="testimonial-items">';
foreach($testimonial_items as $testimonial_item) :
$testimonial_company = get_post_meta($testimonial_item->ID, 'ncweb_testimonial_company', true);
$testimonial_client = get_post_meta($testimonial_item->ID, 'ncweb_testimonial_client_name', true);
echo '<aside class="testimonial-list-item row">';
echo '<div class="col-xs-12 testimonial-list-item-info">';
echo '<div class="testimonial-image">'. get_the_post_thumbnail($testimonial_item->ID) .'</div>';
echo '<div class="testimonial-client"><span class="testimonial-client-name">'. $testimonial_client .'</span><br/><span class="testimonial-company">'. $testimonial_company .'</span></div>';
echo '</div>'; //end of testimonial-list-item-info
echo '<div class="col-xs-12 testimonial-item-content">'. get_the_content($testimonial_item->ID); .'</div>';
echo '</aside>';
$counter++;
endforeach;
echo '</div>';
/*** display pagination ***/
// pagination base
echo '<div id="testimonial-pagination">';
$base = get_permalink(get_the_ID()) . '%_%';
echo paginate_links( array(
'base' => $base,
'format' => '?testimonial-page=%#%',
'prev_text' => __('Previous', 'ncweb'),
'next_text' => __('Next', 'ncweb'),
'total' => $total_pages,
'current' => $page,
'end_size' => 1,
'mid_size' => 5
));
echo '</div>';
/*** end pagination display ***/
else :
echo '<p>' . __('No testimonial items found.', 'ncweb') . '</p>';
endif; // end if($images)
return ob_get_clean();
}
add_shortcode( 'testimonial-items', 'ncweb_display_testimonial_items' );

This is because the get_the_content() function is a wrapper and it's only arguments are the Read More text and the stripteaser argument.
What you actually want is.
$post= get_post($testimonial_item->ID);
$testimonial_items = $post->content ;
$testimonial_items = apply_filters('the_content', $testimonial_items);
Then you will have what you are looking for.

You can try this code to get the perfect output when using shortcode in content.
<?php
ob_start();
the_content();
$content_output = ob_get_clean();
echo $content_output;
?>

Cleanest way to output the_content using a shortcode is this:
function my_sc_content() {
ob_start();
$my_content = the_content();
echo $my_content;
$output_string = ob_get_contents();
ob_end_clean();
return $output_string;
}
add_shortcode('my-content','my_sc_content');

Related

how to show all testimonial on single page via shortcode in wordpress?

i have created shortcode to show all testimonial on one page.
i have created custom post type to add each testimonial.
can anybody tell me how to show all testimonial on single page .
this code is used to create sshortcode
below i m mentioning code :-
function fn_testimonials_block()
{
$args = array(
'post_type'=> 'testimonials',
'order' => 'ASC'
);
$the_query = new WP_Query( $args );
$pages = $the_query->posts;
//echo "<pre>";
//print_r($pages);
//echo "</pre>";
//exit;
$output = '';
$count = 1;
foreach($pages as $page) {
//-----------------
$author = $page->post_title;
$testimonial = $page->post_content;
$page_url = get_page_link( $page->ID );
$author_image = get_the_post_thumbnail_url( $page->ID, 'thumbnail' );
if ($count%2 == 1)
{
$output .= '<div>';
}
$output .= '<div>
<p>'.$testimonial.'<br>
<img src="'.$author_image .'"> <span>'.$author.', </span></p>
</div>';
if ($count%2 == 0)
{
$output .= '</div>';
}
$count++;
}
if ($count%4 != 1){
$output .= '</div>';
}
return $output;
}
I think you will have to pass 'posts_per_page' key in $args array. So your $args array will look like this
$args = array(
'post_type'=> 'testimonials',
'order' => 'ASC',
'posts_per_page' => '-1'
);
I am not sure about the $count variable you are using. I suppose you are trying to implement logic for pagination there but since your question is about showing all testimonials on single page, I won't get into that part.
Making changes in $args will return all testimonials objects.

WP navigation post of a custom post type

I need to include in single.php a navigation buttons with previous and next post of the custom post type called 'works'.
I include this
<?php echo get_next_posts_link('Go to next post'); ?>
<?php echo get_previous_posts_link('Go to prev post');?>
or this
<?php previous_post_link( $taxonomy = 'works' ); ?>
But don´t show nothing or the navigation include all posts and pages. Only need pagination the post of this CUT like a carousel gallery, for example.
I think u search this one:
https://codex.wordpress.org/Pagination
A pagination for the last Posts of this Post Type.
U dosen't need a special "Menü" for this.
Try this
<?php
$term_list = wp_get_post_terms($post->ID, 'TAXONOMY', array("fields" => "slugs"));
if (empty($term_list[1])) {
print_r($term_list[0]);
$termo = $term_list[0];
} else {
print_r($term_list[1]);
$termo = $term_list[1];
}
// get_posts in same custom taxonomy
$postlist_args = array(
'posts_per_page' => -1,
'orderby' => 'menu_order title',
'order' => 'ASC',
'post_type' => 'CUSTOM-POST-TYPE',
'taxonomy'=>'TAXONOMY',
'term'=>$termo,
);
$postlist = get_posts( $postlist_args );
// get ids of posts retrieved from get_posts
$ids = array();
foreach ($postlist as $thepost) {
$ids[] = $thepost->ID;
}
// get and echo previous and next post in the same taxonomy
$thisindex = array_search($post->ID, $ids);
$previd = $ids[$thisindex-1];
$nextid = $ids[$thisindex+1];
if ( !empty($previd) ) {
echo '<a rel="prev" href="' . get_permalink($previd). '">previous</a>';
}
if ( !empty($nextid) ) {
echo '<a rel="next" href="' . get_permalink($nextid). '">next</a>';
}
?>
Good Luck.
Regards
If using the same category does not work, then you should try this. Add the tag "works" to the posts in your custom post-type. Then you can get the previous_ and next_post_link to this tag:
<?php previous_post_link( '%link', 'Previous in works', TRUE, ' ', 'post_tag' ); ?>
<?php next_post_link( '%link', 'Next in works', TRUE, ' ', 'post_tag' ); ?>

wordpress metabox (plugin) display one page theme

I m using the metabox plugin for wordpress
I want to get value from one or few metabox in my one page wordpress theme.
Here's how i get all my page
/set some variables
//get all the pages on your site
$contact = get_page_by_title( 'Contact' );
$pages = get_pages(array(
'sort_order' => 'ASC',
'sort_column' => 'menu_order',
'exclude' => $contact->ID,
) );
foreach ($pages as $page_data) {
$content = apply_filters('the_content', $page_data->post_content);
$title = $page_data->post_title;
$slug = $page_data->post_name;
$pageid=$page_data->ID;
$couleur=rwmb_meta('twg_couleur');
//Put a container around every page's content
echo "<div class='container-fluid content $pageid' id='$slug'>";
echo "<div class='container'>";
//Heading and Content
echo "<h1>$title</h1>";
echo $content;
echo $couleur;
echo "</div>";
echo "</div>";
}
;
But my var doesn't appears.
She's on the single page if I call her but seems to be empty or not there on the one page template.
How i can do that ?
Thanks a lot for your help
OK !
I just use
$couleurs=rwmb_meta('twg_couleur','type=color' , $pageid);
AND
$pageid=$page_data->ID;
it's working
thanks to me :-)

WordPress - Merging two complex queries into one

I have two fairly complex WordPress queries that I need to combine into a single query.
In my first query, I am getting Wordpress Posts by the date they are published. Each day of posts is contained inside a container, with the date showed above the posts as a title. It also only hides any posts that are in the past. Only posts from today or the future are shown.
In my second query, I am getting WordPress Posts from a Custom Taxonomy. For each term in the taxonomy, posts are displayed inside a container utilizing the slug of that term as a class, and displaying the name of the term as the title.
What I need to accomplish and what I need help with, is as follows.
I need the first query exactly as it is now, however, in the first query, where it says "// Need code here to display posts by taxonomy term //", I need to integrate the second query so that where posts are being output for that day, its also listing the posts by the term like in the second query.
Both queries function perfectly on their own, but I am having trouble with implementing a single query that utilizes the functionality from both queries to do what I need to do.
Here are my two queries:
1st Query:
<?php
// First we get yesterdays date
$year = date("Y"); $month = date("m"); $yesterday = date("d", strtotime("-1 day"));
// Then we construct a query to get items from the calendar, either published or scheduled for a future date so that they appear on the calendar. We use date query to hide events that have already passed by querying after the date we got before. We use yesterdays date to ensure that TODAYS post are still obtained
$query = new WP_Query(array('post_type' => 'calendar',
'post_status' => 'publish,future',
'orderby' => 'post_date',
'order' => 'DESC',
'date_query' => array(
array('after' => array(
'year' => $year,
'month' => $month,
'day' => $yesterday
)
)
)
));
// This is a special loop that gets posts by day and encases each days worth of posts in a container and shows the date of those posts. jQuery will be applied to this
if ($query->have_posts()) {
echo '<div class="day-posts">';
while ($query->have_posts()) {
$query->the_post();
echo '<div class="day">';
the_date('l jS F Y', '<div class="title"><div>', '</div>'); //Formats date, before echo, after echo
echo '<div class="posts clearfix">';
echo '<div class="post">';
the_title('<div class="title">', '</div>');
echo '<div class="content">';
// Need custom code here to display posts by taxonomy //
the_content();
echo '</div></div></div></div>';
}
echo '</div>';
}?>
2nd Query:
<?php
$post_type = array('calendar');
$tax = 'event-category';
$tax_terms = get_terms($tax, array('orderby' => 'id', 'order' => 'ASC'));
if ($tax_terms) {
foreach ($tax_terms as $tax_term) {
$args = array(
'post_type' => $post_type,
"$tax" => $tax_term->slug,
'post_status' => 'publish',
'posts_per_page' => - 1,
'caller_get_posts' => 1
); // END $args
$my_query = null;
$my_query = new WP_Query($args);
if ($my_query->have_posts()) {
echo '<div class="' . $tax_term->slug . '">';
echo '<div class="title">' . $tax_term->name . '</div>;
while ($my_query->have_posts()) : $my_query->the_post();
?>
<?php the_title();?>
<?php the_content();?>
<?php endwhile; echo '</div>'; } wp_reset_query(); } } ?>
I hope I have done a good job of explaining what I am trying to do. If I have not, or there are questions, please ask and I'll answer as quick as I can.
Ok here you go (I dont have posts setup like your query so i didn't test it but i believe this what you are looking for):
// Setup the basic structure:
$args = array(
'post_type' => 'calendar',
'post_status' => 'publish,future',
'orderby' => 'post_date',
'order' => 'DESC',
'date_query' => array(
array(
'after' => array(
'year' => $year,
'month' => $month,
'day' => $yesterday
)
)
),
'posts_per_page' => -1,
'caller_get_posts' => 1
);
// For dynamic taxonomy term create a bootstrap tax_query
$tax = 'event-category';
$tax_terms = get_terms($tax, array('orderby' => 'id', 'order' => 'ASC'));
if ($tax_terms) {
$args['tax_query'] = array(
array(
'taxonomy' => $tax,
'field' => 'slug',
)
);
// Append the slugs to the tax_query terms
foreach ($tax_terms as $tax_term) {
$args['tax_query'][0]['terms'][] = $tax_term->slug;
}
}
// Your One and only QUERY
$my_query = new WP_Query($args);
For $tax_term->slug and $tax_term->name you could use get_the_terms() within the query loop like:
$terms = get_the_terms($post->ID, $tax);
$terms = array_slice($terms, 0);
$term = $terms[0];
echo $term->slug;
echo $term->name;
EDITED
See code comments for explanation/clarification
if ($query->have_posts()) {
$_tax = false;
$same_date = array(); // collection of same dates
$same_date_bool = true; // determine previous post date exist
echo '<div class="day-posts">';
while ($query->have_posts()) {
$query->the_post();
$date = get_the_date('l jS F Y');
$same_date_bool = true;
// Checking if post is displayed from the current date
// then this post should be appended inside to previous
// opened div.day tag
if (!empty($same_date) && in_array($date, $same_date)) {
$same_date_bool = false;
}
// Collecting all dates
$same_date[] = $date;
// If post is not in same date
// create new div element
if ($same_date_bool) {
echo '<div class="day">
<div class="title">';
echo $date;
echo '</div>';
}
// If post is not in same date
// create new div element
if ($same_date_bool) {
echo '<div class="posts clearfix">';
}
echo '<div class="post">';
the_title('<div class="title">', '</div>');
echo '<div class="content">';
$terms = get_the_terms($post->ID, $tax);
// Note: I'm assuming your post will
// always have single term
$terms = array_slice($terms, 0);
$term = $terms[0];
if ($term) {
$_tax = true;
echo '<div class="' . $term->slug . '">';
echo '<div class="title">' . $term->name . '</div>';
}
the_content();
if ($_tax) {
echo '</div>';
}
echo '</div></div>';
// If post is in same date
// append closing div element for previous "div.day" element
if (!$same_date_bool) {
echo '</div></div>';
}
}
echo '</div>';
}
Hope this helps now. Also I have replaced the caller_get_posts with ignore_sticky_posts because caller_get_posts has been deprecated since v3.1

Can't get an echo to do what I want in Wordpress plugin

So I'm trying to write a new plugin since I haven't been able to find one that does exactly what I want with the extensibility that I desire. The goal of the plugin is to be able to use a simple shortcode to display an image slider that automatically populates with your blog's latest posts.
I've got the basic plugin files ready and the shortcode implemented and tested. I had a snafu solved yesterday on SO but the solution highlighted a new problem. Here's the code:
function slyd( $category, $slydcount ) {
global $post;
$tmp_post = $post; // Create $tmp_post to empty $post once Slyd is done with it
$args = array(
'category' => $category,
'numberposts' => $slydcount
);
$slydposts = get_posts( $args );
foreach( $slydposts as $post ) : setup_postdata($post);
$post_title = get_the_title(); // Get the post's title
$post_content = get_the_content(); // Get the post's content - will write code to get excerpt later
$post_thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' ); // Get the post's featured image's src
$post_permalink = get_permalink(); // Get the post's permalink
echo '<h2>' . $post_title . '</h2>'
. '<p>' . $post_content . '</p>'
. '<p>' . $post_thumb . '</p>';
endforeach;
$post = $tmp_post; // Empty $post once Slyd is done with it
}
// Create the shortcode
function slyd_shortcode( $atts ) {
// $atts ::= array of attributes
// examples: [slyd]
// [slyd category='slide']
// [slyd slydcount='5']
// [slyd theme='default']
/* Retrieve attributes set by the shortcode and set defaults for
unregistered attributes. */
extract( shortcode_atts( array(
'category' => 'slyd', // Which category(s) to display posts from
'slydcount' => '5', // How many Slyds to display
'theme' => 'default' // Which Slyd theme to use
), $atts ) );
return "<p>category = {$category}, count = {$slydcount}</p>"
. slyd( $category, $slydcount );
}
add_shortcode( 'slyd', 'slyd_shortcode' );
The issue is in the foreach loop in function slyd();. I was originally using a return where the echo is now to put the result on the screen. That worked to display the first post but it would, of course, escape the function. I need it to cycle through and display all of the posts.
From researching the PHP documentation I found that I could use print in place of echo or return but it's giving me the same result as echo. What's happening is the code seems to be executing twice. It places itself where it needs to be the first time, then it also echoes to the browser and places it just below the head of the page.
I suppose my question is whether there's an alternative to return, echo, or print that would solve my problem?
Thanks in advance.
Now I'm trying to get the plugin to pull in the blog's latest posts but I'm running into a bit of a snafu. When I use the_title() and the_permalink() they display outside of the code I'm trying to contain them in. Further, the_content() is displaying once with the_permalink() and the_title() and then a second time where it's supposed to.
You can see the behavior here.
return is what you want in this case. You want to return a value (i.e. html code) from the slyd function so you can use it (in this case append it) in the slyd_shortcode function. However, you need to first collect all output into an additional variable ($ret below), and then return that value:
function slyd( $category, $slydcount ) {
global $post;
$tmp_post = $post;
$args = array(
'category' => $category,
'numberposts' => $slydcount
);
$slydposts = get_posts( $args );
$ret = '';
foreach( $slydposts as $post ) {
setup_postdata($post);
$post_title = get_the_title();
$post_content = get_the_content();
$post_thumb = wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
$post_permalink = get_permalink();
$ret .= '<h2>' . $post_title . '</h2>'
. '<p>' . $post_content . '</p>'
. '<p>' . $post_thumb . '</p>';
}
$post = $tmp_post;
return $ret;
}
As you see you should first initialize the $ret variable with an empty string, then append to it on each iteration of the foreach loop. return is used to return the whole string after the loop.

Categories