Tipo de postagem personalizada do Wordpress 3.3 com /% postname% / permastruct?

9

Há postagens anteriores com título semelhante, mas ele não é direcionado para o WordPress 3.3, e isso é importante porque o 3.3 anuncia de forma interessante: "Use a estrutura de permalink do nome do post sem uma penalidade de desempenho"

O problema com o Wordpress 3.2 e versões anteriores foi que primeiro ele olhou os nomes das páginas e depois o 404. Ele não verificou primeiro os tipos de postagem arbitrários. 3.3, por outro lado, deve procurar os tipos de postagem, as páginas e, finalmente, o 404 (como anuncia esse recurso). Isso implica que os tipos de postagem personalizados sem slug devem ser simples , se não tiverem codificado em post_type=postalgum lugar.

Ainda não consigo encontrar uma solução específica para 3.3.

Pergunta : Como posso definir a estrutura do permalink "/% postname% /" para qualquer tipo de postagem personalizada "xyz"?

Obrigado.

Ciantic
fonte
Não vejo uma pergunta - o que você está realmente perguntando?
Travis Northcutt
Para maior clareza, você deseja definir um novo tipo de postagem personalizado que use a estrutura de link permanente de /% postname% /? Você planeja que as postagens também usem essa mesma estrutura permanente ou elas terão um prefixo?
prettyboymp
Depois disso, para ver se alguém aparece com uma resposta. Eu tentei as abordagens acima também, juntamente com a simples configuração do slug de reescrita para '/', o que também interrompe os links permanentes da página. Le suspiro ...

Respostas:

2

Isso não é fácil no WP 3.3, a menos que você engane as regras de reescrita para estar no local correto e faça com que o wp_rewrite pense que regras detalhadas estão sendo usadas no front-end. A turma abaixo funciona.

class Test_Post_Type {
    const POST_TYPE = 'test';

    public static function init() {
        global $wp_rewrite;

        $post_type_obj = register_post_type( self::POST_TYPE, array(
            'labels' => array(
                'name' => __( 'Tests' ),
                'singular_name' => __( 'Test' ),
                'add_new' => __( 'Add New' ),
                'add_new_item' => __( 'Add New Test' ),
                'edit_item' => __( 'Edit Test' ),
                'new_item' => __( 'New Test' ),
                'all_items' => __( 'All Tests' ),
                'view_item' => __( 'View Test' ),
                'search_items' => __( 'Search Tests' ),
                'not_found' => __( 'No Tests found' ),
                'not_found_in_trash' => __( 'No Tests found in Trash' ),
                'menu_name' => __( 'Tests' )
            ),
            'publicly_queryable' => true,
            'exclude_from_search' => true,
            'hierarchical' => false,
            'public' => true,
            'rewrite' => false,
            'has_archive' => true,
            'supports' => array( 'title', 'editor', 'thumbnail', 'test_source' ),
            'taxonomies' => array( 'category', 'post_tag' ),
        ) );

        $post_type_obj = get_post_type_object(self::POST_TYPE);

        //register the rewrite tag for permalink building
        $wp_rewrite->add_rewrite_tag( '%' . $post_type_obj->query_var . '%', '([^/]+)', $post_type_obj->query_var . '=' );

        //we have to add the permastruct here in order to build the permalink, otherwise we'll need to filter the post_type link
        add_permastruct(self::POST_TYPE, '%' . $post_type_obj->query_var . '%/', false );

        //add a filter to remove the permastructs generated above
        add_filter(self::POST_TYPE . '_rewrite_rules', array(__CLASS__, '_remove_default_rules')); 

        //now we add a filter to put the generated rewrite rules in the correct spot
        add_action('generate_rewrite_rules', array(__CLASS__, '_filter_rewrite_rules'));

        if(!is_admin()) {
            //we need verbose_page_rules to be on on the front end in order for pages to be process properly
            $wp_rewrite->use_verbose_page_rules = true;
        }
    }

    /**
     * Filter to remove the rules for this post type when they're automatically generated due to the permastruct registration
     * @param type $rules
     * @return type 
     */
    public static function _remove_default_rules($rules) {
        return array();
    }

    /**
     * Filters the rules at the end to add back the ones for this post type at the bottom
     * @param WP_Rewrite $wp_rewrite 
     */
    public static function _filter_rewrite_rules($wp_rewrite) {
        $post_type_obj = get_post_type_object(self::POST_TYPE);
        $my_rules = $wp_rewrite->generate_rewrite_rules('%' . $post_type_obj->query_var . '%', EP_NONE);
        $wp_rewrite->rules += $my_rules;
    }

}

add_action( 'init', array( 'Test_Post_Type', 'init' ) );
prettyboymp
fonte
Copiar colou esse código no meu tema, liberou regras de reescrita. Adicionada uma nova postagem, visualizada (a URL está correta), recebida uma 404 ... No WP 3.3.1. Alguma idéia de por que isso não funcionará para mim? (Graças para o código btw!)
Rob Vermeer
EP_NONE -> EP_PERMALINK para que as páginas de comentários funcionem e, para que vários tipos de postagem funcionem com /% postname% /, você também deve usar o filtro parse_query. Veja minha resposta acima.
Ciantic
Rob, você adicionou uma nova postagem ou adicionou uma nova 'teste'? Isso não ficou claro na pergunta original sobre se as postagens também precisam ter a estrutura permanente de /% post_name% /. Se for esse o caso, por que criar um novo tipo de postagem? Além disso, você terá problemas em potencial com conflitos de nome se mais de um tipo de postagem tiver a mesma estrutura permanente.
prettyboymp
1

Chaves do carro santo!

Eu acho que isso funciona . Quase funciona, é super simples, apenas uma linha:

global $wp_rewrite;
$args = array(
    'public' => true,
    'publicly_queryable' => true,
    'show_ui' => true,
    'show_in_menu' => true,
    'query_var' => true,
    'rewrite' => array('slug' => 'anything'),
    'capability_type' => 'post',
    'has_archive' => true,
    'hierarchical' => false,
    'menu_position' => null,
    'supports' => array('title','editor','thumbnail')
);
register_post_type('my_custom_post_type', $args);

$wp_rewrite->add_permastruct('my_custom_post_type', "%my_custom_post_type%");

PS Se você tentar fazer isso em casa, depois de adicionar esta linha, vá para "Configurações" -> "Links permanentes" e Salvar alterações, atualizando os links permanentes.

Eu estava lendo o register_post_type()código fonte do WP e encontrei uma linha:

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

Escusado será dizer que, sem lesmas, concluí que deveria funcionar, e funcionou . Até a edição permalink abaixo do título no editor funciona corretamente!

Atualização: Isso interrompe os permalinks da página, de volta à prancheta ...

Ciantic
fonte
Eu também tentei este, com resultado semelhante. Seria muito legal se isso funcionasse. Talvez alguém com uma ideia?
Rob Vermeer
@RobVermeer Percebeu que sem a linha (com apenas uma lesma padrão), o WordPress já é capaz de redirecionar para o URL. Por exemplo, "some-post" redireciona para "qualquer coisa / some-post". No codespeak, em algum lugar do código há um suporte para CPTs sem slug, apenas o padrão é redirecionar. face palm
Ciantic
1

A resposta prettyboymp é quase a mesma que recebi ontem, mas não estou feliz com isso. A resposta de prettyboymp tem uma falha, não funciona quando /% postname% / está sendo usado simultaneamente em vários tipos de postagem.

Aqui está a minha resposta, que também analisa a estrutura atual e cria uma variedade de tipos de post para recorrer. No entanto, existe uma falha nisso, se dois tipos de postagens tiverem a mesma lesma e ambos forem /% postname% /, será exibido ambos.

class MyCustomPostType {
    /**
     * Register post type
     **/
    public static function register_post_type() {
        global $wp_rewrite;

        $args = array(
            'public' => true,
            'publicly_queryable' => true,
            'show_ui' => true,
            'show_in_menu' => true,
            'query_var' => true,
            'rewrite' => false,
            'capability_type' => 'post',
            'has_archive' => true,
            'hierarchical' => false,
            'menu_position' => null,
            'supports' => array('title','editor','thumbnail')
        );

        register_post_type('my_custom_post_type', $args);

        // Enables the pages to work simultaneously
        $wp_rewrite->use_verbose_page_rules = true;
        add_filter("rewrite_rules_array", array(__CLASS__, 'rewrite_rules_array'));
        add_action("parse_query", array(__CLASS__, 'parse_query'));
        add_filter("post_type_link", array(__CLASS__, 'post_type_link'), 1, 4);
    }

    public static function post_type_link($link, $post, $leavename=false, $sample=false) {
        if ($sample && ($begin = strpos($link, "?my_custom_post_type=")) !== false) {
            return substr($link, 0, $begin-1) . "/%my_custom_post_type%/";
        }
        return str_replace("?my_custom_post_type=", "", $link) . "/";
    }

    public static function parse_query($query) {
        global $wp, $wp_rewrite;

        // Is this query for /%post_name%/? Is it main request query?
        if (isset($query->query['name'])
            && substr($wp->matched_rule, 0, 7) == "([^/]+)"
            && isset($query->query)
            && isset($wp->query_vars)
            && $query->query == $wp->query_vars)
        {
            //echo '<p><h1>hit!</h1></p>';
            if (!($post_types = get_query_var("post_type"))) {
                if ($wp_rewrite->permalink_structure == "/%postname%/")
                    $post_types = array("post");
                else
                    $post_types = array();
            }

            if (is_array($post_types))
                $post_types[] = "my_custom_post_type";

            set_query_var("post_type", $post_types);
            //set_query_var("posts_per_page", 1);
        }
    }

    public static function rewrite_rules_array($array) {
        global $wp_rewrite;
        // Same rules as in /%post_name%/
        return array_merge($array, $wp_rewrite->generate_rewrite_rules("/%postname%/", EP_PERMALINK));
    }
}


add_action('init', array("MyCustomPostType", "register_post_type"));
Ciantic
fonte
É possível que certos tipos de postagem sejam hierárquicos. Eu tentei eu mesmo, mas nada parece funcionar ... Acha que o post é um anexo com pai / filho / ... E se eu fizer pai / filho / neto / ele recebe um 404.
Rob Vermeer
1

Criei uma solução e não consegui encontrar um problema com ela. Por favor, tente e me diga se você encontrar um problema

add_action('init', 'firmasite_resimlitarif_cpt', 0);
function firmasite_resimlitarif_cpt() 
{

// Yemek Tarifi

  $args = array(
    'public' => true,
    'show_in_menu' => true, 
    'permalink_epmask' => EP_NONE,
    'rewrite' => array('slug'=>'/','with_front'=>false),
    'has_archive' => false,
    'supports' => array('title','editor','thumbnail')
  ); 
  register_post_type('yemek',$args);

}


// http://wordpress.stackexchange.com/questions/37650/wordpress-3-3-custom-post-type-with-postname-permastruct
add_action("parse_query", 'firmasite_resimlitarif_parse_query');
function firmasite_resimlitarif_parse_query($query) {
    global $wp, $wp_rewrite;


    // Is this query for /%post_name%/? Is it main request query?
    if (isset($query->query['name'])
        && substr($wp->matched_rule, 0, 7) == "([^/]+)"
        && isset($query->query)
        && isset($wp->query_vars)
        && $query->query == $wp->query_vars)
    {
        if (!($post_types = get_query_var("post_type"))) {
            if ($wp_rewrite->permalink_structure == "/%postname%/")
                $post_types = array("post");
            else
                $post_types = array();
        }

        if (is_array($post_types)){ 
            $post_types[] = 'yemek';
            $post_types[] = 'page';
        }


        set_query_var("post_type", $post_types);
    } 
}

Mude 'yemek' com o nome do seu tipo de postagem.

Ünsal Korkmaz
fonte
0

A resposta mais limpa que eu poderia ter encontrado para isso (estou criando um plug-in que realmente precisa de um tipo de postagem personalizado sem nenhuma lesma à frente) é usar um modelo de página personalizado em vez de usar um tipo de postagem personalizado.

Ao fazer isso, seu "tipo de postagem personalizado" pode ter URLs como / o que for, sem ter que se preocupar em entrar na página ou publicar permalinks.

Para fazer isso, acabei fazendo o seguinte:

  • Adicionando um modelo de página personalizado dentro do meu plugin
  • Configurando o modelo da página para que ele possa ser selecionado no editor de páginas
  • Criando meta boxes personalizados que aparecem apenas no meu modelo de página

Isso me permitiu:

Os lados baixos

É claro que, embora isso não atrapalhe os links da página ou publique, ele tem algumas desvantagens óbvias.

Sem arquivo Você não terá um arquivo (se desejar), mas isso pode ser resolvido criando outro modelo de página para desenhar um arquivo de todas as páginas usando seu modelo personalizado.

Gerenciado em páginas Você não recebe a boa navegação à esquerda no administrador que agrupa todo o tipo de postagem.

Isso pode ser parcialmente resolvido adicionando um filtro à lista de páginas (para permitir que você filtre pelo modelo de página que está sendo usado), mostrando qualquer modelo de página usado em uma nova coluna etc.


Dito isto, eu queria algo que não fizesse com que os usuários se perguntassem por que eles criaram uma nova página personalizada e descobriram que não podiam mais acessar páginas normais ou a nova página personalizada fez com que uma página existente em seu site desaparecesse.

Sei que não é uma solução real , mas é uma alternativa que funcionou muito bem para minhas necessidades.

Corsário
fonte