• Aucun résultat trouvé

Here's where we have to dive into some form generation functions. Each type of form element requires slightly different behavior, a fact which unfortunately makes many PHP-generated forms sloppy. Our plan is to keep things clean by creating a private static function for each input type. They are all fairly simple, so we can add them quickly, but before we do that, we are going to add our simple parsing function that we've used in the previous chapters.

Add the parse function to StandardizedCustomContent.php: /**

* parse *

* A simple parsing function for basic templating.

*

* @param $tpl string A formatting string containing [+placeholders+]

* @param $hash array An associative array containing keys and values e.g. array('key' => 'value');

* @return string Placeholders corresponding to the keys of the hash will be replaced with the values the resulting string will be returned.

*/

public static function parse($tpl, $hash) {

foreach ($hash as $key => $value) {

$tpl = str_replace('[+'.$key.'+]', $value, $tpl);

}

return $tpl;

}

Now let's add five static functions that correspond to the five different input types we will support. Notice that the checkbox and the drop-down functions are the most complex, whereas the text input function is the simplest. Can you guess why the built-in WordPress custom fields only use text inputs?

Add these one at a time, then save your work and refresh your browser to check for errors after each function! Don't go too fast!

//! Private /**

* The following '_get_xxx_element' functions each generate a single form element.

* Note: the checked value is hard-coded to 'yes' for simplicity.

*/

private static function _get_checkbox_element($data) {

$tpl ='<input type="checkbox" name="[+name+]" id="[+name+]"

value="yes" [+is_checked+] style="width: auto;"/>

<label for="[+name+]" style="display:inline;"><strong>[+tit le+]</strong></label>';

* The dropdown is special: it requires that you supply an array of options in its

* 'options' key.

* The $tpl used internally here uses a custom [+options+]

placeholder.

*/

private static function _get_dropdown_element($data) {

// Some error messaging.

if ( !isset($data['options']) || !is_array($data['options']) ) {

return '<p><strong>Custom Content Error:</strong> No options supplied for '.$data['name'].'</p>';

}

$tpl = '<label for="[+name+]"><strong>[+title+]</strong></

label><br/>

<select name="[+name+]" id="[+name+]">

[+options+]

</select>';

$option_str = '<option value="">Pick One</option>';

foreach ( $data['options'] as $option ) private static function _get_text_element($data)

{

$tpl = '<label for="[+name+]"><strong>[+title+]</strong></

label><br/>

<input type="text" name="[+name+]" id="[+name+]"

value="[+value+]" /><br/>';

return self::parse($tpl, $data);

}

private static function _get_textarea_element($data)

{

$tpl = '<label for="[+name+]"><strong>[+title+]</strong></

label><br/>

<textarea name="[+name+]" id="[+name+]" columns="30"

rows="3">[+value+]</textarea>';

return self::parse($tpl, $data);

}

private static function _get_wysiwyg_element($data)

{

$tpl = '<label for="[+name+]"><strong>[+title+]</strong></label>

<textarea name="[+name+]" id="[+name+]" columns="30"

rows="3">[+value+]</textarea>

<script type="text/javascript">

jQuery( document ).ready( function() {

jQuery( "[+name+]" ).addClass( "mceEditor" );

if ( typeof( tinyMCE ) == "object" && typeof( tinyMCE.

execCommand ) == "function" ) {

tinyMCE.execCommand( "mceAddControl", false,

Whew, that's a lot of busy work! Congratulations on working your way through it.

Next, let's add a static variable to StandardizedCustomContent.php. This is merely a preparation for printing the form elements:

/**

* This prefix helps ensure unique keys in the $_POST array by appending

* this prefix to your field names. E.g. if your prefix is 'my_' and your

* field name from the $custom_fields_for_posts array is 'field', then

* your form element gets generated something like <input name="my_

field"/>

* and when submitted, its value would exist in $_POST['my_field']

*

* This prefix is *not* used as part of the meta_key when saving the field

* names to the database. If you want your fields to be

* hidden from built-in WordPress theme functions, you can name them individually

* using an underscore "_" as the first character.

*

* If you omit a prefix entirely, your custom field names must steer clear of

* the built-in post field names (e.g. 'content').

*/

public static $prefix = 'custom_content_';

Read the comments there; it's important to understand that we're taking the trouble here to avoid collisions in the $_POST array. You shouldn't need to change this value—we set it up as a class variable because many functions will access it.

Now that you have written functions that generate each type of form input, you can update the print_custom_fields() function once more so that it references these newly created functions. Like we did in a previous chapter, we are also going to add a nonce to the end of the form to make it more secure:

public static function print_custom_fields($post, $callback_

args='') {

$content_type = $callback_args['args']; // the 7th arg from add_

meta_box()

$custom_fields = self::_get_custom_fields($content_type);

$output = '';

foreach ( $custom_fields as $field ) { $output_this_field = ''

$field['value'] = htmlspecialchars( get_post_meta( $post->ID,

$field['name'], true ) );

$output_this_field .= self::_get_dropdown_

element($field);

break;

case 'textarea':

$output_this_field .= self::_get_textarea_

element($field);

break;

case 'wysiwyg':

$output_this_field .= self::_get_wysiwyg_

element($field);

break;

case 'text':

default:

$output_this_field .= self::_get_text_element($field);

break;

}

// optionally add description if ( $field['description'] ) {

$output_this_field .= '<p>'.$field['description'].'</p>';

}

$output .= '<div class="form-field form-required">'.$output_

this_field.'</div>';

}

// Print the form

print '<div class="form-wrap">';

wp_nonce_field('update_custom_content_fields','custom_content_

fields_nonce');

print $output;

print '</div>';

}

Please save your work, and then refer back to the post you previously edited. When you edit your post, you should see an example of each type of custom field type as pictured below:

Now that we can generate each type of content, we need to handle the saving of that content.