Display custom posts with shortcode - php

I've been searching this forum for help for 2 days now but I can't find a solution for what I'm trying to achieve.
I have a custom post type called "product" and inside each post in that post type there are two custom fields called produktnamn(a textfield with product name) and produktbild(a product image). that's it.
Now I need a shortcode to display a particular post in that post type by entering it's slug (which is the same as it's name).
like this:
[product name="myproduct"]
That will render the name and product image inside some HTML tags.
Please help!
My code so far:
//Product image
function cpt_content_func($atts){
extract( shortcode_atts(['name' => null], $atts ) );
$args = [
'name' => $slug,
'post_type' => 'product',
'numberposts' => 1
];
$posts = get_posts( $args );
$post = $post[0];
$title = $post->title;
$id = $post->ID;
get_post_meta('produktbild', $id);
$content = $post[0]->post_title;
return '<h3>'.$content.'</h3>';
}
add_shortcode('product','cpt_content_func');
Solved it. Here's the code!
function display_custom_post_type( $atts ){
// Handle the attributes
$atts = shortcode_atts(
array(
'cat' => ' '
),
$atts, 'products_by_cat' );
// Set default values for the post
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'post_status' => 'publish',
'category' => $atts['cat']
);
// Get posts
$posts_array = get_posts( $args );
// Check if posts exist
if( !empty($posts_array) ){
$string = '<div class="row">';
foreach( $posts_array as $post ){
$string .= '<div class="col-sm-3 text-center">';
$string .= '<div class="product-container">';
$string .= '<a href="' . get_field( "order_link", $post->ID ) . '">';
$string .= '<img class="product-img" src="' . get_field( "produktbild", $post->ID ) . '">';
$string .= '</a>';
$string .= '</div>';
$string .= '<p class="product-btn">' . get_field( "produktnamn", $post->ID ) . '</p>';
$string .= '</div>';
}
$string .= '</div>';
} else {
// Didn't find any posts.
}
// Return HTML
return $string;

I agree with James--I'd just use woocommerce.
But you first step has to be learning how to build a shortcode: http://code.tutsplus.com/tutorials/wordpress-shortcodes-the-right-way--wp-17165
Once you've attempted creating your own shortcodes, if things still aren't working, that's the time to ask for help.

Related

shortcode for related post in wp

I’m using bellow function for related post shortcode and I have a question about it. It’s supposed to display posts with related tag (I don't why it shows just random posts) but I want to use something like [rps tag=google] and the function just return a post has a tag as “google”, I mean nothing related to the current post tags. How can I do that?
This is the code:
add_shortcode('rps', 'fphp_get_related_posts');
function fphp_get_related_posts() {
$reset_post = $post;
global $post;
$post_tags = wp_get_post_tags($post->ID);
if ($post_tags) {
$post_tag_ids = array();
foreach($post_tags as $post_tag) $post_tag_ids[] = $post_tag->term_id;
$args=array(
'tag__in' => $post_tag_ids,
'post__not_in' => array($post->ID),
'posts_per_page' => 1,
'orderby' => 'rand',
);
$related_query = new wp_query( $args );
if (intval($related_query->post_count) === 0) return '';
$html = '<div class="rps"><ul><h3>Also read:</h3>';
$related_query->the_post();
$html .= '<li style="width:250px">';
$html .= '<div class="relatedthumb"><a rel="external" href="'. get_the_permalink(). '">';
$html .= get_the_title() . '</a>';
$html .= '</div></li>';
}
$post = $reset_post;
wp_reset_query();
$html .= '</ul></div>';
return $html;
}
If you want to show given tag post, then no need to use wp_get_post_tags(), because its return multi tags. try this code,
function fphp_get_related_posts( $atts ) {
$atts = shortcode_atts( [
'tag' => '',
], $atts );
$args = [ 'posts_per_page' => 1, 'tag' => $atts['tag'], 'orderby' => 'rand' ];
$query = new WP_Query( $args );
if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();
ob_start(); ?>
<!-- your html here -->
<?php endwhile; endif; wp_reset_postdata();
return ob_get_clean();
}
add_shortcode( 'rps','fphp_get_related_posts' );

WP Query foreach loop - repeats the same post

I have spent hours on this - hoping someone who knows a bit of PHP can solve it painlessly.
I have a Wordpress query loop which needs to be concatenated together. It kind of works, but I have requested 6 posts, and all 6 are the same!
Here's the code snippet which returns the duplicate posts:
////* New tab *//////
$args = array( 'numberposts' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ($postslist as $post) : setup_postdata($post);
$content .= '<li><a href="' . get_permalink() . '"</a>' . get_the_title() . '</a></li>';
endforeach;
$content .= '</ul></div>';
return $content; // prints all the contents stringed together
This code produces this list:
Any help appreciated...at all! Thanks.
It looks like your code example is taken from inside a function.
a) Please try this:
// ... cut ...
global $post;
$args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ( $postslist as $post ) : setup_postdata( $post );
$content .= sprintf( '<li>%s</li>',
get_permalink(),
get_the_title() );
endforeach;
$content .= '</ul></div>';
wp_reset_postdata();
return $content; // prints all the contents stringed together
where I added the global $post declaration so setup_postdata( $post ) can modify the global $post object.
b) Or try this:
// ... cut ...
$args = array( 'posts_per_page' => 6, 'orderby' => 'post_date' );
$postslist = get_posts( $args );
$content .= '<div class="tab" id="new"><ul>';
foreach ( $postslist as $post ) :
$content .= sprintf( '<li>%s</li>',
get_permalink( $post->ID ),
get_the_title( $post->ID ) );
endforeach;
$content .= '</ul></div>';
return $content; // prints all the contents stringed together
where I used the post id as an input argument for get_permalink() and get_the_title().
c) You can also use the raw post title: $post->post_title or if you want to take it through the the_title filter with:
echo apply_filters( 'the_title', $post->post_title );
So to wrap it up:
Notice that get_the_title() is based on get_post(), and if you don't use an input argument, then it will try to use the global $post object:
if ( empty( $post ) && isset( $GLOBALS['post'] ) )
$post = $GLOBALS['post'];
Therefore you always get the same global post object title (usually from the main query) if you don't modify the global object within the secondary loop.
Hope this helps.

Shortcode to list post titles from certain category

i found this great snippet of code on http://codex.wordpress.org/Template_Tags/get_posts and I edited it a little to suit me. It works.
<p>
<?php
$args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => 1 );
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
<?php the_title(); ?>
</br>
<?php endforeach;
wp_reset_postdata();?>
</p>
I would like to transform it into a shortcode with one changeable variable - category id. But, well, since I don't know php, all I came up is:
function tytuly_postow($atts) {
extract(shortcode_atts(array(
'id' => 1,
), $atts));
$args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => $id );
$q ="<p>
<?php
$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
<?php the_title(); ?>
</br>
<?php endforeach;
wp_reset_postdata();?>
</p>";
}
add_shortcode('tytuly','lista_postow');
Of course, it doesn't work. I use Karma theme and added it in shortcodes.php file. Please, help :)
The code you have is certainly on the right track. Here's how I'd do it:
function tytuly_postow( $atts ) {
extract( shortcode_atts( array(
'id' => 1,
), $atts ) );
$posts = get_posts( array(
'posts_per_page' => -1,
'post_status' => 'publish',
'cat' => $id,
) );
$output = '';
if ( $posts ) {
$output .= '<p>';
foreach ( $posts as $post ) {
$output .= apply_filters( 'the_title', $post->post_title ) . '<br />';
}
$output .= '</p>';
}
return $output;
}
add_shortcode( 'tytuly', 'tytuly_postow' );
Offset by default is 0 so you don't need to add it as an argument. I've set posts_per_page to -1. This means get all.
Since you're just listing off titles it may make sense to order them by title. At the moment they'll be ordered by date descending.
I'm setting output to a blank string and returning output at the end. This means no matter what happens the shortcode will always return something, even if that something happens to be an empty string.
Then I'm checking if posts were found. If that's the case I'm adding a paragraph tag before and after the foreach. This was to match your original code.
Finally it loops through each post and uses the_title filter on the post titles then ends each title with a break tag.
By taking a look at the Shortcode API and add_shortcode Function Reference, you can check that the parameters of function add_shortcode are $tag and $func.
So, to start fixing your code, you need to fix it:
//[tutuly]
function tytuly_postow($atts) {
...
}
add_shortcode('tytuly', 'tytuly_postow');
By doing this, you will have a working structure for your shortcode. Now, your second mistake is that your function needs to return a value, thats what your shortcode will be transformed into. To do this, you need to use return.
Edit: Plus, your logic to retrive posts names was wrong, so I fixed it:
So, your fixed code will look like:
//[tutuly id="1"]
function tytuly_postow($atts) {
extract(shortcode_atts(array(
'id' => 1,
), $atts));
$args = array(
'posts_per_page' => -1,
'category' => $id,
'post_status' => 'publish'
);
$myposts = get_posts($args);
if ($myposts) {
$q = '<p>';
foreach ($myposts as $post) {
$q .= apply_filters('the_title', $post->post_title) . '<br />';
}
$q .= '</p>';
} else {
$q = '';
}
return $q;
}
add_shortcode('tytuly','tytuly_postow');
posts_per_page is now set to -1 to retrieve all posts,
post_status is used to retrieve only posts that are published.
If you want to retrieve links for your posts, instead of just the name, you can change this line:
$q .= apply_filters('the_title', $post->post_title) . '<br />';
to
$q .= '<a href=' . get_permalink($post->ID) . '>' . apply_filters('the_title', $post->post_title) . '</a><br />';
Notice that if you don't have enough programming skills, you can always use the awesome GenerateWP Shorcodes Generator.

Wordpress missing attachment link

I have attached a pdf to a post under a custom post type - I've created a link for users to download but all that displays is Missing Attachment. I've checked the admin panel and I've definitely attached it to a post - I can't seem to get it to link to it.
My Code is:
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 10;
$args = array( 'post_type' => 'stores', 'orderby' => 'title', 'order' => 'asc', 'posts_per_page' => $paged );
$success = new WP_Query( $args );
$output = '';
$output .= sprintf( "<table class='stores'>" );
$output .= sprintf( "<tr><th>File Name</th><th>Date added</th><th>Download</th></tr>" );
while( $success->have_posts() ) {
$success->the_post();
$output .= sprintf( "<tr>" );
$output .= sprintf( "<td>%s</td>", get_the_title() );
$output .= sprintf( "<td>%s</td>", get_the_date() );
$output .= sprintf( "<td><a href='%s'>link</a></td>", wp_get_attachment_link() );
$output .= sprintf( "<tr>" );
}
$output .= sprintf( "</tr></table>" );
return $output;
wp_get_attachment_link() requires the ID of your attachment, not the post that the attachment is attached to, so that it can fetch the link. -
wp_get_attachment_link(1234); // Replace 1234 with your relevant ID
To find your relevant ID, log in to your admin area, click Media and the click on the attachment you wish to link to. Finally, check address bar and you'll see something like http://www.mywebsite.com/wp-admin/post.php?post=7814&action=edit - The ID you require is whatever comes after post=.
Other Suggestions
Firstly, I notice in your query your are mixing up your posts_per_page and paged parameters. Essentially you are telling your query to check to see if there is a page set in the query string, else show you page 10. Try this instead -
$args = array(
'post_type' => 'stores',
'orderby' => 'title',
'order' => 'ASC',
'paged' => get_query_var('paged'), // The page to show
'posts_per_page' => 10 // How many posts to show on the page
);
I also notice that you use sprintf() regardless of whether or not it's actually required. This will slow things down, but to go even further, for just one variable I wouldn't use it at all as it's faster not too. Note also that swapping the " quotes for ' quotes will speed things up (as '"' checks for variable references to convert to the String). For you Loop I recommend this code -
$success = new WP_Query( $args );
if( $success->have_posts() ) :
$output.= '<table class="stores">';
$output.= '<tr><th>File Name</th><th>Date added</th><th>Download</th></tr>';
while( $success->have_posts() ) : $success->the_post();
$child_args = array(
'numberposts' => 1,
'order' => 'ASC',
'post_mime_type' => 'pdf',
'post_parent' => get_the_ID(),
'post_status' => null,
'post_type' => 'attachment',
);
$attachments = get_children($child_args);
if(attachments) :
$attachment_ID = $attachment[0]->ID
endif;
$output.= '<tr>';
$output.= '<td>'. get_the_title() .'</td>';
$output.= '<td>'. get_the_date() .'</td>';
$output.= '<td>link</td>';
$output.= '<tr>';
endwhile;
$output.= '</tr></table>';
endif;
return $output;
Finally, if you don't specifically need to return your output you could just output it direct, again speeding things up slightly.

Output recent posts and excerpt in Wordpress, not of current page

I am trying to output recent posts plus the excerpt onto my homepage using the following code:
<?php
$args = array( 'numberposts' => '3' );
$recent_posts = wp_get_recent_posts( $args );
foreach( $recent_posts as $recent ){
echo '<li><a href="' . get_permalink($recent["ID"]) . '" title="Look '.$recent["post_title"].'" >' . $recent["post_title"].'</a>' . $recent["post_excerpt"] . ' </li> ';
}
?>
This seems to output the title and the permalink just fine, however it does not output the excerpt.
Hope someone can help
put the array in your desired custom post like this in your functions.php
$args = array(
'supports' => array('title','editor','author','excerpt') // by writing these lines an custom field has been added to CMS
);
For retrieving at front end
echo $post->post_excerpt; // this will return you the excerpt of the current post
try this one
<?php
$args = array( 'post_type'=>'post',
'orderby'=>'post_date',
'post_status'=>'publish',
'order' => 'DESC',
'showposts' => '3' );
$recent_posts = get_posts( $args );
foreach( $recent_posts as $recent ){
echo '<li><a href="' . get_permalink($recent->ID) . '" title="Look '.$recent->post_title.'" >' . $recent->post_title.'</a>' . $recent->post_excerpt . ' </li> ';
}
?>
Make sure your post_excerpt is not empty
If you want to add the post_excerpt then use wp_update_post
$my_post = array();
$my_post['ID'] = 37;// it is important
$my_post['post_excerpt'] = 'This is the updated post excerpt.';
wp_update_post( $my_post );
As per your request in comments i am showing you the demo to update the post by copying the post_title in the post_excerpt so here you go
<?php
$args = array( 'post_type'=>'post',
'orderby'=>'post_date',
'post_status'=>'publish',
'order' => 'DESC',
'showposts' => '3' );
$recent_posts = get_posts( $args );
foreach( $recent_posts as $recent ){ // this foreach to add the excerpt
$my_post = array();
$my_post['ID'] = $recent->ID;// it is important
$my_post['post_excerpt'] = $recent->post_content;
wp_update_post( $my_post );
}
foreach( $recent_posts as $recent ){ // this foreach to show the excerpt
echo '<li><a href="' . get_permalink($recent->ID) . '" title="Look '.$recent->post_title.'" >' . $recent->post_title.'</a>' . $recent->post_excerpt . ' </li> ';
}
?>
wp_update_post
Also see wp_insert_post

Categories