Looping through CMB2 attached posts - php

I've set up two different custom post types – one for categories and one for posts. I've attached the posts to the categories with the CMB2 plugin. I now want to display all the attached/related posts on each category page. I'm able to display the different ID's from the array, but not the post content.
Trying to get attached posts:
$attached_users = get_post_meta( get_the_ID(), 'pr2_cmb2_attached_posts', true );
foreach ( $attached_users as $user ) {
$employee = get_post( $user );
}
Trying to display the content from the attached posts
<?php while ( have_posts() ) : the_post(); ?>
<?php echo get_the_title($employee);?>
<?php echo get_the_post_thumbnail($employee);?>
<?php endwhile; // end of the loop. ?>

The plugin you are using gives you an array of ids.
Using this ids gives you the possibility to get the post object by using get_post($id).
The function gives you a post object: https://developer.wordpress.org/reference/functions/get_post/
But if you just want to use functions like get_the_title() you only need the post id, not the whole post object.
Well, you already got all the data you need and do not need to get the post object.
The plugins gives you an array of post ids.
// get array of post ids
$attached_users = get_post_meta( get_the_ID(), 'pr2_cmb2_attached_posts', true );
// loop through posts using post ids
foreach ( $attached_users as $user ) {
echo get_the_title( $user );
echo get_the_post_thumbnail( $user, 'thumbnail' );
}

Related

Display specific blog posts using ACF repeater in WordPress

I am trying to create simple repeter filed with ACF on my WordPress site. What I trying to get is to let admin display "Other interesting" blog posts at the bottom of the article.
So far I have created a loop with Wp_Query:
<?php
if( have_rows('featured') ): while( have_rows('featured') ) : the_row();
?>
<div class="container-fluid blog-container medium-container">
<div class="row">
<div class="col-12 blog-one">
<?php
// Get ACF sub field
$get_ids = get_sub_field('article_id');
// Make them display with comma
$show_ids = implode(', ', $get_ids);
// Featured blog list query
$blog = new WP_Query( array(
'posts_per_page' => 5,
'order' => 'DESC',
// Display post with specific ID using ACF repeater field inside array
'post__in' => array($show_ids)
));
...
...
...
<?php endwhile; endif; ?>
So the goal is to display numbers (posts ID's) included by admin on backend - liost them in array inside "post__in". But my code does not work. Any ideas how to fix that?
Advanced Custom Fields has a post object field type. You can configure it to accept multiple posts which it will then return as an array of posts objects (WP_Post) for you. This avoids any need for looping through a repeater field to build the arguments for a query.
Recommended Solution
Firstly, replace the repeater field with a post object field. Set the post type to post, allow null to true, and multiple to true.
You can then adapt your code to display those posts.
Example:
<?php if ( $featured_posts = get_field( 'featured' ) ) : ?>
<div class="container-fluid blog-container medium-container">
<div class="row">
<div class="col-12 blog-one">
<?php foreach ( $featured_posts as $post ) {
setup_postdata( $post );
// Do whatever you need to do to display the post here...
} ?>
. . .
<?php endif;
Documentation: https://www.advancedcustomfields.com/resources/post-object/
Fixing Your Existing Code
If you'd instead prefer to fix the code you already have, you need to rethink the loop.
Each time you iterate over your repeater field, you'll go in and grab the ID that was entered (subfield) for the post. You need to collect all of those up first and then use that to build your query.
Example:
$posts_ids = [];
if ( have_rows( 'featured' ) ) : while( have_rows( 'featured' ) ) : the_row();
$post_ids[] = get_sub_field( 'article_id' );
endwhile; endif;
// Let's drop any blank elements and force them all to integers.
$filtered_ids = array_map( 'intval', array_filter( $post_ids ) );
$blog_query = new WP_Query( [
'post__in' => $filtered_ids,
] );
You could add some more checks, clean this up, etc. Either way you're still far better off letting ACF do this for you and opting for the recommended solution instead.

How to display number of posts from a tag by id?

Trying
<?php
$number = 'apartamenty';
$terms = get_terms('post_tag', "number=$number");
if($terms){
foreach ($terms as $t){
echo $t->name.' : '.$t->count;
}
}?>
But this code show two tags...
To get the number of posts that are attached to a specific post tag, such as apartamenty, you would use get_term_by(). This WordPress Core construct lets you grab the WP_Term object for the specific post tag. In your case, you are wanting the post tag of apartamenty.
Okay, you'd have a function (i.e. to make it reusable) that runs this code and you'd pass in the actual post tag that you want to explore. This function is using the post tag slug.
function render_post_tag_post_count( $post_tag ) {
$term = get_term_by( 'slug', $post_tag, 'post_tag' );
if ( ! $term ) {
return;
}
// You get back an WP_Term object
// You can then use $term->count, which gives you the
// number of posts attached to this post tag.
echo (int) $term->count;
}
The property $term->count gives you the number of posts that are attached to that term.
You use it like this:
render_post_tag_post_count( 'apartamenty' );
What if I want to get it by post tag ID?
Take the above code and change the first argument from slug to id. Then you would pass the post tag's ID instead of its slug.
You can learn more about the parameters in WordPress Codex.

wordpress combine page and posts

I am creating a wp template based on 2013. I want to display a 'page' that has some content from a page and then 6 posts on it. These posts have been selected via the themes options panel using the settings api. So I can get at each one using
$options = get_option( 'osc_theme_options' );
The template i have been using so far is based on a page so i am guessing I need to change the loop in someway.
The loop goes:
<?php /* The loop */ ?>
<?php while ( have_posts() ) : the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>...
I want to know how to alter the loop so that it pulls in just the posts that have been selected. At the moment this template/loop is only pulling in the page - which I guess is fair enough.
Would it be possible to create 'another loop' maybe under the first that then brings in the selected posts - if so how?
Many thanks
Yes you can effectively create another loop under the existing loop to display the posts. I am not sure what $options = get_option( 'osc_theme_options' ); returns, i.e an array of Post ID's etc. In order to show the posts you need to do a custom loop:
// The Query
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() )
{
echo '<ul>';
while ( $the_query->have_posts() )
{
$the_query->the_post();
echo '<li>' . get_the_title() . '</li>';
}
echo '</ul>';
}
else
{
// no posts found
}
/* Restore original Post Data */
wp_reset_postdata();
This is taken from:
https://css-tricks.com/snippets/wordpress/custom-loop-based-on-custom-fields/
Also see the following:
https://digwp.com/2011/05/loops/
http://www.smashingmagazine.com/2013/01/14/using-wp_query-wordpress/
So effectively it all boils down to the $args variable as to which posts you will get. Here is an example of multiple ids
id=2,6,17,38
So if $options = get_option( 'osc_theme_options' ); returns an array of post ids like so:
array(
0=>1
1=>22
2=>27
)
You could probably do something like:
$args = "id=".implode($options,",");
This is the best advice I can give without deeper knowledge of the theme etc.

Wordpress, global post changed after query

I am developing a plugin. In this plugin, I've created a custom post type 'toto'.
In the admin page, I edit a custom post element with the following post id '82'.
In this page, I launch a query to retrieve elements with another post_type like that :
$featured_args = array(
'post_type' => 'other_type',
'post_status' => 'publish'
);
// The Featured Posts query.
$featured = new WP_Query( $featured_args );
// Proceed only if published posts with thumbnails exist
if ( $featured->have_posts() ) {
while ( $featured->have_posts() ) {
$featured->the_post();
if ( has_post_thumbnail( $featured->post->ID ) ) {
/// do stuff here
}
}
// Reset the post data
wp_reset_postdata();
}
Doing that the global $post changed. It is not the post with the id 82 anymore but the latest post element from the query.
I thought that the wp_reset_postdata() function will allow me to retrieve my current $post. I also tried with wp_reset_query() without changes.
Am I missing something?
Any help would be appreciated.
wp_reset_postdata() resets the main loop. If you want to access $post directly try
global $post;
$backup_post = $post;
//do another loop
wp_reset_postdata();
$post = $backup_post;

How can I have wordpress print posts whose IDs appear in an array?

I have an array of post IDs contained in $postarray. I would like to print the posts corresponding to these IDs in Wordpress.
The code I am using is as follows:
query_posts(array('post__in' => $postarray));
if (have_posts()) :
while (have_posts()) : the_post();
the_title();
the_excerpt();
endwhile;
endif;
Despite this, the loop prints the most recent posts and not the posts contained in the array. How can I have wordpress utilize the post IDs I supply in the array and print those posts in order?
You may have to break out of the standard WP Loop for this...
Try and use the get_post() function which takes the ID of a post and returns an object containing a the details of the post in the usual OBJECT or Associate or Numeric Array format.
See full-explanation of get_post().
You can come up with a custom routine to parse each item in the array. Here's a brief example:
function get_posts_by_ids( $postarray = null ) {
if( is_array( $postarray ) )
foreach( $postarray as $post ) {
$post_details = get_post( $post[0] );
// Title
echo $post_details->post_title;
//Body
echo $post_details->post_content ;
}
}
Hope this helps :)

Categories