Advertisement
  1. Code
  2. Plugins

Adjuntar Archivos a Tus Entradas Usando Campos Meta Personalizados en WordPress, Parte 1

Scroll to top
Read Time: 9 min

() translation by (you can also view the original English article)

Durante el curso de estos dos próximos artículos, veremos cómo podemos mejorar la API de WordPress para definir nuestros propios campos meta para adjuntar una documento (por ejemplo un PDF) a nuestras páginas en WordPress. También veremos cómo eliminar adecuadamente archivos para borrarlos de nuestras entradas.

Hace pocos meses, Christopher Davis demostró cómo crear Custom WordPress Write/Meta Boxes (https://wp.tutsplus.com/tutorials/plugins/how-to-create-custom-wordpress-writemeta-boxes/). Como hemos mencionado en este artículo, los campos personalizados son una característica increíblemente potente que nos permite añadir varias piezas de información adicional a nuestras entradas y páginas en WordPress.

Por supuesto, no estamos limitados a añadir únicamente texto, botones de radio o casillas de verificación. También podemos adjuntar imágenes y archivos a las entradas, páginas y otros tipos de entradas sacando provecho así de los campos meta personalizados; en cualquier caso, trabajar con tipos de archivos requiere un poco más de código para gestionar adecuadamente la carga y la eliminación de los archivos. 

Antes de seguir, es importante advertir que en esta serie se asume que estamos trabajando con el Tema Twentyeleven. Aunque el código funcionará con cualquier tema de WordPress, con esto nos aseguramos de que todos estamos trabajando con el mismo código y debería ser más fácil seguir el tutorial.


Definir El Campo Meta Personalizado

Primero, vamos a crear el campo personalizado de la entrada. Específicamente, el campo personalizado debería…

  • Estar disponible tanto para las páginas como para las entradas
  • Aparecer junto al editor de enradas
  • Aceptar la entrada de un archivo

Ahora, localiza el archivo functions.php en el directorio raíz del tema Twentyeleven. Haremos todos nuestros cambios al final del archivo. Vamos a empezar definiendo una función llamada add_custom_meta_boxes y ésta será registrada con el hook dd_meta_boxes.

1
2
function add_custom_meta_boxes() {
3
4
} // end add_custom_meta_boxes

5
add_action('add_meta_boxes', 'add_custom_meta_boxes');

Luego, definimos nuestro campo meta personalizado. Primero, escribiremos el código tras el cual explicaré lo que éste hace:

1
2
function add_custom_meta_boxes() {
3
4
  // Define the custom attachment for posts

5
	add_meta_box(
6
		'wp_custom_attachment',
7
		'Custom Attachment',
8
		'wp_custom_attachment',
9
		'post',
10
		'side'
11
	);
12
	
13
	// Define the custom attachment for pages

14
	add_meta_box(
15
		'wp_custom_attachment',
16
		'Custom Attachment',
17
		'wp_custom_attachment',
18
		'page',
19
		'side'
20
	);
21
22
} // end add_custom_meta_boxes

23
add_action('add_meta_boxes', 'add_custom_meta_boxes');

Observa que las dos siguientes llamadas a la función add_meta_box son idénticas.

  • El primer parámetro es el ID del campo meta. Esto se usa en el momento de guardar el valor.
  • El segundo parámetro es la etiqueta. Este valor aparece en el título situado sobre el campo meta
  • El tercer valor es la función de respuesta a la llamada usada para definir la estructura del código que aparecerá en el campo meta. Vamos a hacerlo en un momento.
  • El cuarto valor le indica a WordPress el tipo de entrada en la que debe aparecer el campo meta personalizado. Como queremos que aparezca tanto en entradas como en páginas, lo definimos dos veces.
  • El último parámetro define dónde queremos que aparezca el campo meta. Puede ser lateral, avanzado o normal. Nosotros hemos seleccionado lateral, de forma que aparecerá al lado del editor de entradas

Configurar las Respuestas

Ahora mismo, el campo personalizado no hace nada. De hecho, ni siquiera muestra nada:

Esto se debe a que no hemos definido la respuesta a la función empleada para generar el código para el campo meta. Para conseguir esto, necesitamos definir una función con el nombre que hemos indicado anteriormente. Específicamente: 'wp_custom_attachment'.

El campo de entrada debería aceptar un PDF, así que daremos una pequeña descripción y el elemento de entrada adecuado para aceptar archivos:

1
2
function wp_custom_attachment() {
3
4
	wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce');
5
	
6
	$html = '<p class="description">';
7
		$html .= 'Upload your PDF here.';
8
	$html .= '</p>';
9
	$html .= '<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" />';
10
	
11
	echo $html;
12
13
} // end wp_custom_attachment

La primera línea de código define un valor entero para validar y securizar adecuadamente nuestra carga.

Después, simplemente establecemos el código para mostrar el campo de entrada.

Ya tenemos un campo meta personalizado con un aspecto decente, aunque todavía no funciona.


Guardar El Archivo

Ahora estamos preparados para guardar el archivo. Primero, necesitamos crear una función que enganche con el hook save_post. Vamos a definirlo ya:

1
2
function save_custom_meta_data($id) {
3
4
	/* --- security verification --- */
5
	if(!wp_verify_nonce($_POST['wp_custom_attachment_nonce'], plugin_basename(__FILE__))) {
6
	  return $id;
7
	} // end if

8
	  
9
	if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
10
	  return $id;
11
	} // end if

12
	  
13
	if('page' == $_POST['post_type']) {
14
	  if(!current_user_can('edit_page', $id)) {
15
	    return $id;
16
	  } // end if

17
	} else {
18
   		if(!current_user_can('edit_page', $id)) {
19
	    	return $id;
20
	   	} // end if

21
	} // end if

22
	/* - end security verification - */
23
	
24
} // end save_custom_meta_data

25
add_action('save_post', 'save_custom_meta_data');

Aunque esta función realmente no guarda el valor, todavía no, al menos, sí que incluye un fragmento de código que asegura que estamos preparados para guardar el archivo. Específicamente, la función se asegura de que el valor entero este presente, de que no está dándose un guardado automático, y de que el usuario que está intentando guardar datos dispone de permisos para hacerlo.

Ahora ya estamos listos para empezar a validar y guardar el archivo. Cuando se trata de guardar meta datos personalizados basados en archivos, tenemos que introducir código adicional para manejar adecuadamente idiosincrasias propias de la carga de archivos. Primero, definimos el código y después lo explicaremos. La función debería parecerse a lo siguiente:

1
2
function save_custom_meta_data($id) {
3
4
	/* --- security verification --- */
5
	if(!wp_verify_nonce($_POST['wp_custom_attachment_nonce'], plugin_basename(__FILE__))) {
6
	  return $id;
7
	} // end if

8
	  
9
	if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
10
	  return $id;
11
	} // end if

12
	  
13
	if('page' == $_POST['post_type']) {
14
	  if(!current_user_can('edit_page', $id)) {
15
	    return $id;
16
	  } // end if

17
	} else {
18
   		if(!current_user_can('edit_page', $id)) {
19
	    	return $id;
20
	   	} // end if

21
	} // end if

22
	/* - end security verification - */
23
	
24
	// Make sure the file array isn't empty

25
	if(!empty($_FILES['wp_custom_attachment']['name'])) {
26
		
27
		// Setup the array of supported file types. In this case, it's just PDF.

28
		$supported_types = array('application/pdf');
29
		
30
		// Get the file type of the upload

31
		$arr_file_type = wp_check_filetype(basename($_FILES['wp_custom_attachment']['name']));
32
		$uploaded_type = $arr_file_type['type'];
33
		
34
		// Check if the type is supported. If not, throw an error.

35
		if(in_array($uploaded_type, $supported_types)) {
36
37
			// Use the WordPress API to upload the file

38
			$upload = wp_upload_bits($_FILES['wp_custom_attachment']['name'], null, file_get_contents($_FILES['wp_custom_attachment']['tmp_name']));
39
	
40
			if(isset($upload['error']) && $upload['error'] != 0) {
41
				wp_die('There was an error uploading your file. The error is: ' . $upload['error']);
42
			} else {
43
				add_post_meta($id, 'wp_custom_attachment', $upload);
44
				update_post_meta($id, 'wp_custom_attachment', $upload);		
45
			} // end if/else

46
47
		} else {
48
			wp_die("The file type that you've uploaded is not a PDF.");
49
		} // end if/else

50
		
51
	} // end if

52
	
53
} // end save_custom_meta_data

54
add_action('save_post', 'save_custom_meta_data');

El nuevo bloque de código hace varias cosas. Aunque los comentarios han sido proporcionados para proporcionar claridad, aquí tienes una explicación de lo que está sucediendo:

  • Primero, nos aseguramos de que la cadena del archivo está vacía
  • Después, configuramos la cadena para indicar los tipos de archivo admitidos y verificamos que el archivo cargado pertenece a uno de ellos
  • Luego, usamos wp_upload_bits para copiar el archivo al servidor
  • Y por último, si hubiese cualquier error, detenemos la ejecución y se los mostramos al usuario.

Una nota sobre wp_upload_bits (http://codex.wordpress.org/Function_Reference/wp_upload_bits)Esta función es una alternativa a la wp_handle_upload (http://codex.wordpress.org/Function_Reference/wp_handle_upload). Según mi experiencia, wp_handle_upload ha dado algunos problemas con ciertas configuraciones de servidor, por ejemplo en ocasiones ha dado un falso negativo. Con esto me refiero a que ha indicado que existe un problema con la carga del archivo cuando, en realidad, el archivo fue verdaderamente cargado.


Enlazar el Archivo

Ahora deberíamos estar preparados para proporcionar un enlace al archivo de nuestras entradas y páginas. En el directorio del tema Twentyeleven, localiza los dos archivos single.php y page.php. Cada archivo contiene una línea de código parecida a esta:

1
get_template_part( 'content', 'single' );

Justo bajo esta línea, necesitaremos solicitar la información del campo meta personalizado haciendo lo siguiente:

1
echo get_post_meta(get_the_ID(), 'wp_custom_attachment', true);

Específicamente, esta función está solicitando los datos meta identificados por 'wp_custom_attachment' asociados con este ID de entrada. Claro, ¿no? El último parámetro le está indicando a WordPress que queremos recuperar el resultado en forma de cadena (la alternativa es un formato de array y está fuera del ámbito de este tutorial).

El bloque de código final debería parecerse a esto:

1
get_template_part( 'content', 'single' );
1
echo get_post_meta(get_the_ID(), 'wp_custom_attachment', true);

Ahora, intenta cargar un archivo para una página o entrada. Abre la entrada o página en tu navegador. Asumiendo que todo ha ido correctamente, observarás que… ooops… realmente no tienes la ruta a un archivo.


Actualizar El Formulario de la Entrada

El problema es que, por defecto, el elemento del formulario usado para guardar toda la información de la entrada y sus datos asociados no acepta tipos de archivos. Esto puede solucionarse añadiendo una función más que se engancha en el ciclo de la página de WordPress.

1
2
function update_edit_form() {
3
    echo ' enctype="multipart/form-data"';
4
} // end update_edit_form

5
add_action('post_edit_form_tag', 'update_edit_form');

Esto unirá el atributo enctype al elemento de formulario del editor de entrada de forma que la carga de archivos no sea admitida.

Ahora, vamos a intentar subir un archivo de nuevo. Localiza tu entrada o página con el campo meta personalizado e intenta cargar un PDF. Todo funciona bien, deberías ser capaz de navegar a la entrada y/o página y ver la URL que nos dirige al archivo.


Unirlo Todo

El último paso es el más fácil. A continuación, vamos a revisar los archivos single.php y page.php y envolver la llamada a la solicitud de datos personalizados meta en un ancla que se parece a esto:

1
2
<?php get_template_part( 'content', 'single' ); ?>
3
<?php $img = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); ?>
1
2
<a href="<?php echo $img['url']; ?>">
3
	Download PDF Here
4
</a>

En este momento deberías ser capaz de adjuntar un PDF personalizado a tu página y tener un enlace al final del contenido de la página que nos proporciona un enlace de descarga. En el próximo artículo, veremos como podemos mejorar el estilo para el ancla de descarga así como eliminar el archivo de la página usando la API de WordPress.

Mientras, intenta experimentar modificando el campo meta más aún. Por ejemplo, intenta incluir una etiqueta personalizada para proporcionar contenido al enlace.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.