Wordpress shortcode function - php

Can anyone explain why this only returns the 1st result only. I want to return all results that have the same custom field value as the current url. It will ony return 1. Does it need a for each or something? Thank you!!
<?php add_shortcode( 'feed', 'display_custom_post_type' );
function display_custom_post_type(){
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1
);
$new_query = new WP_Query($args);
while($new_query->have_posts()) : $new_query->the_post();
return get_title();
endwhile;
};?>

Because you have added the return inside the loop it will only display the last one. You have to place the return outside the loop for it to display all.
Just a small example to see it work, change this bit:
while($new_query->have_posts()) : $new_query->the_post();
return get_title();
endwhile;
to this:
while($new_query->have_posts()) : $new_query->the_post();
$all_titles .= get_title();
endwhile;
return $all_titles;
It will most probably show all the titles in a single row, so just format as you wish!

You "return" from the function after the first element inside the while loop.
example returning all the posts:
$args = array(
'post_type' => 'custom_post_type',
'posts_per_page' => -1
);
$results = get_posts($args);
return $results;

Related

List each custom post type separately in a wp_query without repeating the loop

I'm using an AJAX search to pull 3 custom post types from wordpress (post, guides, advice). As you can see in my if while loop, the results show which results are which but I'm trying to section them out individually so it will show something like this:
section 1
blog posts
section 2
guides
The problem seems to be that I need to edit the if while loop because adding anything inside that loop will just cause it to be in that loop. Does anyone know the best way to modify the if while loop to achieve this?
function data_fetch(){
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr( $_POST['keyword'] ),
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
)
);
global $post;
if( $the_query->have_posts()) :
while( $the_query->have_posts() ): $the_query->the_post(); ?>
<?php $type = get_post_type();
$term = $_POST['keyword'];
$i++;
$total = $the_query->found_posts;
?>
<span class="search-title">
<?php if ($type == 'post'):?>
<?php echo 'Article: ';?>
<?php elseif($type == 'guide' ):?>
<?php echo 'Guide: ';?>
<?php elseif($type == 'advice' ):?>
<?php echo 'advice: ';?>
<?php endif;?>
<?php the_title();?><br>
</span>
<?php endwhile; ?>
<?php
wp_reset_postdata();
else:
echo '<h3>No Results Found</h3>';
endif;
die();
}
If I were you, I'd probably just do three separate queries. They seem simple enough that it shouldn't cause any issues at all. Otherwise you have to either sort through or reorder the WP_Query results somehow.
If you're set on the single query, however - since these are such short HTML strings, I'd probably just control the output with the Output Buffer.
Basically you can create an associative array, and add the HTML strings to the appropriate keys. You could get a bit more elaborate and have them be nested arrays, but since your output is so light, you can probably get by just by having HTML strings as the values for the keys.
I took the liberty of cleaning up your code a little bit and removing some unused variables, etc.
function data_fetch(){
// Build the Query Arguments
$the_query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
// Do we have posts?
if( $the_query->have_posts()){
// We do. Start an array that will fill with HTML from the output buffer
$output = array(
'post' => '',
'guides' => '',
'advice' => '',
);
// Loop through the posts
while( $the_query->have_posts() ){
$the_query->the_post();
ob_start(); // Turn on the output buffer
$type = get_post_type(); ?>
<span class="search-title">
<?php echo ($type == 'post') ? 'Article: ' : ucwords($type).': '; // Output "Articles: " for posts, or just capitalize the other post type names ?>
<?php the_title();?><br>
</span>
<?php $output[$type] .= ob_get_clean(); // Add the HTML output from the buffer to our array
}
wp_reset_postdata();
// Here we have an array with 3 HTML strings that we can output wherever
echo $output['post'];
echo $output['guides'];
echo $output['advice'];
} else {
echo '<h3>No Results Found</h3>';
}
}
if I understood your concern, I propose to divide your code by creating a generic class.
and you make calls to the different Post Type :
class Custom_Query {
public $post_type;
public $key_word;
public function __construct($post_type, $keyword) {
$this->post_type = $post_type;
$this->key_word = $keyword;
}
public function getResult() {
echo '<h1>Article : ' . $this->post_type . '</h1>';
$the_query = new WP_Query(
array(
'posts_per_page' => 6,
's' => esc_attr($this->key_word),
'post_type' => array($this->post_type),
'post_status' => 'publish'
)
);
if ($the_query->have_posts()):
while ($the_query->have_posts()): $the_query->the_post();
echo '<span class="search-title">';
echo '' . the_title() . '<br>';
echo '</span>';
endwhile;
else:
echo '<h3>No Results Found</h3>';
endif;
wp_reset_postdata();
}
}
global $post;
$type = get_post_type();
$term = $_POST['keyword'];
$article = new Custom_Query($type, $term);
$article->getResult();
You were on the right track initially. You can just use the standard post objects to check for post type. You can adjust to fit your needs, but try something like this:
<?php
query = new WP_Query( array(
's' => esc_attr($_POST['keyword']),
'posts_per_page' => 6,
'post_type' => array('post' , 'guides', 'advice'),
'post_status' => 'publish'
) );
if ($query->have_posts()) {
while ($query->have_posts()):
$query->the_post();
?>
<div class="posts">
<?php
if ($query->post->post_type === 'post') {
// add your content
} else if ($query->post->post_type === 'guides' {
// add your content
} else {
// add your content
}
?>
</div>
<?php endwhile;
} else {
// no posts found
}

How to call a wp_list_categories to page template

I used this code to my category.php and I want it to convert for my page template, this code is fully functional and working on category.php.
<?php
if (in_category('interior')) {
$cat = get_query_var('cat');
$this_category = get_category($cat);
$this_category = wp_list_categories('hide_empty=0&hierarchical=false&order=ASC&orderby=title&show_count=0&title_li=&use_desc_for_title=1&child_of='.$this_category->cat_ID."&echo=0");
if($this_category !='<li>No categories</li>') {
echo '<ul class="ul-menu">'.$this_category.'</ul>';
}
}
?>
Image Attached Sample
Use this code into your page template.
$args = array (
'cat' => array(2,6,9,13),//use category id
'posts_per_page' => -1, //showposts is deprecated
'orderby' => 'date' //You can specify more filters to get the data
);
$cat_posts = new WP_query($args);
if ($cat_posts->have_posts()) : while ($cat_posts->have_posts()) : $cat_posts->the_post();
get_template_part( 'content', 'page' );
endwhile; endif;
I think its work for you. check and let me know

wordpress shortcode render content in dashboard also

I am using a simple wordpress shortcode
function my_recent_post()
{
echo 'hello';
}
add_shortcode( 'recent', 'my_recent_post' );
with the shortcode [recent] and its working fine and visible in front page,
but the problem is, its printing the hello in the dashboard also.
below is the screenshot, can anyone please help.
Update:
I was actually trying to show posts, so can you help me with this, because it renders the lists of posts in the dashboard itself like the "hello". I tried:
function lorem_function() {
global $post;
$args = array( 'posts_per_page' => 10, 'order'=> 'ASC', 'orderby' => 'title' );
$postslist = get_posts( $args );
foreach ( $postslist as $post ) :
setup_postdata( $post ); ?>
<div>
<?php the_date(); ?> <br /> <?php the_title(); ?> <?php the_excerpt(); ?>
</div>
<?php endforeach;
wp_reset_postdata();
return;
}
add_shortcode('lorem', 'lorem_function');
Based on your comments to me & Nikita Dudarev, what you need to do is create a variable to hold all the post information and then return it. Using the function you posted as an example:
function lorem_function() {
global $post;
$args = array( 'posts_per_page' => 10, 'order'=> 'ASC', 'orderby' => 'title' );
$postslist = get_posts( $args );
// create a variable to hold the post information
$html ="";
foreach ( $postslist as $post ) :
setup_postdata( $post );
$backgroundstyle = "";
// get the featured image and set it as the background
if ( has_post_thumbnail() ) { // make sure the post has a featured image
$imageurl = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'medium' ); // you can change "medium" to "thumbnail or full depending on the size you need
// add the css for the background image. You can include background-size etc ad required
$backgroundstyle = "background-image: url('".$imageurl[0]."');";
}
// add the information to the variable
$html .= '<div style="'.$backgroundstyle.'">';
$html .= get_the_date();
$html .= "<br />";
$html .= get_the_title();
$html .= get_the_excerpt();
$html .= "</div>";
endforeach;
wp_reset_postdata();
return $html;
}
add_shortcode('lorem', 'lorem_function');
Note that the_date(), the_title() and the_excerpt() all display the information (just like echo).
Instead you must use get_the_date(), get_the_title() and get_the_excerpt() - these get the same information, but instead of displaying it directly, they return it as a variable which you can then store in your html string to be returned.
Update:
As you don't want to use the variable name on each line for whatever reason, you can do it like this:
$html .= "<div>".get_the_date()."<br />".get_the_title().get_the_excerpt()."</div>";
I'm not sure why you specifically want to change it to do that - it makes absolutely no difference to how it works, it just makes it harder to read and identify any errors :-)
Your function must return a value, not output
function my_recent_post()
{
return 'hello';
}
add_shortcode( 'recent', 'my_recent_post' );

How to pass the results of a custom query in Wordpress to another function

This is I think really simple but I wasn't able to find an answer so far.
I am using a custom query in a function sc_start_custom_loop() which is fired via a custom shortcode.
function sc_start_custom_loop(){
$args_assets = array(
'post_type' => 'assets',
'posts_per_page' => -1,
'post__in' => $asset_ids,
);
$query_assets = new WP_Query($args_assets);
if($query_assets->have_posts()) : while($query_assets->have_posts()) : $query_assets->the_post();
output_custom_title();
endwhile; else:
_e('Sorry. No assets found!');
endif; wp_reset_postdata();
}
function output_custom_title(){
$ouput_title = '<p class="assets-title">'.$query_assets->post->post_title.'</p>';
return $output_title;
}
However, $query_assets->post->post_title in output_custom_title() is empty.
Thanks in advance for any help!
function sc_start_custom_loop(){
$args_assets = array(
'post_type' => 'assets',
'posts_per_page' => -1,
'post__in' => $asset_ids,
);
$query_assets = new WP_Query($args_assets);
if($query_assets->have_posts()) : while($query_assets->have_posts()) : $query_assets->the_post();
echo output_custom_title($query_assets);
endwhile; else:
_e('Sorry. No assets found!');
endif; wp_reset_postdata();
}
function output_custom_title($query_assets){
$ouput_title = '<p class="assets-title">'.$query_assets->post->post_title.'</p>';
return $output_title;
}

Correct PHP Syntax for custom WP loop

I am trying to insert a sorting option into my wordpress site. I already have it working, but need help using it with the wordpress loop correctly. Currently, I have:
On a page, there are options to sort alphabetically or chronologically:
Newest
Alphabetical
Sorting Code starts here, placed above the loop:
<?php $sort= $_GET['sort'];
if($sort == "title") { $order= "'orderby'=>'title','order'=>ASC'"; }
elseif($sort == "date") { $order= "'orderby'=>'date'"; }
else{ $order= "'orderby'=>'date','order'=>'DESC'"; }
?>
note: I am pretty sure the problem lies above in the variable $order
Wordpress Loop Using Variable $order as an argument
<?php $loop = new WP_Query( array( $order, 'post_type' => 'films', 'post_parent' => 0, 'posts_per_page' => -1 ) ); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
Wordpress loop stuff here
<?php endwhile; ?>
The loop displays items correctly, but the sorting links are not working. This code works very well with query_posts but I am trying to get this to work for WP_Query (above). Any ideas here?
UPDATE: This technique works great using query_posts like below (but I still need it working for WP_Query):
<?php $sort= $_GET['sort'];
if($sort == "title") { $order= "&orderby=title&order=ASC"; }
elseif($sort == "date") { $order= "&orderby=date"; }
else{ $order= "&orderby=date&order=DESC"; }
?>
<?php $posts = query_posts($query_string . $order); ?>
<?php if(have_posts()) : while(have_posts()) : the_post(); ?>
Wordpress Stuff Here
<?php endwhile; ?>
<?php endif; ?>
WP_Query expects associative array of parameters (array('param' => 'value')), whereas query_posts accepts only "query strings" ("param=value&param=value"). You are mixing both options, that's why it doesn't work. You need to change $order variable to be array instead of string, for example: $order = array('orderby' => 'title', 'order' => ASC');.
Answer above is not complete and may be misleading. WP_Query docs are here: https://codex.wordpress.org/Class_Reference/WP_Query . This class accepts boths styles, but they must be somewhat different formed. I don't know how exactly to do this, because it is not written in class docs, but you better use arrays, so:
if($sort == "title") { $order = array('orderby' => 'title', 'order' => 'ASC'); }
elseif($sort == "date") { $order= array('orderby' => 'date'); }
else{ $order= array('orderby' => 'date', 'order' => 'DESC'); }
FYI to convert between both types use functions parse_str(): http://php.net/manual/en/function.parse-str.php and http_build_query(): http://www.php.net/manual/en/function.http-build-query.php .

Categories