When I first started using WordPress and wanted to do some custom things to my theme I discovered the Template Tag system in WordPress. At first I was overjoyed that they had decided to do things in a template based system, and that they also decided to do things in a pseudo-programming manner. Most other CMS systems require you to essentially alter the underlying engine of the system in order to add or replace existing functions–or at the very least write your entire code accessing the database and such as if you were directly adding to the engine. WordPress does not do this but instead gives you “hooks” which you can call that then add in your data directly to the stream of output.
I quickly found the header hook, “wp_head” and the footer hook, “wp_footer”, but was dismayed that I couldn’t find “wp_body”. This last hook I assumed would exist so that content could be added at the start of the display area of your page–but alas it didn’t and still doesn’t exist. So what could I do to add some custom content at the start of my index or other pages?
after a little investigation I discovered “loop_start”. This tag is a hook to place content at the beginning of the WordPress post display loop–the loop that displays all of your posts on your index page. It also technically is called to display even one post, so it’s called on your single.php page when you display an archive post page.
So, this should probably do the trick right? Well, yes, it sort of does. But there’s one problem: The loop can happen multiple times on a page in some themes. Yup, you can re-run the loop to do all kinds of stuff; like displaying the most recent series of posts in a sidebar, or showing posts from only a single category beneath your main posts. There are a ton of different ways theme authors have used the loop to do funky things in custom themes.
So this causes havoc then. The information you only wanted to show at the top of the page suddenly shows up all over the place on the page and looks terrible. Worse yet, each display of output calls the function individually, so it’s not easy internally to detect this and compensate, and writing database entries, temp files, or cookies or any other method like that could really slow down the site badly or mess things up.
So I sat down and thought about it and came up with a solution. I realized that the entire display of the WordPress page is itself sort of a loop. And WordPress provided 2 hooks that might come in handy: “init” which happens literally as the page is being formed and “shutdown” which is called after the page is finalized and displayed. So, what can we do with this?
Well, we can create 2 functions within our plugin that hook into these 2 hooks. The first function adds a global variable called “$displayonce” and sets it to 0 during init. In your plugin, right before your function to display your content do a conditional to check the state of this variable. If it is “0” then display your content. Right after your content is displayed make this variable “1” or anything non-zero. Our final function will be a call to the shutdown hook and set the variable $displayonce back to 0. (actually, this ending function isn’t quite necessary, but I added the function in case I decide I want to expand things and track the number of loops in the page for some reason later)
Now we have a way internal to an individual page display to have a global variable help us avoid multiple display of our content.
Bonus Material: BTW, one major issue you can hit with using this method of displaying custom content is messing up RSS feeds . Most likely you don’t want your content in your RSS feed (because if it’s not formatted right it will break the feed) — so placing a conditional on your display of content asking “!is_feed()” is a good idea. Other good conditional checks are: is_home() (checks if it’s the index page), is_single() (checks if it’s an archive page displaying a post), is_admin() (checks if you are on admin pages), is_page() (checks if the content is a page as opposed to a post), or finally using isset() on a $_GET or $_POST variable (the one the form on the page you want to avoid is using) in cases of some form submission pages where your content might conflict with the form being used (an example I ran into is the share-this plugin, which I had to use !isset($_GET[‘akst_action’]) in order to prevent content displaying on their web page based submission form).
[…] updates to the AWSOM Archive and AWSOM News Announcement plugins I decided it might be nice to discuss exactly how I place the output of these plugins on the index page. This is a bit more on the advanced side, so the tutorial is now in a new section on the tutorials […]
[…] Read More … […]
Thanks for the tips! Your article actually assisted me.