it-swarm-pt.com

Remova o slug dos URLs de impressão do tipo de postagem personalizada

Parece que todos os recursos da web com base no assunto de remover um tipo de post personalizado slug ou seja

yourdomain.com/CPT-SLUG/post-name 

agora são soluções muito desatualizadas, muitas vezes referenciando instalações pré-WP versão 3.5. Um comum é:

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

dentro da sua função register_post_type. Isso não funciona mais e é enganoso. Então peço à comunidade no terceiro trimestre de 2018 à beira do WordPress 5 ...

Quais são as maneiras modernas e eficientes de remover o Slug de tipo de postagem de um URL de postagem de tipo de postagem personalizado de dentro do argumento de reconfiguração ou em qualquer outro lugar?

ATUALIZAÇÃO: Parece haver várias maneiras de forçar isso para trabalhar com regex. Especificamente, a resposta de Jan Beck deve estar sempre disposto a monitorar a criação de conteúdo para garantir que não sejam criados nomes conflitantes de páginas/postagens ... No entanto, estou convencido de que essa é uma grande fraqueza no WP core onde deve ser tratado por nós. Ambos como uma opção/gancho ao criar um CPT ou um conjunto avançado de opções para permalinks. Por favor, apoiem o bilhete da pista.

Nota de rodapé: Por favor, apoie este ticket trac assistindo/promovendo: https://core.trac.wordpress.org/ticket/34136#ticket

43
Ben Racicot

O código a seguir funcionará, mas você só precisa ter em mente que os conflitos podem acontecer facilmente se o slug do seu tipo de post personalizado for o mesmo que uma página ou slug de postagem ...

Primeiro, vamos remover o slug do permalink:

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

Apenas removendo a lesma não é suficiente. Agora, você receberá uma página 404 porque o WordPress espera apenas que as postagens e as páginas se comportem dessa maneira. Você também precisará adicionar o seguinte:

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

Basta alterar "eventos" para o seu tipo de postagem personalizado e você é bom para ir. Você pode precisar atualizar seus permalinks.

57
Nate Allen

Escreva o código a seguir no registro de taxonomia.

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

A coisa mais importante que você tem que fazer depois de mudar o código

Depois de alterar o seu documento de taxonomia de tipo de postagem personalizada, tente ir para Configurações> Permalinks e salvar novamente suas configurações , senão você obterá uma página 404 não encontrada.

Verifique aqui a melhor solução: http://www.krazzycodes.com/how-to-remove-custom-post-type-taxonomy-base-from-url-in-wordpress/

19
Mayank Dudakiya

Eu tentei descobrir isso não faz muito tempo e a resposta curta do que eu sei é no . Não de dentro do argumento reescrito pelo menos.

A longa explicação se torna aparente se você olhar o código real de register_post_type em wp-includes/post.php line 1454 :

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

Você pode ver os prefixos $args->rewrite['slug'] na tag de reconfiguração %$post_type%. Alguém poderia pensar "vamos apenas definir a lesma para null então" até você olhar algumas linhas para cima:

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

Você pode ver que a função always espera um valor slug que não esteja vazio e use o tipo de postagem.

12
Jan Beck

Em resposta a minha resposta anterior : você poderia definir o parâmetro rewrite como false ao registrar um novo tipo de postagem e lidar com as regras de reconfiguração você mesmo assim

<?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' );

Você pode ver que a chamada add_permastruct agora não inclui mais a lesma. Eu testei dois cenários:

  1. Quando criei uma página com o slug "calendar" essa página é sobrescrita pelo arquivo de tipo de post que também usa o slug "calendar".

 enter image description here 

  1. Quando criei uma página com o slug "meu-evento" e um evento (CPT) com o slug "meu-evento", o tipo de postagem personalizado é exibido.

 enter image description here 

  1. Quaisquer outras páginas também não funcionam. Se você observar a figura acima, fica claro o porquê: a regra de tipo de postagem personalizada sempre corresponderá a um slug de página. Como o WordPress não tem como identificar se é uma página ou um tipo de post personalizado que não existe, ele retornará 404. É por isso que você precisa de um slug para identificar a página ou o CPT. Uma solução possível seria interceptar o erro e procurar uma página que possa existir semelhante a essa resposta .
7
Jan Beck

Analisando as respostas aqui, acho que há espaço para uma solução melhor que combina algumas coisas que aprendi acima e acrescenta detecção automática e prevenção de duplicatas.

OBSERVAÇÃO: lembre-se de alterar 'custom_post_type' para o seu próprio nome de CPT em todo o meu exemplo abaixo. Existem muitas ocorrências, e um 'localizar/substituir' é uma maneira fácil de capturar todas elas. Todo este código pode ir em suas funções.php ou em um plugin.

Passo 1: Desativar reescreve no seu tipo de postagem personalizada, definindo reescreve a 'falso' quando você registra a postagem:

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

Passo 2: Adicionar manualmente nossas reescritas personalizadas para o bottom do WordPress reescreve para o nosso 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' );

NOTA: Dependendo das suas necessidades, você pode querer modificar as reescritas acima (desative os trackbacks? Feeds ?, etc). Estes representam os tipos de reescrita 'padrão' que teriam sido gerados se você não desativasse as reescritas na etapa 1

Passo 3: Faça permalinks para o seu tipo de post personalizado "bonito" novamente

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

NOTA: Você pode parar por aqui se não estiver preocupado com a criação de uma postagem (duplicada) conflitante em outro tipo de postagem, criando uma situação em que apenas uma delas possa ser carregada quando a página for solicitada.

Passo 4: Prevenir duplicado slugs pós

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

NOTA: Isto irá acrescentar a string '-duplicate' ao final de qualquer slug duplicado. Esse código não pode evitar slugs duplicados se eles já existirem antes de implementar essa solução. Certifique-se de verificar se há duplicatas primeiro.

Eu adoraria ouvir de volta de qualquer outra pessoa que faça isso para ver se funcionou bem para eles também.

5
Matt Keys

Você não precisa de tanto código rígido. Basta usar o plugin leve:

Tem opções personalizáveis.

1
T.Todua

Para qualquer um que lesse isso, que tinha problemas com postagens de crianças, como eu, achei que a melhor maneira era adicionar suas próprias regras de reescrita.

O principal problema que eu tive foi que o WordPress trata o redirecionamento de páginas que são 2 níveis (posts de crianças) profundamente um pouco diferente do que trata de 3 níveis de profundidade (filho de posts de crianças).

Isso significa que quando eu tiver/post-type/post-name/post-child/eu posso usar/post-name/post-child e ele vai me redirecionar para aquele com post-type na frente, mas se eu tiver post-type/pós-nome/pós-filho/pós-neto, então não posso usar pós-nome/pós-filho/pós-neto.

Dando uma olhada nas regras de reescrita parece que combina com outras coisas além de pagename no primeiro e segundo níveis (acho que o segundo nível corresponde ao anexo) e então faz algo lá para redirecioná-lo para a postagem apropriada. A três níveis de profundidade não funciona.

A primeira coisa que você precisa fazer é remover o link do tipo de postagem das crianças também. Essa lógica deve acontecer aqui se você olhar a resposta de Nate Allen acima:

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

Eu mesmo usei uma mistura de diferentes condicionais para verificar se o post tinha filhos e outras coisas para chegar ao permalink direito. Esta parte não é muito complicada e você encontrará exemplos de pessoas fazendo isso em outro lugar.

O próximo passo é onde as coisas mudam da resposta dada. Em vez de adicionar coisas à consulta principal (que funcionava para postagens personalizadas e seus filhos, mas não as outras crianças) eu adicionei uma reescrita que foi para o fundo das regras do WordPress para que se pagename não check-out e estava prestes a Acertar um 404 faria uma última verificação para ver se uma página dentro do tipo de post personalizado tinha o mesmo nome, caso contrário, seria jogar fora o 404.

Aqui está a regra de reescrita que usei supondo que 'evento' é o nome do seu 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);

Espero que isso ajude alguém, eu não consegui encontrar qualquer outra coisa que tenha a ver com o filho de mensagens de crianças e removendo a lesma delas.

0
Moe Loubani

e podemos fazer algumas alterações na função acima mencionada:

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

para:

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

para definir o valor correto de post_type.

0
Max Kondrachuk

Isso funcionou para mim: 'rewrite' => array('slug' => '/')

0
Malki Mohamed