On my blog's archive page if I click on a month, it takes me to a page showing me all the posts that I've created that month (obviously). Is there a way to filter that page so it only shows me posts from one of my categories?
archive.php
<?php if ( have_posts() ) : ?>
<div class="rightColumn">
<?php
while ( have_posts() ) : the_post();
get_template_part( 'content', get_post_format() );
endwhile;
// Previous/next page navigation.
twentyfourteen_paging_nav();
else :
get_template_part( 'content', 'none' );
endif;
?>
</div>
<?php
get_footer();
Thanks.
I ended up finding a solution that worked for me:
function only_show_blog_posts( $query ) {
// Only modify the main loop query
// on the front end
if ( $query->is_main_query() && ! is_admin() ) {
// Only modify date-based archives
if ( is_date() ) {
// Only display posts from category ID 1
$query->set( 'cat', '12' );
}
}
}
add_action( 'pre_get_posts', 'only_show_blog_posts' );
try using the pre_get_posts hook, something along the lines of:
function filter_by_category( $query ) {
if ( $query->is_archive() && $query->is_main_query() && basename( $_SERVER['PHP_SELF'] ) == 'archive.php' ) {
$category_id = get_cat_ID( 'THE_CATEGORY_NAME' ); //change to the actual name of the category you are filtering with
$query->set( 'cat', $category_id );
}
}
add_action( 'pre_get_posts', 'filter_by_category' );
you can drop this code into your functions.php file
you can find more info about the pre_get_posts hook here
That simple hook helped me too. I modified the function a little to get the category Id from $_GET:
function only_show_blog_posts( $query ) {
if ( $query->is_main_query() && ! is_admin() ) {
$catId = (int)$_GET['catId'];
if ( is_date() && is_int($catId))
$query->set( 'cat', $catId);
}
}
No filters or hooks necessary. Just pass the category you want to filter for in the URL.
With an ID
https://myblog.com/2018/?cat=1234
With a slug
https://myblog.com/2018/?category_name=my-category-slug
Related
I need the last post not to be displayed on the post archive page.
What should I do to do this?
You can see the page code of my page archive below.
<?php
/* Start the Loop */
$i=0;
while ( have_posts() ) :
if($i==5) {
echo '
adv code
';
}
the_post();
get_template_part( 'template-parts/content', 'archive' );
$i++;
endwhile;
custom_pagination();
else :
get_template_part( 'template-parts/content', 'none' );
endif;
?>
note: Only the last post. Because the last post of the page archive is displayed manually in the slider of that page. I do not want the last post in the list to be displayed and repeated.
Using offset to the query will do the trick like
function exclude_last_post( $query ) {
if ( $query->is_main_query() && !is_admin() && is_archive() ) {
$query->set( 'offset', '1' );
}
}
add_action( 'pre_get_posts', 'exclude_last_post' );
I'm working on customizing the search results loop within WordPress. I'm displaying search results of two custom post types: Webinars and Research. I'd like to segment the Webinars and Research into their own sections with a heading for each section.
CURRENT LOOP
<?php
if( have_posts() ){
$types = array('webinars', 'research');
foreach( $types as $type ) {
while( have_posts() ){
the_post();
if( $type == get_post_type() ){
get_template_part('loop-templates/content', 'search');
}
}
rewind_posts();
}
}
?>
Any suggestions on getting all Webinars to live in their own div container, and all Research to live in their own div container?
You could simply specify the post type (doesn't have to be in the loop) for each of them straight in the search template. if you want 2 different templates, 1 for webinars and 1 for research, you could do something like that:
<?php if( have_posts() ){
if ( 'webinars' === get_post_type() ):
echo '<h2>Webinars</h2>';
while( have_posts() ){
the_post();
//Template for webinars
the_title(); echo '<br/>';
};
endif;
if ( 'research' === get_post_type() ):
echo '<h2>Research</h2>';
while( have_posts() ){
the_post();
//Template for research
the_title(); echo '<br/>';
};
endif;
}; ?>
You can also restrict the search parameters to go further using pre_get_posts
from the function.php file:
<?php add_action( 'pre_get_posts', function ( $query ) {
if ( ! is_admin() && $query->is_search() && $query->is_main_query() && in_array ( $query->get( 'post_type' ), array( 'webinars', 'research' ) ) ) {
$query->set( 'post_type', array( 'webinars', 'research' ) );
$query->set( 'posts_per_page', 12 );
};
} ); ?>
You can pretty much do anything just keep in mind that your search page must adapt itself to any search query, don't lock it to one specific post type.
Have a wordpress site with woocommerce.
I'm trying to add descriptions for the categories.
It is only adding a description for the first category and then copies it to the other categories.
In my child-themes functions.php I added:
function add_descript() {
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $post;
if ( ! $post->post_excerpt ) {
return;
}
?>
<div itemprop="description">
<?php echo apply_filters( 'woocommerce_short_description', $post->post_excerpt ) ?>
</div> <?php
}
add_action( 'woocommerce_before_subcategory_title', 'add_descript' );
Is there a way to loop through all of the categories and grab and excerpt?
Thanks,
Matt
Currently I have the following code:
<?php while ( have_posts() ) : the_post(); ?>
<?php
if ( get_post_type() !== 'post' ) {
if ( get_post_type() == 'landing-pages' ) {
get_template_part( 'templates/content/archive', 'landingpages' );
} elseif ( get_post_type() == 'product' ) {
get_template_part( 'templates/content/archive', 'product' );
} else {
get_template_part( 'templates/content/archive', 'cpt' );
}
} else {
get_template_part( 'templates/content/archive', 'posts' );
};
?>
<?php endwhile; ?>
<?php get_template_part( 'templates/modules/nav', 'pagination' ); ?>
However, this just displays most recent to oldest. With custom posts, woocommerce products, posts, pages, all mixed togather.
I want only products to be displayed, then once all matching products have been displayed, anything else that matches the search query is returned, eg: other custom post types, pages, and posts.
Any suggestions on how to achieve this?
Thanks.
Copy and paste the following code in functions.php file of your theme.
add_filter('posts_orderby','search_sort_custom',10,2);
function search_sort_custom( $orderby, $query )
{
global $wpdb;
if(!is_admin() && is_search())
$orderby = $wpdb->prefix."posts.post_type DESC, {$wpdb->prefix}posts.post_date DESC";
return $orderby;
}
I'm looking for a way to show random WooCommerce products on a page. This is nothing to do with "featured products" just random from any category.
I've been looking but cant seem to find any plugin or script to do this? Does anyone have an idea how to do this?
Alright folks here is a bit of code I am using for mine its for recent products but is doing the job. Just add to page you want to show them on.
[recent_products per_page="4" columns="4" orderby="rand" order="rand"]
Try this.
Paste code into functions.php
Go to wp-admin/ Woocommerce > Settings > Products > Display
View settings drop down order by random will be a new option. *note: it will be the the last option.
// Shop random order. View settings drop down order by Woocommerce > Settings > Products > Display
add_filter( 'woocommerce_get_catalog_ordering_args', 'custom_woocommerce_get_catalog_ordering_args' );
function custom_woocommerce_get_catalog_ordering_args( $args ) {
$orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) );
if ( 'random_list' == $orderby_value ) {
$args['orderby'] = 'rand';
$args['order'] = '';
$args['meta_key'] = '';
}
return $args;
}
add_filter( 'woocommerce_default_catalog_orderby_options', 'custom_woocommerce_catalog_orderby' );
add_filter( 'woocommerce_catalog_orderby', 'custom_woocommerce_catalog_orderby' );
function custom_woocommerce_catalog_orderby( $sortby ) {
$sortby['random_list'] = 'Random';
return $sortby;
}
You can try it. let post it in function.php
add_filter('woocommerce_get_catalog_ordering_args', 'set_sort_order');
function set_sort_order($args) {
$args['orderby'] = 'rand';
return ($args);
}
This works for me:
<?php
global $post; // setup_postdata will not work without this being set (outside of the foreach loop)
$args = array(
'posts_per_page' => 1,
'orderby' => 'rand',
'post_type' => 'product' );
$random_products = get_posts( $args );
foreach ( $random_products as $post ) : setup_postdata( $post ); ?>
<li>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?></a>
</li>
<?php endforeach;
wp_reset_postdata();
?>
This was the code I used [featured_products per_page="8" columns="4" orderby="rand"]
I just used this [products limit="8" columns="4" orderby="rand" order="rand" visibility="visible"].and it works as expected
If you would like to use code to make the shop homepage sort by random, then use the following code. All you need to do is install a plugin called "code snippets" that allows you to make changes in WordPress without changing any core files.
add_action( 'pre_get_posts', 'shop_default_orderby_rand' );
function shop_default_orderby_rand( $query ) {
if ( is_shop() && ( ! isset($_GET['orderby']) || 'menu_order' === $_GET['orderby'] ) ) {
$query->set( 'orderby', 'rand' );
}
}