Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is there an easy to understand scheme to decide what kind of code belongs to a plugin or the theme’s functions.php?

There are many cases and many debates about that topic, mostly because there are some misconceptions about the inner workings of WordPress. I am asking for an answer based on facts, not on opinions.

It should explain how to handle these points (and probably more):

  • custom post types and taxonomies
  • contact forms
  • shortcodes
  • custom widgets
  • add_theme_support( 'automatic-feed-links' );
  • SEO functions like custom meta elements
  • theme switch

There are often pros and cons for both sides. Our most popular question Best Collection of Code for your functions.php file got a lot of code snippets as answers that are at least debatable.
We need criteria a beginner can understand, maybe a check list – with reasons.

See also the related question by Chip Bennett on our meta site: Questions specifically asking for a solution "without a plugin"

Related: Where do I put the code snippets I found here or somewhere else on the web?

share|improve this question
    
I wonder what would constitute facts for the purpose of this question. Person A says CPT go in plugin, Person B says CPT go in theme. How can we procure a fact to validate one of opinions? This might be dangerously close to "not constructive". –  Rarst Nov 18 '12 at 18:24
add comment

4 Answers

up vote 17 down vote accepted

I would start with this question: Is the functionality related to presentation of content, or with generation/management of content, or of the site, or of the user identity?

If the functionality is not related specifically to presentation of content, then it is squarely within Plugin Territory. This list is long:

  • Modifying core WP filters (wp_head content, such as canonical links, generator and other HTML meta, etc
  • Site Favicon
  • Post-content shortcodes
  • Post sharing links
  • Google Analytics (and similar) footer scripts
  • SEO tools/controls
  • etc.

If the functionality is related to presentation of content, then it is a candidate for being included in the Theme. At this point, I would revert to @Raf912's Theme-switch criterion: would you miss the functionality when you switch Themes? If the answer to that question is no, then the functionality belongs in the Theme. Some examples:

  • Removing/overriding the WP core Gallery CSS
  • Filtering post excerpt length, "read more" text, etc.
  • Anything implemented via add_theme_support() (I suppose this one should be obvious)
  • Custom CSS

Normally, these two questions will provide a fairly clear line of differentation; however, there are exceptions.

Custom Post Types

Custom Post Types, for example, are a bit of a unique hybrid of content generation and presentation, given the way the Template Hierarchy works for single-post-type archive index pages and single post pages. The content-generation aspect of CPTs would normally place them squarely in Plugin Territory; however, Plugins cannot define template pages that inherently fit into the design/layout/style for any given Theme (especially if the CPT displays other than the usual Title/Content/Meta, or has custom taxonomies associated with it).

Long-term, the solution to this disparity, IMHO, is to have a standard convention/consensus for the definition of CPTs for given types of content (real estate listings, calendar events, e-commerce products, book/media library entries, etc.). That way, user-generated content would remain portable between Themes that implement the standard/convention definition of a given CPT, while Theme developers retain the flexibility to define the design/layout/style of that CPT in the Theme template files.

Social Media Links

Similarly, I would normally say that social media profile links, ave become all but ubiquitous in current Themes, are Plugin Territory, because they have nothing to do with presentation of content. The best solution would be for these profiles to be defined somewhere in core; however, there is currently no standard/consensus means of defining these links. Are they best-defined at the site-setting level, or on a per-user basis? If per-user, which user's meta gets exposed in the template? etc.

So again, long-term, the solution to this disparity is for either core to define where these links are defined, or else for the Theme developer community to develop its own consensus. In the meantime, there's really nothing for it but to keep them defined within each Theme.

share|improve this answer
    
add_theme_support( 'automatic-feed-links' ); is not presentational. But it is required by the theme guidelines. Why is it a necessary risk to loose this functionality after a theme switch? –  toscho Nov 19 '12 at 22:01
    
Anything that is implemented via add_theme_support() can only be implemented via the Theme. Using add_theme_support( 'automatic-feed-links' ) within the Theme actually ensures a consistent experience from Theme to Theme, since the feed links generated will be the same. –  Chip Bennett Nov 19 '12 at 22:48
3  
I think it is misnamed: Feed links are not presentational. If the next theme doesn’t call that function the user will lose the feed links. And you can add that per plugin without any problem. That’s why I am confused about it. :) –  toscho Nov 19 '12 at 22:55
1  
You know: that's a good point. :) –  Chip Bennett Nov 19 '12 at 23:49
add comment

From here Themes VS Plugins

Add custom code to a child theme so when you update the parent theme, your custom code is not lost.

You can also create a site specific plugin which contains all your custom code as well.

As far as writing code versus plugins, you can use plugins to and the functions however for most of what you want, hand coding is the best as its easier to modify except in some cases like meta boxes where you may consider using a plugin unless you're a theme developer.

 function modify_contact_methods($profile_fields) {

// Add new fields
$profile_fields['twitter'] = 'Twitter Username';
$profile_fields['facebook'] = 'Facebook URL';
$profile_fields['gplus'] = 'Google+ URL';

return $profile_fields;
}
add_filter('user_contactmethods', 'modify_contact_methods');

http://codex.wordpress.org/Plugin_API/Filter_Reference/user_contactmethods

  1. Add new custom post type - Code
  2. Add new fields to the Users - Code Above
  3. Add new widgets - Code
  4. Add custom permalinks - WordPress Permalink Settings
share|improve this answer
add comment

I don't think there's an easy answer to this question, but I bet we could make a flow chart to help with the decision. Here's a rough outline of such a flow chart, which can and should be expanded. Comment with suggestions!

  • Is this code to be hosted on a single-site installation of WordPress?
    • Yes - Does the site's theme only change with major redesigns and shifts in functionality?
      • Yes - Is the code in question specific to this current design?
        • Yes: functions.php
        • No: Plugin
      • No (it changes often or at a whim) - Plugin
    • No (Multsisite) - Are you hosting the multisite installation OR is it a hosted multisite solution that allows plugins?
      • Yes: Is the functionality in question specific to this site, or can/should it be used by other sites in the network?
        • Specific to this site: functions.php
        • Shared amongst multiple sites - Do you want to force it on every site?
          • Yes: Plugin, stored in mu-plugins directory or network-activated
          • No: Is this a network of unrelated sites? (e.g. different clients)
            • Yes: Would it be bad or unprofessional if client A saw or activated the plugin you wrote for clients B, C, and D? (e.g. maybe it would break the site or cause undesirable functionality)
              • Yes: functions.php
              • No: Plugin
            • No: Probably plugin
      • No (hosted by a service like VIP that doesn't allow plugins): use functions.php
Some other thoughts that I didn't know how to fit in here:

  • Parent themes -- sometimes with shared functionality it would be better to make a parent theme and put the functionality in the parent theme's functions.php file.
  • Plugin directories of large multisite installations can quickly become unruly, so sometimes shared functionality used by a low percentage of sites (e.g. < 1%) would be best to duplicate in functions.php files.
share|improve this answer
add comment

An easy test where the code is best placed:

  • write the code into the functions.php
  • switch theme
  • do you miss the functionality, is the blog not proper working or fragments of the old theme (e.g. shortcodes) are left?

    • yes: put it into a plugin

    • no: leave it in functions.php

Examples: Write a shortcode. After switching the theme, the plain shortcodes are left in your posts. So it will be better placed in a plugin.

Write a function to list the last comments. After switching the theme, everything is ok because maybe the other theme have an equivalent function.

It really depends on the code and what it will do. Some code only influence the styling or content of the theme, some others will modifiy blog posts.

share|improve this answer
3  
+1 If the code is specific to the theme, put it is functions.php. If it needs to apply to more than one theme, put it in a plugin. –  s_ha_dum Nov 18 '12 at 15:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.