Technology

Family hierarchy in WordPress: Pages within pages

Posted by Pixafy Team

wordpress-family-hierarchy

Creating Pages and Page templates can make all the difference in keeping things manageable for both you and the user. Pages are also really simple to apply templates to so that every Page can have its own unique flair. If you haven’t already tried out Page templates, feel free to roll back to our earlier post on the topic.

If you’re familiar with Page template creation, then you may also be familiar with a common problem many face – Pages with more complicated layouts that require all the content to be editable without flooding the WYSIWYG editor with HTML.

If you’re a developer, odds are it’s midnight and you just need this site to catch its one way flight to “Complete.” The easy solution would be to just throw some of the HTML in with the text into the WYSIWYG editor or to leave some text in the template. Then you have to give your client this ominous warning about carefully making changes around this hieroglyphics we call HTML as well as breaking the news to them that not everything on the Page is editable in spite of it being WordPress, and WordPress should make content management, well, manageable.

In the long run, neither of these methods pay off as something will, not can, but will get accidentally deleted in the WYSIWYG editor and you will be guaranteed to receive more phone calls just to change that one bit of un-editable text that you hoped wasn’t too important in the template. So to save frustration on both ends, if you have the timeline and the budget to put a little extra time in, you definitely should.

But how can you make all blocks of text on a Page, regardless of layout, editable and also keep things organized on the dashboard? This is where the family hierarchy and calling Page content within other Pages come in handy.

Prerequisites – Before we begin, this tutorial assumes that:

  1. You know how to create a page on the WordPress dashboard as well as how to create and apply a page template
  2. You have access to your wordpress files via locally or FTP
  3. You already have some experience editing/creating theme files

For our example, we’re going to make an About Page with three editable blocks. One block is the main content of the Page and the other two blocks are going to be called within columns like below:

blocks

To get started, if you don’t already have a Page to experiment with, make a new Page called “About” as well as a template in your files called “about-template.php.” If you’ve already been making Page templates, the template you have should be successfully pulling the content from your About Page once it’s applied.

Now here’s where it get’s tricky – how do we get editable text for blocks 2 and 3?

First, let’s make these two new Pages that will be pulled for blocks 2 and 3. Let’s title them “About Child 1” and “About Child 2”. Inside of each Page, in it’s editable state, on the right side of the WYSIWYG editor, you should see your Page Attributes panel, the same one where you’d normally apply templates. For simplicity’s sake, we’re not going to apply a template to these two Pages; we’ll let the Parent Page do all the work. In Page Attributes, on the drop down beneath “Parent”, select “About,” which should be the Page you made earlier with the main content. Update your Pages to assign these as children to “About.”

When using hierarchy like this, naming Pages accordingly can help to keep related Pages grouped together on your dashboard for easy finding and editing. WordPress visually marks children by adding a preceding underscore before the title. One underscore means it is the direct child of its parent. Two underscores, a grand child of it’s parent and so on. Your dashboard on the All Pages panel should look something like this:

dashboard

Assuming that you’ve put some text in all three pages, if you navigate to your About Page on your site and refresh, you’ll see that you still see the content of the Parent Page, “About,” but not the children.

Before I explain one of the methods for doing so, there’s many ways to call Page content into another Page. If you’ve read “Searching the WordPress Codex Effectively,” you know using the “get” method retrieves information, but will always need “echo” tacked on and possibly array values to actually display information. Here are a few places to get started on pulling Page Content into another Page before we continue:

  1. get_page
  2. get_page_by_path
  3. get_page_children
  4. get_page_by_title

The method we’re going to use for this tutorial is the fourth one in my list, getting a page by its title. Open the about-template.php in a code editor. Outside of the loop of our main page, which should look something like this:

<?php endwhile; // end of the loop. ?>

We should begin getting our two children pages.

Since we’re using the get_page_by_title method, we’re going to need our Page titles, “About Child 1” and “About Child 2”. We’re going to add our php:

<?php 
get_page_by_title(' '); //block 1 
get_page_by_title(' '); //block 2 
?>

And inside the parenthesis in single quotes, we’re going to place the titles of our pages. These titles are case sensitive so caps and spaces matter.

<?php 
get_page_by_title('About Child 1'); //block 1
get_page_by_title('About Child 2'); //block 2 
?>

WordPress now has these Pages, but since it’s using “get,” we need to tell WordPress to show the content of these Pages. To make things neat, here would be a good place to have a variable, and since all we’re writing is PHP, we can write it all into one PHP tag.

<?php
$aboutChildOne = get_page_by_title(‘About Child 1’); //block 1
//"get" will get the information but it needs to be displayed
//get the page by its title

$aboutChildTwo = get_page_by_title(‘About Child 2’); //block 2
//"get" will get the information but it needs to be displayed
//get the page by its title
?>

Now that we have variables for each, let’s use these variables to show the content of each Page.

If you try just tacking on “echo” with the variable, you will get an error. We need to add a bit more to get this to work correctly. If you notice, we also can’t copy and paste the loop that’s calling the “About” main content because more than one loop in a Page will confuse WordPress.

So we want to “echo”, which is to display, then apply_filters, which sets this up so we can filter what information we want from each page and then follow with a set of parenthesis. Inside the parenthesis after apply_filters, we’re going to tell WordPress that we want the content of these Pages, so we write in single quotes, ‘the_content’ and then it needs to know what content it’s getting. So after ‘the_content’, we’re going to follow with a comma, use our variable that is pulling our specific Page information and tell it that we want the content of those Pages. So it would appear as:

echo apply_filters(‘the_content’, $variableHere->post_content);

All together, it should appear like so:

<?php
$aboutChildOne = get_page_by_title( 'About Child A' ); //block 1
//"get" will get the information but it needs to be displayed
//get the page by its title
echo apply_filters('the_content', $aboutChildOne->post_content);
//display the content of this page with "echo"

$aboutChildTwo = get_page_by_title( 'About Child B' ); //block 2
//"get" will get the information but it needs to be displayed
//get the page by its title
echo apply_filters('the_content', $aboutChildTwo->post_content);
//display the content of this page with "echo"
?>

And voila! Check out your About Page on your site and see if your children Page content is showing up as well. If not, then be sure to double check that variables are correct and matching, titles are correct and matching, and syntax is correct. Also make sure that your template is applied on the Parent Page and that your children Pages have “About” assigned as a parent on the dashboard. With a little html and styling, your code should look something like this:

	<div id="primary">
		<div id="content" role="main">

			<?php while ( have_posts() ) : the_post(); ?>
				<?php if ( has_post_thumbnail() ) : ?>
					<div>
						<?php the_post_thumbnail(); ?>
					</div><!-- .entry-page-image -->
				<?php endif; ?>

				<?php get_template_part( 'content', 'page' ); ?>
				<!--this is calling the loop for this About Page in another template-->

			<?php endwhile; // end of the loop. ?>

			<div>

				<?php
				$aboutChildOne = get_page_by_title( 'About Child A' ); //block 1
				//"get" will get the information but it needs to be displayed
				//get the page by its title
				echo apply_filters('the_content', $aboutChildOne->post_content);
				//display the content of this page with "echo"
				?>

			</div><!--column-01-->
			<div>

				<?php
				$aboutChildTwo = get_page_by_title( 'About Child B' ); //block 2
				//"get" will get the information but it needs to be displayed
				//get the page by its title
				echo apply_filters('the_content', $aboutChildTwo->post_content);
				//display the content of this page with "echo"
				?>

			</div><!--column-02-->

		</div><!-- #content -->
	</div><!-- #primary -->

And visually, it might look something like this (depending on the styles you apply, of course):

visual

If you have a site where Page titles may change, perhaps looking into the other methods I listed earlier in this post will send you in the right direction. There are endless possibilities to how fancy you can get with this method. It will keep your dashboard neat, make everything editable, and keep code out of the WYSIWYG editor and away from mishaps. With chaos eluded, and both you and your client satisfied, now you can enjoy all that extra time you would’ve spent breaking your head to get a good night’s sleep instead. Enjoy.

Do you have any WordPress questions or comments? We’d love to hear from you, so drop us a line below. And if you’re not already connected with us on Twitter, be sure to tweet us @Pixafy!