Wordpress 3.3 користувацького типу публікації з /% прізвищем% / permastruct?


9

Існує попередня публікація з подібною назвою, але вона не стосується WordPress 3.3, і це важливо, оскільки 3.3 цікаво рекламує: "Використовуйте структуру постійної посилання на ім'я без покарання за ефективність"

Проблема з Wordpress 3.2 і раніше полягала в тому, що спочатку вони переглядали назви сторінок, а потім 404. Він спочатку не перевіряв довільні типи публікацій. 3.3, з іншого боку, повинні виглядати типи публікацій, потім сторінки та нарешті 404 (як це рекламує ця функція). Це означає, що користувацькі типи публікацій без слизи повинні бути простими , якщо вони post_type=postдесь не мають жорсткого коду .

Я не можу знайти 3.3 конкретного рішення.

Питання : Як я можу визначити структуру постійної посилання "/% прізвище% /" для будь-якого заданого типу "xyz"?

Дякую.


Я не бачу питання - що ви насправді запитуєте?
Травіс Нортчетт

Для наочності ви хочете визначити новий спеціальний тип публікації, який використовує структуру постійної посилання /% імені% /? Чи плануєте ви, щоб публікації також використовували ту саму пермаструктуру, чи вони матимуть префікс?
prettyboymp

Слідом за цим, щоб побачити, чи хтось придумає відповідь. Я також спробував вищезазначені підходи, а також просто встановив перезаписуючу слизьку на '/', що також порушує постійні посилання на сторінку. Le sigh ...

Відповіді:


2

Це не легко зробити в WP 3.3, якщо ви не обдурите правила переписування, щоб вони були в потрібному місці, і не змусили wp_rewrite думати, що правила переказування використовуються на передньому кінці. Клас нижче працює.

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

Копія вставив цей код у мене тему, розмив правила переписування. Додано нове повідомлення, переглянув публікацію (URL-адреса правильна), отримав 404 ... На WP 3.3.1. Будь-яка ідея, чому це не допоможе мені? (Дякую за код btw!)
Роб Вермер

EP_NONE -> EP_PERMALINK для роботи сторінок коментарів, а потім для отримання декількох типів публікацій, що працюють з /% іменем% / / ви також повинні використовувати фільтр parse_query. Дивіться мою відповідь вище.
Сіантік

Роб, ти додав нову публікацію чи додав новий "тестовий" пост? У первісному питанні це було не ясно, чи потрібно публікацій також мати пермаструктуру /% post_name% /. Якщо це так, чому навіть створити новий тип публікації? Крім того, у вас виникнуть потенційні проблеми з конфліктом імен, якщо більше одного типу публікацій має однакову пермаструктуру.
prettyboymp

1

Святі ключі від машини!

Я думаю, це працює . Це майже працює, це дуже просто, лише один рядок:

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 Якщо ви спробуєте це в домашніх умовах, додавши цей один рядок, перейдіть до "Налаштування" -> "Постійні посилання" та Збережіть зміни, це оновить постійні посилання.

Я читав register_post_type()вихідний код WP і знайшов рядок:

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

Потрібно сказати, але без слизу я зробив висновок, що він повинен працювати, і це було . Навіть редагування постійної посилання під заголовком у редакторі працює правильно!

Оновлення: це перерва на сторінку посилання, повернення до таблиці малювання ...


Я також спробував цей, з подібним результатом. Було б дуже круто, якщо це спрацює. Можливо, ще хтось із ідеєю?
Роб Вермер

@RobVermeer Зауважив, що без рядка (з просто замовчуванням) WordPress вже здатний перенаправлятись на URL. Наприклад, "деякий пост" переспрямовується на "що-небудь / якийсь пост". У codepeak десь у коді є підтримка CPT без безвізу, вона просто за замовчуванням переспрямовується. обличчя долоні
Ciantic

1

відповідь prettyboymp майже та сама, що я отримав вчора, але я не задоволений цим. Відповідь prettyboymp має один недолік, він не працює, коли /% прізвище% / використовується одночасно на кількох типах публікацій.

Ось моя відповідь, яка також вписується в поточну структуру, і створює масив типів публікацій, на які можна повернутись. У цьому теж є один недолік, якщо два типи публікацій мають однаковий слуг, і обидва є /% прізвище% /, то він показує обидва.

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

Чи можливо, що певні типи стають ієрархічними. Я сам спробував це, але, здається, нічого не виходить ... Думає, що повідомлення є прихильністю до батьків / дитини / ... І якщо я роблю батьків / дитини / онука / це отримує 404.
Роб Вермер

1

Я створив рішення, і я не міг знайти проблему з ним. Будь ласка, спробуйте і скажіть мені, якщо у вас проблема

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

Змініть "yemek", використовуючи назву типу публікації.



0

Найчистіша відповідь, яку я міг би придумати для цього (я створюю плагін, який дійсно потребує користувацького типу публікації без будь-якого провідного слизу), - це використовувати користувальницький шаблон сторінки замість використання спеціального типу публікації.

Роблячи це, у вашому "користувальницькому типі публікації" можуть бути такі URL-адреси, як / що завгодно, не турбуючись про перехід на сторінку чи посилання на повідомлення.

Для цього я зробив наступне:

  • Додавання користувацького шаблону сторінки всередині мого плагіна
  • Налаштування шаблону сторінки таким чином, щоб його можна було вибрати в редакторі сторінки
  • Створення спеціальних метаполев, які відображаються лише для шаблону моєї сторінки

Це дозволило мені:

Нижні сторони

Звичайно, хоча це не переповнює сторінки чи посилання, у нього є кілька очевидних недоліків.

Немає архіву У вас не буде архіву (якщо ви хочете такого), хоча це можна вирішити, створивши інший шаблон сторінки, щоб намалювати архів усіх сторінок за допомогою власного шаблону.

Керується під Сторінками Ви не отримуєте приємної навігації лівою рукою у адміністратора, який об'єднує всі типи публікації разом.

Це може бути частково вирішено, додавши фільтр до списку сторінок (щоб ви могли фільтрувати за використовуваним шаблоном сторінки), показуючи будь-який шаблон сторінки, використаний у новому стовпці тощо.


Попри це, я хотів чогось, що не змусить користувачів замислюватися, чому вони створили нову користувацьку сторінку, і виявив, що вони вже не можуть дійти до звичайних сторінок, або нова спеціальна сторінка призвела до зникнення існуючої сторінки на їхньому сайті.

Я знаю, що це не справжнє рішення, але це альтернатива, яка чудово працювала для моїх потреб.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.