Have a shortcode thats calling a custom post type to display on an area in a standard loop template.
problem I'm having is that the output is appearing above the what's in the page.
Can anyone help?
Code is:
function JDD_display_stores() {
ob_start();
$args = array(
'post_type' => 'stores',
'tax_query' => array(
array(
'taxonomy' => 'store',
'field' => 'slug'
)
)
);
$success = new WP_Query( $args );
if( $success->have_posts() ) {
while( $success->have_posts() ) {
$success->the_post();
?>
<h1><?php the_title() ?></h1>
<div class='content'>
<?php the_content() ?>
</div>
<?php
return $success;
}
}
else {
echo 'No stores have been added!';
}
}
add_shortcode('display_stores', 'JDD_display_stores');
You'll need return the titles and content rather than echoing it
(which the_content() and the_title() do)
like:
$output = '';
while( $success->have_posts() ) {
$success->the_post();
$output .= sprintf("<h1>%s</h1>", get_the_title());
$output .= sprintf('<div class="content">%s</div>', get_the_content());
}
//reset the orignal main query
//see http://codex.wordpress.org/Function_Reference/wp_reset_query
wp_reset_query();
return $output;
..you'll need get_the_title() and get_the_content() for that.
Also take care, that you put the return outside the while loop, otherwise you'll exit the function in the first iteration...
see http://codex.wordpress.org/Function_Reference/get_the_content
& http://codex.wordpress.org/Function_Reference/get_the_title
Related
I want to get the latest 5 posts using WordPress get_posts function. I did the following:
In functions.php file I have added extra.php file which contain following code:
if( !function_exists( 'evertstrap_post' ) ) {
function evertstrap_post() {
$args = array(
'post_type' => 'post',
'numberposts' => 5,
);
$recent_posts = get_posts( $args );
foreach ( $recent_posts as $post ) {
setup_postdata( $post );
echo get_the_title();
echo '<br/>';
}
wp_reset_postdata();
}
}
Now, from home.php file I am calling evertstrap_post() BUT it's not get the latest 5 posts !!
BUT
If I directly put the code into index.php file then it's working.
How can I solve it?
I've seen this sometimes in WordPress where echoing the output is unfavorable. Could you give this a shot?
if( !function_exists( 'evertstrap_post' ) ) {
function evertstrap_post() {
global $post;
$args = array(
'post_type' => 'post',
'numberposts' => 5,
);
$recent_posts = get_posts( $args );
$output = '';
foreach ( $recent_posts as $post ) {
setup_postdata( $post );
$output .= get_the_title();
$output .= '<br/>';
}
wp_reset_postdata();
return $output;
}
}
Then in home.php you could do:
<?php echo evertstrap_post(); ?>
Try this:
if( !function_exists( 'evertstrap_post' ) ) {
function evertstrap_post() {
$args = array(
'post_type' => 'post',
'numberposts' => 5,
);
$recent_posts = get_posts( $args );
foreach ( $recent_posts as $post ) {
setup_postdata( $post );
echo get_the_title($post->ID);
echo '<br/>';
}
wp_reset_postdata();
}
}
You saw only last post title 5 times because get_the_title() is a template tag used in "while post : do post" wordpress loop. However the same function accepts argument with post ID. more here: https://developer.wordpress.org/reference/functions/get_the_title/
Getting posts via function get_posts() you store post obejcts in an array and using normal foreach loop you can retrieve object data using $post->key_name within this loop. PHP: Getting data out of an object
Also I recommend wordpress codex. Its very well documented.
I've got some code (see below) from an online tutorial that displays an alphabetical list of Category names and then,
underneath each category, a list of post titles for that category.
It works, but I want the post titles to also be displayed alphabetically. At present it's only category names that are alphabetical - see image:
I've done some research online and I think I may need to set up a 'nested loop' - but I have no idea how to edit my code to do this.
Hoping someone can show me how to edit code to get both category names AND post titles to display alphabetically.
This is the code I'm using:
// Grab all the categories from the database that have posts.
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
foreach ( $categories as $category ) {
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'orderby' => 'term_order',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><?php the_title(); ?></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
} // End foreach
$categories = get_terms( 'category', 'orderby=name&order=ASC');
// Loop through categories
foreach ( $categories as $category ) {
// Display category name
echo '<h2 class="post-title">' . $category->name . '</h2>';
echo '<div class="post-list">';
// WP_Query arguments
$args = array(
'cat' => $category->term_id,
'order' => 'ASC',
'orderby' => 'title',
);
// The Query
$query = new WP_Query( $args );
// The Loop
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$query->the_post();
?>
<p><?php the_title(); ?></p>
<?php
} // End while
} // End if
echo '</div>';
// Restore original Post Data
wp_reset_postdata();
} // End foreach
We can add the orderby argument with title.
I have the following shortcode that I am using to display a custom post on a page:
add_shortcode( 'page-section', 'page_section_shortcode' );
function page_section_shortcode( $atts ) {
global $post;
$post_slug=$post->post_name;
$a = shortcode_atts( array(
'post-name' => 'qwerty',
'bg-color' => 'white'
), $atts );
$post_slug=$post->post_name;
$post_name = $a['post-name'];
$query = new WP_Query( array(
'post_type' => 'page_section',
'name' => $post_name,
) );
if ( $query->have_posts() ) { ?>
<?php while ( $query->have_posts() ) : $query->the_post(); ?>
<div style="background-color: <?php echo $a['bg-color']; ?>" id="<?php global $post; $post_slug=$post->post_name; echo $post_slug; ?>" class="page-section">
<div class="row">
<?php the_content(); ?>
</div>
</div>
<?php endwhile;
wp_reset_postdata(); ?>
<?php $myvariable = ob_get_clean();
return $myvariable;
}
}
Everything is working the way I want it to, I can set the content in my custom post and use a short code to pull that content into a page.
The problem is that the content that is pulled in with the short code is always at the top of the page. Using multiple shortcodes in a row they keep their order, but any other content on the page is displayed at the bottom (below all of the shortcode content).
I have tried removing the 'echo' as suggested in another stackoverflow post but cannot seem to find what I am doing wrong.
Replace your code to this code. This code returns generated html so it will not echo at the top of the page
add_shortcode( 'page-section', 'page_section_shortcode' );
function page_section_shortcode( $atts ) {
global $post;
$post_slug=$post->post_name;
$a = shortcode_atts( array(
'post-name' => 'qwerty',
'bg-color' => 'white'
), $atts );
$post_slug=$post->post_name;
$post_name = $a['post-name'];
$query = new WP_Query( array(
'post_type' => 'page_section',
'name' => $post_name,
) );
$returnhtml = '';
if ( $query->have_posts() ) {
while ( $query->have_posts() ) : $query->the_post();
global $post;
$returnhtml .= '<div style="background-color: '. $a['bg-color'].'" id="'.$post->post_name.'" class="page-section">';
$returnhtml .= '<div class="row">'.get_the_content().'</div>';
$returnhtml .= '</div>';
endwhile;
wp_reset_postdata();
return $returnhtml;
}
}
function header_notification()
{
echo '<div><strong>Any html goes here</strong></div>';
}
add_action('wp_head', 'header_notification');
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'm using already designed theme for wordpress, and now instead of regular blog posts I would like to display WooCommerce products (which are custom post types I persume).
This is the current query with display loop:
<?php
$args = array(
//'posts_per_page' => '2',
'paged' => get_query_var('paged')
);
$homepage_query = new WP_Query($args);
?>
<?php //query_posts('posts_per_page=4&paged='.get_query_var('paged')); ?>
<?php if ( have_posts() ) : ?>
<?php while ( $homepage_query->have_posts() ) : $homepage_query->the_post(); ?>
<?php if($style == 'blog_style') { ?>
<div id="blog-style" class="post-box">
<?php get_template_part('content', 'blog'); ?>
</div>
<?php } else { ?>
<div class="post-box grid_4 <?php aero_post_box_class(); ?>">
<?php get_template_part('content', ''); ?>
</div>
<?php } ?>
<?php endwhile; ?>
Is there a way to add options to $args so the loop displays WooCommerce products? I'm also using pagination with this loop, which is required on this project, so that's why it's important to use this loop.
You should be able to access products through the loop, setting the post_type arg to product:
<?php
// Setup your custom query
$args = array( 'post_type' => 'product', ... );
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post(); ?>
<a href="<?php echo get_permalink( $loop->post->ID ) ?>">
<?php the_title(); ?>
</a>
<?php endwhile; wp_reset_query(); // Remember to reset ?>
This is the proper way to re-create and customize the WooCommerce product loop:
if(!function_exists('wc_get_products')) {
return;
}
$paged = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1; // if your custom loop is on a static front page then check for the query var 'page' instead of 'paged', see https://developer.wordpress.org/reference/classes/wp_query/#pagination-parameters
$ordering = WC()->query->get_catalog_ordering_args();
$ordering['orderby'] = array_shift(explode(' ', $ordering['orderby']));
$ordering['orderby'] = stristr($ordering['orderby'], 'price') ? 'meta_value_num' : $ordering['orderby'];
$products_per_page = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
$products_ids = wc_get_products(array(
'status' => 'publish',
'limit' => $products_per_page,
'page' => $paged,
'paginate' => true,
'return' => 'ids',
'orderby' => $ordering['orderby'],
'order' => $ordering['order'],
));
wc_set_loop_prop('current_page', $paged);
wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
wc_set_loop_prop('page_template', get_page_template_slug());
wc_set_loop_prop('per_page', $products_per_page);
wc_set_loop_prop('total', $products_ids->total);
wc_set_loop_prop('total_pages', $products_ids->max_num_pages);
if($products_ids) {
do_action('woocommerce_before_shop_loop');
woocommerce_product_loop_start();
foreach($products_ids->products as $featured_product) {
$post_object = get_post($featured_product);
setup_postdata($GLOBALS['post'] =& $post_object);
wc_get_template_part('content', 'product');
}
wp_reset_postdata();
woocommerce_product_loop_end();
do_action('woocommerce_after_shop_loop');
} else {
do_action('woocommerce_no_products_found');
}
Using the code above, you would customize the wc_get_products() arguments to get the IDs of the products you want (if you have specific criteria). Once that code is in place, all the features of a native WooCommerce loop will be available to you—pagination, ordering, etc. This method is superior to WP_Query and get_posts() because those two methods can break.
I've written a more detailed blog post about custom WooCommerce loops here: https://cfxdesign.com/create-a-custom-woocommerce-product-loop-the-right-way/
You can Also get Category using thi code
$terms = get_terms('product_cat');
foreach ($terms as $term) {
$term_link = get_term_link( $term, 'product_cat' );
echo '<li>' . $term->name . '</li>';
}
If You want only parent category then
wp_list_categories('taxonomy=product_cat&orderby=order&title_li=&depth=1');