How can I add pre-defined options to the "add new" custom field dropdown?

enter image description here

Here's two examples of automatically adding and showing new custom fields:

  1. WordPress: Adding Default Custom Fields on New Posts
  2. Auto create custom field

That's close to what I want to do; my goal is to add pre-defined options to the "add new" custom filed dropdown, but not have them show as fields until the blogger adds them.

I'd like to know how to do this without using a plugin.

  • If you need specific fields filled out, why not use a custom metabox? There are a lot of options out there for doing this easily: Meta Box, WP Alchemy, Advanced Custom Fields, etc May 4, 2013 at 0:57
  • @helgatheviking Thanks for the tips! I'll check out those options (Meta Box, WP Alchemy, and Advanced Custom Fields); those look really nice! Honestly, I'm mostly curious how to do this without using a plugin as I am trying to stay minimal and avoid using a plugin for every problem that I need to solve (I know how fast plugins can build up if one (i.e., me) is not careful). :D
    – mhulse
    May 4, 2013 at 1:06
  • Sure thing. You can make metaboxes without plugins (plenty of examples on here, the Codex or just by googling). but sometimes plugins can do exactly what you need or make your life a lot simpler. May 5, 2013 at 14:01
  • @helgatheviking Thanks! Great advice! I may end up using a plugin down the road depending on how much more meta box tweaks I need to make for this project. Thanks again for the help/links/advice, I really appreciate it!
    – mhulse
    May 6, 2013 at 19:34
  • FYI, to anyone else in same boat as me: WP Alchemy looks nice purely from the standpoint that it's made for programmers; out of the three listed above, I think I like WP Alchemy the best because of that reason. The others look really cool too, but I prefer to stay as close to the code as possible. Something to note though, I'm not sure if WP Alchemy, or the others, can add default options to the stock custom field dropdown. If I end up using one, or all, I'll post back here with confirmation (or, if anyone else can confirm, that would be cool!)
    – mhulse
    May 7, 2013 at 17:26

4 Answers 4


You cannot do that with pure PHP, because the fields are fetched from existing fields, and there is no hook. But you can use JavaScript, check if the post type supports custom fields and the field does not exist already – and insert it:

<?php # -*- coding: utf-8 -*-
/* Plugin Name: Extend custom fields */

add_action( 'admin_footer-post-new.php', 'wpse_98269_script' );
add_action( 'admin_footer-post.php', 'wpse_98269_script' );

function wpse_98269_script()
    if ( ! isset ( $GLOBALS['post'] ) )

    $post_type = get_post_type( $GLOBALS['post'] );

    if ( ! post_type_supports( $post_type, 'custom-fields' ) )
    if ( jQuery( "[value='demo_data']" ).length < 1 ) // avoid duplication
        jQuery( "#metakeyselect").append( "<option value='demo_data'>demo_data</option>" );
  • Whoa, awesome! Trying now, thank you! (+1) I'll be back to mark as answer once tested. Just out of curiosity, what's the meaning behind # -*- coding: utf-8 -*-? Does that comment style mean anything special to WordPress? Thank you!!!! :)
    – mhulse
    May 4, 2013 at 0:55
  • @MickyHulse # -*- coding: utf-8 -*- is an encoding cookie, it helps editors detecting the file encoding. Vim, Scite and some other editors will read it. Part of my standard PHP template.
    – fuxia
    May 4, 2013 at 0:58
  • Works perfectly! I've updated my post with some tweaks that I made to your code (I had to create the <select> if it didn't already exist). Many thanks for the help, I really appreciate it!!!!!
    – mhulse
    May 4, 2013 at 1:44
  • ... and thanks for the info on the encoding cookie, I had not seen that before. Much appreciated.
    – mhulse
    May 4, 2013 at 1:48
function add_predefined_custom_field_names( $query ) {
    $predefined = array(

    global $table_prefix;

    $query = preg_replace('/[\r\n\t]/', ' ', $query); //minify by removing all tabs and line breaks
    $query = preg_replace('/\s+/', ' ', $query); //minify by replacing spaces, tabs and carriages to single space

    //SELECT meta_key FROM wp_postmeta GROUP BY meta_key HAVING meta_key NOT LIKE '\\_%' ORDER BY meta_key LIMIT 30
    $pattern = ("/SELECT meta_key FROM ".$table_prefix."postmeta/i");   

    if( preg_match($pattern, $query) ) {
        $keys = '';     

        foreach($predefined as $key){$keys .= (" UNION SELECT '$key' AS meta_key");}        

        $query = preg_replace('/SELECT/i', 'SELECT meta_key FROM (SELECT', $query);
        $query = preg_replace('/FROM wp_postmeta/i', ('FROM wp_postmeta'.$keys), $query);
        $query = preg_replace('/ GROUP BY/i', ')t GROUP BY', $query);

    return $query;
add_filter('query', 'add_predefined_custom_field_names');

Just add the above code anywhere in your themes function.php. After you've added the above code, it would add 'www.cyberxoft.com' to the drop down as one of the option to select.

If you get to see it, then just replace 'www.cyberxoft.com' with your required field name and refresh the admin page and when you see that happened just go ahead and add as many as you like BUT remember that only 30 could be viewed as thats the default limit set for it.



Below is a modified version of the awesome script posted by @toscho. I just needed the ability to create the <select> if it didn't already exist.

 * Programatically add custom fields.
 * @see http://wordpress.stackexchange.com/questions/98269/programatically-add-options-to-add-new-custom-field-dropdown/

function wpse_98269_script() {

    if (isset($GLOBALS['post'])) {

        $post_type = get_post_type($GLOBALS['post']);

        if (post_type_supports($post_type, 'custom-fields')) {



                    // Cache:
                    var $metakeyinput = jQuery('#metakeyinput'),
                        $metakeyselect = jQuery('#metakeyselect');

                    // Does the default input field exist and is it visible?
                    if ($metakeyinput.length && ( ! $metakeyinput.hasClass('hide-if-js'))) {

                        // Hide it:
                        $metakeyinput.addClass('hide-if-js'); // Using WP admin class.

                        // ... and create the select box:
                        $metakeyselect = jQuery('<select id="metakeyselect" name="metakeyselect">').appendTo('#newmetaleft');

                        // Add the default select value:
                        $metakeyselect.append('<option value="#NONE#">— Select —</option>');


                    // Does "demo_data" already exist?
                    if (jQuery("[value='demo_data']").length < 1) {

                        // Add option:
                        $metakeyselect.append("<option value='demo_data'>demo_data</option>");







add_action('admin_footer-post-new.php', 'wpse_98269_script');
add_action('admin_footer-post.php', 'wpse_98269_script');

I'm sure my JS adaptations could be improved, but it gets the job done. I'll post updated code back here if I make changes/improvements.

Thanks again @toscho!!!! I owe you one. :)


It works in wordpress v5.8.1

add_filter( 'postmeta_form_keys', 'filter_function_name_1552', 10, 2 );
function filter_function_name_1552( $keys, $post ){
    if($post->post_type == 'car') {
        $keys[] = 'regular_price';
    return $keys;
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Oct 31, 2021 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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