是否在不使用页面的情况下为博客设置自定义子路径?

时间:2012-10-10 作者:aendra

警告:前面的请求相当迂腐

我有一个利用帖子(即博客)和一个名为“howto”的自定义帖子类型的设计。网站首页(“/”)有一个显示最新博客帖子和最新指南的模板。当用户导航到blog部分(“/blog”)时,他们看到的模板与导航到howto部分(“/howto”)时看到的模板不同。

我知道这样做的明显方法是创建两个页面(“博客”和“主页”),然后使用“设置”->“阅读选项”中的下拉菜单显式设置这些页面。然后,我可以将特定的页面模板与这些帖子相关联。

但如果这不是真的很凌乱的话,那就糟了——我会有两个无用的空白页面,将任何管理端的页面列表与其中的实际内容混在一起。您可能会认为有某种方法可以使用模板暗示来防止这种情况的发生:

如何存档如何。php存档。php因此,我想问题是:

How does one set a custom path for posts without creating a new page?

3 个回复
SO网友:Adam

I don\'t have time to explain this in detail (I shall upon return) but in the meantime this should work for you,

Answer updated with explanation as promised.
WP Rewrite rules are like voodoo, I\'m sure there\'s more than one way to go about this, but here\'s mine.

Problem:

Just to clarify your question for others who may stumble upon this thread, what you want to do is create a page without having to physically create an empty-placeholder-page within the administration dashboard found under: Page -> Add New.

Essentially, you want to create a Fake Page and have that page use any template you specify.

Solution:

First we setup our rewrite rules,

add_action(\'init\', \'fake_page_rewrite\');

function fake_page_rewrite(){

    global $wp_rewrite;

    //set up our query variable %fake_page% which equates to index.php?fake_page= 
    add_rewrite_tag( \'%fake_page%\', \'([^&]+)\'); 

    //add rewrite rule that matches /blog/page/2, /blog/page/3, /blog/page/4, etc..
    add_rewrite_rule(\'^blog/page/?([0-9])?\',\'index.php?fake_page=blog&paged=$matches[1]\',\'top\');  

    //add rewrite rule that matches /blog
    add_rewrite_rule(\'^blog/?\',\'index.php?fake_page=blog\',\'top\');

    //add endpoint, in this case \'blog\' to satisfy our rewrite rule /blog, /blog/page/ etc..
    add_rewrite_endpoint( \'blog\', EP_PERMALINK | EP_PAGES );

    //flush rules to get this to work properly
    $wp_rewrite->flush_rules();

}

Within the add_rewrite_tag we specify our query variable in the form of %fake_page%, which by the way you can specify whatever you want or appropriate for your needs. My example fake_page is only symbolic to illustrate the mechanics of this answer.

How the query variable works in this instance is by matching a request for,

http://www.example.com/blog

...which is then internally mapped to,

http://www.example.com/index.php?fake_page=blog

The latter being what you would see when running the default permalink structure.

In a similar fashion requests for,

http://www.example.com/blog/page/2
http://www.example.com/blog/page/3
http://www.example.com/blog/page/4
etc...

...would each map to their equivalents,

http://www.example.com/index.php?fake_page=blog&paged=2
http://www.example.com/index.php?fake_page=blog&paged=3
http://www.example.com/index.php?fake_page=blog&paged=4
etc...

In the example snippet above you will notice that we have the rewrite rule which firsts matches the pagination /blog/page/{page_number}, above our second rule which matches the base for our fake page of /blog.

This is necessary so that the base rule doesn\'t return a match on the first occurrence of our endpoint which is defined as blog before having a chance to evaluate the rest of the requested URL to ensure that the user hadn\'t in fact requested a paged result. Basically, reverse those rules and it doesn\'t work.

As mentioned before, rewrite rules are like voodoo to me so there\'s probably another way to go about the order in which you specify your rules which is possibly related to using the function add_permastruct . If anyone has an alternative, then chime in!

The next function which hooks onto template_redirect checks for the existence of our fake_page within the query variables, if its matched/exists within the array we then request the inclusion of our desired template file to handle the presentation of data.

add_action(\'template_redirect\', \'fake_page_redirect\');

    function fake_page_redirect(){

        global $wp;

        //retrieve the query vars and store as variable $template 
        $template = $wp->query_vars;

        //pass the $template variable into the conditional statement and
        //check if the key \'fake_page\' is one of the query_vars held in the $template array
        //and that \'blog\' is equal to the value of the key which is set
        if ( array_key_exists( \'fake_page\', $template ) && \'blog\' == $template[\'fake_page\'] ) {

            //if the key \'fake_page\' exists and \'blog\' matches the value of that key
            //then return the template specified below to handle presentation
            include( get_template_directory().\'/your-template-name-here.php\' );

            exit;

        }
    }

PS. I have tested this and it works under my conditions, though I\'m not sure if any other quirks may popup with rewrite rules and end point masks the deeper you go, therefore you should thoroughly test all pagination and permalinks and make sure that they resolve to their intended paths correctly . If not, we can address those issues as they arise.

SO网友:Joseph Carrington

制作两个存档页。

档案文件php用于您的博客帖子,并归档howto。php为您的howtos。

http://codex.wordpress.org/images/1/18/Template_Hierarchy.png

制作假页面和重写是一种过分的手段,有些危险。

除非我完全没有抓住要点。

SO网友:gregn3

也许您正在寻找:

<?php

define (\'HOWTO_SLUG\', \'my_howtos\');
define (\'HOWTO_REWRITE_SLUG\', \'howtos\');

register_post_type (HOWTO_SLUG,
    array
    (
        \'labels\' => array
        (
            \'name\' => \'Howtos\'
            , \'singular_name\' => \'Howto\'
        )
        , \'public\' => true
        , \'has_archive\' => true
        , \'rewrite\' => array (\'slug\' => HOWTO_REWRITE_SLUG)
    )
);
这些帖子将显示在WP admin中post_type=my_howtos, 在面向公众的一侧,URL-s将显示为/howtos/, 和文件archive-my_howtos.php 在主题中将用于显示页面。

这个HOWTO_SLUGHOWTO_REWRITE_SLUG 不可能是一样的,否则它会坏的。

结束

相关推荐

pre_get_posts on a page

是否可以使用pre_get_posts 滤器我试过了,但似乎不起作用。function pre_wp_queries( $query ) { // only trigger on main qyery if ( !$query->is_main_query() ) return; if (is_page_template(\'TEMPLATE_NAME.php\')) { $query->