Ask your WordPress questions! Pay money and get answers fast! (more info)

Custom Write Panel

  • SOLVED

Hi,

I need help creating a second custom write panel. I already created one custom write panel and everything works fine. Now I need to create another write panel, and I can't figure out how to modify my code in order to do so. Here is the code for the first write panel. Any help is greatly appreciated.

<strong>*** UPDATE: I am now able to create a second write panel, but need help specifying whether it gets displayed on the "post" page or "pages" page. I need the first write panel to get displayed on "page" and the second write panel to get displayed on "post". ***</strong>


<strong>Here is the code that pulls in the value of the write panel and displays it within the custom page template:</strong>
<p><?php if(get_post_meta($post->ID, "text_value", $single = true) != "") : echo get_post_meta($post->ID, "text_value", $single = true); ?><?php endif; ?></p>


<strong>Here is the code that creates the custom write panel:</strong>

<?php
$new_meta_boxes =
array(
"image" => array(
"name" => "text",
"std" => "",
"title" => "This text will appear at the top of the page in the colored banner area.",
"description" => "Keep this text to under 35 words.")
);



function new_meta_boxes() {
global $post, $new_meta_boxes;

foreach($new_meta_boxes as $meta_box) {
$meta_box_value = get_post_meta($post->ID, $meta_box['name'].'_value', true);

if($meta_box_value == "")
$meta_box_value = $meta_box['std'];

echo'<input type="hidden" name="'.$meta_box['name'].'_noncename" id="'.$meta_box['name'].'_noncename" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';

echo'<h2>'.$meta_box['title'].'</h2>';

echo'<input type="text" name="'.$meta_box['name'].'_value" value="'.$meta_box_value.'" style="width:600px;height:200px;"/><br /><br />';

echo'<p><label for="'.$meta_box['name'].'_value">'.$meta_box['description'].'</label></p>';
}
}





function create_meta_box() {
global $theme_name;
if ( function_exists('add_meta_box') ) {
add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes', 'page', 'normal', 'high' );
}
}







function save_postdata( $post_id ) {
global $post, $new_meta_boxes;

foreach($new_meta_boxes as $meta_box) {
// Verify
if ( !wp_verify_nonce( $_POST[$meta_box['name'].'_noncename'], plugin_basename(__FILE__) )) {
return $post_id;
}

if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ))
return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;
}

$data = $_POST[$meta_box['name'].'_value'];

if(get_post_meta($post_id, $meta_box['name'].'_value') == "")
add_post_meta($post_id, $meta_box['name'].'_value', $data, true);
elseif($data != get_post_meta($post_id, $meta_box['name'].'_value', true))
update_post_meta($post_id, $meta_box['name'].'_value', $data);
elseif($data == "")
delete_post_meta($post_id, $meta_box['name'].'_value', get_post_meta($post_id, $meta_box['name'].'_value', true));
}
}



add_action('admin_menu', 'create_meta_box');
add_action('save_post', 'save_postdata');
?>

Answers (2)

2010-03-27

Buzu B answers:

you would need to use the function is_single and is_page to determin whether it is a post or a page.

Something like this:

if(is_post()){
//display second write panel
}else if(is_page()){
display first write panel
}


WP Answers comments:

Hi,

Thank you for your response. Please see the code below. Both arrays are stored within the same variable. How would I separate the arrays to put them within the if else loop you posted above?

I don't necessarily need to stick with my existing code if there is an easier way to create multiple write panels with the ability to specify whether they show on the 'post' or 'page' pages.



<strong>Here is the array</strong>

$new_meta_boxes =
array(
"image" => array(
"name" => "text",
"std" => "",
"title" => "This text will appear at the top of the page in the colored banner area.",
"description" => "<b>NOTE:</b> The ideal length for this text is 35 words."),

"image2" => array(
"name" => "portimage",
"std" => "",
"title" => "Enter the URL of the full-size image for the gallery/portfolio page.",
"description" => "<b>EXAMPLE:</b> http://www.yourdomain.com/images/coolimage.jog")
);




<strong>Here is function that creates the meta box and tells it what page type to display on</strong>

function create_meta_box() {
global $theme_name;
if ( function_exists('add_meta_box') ) {
add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes', 'page', 'normal', 'high' );
}
}




<strong>And here is all of the code put together</strong>

<?php
$new_meta_boxes =
array(
"image" => array(
"name" => "text",
"std" => "",
"title" => "This text will appear at the top of the page in the colored banner area.",
"description" => "<b>NOTE:</b> The ideal length for this text is 35 words."),

"image2" => array(
"name" => "portimage",
"std" => "",
"title" => "Enter the URL of the full-size image for the gallery/portfolio page.",
"description" => "<b>EXAMPLE:</b> http://www.yourdomain.com/images/coolimage.jog")
);



function new_meta_boxes() {
global $post, $new_meta_boxes;

foreach($new_meta_boxes as $meta_box) {
$meta_box_value = get_post_meta($post->ID, $meta_box['name'].'_value', true);

if($meta_box_value == "")
$meta_box_value = $meta_box['std'];

echo'<input type="hidden" name="'.$meta_box['name'].'_noncename" id="'.$meta_box['name'].'_noncename" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';

echo'<h2>'.$meta_box['title'].'</h2>';

echo'<input type="text" name="'.$meta_box['name'].'_value" value="'.$meta_box_value.'" style="width:600px;height:200px;"/><br /><br />';

echo'<p><label for="'.$meta_box['name'].'_value">'.$meta_box['description'].'</label></p>';
}
}





function create_meta_box() {
global $theme_name;
if ( function_exists('add_meta_box') ) {
add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes', 'page', 'normal', 'high' );
}
}





function save_postdata( $post_id ) {
global $post, $new_meta_boxes;

foreach($new_meta_boxes as $meta_box) {
// Verify
if ( !wp_verify_nonce( $_POST[$meta_box['name'].'_noncename'], plugin_basename(__FILE__) )) {
return $post_id;
}

if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ))
return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;
}

$data = $_POST[$meta_box['name'].'_value'];

if(get_post_meta($post_id, $meta_box['name'].'_value') == "")
add_post_meta($post_id, $meta_box['name'].'_value', $data, true);
elseif($data != get_post_meta($post_id, $meta_box['name'].'_value', true))
update_post_meta($post_id, $meta_box['name'].'_value', $data);
elseif($data == "")
delete_post_meta($post_id, $meta_box['name'].'_value', get_post_meta($post_id, $meta_box['name'].'_value', true));
}
}



add_action('admin_menu', 'create_meta_box');
add_action('save_post', 'save_postdata');
?>



WP Answers comments:

Also, just to be clear, the functions above are all located within the functions.php file. And when I say "posts" or "pages" page, I mean that when the user is in the admin back-end of wordpress, and they click on 'add new page', the custom write panels show up on that page. I need to separate out the write panels so that the write panel from the first array gets put on the "pages" page, and the write panel from the second array gets put on the "posts" page.

Thank you.


Buzu B comments:

Ok, first of all, forget about the conditional i posted before. I was a bit confused.

Now, lets try like this:


<?php

$new_meta_boxes =
array(

"image" => array(

"name" => "text",

"std" => "",

"title" => "This text will appear at the top of the page in the colored banner area.",

"description" => "<b>NOTE:</b> The ideal length for this text is 35 words.")
);

$new_meta_boxes_2 =
array(
"image2" => array(

"name" => "portimage",

"std" => "",

"title" => "Enter the URL of the full-size image for the gallery/portfolio page.",

"description" => "<b>EXAMPLE:</b> http://www.yourdomain.com/images/coolimage.jog")

);







function new_meta_boxes() {

global $post, $new_meta_boxes;



foreach($new_meta_boxes as $meta_box) {

$meta_box_value = get_post_meta($post->ID, $meta_box['name'].'_value', true);



if($meta_box_value == "")

$meta_box_value = $meta_box['std'];



echo'<input type="hidden" name="'.$meta_box['name'].'_noncename" id="'.$meta_box['name'].'_noncename" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';



echo'<h2>'.$meta_box['title'].'</h2>';



echo'<input type="text" name="'.$meta_box['name'].'_value" value="'.$meta_box_value.'" style="width:600px;height:200px;"/><br /><br />';



echo'<p><label for="'.$meta_box['name'].'_value">'.$meta_box['description'].'</label></p>';

}

}





function new_meta_boxes_2() {

global $post, $new_meta_boxes_2;



foreach($new_meta_boxes_2 as $meta_box) {

$meta_box_value = get_post_meta($post->ID, $meta_box['name'].'_value', true);



if($meta_box_value == "")

$meta_box_value = $meta_box['std'];



echo'<input type="hidden" name="'.$meta_box['name'].'_noncename" id="'.$meta_box['name'].'_noncename" value="'.wp_create_nonce( plugin_basename(__FILE__) ).'" />';



echo'<h2>'.$meta_box['title'].'</h2>';



echo'<input type="text" name="'.$meta_box['name'].'_value" value="'.$meta_box_value.'" style="width:600px;height:200px;"/><br /><br />';



echo'<p><label for="'.$meta_box['name'].'_value">'.$meta_box['description'].'</label></p>';

}

}





function create_meta_box() {

global $theme_name;

if ( function_exists('add_meta_box') ) {

add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes', 'page', 'normal', 'high' );
add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes_2', 'post', 'normal', 'high' );

}

}











function save_postdata( $post_id ) {

global $post, $new_meta_boxes;



foreach($new_meta_boxes as $meta_box) {

// Verify

if ( !wp_verify_nonce( $_POST[$meta_box['name'].'_noncename'], plugin_basename(__FILE__) )) {

return $post_id;

}



if ( 'page' == $_POST['post_type'] ) {

if ( !current_user_can( 'edit_page', $post_id ))

return $post_id;

} else {

if ( !current_user_can( 'edit_post', $post_id ))

return $post_id;

}



$data = $_POST[$meta_box['name'].'_value'];



if(get_post_meta($post_id, $meta_box['name'].'_value') == "")

add_post_meta($post_id, $meta_box['name'].'_value', $data, true);

elseif($data != get_post_meta($post_id, $meta_box['name'].'_value', true))

update_post_meta($post_id, $meta_box['name'].'_value', $data);

elseif($data == "")

delete_post_meta($post_id, $meta_box['name'].'_value', get_post_meta($post_id, $meta_box['name'].'_value', true));

}

}







add_action('admin_menu', 'create_meta_box');

add_action('save_post', 'save_postdata');

?>




Let me know how that works...


WP Answers comments:

Looks like your on the right track.

The write panels are now in the correct place, but when I enter something into the new write panel we added (the second array that display on the post pages) the information doesn't get saved, the field just gets cleared out when I update the post.


Buzu B comments:

I looks like you will have to also modify your save_postdata() function.


function save_postdata( $post_id ) {



global $post, $new_meta_boxes, $new_meta_boxes_2;



if('post' == $_POST['post_type']){
$new_meta_boxes = $new_meta_boxes_2;//just a little trick to use either array depending on the type of post.
}



foreach($new_meta_boxes as $meta_box) {



// Verify



if ( !wp_verify_nonce( $_POST[$meta_box['name'].'_noncename'], plugin_basename(__FILE__) )) {



return $post_id;



}







if ( 'page' == $_POST['post_type'] ) {



if ( !current_user_can( 'edit_page', $post_id ))



return $post_id;



} else {



if ( !current_user_can( 'edit_post', $post_id ))



return $post_id;



}







$data = $_POST[$meta_box['name'].'_value'];







if(get_post_meta($post_id, $meta_box['name'].'_value') == "")



add_post_meta($post_id, $meta_box['name'].'_value', $data, true);



elseif($data != get_post_meta($post_id, $meta_box['name'].'_value', true))



update_post_meta($post_id, $meta_box['name'].'_value', $data);



elseif($data == "")



delete_post_meta($post_id, $meta_box['name'].'_value', get_post_meta($post_id, $meta_box['name'].'_value', true));



}



}


I think that should do it.


WP Answers comments:

Dude, you are the man. It works like a charm.

I may need to add more write panels to this in the future. Is this possible to do, or is it a bit more tricky?Do you mind just outlining what I would need to do? From the looks of it it looks like I would need to:

- create the new variable / array at the top
- create the new function for new_meta_boxes_3()
- add the new meta box in the create_meta_box function

...the saving part is where I am a bit confused...


Thank you so much for your help. I am learning so much cool wordpress stuff from you.


Buzu B comments:

Whele if you are thinking about that, I might be better to rewrite some parts of your code. But that's just if you are planning to add a big amount of new custom write panels though.

The saving part is a bit tricky because it basically depends on what you are saving and mostly where you are saving it. For example, in our case, before we modified the saving function it was working with $new_meta_boxes which has an index of image, whereas $new_meta_boxes_2 has an index of image_2 that is why it was not saving anything. I can't really explain my self that well. However, I'm thinking a solution to this would be to just use the same format for all the arrays, for example:

$new_meta_boxes =

array(



"image" => array(



"name" => "text",



"std" => "",



"title" => "This text will appear at the top of the page in the colored banner area.",



"description" => "<b>NOTE:</b> The ideal length for this text is 35 words.")

);



$new_meta_boxes_2 =

array(

"image" => array(



"name" => "portimage",



"std" => "",



"title" => "Enter the URL of the full-size image for the gallery/portfolio page.",



"description" => "<b>EXAMPLE:</b> http://www.yourdomain.com/images/coolimage.jog")



);

Notice how I've changed imgae2 to just image in the second array. Then you can comment out this part:


if('post' == $_POST['post_type']){

$new_meta_boxes = $new_meta_boxes_2;//just a little trick to use either array depending on the type of post.

}

on the save_postdata function and see if it works. If it does, and it should, you can then just do the steps you told me on your last response and forget about the saving. I'd automatically adjust itself.

Note here that I'm blindly speaking just assuming stuff because I do not know the exact conditions in which the new custom write panel will be implemented. However, it should work just fine if they are implemented the same way we just implemented this one.


WP Answers comments:

Thanks for the tip. I tried what you said, but upon saving the post, it just reverted the value of the text field back to its old value.

Unless its a super easy fix, I think this is fine for now. I will just have to cross that bridge when I get to it.

Just let me know though. If it'd be easy to modify the code so I can add more write panels that'd be great, but if not, I'm totally ok with everything you've done and i'll award you the prize money.


Buzu B comments:

In that case I'm afraid it'll be a bit trickier. The saving trick I used is to modify the value of $new_meta_boxes according to what we need to use. For example, if the post is indeed a post and not a page, we want to use the values on $new_meta_boxes_2, so we set $new_meta_box to $new_meta_box. This way, $new_meta_box looses its old values and becomes kind of a clone of $new_meta_boxes_2 so later on when the function does this:

foreach($new_meta_boxes as $meta_box) {

it is actually working with a copy of the values stored in $new_meta_boxex_2 and not with its original values. It is kind of fooling the code, or maybe more like tricking it so we don't have to rewrite the whole function again to work with $new_meta_boxes_2. So, if you had to add a new custom write panel for links, you would first do a check to see the post type:

if('link' == $_POST['post_type']){


}

and then asign the correct value to $new_meta_boxes

if('post' == $_POST['post_type']){

$new_meta_boxes = $new_meta_boxes_3;

}

That is assuming you are adding you 3rd custom write panel.

I sound a bit complicated, but that is just because I always have a hard trying to explain this stuff. I just do it naturally and never really think much of the logic behind it, but once you understand the concept you realize that it is actually quite simple.


Buzu B comments:

I should say there are better ways to do this, but since I have really no idea of what it is you are doing or intending to do, it is difficult to suggest the best path to follow.


WP Answers comments:

Thanks for the explanation. I sort of understand it but still a confused by it.

No worries though. If it comes up in the future and I have a more concrete explanation of what I need the function to do, I'm sure you'll be able to code it up.

Thank you again for your help - I truly appreciate your time.


Buzu B comments:

No problem dude... I'm glad I could help.

2010-03-27

Magnus Kolstad answers:

What about just adding another array in $new_meta_boxes? Should work.

$new_meta_boxes = array(
"image" => array(
"name" => "text",
"std" => "",
"title" => "This text will appear at the top of the page in the colored banner area.",
"description" => "Keep this text to under 35 words."
),
"audio" => array(
"name" => "text",
"std" => "",
"title" => "This text will appear at the top of the page in the colored banner area.",
"description" => "Keep this text to under 35 words."
)
);


WP Answers comments:

Hi Magnus,

Adding another array does indeed work. Thank you for that.

The problem I am running into now is that I want the first array to appear on the "pages" screen, and the second array to appear on the "posts" screen.

Here is the function that adds the meta box and defines if it should go on "post" or "page". Do you know how to modify this function so that I can add each array separately and have one appear on "page" and one appear on "post"?


function create_meta_box() {
global $theme_name;
if ( function_exists('add_meta_box') ) {
add_meta_box( 'new-meta-boxes', 'Custom Banner Text', 'new_meta_boxes', 'page', 'normal', 'high' );
}
}