Trusted WordPress tutorials, when you need them most.
Beginner’s Guide to WordPress
25 Million+
Websites using our plugins
Years of WordPress experience
WordPress tutorials
by experts

WordPress Custom Post Types Debate – Functions.php or Plugins?

Editorial Note: We earn a commission from partner links on WPBeginner. Commissions do not affect our editors' opinions or evaluations. Learn more about Editorial Process.

As many of you know, this past week Syed Balkhi attended WordCamp Raleigh 2012. During the event, one of his tweets sparked quite a debate. In this article, our founder Syed Balkhi will debate whether WordPress Custom Post Types belong in functions.php file or in plugins. Below is a tweet that started this debate:

After the tweet, many reputable folks in the WordPress community chimed in. You can see the full conversation here. Curtis McHale took it one step further and elaborated on the topic in his new blog post.

The conversation from twitter brought up some great points.

Summary of Arguments

Plugins argument: The user will always have the data even if they change the theme. It might not look as pretty, but it will stay there.

Functions.php Argument: Data without design would be irrelevant. It will confuse users even more.

Which side do you agree with more? Clearly both sides have their issues, but which is the lesser of two evils?

Here is why we believe that Custom Post Types should ALWAYS live in a site-specific plugin or a separate plugin altogether.

Long Live Data

Custom Post Types are data. In most cases, your data will outlive the current design. Having changed our themes a few times, we understand that statement clearly. Posts, Pages, Links, Attachments, and Revisions are all types of post types that comes built-in with WordPress. On top of that, we have post types like Books, Testimonials, Deals, etc. Now could you imagine if we change a theme and have all these vanish? Surely, we wouldn’t want that to happen.

Having developers in our team, this shouldn’t matter much. Considering all of our themes are custom designed by our team, what difference does it really make? The secret lies in two words: time and centralization. As long as we have all the necessary data, all we would have to do in the future is change the styling. We won’t have to worry about copying and pasting the functions from one file to another every single time. What if you want to replicate the functionality? Simply take the plugin and drop it in your new site. Change the styling, and you are done.

Rules and Standards

When you use the word ALWAYS like we did in our tweet, it can mean both rule and standards. Both rules and standards are made for the majority. There will always be special case scenarios where rules are bent and standards are broken, but that doesn’t mean we should get rid of standards altogether.

There are tons of generic post types that mostly requires the same set of additional meta fields. Some examples that come to mind would be: Quotes, Books, Recipe, Testimonials, Portfolio, etc.

Considering the large number of photography and portfolio themes that are available in the free and commercial market, it makes almost no sense to make the user re-enter all of their custom post type information every time they change a theme. Let’s take a look at an example case scenario:

Photographer – User setup a WordPress which has a blog functionality (default “post” CPT). He wants to add a portfolio of his work (requires a Portfolio CPT). He wants to show client testimonials (requires a Testimonial CPT). All of this information is surely going to live past a theme design. A year later, the user wants to change the look of his site and give it a refresh. Finds a new theme that has all the similar functions. The moment he switches the theme, BOOM. All the previous data that he entered has vanished. There is a menu called Portfolio, and a menu called Testimonials however none of the data is there. User’s thinks “HOLY CRAP, I lost all my content”. Creates a new support questions in the forum. Sends emails to sites like WPBeginner etc. If they receive no good response, they will have to re-enter all the data. This is a crappy user experience.

So how do we solve this issue?

Possible Solution?

We create a new standard base. Justin Tadlock already started working on this issue a while back by creating a base portfolio plugin. Is it going to be the perfect solution for everyone? NO, but it will be for the majority.

As Justin asks in his post, what standard fields should be included in the portfolio plugin (referring to post meta). This type of conversation needs to happen among developers who are creating similar functionality in their themes. Why copy and paste the same thing over and over from one theme to another when it can be done via a plugin? Once it becomes a standard, other themes authors will begin to adapt to it.

For example, we are seeing an increase in style support for Gravity Forms in WordPress theme frameworks like Genesis and others. Why? Because they understand that their users are using it.

There are some robust WordPress themes which comes loaded with functionality which we believe should be plugins. Job Board themes, Issue Tracking themes, Classified Ads theme, Real Estate Themes, etc. They should all be powered by a base plugin. It is already happening with WooCommerce. WooThemes have released numerous themes that have built-in styling support for the plugin. Other theme companies have promised to release WooCommerce based eCommerce themes as well. You can switch from one theme to another and keep all your products as is. That’s almost like the theme changed but everything just fell right in place. That’s the theme changing experience we need to strive for.

Why not do the same thing with Portfolio, Testimonials, and other generic custom post types? Is it because it’s too simple vs. eCommerce is a bigger beast to conquer? Clearly, eCommerce has far too many fields compared to the other ones, so it should be much easier for these generic post types. It is just a matter of making a conscious effort toward making things better.

Take a look at ReciPress plugin. It creates a custom metabox with recipe fields and attaches it with posts. However it is possible to attach it with custom post types. Anyone using this plugin can change themes without having to go through such a hassle.

It would be nice to see themes like AgentPress be powered by a centralized base plugin. It would be great to see the transition of changing themes become easier. For example, if a user switch from one photography theme to another, it shouldn’t be chaos. Minor errors might happen, but at least in the bigger picture, things will work.

You can always give examples of super customized post types created for one-time client usage, but that is the exception not the rule.

What do you guys think about this topic? Where should the custom post types code reside? In the functions.php file or in plugins?

Disclosure: Our content is reader-supported. This means if you click on some of our links, then we may earn a commission. See how WPBeginner is funded, why it matters, and how you can support us. Here's our editorial process.

Editorial Staff

Editorial Staff at WPBeginner is a team of WordPress experts led by Syed Balkhi with over 16 years of experience in WordPress, Web Hosting, eCommerce, SEO, and Marketing. Started in 2009, WPBeginner is now the largest free WordPress resource site in the industry and is often referred to as the Wikipedia for WordPress.

The Ultimate WordPress Toolkit

Get FREE access to our toolkit - a collection of WordPress related products and resources that every professional should have!

Reader Interactions

34 CommentsLeave a Reply

  1. Syed Balkhi says

    Hey WPBeginner readers,
    Did you know you can win exciting prizes by commenting on WPBeginner?
    Every month, our top blog commenters will win HUGE rewards, including premium WordPress plugin licenses and cash prizes.
    You can get more details about the contest from here.
    Start sharing your thoughts below to stand a chance to win!

  2. Yazmin says

    Having been on the end of losing my CPTs numerous times as I switched themes, I find it frustrating to have to set up the same functionality over and over again in functions.php.

    I completely prefer the plugin route and that is the method I will be using from here on out for my business projects as well.

  3. Joshua Jarvis says

    Having this exact issue with a real estate theme. The “listings” were all custom types in a theme that is now functionally obsolete. When I went to upgrade the theme I lost all the custom post content, now I have to figure out a way to transfer it all. I have options, but if it were plugin, this wouldn’t be necessary.

  4. Hugh H. Sands says

    “We won’t have to worry about copying and pasting the functions from one file to another every single time.”
    I can’t imagine someone writing code for a CPT in functions.php when it’s so easy to isolate it with includes

    This debate goes most of the times around data vs design and I wonder, being quite new to WP, what about performance? Do plugins impose any overload?

  5. Kelvin Alfonso says

    I’ve always included CPT’s through a separate file into the functions.php but I think I’ll be switching over to the plugins route. Thank you!

  6. Sudhakar says

    I am a beginner and I have no expertise to comment one way or the other in favor or against of a plug-in or functions.php. But I am wondering if I want to go the functions.php route and do it under a child theme, what is the problem then? Why do I need to have it in a plug-in, wouldn’t my child theme save me from future theme upgrades and changes in the themes?

    • Editorial Staff says

      Your child theme would save you from future theme updates. However, it will NOT save you if you change your themes. Because you change the child theme if you change the active theme.


  7. Pat Ramsey says

    I’m a believer in the plugin route for custom post types & taxonomies. The author’s mention of a site-specific plugin is how I do it. I place any custom post types, custom taxonomies & metaboxes in this plugin, tailored for the site’s purpose. Eventually the site’s theme will change but the data lives on & is still easily accessible.

  8. shawn says

    If developers continue to ignore the fact that separating “data” from for “design” is necessary to create modular apps, and it does not matter where it is the data placed, reusing that data / code will always be problem.

    There seems to be a perception by some in the WP community, for one reason or the other that you can only access data in the WordPress ecosystem if it is wrapped in a plugin so we keep seeing discussions like this contributing to “The great plugin vs theme debate”.

    Focus needs to placed on evolving the WordPress’ archaic plugin system, to creating libraries based on a modular design patterns that separate code / data from design. Libraries that can be used in both themes and plugins….

    Debates like these are pointless in the WP post PHP4 era!!! (re-post)

  9. Mark Simchock says

    Re: “As Justin asks in his post, what standard fields should be included in the portfolio plugin (referring to post meta). This type of conversation needs to happen among developers who are creating similar functionality in their themes.”

    Moi? I would prefer a well documented plugin that’s engineered to be enhanced than a “closed”, one size fits all approach that difficult to work with (that code).

    My point is, perhaps it’s possible to say, “I’m not trying to be all things to all people. Here’s my basic plugin. Here’s how you trick it out. It’s designed to be tricked out.” and just leave it at that. No matter what you do it’s difficult to anticipate every use case, every use need. So why bother? Why not approach it as a framework (of sorts) and let the dev in need just customize as needed?

    • Justin Tadlock says

      That’s actually the plan. I’m building an extremely small and easily-customizable base. But, I’d like to know what, if any, fields should be standard.

  10. Affan Ruslan says

    I believe it should be on plugin.
    In case the user might not need the data in future, they can always convert the custom post type post to the “normal” post type. There’s plugin to do so, search in the repo and you’ll find at least one.

  11. Christophe Debruel says

    I don’t really care what people say. Custom post type goes into a plugin. A theme can easily be modified to fit the custom post type in the frontend. I find it more logic to style the theme for the CTP than having different themes with the same CTP code.

  12. Elliott Richmond says

    Plugin for me. At least for a non technical client, although the theme might not function correctly it will become apparent that there is a problem and that will prompt them to get a developer onboard.

  13. Kailas Mahajan says

    Its all depend on the project…
    if one handling project which needs to change theme after a certaine period of time…can use plugin..

    or if project which are sticking with the one theme.. can go with function.php

  14. Ross W says

    Everyone’s talking about how the data needs to be styled by the theme, and examples where that’s the case and where the data and theme can be separated.

    What I don’t see is anyone talking about cases where a theme depends on having some specific data available. Lets say you have a theme that has a map of countries and some country-specific data, and that, without that map and data the theme loses some of its key functionality.

    Yes, you could still do this with the data in a plugin, but is it reasonable for a theme to assume that some data exists? Is it reasonable to assume that the plugin that creates the data types is installed and enabled? (Genuine questions…discuss!)

    What if my slightly non-technical client wants to create a copy of the site with their ‘theme’. They enable the theme on a new WordPress install only to find that a whole load of stuff is missing or broken? They thought that the theme contained all that they needed for their site to look right?

    I can see uses for both approaches. For most of my client work I set up CPT’s, meta-boxes, and some functions to make accessing them simple, in library files and include them. This keeps all the ‘stuff’ that my theme needs to work in one package, but keeps it simple to move the CPT’s to a new theme should I want to.

    Of course, if a CPT looks like it could be used across multiple themes and isn’t SO specific that it only really applies to a single client’s data then you turn it into a plugin that can be deployed at will.

    I don’t think there’s a simple, one-way relationship between data and themes. It’s not always the case that ‘I have some data that needs styling’…sometimes ‘my styling needs some data’.

    Thoughts on that?

    • Andres Hermosilla says

      I definitely agree that there is a benefit to having one “complete” package. Often times there is very theme specific functionality that is better to be tied in directly (i.e. P2 from Auttomatic) vs. installed theme and theme plugin.

  15. Curtis McHale says

    Your reference to AgentPress is one of the reasons I’m 100% for CPT’s in plugins. I’ve had to deal with themes like that and it’s so hard to skin them properly unless you remove the custom function from the theme. My client and I spent 20 hours getting the code to a point we could actually work on it.

      • Birgit says

        The plugin is a “toolbox” for code snippets, that you do normally in your functions.php.
        But with a theme update, custom code in the theme’s function.php might get lost.
        So I use within my network installation this plugin, activated it network-wide and then the plugin comes with “modules”, that you can access for example by FTP.
        You can create modules as much as you like – I have one for each of my blogs within this network. In this modules (= just .php files, let’s say just like site-specific plugins) you can add all the code, that you normally put in your theme’s function.php.
        Then at the options page of the plugin you can activate in each blog, which module you would like to load and whether to load it only for frontend or only for backend or for both.
        So I only need to have 1 plugin to serve all blogs with individual code snippets, that normally go to their functions.php – and can decide, where to load these modules.
        uff, hope this is understandable, because my English is not the best ;-)

        Perhaps this will work for you to read it:

        • Editorial Staff says

          Brigit, I did translate the page as well. I understood what the plugin was intended for. However the screenshots were in German, and google is not smart enough to translate images just yet. Same issue is with the link you posted :)

  16. Sara says

    I always prefer plugins over functions.php for anything that would materially “break” on the front end or lose data if the theme were changed. This is for precisely the reasons you cite, and I also feel that it is NUTSO for those of us who are not really php programmers to try to troubleshoot conflicts when you have to be commenting out stuff in functions.php to isolate a problem.

    • Editorial Staff says

      The idea is that you should register CPT’s in a site-specific plugin. There is not a specific plugin out there yet. But this is just tossing around the idea of creating a base plugin for generic post types.


  17. Muhammad Waqas says

    I’m more convinced with the use of local functions. but in this case I think plugin can be trusted more. For example if you start using wp with a specific framework. In most of cases It possible that you’ll become a slave for a long time unless until you hire a wp professional to help you escape from that framework without losing your settings and data. On the other hand plugins can work at almost at every theme.

    When I started working with wp I preferred framework over plugin. The reality is that plugin developer consider newbie and less literate people when developing something. I personally believe that most part of wp users like manual code hacks than depending on plugins for core functions of sites. in long term plugins aren’t reliable. I fee so..

Leave A Reply

Thanks for choosing to leave a comment. Please keep in mind that all comments are moderated according to our comment policy, and your email address will NOT be published. Please Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.