Get WordPress Child Page IDs - php

I'd like to shorten this code and instead of manually placing all children Id's, I'd like to pull out only the id's and set it to array. this could be something dynamic in the future when they are adding new child page from the parent page.
if ( in_array($post->ID, ['39','41','43','45']) ) {
$menuPage = 'about';
} elseif ( in_array($post->ID, ['47','49','51','53','55','57']) ) {
$menuPage = 'asset';
}
get_template_part( _menu, $menuPage );
I tried some codes but it technically display the title only. Where I am currently using similar to this code.
<ul class="uk-nav uk-navbar-dropdown-nav uk-list uk-list-inline">
<?php
$args = array(
'depth' => 1,
'include' => 15,
'title_li' => '',
);
wp_list_pages($args);
$args['child_of'] = $args['include'];
unset($args['include']);
wp_list_pages($args);
?>
</ul>

You can verify the menu to be printed by using wp_get_post_parent_id( $post_ID );, see codex: https://codex.wordpress.org/Function_Reference/wp_get_post_parent_id
Will check the parent ID of every visited child page, then use PHP switch to match the menu.
switch(wp_get_post_parent_id( $post->ID )){
case 1: //parent page ID
$menuPage = 'about';
break;
case 2: //parent page ID
$menuPage = 'asset';
break;
default:
$menuPage = 'default-menu';
}
Also, if you only want to return the child pages from a specific parent, you can use:
$args = array(
'child_of' => $post->ID,
);
$pages = get_pages($args);

Related

Exclude specific category from Related Posts

Looking to exclude specific category (ID = 100) from "Related Posts" feed at bottom of Blog pages. Extra bonus if it can also exclude from the sidebar archive (not sure if they are connected??)
I'm using WP Theme "TheFox", have asked them - not part of their theme.
I "think" it has to do in the functions.php. I have found some similar questions, and code, but have not had any luck.
I'm a complete noob for .php, so be gentle :)
I've found some other attempts, no luck. Not registering or effecting the feed.
$categories_to_exclude [ 100 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
What I could gather from your question is that You want to ignore one category (may be more) in the related post query?
use the following CODE (some explanation is given within the CODE in comments):
// set the category ID (or multiple category IDs)
// you want to ignore in the following array
$cats_to_ignore = array( 2 );
$categories = wp_get_post_categories( get_the_ID() );
$category_in = array_diff( $categories, $cats_to_ignore );
// ignore only if we have any category left after ignoring
if( count( $category_in ) == 0 ) {
$category_in = $categories;
}
$cat_args = array(
'category__in' => $category_in,
'posts_per_page' => 4,
'orderby' => 'date',
'post__not_in' => array( get_the_ID() )
);
$cat_query = new WP_Query( $cat_args );
while ( $cat_query->have_posts() ) : $cat_query->the_post();
/* just example markup for related posts */
echo '<h2>' . get_the_title() . '</h2>';
endwhile;
// reset $post after custom loop ends (if you need the main loop after this point)
wp_reset_postdata();
Use the below code, it must work
$categories_to_exclude [ 81, 11, 21 ];
$first_cat = false;
$categories = get_the_category( $post->ID );
while ( ! empty( $categories ) && false === $first_cat ) {
if ( in_array($categories[0]->cat_ID, $categories_to_exclude) ) {
array_shift($categories);
}
else {
$first_cat = $categories[0]->cat_ID;
}
}
You get the categories with get_the_category. Then in the while loop you skip the first category if it's 81, and look again. If it's not 81 (and you still have categories available), you asign it to $first_cat and carry on.

Displaying parent page on child page list

I have a script that is displaying child page list on parent page and a list o child pages without the current child page.
I would like to add the parent page on child pages, but I don't know how to achieve it. Could you please help me out?
This is my code:
if ('page-parent') {
echo '<h3>See also</h3>';
// if we are on a parent page set the $parent variable to current post id
// otherwise set $parent variable to current post parent
$parent = $post->post_parent == 0 ? $post->ID : $post->post_parent;
// if we use current post parent as $parent, exclude the current page
$exclude = $parent == $post->post_parent ? $post->ID : false;
// get all the children
$args = array( 'parent' => $parent, 'sort_column' => 'menu_order' );
if ( $exclude ) $args['exclude'] = $exclude;
$child_pages = get_pages($args);
// show only if there are children
if ( ! empty($child_pages) ) {
global $post;
foreach ( $child_pages as $post ) { setup_postdata( $post );
?>
<div class="child-thumb">
<?php the_title(); ?>
</div>
<?php
}
wp_reset_postdata();
}
}
You need to use 'child_of' argument instead of 'parent'. 'parent' in get_pages means to fetch or not to fetch parental pages.
But your case needs to fetch children of given page.
So you must use
$args = array( 'child_of' => $parent,
'sort_column' => 'menu_order' );
To display one single parent page above children, you can use get_post function:
if ($post->post_parent>0){
$parent_page=get_post($post->post_parent);
echo '<div>'.$parent_page->post_title.'</div>';
}
if ( ! empty($child_pages) ) {
///and so on...
For more information: https://codex.wordpress.org/Function_Reference/get_pages

Listing WordPress Pages - Replace heading with custom field text

I am working with a hierarchy of pages and want to list the parent & children as a sidebar index (with current page bolded). It's sort of working, but the PHP script I've come up with is using the main page heading to create the link text. These headings are very long for SEO purposes, so I'd like to replace them with the ACF 'subtitle' field that I'm already using. Here's the project before I begin to explain:
https://newstart.staging.wpengine.com/treatment/mental-health/depression
In This Section shows the script-generated list first with the obnoxiously long titles. The shorter titles (beginning with "Mental Health") were hard coded as placeholders, and that is what I would like the script to end up looking like. For example:
Depression is a Huge Risk Factor for Substance Abuse
(should be...)
Depression
How can I replace these titles with the subtitles? The get_field value in ACF is subtitle
Here is what the PHP looks like now:
<?php
//---- GET THE PAGE'S ANCESTORS
global $post;
$anc = get_post_ancestors( $post->ID );
//---- IF $ANC HAS MORE THAN 1 VALUE
//---- THEN WE HAVE A 3RD LEVEL CHILD PAGE
//---- AND THUS WANT THE PARENT ID
$top_id = $post->ID;
if (count( $anc ) > 1 ){
$top_id = $anc[0];
}
//---- TAKEN FROM WP CODEX
$ancestor_id = $top_id;
//VERY IMPORTANT, THE ORDER OF THIS ARRAY
//ENSURE THE SORTING MATCHES IN WP_LIST_PAGES BELOW
$descendants = get_pages(array(
'child_of' => $ancestor_id,
'sort_order' =>'ASC',
'sort_column' => 'menu_order',
));
$incl = "";
foreach ($descendants as $page) {
if (($page->post_parent == $ancestor_id) ||
($page->post_parent == $post->post_parent) ||
($page->post_parent == $post->ID))
{
$incl .= $page->ID . ",";
}
}
//---- MAKE A FINAL ARRAY FOR USE
//---- AS THE PREV//NEXT NAVIGATION
$pages_array = explode( ',', $incl );
array_pop($pages_array); //pop off last empty value
array_unshift( $pages_array, $ancestor_id); //add the top level page
// echo '<pre>';
// print_r($pages_array);
// echo '</pre>';
?>
<?php
//FIND THE NEXT ITEM
//IN THE PAGES ARRAY
//AFTER THE CURRENT PAGE
$curr_key = array_search($post->ID, $pages_array);
$curr_key++;
?>
<?php if( $curr_key < count($pages_array) ){ ?>
<?php
$id = $pages_array[$curr_key];
$title = get_the_title( $id );
$post = get_post( $id );
?>
<div class="col-md-2 hidden-sm hidden-xs section-index">
<h6>In This Section</h6>
<ul>
<?php
wp_list_pages(array(
"include" => $ancestor_id,
"link_before" => "",
"title_li" => "",
));
wp_list_pages(array(
"child_of" => $ancestor_id,
"include" => $incl,
"link_before" => "",
"title_li" => "",
'sort_order' =>'ASC',
'sort_column' => 'menu_order',
));
?>
</ul>
I come from a design background so I am not good with PHP syntax yet. Most of this is inherited code that I only vaguely understand. Any help would be appreciated!

Custom Fields not showing in custom post type post

I have a custom post type named "Designer" Each posts will be using different unique Advanced Custom Fields as each posts has unique templates.With the below code I am able to give rules for each posts in Designer post type and save but the custom fields are not displaying on post edit pages on backend.
Normally this code should ork but no idea what happend to the code
Please Help.
add_filter('acf/location/rule_types', 'acf_location_rules_types');
function acf_location_rules_types( $choices )
{
$choices['Custom Post types']['cpt_parent'] = 'Custom post type parent';
return $choices;
}
add_filter('acf/location/rule_values/cpt_parent', 'acf_location_rules_values_cpt_parent');
function acf_location_rules_values_cpt_parent( $choices )
{
$args = array(
'hierarchical' => true,
'_builtin' => false
);
$posttypes = get_post_types( $args );
if( $posttypes )
{
foreach( $posttypes as $posttype ):
if( $posttype != 'acf' ):
$args = array(
'post_type' => 'designer',
'posts_per_page' => -1,
'post_status' => 'publish'
);
$customposts = get_posts( $args );
if ( $customposts ) {
foreach( $customposts as $custompost ){
$choices[ $custompost->ID] = $custompost->post_title;
}
}
endif;
endforeach;
}
return $choices;
}
//MATCH THE RULE
add_filter('acf/location/rule_match/cpt_parent', 'acf_location_rules_match_cpt_parent', 10, 3);
function acf_location_rules_match_cpt_parent( $match, $rule, $options )
{
global $post;
$selected_post = (int) $rule['value'];
// post parent
$post_parent = $post->post_parent;
if( $options['page_parent'] ) {
$post_parent = $options['page_parent'];
}
if ($rule['operator'] == "=="){
$match = ( $post_parent == $selected_post );
}
elseif ($rule['operator'] != "!="){
$match = ( $post_parent != $selected_post );
}
return $match;
}
Your Artist Collection field group is set to only appear on one post, the post Designer Post 1 which is a Designer Post type.
I don't understand what all the code is for? Just create a different field group for each post that needs a different field group and a separate rule for each.
Ok sorry I understand the issue now and I have recreated the issue on my local install.
On the line of code below you are looking for the post_parent but I think you should be looking for the ID.
I changed this:
$post_parent = $post->post_parent;
to this:
$post_parent = $post->ID;
and it's working for me.
If I understand your problem correctly, in wp-admin post edit page click on screen options on the upper right corner. In the menu that appears make sure the Custom fields is selected. This will make the custom fields appear for edit.

Count or/and list only unique items of a WordPress loop

Here is an example loop:
$args = array('s' => 'Example search term', 'cat' => 100, 'posts_per_page' => -1);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
while ( $query->have_posts() ) { $query->the_post();
foreach((get_the_category()) as $category) {
echo $category->cat_name . '<br />';
}
}
}
wp_reset_query();
Assuming that the category with the id# 100 is a parent category for several subcategories, this loop successfully returns a list of heavily duplicated category names.
How could I list only unique category names and count them? And put both values into appropriate variables.
Along with the complete list of all found results and their count, too...
Of course I'll try to figure out the solution myself while waiting for your kind answer, as always. But, actually, a little help would be much appreciated.
So, I'll respond to myself. Again )
Thanks to #Perumal93's hint which directed me the correct way, I now have the solution.
In case it would be usable for anyone like me, here is the commented code ready for copy and paste:
$args = array('s' => 'Example search term', 'cat' => 100, 'posts_per_page' => -1);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
$categories = array(); // 1. Defining the empty array outside of the loop
while ( $query->have_posts() ) { $query->the_post();
foreach((get_the_category()) as $category) {
$categories[] = $category->cat_name; // 2. Filling the array with required data
}
}
$u_categories = array_unique($categories); // 3. Clearing the array from repeated data
$u_categories_cnt = count($u_categories); // 4. Counting the cleared array items
foreach( $u_categories as $category ) { // 5. Outputting
if($category == end($u_categories)) { echo $category.'.'; } // the cleared
elseif($category == prev($u_categories)) { echo $category.' and '; } // array in a
else {echo $category.', '; } // human
} // friendly way
echo $u_categories_cnt; // 6. Outputting the cleared array items count
}
wp_reset_query();
That's it

Categories