Reescribiendo el slug del post antes de guardarlo

10 jul 2013, 09:50:41
Vistas: 26.7K
Votos: 12

Necesito recuperar un campo ACF dentro del post y cambiar el slug (enlace permanente) del post antes de guardarlo en la base de datos. ¿Cuál es el enfoque para lograr esto? Necesito que el slug se cambie en cada operación de creación/edición de post.

Solución

Puedes usar el hook save_post o wp_insert_post_data para modificar el slug antes de que se guarde el post. Aquí hay dos ejemplos:

Usando save_post:

add_action('save_post', 'modificar_slug_antes_de_guardar', 10, 3);

function modificar_slug_antes_de_guardar($post_id, $post, $update) {
    // Evitar recursión infinita
    remove_action('save_post', 'modificar_slug_antes_de_guardar');

    // Verificar si es una autoguardado
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }

    // Obtener el valor del campo ACF
    $campo_acf = get_field('nombre_del_campo', $post_id);
    
    // Actualizar el slug
    wp_update_post(array(
        'ID' => $post_id,
        'post_name' => sanitize_title($campo_acf)
    ));

    // Volver a añadir el action
    add_action('save_post', 'modificar_slug_antes_de_guardar', 10, 3);
}

Usando wp_insert_post_data (recomendado):

add_filter('wp_insert_post_data', 'modificar_datos_post_antes_de_guardar', 10, 2);

function modificar_datos_post_antes_de_guardar($data, $postarr) {
    // Verificar si tenemos ID del post
    if (!empty($postarr['ID'])) {
        // Obtener el valor del campo ACF
        $campo_acf = get_field('nombre_del_campo', $postarr['ID']);
        
        // Modificar el slug
        $data['post_name'] = sanitize_title($campo_acf);
    }
    
    return $data;
}

La segunda opción usando wp_insert_post_data es más eficiente porque:

  • No genera una consulta adicional a la base de datos
  • No hay riesgo de recursión infinita
  • Se ejecuta antes de que el post sea guardado en la base de datos

Recuerda reemplazar 'nombre_del_campo' con el nombre real de tu campo ACF.

0
Todas las respuestas a la pregunta 2
3
26

Lo siguiente debe tomarse más como una prueba de concepto que como una solución lista para copiar/pegar.
Dicho esto, así es como lo harías:

La save_post acción se ejecuta cada vez que se actualiza o crea una publicación. Puedes enlazar una función de retorno (callback) usando add_action.

Por lo tanto, tu caso debería verse algo así:

// enlace inicial
add_action( 'save_post', 'wpse105926_save_post_callback' );

function wpse105926_save_post_callback( $post_id ) {

    // verificar que la publicación no sea una revisión
    if ( ! wp_is_post_revision( $post_id ) ) {

        // desenlazar esta función para evitar bucles infinitos
        remove_action( 'save_post', 'wpse105926_save_post_callback' );

        // actualizar el slug de la publicación
        wp_update_post( array(
            'ID' => $post_id,
            'post_name' => 'algun-nuevo-slug' // haz lo tuyo aquí
        ));

        // volver a enlazar esta función
        add_action( 'save_post', 'wpse105926_save_post_callback' );

    }
}

Lo que puede resultar un poco confuso en el código anterior es el desenlazado y reenlazado de la función desde dentro de ella misma. Esto es necesario porque llamamos a wp_update_post para actualizar el slug, lo que a su vez volverá a disparar la acción save_post.

Como nota adicional, si quieres que WordPress genere automáticamente el nuevo slug basado en el título de la publicación, simplemente pasa una cadena vacía:

wp_update_post( array(
    'ID' => $post_id,
    'post_name' => '' // WP generará el slug basado en el título
));
10 jul 2013 11:46:23
Comentarios

gracias por el concepto, me ayudó a entender mejor el proceso

Vit Kos Vit Kos
10 jul 2013 13:31:43

La pregunta se refiere a ACF, específicamente a "recuperar" el campo (valor) y tu concepto funciona en php pero justamente le falta lo que comentaste como "do your thing here". ¿Podrías mostrar un proof of concept para la recuperación también? (recuerda que el campo #postname ni siquiera está ahí hasta que se hace clic en el botón "edit" (permalink). Lo mismo con el campo invisible #new-post-slug)

sergio sergio
9 jul 2015 09:54:00

¿No podría hacer esto también usando el filtro wp_insert_post_data, que se ejecuta después de la sanitización, justo antes de guardar? ¿Cuál es la mayor ventaja de este método?

toni_lehtimaki toni_lehtimaki
3 sept 2017 12:22:33
0

Necesitaba lo mismo pero solo para la creación de publicaciones.

Implementé la solución aquí (esta está lista para copiar/pegar).

Solo elimina la línea que verifica que ambas fechas sean iguales, y actualizará el slug también para operaciones de edición. Sin embargo, no lo recomiendo ya que cambiará la URL de la publicación y esto no es bueno para SEO, entre otras cosas como enlaces rotos (404).

11 feb 2016 01:15:37