Schimbarea structurii permalink pentru tipuri de postări personalizate

1 feb. 2016, 18:59:28
Vizualizări: 22.6K
Voturi: 2

Am 2 tipuri de postări personalizate: software și hardware. Din motive SEO, aș dori ca permalink-urile paginilor individuale software și hardware să arate astfel:

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

Dar în mod implicit WordPress adaugă slug-ul tipului de postare astfel:

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

Am eliminat slug-ul cu scriptul următor care face o înlocuire a șirului de caractere. Acum pagina individuală este accesibilă cu ambele URL-uri descrise mai sus și Google Search Console găsește 2 pagini cu exact același conținut, ceea ce nu este bun pentru SEO. Este posibil să schimb complet structura permalink-ului și să scap de slug-ul tipului de postare personalizat?

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
Comentarii

Te rugăm să editezi întrebarea ta și să ne spui cum ai folosit register_post_type

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

` //înregistrează tipul de postare 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
Toate răspunsurile la întrebare 5
0

Notă importantă despre răspunsul de mai sus:

Deși la prima vedere va funcționa corect, acest cod poate cauza probleme de performanță. Tot acest cod va fi apelat pe hook-ul init, astfel încât la fiecare încărcare de pagină se va executa, iar flush_rules() este o operațiune foarte costisitoare din punct de vedere al timpului.

Prin urmare, este recomandat să apelați flush rules doar la activarea temei/plugin-ului. De asemenea, puteți utiliza funcțiile add_permastruct fără a fi nevoie să accesați global $wp_rewrite.

Soluția finală îmbunătățită ar fi:

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 );
}

 /* în cazul unui plugin */
register_activation_hook(__FILE__,'my_custom_plugin_activate');
function my_custom_plugin_activate() {
    flush_rewrite_rules();
}


/* în cazul unei teme personalizate în Functions.php */
add_action('after_switch_theme', 'mytheme_setup');
function mytheme_setup () {
    flush_rewrite_rules();
}
20 ian. 2017 17:35:54
0

Am reușit să rezolv problema folosind {$field_no_prefix}_save_pre cu post_name.

/**
 * Personalizează permalink-urile.
 *
 * @param string $post_name
 *
 * @return string
 *   Returnează o combinație nume-SKU pentru produse, dacă toate componentele sunt disponibile.
 */
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(
        { modifică $_POST['post_title'] după preferințe }
    );

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

Dacă te uiți la argumentul rewrite pentru register_post_type, există o opțiune with_front pentru a dezactiva baza implicită care este adăugată în fața permalink-ului tipului de postare personalizat. Dacă setezi aceasta la false, /blog/produse/ de exemplu devine /produse/.

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

'rewrite' => array(
    'slug' => 'produse',
    'with_front' => false
)
8 nov. 2023 21:26:25
Comentarii

Atât de simplu, un răspuns drăguț!

brasofilo brasofilo
3 iul. 2024 20:46:07
1

REZOLVAT

folosind $wp_rewrite poți adăuga o nouă structură de 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();
}

apoi înlocuiești eticheta personalizată cu str_replace când filtrezi URL-ul linkului

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

NOTĂ: dacă folosești această funcție așa cum este scrisă (eliminând slug-ul tipului de post din permalink), poți întâmpina probleme grave deoarece nu există control dacă faci un permalink personalizat la fel ca o pagină sau un post standard

2 feb. 2016 19:04:27
Comentarii

Este o practică proastă să reîmprospătezi regulile la fiecare încărcare de pagină (acțiunea init). Ar trebui să faci asta doar o singură dată.

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

Oricine ajunge la această întrebare și a întâmpinat problema linkurilor moarte cu "următorul script" menționat în întrebare, iată scriptul mulțumită Wayback Machine, cu o corecție la ceea ce cred că a fost o eroare în cod:

/**
 * Elimină slug-ul din permalinkurile postărilor publicate. Afectează doar CPT-ul nostru.
 */
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 ) {
    // Acționează doar pentru interogarea principală
    if ( ! $query->is_main_query() )
        return;
    // Acționează doar pentru o potrivire specifică a regulii de rescriere
    if ( 2 != count( $query->query )
        || ! isset( $query->query['page'] ) )
        return;
    // 'name' va fi setat dacă permalinkurile postărilor sunt doar post_name, altfel se va potrivi regula pentru pagină
    if ( ! empty( $query->query['name'] ) )
        $query->set( 'post_type', array( 'post', 'your_post_type', 'page' ) );
}
add_action( 'pre_get_posts', 'vipx_parse_request_tricksy' );

Împreună cu revizuirea lui Mikhail a soluției propuse de 3ky, dacă ați fost ca mine și nu v-a fost imediat evident, am considerat necesar să implementez funcția vipx_parse_request_tricksy() și acțiunea corespunzătoare. Dar funcția vipx_remove_cpt_slug() face același lucru ca my_custom_permalinks(), deci nu sunt necesare ambele - alegeți una?

22 ian. 2021 00:43:11