How to create a custom wordpress meta box instead of using wordpress custom fields


The code for your meta box will pretty much go in one of two places: in a plugin file or in yourfunctions.php file. This tutorial will cover the latter (for those of you creating plugins, you will be able to adapt the code for your use as well). I like tutorials with code examples and lots of comments, with that said, lets dive right in:
I recommend that you download the sample files or cut + paste the code and markup below in the appropriate places as indicated. There are three sample files (you will also need to create a folder and name it custom):
/current_theme_folder/functions.php
/current_theme_folder/custom/meta.php
/current_theme_folder/custom/meta.css
/current_theme_folder/functions.php file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
define('MY_WORDPRESS_FOLDER',$_SERVER['DOCUMENT_ROOT']);
define('MY_THEME_FOLDER',str_replace("\\",'/',dirname(__FILE__)));
define('MY_THEME_PATH','/' . substr(MY_THEME_FOLDER,stripos(MY_THEME_FOLDER,'wp-content')));
add_action('admin_init','my_meta_init');
function my_meta_init()
{
    // review the function reference for parameter details
    //wp_enqueue_script('my_meta_js', MY_THEME_PATH . '/custom/meta.js', array('jquery'));
    wp_enqueue_style('my_meta_css', MY_THEME_PATH . '/custom/meta.css');
    // review the function reference for parameter details
    // add a meta box for each of the wordpress page types: posts and pages
    foreach (array('post','page') as $type)
    {
        add_meta_box('my_all_meta', 'My Custom Meta Box', 'my_meta_setup', $type, 'normal', 'high');
    }
     
    // add a callback function to save any data a user enters in
    add_action('save_post','my_meta_save');
}
function my_meta_setup()
{
    global $post;
  
    // using an underscore, prevents the meta variable
    // from showing up in the custom fields section
    $meta = get_post_meta($post->ID,'_my_meta',TRUE);
  
    // instead of writing HTML here, lets do an include
    include(MY_THEME_FOLDER . '/custom/meta.php');
  
    // create a custom nonce for submit verification later
    echo '<input type="hidden" name="my_meta_noncename" value="' . wp_create_nonce(__FILE__) . '" />';
}
  
function my_meta_save($post_id)
{
    // authentication checks
    // make sure data came from our meta box
    if (!wp_verify_nonce($_POST['my_meta_noncename'],__FILE__)) return $post_id;
    // check user permissions
    if ($_POST['post_type'] == 'page')
    {
        if (!current_user_can('edit_page', $post_id)) return $post_id;
    }
    else
    {
        if (!current_user_can('edit_post', $post_id)) return $post_id;
    }
    // authentication passed, save data
    // var types
    // single: _my_meta[var]
    // array: _my_meta[var][]
    // grouped array: _my_meta[var_group][0][var_1], _my_meta[var_group][0][var_2]
    $current_data = get_post_meta($post_id, '_my_meta', TRUE); 
  
    $new_data = $_POST['_my_meta'];
    my_meta_clean($new_data);
     
    if ($current_data)
    {
        if (is_null($new_data)) delete_post_meta($post_id,'_my_meta');
        else update_post_meta($post_id,'_my_meta',$new_data);
    }
    elseif (!is_null($new_data))
    {
        add_post_meta($post_id,'_my_meta',$new_data,TRUE);
    }
    return $post_id;
}
function my_meta_clean(&$arr)
{
    if (is_array($arr))
    {
        foreach ($arr as $i => $v)
        {
            if (is_array($arr[$i]))
            {
                my_meta_clean($arr[$i]);
                if (!count($arr[$i]))
                {
                    unset($arr[$i]);
                }
            }
            else
            {
                if (trim($arr[$i]) == '')
                {
                    unset($arr[$i]);
                }
            }
        }
        if (!count($arr))
        {
            $arr = NULL;
        }
    }
}
?>
/current_theme_folder/custom/meta.php file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="my_meta_control">
     
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras orci lorem, bibendum in pharetra ac, luctus ut mauris. Phasellus dapibus elit et justo malesuada eget <code>functions.php</code>.</p>
    <label>Name</label>
    <p>
        <input type="text" name="_my_meta[name]" value="<?php if(!empty($meta['name'])) echo $meta['name']; ?>"/>
        <span>Enter in a name</span>
    </p>
    <label>Description <span>(optional)</span></label>
    <p>
        <textarea name="_my_meta[description]" rows="3"><?php if(!empty($meta['description'])) echo $meta['description']; ?></textarea>
        <span>Enter in a description</span>
    </p>
</div>
/current_theme_folder/custom/meta.css file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.my_meta_control .description
{ display:none; }
.my_meta_control label
{ display:block; font-weight:bold; margin:6px; margin-bottom:0; margin-top:12px; }
.my_meta_control label span
{ display:inline; font-weight:normal; }
.my_meta_control span
{ color:#999; display:block; }
.my_meta_control textarea, .my_meta_control input[type='text']
{ margin-bottom:3px; width:99%; }
.my_meta_control h4
{ color:#999; font-size:1em; margin:15px 6px; text-transform:uppercase; }
If you’ve set everything up correctly you should see the following meta box in a edit post or edit page screen:
WordPress Custom Meta Box

Using The Meta Box Values In Your Template

Being able to create the values is just the first part, now you need to do something with those values. Most likely you will be displaying the values in your post or page templates.
REMEMBER the example above uses a single variable (_my_meta) to store values as an array, so when you get the meta value back from WordPress it will be an array and you will have to access the values using array syntax. Doing this is pretty straight forward:
1
2
3
$my_meta = get_post_meta($post->ID,'_my_meta',TRUE);
echo $my_meta['name'];
echo $my_meta['description'];
The global $post variable should always be available, but here are some other methods you can use to get the current post or page ID which you will need to use with get_post_meta():
1
2
3
4
5
6
7
8
9
// using $post global variable
echo $post->ID;
// get a page by its path (recommended over using a page ID)
$page = get_page_by_path('company/contact-us');
echo $page->ID;
// if you are working in the loop
echo get_the_ID();
The above code and markup will help you produce clean UI elements for your next WordPress project. Like any tutorial, consider this a starting point for you to do great things. I hope you’ve enjoyed!

Tutorial source:  http://www.farinspace.com/how-to-create-custom-wordpress-meta-box/

No comments:

Post a Comment