add_rewrite_endpoint () не работает для пользовательских архивов типа записей

Я работаю над некоторыми системами wiki / encyclopedia, основанными на wordpress.

существует два пользовательских типа сообщений. я покажу свою конфигурацию для одного из них:

$labels = array( 'name' => _x('Objects', 'post type general name'), 'singular_name' => _x('Object', 'post type singular name'), 'add_new' => _x('Add New', 'object'), 'add_new_item' => __('Add New Object'), 'edit_item' => __('Edit Object'), 'new_item' => __('New Object'), 'view_item' => __('View Object'), 'search_items' => __('Search Objects'), 'not_found' => __('Nothing found'), 'not_found_in_trash' => __('Nothing found in Trash'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'has_archive' => 'objects', // this is the archive-slug (could be "objects/index"!!) 'rewrite' => array( 'slug' => 'objects' ), // this is the prepended slug (like "objects/my-object") 'capability_type' => 'post', 'hierarchical' => false, 'menu_position' => null, 'supports' => array('title','thumbnail') ); register_post_type( 'dr_object' , $args ); 

все работает так, как ожидалось: mysite.de/objects дает мне обзор (archive-dr_object.php template), mysite.de/objects/my-object показывает детали объекта.

чтобы иметь некоторые хорошие URL-адреса для функций редактирования интерфейса, я добавил переписывающие конечные точки.

 add_rewrite_endpoint('do', EP_PERMALINK | EP_PAGES ); // for do/edit, do/remove, etc 

это отлично подходит для URL-адресов, таких как mysite.de/objects/my-object/do/edit

вот моя проблема:

в архивах также должны быть некоторые возможности редактирования. но mysite.de/objects/do/edit дает мне 404: «Страница не найдена».

i print_r'ed $ wp_query и похоже, что wp запрашивает вложение с именем "edit"

надеюсь кто-нибудь может мне помочь – к настоящему времени я буду придерживаться уродливого? do = редактировать URL-адреса для архивов.

заранее спасибо, hans

// обновление 09/03/2012

удаленный код my-plugin.php

 add_action('init', 'object_register'); function object_register() { $labels = array( 'name' => _x('Objects', 'post type general name'), 'singular_name' => _x('Object', 'post type singular name'), 'add_new' => _x('Add New', 'object'), 'add_new_item' => __('Add New Object'), 'edit_item' => __('Edit Object'), 'new_item' => __('New Object'), 'view_item' => __('View Object'), 'search_items' => __('Search Objects'), 'not_found' => __('Nothing found'), 'not_found_in_trash' => __('Nothing found in Trash'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'has_archive' => 'objects', // this is the archive-slug (could be "objects/index"!!) 'rewrite' => array( 'slug' => 'objects' ), // this is the prepended slug (like "objects/my-object") 'capability_type' => 'post', 'hierarchical' => false, 'menu_position' => null, 'supports' => array('title','thumbnail') ); register_post_type( 'dr_object' , $args ); } add_action('init', 'cluster_register'); function cluster_register() { $labels = array( 'name' => _x('Cluster', 'post type general name'), 'singular_name' => _x('Cluster', 'post type singular name'), 'add_new' => _x('Add New', 'cluster'), 'add_new_item' => __('Add New Cluster'), 'edit_item' => __('Edit Cluster'), 'new_item' => __('New Cluster'), 'view_item' => __('View Cluster'), 'search_items' => __('Search Cluster'), 'not_found' => __('Nothing found'), 'not_found_in_trash' => __('Nothing found in Trash'), 'parent_item_colon' => '' ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'query_var' => true, 'has_archive' => true, 'rewrite' => array( 'slug' => 'cluster' ), 'capability_type' => 'post', 'hierarchical' => false, 'menu_position' => null, 'supports' => array('title') ); register_post_type( 'dr_cluster' , $args ); } add_action( 'init', 'build_taxonomies', 0 ); function build_taxonomies() { register_taxonomy( 'dr_designers', array("dr_object"), array("hierarchical" => false, "label" => "Designers", "singular_label" => "Designer", "rewrite" => array('slug' => 'designer'))); register_taxonomy( 'dr_tags', array("dr_object", "dr_cluster"), array("hierarchical" => false, "label" => "Tags", "singular_label" => "Tag", "rewrite" => array('slug' => 'tags'))); register_taxonomy( 'dr_manufactors', array("dr_object"), array("hierarchical" => false, "label" => "Manufactors", "singular_label" => "Manufactor", "rewrite" => array('slug' => 'manufactors'))); } function dr_rewrite_settings(){ // this enables to get action form objects, cluster etc by adding sth like "objects/my-object/do/edit" -- YEAH! add_rewrite_endpoint('do', EP_PERMALINK | EP_PAGES ); // ATTENTION: This is *only* done during plugin activation hook in this example! // You should *NEVER EVER* do this on every page load!! flush_rewrite_rules(); } //register_activation_hook( __FILE__, 'dr_rewrite_settings' ); this should happen add_action('init', dr_rewrite_settings); 

как вы можете видеть – у меня была проблема с правильным переписыванием перезаписи (register_activation_hook).

что я должен упомянуть, что я использую другой плагин для создания fakepage: mysite.de/objects/new, и он выглядит следующим образом:

 <?php /** * Plugin Name: Fake Page Plugin 2 * Plugin URI: http://scott.sherrillmix.com/blog/blogger/creating-a-better-fake-post-with-a-wordpress-plugin/ * Description: Creates a fake page without a 404 error (based on <a href="http://headzoo.com/tutorials/wordpress-creating-a-fake-post-with-a-plugin">Sean Hickey's Fake Plugin Page</a>) * Author: Scott Sherrill-Mix * Author URI: http://scott.sherrillmix.com/blog/ * Version: 1.1 */ class FakePage { /** * The slug for the fake post. This is the URL for your plugin, like: * http://site.com/about-me or http://site.com/?page_id=about-me * @var string */ var $page_slug = 'objects/new'; /** * The title for your fake post. * @var string */ var $page_title = 'New Object'; /** * Allow pings? * @var string */ var $ping_status = 'open'; /** * Class constructor */ function FakePage() { /** * We'll wait til WordPress has looked for posts, and then * check to see if the requested url matches our target. */ add_filter('the_posts',array(&$this,'detectPost')); } /** * Called by the 'detectPost' action */ function createPost() { /** * What we are going to do here, is create a fake post. A post * that doesn't actually exist. We're gonna fill it up with * whatever values you want. The content of the post will be * the output from your plugin. */ /** * Create a fake post. */ $post = new stdClass; /** * The author ID for the post. Usually 1 is the sys admin. Your * plugin can find out the real author ID without any trouble. */ $post->post_author = 1; /** * The safe name for the post. This is the post slug. */ $post->post_name = $this->page_slug; /** * Not sure if this is even important. But gonna fill it up anyway. */ $post->guid = get_bloginfo('wpurl') . '/' . $this->page_slug; /** * The title of the page. */ $post->post_title = $this->page_title; /** * This is the content of the post. This is where the output of * your plugin should go. Just store the output from all your * plugin function calls, and put the output into this var. */ $post->post_content = $this->getContent(); /** * Fake post ID to prevent WP from trying to show comments for * a post that doesn't really exist. */ $post->ID = -1; /** * Static means a page, not a post. */ $post->post_status = 'static'; /** * Turning off comments for the post. */ $post->comment_status = 'closed'; /** * Let people ping the post? Probably doesn't matter since * comments are turned off, so not sure if WP would even * show the pings. */ $post->ping_status = $this->ping_status; $post->comment_count = 0; /** * You can pretty much fill these up with anything you want. The * current date is fine. It's a fake post right? Maybe the date * the plugin was activated? */ $post->post_date = current_time('mysql'); $post->post_date_gmt = current_time('mysql', 1); add_post_meta($post->ID, '_wp_page_template', 'objects-new.php', true); return($post); } function getContent() { return '<p>Hi there! You are viewing my fake post!</p>'; } function detectPost($posts){ global $wp; global $wp_query; /** * Check if the requested page matches our target */ if (strtolower($wp->request) == strtolower($this->page_slug)){ //09.03 removed: || $wp->query_vars['page_id'] == $this->page_slug //Add the fake post $posts=NULL; $posts[]=$this->createPost(); /** * Trick wp_query into thinking this is a page (necessary for wp_title() at least) * Not sure if it's cheating or not to modify global variables in a filter * but it appears to work and the codex doesn't directly say not to. */ $wp_query->is_page = true; //Not sure if this one is necessary but might as well set it like a true page $wp_query->is_singular = true; $wp_query->is_home = false; $wp_query->is_archive = false; $wp_query->is_category = false; //Longer permalink structures may not match the fake post slug and cause a 404 error so we catch the error here unset($wp_query->query["error"]); $wp_query->query_vars["error"]=""; $wp_query->is_404=false; } return $posts; } } /** * Create an instance of our class. */ new FakePage; ?> с <?php /** * Plugin Name: Fake Page Plugin 2 * Plugin URI: http://scott.sherrillmix.com/blog/blogger/creating-a-better-fake-post-with-a-wordpress-plugin/ * Description: Creates a fake page without a 404 error (based on <a href="http://headzoo.com/tutorials/wordpress-creating-a-fake-post-with-a-plugin">Sean Hickey's Fake Plugin Page</a>) * Author: Scott Sherrill-Mix * Author URI: http://scott.sherrillmix.com/blog/ * Version: 1.1 */ class FakePage { /** * The slug for the fake post. This is the URL for your plugin, like: * http://site.com/about-me or http://site.com/?page_id=about-me * @var string */ var $page_slug = 'objects/new'; /** * The title for your fake post. * @var string */ var $page_title = 'New Object'; /** * Allow pings? * @var string */ var $ping_status = 'open'; /** * Class constructor */ function FakePage() { /** * We'll wait til WordPress has looked for posts, and then * check to see if the requested url matches our target. */ add_filter('the_posts',array(&$this,'detectPost')); } /** * Called by the 'detectPost' action */ function createPost() { /** * What we are going to do here, is create a fake post. A post * that doesn't actually exist. We're gonna fill it up with * whatever values you want. The content of the post will be * the output from your plugin. */ /** * Create a fake post. */ $post = new stdClass; /** * The author ID for the post. Usually 1 is the sys admin. Your * plugin can find out the real author ID without any trouble. */ $post->post_author = 1; /** * The safe name for the post. This is the post slug. */ $post->post_name = $this->page_slug; /** * Not sure if this is even important. But gonna fill it up anyway. */ $post->guid = get_bloginfo('wpurl') . '/' . $this->page_slug; /** * The title of the page. */ $post->post_title = $this->page_title; /** * This is the content of the post. This is where the output of * your plugin should go. Just store the output from all your * plugin function calls, and put the output into this var. */ $post->post_content = $this->getContent(); /** * Fake post ID to prevent WP from trying to show comments for * a post that doesn't really exist. */ $post->ID = -1; /** * Static means a page, not a post. */ $post->post_status = 'static'; /** * Turning off comments for the post. */ $post->comment_status = 'closed'; /** * Let people ping the post? Probably doesn't matter since * comments are turned off, so not sure if WP would even * show the pings. */ $post->ping_status = $this->ping_status; $post->comment_count = 0; /** * You can pretty much fill these up with anything you want. The * current date is fine. It's a fake post right? Maybe the date * the plugin was activated? */ $post->post_date = current_time('mysql'); $post->post_date_gmt = current_time('mysql', 1); add_post_meta($post->ID, '_wp_page_template', 'objects-new.php', true); return($post); } function getContent() { return '<p>Hi there! You are viewing my fake post!</p>'; } function detectPost($posts){ global $wp; global $wp_query; /** * Check if the requested page matches our target */ if (strtolower($wp->request) == strtolower($this->page_slug)){ //09.03 removed: || $wp->query_vars['page_id'] == $this->page_slug //Add the fake post $posts=NULL; $posts[]=$this->createPost(); /** * Trick wp_query into thinking this is a page (necessary for wp_title() at least) * Not sure if it's cheating or not to modify global variables in a filter * but it appears to work and the codex doesn't directly say not to. */ $wp_query->is_page = true; //Not sure if this one is necessary but might as well set it like a true page $wp_query->is_singular = true; $wp_query->is_home = false; $wp_query->is_archive = false; $wp_query->is_category = false; //Longer permalink structures may not match the fake post slug and cause a 404 error so we catch the error here unset($wp_query->query["error"]); $wp_query->query_vars["error"]=""; $wp_query->is_404=false; } return $posts; } } /** * Create an instance of our class. */ new FakePage; ?> 

Я сделал две модификации стандартного плагина. возможно, они вмешиваются в rewrite_rules? (я попытался отключить этот плагин – ничего не изменил)

1) с использованием «иерархической» пули. он работает, но: разрешено? 2) пусть поддельная страница использует настраиваемый шаблон: add_post_meta($post->ID, '_wp_page_template', 'objects-new.php', true); (прямо перед возвратом сообщения в createPost() )