WordPress, change template layout based on post category? - php

I'm trying to output all posts under custom post type "philosophy" on a page in a list. Alternating between categories "img-left" and "img-right".
I can get the posts to display ALL "philosophy" posts however i want to lay out the posts in two layouts depending on their custom category.
If the category is "img-right" i want the post to be shown with the text on the left and image on the right and vice-versa for "img-left".
I have tried the below code which doesn't work at all.
<?php
$args = array( 'post_type' => 'philosophy', 'posts_per_page' => 10 );
$loop = new WP_Query( $args );
if( in_category( 'img-right' ) ):
while ( $loop->have_posts() ) : $loop->the_post();
echo '<div class="col-md-12"><h2>';
the_title();
echo '</h2></div><div class="row content"><div class="col-md-6"';
the_content();
echo '</div><div class="col-md-5 offset-1 float-right">';
the_post_thumbnail('array(100,100)');
echo '</div></div>';
endwhile;
endif;
?>
by removing the "if" and "endif" i have the code that lists all the posts in one layout. What I need is conditionals that can output both "img-right" and "img-left" layouts based on the post's category. The only layout shown in my example above is "img-right".
Any help would be greatly appreciated. This PHP is making my head spin!

So...with all the help from the guys answering i figured it out using the CSS approach touched on by #Mohsin.
Here is my code:
<div id="content" class="col-12" role="main">
<?php get_template_part('loops/page-content'); ?>
</div>
<div class="row">
<?php
$args = array( 'post_type' => 'philosophy', 'posts_per_page' => 10 );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
echo '<div class="row content"><div class="col-md-12"><h2>';
the_title();
echo '</div><div class="col-md-6">';
the_content();
echo '</div><div class="col-md-6">';
the_post_thumbnail();
echo '</div></div>';
endwhile;
?>
I then applied this:
.row.content:nth-child(even) {
flex-direction: row-reverse;
}
and we're golden.
Thank you to everyone who helped.

If I understand correctly:
<?php $args = array( 'post_type' => 'philosophy', 'posts_per_page' => 10 ); ?>
<?php $loop = new WP_Query( $args ); ?>
<?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<div class="col-md-12"><h2>
<?php the_title(); ?>
</h2></div>
<div class="row content">
<?php if( in_category( 'img-left' ) ): ?>
<div class="col-md-5 offset-1 float-left">
<?php the_post_thumbnail('array(100,100)'); ?>
</div>
<?php endif; ?>
<div class="col-md-6">
<?php the_content(); ?>
</div>
<?php if( in_category( 'img-right' ) ): ?>
<div class="col-md-5 offset-1 float-right">
<?php the_post_thumbnail('array(100,100)'); ?>
</div>
<?php endif; ?>
</div>
<?php endwhile; ?>
The above code will output all of the posts, with a thumbnail to the left if it is category img-left and thumbnail to the right if in img-right (and outputting both if it is categorized as both, and neither if it is neither category. You may want different behavior, but it should be simple to adjust the conditionals).
If your template becomes anymore complicated, I would recommend moving sections out to template-parts/using functions like get_sidebar().

Related

Hide loop if no posts exist

I simply have a single loop that's pulling through a CPT, but I would like to hide the whole container div of the loop, if it has no posts...
I'm trying various iterations of this if statement surrounding the container:
<?php if( have_posts() ): ?>
<?php endif; ?>
But I can't seem to get it to work properly... The full code blog is here:
<?php if( have_posts() ): ?>
<div class="container default-strip-section">
<h2><?php the_field('vacancies_title'); ?></h2>
<div class="row justify-content-center">
<?php
$args = array(
'post_type' => 'vacancies',
'posts_per_page' => 9999
// 'orderby' => 'title',
// 'order' => 'ASC'
);
$the_query = new WP_Query( $args );
?>
<?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<div class="col-md-12">
<a href="<?php the_permalink(); ?>">
<p><?php the_title() ?></p>
</a>
</div>
<?php endwhile; wp_reset_postdata(); endif; ?>
</div>
</div>
<?php endif; ?>
Can anyone point out what I'm doing wrong? I'm sure I'm missing something simple! Thanks for looking!! :)
#rank's answer is nearly correct -- it needs the object instance before the_post() again:
<?php
$args = array(
'post_type' => 'vacancies',
'posts_per_page' => 9999, // If you're wanting to show all posts, use -1 here.
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
?>
<div class="container default-strip-section">
<h2><?php the_field('vacancies_title'); ?></h2>
<div class="row justify-content-center">
<?php
while ( $the_query->have_posts() ) :
$the_query->the_post();
?>
<div class="col-md-12">
<p><?php the_title(); ?></p>
</div>
<?php
endwhile;
?>
</div>
</div>
<?php
endif;
wp_reset_postdata();
?>
You need to put the html of the container after the if have_posts(), where you check if there are any posts. This way the whole container is not displayed when the if is not true.
But you are using a ACF field of the post where you are showing this list of vacancies. So we save the id into a variable to be able to view the value inside of your custom query called the_query (this is not a self-explanatory / good name). Why not call it vacancies_query to have a more readable code. Putting it together it should look like this:
<?php
$current_post = get_the_ID();
$args = array(
'post_type' => 'vacancies',
'posts_per_page' => 9999
);
$vacancies_query = new WP_Query( $args );
if ( $vacancies_query->have_posts() ) : ?>
<div class="container default-strip-section">
<h2><?php the_field('vacancies_title', $current_post); ?></h2>
<div class="row justify-content-center">
<?php while ( $vacancies_query->have_posts() ) : the_post(); ?>
<div class="col-md-12">
<a href="<?php the_permalink(); ?>">
<p><?php the_title() ?></p>
</a>
</div>
<?php endwhile; ?>
</div> <!-- row -->
</div> <!-- container -->
<?php else :
/* nothing to see here */
endif;
wp_reset_postdata();
?>

Show recent blog posts, but exclude current post

I want to display the 3 most recent posts at the bottom of my single-blog page, but without the current posts.
my code:
<div class="blog__posts">
<h2><?php esc_html_e('andere blogberichten', 'dfib-theme'); ?></h2>
<?php esc_html_e('alle blogberichten', 'dfib-theme'); ?>
<div class="blog__posts--wrapper">
<?php
$the_query = new WP_Query( array(
'posts_per_page' => 2,
));
?>
<?php if ( $the_query->have_posts() ) : ?>
<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<div class="blog__single">
<div class="blog__single--img" style="background-image: url(<?php echo get_the_post_thumbnail_url();?>);"></div>
<h2><?php the_title(); ?></h2>
<?php the_excerpt(); ?>
lees meer
</div>
<?php endwhile; ?>
<?php wp_reset_postdata(); ?>
<?php else : ?>
<p><?php __('No News'); ?></p>
<?php endif; ?>
</div>
</div>
It displays 3 posts, but when I visit the most recent post, the same post is displayed at the bottom again. Is there a way to exclude the current one every time?
I just found the solution on this website: https://pineco.de/snippets/exclude-current-post-from-wp_query/
I just added this piece to my query:
'post__not_in' => array(get_the_ID())
You have to exclude the current post with the post__not_in.
Add post__not_in in WP_Query array like below.
<?php
$the_query = new WP_Query( array(
'posts_per_page' => 2,
'post__not_in' => array( get_the_ID() )
));
?>

Loop inside content-single

I try to build an option for the user to highlight "related posts" to be shown at the bottom of a single post, so I put this code at the bottom of "content-single.php":
<div class="related-post">
<?php
$args = array( 'post__in' => array(38328, 38359, 21321) );//it's going to be the user choice, for example, I put three id's
$related_query = new WP_Query($args);
if ($related_query):
echo '<div class="row">';
while ($related_query->have_posts()): $related_query->the_post();?>
<div class="col-sm-4">
<?php
if (has_post_thumbnail()):
the_post_thumbnail();
endif;
?>
<?php the_title() . '<br/>'; ?>
</div>
<?php endwhile;
echo '</div>';
wp_reset_postdata();
?>
</div>
But in some posts, I get 8 diefferent posts, in some posts I don't get any posts (though I put only three id's in post__in).
I guess the problem is that I try to loop inside the main loop.
I tried with query_posts and with get_posts, doesn't work.
Any help will be appreciate!
I think that is related to the missing post_type argument. Yet you need some corrections in your loop structure:
<div class="related-post">
<?php
$args = array( 'post_type' => 'your_post_type', 'post__in' => array(38328, 38359, 21321) );
$related_query = new WP_Query($args);
if( $related_query->have_posts() ){ ?>
<div class="row"><?php
while( $related_query->have_posts() ){ $related_query->the_post();?>
<div class="col-sm-4"><?php
if( has_post_thumbnail() ) the_post_thumbnail();
the_title();?>
</div><?php
}
wp_reset_postdata();?>
</div><?php
}?>
</div>
UPDATE
Please try to add 'posts_per_page' => 3 to the args array.
I have a solution to this post. Hope so you are wrong with the query post.
<div class="related-post">
<?php
$args = array(
'post_type' => 'your_post_type',
'post__in' => array(38328, 38359, 21321),
'post_status'=>'publish'
);
$related_query = new WP_Query( $args );
?>
<?php if ( $related_query->have_posts() ) : ?>
<div class="row">
<?php while ( $related_query->have_posts() ) : $related_query->the_post(); ?>
<div class="col-sm-4">
<!-- do stuff ... -->
the_post_thumbnail();
the_title();
</div>
<?php endwhile; ?>
</div>
<?php endif; wp_reset_postdata(); ?>
</div>
Hope so it helps you to fetch out your Output Required.
Make sure you have post in the ID that you have mentioned in the post_in section.
Well, I manage to solve this by adding this 'ignore_sticky_posts' => 1 to the arguments. thanks #Pieter Goosen

ACF CPT two columns with each category

I have created custom post types and added some things through advanced custom fields.
Usually when i don't need to select from each category i would do something like this.
<?php if ( have_posts() ) : while ( have_posts() ) : the_post();
<?php the_field('name_of_field'); ?>
endwhile; else: ?>
<?php endif; ?>
However now i have to select if it is one of two particular categories and then put category 'tjanster' in left column and 'produkter' in right column within my bootstrap grid.
So it will be 50% 'tjanster', 50% 'produkter'.
I have been searching like crazy for an solution but only found some code for functions.php that didn't work and 5years old posts that didn't work for me.
What am i suposed to to so i can have some similar output like this?
<div class="container">
<div class="row">
<div class="col-sm-6">
<!-- Output of category tjanster. -->
</div>
<div class="col-sm-6">
<!-- Output of category produkter. -->
</div>
</div>
</div>
For each column you need a WP_Query(). See codex for reference: http://codex.wordpress.org/Class_Reference/WP_Query.
<div class="container">
<div class="row">
<div class="col-sm-6">
<?php // tjanster
$args1 = array(
'category_name' => 'tjanster'
);
$query1 = new WP_Query( $args1 );
while ( $query1->have_posts() ) : $query1->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
<?php endwhile;
wp_reset_postdata(); ?>
</div>
<div class="col-sm-6">
<?php // produkter
$args2 = array(
'category_name' => 'produkter'
);
$query2 = new WP_Query( $args2 );
while ( $query2->have_posts() ) : $query2->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
<?php endwhile;
wp_reset_postdata(); ?>
</div>
</div>
</div>

Wordpress Single.php advanced custom fields loop

I have a few advanced custom fields pages, they all have the same structure using a repeater field. I want them all to share the same single.php file. (which i believe should be fine?)
All my php is in the right order as its working fine when i add this above if have posts:
<?php
// The Query
$args = array(
'post_type' => 'chemicals'
);
$the_query = new WP_Query( $args );
?>
But once it is removed it is not getting the post information.. Maybe I have my php structure wrong? im very new to php and wordpress so any help would be great.
<div class="section group">
<div class="col span_3_of_12">
<?php wp_nav_menu(
array(
'menu' => 'consumables',
'container' => 'div',
'container_class' => 'product-menu',
'menu_class' => 'product-menu',
)); ?>
</div>
<?php if ( have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
<?php if( have_rows('product') ): ?>
<div class="col span_3_of_12">
<?php while( have_rows('product') ): the_row();
// vars
$title = get_sub_field('product_title');
$thumbnail = get_sub_field('thumbnail');
$blurb = get_sub_field('main_blurb');
$technical = get_sub_field('technical');
$description = get_sub_field('description');
?>
<a href""><img class="open-image" src="<?php echo $thumbnail; ?>"></a>
</div>
<div class="col span_6_of_12">
<div class="product-details">
<h4><?php echo $title; ?></h4>
<p><?php echo $blurb; ?></p>
</div>
<div class="product-tech">
<div class="technical">
<h5>Technical</h5>
<p><?php echo $technical; ?></p>
</div>
<div class="technical">
<h5>Description</h5>
<p><?php echo $description; ?></p>
</div>
</div>
<?php endwhile; ?>
</div>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>
I see that yours is a custom post. The file name of the template should be single-chemicals.php instead of single.php
From WordPress codex:
single-{post_type}.php If your custom post type were 'product', and/or query_var = "product", WordPress would look for
single-product.php to display the single or permalink of the post.

Categories