Contents
Introducción
El contenido duplicado es un problema común en sitios WordPress que afecta al SEO, la experiencia de usuario y la gestión interna. Este artículo explica en detalle cómo impedir la creación de contenido duplicado mediante una verificación previa en PHP, integrándose con el flujo de guardado de WordPress. Incluye técnicas seguras y prácticas —cálculo de huellas (hash), comprobaciones previas al insertado, notificaciones en el admin, manejo en formularios front-end y opciones para detección difusa— además de recomendaciones de rendimiento y migración.
Estrategia general
- Normalizar el título y contenido (quitar HTML, espacios, convertir a minúsculas).
- Calcular una huella (hash) del contenido relevante (por ejemplo sha1 de título contenido).
- Comprobar en la base de datos si ya existe esa huella antes de permitir publicar/crear el post.
- Guardar la huella en postmeta cuando el post se guarda definitivamente para futuras comprobaciones rápidas.
- Opcional: detección difusa (similaridad con levenshtein o similitud porcentual) para evitar copias con ligeras variaciones.
Ventajas de este enfoque
- Rápido y determinista: comparar hashes es muy eficiente.
- Integración nativa con hooks de WordPress (pre-insert, save_post).
- Se puede aplicar tanto en el admin como en formularios públicos (AJAX).
- Permite acciones configurables: bloquear, convertir a borrador, o avisar al usuario.
Detalles de implementación
Debajo se muestran los bloques principales de código. Todos los ejemplos están preparados para pegar en el archivo functions.php de un tema hijo o en un plugin propio. Recuerde probar en un entorno de desarrollo antes de desplegar en producción.
1) Función para normalizar y calcular hash
Normalice eliminando HTML, múltiples espacios y convirtiendo a minúsculas. Luego calcule un hash (sha1 o md5).
2) Comprobación previa antes de insertar o publicar
Hook recomendado: wp_insert_post_data, que permite interceptar los datos antes de que WordPress haga el INSERT/UPDATE. Podemos, si detectamos duplicado, cambiar el estado del post a draft y añadir un flag para mostrar un aviso al usuario.
postarr[post_type], post_status => array( publish, draft, pending, future ), meta_query => array( array( key => _mi_content_hash, value => hash, ), ), fields => ids, posts_per_page => 1, post__not_in => isset( postarr[ID] ) ! empty( postarr[ID] ) ? array( intval( postarr[ID] ) ) : array(), ) q = new WP_Query( args ) if ( q->have_posts() ) { // Se encontró duplicado: evitar publicación cambiando a borrador // También marcamos un flag temporal para mostrar aviso después add_filter( redirect_post_location, function( location ) { return add_query_arg( mi_duplicate_detected, 1, location ) } ) // Asegurar que no se publique — forzamos draft si intentaban publicar if ( data[post_status] === publish ) { data[post_status] = draft } // Guardamos el hash en el array para procesarlo después (save_post) if ( isset( postarr[ID] ) ! empty( postarr[ID] ) ) { // En actualización, no necesitamos más, save_post lo guardará } else { // En creación, podemos pasar el hash por post_content_filtered para recuperarlo data[post_content_filtered] = data[post_content_filtered] . n } } wp_reset_postdata() return data } ?>
3) Guardar el hash en postmeta cuando el post se guarda
Hook: save_post. Guardamos permanentemente la huella para futuras búsquedas.
post_type, allowed_types, true ) ) { return } // Obtener título y contenido actuales title = post->post_title content = post->post_content hash = mi_normalizar_y_hash_post( title, content ) // Guardar meta update_post_meta( post_ID, _mi_content_hash, hash ) } ?>
4) Mostrar aviso en el área de administración cuando se bloquea por duplicado
Usamos la query arg añadida en el filtro anterior para mostrar un admin notice claro.
Duplicado detectado: Se ha detectado contenido similar en otra entrada. La publicación ha quedado en borrador. Revise y actualice el contenido o confirme que desea crear una entrada duplicada.