{"id":5513,"date":"2011-01-28T07:13:46","date_gmt":"2011-01-28T12:13:46","guid":{"rendered":"http:\/\/www.allyngibson.net\/?p=5513"},"modified":"2011-01-28T07:13:46","modified_gmt":"2011-01-28T12:13:46","slug":"on-turning-wordpress-posts-into-pages","status":"publish","type":"post","link":"http:\/\/www.allyngibson.com\/?p=5513","title":{"rendered":"On Turning WordPress Posts Into Pages"},"content":{"rendered":"<p>I&#8217;ve been using WordPress for over six years.  When I began using WordPress, with version 1.2, it was a blogging platform and nothing more.  With version 1.5 WordPress added a new wrinkle; it could still be used for blogging and creating blog posts, but it could also be used as a CMS-lite, with static pages that didn&#8217;t belong to the blog heirarchy.  Blog posts were for a daily (or, at least, semi-frequent) updating schedule and they were accessed and read in a chronological fashion, whereas pages were more organized, they could be arranged by subpages and sub-subpages, and they could be read outside of a blog chronology.<\/p>\n<p>Pages and Posts were separate things; they went in the same database, they were handled in the same basic way, but there was a wall, albeit an imaginary one, in between them and it could never be bridged.  If you wrote it as a Post, it stayed as a Post &mdash; unless you went and hacked the SQL database to change it to a Page, but that&#8217;s for people who like to live on the edge.<\/p>\n<p>But sometimes, one might write a blog post &mdash; as an example, a book review &mdash; and because it&#8217;s evergreen information that isn&#8217;t really tied to a chronological ordering, it should be organized as a subpage to a book review index.  But there&#8217;s no easy way to do that, to place that blog post as a subpage, is there?<\/p>\n<p>Oh, there are workarounds.  One could, on that book review index page, place a link directly to the blog post.  But more and more WordPress designs today are making use of dropdown and hover menus, so wouldn&#8217;t it be more convenient to have this as a page?  An option might be to simply create a page with the book review, but then the advantages to making the review a blog post &mdash; pinging update services, letting regular readers see the post in their RSS readers &mdash; are lost.  Or, after making the blog post, the post&#8217;s content could be copied to a separate page.  And while the SQL editing technique I mention above is a viable tactic once the review post drops off the front page is an option, a person has to be comfortable with editing a database.<\/p>\n<p>An idea occured to me.<\/p>\n<p>Custom page templates.<\/p>\n<p>WordPress allows a website owner to create a <a href=\"http:\/\/codex.wordpress.org\/Pages#Page_Templates\">custom page template<\/a> that is used instead of the standard page.php when the page is called.  Replacing the loop in the custom page.php with <a href=\"http:\/\/weblogtoolscollection.com\/archives\/2008\/04\/13\/define-your-own-wordpress-loop-using-wp_query\/\">a custom loop that calls a specific post<\/a> <i>would<\/i> be a wordaround for the problem of displaying a post&#8217;s content in the page heirarchy.  One would simply create a custom page template that calls the specific post, then create a page and use that custom page template as its base.  It wouldn&#8217;t matter what was entered as the page&#8217;s content, indeed there&#8217;s not <i>point<\/i> to adding any text to the page except for the title; the custom loop would call instead the content of the blog post.<\/p>\n<p>This solution is fine, <i>if<\/i> you only need a few blog posts turned into pages.  But what if you need five, ten, twenty?  You would have to create a custom page template for <i>each<\/i> blog post, because each custom page template would be hardcoded to call a single blog post.<\/p>\n<p>What if there were a way to automate the system?  WordPress allows both posts and pages to have something called &#8220;Custom Fields.&#8221;  This is basically some additional data that can be used by a theme or a plugin to achieve a certain effect with a post, like a post thumbnail or a mood icon.  What if a Custom Field were used to contain the Post ID (a WordPress reference number to the post&#8217;s record in the SQL database), and then the custom loop in the custom page template would pull that information from the page&#8217;s database record to populate the custom query that calls the WordPress post?<\/p>\n<p>I thought that was a clever solution.  I had to give it a try.<\/p>\n<p>Here&#8217;s the code I came up with for my WordPress theme:<\/p>\n<p><code>&lt;?php<br \/>\n\/*<br \/>\nTemplate Name: Custom -- Post to Page<br \/>\n*\/<\/p>\n<p>get_header(); ?&gt;<\/p>\n<p>&lt;div id=\"content\"&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id=\"contentleft\"&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=\"postarea\"&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php include(TEMPLATEPATH.\"\/breadcrumb.php\");?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php $postpage = get_post_meta($post-&gt;ID, \"post-page\", $single = true); ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=\"aheadline\"&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h1&gt;&lt;?php the_title(); ?&gt;&lt;\/h1&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=\"clear\"&gt;&lt;\/div&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php endwhile; else: ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;p&gt;&lt;?php _e('Sorry, no posts matched your criteria.', 'studiopress'); ?&gt;&lt;\/p&gt;&lt;?php endif; ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$recentPosts = new WP_Query();<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$recentPosts-&gt;query('p='.$postpage);<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php while ($recentPosts-&gt;have_posts()) : $recentPosts-&gt;the_post(); ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php the_content(__('Read more', 'studiopress'));?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php endwhile; ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php comments_template('',true); ?&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/div&gt;<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?php include(TEMPLATEPATH.\"\/sidebar.php\");?&gt;<\/p>\n<p>&lt;\/div&gt;<\/p>\n<p>&lt;?php \/\/ The main column ends  ?&gt;<\/p>\n<p>&lt;?php get_footer(); ?&gt;<\/code><\/p>\n<p>I created a Custom Field called &#8220;post-page.&#8221;  The custom page template runs the standard WordPress loop, with one exception &mdash; in the loop it looks to see what the value of &#8220;post-page&#8221; is and assigns that value to a variable.  The standard WordPress loop is closed, then a custom loop is called.  The custom loop uses the variable to call the post from the blog heirarchy.  Thus, a single custom page template can be used to place any chronological blog post into WordPress&#8217; page heirarchy.<\/p>\n<p>To create your own custom Page-to-Post template, try this:<\/p>\n<p>1) Make a copy of the page.php file in your theme folder and call it something like custom-page.php<\/p>\n<p>2) Replace the opening &#8220;&lt;?php get_header(); &gt;&#8221; tag in custom-page.php with the first five lines of the code I posted above.<\/p>\n<p>3) Find the start of the WordPress loop:<br \/>\n<code>&lt;?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;<\/code><\/p>\n<p>4) Follow that line with this:<br \/>\n<code>&lt;?php $postpage = get_post_meta($post-&gt;ID, \"post-page\", $single = true); ?&gt;<\/code><\/p>\n<p>5) Make sure the WordPress loop is closed before the &lt;?php the_content();?&gt;<\/p>\n<p>6) Replace &lt;?php the_content();?&gt; with this:<br \/>\n<code>&lt;?php<br \/>\n$recentPosts = new WP_Query();<br \/>\n$recentPosts-&gt;query('p='.$postpage);<br \/>\n?&gt;<\/p>\n<p>&lt;?php while ($recentPosts-&gt;have_posts()) : $recentPosts-&gt;the_post(); ?&gt;<\/p>\n<p>&lt;?php the_content();?&gt;<\/code><\/p>\n<p>That should cover it.<\/p>\n<p>One interesting side effect of this method is that the custom page template, if it calls comments, will pull the comments from the original blog post.<\/p>\n<p>With this method, someone can create blog posts, and then utilize them within WordPress&#8217; CMS-like page heirarchy.<\/p>\n<p>To my surprise, my code worked properly for me the first time. \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve been using WordPress for over six years. When I began using WordPress, with version 1.2, it was a blogging platform and nothing more. With version 1.5 WordPress added a new wrinkle; it could still be used for blogging and creating blog posts, but it could also be used as a CMS-lite, with static pages<a class=\"more-link\" href=\"http:\/\/www.allyngibson.com\/?p=5513\">Continue reading <span class=\"screen-reader-text\">&#8220;On Turning WordPress Posts Into Pages&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4095],"tags":[227,58,4096],"class_list":["post-5513","post","type-post","status-publish","format-standard","hentry","category-wordpress","tag-coding","tag-php","tag-wordpress","entry"],"_links":{"self":[{"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=\/wp\/v2\/posts\/5513","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=5513"}],"version-history":[{"count":0,"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=\/wp\/v2\/posts\/5513\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5513"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.allyngibson.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}