it-swarm-eu.dev

Odstraňte slug z vlastních poštovních adres typu příspěvku

Zdá se, že všechny webové zdroje založené na téma odstranění vlastního příspěvku typu slug tj

yourdomain.com/CPT-SLUG/post-name 

jsou nyní velmi zastaralá řešení často odkazující na pre WP verze 3.5 nainstaluje. Společný je:

'rewrite'   => array( 'slug' => false, 'with_front' => false ),  

v rámci funkce register_post_type. To už nefunguje a je zavádějící. Tak jsem požádal komunitu v Q3 2018 na pokraji WordPress 5 ...

Jaké jsou moderní a účinné způsoby, jak odstranit typ příspěvku Slug z uživatelského příspěvku, který zadává adresu URL z argumentu přepsání nebo kdekoli jinde?

AKTUALIZACE: Zdá se, že existuje několik způsobů, jak to donutit pracovat s regexem. Konkrétně odpověď od Jana Becka byste měli být důsledně ochotni sledovat tvorbu obsahu, abyste zajistili, že nebudou vytvořeny žádné konfliktní názvy stránek/poštovních stránek. Jsem však přesvědčen, že toto je hlavní slabina v jádru WP mělo by se s námi zacházet. Jak možnost/hák při vytváření CPT nebo pokročilé sady možností pro permalinks. Podporujte prosím lístek na trať.

Poznámka: Prosíme, podporujte tuto trac lístek sledováním/propagací: https://core.trac.wordpress.org/ticket/34136#ticket

43
Ben Racicot

Následující kód bude fungovat, ale musíte mít na paměti, že konflikty se mohou snadno vyskytnout, pokud je slim pro váš vlastní typ příspěvku stejný jako u stránky nebo u poštovního uzlu.

Nejprve odstraníme slimák z permalinku:

function na_remove_slug( $post_link, $post, $leavename ) {

    if ( 'events' != $post->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', 'na_remove_slug', 10, 3 );

Stačí odstranit slug nestačí. Právě teď, dostanete stránku 404, protože WordPress očekává pouze příspěvky a stránky, aby se takto chovaly. Budete také muset přidat následující položky:

function na_parse_request( $query ) {

    if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
        return;
    }

    if ( ! empty( $query->query['name'] ) ) {
        $query->set( 'post_type', array( 'post', 'events', 'page' ) );
    }
}
add_action( 'pre_get_posts', 'na_parse_request' );

Stačí změnit "události" na svůj vlastní typ příspěvku a můžete jít. Možná budete muset obnovit vaše permalinks.

57
Nate Allen

Do registrace taxonomie napište následující kód.

'rewrite' => [
  'slug' => '/',
  'with_front' => false
]

Nejdůležitější věc, kterou musíte udělat po změně kódu

Po změně vlastního dokumentu typu taxonomie typu příspěvku zkuste přejít na Nastavení> Permalinks a znovu uložit nastavení , jinak se vám stránka 404 nenalezne.

Zde naleznete nejlepší řešení: http://www.krazzycodes.com/how-to-vyberte-post-type-taxonomy-base-from-url-in-wordpress/

19
Mayank Dudakiya

Snažil jsem se to zjistit už dávno a krátká odpověď z toho, co vím, je ne . Nejméně z argumentu přepsání.

Dlouhé vysvětlení je zřejmé, pokud se podíváte na aktuální kód register_post_type v wp-includes/post.php řádek 1454 :

add_permastruct( $post_type, "{$args->rewrite['slug']}/%$post_type%", $permastruct_args );

Můžete vidět předpony $args->rewrite['slug'] do tagu %$post_type%. Dalo by se myslet: „pojďme nastavit slug na null“, dokud se nerozhlédneš několik řádků:

if ( empty( $args->rewrite['slug'] ) )
    $args->rewrite['slug'] = $post_type;

Vidíte, že funkce vždy očekává, že hodnota slug, která není prázdná, a jinak použije typ příspěvku.

12
Jan Beck

V reakci na mou předchozí odpověď : můžete samozřejmě nastavit parametr rewrite na false při registraci nového typu příspěvku a zpracovat pravidla přepisu sami

<?php
function wpsx203951_custom_init() {

    $post_type = 'event';
    $args = (object) array(
        'public'      => true,
        'label'       => 'Events',
        'rewrite'     => false, // always set this to false
        'has_archive' => true
    );
    register_post_type( $post_type, $args );

    // these are your actual rewrite arguments
    $args->rewrite = array(
        'slug' => 'calendar'
    );

    // everything what follows is from the register_post_type function
    if ( is_admin() || '' != get_option( 'permalink_structure' ) ) {

        if ( ! is_array( $args->rewrite ) )
            $args->rewrite = array();
        if ( empty( $args->rewrite['slug'] ) )
            $args->rewrite['slug'] = $post_type;
        if ( ! isset( $args->rewrite['with_front'] ) )
            $args->rewrite['with_front'] = true;
        if ( ! isset( $args->rewrite['pages'] ) )
            $args->rewrite['pages'] = true;
        if ( ! isset( $args->rewrite['feeds'] ) || ! $args->has_archive )
            $args->rewrite['feeds'] = (bool) $args->has_archive;
        if ( ! isset( $args->rewrite['ep_mask'] ) ) {
            if ( isset( $args->permalink_epmask ) )
                $args->rewrite['ep_mask'] = $args->permalink_epmask;
            else
                $args->rewrite['ep_mask'] = EP_PERMALINK;
        }

        if ( $args->hierarchical )
            add_rewrite_tag( "%$post_type%", '(.+?)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&pagename=" );
        else
            add_rewrite_tag( "%$post_type%", '([^/]+)', $args->query_var ? "{$args->query_var}=" : "post_type=$post_type&name=" );

        if ( $args->has_archive ) {
            $archive_slug = $args->has_archive === true ? $args->rewrite['slug'] : $args->has_archive;
            if ( $args->rewrite['with_front'] )
                $archive_slug = substr( $wp_rewrite->front, 1 ) . $archive_slug;
            else
                $archive_slug = $wp_rewrite->root . $archive_slug;

            add_rewrite_rule( "{$archive_slug}/?$", "index.php?post_type=$post_type", 'top' );
            if ( $args->rewrite['feeds'] && $wp_rewrite->feeds ) {
                $feeds = '(' . trim( implode( '|', $wp_rewrite->feeds ) ) . ')';
                add_rewrite_rule( "{$archive_slug}/feed/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
                add_rewrite_rule( "{$archive_slug}/$feeds/?$", "index.php?post_type=$post_type" . '&feed=$matches[1]', 'top' );
            }
            if ( $args->rewrite['pages'] )
                add_rewrite_rule( "{$archive_slug}/{$wp_rewrite->pagination_base}/([0-9]{1,})/?$", "index.php?post_type=$post_type" . '&paged=$matches[1]', 'top' );
        }

        $permastruct_args = $args->rewrite;
        $permastruct_args['feed'] = $permastruct_args['feeds'];
        add_permastruct( $post_type, "%$post_type%", $permastruct_args );
    }
}
add_action( 'init', 'wpsx203951_custom_init' );

Můžete vidět volání add_permastruct nyní nezahrnuje slug ještě. Testoval jsem dva scénáře:

  1. Když jsem vytvořil stránku s "kalendářem" slug, tato stránka je přepsána archivem typu pošty, který také používá "kalendář" slug.

 enter image description here 

  1. Když jsem vytvořil stránku se slugem "my-event" a událostí (CPT) se slugem "my-event", zobrazí se typ vlastního příspěvku.

 enter image description here 

  1. Žádné jiné stránky nefungují. Pokud se podíváte na obrázek nahoře, je zřejmé, proč: pravidlo vlastního typu příspěvku bude vždy odpovídat stránkování stránky. Protože WordPress nemá žádný způsob, jak identifikovat, zda je to stránka nebo vlastní typ příspěvku, který neexistuje, vrátí se 404. To je důvod, proč potřebujete identifikovat stránku nebo CPT. Možným řešením by bylo zachytit chybu a vyhledat stránku, která by mohla existovat podobná této odpovědi .
7
Jan Beck

Při pohledu přes odpovědi zde myslím, že existuje prostor pro lepší řešení, které kombinuje některé věci, které jsem se naučil výše, a přidává automatickou detekci a prevenci duplicitních post slugs.

POZNÁMKA: Ujistěte se, že jste změnili 'custom_post_type' pro svůj vlastní název CPT v mém příkladu níže. Existuje mnoho událostí a „najít/nahradit“ je snadný způsob, jak je všechny chytit. Všechny tyto kódy mohou jít do vaší function.php nebo do pluginu.

Krok 1: Zakázat přepisy na vašem typu vlastního příspěvku nastavením přepisu na 'false' při registraci příspěvku:

register_post_type( 'custom_post_type',
    array(
        'rewrite' => false
    )
);

Krok 2: Manuálně přidejte naše vlastní přepisy do přepisu bottom přepsání WordPressu pro náš custom_post_type

function custom_post_type_rewrites() {
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/attachment/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/embed/?$', 'index.php?custom_post_type=$matches[1]&embed=true', 'bottom');
    add_rewrite_rule( '([^/]+)/trackback/?$', 'index.php?custom_post_type=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '([^/]+)/page/?([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&paged=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?custom_post_type=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '([^/]+)(?:/([0-9]+))?/?$', 'index.php?custom_post_type=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/?$', 'index.php?attachment=$matches[1]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/trackback/?$', 'index.php?attachment=$matches[1]&tb=1', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/(feed|rdf|rss|rss2|atom)/?$', 'index.php?attachment=$matches[1]&feed=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/comment-page-([0-9]{1,})/?$', 'index.php?attachment=$matches[1]&cpage=$matches[2]', 'bottom');
    add_rewrite_rule( '[^/]+/([^/]+)/embed/?$', 'index.php?attachment=$matches[1]&embed=true', 'bottom');
}
add_action( 'init', 'custom_post_type_rewrites' );

POZNÁMKA: V závislosti na vašich potřebách můžete změnit výše uvedené přepisy (zakázat zpětné odkazy? Zdroje ?, atd.). Jedná se o „výchozí“ typy přepisů, které by byly generovány, pokud byste v kroku 1 nezakázali přepisy

Krok 3: Znovu udělejte permalinks na váš vlastní příspěvek typu 'pretty'

function custom_post_type_permalinks( $post_link, $post, $leavename ) {
    if ( isset( $post->post_type ) && 'custom_post_type' == $post->post_type ) {
        $post_link = home_url( $post->post_name );
    }

    return $post_link;
}
add_filter( 'post_type_link', 'custom_post_type_permalinks', 10, 3 );

POZNÁMKA: Zde se můžete zastavit, pokud se neobáváte, že uživatelé vytvoří konfliktní (duplikovaný) příspěvek v jiném typu příspěvku, který vytvoří situaci, kdy pouze jeden z nich může načíst, když je stránka požadována.

Krok 4: Zabránit duplicitním post slugs

function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
    $check_post_types = array(
        'post',
        'page',
        'custom_post_type'
    );

    if ( ! in_array( $post_type, $check_post_types ) ) {
        return $slug;
    }

    if ( 'custom_post_type' == $post_type ) {
        // Saving a custom_post_type post, check for duplicates in POST or PAGE post types
        $post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
        $page_match = get_page_by_path( $slug, 'OBJECT', 'page' );

        if ( $post_match || $page_match ) {
            $slug .= '-duplicate';
        }
    } else {
        // Saving a POST or PAGE, check for duplicates in custom_post_type post type
        $custom_post_type_match = get_page_by_path( $slug, 'OBJECT', 'custom_post_type' );

        if ( $custom_post_type_match ) {
            $slug .= '-duplicate';
        }
    }

    return $slug;
}
add_filter( 'wp_unique_post_slug', 'prevent_slug_duplicates', 10, 6 );

POZNÁMKA: Tím se řetězec '-duplicate' připojí ke konci duplikátu. Tento kód nemůže zabránit duplicitním slimákům, pokud již existují před implementací tohoto řešení. Nejprve zkontrolujte, zda nejsou duplikáty.

Ráda bych slyšela od kohokoli jiného, ​​kdo to udělá, aby zjistil, zda pro ně funguje stejně dobře.

5
Matt Keys

Nepotřebujete tolik hard-code. Stačí použít lehký plugin:

Má přizpůsobitelné možnosti.

1
T.Todua

Pro každého, kdo čte to, že měl problémy s dětské příspěvky, jako jsem já jsem našel nejlepší způsob, jak přidat vlastní pravidla přepsání.

Hlavní problém, který jsem měl, bylo to, že WordPress zachází s přesměrováním ze stránek, které jsou 2 úrovně (dětské příspěvky) hluboko trochu jinak, než s 3 úrovněmi hluboko (dítě z dětských příspěvků).

To znamená, že když mám/post-type/post-name/post-child/mohu použít/post-name/post-child a přesměrovat mě na ten s post-type vpředu, ale pokud mám post-type/post-name/post-child/post-vnuk pak nemohu použít post-name/post-child/post-vnouče.

Podívejme se na pravidla pro přepisování a vypadá to, že se shoduje s jinými věcmi než stránkami na první a druhé úrovni (myslím, že druhá úroveň odpovídá příloze) a pak tam něco udělá, aby vás přesměrovala na správné místo. Na třech úrovních hluboko to nefunguje.

První věc, kterou musíte udělat, je odstranit odkaz typu příspěvku také z dětí. Tato logika by se měla stát, pokud se podíváte na odpověď Nate Allenové výše:

$post_link = str_replace( '/' . $post->post_type . '/', '/', $post_link );

Já sám jsem použil kombinaci různých podmínek, abych zkontroloval, zda post měl děti a co ne, abych se dostal na správný permalink. Tato část není příliš složitá a najdete příklady lidí, kteří to dělají jinde.

Dalším krokem je však to, kde se věci mění od dané odpovědi. Namísto přidávání věcí do hlavního dotazu (který pracoval pro vlastní příspěvky a jejich děti, ale ne další děti) jsem přidal přepsání, které šlo na dno pravidel WordPressu tak, že pokud se název stránky nevyzkoušel a bylo to asi hit 404 to by udělal jednu poslední kontrolu, aby zjistil, zda stránka v rámci vlastního typu příspěvku měl stejný název, jinak by to vyhodilo 404.

Zde je pravidlo přepsání, které jsem použil za předpokladu, že název události je název vaší CPT

function rewrite_rules_for_removing_post_type_slug()
{
    add_rewrite_rule(
        '(.?.+?)?(:/([0-9]+))?/?$',
        'index.php?event=$matches[1]/$matches[2]&post_type=event',
        'bottom'
    );
}

add_action('init', 'rewrite_rules_for_removing_post_type_slug', 1, 1);

Doufám, že to pomůže někomu jinému, nemohl jsem najít nic jiného, ​​co by mělo co do činění s dítětem dětských příspěvků a odstraňováním slimáka z těch.

0
Moe Loubani

a můžeme provést některé změny výše uvedené funkce:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {
    $query->set( 'post_type', array( 'post', 'events', 'page' ) );
}
}

na:

function na_parse_request( $query ) {

if ( ! $query->is_main_query() || 2 != count( $query->query ) || ! isset( $query->query['page'] ) ) {
    return;
}

if ( ! empty( $query->query['name'] ) ) {

    global $wpdb;
    $pt = $wpdb->get_var(
        "SELECT post_type FROM `{$wpdb->posts}` " .
        "WHERE post_name = '{$query->query['name']}'"
    );
    $query->set( 'post_type', $pt );
}
}

pro nastavení správné hodnoty post_type.

0
Max Kondrachuk

To fungovalo pro mě: 'rewrite' => array('slug' => '/')

0
Malki Mohamed