Steve Taylor photo

WordPress Custom Fields plugin

Well, it turns out that my release of a “reloaded” version of my hugely popular custom fields theme code was a bit premature. I quickly realized that even though (or especially because) my target audience is developers, the code should become a plugin. The field definitions should be separate, in the theme, so the core plugin code can be easily update. D’uh!

So, while I’m not officially releasing the plugin yet on the WP repository, I thought I’d kick off a public beta. Check out the SLT Custom Fields plugin. Documentation is incomplete, and bugs may exist. However, all functionality seems to be working good on test sites. Use on production servers at your own risk, but please report any problems here.

I’m hoping this will grow into a powerful and stable tool for WordPress custom theme developers.

To get you going, here’s an example for registering a box of custom fields. This code should go in your custom theme’s functions.php file.

NOTE: Please refer to the plugin’s readme.txt for the latest details on parameters and usage.

slt_cf_register_box( array(
	'type'			=> 'post',
	'id'			=> 'seo',
	'title'		=> 'Search Engine Optimization',
	'context'	=> 'normal',
	'priority'	=> 'high',
	'fields'		=> array(
			'name'			=> 'title',
			'label'			=> 'Title',
			'description'	=> 'This title will get used in the top of the browser window, as the page heading, and when the page is bookmarked.',
			'type'			=> 'text',
			'scope'			=>	array( 'post', 'page' ),
			'capabilities'	=> array( 'edit_pages' )
			'name'			=> 'description',
			'label'			=> 'Description',
			'description'	=> 'If there's a description here, it'll get used for the <code>meta</code> description, which replaces Google's automatically generated description when the page appears in search results. It should be less than 160 characters long.',
			'type'			=> 'textarea',
			'height'		=> 10,
			'scope'			=>	array( 'post', 'page' ),
			'capabilities'	=> array( 'edit_pages' ),
			'charcounter'	=> true
			'name'			=> 'keywords',
			'label'			=> 'Keywords',
			'description'	=> 'Enter comma-separated keywords that summarize the content's subject matter. Try not to exceed around 160 characters.',
			'type'			=> 'textarea',
			'scope'			=>	array( 'post', 'page' ),
			'capabilities'	=> array( 'edit_pages' ),
			'charcounter'	=> true


  1. Hi steve, I’m trying to use your plugin, but when I register a box in my functions.php, PHP raises a “Call to undefined function slt_cf_register_box()” error.
    Even if your plugin is installed and active, it seems WP doesn’t execute your plugin code.
    Here is my code:

    Trust me, I’m feeling very stupid, but I cannot see what I’m missing…

    Thanks in advance, Daniele.

  2. Hi Daniele, I suspect this is an issue with the handling of AJAX requests. I’ve been too blunt, and excluded the plugin from all AJAX requests. If you comment out line 45 of slt-custom-fields.php does this fix things? It’s fixed in the new version, coming very soon. If this isn’t to do with AJAX, please post more details.

  3. Thanks for your freaking-fast reply!
    Now the error is gone, but I can’t see any new box in the post edit page.
    I’m going to try harder this week-end…


  4. Sorry, I think I forgot to update the example code here. The current version of the plugin has a new argument for boxes to say whether they go on post edit screens or on user profiles. Try adding type => 'post' to your box code, and check the latest readme.txt.

  5. Hi Steve, here I am again with some stuff about your plugin.
    1) I’ve tryed your plugin with custom post types and scope parameter to restrict usage of new custom fields only to certain post types: great, it works perfectly!

    2) I’ve a problem with “capabilities” option (under “fields” array): if “type” (of box) is set to “post” and I don’t set “capabilities” option, I get a ” PHP Warning: Invalid argument supplied for foreach in slt-custom-fields-lib.php on line 104″. It seems that default capability for post type boxes
    array( 'edit_posts' )
    doesn’t taken into account.
    If I explicity declare 'capabilities' => array( 'edit_posts' ) in my register function, all works great.

    3) when, in “fields” array, I use 'type'=>'select' and then 'options_type'=>'posts', your plugin correctly autocreate a select box with posts filtered by “options_query”. I’ve found usefull to be able to add an empty option in the autogenerated select so the user is not forced to set the custom field to one of those values or he/she can delete that value later, selecting the empty option. So I’ve added a little of code here’n’there.

    Bye, Daniele.

  6. Hi Daniele, thanks for the feedback.

    Regarding the “capabilities” issue, I can’t replicate it. If you look at slt-custom-fields-init.php, lines 98-109, the default capabilities should be set here. I guess if something other that ‘post’ or ‘user’ was passed as the $request_type, no default would be set; but the only calls to this function (slt_cf_init_fields) use one of these values. Could you maybe do some test outputs from your set up, to see where things are going missing? Maybe see what’s in $field_defaults at line 110 and go from there?

    Regarding empty options for the posts select input, I’ll add this to the next release!

  7. Adrian Jones avatar Adrian Jones

    Hi Steve,

    Just started making use of SLT and everything is working beautifully, but I have come across one problem. It removes the default Custom Fields dialog. On its own, this is not a huge concern for my purposes but I expect for others it will be. The main problem for me is that it removes a custom “Twitter Tools” field. Is there currently a simple way to restore this functionality? I guess I could manually add that field back in?


  8. Hi Adrian, glad it’s working well for you. Regarding the default custom fields meta box, check out the usage instructions. You’ll need something like this in your theme’s functions.php:

    <?php slt_cf_setting( 'hide_default_custom_meta_box', false ); ?>

  9. Adrian Jones avatar Adrian Jones

    Sorry about that Steve – and thanks for not RTFM’ing me.

    Working beautifully now :)

  10. Steve, this plugin is brilliant! It took me all day to get this working, and credit all goes to you. I only wish I’d found it earlier.

    To make things even easier you should include that sample code (from this post) in the ReadMe file on the plugin’s page.

    Also one question: Is there any way to have page templates as a scope condition?

  11. Hey Adal, glad you like the plugin! I do need to improve the docs, yes.

    Regarding page templates as a scope condition, it’s a good idea that’s not currently implemented. Until it is, you should be able to get it going with the slt_cf_check_scope filter. HTH!

  12. Hey Steve,

    The scope check filter is great help, but there seems to be some larger obstacles to what I’m trying to accomplish.

    I tried this: unsuccessfully then did some research…

    First of all, I want to control the appearance of options on the backend so I can’t test for page templates like that anyway…

    Second, “You can only use conditional query tags on or after the init action hook in WordPress. For themes, this means the conditional tag will never work properly if you are using it in the body of functions.php, i.e. outside of a function.”

    If you have any pointers or clues, I’d be delighted, otherwise I guess I’ll just settle for Only works for this type of template remarks!

  13. Adal, yes, this plugin is pretty much a backend thing, so frontend-only tags obviously won’t work. But with all the info being passed through to the slt_cf_check_scope filter, you should easily be able to rustle up a check yourself. Maybe check the WP core for the source of is_page_template for some pointers?

  14. Hi steve, here I am again. What do you think about posting your plugin on github? It should be a good way to share patches, improvements etc ect in a organic way and could lead to a quick plugin growth and improvement.

    I think you plugin it’s a great tool for developers (of themes also) like me so I’d like to effectively contribute.

    Bye, Daniele

  15. Hope not to be a pain in the neck, but I’ve found a little bug (or strange behaviour) when creating a select element in which options have int values (not a string) as in this example:

    the option with value 0 (zero) is converted in a optgroup!
    So I’ve modified line 271 of slt-custom-fields-display.php as you can se in the link above and now it seems to work fine with both string and/or int values.


  16. Hey Steve,

    I’m still working on finding a way to use something similar to is_page_template for the back-end and conditionally display custom fields on page edit.

    Also I have encountered broken theme issues a lot using your plugin and thought you might want to point users here:
    Checking for deactivated plugins

  17. @Daniele, not a pain in the neck, a real help! :) Many thanks, I’ve incorporated a fix (using === instead of ==) in the new version. Let me know how you get on with it!

    @Adal, did you not get anything working with slt_cf_check_scope filter for checking against the page template? Could you post (in the code you’ve tried?

    Regarding your broken theme issues, of course that’s good advice – always wrap code that relies on a plugin with a check for the plugin functions you call.

  18. A new release, great! Just in time to test it on my actual WP work.

    Correct me if I’m wrong, but at a glance it seems to me it’s not yet possible to add an empty option to a non-static field, i.e. a select filled via options_query parameter (as we was talking about here).

    Oh, and I’m really interested in your idea of a “reciprocal” flag: I’ve implemented a similar behaviour some weeks ago using your plugin. In my case I was trying to link a post of a custom type to another post of another custom type.
    For example, if the post A is linked to the post B via a custom field, the post B must be “auto-linked” to post A (i.e. it must have the post A already selected in its relative custom field). Same thing when you unlink A from B or viceversa.
    I managed to get it work, by adding an action to the “save_post” hook that create/update/delete the same post_meta field on the linked post.
    I can certainly cut&paste my code on pastebin if it can be useful to you.

    Hope to hear other great news on your plugin soon!

  19. @Daniele, you’re right, I missed out that empty option feature! So, head over to the plugin download page, you’ll find 0.4.1.

    Seems to work fine. I’ve set the required flag to default to false. Currently it’s only used for the non-static select fields, and in theory defaulting to true would make the behaviour change “invisible”, i.e. if you don’t use the new setting, things will be as before. However, I’ll probably look into using this field to enforce validation on other fields in the future, and the default really should be false. If you have non-static selects that are required, remember to set this flag. Let me know if it works for you.

    Yes, a “reciprocal” flag will be great, but in planning it, it seemed quite complex. If you check the readme.txt, you’ll see my description of the functionality is a little wider than you’re thinking of. If posts can be associated with multiple users, there would be a field to select posts on user profiles, and they would be working from the same data. Selecting the users for a post would be a case of just grabbing that custom field for the post. But selecting the posts for a user would mean selecting ALL values of that custom field, then looping through them to find which ones contained the current user’s ID. As the value (multiple user IDs) will be stored as a serialized array, there’s no way of doing the selection via SQL.

    This seemed to be the way to do things, keeping the data integrity solid. But it might be better to do things as you’ve described – put the weight of processing on the updating instead of on the selection. I’ll have a look!

  20. First of all thanks for you super quicky update.
    I’m using now v 0.4.1 but I noticed some strangeness (maybe I’m misreading the documentation):

    1) suffix string it’s added after the description and not just after the field (text and select field). So if you have a text input containing a price, I expect I can put the “$” sign in the suffix parameter.

    2) the empty option for select fields is added even with ‘static’ options type (while in the readme.txt I read only relevant for non-static options)

    3) if I set a width for a text input field, even if ‘label_layout’ is setted as block, class “label-block” it’s never added to the containing div (look at line 87 in slt-custom-fields-display.php where label_layout is checked alternatively with the width parameter)

    bye (and stop working during the w-e! ;D )

Comments are closed.