Metadatos y Custom Fields en WordPress (3/3)

Ya después de algunos meses y tras habérmelo pedido varias personas voy a terminar la serie que habla de metadatos y custom fields en WordPress. En la primera entrada hablaba de los campos personalizados por defecto de WordPress y en el segundo hablaba del plugin Types que sin duda nos facilitaba mucho el trabajo.

El objetivo de esta última entrada sobre el tema es hablar de este tema pero a través de la programación, con todas las ventajas que ello conlleva, principalmente la de no depender de un plugin de terceros y por lo tanto no cargar nuestra instalación de WordPress con más plugins.

Poniéndonos en situación

No hay mejor manera de entender las cosas que poniendo un ejemplo. En la entrada anterior sobre este tema aprendimos a crear tipos personalizados de posts, en concreto creamos un tipo llamado actividad. Siguiendo el mismo esquema actualmente estoy desarrollando un tipo de post llamado oferta en el cual poder ir introduciendo ofertas de un hotel.

Los metadatos por definición son datos que describen otros datos así que en este caso, para las ofertas he creado tres atributos:

  • Vigencia: Indica las fechas durante las cuales está vigente la oferta.
  • Título de botón: En la vista de la oferta incorporaré un botón, este campo indica el texto que aparecerá para esta oferta, me permitirá cambiar la llamada a la acción en cada una.
  • Precio: El precio de la oferta, así de simple.

NOTA: Todo el código que pongo en esta entrada se debe poner en el fichero functions.php o en su defecto en ficheros que sean importados desde este último.

Los pasos

1. Definiendo los campos de las ofertas

El primer paso es definir los campos que incluirá la oferta, para este menester he creado una función que devolverá un array con todo lo necesario para pintar los inputs. Si bien no es necesario hacerlo así de esta manera tenemos un código más limpio y estructurado.

/**
 * @return array that represents the information that has the offer
 */
function jiac_offer_metadata() {

  $metadata = array();

  $metadata[] = array(
    'name' => 'offer_period',
    'id' => 'offer_period',
    'label' => __('Offer date period', 'jiac'),
    'desc' => __('Indicates the period when the offer is active', 'jiac'),
    'type' => 'text'
  );

  $metadata[] = array(
    'name' => 'offer_button',
    'id' => 'offer_button',
    'label' => __('Offer button text', 'jiac'),
    'desc' => __('Indicates text that will be in the CTA', 'jiac'),
    'type' => 'text'
  );

  $metadata[] = array(
    'name' => 'offer_price',
    'id' => 'offer_price',
    'label' => __('Value', 'jiac'),
    'desc' => __('Indicates the offer value', 'jiac'),
    'type' => 'text'
  );

  return $metadata;
}

2. Indicando como pintar los inputs

En este caso de ejemplo estamos trabajando con tipos de input text, de hecho si veis el código anterior en el array asociativo de cada celda he introducido el type para que dinámicamente se vaya escupiendo el código HTML apropiado dependiendo de este campo.

function jiac_input_text($name, $value, $args) {
    $output = null;
    $width = (isset($args['width']))? "style='width: ".$args['width']."'" : null;
    $placeholder = (isset($args['placeholder']))? "placeholder='".$args['placeholder']."'" : null;
    $output .= "<input type='text' name='$name' value='$value' $width $placeholder/>";
    return $output;
  }

3. Añadiendo el metabox al tipo de post

Los campos deben estar en un contenedor, a este contenedor se le llama metabox dentro de la cual se muestran los campos, os recomiendo un paso por el CODEX de WordPress para ver como se registran, aunque en el ejemplo queda claro.

add_action( 'add_meta_boxes', 'jiac_add_metaboxes');

/**
 * Add metaboxes for custom posts
 */
function jiac_add_metaboxes() {

  // Metabox for each custom post
  add_meta_box('jiac_offers_metabox', __('Offer data','jiac'), 'jiac_offer_metabox', 'oferta', 'normal', 'high');
}


/**
 * @param $post Post object
 */
function jiac_offer_metabox( $post ) {
  jiac_print_metabox( $post, jiac_offer_metadata());
}

El tercer parámetro de la función add_meta_box es la función de callback que tiene como parámetro por defecto el objeto post, en este caso he creado una función que pasado el objeto y el array de campos devuelto por la función jiac_offer_metadata().

3. Pintando el metabox

Esta función es la encargada de pintar el formulario con los datos del post (en este caso custom post) en concreto.

/**
 * @param $post is the post object
 * @param $metadata is the fields array that returns a function
 */
function jiac_print_metabox( $post, $metadata ) {

  // Nonce field dor save custom post
  wp_nonce_field('jiac_save_custom_post', 'jiac_save_custom_post');


  // Foreach field we are going to print it
  foreach ( $metadata as $field )  {

    $field_name = $field['name'];
    $field_title = $field['label'];
    $field_type = $field['type'];
    $field_value = (get_post_meta($post->ID, $field_name, true) != null)? get_post_meta($post->ID, $field_name, true) : '';

    // Prints the label
    echo "<label form='$field_name'>$field_title</label>";

    // Depends on the input type
    if ($field_type == 'text') {
      echo jiac_input_texto($field_name, $field_value, null);
    }

    /*if ($field_type == 'checkbox') {
      echo jiac_input_checkbox($field_name, $field_value);
    }*/
  }
}

Con todos estos pasos tenemos el siguiente resultado:

oferta

NOTA: Los campos de texto y su visualización se puede modificar añadiendo CSS.

Cuando rellenamos los datos y guardamos se envían por POST muchos datos entre los que están los introducidos en estos campos input, os lo enseño con la herramienta para desarrolladores de Chrome.

_wpnonce:c41b91fc63
_wp_http_referer:/wp-admin/post-new.php?post_type=oferta
user_ID:2
action:editpost
originalaction:editpost
post_author:2
post_type:oferta
original_post_status:auto-draft
referredby:http://artiemmadrid.dev/wp-admin/
_wp_original_http_referer:http://artiemmadrid.dev/wp-admin/
auto_draft:1
post_ID:24
meta-box-order-nonce:15041b43c4
closedpostboxesnonce:2f176bcbcc
post_title:
samplepermalinknonce:a6177f84e9
content:
wp-preview:
hidden_post_status:draft
post_status:draft
hidden_post_password:
hidden_post_visibility:public
visibility:public
post_password:
mm:09
jj:30
aa:2015
hh:19
mn:31
ss:41
hidden_mm:09
cur_mm:09
hidden_jj:30
cur_jj:30
hidden_aa:2015
cur_aa:2015
hidden_hh:19
cur_hh:19
hidden_mn:31
cur_mn:31
original_publish:Publicar
publish:Publicar
menu_order:0
jiac_save_custom_post:bc9ec99056
_wp_http_referer:/wp-admin/post-new.php?post_type=oferta
offer_period:fsdf
offer_button:fsdfsdf
offer_price:fsdfsdf
excerpt:
trackback_url:
advanced_view:1
comment_status:open
ping_status:open
post_name:
post_author_override:2

Sabiendo que estos parámetros se pasan por POST incluido el campo post_type y post_ID podemos crear una función asociada a la acción edit_post que dependiendo del tipo de post que sea guarde unos campos u otros.

/**
 * @param $post object
 */
function jiac_save_metabox( $post ) {

  $post_type = get_post_type($post); // Getting the post type
  $metadata = null;

  switch ($post_type) { // We have different post types with different custom data, we can also retrieve it from POST

    case 'oferta':
      $metadata = jiac_offer_metadata();
      break;

  }

  jiac_save_custom_meta($metadata); // Passing the custom data form saving it
}

/**
 * @param $metadata that contains all custom data fields for the post
 */
function jiac_save_custom_meta( $metadata ) {

  if (!isset($_POST['post_ID'])) return; // If no post is set then return (exit)

  if (!wp_verify_nonce($_POST['jiac_save_custom_post'], 'jiac_save_custom_post')) return; // If cant verify nonce field then exit

  $post_id = $_POST['post_ID']; // Getting the post id

  // Foreach field in custom data
  foreach ($metadata as $field) {

    $field_name = $field['name']; // Get the field name

    if(isset($_POST[$field_name])){ // Only if isset the post parameter

      $field_value = '';
      $field_value = trim($_POST[$field_name]);

      $current_value = '';
      $current_value = get_post_meta($post_id, $field_name, true);

      // Add metadata
      if(get_post_meta($post_id, $field_name) == ""){
        add_post_meta($post_id, $field_name, $field_value, true);
      }
      // Update metadata
      elseif($field_value != get_post_meta($post_id, $field_name, true)){
        update_post_meta($post_id, $field_name, $field_value);
      }
      // Delete unused metadata
      elseif($field_value == ""){
        delete_post_meta($post_id, $field_name, get_post_meta($post_id, $field_name, true));
      }
    } else { // If not then we delete for checkboxes
      //if ($field['type'] == 'checkbox') update_post_meta($post_id, $field_name, 0);
    }
  }
}

Con un código bien estructurado podemos hacer casi cualquier cosa con WordPress y añadir cualquier metadato  nuestros posts, sea del campo que sea pudiendo generar metaboxes con un sin fin de campos, por ejemplo, color de fondo, fuente, color de texto, inclusión de slider, etc, etc.

Espero que os haya resultado de interés y recordad que para aprender lo mejor es fijarse en otros temas, mirar el código y aprender de los demás.

Quedo a vuestra disposición en los comentarios 🙂

(Visited 461 times, 1 visits today)

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Ir arriba

Si continuas utilizando este sitio, aceptas el uso de las cookies. Más información

Las opciones de cookie en este sitio web están configuradas para "permitir cookies" para ofrecerte una mejor experiéncia de navegación. Si sigues utilizando este sitio web sin cambiar tus opciones o haces clic en "Aceptar" estarás consintiendo las cookies de este sitio.

Cerrar