¿Tipo de publicación personalizada de Wordpress 3.3 con /% postname% / permastruct?

9

Hay una publicación anterior con un título similar, pero no se ve en WordPress 3.3, y eso es importante ya que 3.3 anuncia de manera interesante: "Use la estructura de enlace permanente de nombre de correo sin penalización de rendimiento"

El problema con Wordpress 3.2 y versiones anteriores era que primero buscaba los nombres de las páginas y luego 404. Primero no verificaba los tipos de publicaciones arbitrarias. 3.3, por otro lado, debe buscar tipos de publicaciones, luego páginas y finalmente 404 (ya que anuncia esta característica). Esto implica que los tipos de publicaciones personalizadas sin slug deberían ser simples , si no codificaron en post_type=postalguna parte.

Sin embargo, todavía no puedo encontrar una solución específica 3.3.

Pregunta : ¿Cómo puedo definir la estructura de enlace permanente "/% postname% /" para cualquier tipo de publicación personalizada "xyz"?

Gracias.

Ciatico
fuente
No veo una pregunta, ¿qué estás preguntando realmente?
Travis Northcutt
Para mayor claridad, desea definir un nuevo tipo de publicación personalizada que utilice la estructura de enlace permanente de /% postname% /? ¿Estás planeando que las publicaciones también usen esta misma estructura o tendrán un prefijo?
prettyboymp
Después de esto para ver si a alguien se le ocurre una respuesta. También probé los enfoques anteriores junto con simplemente establecer la babosa de reescritura en '/' que también rompe los enlaces permanentes de la página. Le

Respuestas:

2

Esto no se hace fácilmente en WP 3.3 a menos que engañe a las reglas de reescritura para que estén en el lugar correcto y haga que wp_rewrite piense que se están utilizando reglas detalladas en el front end. La clase de abajo 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
fuente
Copia pegó este código en mi tema, reglas de reescritura enrojecidas. Se agregó una nueva publicación, se visualizó la publicación (la URL es correcta), se obtuvo un 404 ... En WP 3.3.1. ¿Alguna idea de por qué esto no funcionará para mí? (¡Gracias por el código por cierto!)
Rob Vermeer
EP_NONE -> EP_PERMALINK para que las páginas de comentarios funcionen, y luego para que varios tipos de publicaciones funcionen con /% postname% / también debe usar el filtro parse_query. Vea mi respuesta arriba.
Ciantic
Rob, ¿agregaste una nueva publicación o agregaste una nueva publicación de 'prueba'? Esto no estaba claro en la pregunta original de si las publicaciones también debían tener la permastructura de /% post_name% /. Si ese es el caso, ¿por qué incluso crear un nuevo tipo de publicación? Además, tendrá posibles problemas con los conflictos de nombres si más de un tipo de publicación tiene la misma estructura.
prettyboymp
1

¡Llaves santas del auto!

Creo que esto funciona . Casi funciona, es súper simple, solo una línea:

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

PD: Si prueba esto en casa, después de agregar esta línea Vaya a "Configuración" -> "Enlaces permanentes" y Guardar cambios, se actualizan los enlaces permanentes.

Estaba leyendo el register_post_type()código fuente de WP y encontré una línea:

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

No hace falta decirlo, pero sin babosa concluí que debería funcionar, y lo hizo . ¡Incluso la edición de enlace permanente debajo del título en el editor funciona correctamente!

Actualización: Esto rompe los enlaces permanentes de la página, de vuelta al tablero de dibujo ...

Ciatico
fuente
También probé este, con un resultado similar. Sería genial si esto funcionara. Tal vez alguien más con una idea?
Rob Vermeer el
@RobVermeer Notó que sin la línea (con solo slug predeterminado), WordPress ya es capaz de redirigir a la url. Por ejemplo, "alguna publicación" redirige a "cualquier cosa / alguna publicación". En codepeak, en algún lugar del código hay un soporte para CPT sin slug, solo se predetermina la redirección. cara palma
Ciantic
1

La respuesta de prettyboymp es casi la misma que recibí ayer, pero no estoy contento con eso. La respuesta de prettyboymp tiene un defecto, no funciona cuando /% postname% / se usa simultáneamente en múltiples tipos de publicaciones.

Aquí está mi respuesta, que también analiza la estructura actual y crea una variedad de tipos de publicaciones para respaldar. Sin embargo, también hay una falla en esto, si dos tipos de publicaciones tienen la misma babosa y ambas son /% postname% /, entonces muestra ambas.

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"));
Ciatico
fuente
¿Es posible que ciertos post-tipos se vuelvan jerárquicos? Lo intenté yo mismo, pero nada parece funcionar ... Piensa que la publicación es un archivo adjunto con padre / hijo / ... Y si lo hago padre / hijo / nieto / obtiene un 404.
Rob Vermeer
1

Creé una solución y no pude encontrar un problema con ella. Intenta decirme si encuentras un 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);
    } 
}

Cambie 'yemek' con su nombre de tipo de publicación.

Ünsal Korkmaz
fuente
0

La respuesta más clara que se me ocurre para esto (estoy construyendo un complemento que realmente necesita un tipo de publicación personalizado sin ningún slug inicial) es usar una plantilla de página personalizada en lugar de usar un tipo de publicación personalizado.

Al hacer esto, su "tipo de publicación personalizada" puede tener URL como / lo que sea, sin tener que preocuparse de pisar la página o publicar enlaces permanentes.

Para hacer esto, terminé haciendo lo siguiente:

  • Agregar una plantilla de página personalizada dentro de mi complemento
  • Configurar la plantilla de página para que pueda seleccionarse en el editor de página
  • Crear meta cuadros personalizados que solo se muestran para mi plantilla de página

Esto me permitió:

Los lados bajos

Por supuesto, si bien esto no pisotea la página o publica enlaces, tiene un par de desventajas obvias.

Sin archivo No tendrá un archivo (si lo desea), aunque eso se puede resolver creando otra plantilla de página para dibujar un archivo de todas las páginas usando su plantilla personalizada.

Administrado en páginas No obtienes la agradable navegación de la izquierda en el administrador que agrupa todo el tipo de publicación.

Esto podría resolverse parcialmente agregando un filtro a la lista de páginas (para permitirle filtrar por la plantilla de página utilizada), mostrando cualquier plantilla de página utilizada en una nueva columna, etc.


Dicho esto, quería algo que no hiciera que los usuarios se preguntaran por qué crearon una nueva página personalizada y descubrieron que ya no podían llegar a las páginas normales o que la nueva página personalizada hacía que desapareciera una página existente en su sitio.

Sé que no es una solución real , pero es una alternativa que funcionó muy bien para mis necesidades.

Corsario
fuente