Introduce Us to Your Blog / Posts Page

If you’ve set up a WordPress site with a blog, or Posts Page (I’ll be calling it this throughout the post, as we’re using WordPress for so much more than just blogs now), you’ve probably noticed that anything you put in for the title and content for this page doesn’t actually show on your site. For many users, this may be no big deal, but maybe you want your Posts Page to have a title, and maybe a snappy introduction. This is not a new idea, and I’ve mentioned it in a previous blog post, but GaryJ pointed out to me that it probably merits a post of its own.

If you have set up your site to have a Static Front Page and a separate Posts Page for your blog (under Settings > Reading), you’ve encountered this already, but why? What happens is that once you’ve set a specific page to show your latest posts, or your Posts Page, according to WordPress, it actually stops being a page. This may never cause an issue for you, but if you’re using conditionals such as if ( is_singular( 'page' ) ) to target single pages, you might be frustrated that whatever action you’ve wanted to happen, is no longer happening on your Posts Page. It still shows in your list of Pages, and you can edit it, add a featured image, a title, and content, and pretty much anything else you can do to a Page, but once you’re on the front end of your site, WordPress firmly believes that it is not a page, and that it has no content of its own–its content is your latest posts.

If you are willing to invest some elbow grease and dust off your PHP skills, though, you absolutely can get your Posts Page to display its own title and content, by way of an introduction.

Find Your Posts Page

First, we know that our normal conditional tags won’t work, so how do we extract any of this information from WordPress? This Page no longer exists as a Page, remember, but we can still retrieve its information. We start with:

$posts_page = get_option( 'page_for_posts' );

This just allows us to determine whether there is, in fact, a Posts Page for the site. If one has been set, our new $posts_page variable is the ID of the Posts Page. Now, we can use WordPress’ get_post function to retrieve all kinds of information about our Posts Page. For example, to retrieve the Posts Page title:

$title = get_post( $posts_page )->post_title;

Once we have this tool in hand, we can get to work.

Create a New Posts Page

First, if your settings under Settings > Reading are set for the Front Page of your site to show the latest posts, you can stop right here, because this won’t apply to you. This works for sites with a static Front Page and a dedicated Posts Page, or blog page, or whatever you want to call it.

Putting this together is pretty simple. Because I use Genesis, my code is specific to the Genesis Framework (affiliate link), but you could easily use this with any theme if you change the hook. You’ll be creating a new file called home.php (or modifying it if your theme already has one), because that’s the template file that WordPress uses for its Posts Page. Here’s everything you want in your new file:

/**
 * Blog Intro
 *
 */

remove_action( 'genesis_before_loop', 'genesis_do_posts_page_heading' );
add_action( 'genesis_before_loop', 'rgc_blog_intro' );
function rgc_blog_intro() {

	$posts_page = get_option( 'page_for_posts' );

	if ( is_null( $posts_page ) ) {
		return;
	}

	$title   = get_post( $posts_page )->post_title;
	$content = get_post( $posts_page )->post_content;

	$title_output = $content_output = '';

	if ( $title ) {
		$title_output = sprintf( '<h1 class="archive-title">%s</h1>', $title );
	}
	if ( $content ) {
		$content_output = wpautop( $content );
	}

	if ( $title || $content ) {
		printf( '<div class="archive-description">%s</div>', $title_output . $content_output );
	}
}

genesis();Code language: PHP (php)

Fairly simple–it takes more lines to write it out than it actually does to do its work. The code first checks to see if we’re on a Posts Page, and quits if we’re not (so, if you set your Front Page to show the latest posts, this code quits). Then it checks to see if your designated Posts Page has a title (which it probably does) and content (which it may or may not). If it has either one, it wraps them up and outputs them just like a category/term/custom post type archive page. If you change your mind and set your Front Page to show the latest posts, no worries, this won’t break your site.

If you are using my Display Featured Images for Genesis plugin, you’ll want to use a modified version of this code, so that your title is not duplicated.

Changes in WordPress 4.2

WordPress 4.2 is supposed to launch quite soon, and while working through this tutorial, I discovered that because WordPress and most themes do not show the Posts Page content, 4.2 will helpfully remove the editor from the Posts Page altogether, if there is no content, since WordPress doesn’t output this content.

Goodbye, Posts Page editor!
Goodbye, Posts Page editor!

I get the reasoning behind this, but for our purposes, it’s not helpful, so I looked into how to bring back the editor (if your Posts Page has content, the editor will not disappear, so you may not encounter this unless you delete that content). It’s not all that difficult. You’ll want to add this to your theme’s functions.php file, or the appropriate place of your choosing:

add_action( 'edit_form_after_title', 'rgc_posts_page_edit_form' );
function rgc_posts_page_edit_form( $post ) {
	$posts_page = (int) get_option( 'page_for_posts' );
	if ( $posts_page === $post->ID ) {
		add_post_type_support( 'page', 'editor' );
	}
}Code language: PHP (php)

If your Posts Page has no content, you’ll still see that notice, but you can add content as you like.

So that’s it–just add this new file to your theme folder and you can be all friendly and introduce your posts.

Reader Interactions

Comments

  1. Derek says

    Thanks for the post. Most of my sites I build have a static page and a page for blog/news like you’ve mentioned above. I’m always back and forth about how to implement this and was wondering if you have any suggestions. Here’s the ways I’ve done it in the past. I don’t use Genesis by the way, not that it matters for this I suppose.

    – Set specific pages for static and blog in the reading settings like you’ve mentioned above. Let the posts page use index.php and the home use something like page-home.php. Similar to what you’ve mentioned above.

    – Set a static front page, ignore the posts page setting. Giving both their own page layout (determined by page-name.php) where the posts page gets a wp query that displays a list of posts.

    – Ignore the settings (so they stay with default) and simply using the index.php for the home layout (maybe with a wp query page name = home) and page-blog.php for my posts page layout with a wp query listing the posts.

    There may not be a right answer and like most things there may be several different ways to do the same thing, but was curious. Thanks!

    • Robin says

      You’re right, this discussion isn’t Genesis specific, so we can discuss all we want. 🙂

      If you set a static Front Page and another page as your Posts Page, all you need to do for a custom layout on either is to create a front-page.php (for the static front page) and a home.php for the Posts Page. So your first option, if you don’t create a special template to handle posts, will work just fine for the Posts Page. If you want to create a custom Front Page template, you want to name that file front-page.php, because WordPress will automatically use it, without you having to select a custom template or anything like that.

      WordPress terminology, especially conditional tags, refers to your Front Page as is_front_page() and your Posts Page as is_home(), so I would now avoid using the phrase “home page” for anything, as it gets confusing from a development standpoint. It could be the Front Page of your site, or it could not–but it is the page which will show your posts.

      Honestly, the only reason I would not use the above setup, and stick with the defaults, at least that I can think of, is if my client is truly wanting to use WordPress as a blog. It doesn’t make sense to me to leave the defaults in place and then create a custom template with a custom query to do the job of the Posts Page–it’s more efficient to let WordPress handle it. In that situation, I’ll leave the defaults in place, because my Front Page and my Posts Page are one and the same.

      • Derek says

        Thanks for the reply. I guess it’s just weird to me to create front-page.php or home.php when there’s a perfectly good index.php just sitting there doing nothing.

        I agree saying “home page” is indeed confusing when, for WordPress, home.php is referring to the posts page. I always think of home page as the first page of the site (index).

        Thanks again!

        • Robin says

          I think, however, if you put specific code like this into your index.php file, you may end up with unintended results. According to the template hierarchy in the Codex, the index.php file is what WP will use for pretty much everything (categories, single posts, front page, home page, etc.) if no other, more specific, template is available.

          So the way I read that is that it’s similar to putting all of your custom theme functionality into your functions.php file. You can certainly do it, but you’ll end up having to deal with a lot more conditionals to make sure your code runs only when you want it, and that poor file can get a bit out of control.

          If you put this code (for example) into a home.php file, however, you know that it will only be called when the specific conditions are met (is_home()). It seems to me that it’s more efficient, and safer in the end.

          • Derek says

            Yeah, I seem to always have those other files (archive, single, page, 404, search) so I guess I haven’t ran across that issue, but that’s a great point.

            What do you have in your index.php if you use the setup you described in your post? A simple loop for those just in case fallbacks?

          • Robin says

            Well, because of how the Genesis Framework is set up, I work with just child themes, which pull the Genesis index.php file, which consists of the header and genesis();. But if you look into that function, it’s pretty similar to what’s in the index.php files for the default WordPress themes, such as Twenty Fifteen and Twenty Fourteen, just with Genesis specific markup and hooks.

            Both default themes preface the index.php code with this statement: “This is the most generic template file in a WordPress theme and one of the two required files for a theme (the other being style.css). It is used to display a page when nothing more specific matches a query. e.g., it puts together the home page when no home.php file exists.” And then the code is the simple loop, as you describe.

            So the short answer is yes, the index.php file (wherever it is) would have a simple loop–but if no other files exist, this loop will play out on single posts, pages, archives, everywhere, because it is the “catch all” template file.

          • Derek says

            Thanks Robin! Always cool to see the different ways to use WordPress.

  2. Valeria says

    ‘if your Posts Page has no content, the editor will disappear’, thanks! you save a lot of time with this one.

  3. julian walker says

    Thanks for your help but when I upload my home.php file & hit the blog I get this:
    Parse error: syntax error, unexpected T_NS_SEPARATOR, expecting T_STRING in /var/sites/a/…/public_html/wp-content/themes/genesis-sample/home.php on line 9
    Any ideas?

    • Robin says

      Hmmm, I am not sure what could be going on there, Julian. Did you change the home.php file? If you can put your code in a gist, or at least line 9, that would probably help diagnose the issue.

  4. Jason says

    I just want to say TANKYOU. It was very very very helpful.

  5. Shadi says

    I would like to thank you for all details .. I have to contents in my posts pages and I put the code in the functions.php and got the editor again but the problem is I am not able to publish any post or page because the (publish button) replaced with (submit for review button) .. I stuck there .. do you have any advise to solve it ..

    • Robin says

      This code should not have made anything like that happen–very strange. It sounds like you may be logged in as a Contributor, which is a user level without actual publishing privileges–posts by Contributors must be approved by someone else. That is the situation I would expect to see that kind of button in. If you remove the code, is the button back to normal? Meaning, is it really happening as a result of this code?

  6. James Graham says

    Hi there,

    Great post and answered a lot of questions about why my blog page was only showing posts. Seems like such an odd update to delete the ability to have a title and an introduction. Anyway, bad news is that I still haven’t been able to fix it using the code you suggested above. I have the page builder editor back (using your functions.php workaround) but when I add new text boxes it still does not show on the blog page. I am using the Sydney theme (by aThemes) and I have added the code to the end of the home.php file and changed where it mentions ‘genesis’ to ‘sydney’. Is that all I need to change? Any help would be greatly appreciated…

    • Robin says

      Since this tutorial uses a Genesis-specific hook to add the posts page title and content, you’ll need to look into your theme code for a similar hook to use instead of genesis_before_loop. And check if Sydney uses a comparable function to genesis(); at the end–that’s fairly unique to Genesis, because of how the framework is set up. Hope that helps!

  7. David Alexander says

    Great post. Really needed this. One comment though, in your first function you have the genesis function running after the function, which is I think only for use in a template file but not if you are including this function within your functions.php or a custom.php file. Is that accidentally pasted there? It breaks with that but works without for me.

    Also the first function outputted sitewide for me until I changed the first conditional statement to is_home()

    Great find on bringing the editor back on the blog assigned page too! 🙂 Thanks Robin.

    • Robin says

      Yes, that first block of code is intended to be in its own file, home.php. If you do it this way, the genesis(); line must be there, and no conditional is required, because the condition is already met by the template. If you do the code in your functions.php, then yes, you would remove the Genesis call, and you would need to add in a conditional check. I prefer to do it in the template, personally, so I don’t have to mess with the conditional.

      • David Alexander says

        Okay now I see yes. That makes sense. However if that is the case, is there any need for your posts call? I suppose incorrect or older Genesis themes use the home.php for both static front page and the blog style front page (home) however shouldn’t they be using front_page.php for any static front page template? If so then you wouldn’t need the call to

        if ( is_null( $posts_page ) ) {

        I am just speculating here Bill has a great article on this topic http://www.billerickson.net/dont-use-genesis-blog-template/ I didn’t know Genesis once didn’t use this correct, I come from a Thesis background where the front_page.php has always been different from home.php the same way it should be with properly developed Genesis sites.

        Feel free to correct me if I am wrong? Maybe it depends on what child theme you are using?

        • Robin says

          I think it is possible to have a null value for the page_for_posts, i.e. if one is not set at all under Settings > Reading. (I’ve never done that myself but have had to at least test the scenario.) So if that does return null, then the rest of the function will throw errors, so yes, I’d keep it in.

          Yes, the blog template is a bit of a throwback, and causes confusion. Quite a few developers remove it from the choices altogether, but I confess that there have been times where I’ve found it to be useful. Would I use it today? Most likely not, and yes, I would refer to Bill’s excellent article as well.

          Older Genesis child themes have used home.php instead of front_page.php. I think the change is a sign of WordPress’ roots as a pure blogging platform, and its evolution to so much more. The newer themes do tend to have both, I believe.

  8. Anthony says

    Thanks Robin,

    For what it’s worth, I noticed on my sample genesis theme that shortcodes are not working inside my posts page body content field. Also as a side note: Beaver Builder editor does not work on the page – probably need to hook into it and create an exception for the posts page – in which BB automatically deactivates.

    • Robin says

      That’s a good catch on the shortcodes, Anthony. I think if you run a do_shortcode() on this output (maybe line 27), you should be able to use shortcodes here. It would be similar to what I did in the Gravity Forms shortcode post. As far as BB goes, yes, you probably need to dig into their codebase to figure out if it’s possible to enable it for the posts page, and if so, how.

  9. Anything Graphic says

    Robin,

    Thanks so much for this! I needed to display the title of the page on a recent project and this guided me in the right direction 🙂

  10. Carrie says

    THANK YOU! I looked everywhere for the answer to just showing the dang page title on my posts page and this finally worked for me. So appreciated!

  11. Alex says

    Robin, I can’t even begin to tell you how helpful this was. Thank you for explaining everything so clearly. I also found your featured image plug-in today, your blog has really been a lifesaver <3
    Does the code for adding the editor on the posts page still work for you? I'm putting it into my functions.php file and so far no-go, and I'm hoping WP hasn't changed something in the two years since this was written.
    All the best, thanks so much!

  12. Jochem says

    Hi Robin,

    Thanks for providing this smart solution! I created the home.php file and uploaded it into the root folder of my theme. When I open my blog page I now get this error message. Am I doing something wrong? Unfortunately I have very little knowledge about coding, let alone Genesis.

    Fatal error: Uncaught Error: Call to undefined function genesis() in /home/jochemva/public_html/wp-content/themes/enlightenment/home.php:35 Stack trace: #0 /home/jochemva/public_html/wp-includes/template-loader.php(74): include() #1 /home/jochemva/public_html/wp-blog-header.php(19): require_once(‘/home/jochemva/…’) #2 /home/jochemva/public_html/index.php(17): require(‘/home/jochemva/…’) #3 {main} thrown in /home/jochemva/public_html/wp-content/themes/enlightenment/home.php on line 35

    • Robin says

      The genesis function is part of the Genesis Framework–if your theme is not a Genesis child theme, you need to remove that line, and change the genesis_before_loop hook to one which is used by your theme, since that also is specific to the Genesis Framework.

  13. Kevin Lycett says

    Hi, This looks awesome but I can’t get it to work. I’m using Genesis with Dynamik. I have several pages that each show a list of posts filtered by category. (I use the blog template and filter the posts by using a custom field). I made a template file in Dynamik, called it home.php and put your code in – it had no effect. Can you suggest what I can do to get it to work?
    Thanks for taking the time to write the code and to answer everyone’s questions!

  14. Adam says

    Thanks for this very helpful post!! Is there an update yet that would be compatible with the upcoming Gutenberg launch?

    • Robin says

      That’s a great question. This code is exclusively for the tinyMCE editor. I believe that Gutenberg only is active if a post type supports the editor, which is part of what this code is forcing. So right now, this code will work with Gutenberg, in that if you try to edit the Posts Page, the Classic Editor will load, rather than Gutenberg. To enable Gutenberg support, the check for the Posts Page ID and the current page ID would have to be moved to a different hook, before Gutenberg loads, but after the post ID is available, if that hook exists (I’m honestly not sure right now).

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.