Link to home
Start Free TrialLog in
Avatar of manticlight
manticlight

asked on

Wordpress Hierarchical List Pages In Custom Format

I need to generate a list of all Wordpress Pages and have them display in a HTML Table, that will be printed for offline use.

First column is Blank
Second column will have the Page Creation Date
Third column will have the last Page Modified Date
Fourth column will have the Page Title

However, the Pages need to be listed by Menu_Order and if a Page is a child of the one above it, that Page Title either will need to be intended.

Basically, I need something similar to the Wordpress "All Pages" list, but in a simple table format and only the information above.

I have searched Google for several hours and have found some code snippets, but nothing has worked.

wp_list_pages will not allow me to display both Creation and Modified Dates at the same time, nor can I get the formatting I need.
Avatar of Jason C. Levine
Jason C. Levine
Flag of United States of America image

Why not just create a custom page template and add PHP code (wp_query) that directly queries the wp_posts table and returns the columns you need?
Avatar of manticlight
manticlight

ASKER

Because wp_query would not necessarily return the pages in a Hierarchical Order, and I would still have the problem of needing indentation of SubPages, Sub-SubPages, etc.
Ah-ha...now I understand.  Okay, let me dig through some code snippets I have and see if I can cobble something together.
Thanks.  I look forward to hearing back from you.
Sometimes people get so caught up in the siren call of wp_list_pages() they forget about get_pages()

<?php
/**
 Template Name: List Pages With get_page()
 */

get_header(); ?>

		<div id="primary">
			<div id="content" role="main">
				<table>
				<tr><td>Blank</td><td>Page Creation</td><td>Page Modified</td><td>Page Title</td></tr>
				
				<?php 
					$args = array( // including all of the defaults here so you can play with them
						'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 ); 
						foreach ( $pages as $page ) {
						$tablerow = '<tr><td>&nbsp;</td>';
						$tablerow .= '<td>' . $page->post_date . '</td>';
						$tablerow .= '<td>' . $page->post_modified . '</td>';
						$tablerow .= '<td>' . $page->post_title . '</td></tr>';
						echo $tablerow;
					}
				?>
				
				</table>
			</div><!-- #content -->
		</div><!-- #primary -->

<?php get_footer(); ?>

Open in new window


http://codex.wordpress.org/Function_Reference/get_pages
Thank you for your response, but yes - I do know about get_pages().  However, that does not indent the post_title as I require, and mentioned in my original question.  If a page is a subpage, sub-subpage, sub-sub-subpage, etc - I need to have it indented accordingly.

While get_pages() will list the pages in a Hierarchical Order, it does not indent - and that is where I am stuck the most.

As the column Page Title is populated, I need the page_title to indent, similar to:

ID 1 PARENT-ID 0
ID 2 PARENT-ID 0
    ID 3 PARENT-ID 2
    ID 4 PARENT-ID 2
        ID 5 PARENT-ID 4
    ID 6 PARENT-ID 2
ID 7 PARENT-ID 0
ID 8 PARENT-ID 0
   ID 9 PARENT-ID 8

Open in new window

You can fake it by doing a check on $page->post_parent as the foreach loop begins and if the parent value is there, indent by opening a new unordered list or something.
Unfortunately, I do not know how to do that - as there can be any number of pages with the same parent, and while it is indenting those, there can be sub-subpages, sub-sub-subpages, etc. - and I do not know how to put that into a function so that regardless of how deep a page is, it will indent accordingly.
Try this:

Put this to your Theme's Functions.php

function PagesToHtmlTable() {
	// Query pages.
	$args = array(
		'hierarchical' => 0,
		'post_type' => 'page',
		'parent' => 0, //returns all top level pages 
		'sort_column' => 'menu_order',
		'sort_order' => 'asc' //or 'desc'
	); 
	
	$output = '';
	$output = '<table class="my-pages-to-html-table">';

	$output .= '<tr>';
	$output .= '<th>Notice</th>';
	$output .= '<th>Creation Date</th>';
	$output .= '<th>Modified Date</th>';
	$output .= '<th>Page Title</th>';
	$output .= '</tr>';

	$iLevel = 0;

	$mypages = get_pages($args);
	
	foreach( $mypages as $page ) {
		$iLevel = 0;
		
		$output .= AppendPageToHtmlTable($page, $page->post_date, $page->post_modified, $page->post_title, $iLevel);
		
		$mysubpages = get_pages( array( 'child_of' => $page->ID, 'sort_column' => 'menu_order', 'sort_order' => 'asc' ) );

		if ( !empty($mysubpages) ) {
		
			foreach ( $mysubpages as $page ) {
				$iLevel = 1;
				
				// Get depth value
				$iLevel = sizeof($page->ancestors);
				
				$output .= AppendPageToHtmlTable($page, $page->post_date, $page->post_modified, $page->post_title, $iLevel);
			}	
		}
	}
	$output .= '</table>';
	return $output;
}
add_shortcode( 'pages_to_html_table', 'PagesToHtmlTable' );

function AppendPageToHtmlTable($page, $cDate, $mDate, $pTitle, $iLevel) { 

	$output .= '<tr>';
	$output .= '<td>&nbsp;</td>';

	$output .= '<td>' . $cDate . '</td>';
	$output .= '<td>' . $mDate . '</td>';

	if ( 0 == $iLevel ) {
		$output .= '<td>';
	} else {
		$output .= '<td style="text-indent: ' . $iLevel * 15 . 'px">';
	}
	
	
	$output .= $pTitle;
	$output .= '</td>';

	$output .= '</tr>';

	return $output;

}

Open in new window


Put this into your Theme's css file:
table.my-pages-to-html-table{
	border-collapse:collapse;
	border: 1px;
	border-style:solid;
	border-color:black;
	width: 100%;
	margin: 24px 0;
}

table.my-pages-to-html-table td,
table.my-pages-to-html-table th {
	border:1px solid black;
	padding-left:5px;
}

table.my-pages-to-html-table th {
	background-color:yellow;
	/*color:white;*/
	color:black;
}

Open in new window



Add this to your Post or Page:
[pages_to_html_table]

Open in new window


Or add this to your Template file:
<?php echo do_shortcode('[pages_to_html_table]'); ?>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of eemit
eemit
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@eemit - Thank you for providing the code you did.  I feel it is very close to what I need.  However, with both versions of the code, I get the following error "Notice: Undefined property: stdClass::$ancestors" referring to $iLevel = sizeof($page->ancestors);

Referring to http://codex.wordpress.org/Function_Reference/get_pages - "ancestors" is not a key returned with get_pages().
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
With:
$iLevel = sizeof($page->ancestors);
var_dump($page->ancestors);
var_dump($iLevel);

I get:
array
  empty
int 0
array
  empty
int 0
array
  0 => int 87
int 1
array
  0 => int 87
int 1
array
  0 => int 424
  1 => int 87
int 2
array
  empty
int 0

The same with:
$ancestors = get_ancestors( $page->ID, 'page' );
$iLevel = sizeof($ancestors);
var_dump($ancestors);
var_dump($iLevel);

But not with:
$ancestors = get_ancestors( $page->ID ); //as in codex
$iLevel = sizeof($ancestors);
var_dump($ancestors);
var_dump($iLevel);
@eemit - The solution to the error message I reported, was for me to use - as you suggested:

$ancestors = get_ancestors( $page->ID, 'page' );
$iLevel = sizeof($ancestors);

Open in new window


That got me exactly to what I need, and to a point where all I need to do is style it more to my liking.

I chose "Version 2" as the solution because code was several lines smaller and didn't require the extra Append Function.

Awesome work!
That's good stuff.  Nice work eemit