In my custom theme in WordPress I have created a front-page.php. There I have three WP_Query's. The first one just takes a custom post type.
$args = array (
'post_type' => array( 'frontpage_element' ),
'orderby' => 'rand',
'posts_per_page' => '1',
);
$query = new WP_Query( $args );
if ($query->have_posts()):
while ($query->have_posts() ) : $query->the_post();
// DISPALY A PICTURE
endwhile;
// Reset postdata
wp_reset_postdata();
endif;
The second is the default Loop.
if (have_posts()) :
while (have_posts()) : the_post(); ?>
the_title();
the_content();
endwhile;
// Reset postdata
wp_reset_postdata();
endif;
The third WP_Query shows the first 6 post entries of a category.
$options = get_option('custom_theme_options');
$categories = implode("," , $options['catprojectlayout']);
$atts = shortcode_atts( array(
'paging' => 'projectpage',
'post_type' => 'post',
'posts_per_page' => '6',
'post_status' => 'publish',
'cat' => $categories,
'cache_results' => false
), $atts );
$paging = $atts['paging'];
unset( $atts['paging'] );
if( isset($_GET[$paging]) )
$atts['paged'] = $_GET[$paging];
else
$atts['paged'] = 1;
$custom_query = new WP_Query( $atts );
$pagination_base = add_query_arg( $paging, '%#%' );
if ($custom_query->have_posts()) : while ($custom_query->have_posts()) : $custom_query->the_post();
the_title();
the_content();
endwhile; endif;
echo paginate_links( array(
'type' => '',
'base' => $pagination_base,
'format' => '?'. $paging .'=%#%',
'current' => max( 1, $custom_query->get('paged') ),
'total' => $custom_query->max_num_pages,
'prev_text' => '<div class="prevbtn"></div>',
'next_text' => '<div class="nextbtn"></div>',
'show_all' => true
));
The code works, but I have troubles with caching. When I add a new Post to the defined category, the second WP_Query was not updated (I think because of browser caching).
I think I have the code done like is defined in WP Codex.
It should be work like this: When I add a new post in the defined category, a User browse to the front-page, the site must be reloaded from server (because in the third WP_Query there is a new entry).
it is ulikely to be browser caching as browsers tend to store style sheets and images page content is normally re-interpreted each time the page is loaded incase it has changed.
It is more likely to be either cashing on the server or another 3rd party service such as Cloud flare which store the page appearance for a period of time to save regenerating the same wedge of dynamic page controls over and over.
WP_Engine hosting has it's own caching that can be cleared through the installs dash board, Cloud flare allows cache to be cleared per URL and plugins... well these are all different, check if there are any plugins that control caching and either turn them off whilst you are making a change or clear their cache.
Related
Cant find full loop example on the web with wc_get_template_part() and wc_get_products(), so looking for help here:
global $woocommerce;
global $product;
$args = array(
'limit' => 15,
'category' => array('printers', 'laptop')
);
$query_cats = wc_get_products($args);
foreach ($query_cats as $query_cat) {
echo $query_cat->get_id();
echo $query_cat->get_title();
// echo "<pre>";
// var_dump($query_cat);
wc_get_template_part('content', 'product');
}
?>
Titles and ids are displayed, var_dump also, bu wc_get_template_part - no. I have add_theme_support('woocommerce'); and also body_class();
WooCommerce content-product.php template only works only with standard loop(with instance of Wp_Query). May be following solution can help:
$args = array(
'post_type' => 'product',
'post_status' => 'publish',
'tax_query' => [
array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => ['printers', 'laptop'],
)
],
);
$product = new WP_Query( $args );
while ( $product->have_posts() ) {
$product->the_post();
wc_get_template_part( 'content', 'product' );
}
wp_reset_postdata();
Thanks
Yes, it can be done (2022 update)
If you want to avoid native WP_Query or using shortcodes, this actually can be done using wc_get_products().
You just need to setup and reset postdata within your foreach loop and setup WooCommerce loop properly.
global $post; // Do not forget this!
$args = array(
'limit' => 15,
'category' => array('printers', 'laptop')
);
$products = wc_get_products( $args );
// Set loop properties
wc_set_loop_prop('columns', 5);
// Start custom WC loop
woocommerce_product_loop_start();
foreach( $products as $product ) {
// Setup postdata
$post = get_post( $product->get_id() );
setup_postdata( $post );
// Get template part
wc_get_template_part( 'content', 'product' );
}
// End loop and reset postdata
woocommerce_product_loop_end();
wp_reset_postdata();
Important note: this will only work if queried products are within any HTML element with the woocommerce class (otherwise WooCommerce CSS won't load for your products). In some templates, the woocommerce class is already part of the DOM (e.g. <body> element), but if it isn't, wrap your loop within an element as such:
<div class="woocommerce my-products-loop">
<?php // Your loop goes here ?>
</div>
TIP: You can set various loop properties using wc_set_loop_prop in the "Set loop properties" part of the code
I have a custom post-type call Called 'Sectors' and another post type called 'Challenges' The challenges post type has a taxonomy called 'sectortype' - which has the same names as the sectors.
I created a page called 'single-sector.php' On that page displays a loop that includes challenges related to that sector.
When I write the loop for displaying challenges, how do I make the 'sectortype' => 'advanced-education' a variable so it will work on other single sector pages?
Here's what I have for the loop...
<?php $challenge_args = array(
'post_type' => 'challenge',
'sectortype' => 'advanced-education', //Need Help Here
);
// create a new instance of WP_Query
$challenge_query = new WP_Query( $challenge_args );
?>
<?php if ( $challenge_query->have_posts() ) : while ($challenge_query->have_posts() ) : $challenge_query->the_post(); // run the loop ?>
Get Custom posts by custom taxonomy terms :
<?php
$terms = get_terms('sectortype');
$challenge_args = array(
'post_type' => 'challenge',
'publish_status' => 'published',
'posts_per_page' => -1,
'tax_query' => array(
array(
'taxonomy' => 'sectortype',
'field' => 'slug',
'terms' => $terms[0], //whichever term you want to select
),
),
);
// create a new instance of WP_Query
$challenge_query = new WP_Query( $challenge_args );
?>
<?php if ( $challenge_query->have_posts() ) : while ($challenge_query->have_posts() ) : $challenge_query->the_post(); // run the loop ?>
DISPLAY IN SEPARATE PAGES
TO display the posts in separate pages as you mentioned in the comment, you have to do the following:
Create Separate Page Links:: (use on page as navigation items)
<?php $categories = get_terms('sectortype');?>
<ul>
<?php foreach( $categories as $key => $c ):?>
<?php $cat_link = get_term_link( $c->term_id );?>
<?php $term_title= single_term_title('', false);?>
<li class="<?php echo ($c->name == $term_title )?'active':'';?>"><?php echo $c->name;?></li>
<?php endforeach;?>
</ul>
Create a file in theme directory (actually an archive template for taxonomy terms) with the filename 'taxonomy-sectortype.php'.
On that template, get the posts from the usual loop without using any queries and you will get the respective posts.
I’d like to create a page for filtering posts based on a number of criteria.
I can work with wp_query and deliver posts quite easily, my problem is that I can’t figure out (nor can I find any answers online about this, believe me I looked) how to let users do this.
Take this for example, returns the posts in order of price (custom field meta value) from highest to lowest with 33 posts.
<?php
$featuredPosts = new WP_Query( array(
'posts_per_page' => 33,
'meta_key'=>'Price',
'orderby' => 'meta_value_num',
'order' => DESC
) );
?>
<?php if ( $featuredPosts->have_posts() ) : ?>
<?php while ( $featuredPosts->have_posts() ) : $featuredPosts->the_post(); ?>
<article <?php post_class('item-post block'); ?> id="post-<?php the_ID(); ?>">
<h2 class="price-title"><?php the_title(); ?> </h2>
</article> <!-- end div post -->
<?php endwhile; wp_reset_query(); ?>
<?php endif; ?>
Now, even after reading and googling, I’ll be damned if I can figure out how I’d implement this on the front end for users to filter posts.
I mean, I know you can append to the URLs in Wordpress to alter the order of posts, but in this context I’m totally lost.
I tried this, but it doesn't work.
<?php
$by_price = esc_url(add_query_arg(array(
'meta_key' => 'price',
'orderby' => 'meta_value_num',
'order' => ASC
)));
$by_date = esc_url(add_query_arg(array(
'orderby' => 'date',
'order' => DESC
)));
?>
<ul>
<li>Order by price</li>
<li>Order by date</li>
</ul>
What I’m trying to achieve is actually quite simple as well, let the user choose the category, choose the price range (guessing I’d write something in JQuery to deliver a value into an field), set the number of results they’d like to be returned.
I’ve tried googling everything under the sun I can think of for this, no dice.
Try Simple Custom Post Order plugin.
It is using AJAX and JavaScript, you don’t have to load anything else. You have to just drag and drop the posts.
OK, I update the code to make it clear:
---I do not think meta_key would be auto-pickup---
functions.php
...
$whitList = array(
'price' => array(
'posts_per_page' => 33,
'meta_key'=>'price',
'orderby'=>'meta_value_num',
'order' => ASC
),
'date' => array(
'posts_per_page' => 33,
'orderby'=>'date',
'order' => DESC
)
);
...
Your first loop php:
<?php
gloabl $whitList; //to use the $whitList in your functions.php.
$aryQuery = $whitList[$_REQUEST['orderby']] ? $whitList[$_REQUEST['orderby']] : $whitList['price'];
$featuredPosts = new WP_Query( $aryQuery );
....
....
?>
For your list page:
<ul>
<?php
gloabl $whitList; //to use the $whitList in your functions.php.
foreach( $whitList as $orderby => $aryOrderBySettings){
?>
<li> Order by <?php echo $orderby;?></li>
<?php
}
?>
</ul>
Using $_GET parameters is the way to go here. First of all you'll want to allow your visitors access to these add these variables. The link approach is fine, overall, so we can generate augmented links by using the add_query_arg to tack on extra parameters to the current URL.
<?php
$urla = add_query_arg( 'sort' => 'price', 'asc' => '1' );
$urld = add_query_arg( 'sort' => 'price', 'asc' => '0' );
?>
Sort by price (asc)
Sort by price (desc)
When clicked, the tacked on variables can thus be detected:
<?php
// Get an allowed sort variable and the order
$sort = isset( $_GET['sort'] ) && in_array( $_GET['sort'], array( 'price' ) ) )
? $_GET['sort'] : null;
$order = isset( $_GET['asc'] ) && $_GET['asc'] == '0' ? 'DESC' : 'ASC';
?>
Now you would augment your main query with the data you just retrieved. If you're using the default way of querying posts on a page you should be able to get away with query_posts, although it is not recomended. And, if you're using a custom loop, simply inject the new arguments into it:
<?php
$args = array();
switch ( $sort ):
case 'price':
$args['order'] = $order;
$args['orderby'] = 'meta_value_num';
$args['meta_key'] = 'price';
break;
default:
break;
endswitch;
$defaults = array( 'posts_per_page' => 33 );
$query = new WP_Query( wp_parse_args( $args, $defaults ) );
?>
You can add more variables, by creating more URLs and buttons to press, and more cases in the switch statement to extend the basic example above.
The first piece of code would go wherever you want your buttons to appear. The second piece of code goes before the third one, which goes before outputting the results.
I have such a piece of code
<?php
global $wp_query;
$args = array_merge( $wp_query->query_vars, array( 'post_type' => array( 'post', 'project') ) );
$wp_query = new WP_Query( $args );
if ( have_posts() ) : while ( have_posts() ) : the_post();
?>
after the loop i have
<?php
$permalink_structure = get_option('permalink_structure');
$format = empty( $permalink_structure ) ? '?paged=%#%' : 'page/%#%/';
echo paginate_links( array(
'base' => get_pagenum_link(1) .'%_%',
'format' => $format,
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => __('«'),
'next_text' => __('»'),
'show_all' => false,
'mid_size' => 2,
'end_size' => 1,
) );
?>
now the problem is that if I have 6 posts and 18 projects and 3 posts per page ... paginate_links will generate (6+18)/3 pages i.e. 8 pages ... so I click on 2 and go to page number 2 .. but when I click on 3 .. I get error 404.
As if paginate_links generates the required amound of page links but only the links to 6/3 pages word .. like 1 and 2.
Problem is for sure because of custom post type added but I can't understand where is that problem.
What may be the problem?
It looks like you have to alter the "main query" (you are using a "sub query" inside the "main query") to include your custom post type, so your pagination links will work.
You can try to alter the "main query" using the pre_get_posts hook
add_action( 'pre_get_posts', 'my_pre_get_posts' );
function my_pre_get_posts( $query ) {
if($query->is_main_query() && $query->is_home()){ // <-- EDIT this condition to your needs
$query->set( 'post_type', array( 'post','projects' ) );
}
}
where you place this code into the functions.php file in your current theme directory.
This assumes you are using the pagination on the frontpage, i.e.
http://example.com/page/5
We have the condition $query->is_home() to check if we are on the frontpage. If you are on a different page, you can alter this condition to your needs.
ps: I think your way is not working because you are doing it in the theme file and that is "too late" to alter the scope of the pagination links.
So with my blog i have a photo attachment page but it only shows to photo's at a time, and those two photo's are used as the navigation and i hate that.
I want the attachment page to show all the photo's that goes along with the rest of that set.
Here is the current code
<div id="nav-images" class="navigation clearfix">
<div class="nav-next"><?php next_image_link() ?></div>
<div class="nav-previous"><?php previous_image_link() ?></div>
How do i change that to show all the post attachments?
To clarify, this doesn't work anymore - at least with version 3.5.2. I used this instead;
$attachments = get_children(
array(
'post_type' => 'attachment',
'post_parent' => get_the_ID()
)
);
foreach ($attachments as $attachment) {
// ...
}
Only resurrecting an old thread because this one ranks quite highly for this search term.
When you're on a page or post, you can get all of its attachments with the following:
global $post; // refers to the post or parent being displayed
$attachements = query_posts(
array(
'post_type' => 'attachment', // only get "attachment" type posts
'post_parent' => $post->ID, // only get attachments for current post/page
'posts_per_page' => -1 // get all attachments
)
);
foreach($attachements as $attachment){
// Do something exceedingly fancy
}
Since you're currently on an attachment page, you can get all the other attachments using the $post->post_parent value:
global $post; // refers to the attachement object
$attachements = query_posts(
array (
'post_type' => 'attachment', // only get "attachment" type posts
'post_parent' => $post->post_parent, // attachments on the same page or post
'posts_per_page' => -1 // get all attachments
)
);
To then display the attachment images, you can use the wp_get_attachment_image_src function. The attachment's ID will be available in each iteration of your foreach loop as $attachement->ID (if you use the same naming convention as my first example).
Since WordPress 3.6.0 you can also use get_attached_media.
$media = get_attached_media( 'image', $post->ID );
if(! empty($media)){
foreach($media as $media_id => $media_file){
$thumbnail = wp_get_attachment_image_src ( $media_id, 'thumbnail' );
$full = wp_get_attachment_url( $media_id );
echo '<img src="'.$thumbnail[0].'" alt="'.$media_file->post_title.'" />';
}
}