When producing a front page of a website and trying to grab five excerpts from the wordpress database it produces the excerpt, no problem, but it completely ignores my the_title, get_the_id and the_date:
foreach( $post as $posts) : setup_postdata($posts);
echo "<hr><h1>" . the_title( false, false, false ) . "</h1>";
echo the_excerpt( ) . "<br />";
echo "<a href='./index.php?p=" . get_the_ID( ) . "'><font color='white'>Read More...</font></a><br />";
echo "Published on: " . the_date( false, false, false, false );
endforeach;
Which produces the output:
http://i.stack.imgur.com/JNkxh.png
And as such, the 'Read More...' is directed to './index.php?p='
I have defined the get_posts statement as follows:
$args = array(
'posts_per_page' => 5,
'numberposts' => 5,
'offset' => 0,
'category' => $c,
'order_by' => 'post_date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => 'post',
'post_mime_type' => '',
'post_parent' => '',
'post_status' => 'publish',
'suppress_filters' => true );
$post = get_posts( $args );
Any ideas on what went wrong would be much appreciated.
I think the problem lies with setup_postdata function.
Quote from setup_postdata Codex Page:
Important: You must make use the global $post variable to pass the
post details into this function, otherwise functions like the_title()
don't work properly...
Example from that Codex page:
global $post;
// Assign your post details to $post (& not any other variable name!!!!)
$post = $post_object;
setup_postdata( $post );
...
So try renaming $post to $mypost and then use exact $post variable in the setup_postdata() like this:
foreach( $mypost as $post) : setup_postdata($post);
Related
I'm trying to create a custom shortcode in Wordpress that will let me place an attribute to specify a category and query within a custom post type called "case_studies". The taxonomy itself is called "case_study_categories" and I've set the default to be "furniture-interior", as you can see.
What I need is for the shortcode to look something like this:
[get_project_gallery order="ASC" tax_query="flooring"]
Ideally, the shortcode attribute I've placed would override the default of "furniture-interior" and instead use "flooring" to display the appropriate posts. Actually, I would think I don't even really need a default defined at all (so it would just get all the case_studies posts if no attribute is specified) but I can't get that to work either.
BTW, the attribute for order works exactly the way I would want - it overrides the defined default. I just can't figure out how to get this done with the $tax_query.
Any help on this would be very much appreciated. Thanks in advance all!
Here's my code:
function project_gallery_function($atts, $content = null) {
extract(shortcode_atts(array(
'order' => 'DESC',
'orderby' => 'date',
'tax_query' => array(
array(
'taxonomy' => 'case_study_categories',
'field' => 'slug',
'terms' => 'furniture-interior'
)
)
), $atts));
$args = array(
'post_type' => 'case_studies',
'post_status' => 'publish',
'posts_per_page' => '4',
'order' => $order,
'orderby' => $orderby,
'tax_query' => array($tax_query)
);
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
echo '<aside class="grid-gallery four-col grid-gap-4">';
while ( $the_query->have_posts() ) {
$the_query->the_post();
$gallery_thumb = get_the_post_thumbnail_url( $page->ID, 'thumbnail' );
echo '<img src="'. $gallery_thumb .'" alt="" />';
}
echo '</aside>';
}
/* Restore original Post Data */
wp_reset_postdata();
}
add_shortcode( 'get_project_gallery', 'project_gallery_function' );
You shouldn't be worrying about the whole entire tax_query unless you plan on actually redoing the whole tax_query. You should consider changing it to just using $terms instead, since that's the only part you're replacing with the shortcode (you don't need to rebuild the whole array).
Secondly, make sure your code is normalized with your spacing and indentation - future you appreciates the forethought!
Lastly, you could consider passing even more variables to the array to make it a bit more extensible - $posts_per_page, $taxonomy etc.
function project_gallery_function( $atts, $content = null ){
extract( shortcode_atts( array(
'terms' => 'furniture-interior',
'field' => 'slug',
'order' => 'DESC',
'orderby' => 'date',
'taxonomy' => 'case_study_categories',
'post_type' => 'case_studies',
'posts_per_page' => 4,
), $atts ) );
$tax_query = array(
array(
'taxonomy' => $taxonomy,
'field' => $field,
'terms' => explode(',', preg_replace('/\s+/', '', $terms)), // Force to array, allowing comma sep values
)
);
$args = array(
'post_type' => $post_type,
'post_status' => 'publish',
'posts_per_page' => $posts_per_page,
'order' => $order,
'orderby' => $orderby,
'tax_query' => array( $tax_query )
);
// The Query
$the_query = new WP_Query( $args );
// The Loop
if( $the_query->have_posts() ){
echo '<aside class="grid-gallery four-col grid-gap-4">';
while( $the_query->have_posts() ){
$the_query->the_post();
if( $gallery_thumb = get_the_post_thumbnail_url( $page->ID, 'thumbnail' ) ){
printf( '<img src="%s" alt="" />', get_the_permalink(), $gallery_thumb );
}
}
echo '</aside>';
}
/* Restore original Post Data */
wp_reset_postdata();
}
add_shortcode( 'get_project_gallery', 'project_gallery_function' );
A few other notes, get_the_post_thumbnail_url() returns a falsey value if it doesn't exist, so you should wrap that in an if statement incase the image can't be found for some reason (corrupted, removed, forgot to add, etc). Also you have a $page->ID variable in get_the_post_thumbnail_url() - but don't seem to have a global $page in the function? Make sure that's the variable you want to use there.
Using code like what I've provided will let you do what you want, [get_project_gallery order="ASC" terms="flooring"], or even add multiple [get_project_gallery order="ASC" terms="flooring,something-else,a-third-thing"] - just match up the shortcode attributes with the parameter you want to override: [get_project_gallery order="ASC" terms="flooring,something-else,a-third-thing" posts_per_page="15"]
I'm currently working a wordpress loop to retrieve blog posts, their titles, featured image, date and category. With that said, I'm attempting to offset the loop begin on the 5th descending post because the previous 4 are referenced earlier on the page.
I have successfully offset the posts but it seems that I can't grab the category.
<?php
$post_args = array(
'post_type' => 'post',
'post_status' => 'publish',
'order' => 'DESC',
'offset' => 4
);
$post_query = new WP_Query($post_args);
if ($post_query->have_posts() ):
$count = 1;
$terms = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => true
) );
while ( $post_query->have_posts() ) : $post_query->the_post();
$feat_img = wp_get_attachment_url( get_post_thumbnail_id() );
?>
<div class="col-sm-3 col-xs-6">
<div class="featured-img" style="background-image: url(<?php echo $feat_img; ?>)"
<?php the_date('F j Y', '<h6>', '</h6>'); ?>
<h3><?php the_title(); ?></h3>
<div class="category"><?php echo $terms->name; ?></div>
</div>
</div>
I tried a slightly different approach and was able to get each posts category using a foreach loop, followed by a while and if loop. While I successfully got each posts category, the offset wasn't cooperating. Perhaps I'm overthinking it. Here's my other attempt at this.
<?php
$terms = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => true,
) );
$count = 1;
foreach ( $terms as $term ) :
$post_args = array(
'offset' => 4,
'post_type' => 'post',
'order' => 'DESC',
'post_status' => 'publish',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $term->slug
)
),
);
$post_query = null;
$post_query = new WP_Query($post_args);
if ( $post_query->have_posts() ) :
while ($post_query->have_posts() ) : $post_query->the_post();
$feat_img = wp_get_attachment_url( get_post_thumbnail_id() );
?>
Anyone mind lending a hand to help accomplish both tasks? Any input would be greatly appreciated. Thank you in advance.
you need to set "posts_per_page" to some other value than -1, it's explained well in documentation
https://codex.wordpress.org/Class_Reference/WP_Query
posts_per_page (int) - number of post to show per page (available
since Version 2.1, replaced showposts parameter). Use
'posts_per_page'=>-1 to show all posts (the 'offset' parameter is
ignored with a -1 value). Set the 'paged' parameter if pagination is
off after using this parameter. Note: if the query is in a feed,
wordpress overwrites this parameter with the stored 'posts_per_rss'
option. To reimpose the limit, try using the 'post_limits' filter, or
filter 'pre_option_posts_per_rss' and return -1
I am adding an image from media in every single post that are created.
To get the attached image and url of that post, I am implementing this code:
$args = array(
'post_type' => 'attachment',
'post_mime_type' => 'image',
'numberposts' => 5,
'post_status' => null,
'post_parent' => 'any', // any parent
);
$attachments = get_posts($args);
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
setup_postdata($attachment);
$v =$attachment->ID;
$imageurl = wp_get_attachment_url($v);
$postlink = get_permalink($v);
}
The above code works fine for retrieving image url. My question is how do I pass post ID in get_permalink() to make sure that I get link of that post. I know that passing $v in get_permalink() is wrong.
There is a code spinet to print attachment posts.
$args = array(
'post_type' => 'attachment',
'post_mime_type' => 'image',
'posts_per_page' => 5,
'post_status' => 'inherit',
'post_parent' => 'any', // any parent
);
$loop = new WP_Query($args);
while ( $loop->have_posts() ) : $loop->the_post();
global $post;
echo '<pre>';
print_r($post);
echo '</pre>';
endwhile; wp_reset_query();
Its depending which ID you are looking for inside the loop
$post-ID : That return the post ID for attachment post.
$post->post_parent : It returns the current attachment post parent post ID.
Hi I have created my own custom post type within Wordpress to contain projects that i can call via my theme files.
I am new to creating my own themes. I currently am using the following code in my single.php file to call in related articles based on the category of the blog post.
<?php
// Default arguments
$args = array(
'posts_per_page' => 3, // How many items to display
'post__not_in' => array( get_the_ID() ), // Exclude current post
'no_found_rows' => true, // We don't ned pagination so this speeds up the query
);
// Check for current post category and add tax_query to the query arguments
$cats = wp_get_post_terms( get_the_ID(), 'category' );
$cats_ids = array();
foreach( $cats as $wpex_related_cat ) {
$cats_ids[] = $wpex_related_cat->term_id;
}
if ( ! empty( $cats_ids ) ) {
$args['category__in'] = $cats_ids;
}
// Query posts
$wpex_query = new wp_query( $args );
// Loop through posts
foreach( $wpex_query->posts as $post ) : setup_postdata( $post ); ?>
<div class="col-md-4 related-post">
<?php the_post_thumbnail('large'); ?>
<?php the_title(); ?>
</div>
<?php
// End loop
endforeach;
// Reset post data
wp_reset_postdata(); ?>
In my new post type "projects" i would like to call in related projects. Which im assuming would be very similar code except i need to stop it looking for posts and instead look for my projects.
Here is my code for new post type:
// Projects
add_action( 'init', 'create_post_type' );
add_post_type_support( 'bw_projects', 'thumbnail' );
add_post_type_support( 'bw_projects', 'custom-fields' );
function create_post_type() {
register_post_type( 'bw_projects',
array(
'labels' => array(
'name' => __( 'Projects' ),
'singular_name' => __( 'Projects' )
),
'public' => true,
'has_archive' => true,
'taxonomies' => array( 'category','post_tag'),
)
);
}
What would i need to change in my first code snippet in order to look for bw_projects and not look for 'posts' anymore. I tried playing around and changing certain lines myself but i caused more issues and stopped the page loading. Is this even right i can use the same code, slightly altered or would i need something completely different?
Thanks in advance.
You can get any post type that you require using get_posts();
<?php $args = array(
'posts_per_page' => 5,
'offset' => 0,
'category' => '',
'category_name' => '',
'orderby' => 'date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => 'projects',
'post_mime_type' => '',
'post_parent' => '',
'author' => '',
'author_name' => '',
'post_status' => 'publish',
'suppress_filters' => true
);
$posts_array = get_posts( $args ); ?>
Simply set the 'post_type' argument to that of you custom post type, to get only these posts. You can also set the number of post, and filter by category etc.
You can find more info in the codex.
Alternatively, if you wanted to keep something similar to your existing code you could try using 'pre_get_posts' to filter the query to just your projects. However you'd need to remember to add / remove this filter so it only operates on the queries that need it.
To display the posts you can use a simple foreach to churn them out. You#d obviously want to do some sort of styling to get the layout correct:
$args = array("posts_per_page" => 10, "orderby" => "comment_count");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}
Or a really concise way of doing all of the above would be something like:
$args = array("posts_per_page" => 5, "post_type" => "projects");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}
This question is about tidying up code and better management of said code butI'm a complete novice when it comes to PHP so would appreciate a little help.
I have this code:
<?php
$thumb_id = get_post_thumbnail_id(get_the_ID()); // gets the post thumbnail ID
$args = array(
'order' => 'ASC',
'orderby' => 'rand',
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => 1,
'exclude' => $thumb_id
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
echo wp_get_attachment_image($attachment->ID, 'full', false);
}
}
?>
What it does isn't important for reference, the above code gets random images from a Wordpress post randomly generates one of them in a DIV. I want this functionality across many templates but I don't want to cram my PHP files with it as my files will get messy and inefficiently large.
2 questions.
Do I need to change the code above in order to put it within functions.php?
How can I reference the above code (that will be within my functions.php) using a short one liner that I can reuse across many different templates?
You may like to try putting the snippet in to a function, inside functions.php, and passing it a few parameters, allowing the usage to be more flexible.
Untested, but this takes an array of options, and overwrites the default values (e.g for changing the order or orderby etc on a per-use basis). As an optional parameter you can pass a post_id, in case you want to query a post that isn't the current one.
It also returns an array of rather than outputs them directly, which can be seen as the preferred way of working with functions.
// functions.php
function get_random_post_image($options=array(), $post_id=NULL) {
if($post_id != NULL) :
$thumb_id = get_post_thumbnail_id($post_id);
else :
$thumb_id = get_post_thumbnail_id(get_the_ID());
endif;
$default_args = array(
'order' => 'ASC',
'orderby' => 'rand',
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => 1,
'exclude' => $thumb_id
);
// merge custom options
$args = array_merge($default_args, $options);
$attachments = get_posts($args);
if ($attachments) {
$images = array();
foreach ($attachments as $attachment) {
$images[] = wp_get_attachment_image($attachment->ID, 'full', false);
}
return $images;
}
return false; // or, return default image/placeholder
}
// and within your template/posts:
if(function_exists('get_random_post_image')) :
$images = get_random_post_image(array('order'=>'DESC')); // overwrite `ASC`
if($images) :
foreach($images as $img) {
echo '<div class="post-img"> ' . $img . '</div>';
}
else :
echo 'No images!';
endif;
endif;
not perfect; but you could extend it easily enough.
1. You need to get out the <?php and ?> if you already put your code inside those tags
example functions.php:
<?php
blah blah
....
// your code here
$thumb_id = get_post_thumbnail_id(get_the_ID()); // gets the post thumbnail ID
$args = array(
'order' => 'ASC',
'orderby' => 'rand',
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => 1,
'exclude' => $thumb_id
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
echo wp_get_attachment_image($attachment->ID, 'full', false);
}
}
// be careful, only one "?>" in the file, no nested "<?php ?>" blocks
?>
2. Use include(), include_once(), require() or require_once() and save your function in another file, so you can reference that file.
random_img.php
<?php
$thumb_id = get_post_thumbnail_id(get_the_ID()); // gets the post thumbnail ID
$args = array(
'order' => 'ASC',
'orderby' => 'rand',
'post_type' => 'attachment',
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => 1,
'exclude' => $thumb_id
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
echo wp_get_attachment_image($attachment->ID, 'full', false);
}
}
?>
functions.php
<?php
blah blah
....
include ("random_img.php")
?>