Cambiare la struttura dei permalink per i custom post type

1 feb 2016, 18:59:28
Visualizzazioni: 22.6K
Voti: 2

Ho 2 custom post type: software e hardware. Per motivi SEO vorrei avere i permalink delle singole pagine software e hardware così:

https://domain.com/custom-post-name/

Ma di default WordPress aggiunge lo slug del post-type come:

https://domain.com/post-type-slug/custom-post-name/

Ho rimosso lo slug con questo script che fa una sostituzione della stringa. Ora la singola pagina è raggiungibile con entrambi gli URL descritti sopra e Google Search Console trova 2 pagine con lo stesso identico contenuto, il che non è positivo per la SEO. È possibile modificare completamente la struttura di un permalink ed eliminare lo slug del custom post type?

register_post_type( 'hardware',
    array (
        'labels' => $labels,
        'has_archive' => true,
        'public' => true,
        'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail' ),
        'taxonomies' => array( 'hardware-post_tag', 'hardware-category' ),
        'exclude_from_search' => false,
        'capability_type' => 'post',
        'rewrite' => array( 'slug' => 'hardware' ),
    )
);

2
Commenti

Per favore modifica la tua domanda e facci sapere come hai usato la funzione register_post_type

WordPress Speed WordPress Speed
1 feb 2016 19:10:03

` //registra il tipo di post register_post_type( 'hardware', array ( 'labels' => $labels, 'has_archive' => true, 'public' => true, 'supports' => array( 'title', 'editor', 'excerpt', 'custom-fields', 'thumbnail' ), 'taxonomies' => array( 'hardware-post_tag', 'hardware-category' ), 'exclude_from_search' => false, 'capability_type' => 'post', 'rewrite' => array( 'slug' => 'hardware' ),

) ); `

Rico Rico
1 feb 2016 20:35:06
Tutte le risposte alla domanda 5
0

Nota una cosa importante riguardo alla risposta precedente:

Sebbene a prima vista funzioni bene, causerà problemi di performance. Tutto questo codice verrà eseguito sull'hook init quindi ogni caricamento di pagina lo farà girare e flush_rules() è un'operazione molto costosa in termini di tempo.

Quindi è consigliato chiamare il flush delle regole solo all'attivazione del tema/plugin. Inoltre puoi usare le funzioni add_permastruct senza bisogno di accedere a global $wp_rewrite

La soluzione finale migliorata sarebbe:

add_action('init', 'my_custom_rewrite'); 
function my_custom_rewrite() {

    add_permastruct('hardware', '/%customname%/', false);
    add_permastruct('produkt', '/%customname%/', false);
}

add_filter( 'post_type_link', 'my_custom_permalinks', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
      return str_replace( '%customname%/', $post->post_name, $permalink );
}

 /* nel caso di un plugin */
register_activation_hook(__FILE__,'my_custom_plugin_activate');
function my_custom_plugin_activate() {
    flush_rewrite_rules();
}


/* nel caso di un Tema personalizzato in Functions.php */
add_action('after_switch_theme', 'mytheme_setup');
function mytheme_setup () {
    flush_rewrite_rules();
}
20 gen 2017 17:35:54
0

Sono riuscito a risolverlo utilizzando {$field_no_prefix}_save_pre con post_name.

/**
 * Personalizza i permalink.
 *
 * @param string $post_name
 *
 * @return string
 *   Restituisce una combinazione nome-SKU per i prodotti, se tutti i componenti sono disponibili.
 */
function my_custom_permalinks( $post_name ) {

    if (
        ($_POST['post_type'] !== 'product')
    ||  ($_POST['post_status'] === 'auto-draft')
    ) {
        return $post_name;
    }

    $post_name = sanitize_title_with_dashes(
        { modifica $_POST['post_title'] come preferisci }
    );

    return $post_name;
}
add_filter('name_save_pre', 'my_custom_permalinks', 1, 1);
27 lug 2021 18:13:41
1

Se osservi l'argomento rewrite per register_post_type, c'è un'opzione with_front per disabilitare la base predefinita che viene anteposta al permalink del tipo di post personalizzato. Se imposti questo valore su false, /blog/prodotti/ per esempio diventa /prodotti/.

https://developer.wordpress.org/reference/functions/register_post_type/#rewrite

'rewrite' => array(
    'slug' => 'prodotti',
    'with_front' => false
)
8 nov 2023 21:26:25
Commenti

Risposta così semplice e dolce!

brasofilo brasofilo
3 lug 2024 20:46:07
1

RISOLTO

utilizzando $wp_rewrite puoi aggiungere una nuova struttura di permalink

add_action('init', 'my_custom_rewrite');
function my_custom_rewrite() {
    global $wp_rewrite;
    $wp_rewrite->add_permastruct('hardware', '/%customname%/', false);
    $wp_rewrite->add_permastruct('produkt', '/%customname%/', false);
    $wp_rewrite->flush_rules();
}

poi sostituisci il tuo tag personalizzato con str_replace quando filtri l'URL del link

add_filter( 'post_type_link', 'my_custom_permalinks', 10, 2 );
function my_custom_permalinks( $permalink, $post ) {
    return str_replace( '%customname%/', $post->post_name, $permalink );
}

NOTA: se usi questa funzione così com'è scritta (rimuovendo lo slug del post type dal permalink) puoi aspettarti problemi gravi perché non c'è alcun controllo se crei un permalink di post personalizzato uguale a una pagina o a un post standard

2 feb 2016 19:04:27
Commenti

È una cattiva pratica eseguire il flush delle regole ad ogni caricamento di pagina (azione init). Devi farlo solo una volta.

Serhiy Zaharchenko Serhiy Zaharchenko
8 apr 2020 13:06:37
0

Chiunque si imbatta in questa domanda e abbia affrontato il fastidioso problema del link rot con il collegamento "following script" menzionato nella domanda, ecco lo script gentilmente fornito dalla Wayback Machine, con una correzione a quello che credo fosse un errore nel codice:

/**
 * Rimuove lo slug dai permalink dei post pubblicati. Interessa solo il nostro CPT.
 */
function vipx_remove_cpt_slug( $post_link, $post, $leavename ) {
    if ( ! in_array( $post->post_type, array( 'your_post_type' ) ) || 'publish' != $post->post_status )
        return $post_link;
    $post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );
    return $post_link;
}
add_filter( 'post_type_link', 'vipx_remove_cpt_slug', 10, 3 );

function vipx_parse_request_tricksy( $query ) {
    // Intervieni solo sulla query principale
    if ( ! $query->is_main_query() )
        return;
    // Intervieni solo in caso di corrispondenza con la nostra specifica regola di rewrite
    if ( 2 != count( $query->query )
        || ! isset( $query->query['page'] ) )
        return;
    // 'name' sarà impostato se i permalink dei post sono solo post_name, altrimenti verrà applicata la regola della pagina
    if ( ! empty( $query->query['name'] ) )
        $query->set( 'post_type', array( 'post', 'your_post_type', 'page' ) );
}
add_action( 'pre_get_posts', 'vipx_parse_request_tricksy' );

Insieme alla revisione di Mikhail della soluzione di 3ky, se come me non ti era immediatamente chiaro, ho trovato necessario implementare la funzione vipx_parse_request_tricksy() e la corrispondente azione. Ma la funzione vipx_remove_cpt_slug() duplica ciò che fa my_custom_permalinks(), quindi entrambe non sono necessarie—scegline una?

22 gen 2021 00:43:11