Rigenera gli Slug dal Titolo dei Post

19 mar 2012, 18:38:12
Visualizzazioni: 26.3K
Voti: 17

È possibile rigenerare gli slug programmaticamente dopo aver modificato i titoli dei post? Numerosi titoli dei post sono stati aggiornati e lo slug non è stato aggiornato con il titolo, quindi ho bisogno di rigenerare tutti questi slug.

1
Commenti

Ho dovuto farlo diverse volte e ho scoperto che in ambienti server diversi che non riescono a gestire array di grandi dimensioni (con numberposts impostato su illimitato) né chiamare ripetutamente wp_update_post con un elevato consumo di memoria, suddividere il tutto in una chiamata WP_Query con paginazione e utilizzare $wpdb risulta più gestibile e performante. Ho fornito un esempio di codice in un post simile.

codearachnid codearachnid
27 feb 2014 05:14:30
Tutte le risposte alla domanda 5
3
28

Sì, è possibile.

Codice di esempio, da testare e perfezionare:

// ottieni tutti i post
$posts = get_posts( array (  'numberposts' => -1 ) );

foreach ( $posts as $post )
{
    // controlla lo slug ed esegui un aggiornamento se necessario
    $new_slug = sanitize_title( $post->post_title );
    if ( $post->post_name != $new_slug )
    {
        wp_update_post(
            array (
                'ID'        => $post->ID,
                'post_name' => $new_slug
            )
        );
    }
}

L'ho appena creato, probabilmente ci sono alcuni errori e casi particolari, ma dovrebbe darti un'idea. Inoltre, potrebbe richiedere del tempo, quindi potrebbe essere utile suddividere l'aggiornamento in blocchi più piccoli.

19 mar 2012 21:20:32
Commenti

Uhm... dalla mia esperienza, questo non funziona. L'argomento post_name viene ignorato dalla funzione wp_update_post, almeno nella versione 3.9 del core

Alexandre Bourlier Alexandre Bourlier
4 set 2014 16:55:37

Attualmente, post_name viene ignorato all'interno della funzione wp_update_post(), ma viene preso in considerazione quando l'aggiornamento del post richiama la funzione wp_insert_post(): ciò significa che passare il nuovo slug all'aggiornamento, risulterà nella modifica effettiva dello slug per il post che viene aggiornato.

Erenor Paz Erenor Paz
30 mag 2018 11:00:27

@fuxia, ho provato qualcosa di simile ma va in timeout. Saresti in grado di suggerire un approccio?

Motivated Motivated
5 ott 2022 08:39:53
0

Anche questo plugin svolge il lavoro: http://www.jerrytravis.com/598/wordpress-plugin-to-generate-post-slugs

Tuttavia, dato che lo fa solo per i post che non hanno ancora uno slug, se hai bisogno di rigenerare gli slug modifica la seguente linea nel plugin:

if ($post->post_name == "") {

Ad esempio, potresti cambiarla con:

if (true) {

24 lug 2014 11:31:09
2

Stavo provando il metodo suggerito da Toscho, che è quello "istintivo", ma in molti casi non funziona (vedi il codice core per capire cosa intendo con "molti casi").

Analizzando il codice, ho trovato l'hook filter wp_insert_post_data, chiamato dalla funzione wp_update_post poco prima di inserire il post nel database.

Chiamando questo filtro e modificando il valore di $data['post_name'], sono riuscito a farlo funzionare correttamente. WordPress è fantastico ma così male documentato...

Ho modificato la documentazione, in modo che più persone possano trovare questa soluzione alternativa se necessario.

4 set 2014 17:30:06
Commenti

Puoi indicare perché wp_update_post sovrascrive il post_name? L'unica ragione che vedo perché questo accada è se l'utente che cerca di modificare il post_name è solo un collaboratore (o livello simile) nel qual caso non dovrebbe permettere a quell'utente di cambiare lo slug, hai trovato altri casi in cui il post_name viene sovrascritto?

jnhghy - Alexandru Jantea jnhghy - Alexandru Jantea
16 ott 2014 10:32:59

Sì, questo è il modo corretto per farlo. Grazie @Alexandre

User User
10 mar 2017 10:44:41
0

puoi farlo direttamente in mysql se necessario. (il nostro sito woocommerce ha centinaia di migliaia di prodotti):

update wp_posts set post_name = concat(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(lower(post_title), '"', ''), "'", ''), ",", '-'), " ", '-'), "&", ''), ";", ''), "@", ''), ".", ''), ":", ''), "/", ''), "+", ''), "(", ''), ")", ''), "--", '-'), "---", '-'), "--", '-'), "--", '-'), '-', id) where post_type = 'product';

dove post_type = 'product' - questo limiterà l'aggiornamento ai soli prodotti woocommerce; dovresti capire quali limiti vuoi impostare su questa query.

7 gen 2020 07:19:26
0

Abbiamo avuto un problema durante la migrazione e unione di diversi tipi di post. Avevamo anche molti titoli vuoti. Ho scritto un comando WP CLI per sistemarli tutti, ma ecco l'essenza di ciò che ho fatto:

    global $wpdb;
    $types = [
      'page',
      // I nomi machine dei vostri CPT
    ];

    // Formatta correttamente la nostra query IN.
    $final = array_map(function($type) {
      return "'" . esc_sql($type) . "'";
    }, $types);

    // Recupera tutti i campi titolo vuoti.
    $query = sprintf("SELECT post_title, ID FROM `%s` WHERE post_type IN (%s) AND post_name = ''",
      $wpdb->posts,
      implode(",", $final)
    );

    foreach ($wpdb->get_results($query) as $post) {
      $title = sanitize_title_with_dashes( $post->post_title );
      $wpdb->update('wp_posts', ['post_name' => $title], ['ID' => $post->ID]);
    }

È stato necessario fare un aggiornamento MySQL diretto poiché wp_update_post non aggiorna il post_name.

12 giu 2020 16:44:19