Ok here's one for ya...
On a custom template I'm using this code to retrieve & display a list of child pages/posts
$args = array(
'depth' => 1,
'show_date' => '',
'date_format' => get_option('date_format'),
'child_of' => $post->ID,
'exclude' => '',
'include' => '',
'title_li' => '',
'echo' => 1,
'authors' => '',
'sort_column' => 'menu_order, post_title',
'link_before' => '',
'link_after' => '',
'walker' => '' );
wp_list_pages( $args );
This works great, I'm also wondering how I can access/create an array of child post ID's. My goal is to access some custom fields meta data through the get_post_meta() function of each child post using it's ID.
Thanks guys.
I guess I wasn't very clear with this one as it's the first time I've never recieved an answer from SO.
I managed to find the information I needed and will place it here for anyone else browsing with the same request.
ok - To get all child IDs..
$pages = get_pages('child_of=X');
foreach($pages as $child) {
// Now you have an object full of Children ID's that you can use for whatever
// E.G
echo $child->ID . "<br />";
}
If you want to build an array of post ids for later use you can do this:
$pageids = array();
$pages = get_pages('child_of=X');
foreach($pages as $page){
$pageids[] = $page->ID;
}
And you have a clean array of just page ids.
$children = get_posts('post_parent=SLUG_OF_PARENT_POST&post_status=publish');
foreach($children as $child)
{
echo '<br/>ID:'.$child->ID;
}
you can use other attributes (i.e. $child->post_content)...
if you need to define post_type, then add this argument too : &post_type=POST_TYPE_NAME
Another way to do this:
$my_page_id = 12345;
$child_query_args = array(
'post_parent' => $my_page_id,
'post_type' => 'page',
'posts_per_page' => -1,
'fields' => 'ids',
);
$child_query = new WP_Query($child_query_args);
if ( $child_query && $child_query->have_posts() && $child_query->posts ) {
// (Since fields=ids, $child_query->posts is just an array of IDs)
$child_ids = $child_query->posts;
foreach ( $child_ids as $child_id ) {
$whatever = get_post_meta( $child_id, 'whatever', true );
echo esc_html($whatever);
}
}
Related
I'm making a sidebar that will display sibling pages if the current page is the deepest level child, and only child pages if it is not. This is as far as I've gotten, I haven't been able to figure out the logic to complete it. Any ideas? Thank you in advance.
global $post;
if ( is_page() && $post->post_parent )
$childpages = wp_list_pages( 'sort_column=menu_order&title_li=&child_of=' . $post->post_parent . '&echo=0' );
else
$childpages = wp_list_pages( 'sort_column=menu_order&title_li=&child_of=' . $post->ID . '&echo=0' );
if ( $childpages ) {
$interior_sidebar = '<ul class="child-pages">' . $childpages . '</ul>';
}
Use wp_list_pages() with your parameters to get children of current post. If it comes back empty then display wp_list_pages() of current post's parent; if not empty display what was returned.
You are on the right track.
global $post isn't safe to use (it can be a post other than the page you are viewing), especially in a sidebar - I'd recommend doing something like get_queried_item().
And, to keep things simple, rather than calling wp_list_pages multiple times, I'd recommend setting up the arguments in each of condition, then having a single wp_list_pages call at the end.
// safer method to get the page you are viewing
$post = get_queried_object();
// will be TRUE if there's any child pages, FALSE if not
$has_children = (0 != get_pages( [ 'child_of' => $post->ID ] ) );
// set to prevent notices
$child_pages = FALSE;
if ( is_page( $post->ID ) && $post->post_parent ) {
$args = [
'sort_column' => 'menu_order',
'title_li' => '',
'echo' => 0,
// this is a ternary operation, that assigns $post->ID if $has_children, or $post_parent if not
'child_of' => ( $has_children ) ? $post->ID : $post->post_parent
];
$childpages = wp_list_pages( $args );
}
if ( $childpages ) {
$interior_sidebar = '<ul class="child-pages">' . $childpages . '</ul>';
}
NOTE: I've used the shorthand version for array declarations (example, [ 'child_of' => $post->ID ] instead of array( 'child_of' => $post->ID ) - this works for PHP versions 5.4+ - if you're on an older version of PHP, upgrade - it's not supported any longer
Solved with:
function wpb_list_child_pages() {
global $post;
$childpages = wp_list_pages(array(
'child_of' => $post->ID,
'depth' => 1,
'echo' => '0',
'sort_column' => 'menu_order',
'title_li' => ''
));
if ( $childpages ) {
$string =$childpages;
} else {
$childpages = wp_list_pages(array(
'child_of' => $post->post_parent,
'depth' => 1,
'exclude' => $post->ID,
'title_li' => ''
));
$string = $childpages;
}
echo $string; }
I then simply called the function in my template: <ul class="child-pages"><?php wpb_list_child_pages(); ?></ul>
Hi I have created my own custom post type within Wordpress to contain projects that i can call via my theme files.
I am new to creating my own themes. I currently am using the following code in my single.php file to call in related articles based on the category of the blog post.
<?php
// Default arguments
$args = array(
'posts_per_page' => 3, // How many items to display
'post__not_in' => array( get_the_ID() ), // Exclude current post
'no_found_rows' => true, // We don't ned pagination so this speeds up the query
);
// Check for current post category and add tax_query to the query arguments
$cats = wp_get_post_terms( get_the_ID(), 'category' );
$cats_ids = array();
foreach( $cats as $wpex_related_cat ) {
$cats_ids[] = $wpex_related_cat->term_id;
}
if ( ! empty( $cats_ids ) ) {
$args['category__in'] = $cats_ids;
}
// Query posts
$wpex_query = new wp_query( $args );
// Loop through posts
foreach( $wpex_query->posts as $post ) : setup_postdata( $post ); ?>
<div class="col-md-4 related-post">
<?php the_post_thumbnail('large'); ?>
<?php the_title(); ?>
</div>
<?php
// End loop
endforeach;
// Reset post data
wp_reset_postdata(); ?>
In my new post type "projects" i would like to call in related projects. Which im assuming would be very similar code except i need to stop it looking for posts and instead look for my projects.
Here is my code for new post type:
// Projects
add_action( 'init', 'create_post_type' );
add_post_type_support( 'bw_projects', 'thumbnail' );
add_post_type_support( 'bw_projects', 'custom-fields' );
function create_post_type() {
register_post_type( 'bw_projects',
array(
'labels' => array(
'name' => __( 'Projects' ),
'singular_name' => __( 'Projects' )
),
'public' => true,
'has_archive' => true,
'taxonomies' => array( 'category','post_tag'),
)
);
}
What would i need to change in my first code snippet in order to look for bw_projects and not look for 'posts' anymore. I tried playing around and changing certain lines myself but i caused more issues and stopped the page loading. Is this even right i can use the same code, slightly altered or would i need something completely different?
Thanks in advance.
You can get any post type that you require using get_posts();
<?php $args = array(
'posts_per_page' => 5,
'offset' => 0,
'category' => '',
'category_name' => '',
'orderby' => 'date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => 'projects',
'post_mime_type' => '',
'post_parent' => '',
'author' => '',
'author_name' => '',
'post_status' => 'publish',
'suppress_filters' => true
);
$posts_array = get_posts( $args ); ?>
Simply set the 'post_type' argument to that of you custom post type, to get only these posts. You can also set the number of post, and filter by category etc.
You can find more info in the codex.
Alternatively, if you wanted to keep something similar to your existing code you could try using 'pre_get_posts' to filter the query to just your projects. However you'd need to remember to add / remove this filter so it only operates on the queries that need it.
To display the posts you can use a simple foreach to churn them out. You#d obviously want to do some sort of styling to get the layout correct:
$args = array("posts_per_page" => 10, "orderby" => "comment_count");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}
Or a really concise way of doing all of the above would be something like:
$args = array("posts_per_page" => 5, "post_type" => "projects");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}
Since I didn't find anything helpful on the web I'd like to ask:
In WP you can with wp_list_categories and show_count=1 and hide_empty=0 list all categories (even empty ones) with the number of posts at the end.
example output: General (9)
So when I make a private post and publish it the count for General remains on 9.
Is there a way I can also show the count of private posts?
Well I found quite a solution for this:
$args = array(
'include' => array( 8,9,10 ), //categories that contains the private articles
'title_li' => '',
'show_count' => 0,
'hide_empty' => 0,
);
$categories = get_categories($args);
foreach($categories as $category) {
$args_priv = array(
'cat' => $category->term_id,
'post_status' => array( 'private','publish' ),
);
$the_query = new WP_Query( $args_priv );
$count = '('. $the_query->found_posts .')';
echo '' . $category->name.' '.$count.'<br />';
}
I am trying to get the categories of my custom post type in functions.php But it not return any value, when i run this query in any theme file it work fine. Here is my code
function get_destinations(){
$args = array(
'type' => 'accomodation',
'child_of' => 0,
'parent' => '',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => 1,
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'number' => '',
'taxonomy' => 'facilitie',
'pad_counts' => false
);
$categories = get_categories($args);$destinations = array();
foreach ($categories as $cat) {
if($cat->cat_name != ''){
$destinations[$cat->cat_name] = $cat->cat_name;
}
}
return $destinations;
}
I am using this code to add meta field, now i have to pass the category to select tag which is
$my_meta2->addSelect($prefix.'select_field_id',get_destinations(),array('name'=> 'Select Destination'));
The original code is like this, they pass the value in array.
$my_meta->addSelect($prefix.'select_field_id',array('selectkey1'=>'Select Value1','selectkey2'=>'Select Value2'),array('name'=> 'My select ', 'std'=> array('selectkey2')));
But not getting any value, Any idea where i am wrong. Thanks
As far as i know, get_categories() won't accept a post_type argument. You probably should use taxonomy for that.
You can find more info here:
https://codex.wordpress.org/Function_Reference/get_categories
I need to display all the pages on the one page.
At the moment I am using this to bring in each page:
<?php
$page_id = 5; //id example
$page_data = get_page( $page_id );
$content = apply_filters('the_content', $page_data->post_content);
$title = $page_data->post_title;
echo $content;
?>
But if a new page is created it wont display it as wont have this code and its ID in place..
Is there a way to bring all the pages in automatically?
Any help will be appreciated, thanks
You can get all the pages of your blog by using get_pages();, do this in a loop like so:
$pages = get_pages();
foreach ($pages as $page_data) {
$content = apply_filters('the_content', $page_data->post_content);
$title = $page_data->post_title;
echo $content;
}
The accepted answer's returned array doesn't contain "post customs" (which I needed in my case). And also you may need to retrieve pages with specific attributes. Use args for more customized results:
<?php $args = array(
'sort_order' => 'asc',
'sort_column' => 'post_title',
'hierarchical' => 1,
'exclude' => '',
'include' => '',
'meta_key' => '',
'meta_value' => '',
'authors' => '',
'child_of' => 0,
'parent' => -1,
'exclude_tree' => '',
'number' => '',
'offset' => 0,
'post_type' => 'page',
'post_status' => 'publish'
);
$pages = get_pages($args);
?>
And use them like this:
<?php
foreach ($pages as $page) {
$title = $page->post_title;
echo $title. "<br />";
} ?>
Read more here
Also, if you are using the Twenty Ten theme (I don't know how will it work in others) you can easily get all the pages formatted:
echo "<h1 class=\"entry-title\">".$title."</h1>"
."<div class=\"entry-content\">".$content."</div>";
Well you can get the contents of each page by this code as well.
$content = apply_filters( 'the_content', $content );
Still there is huge problem if you are using custom templates for different pages you can get the content but not the template files on your one page