Including a Template in a WordPress Plugin (Well, a Template Part)

Late last year, I wrote a post that provided a way on how to include a page template in a WordPress plugin. There’s an accompanying project on GitHub that’s been maintained and relatively-well updated since.

Although this post is similar in nature, it doesn’t exactly deal with templates, but parts of code that may be considered partials (or template parts, in WordPress).

Let’s say that you’ve got a single post and you want to append a template to the end of the content. The content can be a little more complicated that markup because that’s easy enough to do inline, isn’t it?

So, for all intents and purposes, let’s say that we have a partial that includes a form that can be used to submit some type of information.

Including a Template in a WordPress Plugin

To make this as simple as possible, we’ll assume that the form has a single input field – a text field – in which the user can enter anything.

Whatever happens on the server doesn’t matter, but we can assume all of the necessary steps for sanitization, serialization, error checking, and all of that fun stuff is taken care of. Anyway, it’s not part of what we’re working on so it’s not what’s going to be covered.

Here’s an example of what the form may look like:

Remember that this is actually more of a template part than a full on template, so there’s a lot of standard WordPress template tags that aren’t included.

This can be kept in the plugin wherever works best for you – I opt for includes/templates/acme-my-template.php

Next, we need to define a function that will be hooked to the_content action and that will append the data to the actual content prior to displaying it.

This is where it gets a little bit interesting because it’s not a simple matter of reading the file contents and appending it to the markup (there’s filtering that doesn’t occur), and there’s also some work with the output buffering that I’ll share after the gist:

Here’s what’s happening:

  • First, the code is activating output buffering. This means that no output is going to be sent from the PHP script that’s calling this function. It’s stored in memory.
  • Next, the code grabs the content of the template part to include in the output of `the_content`.
  • It then uses `ob_get_contents` to read the content of the output buffer. Since it contains the data in the template part, it’s appending it to the `$content` variable.
  • Finally, the code empties the internal buffer by calling `ob_end_clean()`.

And that will do it. Nothing terribly complicated, right?

But What About This Buffering Business?

Here’s the thing: I’m not positive that this is the best way to do this (and I’m hoping some of you can share some insight in the comments). The thing is, I did try a few different ways each of which yielded mixed results – this one ended up being the way that produced exactly what I needed.

So this is a way to include a template in a WordPress plugin, but beware of the output buffering if you’re doing more complex operations.

This naturally raises the question: is it the best way to do this? Honestly, I’m not so sure.

I’ve yet to experience any issues with it, but I’ve also not done anymore complex operations with additional output or filtering. So if you’ve got feedback on this, I’d love to hear it in the comments.

12 Comments

The first and second examples are the same, aren’t they?

Couple of thoughts:
1. Since you’re also using ob_get_clean(), could you use $template = ob_get_clean(); instead to cobine two function calls? http://www.php.net/manual/en/function.ob-get-clean.php

What happens if you have PHP code inside your template? Does ob_*() parse it correctly? I’m thinking of use cases where do_action() or running a shortcode could come in handy.

Also, the same Gist shows up in both your examples. It looks like you intended to use https://gist.github.com/tommcfarlin/ac53e281c2a30579a1d3#file-acme-add-template-part-php in the second one.

I have used output buffering in a plugin framework I wrote and maintain. I have also suggested it as one way to implement MVC using it.

This is not something I came up with as an idea(obviously ;-) but first came across the technique in CakePHP. They do not seem to have any problems with it so I think it is a very solid technique.

I think this is the best way to handle template parts in plugins, there are other ways to do this as well like using sandwiching content between get_header and get_footer calls but they have the problem that they are not compatible with all themes out there, appending it to the_content is however surefire. I think you need some conditional tags and is_main_query() in there as well to prevent the form from appearing everywhere. :)

    Ah, perhaps lack of context made this unclear.

    The form won’t appear every where and it is appearing after $content but only on certain pages. That has more to do with the specific requirements of the plugin.

    Regardless, this isn’t bad advice! It’s just not exactly inline with what I was looking to accomplish given the current problem set I had ;).

Every time I come across this issue I have tried a different method. What I have ended up doing is just creating a function that returns the template part. This allows me to still keep the file in a separate location or even pass args like maybe some conditional CSS class, etc.

Definitely on to something! Keen to see more of this!

Leave a Reply

Name and email address are required. Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>