Create hierarchical navigation for custom post types in Wordpress with PODS

By: (plus.google.com) +David Herron; Date: 2015-06-20 23:27

Tags: Wordpress

On (longtailpipe.com) my Wordpress site I want to create "documentation" areas with a cluster of pages organized as a hierarchy, with an index to those pages showing as a sidebar. Many think of doing this for "Product Documentation", but I simply want to organize notes and additional material related to some books that I'm writing. Just as a book is organized by chapters and subsections, I want to hierarchically organize these pages.

As a Drupaler, what I want is the "book" content type but for Wordpress. The Drupal book content type is one of the out-of-the-box features to organize pages in a hierarchy, along with nice hierarchical navigational elements attached to the page automagically.

Apparently one can do this in Wordpress for Pages, but I wanted these pages to be outside the Page list. I use the PODS Framework to help with creating custom content types since it's similar to the effect of adding CCK to a Drupal 6 site. When creating a custom content type in PODS it's simple enough to add hierarchy support, but the problem is how to get the hierarchy to display.

Turns out that Wordpress provides some functions with which to construct the navigational elements.

The first thing to cover is the Next and Previous entries in the book page hierarchy. That seems to be automagically generated by something, presumably Wordpress in supporting Hierarchical node types.

The next thing - and this is what I wanted to show off - is creating a tree structured listing of pages within a particular book page area. While it's fairly easy to do, the steps weren't well documented.

Let's first back up a second to discuss the display of custom fields in a custom post type. The PODS framework doesn't help with this, nor does Wordpress do so out of the box. You can create a custom post type with PODS and add a bunch of fields to that post type, but your visitors won't know anything about that extra data by default.

Therefore it's necessary to create a custom theme file -- actually two of them -- for each custom post type. One custom theme file shows the "excerpt" for Archive pages, and the other shows the Full display for use from single.php. Theoretically the PODS Frontier Auto Template plugin is supposed to be used for displaying custom content of custom post types -- but I couldn't figure out how to do anything useful with that plugin. Hence, the plugin is installed and activated but I'm ignoring it.

In other words, what I'm about to show you is code for the template file for the full display of the custom post type.

With that in mind - in the full display template for your custom post type, add the following:

<?php the_content(); ?>
<?php theme_name_book_show_children($post); ?>

This is going to immediately make page loading for this post type fail. That's good because we know there's a problem, and now we get to fix it.

In the functions.php for your theme add this function:

function theme_name_book_show_children($post) {
    if ($post->post_parent) {
      $post_parent = get_post($post->post_parent);
      ?>
      <ul>
      <li><a href="<?php echo get_permalink($post->post_parent); ?>"><?php echo $post_parent->post_title; ?></a>
      <ul>
      <?php 
        wp_list_pages(array(
           'post_type' => 'book_page',
           'sort_column' => 'menu_order',
           'child_of' => $post->post_parent,
           'title_li' => null
        ));
       ?>
      </ul></li></ul><?php
    } else {
      ?><ul>
      <ul>
      <li><a href="<?php echo get_permalink($post->ID); ?>"><?php echo $post->post_title; ?></a>
      <ul>
      <?php 
        wp_list_pages(array(
           'post_type' => 'book_page',
           'sort_column' => 'menu_order',
           'child_of' => $post->ID,
           'title_li' => null 
        ));
       ?>
      </ul></li></ul><?php
    }
}

That's a fair amount of code, but it's pretty straight-forward. The key is the wp_list_pages function. This function generates HTML for a list of posts, given parameters we pass in through the array.

Since we've created a custom post type, we have to specify it's slug name in the post_type parameter.

The sort_column parameter makes the results make sense within the hierarchical ordering of posts of this custom post type.

The title_li parameter is something I'm doing by hand, rather than letting the wp_list_pages function do it. Passing null like this turns off that feature. The code as I've written it creates an outer ul list, with its item listing the parent post of the tree of posts we're going to display. That way the user can navigate to the parent post fairly easily. Within that it creates another ul list, containing the posts generated using the wp_list_pages function.

Finally we get to the child_of parameter. That parameter tells Wordpress from which post to generate the tree of posts. As it stands we'll go to the parent of the current post (if there is one) or start at the current post.

This code does have a problem - it seems to only go one level deep - and it doesn't go the top-most parent of the page tree that this post belongs to. I'll work on this issue and then update this blog post.

« Russia’s disinformation campaign in Europe Why are Russian trolls spreading online hoaxes in the U.S.? »
2016 Election Acer C720 Ad block AkashaCMS Amazon Amazon Kindle Amiga Android Anti-Fascism Apple Apple Hardware History Apple iPhone Apple iPhone Hardware April 1st Arduino ARM Compilation Astronomy Asynchronous Programming Authoritarianism Automated Social Posting Ayo.JS Bells Law Big Brother Big Finish Black Holes Blade Runner Blogger Blogging Books Botnet Botnets Cassette Tapes Cellphones Christopher Eccleston Chrome Chrome Apps Chromebook Chromebooks Chromebox ChromeOS CIA CitiCards Citizen Journalism Civil Liberties Clinton Cluster Computing Command Line Tools Computer Hardware Computer Repair Computers Cross Compilation Crouton Curiosity Rover Cyber Security Cybermen Daleks Darth Vader Data backup Data Storage Database Database Backup Databases David Tenant DDoS Botnet Detect Adblocker Developers Editors Digital Photography DIY DIY Repair DNP3 Docker Doctor Who Doctor Who Paradox Drobo Drupal Drupal Themes DVD E-Books E-Readers Early Computers Election Hacks Electric Bicycles Electric Vehicles Electron Emdebian Energy Efficiency Enterprise Node EPUB ESP8266 Ethical Curation Eurovision Event Driven Asynchronous Express Facebook Fake News Fedora VirtualBox File transfer without iTunes FireFly Fraud Freedom of Speech Gallifrey git Gitlab GMAIL Google Google Chrome Google Gnome Google+ Government Spying Great Britain Heat Loss Hibernate Home Automation HTTPS I2C Protocol Image Analysis Image Conversion Image Processing ImageMagick InfluxDB Infrared Thermometers Insulation Internet Internet Advertising Internet Law Internet of Things Internet Policy Internet Privacy iOS Devices iPad iPhone iPhone hacking Iron Man Iternet of Things iTunes Java JavaScript JavaScript Injection JDBC John Simms Journalism Joyent Kindle Marketplace Lets Encrypt LibreOffice Linux Linux Hints Linux Single Board Computers Logging Mac OS Mac OS X MacOS X setup Make Money Online MariaDB Mars Matt Lucas MEADS Anti-Missile Mercurial Michele Gomez Micro Apartments Military Hardware Minification Minimized CSS Minimized HTML Minimized JavaScript Missy Mobile Applications MODBUS Mondas MongoDB Mongoose Monty Python MQTT Music Player Music Streaming MySQL NanoPi Nardole NASA Net Neutrality Node Web Development Node.js Node.js Database Node.js Testing Node.JS Web Development Node.x North Korea Online advertising Online Fraud Online Journalism Online Video Open Media Vault Open Source Governance Open Source Licenses Open Source Software OpenAPI OpenVPN Personal Flight Peter Capaldi Photography PHP Plex Plex Media Server Political Protest Postal Service Power Control Privacy Production use Public Violence Raspberry Pi Raspberry Pi 3 Raspberry Pi Zero Recycling Remote Desktop Republicans Retro-Technology Reviews Right to Repair River Song Robotics Rocket Ships RSS News Readers rsync Russia Russia Troll Factory SCADA Scheme Science Fiction Season 1 Season 10 Season 11 Security Security Cameras Server-side JavaScript Shell Scripts Silence Simsimi Skype Social Media Warfare Social Networks Software Development Space Flight Space Ship Reuse Space Ships SpaceX Spear Phishing Spring Spring Boot SQLite3 SSD Drives SSD upgrade SSH SSH Key SSL Swagger Synchronizing Files Telescopes Terrorism The Cybermen The Daleks The Master Time-Series Database Torchwood Total Information Awareness Trump Trump Administration Ubuntu UDOO Virtual Private Networks VirtualBox VLC VNC VOIP Web Applications Web Developer Resources Web Development Web Development Tools Web Marketing Website Advertising Weeping Angels WhatsApp Window Insulation Wordpress YouTube