Wordpress: Query child pages with specific templates for each page - wordpress

I created a query to call all child pages of the current parent page. This works great, however each child page has a custom template. I don't know how to add a custom query parameter to account for the template. Currently I query the_content for each child page, however that doesn't account for the template.
Can anyone help me modify the query?
<?php $children = get_pages(
array(
'sort_column' => 'menu_order',
'sort_order' => 'ASC',
'hierarchical' => 0,
'parent' => $post->ID,
'post_type' => 'projects',
'meta_query' => array(
array(
'key' => '_wp_page_template',
'value' => 'template-city.php', // template name as stored in the dB
)
)
));
foreach( $children as $post ) {
setup_postdata( $post ); ?>
<div class="section-container">
<?php the_content(); ?>
</div>
<?php } ?>

You can use get_post_meta !
With template_redirect action :
function my_page_template_redirect()
{
global $post;
if(get_post_type($post) == 'projects' )
{
$tpl = get_post_meta($post->ID, '_wp_page_template');
if ($tpl) {
include( get_template_directory() . $tpl );
exit();
}
}
}
add_action( 'template_redirect', 'my_page_template_redirect' );

I think get_pages function doesn't use meta_query, you need to do something like this:
$children = get_pages(
array(
'sort_column' => 'menu_order',
'sort_order' => 'ASC',
'hierarchical' => 0,
'parent' => $post->ID,
'post_type' => 'projects',
'meta_key' => '_wp_page_template',
'meta_value' => 'template-city.php',
));
Or use get_posts function that uses meta_query.

Related

woocommerce product shortcodes template

As I know
[products limit=”4″ columns=”4″ on_sale=”true” ] will show all on sale products,
[products limit=”3″ columns=”3″ best_selling=”true” ] will show best selling products,
If I were not wrong, both of the shortcodes would call the content-product.php file to display the products.
My question is how can I make different product shortcodes call different php template files to show the related products instead of calling the same file that is content-product.php?
For example,
on sale shortcodes call content-product-1.php
best selling shortcodes call content-product-2.php
Thank you!
Create our own shortcode to display the specific products and our our own template as below,
for example, wc_get_template_part( 'content', 'product-test' );
add_shortcode( 'sale_products_test', 'sale_products' );
function sale_products( $atts ){
global $woocommerce_loop, $woocommerce;
extract( shortcode_atts( array(
'per_page' => '12',
'columns' => '3',
'orderby' => 'title',
'category' => 'clearance',
'order' => 'asc'
), $atts ) );
// Get products on sale
$product_ids_on_sale = woocommerce_get_product_ids_on_sale();
$meta_query = array();
$meta_query[] = $woocommerce->query->visibility_meta_query();
$meta_query[] = $woocommerce->query->stock_status_meta_query();
$args = array(
'posts_per_page'=> $per_page,
'orderby' => $orderby,
'order' => $order,
'no_found_rows' => 1,
'post_status' => 'publish',
'post_type' => 'product',
'orderby' => 'date',
'order' => 'ASC',
'meta_query' => $meta_query,
'post__in' => $product_ids_on_sale,
'tax_query' => array( array(
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $category,
)),
);
ob_start();
$products = new WP_Query( $args );
$woocommerce_loop['columns'] = $columns;
if ( $products->have_posts() ) : ?>
<?php woocommerce_product_loop_start(); ?>
<?php while ( $products->have_posts() ) : $products->the_post(); ?>
<?php wc_get_template_part( 'content', 'product-test' ); ?>
<?php endwhile; // end of the loop. ?>
<?php woocommerce_product_loop_end(); ?>
<?php endif;
wp_reset_postdata();
return ob_get_clean();
}
Not Possible. This type of shortcode require to use wp_query and fetch data your requirement wise

Render child page on parent page in Wordpress

How can I render a child page on the parent page in wordpress? I'am building a landing page website, and the idea is to use child pages to make landing page structure.
Now I'am using this code in my parent page template:
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'orderby' => 'rand',
'posts_per_page' => 1,
'no_found_rows' => true
);
$child = new WP_Query($args);
var_dump($child->posts);
But it just gives me an array, and I need fully rendered HTML of my child pages.
Thank you in advance)
Try this code here:
$args = array(
'hierarchical' => 0,
'child_of' => $post->ID,
'parent' => $post->ID,
'sort_column' => 'menu_order, ID',
);
$pages = get_pages( $args );
foreach ( $pages as $post ) : setup_postdata( $post );
// child page html content here
endforeach;
//reset to the main page
wp_reset_postdata();
Finally I've found the proper solution, inspired by Matt Browne's answer
functions.php
function eatwings_show_page($pageid)
{
global $post;
$post = get_page($pageid);
$tpl_slug = get_page_template_slug($post->ID);
$tpl_slug_exp = explode('.', $tpl_slug);
get_template_part($tpl_slug_exp[0]);
}
parent-page-template.php:
$args = array(
'post_type' => 'page',
'post_parent' => $post->ID,
'orderby' => 'menu_order, ID',
'posts_per_page' => 1,
'no_found_rows' => true
);
$child = new WP_Query($args);
foreach($child->posts as $childpage)
{
eatwings_show_page($childpage->ID);
}

How to make function to get page ancestors in wordpress

How I can get child pages for each page, if a page dont have any child then there must be shown right menu.
For Example:
Parent Page
child page 1
child page 2
if parent don't have any child then display any menu
Right now I am using following code in:
FUNCTION.PHP
function get_top_ancestor_id() {
global $post;
if ($post->post_parent) {
$ancestors = array_reverse(get_post_ancestors($post->ID));
return $ancestors[0];
}
return $post-> ID;
}
HEADER.PHP
<?php
$args = array(
'child_of' => get_top_ancestor_id(),
'title_li' => ''
);
?>
<?php wp_list_pages($args); ?>
This is the default menu calling in wordpress
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu', 'menu_id' => 'primary-menu' ) ); ?>
Directly use this function
<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu', 'menu_id' => 'primary-menu' ) ); ?>
Ahmad, if you just want to list the children of the page that you're currently on, you can use the function wp_get_post_parent_id (http://codex.wordpress.org/Function_Reference/wp_get_post_parent_id)
So, your code might be simplified to
<?php
global $post;
//If the page has children - print the list
if(wp_get_post_parent_id( $post->ID ))
{
$args = array(
'child_of' => wp_get_post_parent_id( $post->ID ),
'title_li' => ''
);
wp_list_pages($args);
}
else{
$args = array(
'child_of' => $post->ID,
'title_li' => ''
);
wp_list_pages($args);
}
?>

Why isn't this Wordpress query sorting properly

I have a custom post_type called special_listing which contains a custom field called listing_index. A special_listing with a listing_index of 20, should appear before one with an index of 15, then 10, and so on. However this doesn't appear to be working and listings appear in whatever order they choose.
I'm not a PHP or Wordpress guy, I mainly deal with ASP.Net and C# so this is a bit confusing for me. Is there some simple mistake I'm making?
Function:
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
sort_array_on_field($posts, 'listing_index', 'DESC');
truncate_array($posts, $count);
return $posts;
}
View:
<?php
$listings = get_listings(get_microsite_slug() . '-microsite-home-featured', 4);
$i = 0;
if (sizeof($listings) > 0) : while ($i < sizeof($listings)) : $listing = $listings[$i]; // Loop and set current listing
?>
<section>
<a href="<?php echo $listing->destination; ?>">
<h3><?php echo $listing->post_title; ?></h3>
<p><?php echo $listing->post_content; ?></p>
</a>
</section>
<?php $i++; ?>
<?php endwhile; ?>
<?php endif; ?>
My attempt:
I don't know how to return the listing_index value
function get_sorted_listings($region_slug, $count){
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_query' => array(
'relation' => 'AND',
array (
'key' => 'listing_region_slug',
'value' => $region_slug
),
array (
'key' => 'listing_index',
'value' => ''
),
orderby: 'listing_index',
order: 'DESC'
)
);
$posts = get_posts($args);
truncate_array($posts, $count);
return $posts;
}
Update
Trying a new way and it now pulls the content in by the published date. Still not ordering by listing_index, but at least it's not completely random either. I began looking to meta_query. Won't this only return a result with a single value? I've also tried out this other SO answer, but I find it's implementation confusing.
<?php
$args = array(
'post_type' => 'kodakalaris_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => get_microsite_slug() . '-microsite-home-featured',
'posts_per_page' => 4,
'order' => 'DESC',
'orderby' => 'listing_index'
);
$listings = new WP_Query($args);
if ($listings->have_posts()) : while ($listings->have_posts()) : $listings->the_post();
?>
...
...
<?php
endwhile;
endif;
?>
You don't need to sort after you query. WP_Query has orderby parameters:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug,
'orderby' => 'meta_value_num'
);
$posts = new WP_Query($args);
return $posts;
}
You'll then want to use The Loop rather than a foreach loop, in your view.
So I was able to figure this out after reading this article, but basically assigning a name to each meta_query array allows you to call which one should take priority when using orderby.
$args = array(
'post_type' => 'special_listing',
'posts_per_page' => 4,
'orderby' => 'index_clause',
'meta_query' => array (
'site_clause' => array (
'key' => 'listing_region_slug',
'value' => get_microsite_slug() . '-microsite-home-featured'
),
'index_clause' => array (
'key' => 'listing_index',
)
)
);
Change the function to :
<?php
// Get the first $count listings with the highest indices for a given $region_slug:
function get_listings($region_slug, $count) {
$args = array(
'post_type' => 'special_listing',
'orderby' => 'listing_index',
'order' => 'DESC',
'meta_key' => 'listing_region_slug',
'meta_value' => $region_slug
);
$posts = get_posts($args);
return $posts;
}

WP magic fields query_posts

I'm trying to display titles from posts of type 'products' with that have a custom field "product_category" (dropdown) with value "food".
When the "food" field is set to type "text" everything is fine. When I change the type of this
field to "dropdown" nothing appears.
To create custom page and custom fields I use Magic Fields plugin in Wordpress.
Here's the code:
<?php
global $wp_query;
query_posts(array(
'post_type' => 'products',
'meta_query' => array(
array(
'key' => 'product_category',
'value' => 'food',
)
))
);
while(have_posts()) : the_post(); ?>
<?php $key = get_post_meta($post->ID, 'title'); ?>
<li <?php post_class(); ?>><?php if($key) { echo $key[0]; } else { the_title(); }; ?></li>
<?php
endwhile;
wp_reset_query();
?>
use meta_key and meta_value
<?php
global $wp_query;
query_posts(array(
'post_type' => 'products',
'meta_query' => array(
array(
'meta_key' => 'product_category',
'meta_value' => 'food',
)
))
);
?>
You need to add the parameter metacompare to the array (meta_compare => 'like') because on table wp_postmeta the key_value is saved like "a:1:{i:0;s:7:"Food";}"
so
you should change to:
query_posts(array(
'post_type' => 'products',
'meta_key' => 'product_category',
'meta_value' => 'food',
'meta_compare' => 'like'
))
);
Try using meta_query instead. Make sure you try both products and product as your post_type parameter.
$args = array(
'post_type' => 'product',
'meta_query' => array(
array(
'key' => 'product_category',
'value' => 'food'
)
)
);
$query = new WP_Query( $args );
Also, don't use query_posts. Here's why.

Resources