Siempre estamos con la discusión de cuál es el mejor plugin de SEO, que si el de Yoast porque tiene más cosas, que si el All in one SEO pack porque no falla nunca, que si Fernando está loco, que si meto las tags manualmente, etc. Pero ¿y si creas el tuyo propio?
Así que basta de debates estériles y discusiones inútiles de a ver quién la tiene más larga y manos a la obra a crear un plugin SEO básico que añada las descripciones meta y un título para Open Graph con su descripción a la cabecera de las publicaciones de WordPress.
De paso aprenderemos cómo crear cajas meta a medida, cómo sanear los datos facilitados por el usuario, cómo guardar los datos en una entrada o página y cómo recuperar los datos guardados, ahí es nada.
Índice de contenidos
:: Creando la caja meta ::
Lo primero es decidir donde debe aparecer la caja meta.
En nuestro plugin la caja meta se añadirá en la pantalla de edición de entradas y páginas. Para hacer esto se crea una función que contenga una variable que almacene un array
que indique donde mostrar la caja meta y luego un loop foreach
que devuelva el array
y añada la caja meta a la pantalla elegida usando la función add_meta_box
.
Finalmente se conecta la función con la acción add_meta_boxes
.
function tes_mb_create() { /** * @array $screens Pantalla en la que se mostrará la caja meta * @values post, page, dashboard, link, attachment, custom_post_type */ $screens = array( 'post', 'page' ); foreach ( $screens as $screen ) { add_meta_box( 'tes-meta', 'Ajustes SEO ayudaWP', 'tes_mb_function', $screen, 'normal', 'high' ); } } add_action( 'add_meta_boxes', 'tes_mb_create' );
Si lo prefieres, también podrías añadir una función add_meta_box
doble para incluir la caja meta tanto en la pantalla de edición de entradas como en la de páginas, algo así:
function tes_mb_create() { add_meta_box( 'tes-meta', 'Ajustes SEO ayudaWP', 'tes_mb_function', 'post', 'normal', 'high' ); add_meta_box( 'tes-meta', 'Ajustes SEO ayudaWP', 'tes_mb_function', 'page', 'normal', 'high' ); } add_action('add_meta_boxes', 'tes_mb_create');
:: Código de las cajas meta ::
En el código anterior, la función callback
que imprime el HTML en la pantalla del editor es la denominada tes_mb_function
, que es el tercer argumento de la función add_meta_box
.
En nuestro plugin solo estamos programando dos campos de formulario HTML con los que gestionar los datos de title
y description
.
function tes_mb_function($post) { //si existen se recuperan los valores de los metadatos $tes_meta_title = get_post_meta( $post->ID, '_tes_meta_title', true ); $tes_meta_description = get_post_meta( $post->ID, '_tes_meta_description', true ); // Se añade un campo nonce para probarlo más adelante cuando validemos wp_nonce_field( 'tes_inner_custom_box', 'tes_inner_custom_box_nonce' ); echo '<div style="margin: 10px 100px; text-align: center"> <table> <tr> <td><strong>Etiqueta "title":</strong></td><td> <input style="padding: 6px 4px; width: 300px" type="text" name="tes_meta_title" value="' . esc_attr($tes_meta_title) . '" /> </td> </tr> <tr> <td><strong>Meta "description":</strong></td><td> <textarea rows="3" cols="50" name="tes_meta_description">' . esc_attr($tes_meta_description) . '</textarea></td> </tr> </table> </div>'; }
La explicación del código tes_mb_function
anterior es la siguiente:
- Recupera y almacena los valores de meta datos en una variable solo si esta existe. Se hace así para completar los campos con sus valores cuando estén presentes en la base de datos.
- Se añade un
nonce
para que podamos probarlo más tarde, durante la verificación que ocurre antes de que los datos insertados en los campos de formulario se guarden en la base de datos. - El formulario HTML consistente de un campo de texto de introducción de datos y un área de texto donde capturar el título etiqueta description hace echo y se imprime.
Con solo esto ya deberías poder ver la caja meta en la pantalla de edición de entradas y páginas.
:: Guardando los datos de la caja meta ::
Una caja meta no estará completa hasta que pueda guardar los datos en la base de datos. El nombre de la función que gestiona el guardado de datos será tes_mb_save_data
. El código sería este:
function tes_mb_save_data($post_id) { /* * Tenemos que verificar que esto proviene de nuestra pantalla y con la autorización adecuada, * para poder lanzar save_post en cualquier otro momento. */ // Comprobamos si se ha definido el nonce. if ( ! isset( $_POST['tes_inner_custom_box_nonce'] ) ) return $post_id; $nonce = $_POST['tes_inner_custom_box_nonce']; // Verificamos que el nonce es válido. if ( ! wp_verify_nonce( $nonce, 'tes_inner_custom_box' ) ) return $post_id; // Si es un autoguardado nuestro formulario no se enviará, ya que aún no queremos hacer nada. if ( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; // Comprobamos los permisos de usuario. 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; } /* Vale, ya es seguro que guardemos los datos. */ // Si existen entradas antiguas las recuperamos $old_title = get_post_meta( $post_id, '_tes_meta_title', true ); $old_description = get_post_meta( $post_id, '_tes_meta_description', true ); // Saneamos lo introducido por el usuario. $title = sanitize_text_field( $_POST['tes_meta_title'] ); $description = sanitize_text_field( $_POST['tes_meta_description'] ); // Actualizamos el campo meta en la base de datos. update_post_meta( $post_id, '_tes_meta_title', $title, $old_title ); update_post_meta( $post_id, '_tes_meta_description', $description, $old_description ); } add_action( 'save_post', 'tes_mb_save_data' );
La explicación del código anterior es la siguiente:
- Primero verificamos que proviene de nuestra pantalla y con la autorización adecuada, para poder lanzar en cualquier otro momento
save_post
y también verificamos que sea válido el nonce definido anteriormente entes_mb_function
. - A continuación, si ya existe una entrada en la base de datos la recuperamos y la guardamos en las variables
$old_title
y$old_description
. Hacemos esto debido a que la funciónupdate_post_meta
que se ocupa de guardar los datos en la base de datos en ocasiones requiere comprobar un valor anterior antes de actualizar la fila de la caja meta en la base de datos con los nuevos valores. - Después de esto saneamos los datos enviados usando la función de WordPress
sanitize_text_field
, que convierte HTML a su entidad, recorta todas las tags, borra saltos de línea, tabulados y espacios en blanco extras y recorta octetos. - Los datos meta se actualizan en la base de datos mediante
update_post_meta
. - Finalmente se conecta
tes_mb_save_data
con la acciónsave_post
para guardar los datos de la caja meta cuando se actualice la entrada o página.
:: Utilizando los datos guardados ::
No olvides que los datos guardados se usarán para añadir el título y descripción de Open Graph y también para añadir la meta «description» a la cabecera de cada página.
Para lograrlo creamos la función denominada tes_mb_display
, que contendrá las tags que queremos, para luego conectar con la acción wp_head
.
function tes_mb_display() { global $post; // recuperamos los valores de los metadatos si existen $tes_meta_title = get_post_meta( $post->ID, '_tes_meta_title', true ); $tes_meta_description = get_post_meta( $post->ID, '_tes_meta_description', true ); echo ' <!-- Mi plugin SEO (author: https://ayudawp.com) --> <meta property="og:title" content="' . $tes_meta_title . '" /> <meta property="og:description" content="' . $tes_meta_description . '" /> <meta name="description" content="' . $tes_meta_description . '" /> <!-- /Mi plugin SEO --> '; } add_action( 'wp_head', 'tes_mb_display' );
¿Qué hemos hecho?
- Para detectar correctamente el ID de la entrada recuperamos la referencia a la misma usando el objeto global
$post
. - A continuación se recuperan los datos meta de la base de datos y se guardan en las variables
$tes_meta_title
y$tes_meta_description
respectivamente. - Luego definimos la gaga meta que debe insertarse en la cabecera de la plantilla.
- Para finalizar conectamos la función con
wp_head
.
Si has escrito y guardado un título y descripción para una entrada o página al ver el código fuente de la misma podrás comprobar la presencia de las tags «title» y «description» para Open Graph y la meta «description» utilizada por los motores de búsqueda.
Al final, en muy pocos pasos, hemos creado un plugin SEO que añade etiquetas de título y descripción para Open Graph y la meta «description» a la cabecera de nuestras entradas y páginas.
El código completo del plugin sería algo así:
<?php /** * @package Plugin_SEO * @version 1.0 */ /* Plugin Name: Mi plugin SEO Plugin URI: https://ayudawp.com/ Description: Añade cajas meta para incluir metas "description" y "title" para Open Graph y buscadores. Author: Fernando Tellado Version: 1.0 Author URI: http://tellado.es */ function tes_mb_create() { /** * @array $screens Pantalla en la que se mostrará la caja meta * @values post, page, dashboard, link, attachment, custom_post_type */ $screens = array( 'post', 'page' ); foreach ( $screens as $screen ) { add_meta_box( 'tes-meta', 'Ajustes SEO ayudaWP', 'tes_mb_function', $screen, 'normal', 'high' ); } } add_action( 'add_meta_boxes', 'tes_mb_create' ); function tes_mb_function($post) { / /si existen se recuperan los valores de los metadatos $tes_meta_title = get_post_meta( $post->ID, '_tes_meta_title', true ); $tes_meta_description = get_post_meta( $post->ID, '_tes_meta_description', true ); // Se añade un campo nonce para probarlo más adelante cuando validemos wp_nonce_field( 'tes_inner_custom_box', 'tes_inner_custom_box_nonce' ); echo '<div style="margin: 10px 100px; text-align: center"> <table> <tr> <td><strong>Etiqueta "title":</strong></td><td> <input style="padding: 6px 4px; width: 300px" type="text" name="tes_meta_title" value="' . esc_attr($tes_meta_title) . '" /> </td> </tr> <tr> <td><strong>Meta "description":</strong></td><td> <textarea rows="3" cols="50" name="tes_meta_description">' . esc_attr($tes_meta_description) . '</textarea></td> </tr> </table> </div>'; } function tes_mb_save_data($post_id) { /* * Tenemos que verificar que esto proviene de nuestra pantalla y con la autorización adecuada, * para poder lanzar save_post en cualquier otro momento. */ // Comprobamos si se ha definido el nonce. if ( ! isset( $_POST['tes_inner_custom_box_nonce'] ) ) return $post_id; $nonce = $_POST['tes_inner_custom_box_nonce']; // Verificamos que el nonce es válido. if ( ! wp_verify_nonce( $nonce, 'tes_inner_custom_box' ) ) return $post_id; // Si es un autoguardado nuestro formulario no se enviará, ya que aún no queremos hacer nada. if ( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; // Comprobamos los permisos de usuario. 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; } /* Vale, ya es seguro que guardemos los datos. */ // Si existen entradas antiguas las recuperamos $old_title = get_post_meta( $post_id, '_tes_meta_title', true ); $old_description = get_post_meta( $post_id, '_tes_meta_description', true ); // Saneamos lo introducido por el usuario. $title = sanitize_text_field( $_POST['tes_meta_title'] ); $description = sanitize_text_field( $_POST['tes_meta_description'] ); // Actualizamos el campo meta en la base de datos. update_post_meta( $post_id, '_tes_meta_title', $title, $old_title ); update_post_meta( $post_id, '_tes_meta_description', $description, $old_description ); } add_action( 'save_post', 'tes_mb_save_data' ); function tes_mb_display() { global $post; // recuperamos los valores de los metadatos si existen $tes_meta_title = get_post_meta( $post->ID, '_tes_meta_title', true ); $tes_meta_description = get_post_meta( $post->ID, '_tes_meta_description', true ); echo ' <!-- Mi plugin SEO (author: https://ayudawp.com) --> <meta property="og:title" content="' . $tes_meta_title . '" /> <meta property="og:description" content="' . $tes_meta_description . '" /> <meta name="description" content="' . $tes_meta_description . '" /> <!-- /Mi plugin SEO --> '; } add_action( 'wp_head', 'tes_mb_display' ); ?>
Si te animas puedes añadirle también, por ejemplo, la meta «keywords«, que también te agradecerán los buscadores.
Si quieres, en vez de copiar cada parte del código puedes descargarte el plugin a continuación:
[download id=»75792»]
Fuente: tuts+
¿Te gustó este artículo? ¡Ni te imaginas lo que te estás perdiendo en YouTube!
hola
gracias muy interesante
si no es molestia, que plugin usas para contar las descargas?
saludos
Download Monitor
gracias
Te iba a hacer la misma pregunta jeje
Gracias por la información.
Download Monitor
Falta el código para poder poner un checkbox para marcar si queremos indexar o no la entrada y una pestaña para generar el sitemap y nos montamos un plugin sin tantas tonterias.
Muy buen tutorial Fernando por 3 motivos:
1. De éste modo no tenemos que instalar un plugin adicional.
2. No nos hacemos esclavos de un plugin. Después de haber rellenado los parámetros de mil entradas, a ver quien es el guapo que elimina el plugin.
3. Hay temas como Genesis y que sabes que uso, que añade éstos parámetros, pero estamos en las mismas, si cambio de tema, adiós seo.
Por cierto, me gustó el debate/hangout sobre frameworks si o no. Yo por supuesto estoy a favor de hacerse uno su propio tema, pero usar un framework te ahorra mucho trabajo.
Un saludo.
Buenas,
Ya, para hacerlo redondo del todo, se puede usar la función get_post_types() para saber todos los CPT que se usan y montarlo de forma automática en el Array. De esta forma, no debes estar modificando constantemente el código del mini plugin si cambias de theme o añades CPTs nuevos
http://codex.wordpress.org/Function_Reference/get_post_types
Muy buena Fernando! Aprovecho para dejar mi primer comentario en esta comunidad!! 😀
Estimado: soy asiduo lector, y creo que luego de buscar y buscar, solo aquí tendré una respuesta. Podrias en algun momento crear y explicar un pequeño plugging como éste que has creado en este post pero para lo siguiente:
AGREGAR OG:TITLE ,GG:DESCRIPTION y OG:IMAGE (con posibilidad de indicar una URL DE IMGAGEN) de OPEN GRAPH en CATEGORIAS de wordpress.
No existe ningun pluggin que permita agregar codigo OPEN GRAPH en categorias de wordpress y que permita establecer una OG:IMAGE. Esto es muy frustrante para los que queremos publicar una CATEGORIA en nuestras fanpages porque no muestra una imagen, y claro está que esto hace mucho menos llamativo a nuestro anuncio en Facebook.
Podras darnos una solucion? Gracias desde Argentina.