Hi WordPress nerds out there, I need help with this loop, I want to display an image that I have added with advanced custom field plugin but it seems to not work in this case. I know something is missing from my code, but I can't find the solution. Here is the reference article that I used in the implementation. link
<?php
// get the current taxonomy term
$term = get_queried_object();
// vars
$image = get_field('category_featured_image', $term);
$size = 'full'; // (thumbnail, medium, large, full or custom size)
foreach ( get_categories( [
'orderby'=> 'name',
'order' => 'ASC',
'hide_empty' => 1,
'exclude' => array(1)
] ) as $category ) {
if( $image ) :
echo wp_get_attachment_image( $image, $size, "", ["class" => "category-feature-image"] );
endif; ?>
<h2 class="category-snippet__title"><?php echo $category->name; ?></h2>
<p class="category-snippet__description"><?php echo $category->description; ?></p>
<a class="category-snippet" href="<?php echo $term_link; ?>"><?php esc_html_e('Learn more', 'pluto'); ?>
<?php
}
The solution to this is the code bellow after some research I discovered, $term = get_queried_object(); On any singular page (a single post, a single page, or a post in a custom post type), it will return the WP_Post object of that post or page.
<?php
foreach ( get_categories( [
'orderby'=> 'name',
'order' => 'ASC',
'hide_empty' => 1,
'exclude' => array(1)
] ) as $category ) :
$image = get_field('category_featured_image', $category);
$size = 'full'; // (thumbnail, medium, large, full or custom size
$term_link = get_term_link( $category, 'category' );
if( $image ) :
echo wp_get_attachment_image( $image, $size, "", ["class" => "category-feature-image"] );
endif; ?>
<h2 class="category-snippet__title"><?php echo $category->name; ?></h2>
<p class="category-snippet__description"><?php echo $category->description; ?></p>
<a class="category-snippet" href="<?php echo $term_link; ?>"><?php esc_html_e('Learn more', 'pluto'); ?>
<?php endforeach; ?>
Related
I am struggling with this code to display categories (with posts) only if posts in that category are greater than / equal to 3.
I am using WP_Query with args() to get the categories and display latest 3 posts from those categories.
Any help will be highly appreciated.
<?php
$categories = get_categories( $args );
foreach( $categories as $category ) {
$args = array(
'cat' => $category->term_id,
'posts_per_page' => 3,
'post_type' => 'post',
);
$terms = get_terms(array(
'taxonomy' => 'category'
) );
foreach($terms as $term) {
if($term->count >= 3) {
echo $term->name;
$the_query = new WP_Query( $args );
echo '<h3>' . $category->name . '</h3>'; // Display category name
while ( $the_query->have_posts() ) : $the_query->the_post();
?>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h3>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail(); ?>
</a>
</h3>
<?php
endwhile;
}
}
}
wp_reset_postdata();
?>
The WP_Query will return posts for a specific category and not categories themself.
You need to grab all of the categories and loop through them and check the count.
https://developer.wordpress.org/reference/functions/get_terms/
It should be something like this: (untested!)
$terms = get_terms(array(
'taxonomy' => 'category'
) );
foreach($terms as $term) {
if($term->count >= 3) {
echo $term->name;
}
}
$categories = get_terms( array(
'taxonomy' => 'category',
'hide_empty' => false,
));
foreach ($categories as $category) {
$args = array(
'cat' => $category->term_id,
'posts_per_page' => -1,
'post_type' => 'post'
);
if ($category->count >= 3) {
echo $category->name;
$the_query = new WP_Query($args);
echo '<h3>' . $category->name . '</h3>'; // Display category name
while ($the_query->have_posts()) : $the_query->the_post();
?>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_title(); ?>
</a>
</h3>
<h3>
<a href="<?php the_permalink(); ?>">
<?php the_post_thumbnail(); ?>
</a>
</h3>
<?php
endwhile;
}
}
wp_reset_postdata();
get_terms() array can take in a lot of arguments so please check the documentation first.
Let me know if you have any problems with it. I'll try to help :)
In wordpress i am creating a custom loop/query throughwhich i pass certain parameters. As i click through pages however the last page duplicates some posts/products inorder to satisfy the posts_per_page variable however i would like to specify that i dont want any repetitions. Is there a standard way to do this? It would seem like a pretty obvious point.
<?php
$args = array( 'post_type' => 'product', 'posts_per_page' => 5, 'product_cat' => 'products', 'orderby' => 'rand' );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>
<li class="product">
<a href="<?php echo get_permalink( $loop->post->ID ) ?>" title="<?php echo esc_attr($loop->post->post_title ? $loop->post->post_title : $loop->post->ID); ?>">
<?php woocommerce_show_product_sale_flash( $post, $product ); ?>
<?php if (has_post_thumbnail( $loop->post->ID )) echo get_the_post_thumbnail($loop->post->ID, 'shop_catalog'); else echo '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="300px" height="300px" />'; ?>
<h3><?php the_title(); ?></h3>
<span class="price"><?php echo $product->get_price_html(); ?></span>
</a>
<?php woocommerce_template_loop_add_to_cart( $loop->post, $product ); ?>
</li>
<?php endwhile; ?>
<?php previous_posts_link('« Previous', $loop ->max_num_pages);
next_posts_link(' Next »', $loop ->max_num_pages); ?>
<?php wp_reset_query();?>
It would seem like a pretty obvious point.
Not if you're using 'orderby' => 'rand' on your query, which is also very expensive by the way on large tables.
If you want to make sure that the items which already have been displayed will be excluded in the upcoming queries you'll need to save the post_ids which already has been displayed and pass them to the post__not_in parameter, see the codex page an search for post__not_in .
You could do something like this which should help you get the idea:
...
// don't forget to initialize the session somewhere
$already_displayed_post_ids = [];
if ( ! isset( $_SESSION['already_displayed_post_ids'] ) {
$_SESSION['already_displayed_post_ids'] = $already_displayed_post_ids;
} else {
$already_displayed_post_ids = array_merge( $already_displayed_post_ids, $_SESSION['already_displayed_post_ids'] );
}
$args = [
'post_type' => 'product',
'posts_per_page' => 5,
'product_cat' => 'products',
'orderby' => 'rand',
'post__not_in' => $already_displayed_post_ids
];
$loop = new WP_Query( $args );
...
I'm attempting to loop thought a custom post type (artists), then each category, then another custom post type (story) which has a relationship with the artist.
The issue is, the function <?php echo get_the_title( $story->ID ); ?> in the final loop is returning a title of the Artist many times over, along with the title of the current custom post. I just need the title of the currentent loops post.
<!-- get all the artists -->
<?php
$args = array(
'post_type' => 'artists'
);
$query = new WP_QUERY( $args );
?>
<?php if( $query->have_posts() ) : while( $query->have_posts() ) : $query->the_post(); ?>
<h1><?php the_title(); ?></h1>
<p><?php the_field('artist_website'); ?></p>
<!-- looping through all the categories -->
<?php
$cats = get_categories();
// loop through the categries
foreach ($cats as $cat) {
// setup the cateogory ID
$cat_id= $cat->term_id;
// Make a header for the cateogry
echo "<h2>".$cat->name."</h2>";
?>
<!-- looping through the stories that have a relationship with the artist (select_artist) -->
<?php
$post_type = 'story';
$args = array(
'post_type' => $post_type,
'posts_per_page' => -1, //show all posts
'tax_query' => array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $cat->slug,
)
),
'meta_query' => array(
array(
'key' => 'select_artist', // name of custom field
'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123.
'compare' => 'LIKE'
)
)
);
$stories = new WP_Query($args);
?>
<?php if( $stories ): ?>
<ul>
<?php foreach( $stories as $story ): ?>
<!-- Problem echo below -->
<?php echo get_the_title( $story->ID ); ?>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php } // done the foreach statement ?>
<?php endwhile; wp_reset_postdata(); endif; ?>
</section>
If you're using WP_Query you should be using a while loop and end with the_post() in order to set up the internal variables that would allow get_the_title() to work properly.
As an added measure you could set the $post variable to a $temp variable before your inner loop, then reset back after.
<?php
$stories = new WP_Query($args);
if( $stories->have_posts() ):
global $post;
$temp = $post;
?>
<ul>
<?php
while( $stories->have_posts() ): $stories->the_post();
the_title();
endwhile;
$post = $temp;
?>
<ul>
<?php endif; ?>
I have a custom post type with page attributes so I can create sub pages. I'm trying to display the title of the parent page in the h1 and then have it loop through and display the content of the child pages. The code below almost does this but it's outputting the child pages also in the first bit as h1 titles so I'm getting duplicates of the child page titles. How can I exclude the child pages and prevent them from displaying in the first part of the loop?
Many thanks.
<?php
echo "<ul>";
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
echo "<li><h1>".get_the_title()."</h1>";
$args=array(
'orderby' => 'menu_order',
'order' => 'ASC',
'post_parent' => $post->ID,
'post_type' => get_post_type( $post->ID ),
'posts_per_page' => 10
);
$childpages = new WP_Query($args);
if($childpages->post_count > 0) { /* display the children content */
echo "<ul>";
while ($childpages->have_posts()) {
$childpages->the_post();
echo "<li><h2>".get_the_title()."</h2></li>";
echo "<li><h2>".the_content()."</h2></li>";
}
echo "</ul>";
}
wp_reset_query();
echo "</li>";
}
}
echo "</ul>";
?>
Update: Managed to get a little bit further, almost there I think. I can now see just one sub post (the latest) and the same sub post is duplicated under each parent title either though it isn't a child of the others.
Can anyone please help me nail this last bit. Thanks.
<?php $parent_pages = get_pages( array(
'parent' => 0,
'post_type'=> 'archive'
));
foreach( $parent_pages as $parent_pages)
{ ?>
<h1><?php echo $parent_pages->post_title; ?></h1>
<?php
$children = get_pages(array(
'orderby' => 'menu_order',
'order' => 'ASC',
'post_parent' => $post->ID,
'post_type' => get_post_type( $post->ID )
));
foreach($children as $child);
?>
<h2><?php the_title(); ?></h2>
<?php the_content(); ?>
<?php } ?>
Update: Trying #robbintt suggestions, I'm now here. Not sure if I'm using the get_page_children correctly and I'm now getting "Parse error: syntax error, unexpected T_AS, expecting ';' "
<?php
$parent_pages = get_pages( array(
'parent' => 0,
'post_type'=> 'archive'
) );
for ( $parent_pages as $parent_page { ?>
<h1><?php echo $parent_page->post_title; ?></h1>
<?php
$all_pages = get_pages()
$child_pages = get_page_children($parent_pages->ID, $all_pages );
for ( $child_pages as $child_page ) { ?>
<h2><?php echo $child_page->post_title; ?></h2>
<p><?php echo $child_page->post_content; ?></p>
<?php } ?>
Update: Here's my final working code thanks to #robbintt for the help.
<?php
$parent_pages = get_pages( array( 'parent' => 0, 'post_type'=> 'archive' ) );
foreach ( $parent_pages as $parent_page ) {
echo '<h1>';
echo $parent_page->post_title;
echo '</h1>';
$all_pages = get_pages(array( 'post_type'=> 'archive' ) );
$child_pages = get_page_children($parent_page->ID, $all_pages );
foreach ( $child_pages as $child_page ) {
echo '<h2>';
echo $child_page->post_title;
echo '</h2>';
echo '<p>';
echo $child_page->post_content;
echo '</p>';
}
}
?>
You're abusing the loop a little bit here by using the standard while ( have_posts() ) {}.
Instead, lets target the parent page, and then use a for loop to get the child pages.
/* here we include only pages with no parent */
$parent_pages = get_pages( 'parent' => 0 )
foreach ( $parent_pages as $parent_page ) {
/* Proceed as you have inside the while loop, targeting $parent_page each time */
}
Here is the rest of the documentation so you can sort as you wish: http://codex.wordpress.org/Function_Reference/get_pages#Parameters
Part 2:
Here's the next requested section, how to get information for child pages:
http://codex.wordpress.org/Function_Reference/get_page_children
This function will return an array of page children. The key here is that this loop is run inside the other loop which actually gets all the parent pages.
$all_pages = get_pages( array( 'post_type'=> 'archive' ) )
$child_pages = get_page_children($parent_page->ID, $all_pages );
foreach ( $child_pages as $child_page ) {
/* proceed with any calls on child page such as ID/title, in the format $child_page->ID */
Let me know how it goes! Here's the new function we are using:
http://codex.wordpress.org/Function_Reference/get_page_children
Part Three:
Here I've cleaned up your code a bit for the child page section. There was a lot going on, so I standardized and simplified how you echo'd HTML and added a lot more lines. This made the design pattern a lot more visible to the human eye.
<?php
$parent_pages = get_pages( array( 'parent' => 0, 'post_type'=> 'archive' ) );
foreach ( $parent_pages as $parent_page ) {
echo '<h1>';
echo $parent_page->post_title;
echo '</h1>';
$all_pages = get_pages( array( 'post_type'=> 'archive' ) );
$child_pages = get_page_children($parent_page->ID, $all_pages );
foreach ( $child_pages as $child_page ) {
echo '<h2>';
echo $child_page->post_title;
echo '</h2>';
echo '<p>';
echo $child_page->post_content;
echo '</p>';
}
}
?>
Here's my original writeup of this code: http://codepad.org/pLtFCI1l
I am building a shopping website and I am trying to put a shortcode in that will show the customer a buy button and the quantity of the product the customer wants to purchase. On my post page the shortcode works fine:
http://warringah-plastics.com.au/blog/dt_catalog/recess-gasket-large/
but on the archive page:
http://warringah-plastics.com.au/store/
the shortcode id displayed as text and not the actual button and quantity e.g. [add_to_cart item="FPROWAR-160713-1" showprice="no" quantity="user:1" ajax="yes" ].
The code that works in the post page is this:
<?php
$my_textbox_value = mtbxr_val("shopping_shortcode");
echo do_shortcode("$my_textbox_value");
?>
but it just displays the shortcode text on that archive page. Anyone have any ideas? Much appreciated,
UPDATE
THIS IS THE CODE THAT DISPLAYS THE SHORTCODE CORRECTLY:
<?php get_header(); ?>
<?php dt_storage('have_sidebar', true); ?>
<?php get_template_part('top-bg'); ?>
<?php get_template_part('parallax'); ?>
<div id="wrapper">
<?php get_template_part('nav'); ?>
<div id="container">
<?php if( have_posts() ): while( have_posts() ): the_post(); ?>
<h1><?php the_title(); ?></h1>
<h1 style="color: #3C3C3B !important; margin-top:-20px !important;"><?php $terms_as_text = strip_tags( get_the_term_list( $wp_query->post->ID, 'dt_catalog_category', '', ', ', '' ) );
echo $terms_as_text; ?></h1>
<?php
global $post;
$post_opts = get_post_meta($post->ID, '_dt_catalog-post_options', true);
if( !isset($post_opts['hide_media']) || (isset($post_opts['hide_media']) && !$post_opts['hide_media']) ) {
$args = array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'posts_per_page' => -1,
'post_parent' => $post->ID,
'post_mime_type' => 'image',
'orderby' => 'menu_order',
'order' => 'ASC'
);
if( !empty($post_opts['hide_thumbnail']) )
$args['post__not_in'] = array( get_post_thumbnail_id() );
$dt_tmp_query = new WP_Query( $args );
if( $dt_tmp_query->have_posts() ) {
$slides = array();
foreach( $dt_tmp_query->posts as $slide ) {
$video = get_post_meta( $slide->ID, '_dt_catalog_video_link', true );
$tmp_arr = array();
$tmp_arr['caption'] = $slide->post_excerpt;
if ( ! $video ) {
$slide_src = dt_get_resized_img( wp_get_attachment_image_src( $slide->ID, 'full' ), array( 'w' => 710 ) );
$tmp_arr['alt'] = get_post_meta( $slide->ID, '_wp_attachment_image_alt', true );
$tmp_arr['src'] = $slide_src[0];
$tmp_arr['size_str'] = $slide_src[3];
} else {
$tmp_arr['is_video'] = true;
$tmp_arr['src'] = $video;
$tmp_arr['size_str'] = array( 710, 1024 );
}
$slides[] = $tmp_arr;
}
dt_get_anything_slider( array( 'id' => 'slider2', 'items_arr' => $slides ) );
}
}
?>
<?php $opts = get_post_meta($post->ID, '_dt_catalog-goods_options', true); ?>
<?php if( !empty($opts['price']) ): ?>
<span class="price"><?php _e('Price: ', LANGUAGE_ZONE); echo esc_html($opts['price']); ?></span>
<?php endif; ?>
<?php
$my_textbox_value = mtbxr_val("shopping_shortcode");
echo do_shortcode("$my_textbox_value");
?>
<?php
the_content();
if( dt_is_page_soc_buttons_enabled('catalog') ) {
dt_get_like_buttons( get_the_ID() );
}
?>
<?php if( !empty($opts['p_link']) ): ?>
<span><i class="dol"></i><?php _e('Make purchase!', LANGUAGE_ZONE); ?></span>
<?php endif; ?>
<p class="gap"></p>
<?php
$rel_works = get_post_meta($post->ID, '_dt_catalog_related', true);
if( isset($rel_works['show_related']) && $rel_works['show_related'] ):
if( 'same' == $rel_works['related'] ) {
$rel_works['related'] = wp_get_post_terms(
$post->ID,
'dt_catalog_category',
array('fields' => 'ids')
);
}
if( !empty($rel_works['related']) ):
?>
<p class="hr hr-narrow gap-small"></p>
<div class="gap"></div>
<div class="full-width w-photo">
<h2><?php _e('Related Items', LANGUAGE_ZONE); ?></h2>
<?php
if( 'same' == $rel_works['related'] ) {
$rel_works['related'] = wp_get_post_terms(
$post->ID,
'dt_catalog_category',
array('fields' => 'ids')
);
}
$dt_tmp_query = new WP_Query( array(
'posts_per_page' => -1,
'post_type' => 'dt_catalog',
'post_status' => 'publish',
'post__not_in' => array($post->ID),
'tax_query' => array( array(
'taxonomy' => 'dt_catalog_category',
'field' => 'id',
'terms' => $rel_works['related'],
'operator' => 'IN'
) )
) );
if( $dt_tmp_query->have_posts() ) {
$thumb_arr = dt_core_get_posts_thumbnails( $dt_tmp_query->posts );
$items = array();
foreach( $dt_tmp_query->posts as $rel_post ) {
$item = array();
$img = dt_get_resized_img(
dt_get_thumb_meta($thumb_arr['thumbs_meta'], 'full', $rel_post->ID),
array('w' => 196, 'h' => 123, 'use_noimage' => true)
);
$item['src'] = $img[0];
$item['size_str'] = $img[2];
$item['post_id'] = $rel_post->ID;
$item['desc'] = apply_filters('get_the_excerpt', $rel_post->post_excerpt);
$item['title'] = apply_filters('the_title', $rel_post->post_title, $rel_post->ID);
$item['alt'] = esc_attr( $item['title'] );
$items[] = $item;
}
$args = array( 'items_arr' => $items, 'id' => '', 'class' => 'list-carousel recent bx', 'ul_class' => 'slider1' );
$args['wrap'] = '<div class="%CLASS% bx">%SLIDER%</div>';
if( ! empty( $rel_works['show_desc'] ) || ! empty( $rel_works['show_title'] ) ) {
$title = '';
if( ! empty( $rel_works['show_title'] ) ) {
$title = '<h3>%TITLE%</h3>';
}
$desc = '';
if( ! empty( $rel_works['show_desc'] ) ) {
$desc = '<p>%DESC%</p>';
}
$args['item_wrap'] = '
<li>
<div class="textwidget">
<div class="textwidget-photo">
<a class="photo" href="%LINK%"><img src="%IMG_SRC%" alt="%ALT%" %IMG_SIZE% /></a>
</div>
<div class="widget-info">
<div class="info">
' . $title . $desc . '
</div>
</div>
</div>
</li>
';
}
dt_get_carousel_slider( $args );
}
?>
</div>
<?php endif; endif; ?>
<?php comments_template(); ?>
<?php
endwhile;
endif;
?>
</div>
<?php dt_widget_area('sidebar', null, 'sidebar_4'); ?>
</div>
<?php get_footer(); ?>
AND THIS IS THE CODE THAT DISPLAYS THE SHORTCODE JUST AS TEXT:
<?php
global $post;
$page_data = dt_storage( 'page_data' );
$page_opts = ! empty( $page_data['page_options'] ) ? $page_data['page_options'] : array();
$add_data = dt_storage( 'add_data' );
$first_class = '';
if( 1 === dt_storage('post_is_first') ) {
$first_class = ' first';
dt_storage( 'post_is_first', -1 );
}
$opts = get_post_meta($post->ID, '_dt_catalog-goods_options', true);
?>
<div class="<?php dt_portfolio_classes( '2_col-list', 'block' ); echo $first_class; ?>">
<?php
$h = 220;
if ( ! empty ( $page_opts['thumb_height'] ) ) {
$h = $page_opts['thumb_height'];
}
dt_get_thumb_img( array(
'class' => 'photo',
'use_noimage' => true,
'href' => get_permalink(),
'thumb_opts' => array( 'w' => 343, 'h' => $h )
),
'<div class="textwidget-photo">
<a %HREF% %CLASS% %TITLE% %CUSTOM%><img %ALT% %SRC% %IMG_CLASS% %SIZE% /></a>
</div>'
);
?>
<div class="<?php dt_portfolio_classes( '2_col-list', 'info' ); ?>">
<a class="<?php dt_portfolio_classes( '2_col-list', 'head' ); ?>" href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
<?php if( !empty($opts['price']) ): ?>
<span class="price"><?php _e('Price: ', LANGUAGE_ZONE); echo esc_html($opts['price']); ?></span>
<?php endif; ?>
<?php
dt_the_content();
dt_details_link();
dt_edit_link();
?>
<div id="specialpriceshortcode">
<?php
$my_textbox_value = mtbxr_val("shopping_shortcode");
echo do_shortcode("$my_textbox_value");
?>
</div>
</div>
</div>
Try using single quotes in the do_shortcode call, like so:
echo do_shortcode('$my_textbox_value');
More likely though is that the shortcode isn't defined on the archive page so you'd need to look at where it is being instantiated to see if that is the issue. Normally when a shortcode just echoes out the content it means that shortcode doesn't exist. You can test easily enough by using the shortcode_exists() function:
<?php if ( shortcode_exists( 'add_to_cart' ) ) { echo "The shortcode exists";} ?>
If that doesn't work then you know the issue is with the shortcode not being registered on your archives page. If it does work then you know it's something with the format of the content being passed to the shortcode.
Add this to your functions.php
// Allow shortcodes on widgets
add_filter('widget_text','do_shortcode');
// Allow shortcodes on pages (not tested, but should work)
add_filter('the_content','do_shortcode');
Typically your shortcode is getting registered in a plugin or your theme's functions.php file. In a plugin it's often something like:
add_action('init', 'register_my_shortcode');
function register_my_shortcode(){
add_shortcode('my_shortcode', 'do_my_shortcode');
}
And then you'd have a function do_my_short_code() that actually outputs the content. With something like that the shortcode is getting registered via the 'init' hook (http://codex.wordpress.org/Plugin_API/Action_Reference) which is called before WP has started figuring out what template to use, what content to output, etc.
But some plugins will register the shortcode in a way that it is only available on pages / posts where it's going to potentially be used. For example, I can think of one plugin where they register the shortcode and enqueue some javascripts in the same function. That function checks to see if you're on a particular page before it executes so that the js files are not included unnecessarily all over the place. Since the shortcode registration takes place in the same function it means the shortcode only exists on those pages.
Anyhow, if the shortcode is showing as existing on your archives page you know that isn't the problem, so check that first and let me know what you find.