Displaying parent page on child page list - php

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

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.

Get WordPress Child Page IDs

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);

Calling & Displaying Attachments from Sub-Pages - WordPress

I'm new to WordPress (duh) and trying something I'm very close to getting.
I have several Sub-Pages, each of which has attachments - images. I simply want to display these images. The client will regularly be adding more subpages so the code has to know to only display the images of its self, so to speak. An issue I'm running into is each subpage is displaying all the attachments of all subpages.
In my Functions.php I have this code to determine if the page is infact a subpage:
//find out if it is a suppage to use in page.php as function 'is_subpage'
function is_subpage() {
global $post; // load details about this page
if ( is_page() && $post->post_parent ) { // test to see if the page has a parent
return $post->post_parent; // return the ID of the parent post
} else { // there is no parent so ...
return false; // ... the answer to the question is false
}
}
In my page.php I have an If statement, for all my usual pages. It culminates in this:
elseif ( is_subpage() ) {
get_template_part( 'exhibition-template' );
get_template_part( 'normalfooter' );
}
In exhibition-template.php, where I want my images to appear I have this:
<?php
if ( is_subpage( $post->ID ) ) { //I think I screwed up here, innermost brackets
$args = array(
'order' => 'ASC',
'post_type' => 'attachment',
'post_parent' => $post->ID, //or is my issue here...?
'post_mime_type' => 'image',
'post_status' => null,
'numberposts' => -1,
);
$attachments = get_posts($args);
if ($attachments) {
foreach ($attachments as $attachment) {
echo wp_get_attachment_link($attachment->ID, 'large', false, false);
}
}
}
?>
However, what happens is each and every subpage simply displays all the images across all subpages, and frankly, I'm just too DUMB to know how to progress, or what to play with, where to start.
Any ideas?
It looks like you have a few issues.
When testing to see if a page is a subpage you should test to see if $post->post_parent is greater than 0. So like this:
if ( is_page() && $post->post_parent > 0 ) {
return $post->post_parent;
} else {
return false;
}
You do not need to pass any arguments into if ( is_subpage( $post->ID ) )... You could also just use WordPress' get_attached_media() function to get these attachements as well. This is how your exhibition-template.php could look:
if ( is_subpage() ) {
$attachments = get_attached_media('image', $post->ID);
foreach ($attachments as $attachment) {
echo wp_get_attachment_link($attachment->ID, 'large', false, false);
}
}

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!

List only child categories a post is in, of a specific parent category

Either this is harder than it needs to be or I am just not understanding WordPress/PHP very well :( All I want to do is show the child/sub categories of a specific parent category...but only if the post is in those subcategories. Specific example:
I am building a wine reviews website and these are the categories:
BrandSubcategory 1Subcategory 2etc.
RegionSubcategory 1Subcategory 2etc.
GrapeSubcategory 1Subcategory 2etc.
The parent categories will never change, and every post will have at least 1 subcategory selected under each parent, so in the LOOP I can just list the parents by name. But I am needing to dynamically output the subcategories, something like this:
Brand: <?php list_post_subcategories('brand'); ?>
Region: <?php list_post_subcategories('region'); ?>
Grape: <?php list_post_subcategories('grape'); ?>
Is there any easy way like this? It seems like this should be a basic function in Wordpress? I've looked at the functions 'get_categories' and 'in_category' but they don't seem to be able to do this.
<?php $post_child_cat = array();
foreach((get_the_category()) as $cats) {
$args = array( 'child_of' => $cats->cat_ID );
$categories = get_categories( $args );
if( $categories ) foreach( $categories as $category ) {
echo $category->cat_name; }
} ?>
try this
I posted to Wordpress Answers to get more help and #Milo gave a great code solution:
// get top level terms
$parents = get_terms( 'category', array( 'parent' => 0 ) );
// get post categories
$categories = get_the_terms( $post->ID, 'category' );
// output top level cats and their children
foreach( $parents as $parent ):
// output parent name and link
echo '' . $parent->name . ': ';
// initialize array to hold child links
$links = array();
foreach( $categories as $category ):
if( $parent->term_id == $category->parent ):
// put link in array
$links[] = '' . $category->name . '';
endif;
endforeach;
// join and output links with separator
echo join( ', ', $links );
endforeach;
You can use array_map so you can return only the categories that you want. For example:
array_map( function( $cat ) {
if ( $cat->parent != 0 ) {
return $cat;
}
},
get_the_category()
);

Categories