如何仅为一个页面添加重写规则?

时间:2016-10-25 作者:Work-Together2013

我只想为某些页面(不是所有页面)添加一个重写,将基本段塞插入永久链接。这是一种独特的情况,我们事先知道所有的页面名称,它们不会改变。

For example:

sitename.com/pagetitle

sitename.com/service/pagetitle

我正在尝试使用“add\\u rewrite\\u rule”,但运气不太好。下面是我的一个迭代,我有很多迭代。如有任何指导,将不胜感激。

我知道有一个插件可以让你将你的文章和页面的永久链接完全更改为你想要的任何内容,但我希望我可以自己通过编程实现。

add_action( \'init\', \'page_change\' );
function page_change()
{
    add_rewrite_rule(
        \'^pagenamehere/?\',
        \'index.php?post_type=service\',
        \'top\' );
}

Updated code below:

function new_rewrite_rule()
{
    add_rewrite_rule(\'^services/statictitle$\', \'index.php?pagename=oldname\', \'top\');
}
add_action(\'init\', \'new_rewrite_rule\');
因此,此代码允许在“services/statictitle”上访问该链接但是,旧链接仍然可以访问。因此,我不确定我是否会以正确的方式进行。。。。。任何帮助都将不胜感激。

谢谢

Update

这里有一种我认为可能更合适的替代方法。尽管如此,这是针对所有页面的。有没有一种方法可以只针对pagename或id?

function custom_page_rules() {
  global $wp_rewrite;
  $wp_rewrite->page_structure = $wp_rewrite->root . \'services/%pagename%\'; 
}

6 个回复
SO网友:cowgill

Asumption: 您使用Apache作为web服务器。

如果您已经知道了页面段塞,并且它们不会更改,只需将它们添加到您的.htaccess 文件它会更快、更简单。

粘贴以下内容Redirect 在您的.htaccess 文件

Redirect 301 /pagetitle/ /service/pagetitle/
Redirect 301 /pagetitle2/ /another-dir/pagetitle2/


# BEGIN WordPress
<IfModule mod_rewrite.c>
....

SO网友:Syed Fakhar Abbas

请查看以下代码:

add_rewrite_rule( \'services/([^/]*)/?\',\'index.php?post_type=\'.$post_type.\'&name=$matches[1]\',\'top\');
为了更好地理解重写API,请检查WP_REWRITE_APIBuilding Customized URLs in WordPress

等待您的反馈!

希望它对你有用!

SO网友:jgraup

这种方法可能更灵活一些。

$basePageRewrite->add_rule( \'service\', \'page-title\' );
在类定义的末尾,您应该能够添加basepage. 将为您添加的规则动态构建URL重写。如果apage 直接调用is将重定向到$base/$pageTitle.

<?php

if ( ! class_exists( \'BasePageRewrite\' ) ):

    class BasePageRewrite {

        const ENDPOINT_QUERY_PARAM_REDIRECT = \'____base_page_rewrite__redirect\';

        private static $_hash_map = array ();

        /**
         * BasePageRewrite constructor.
         */
        public function __construct() {
            add_filter( \'query_vars\', array ( $this, \'add_query_vars\' ), 0 );
            add_action( \'parse_request\', array ( $this, \'sniff_requests\' ), 0 );
            add_action( \'init\', array ( $this, \'add_endpoint\' ), 0 );
        }

        /**
         * Add rewrite rules here.
         *
         * @param string $base Base of URL
         * @param string $page Slug of page
         */
        public function add_rule( $base, $page ) {
            if ( ! array_key_exists( $base, static::$_hash_map ) ) {
                static::$_hash_map[ $base ] = array ();
            }

            if ( ! array_key_exists( $page, static::$_hash_map[ $base ] ) ) {
                static::$_hash_map[ $base ][ $page ] = \'name\';
            }
        }

        /**
         * Add our custom query arg to check in `parse_request`.
         *
         * @param $vars
         *
         * @return array
         */
        public function add_query_vars( $vars ) {
            $vars[] = static::ENDPOINT_QUERY_PARAM_REDIRECT;

            return $vars;
        }

        /**
         * Add rewrite rules.
         *
         *      page --> base/page
         *
         *      base/page === page
         *
         * Note:
         *
         *      `flush_rewrite_rules()` is only added for testing.
         */
        public function add_endpoint() {

            foreach ( static::$_hash_map as $base => $pages ) {

                foreach ( $pages as $pageName => $param ) {

                    // page --> service/page

                    add_rewrite_rule( "^$pageName/", \'index.php?\' . static::ENDPOINT_QUERY_PARAM_REDIRECT . "=/$base/$pageName/", \'top\' );

                    // service/page === page

                    add_rewrite_rule( "^$base/$pageName/", "index.php?$param=$pageName", \'top\' );
                }
            }

            //////////////////////////////////
            flush_rewrite_rules( true );  //// <---------- REMOVE THIS WHEN DONE TESTING
            //////////////////////////////////
        }

        /**
         * Redirect regular page to base/page,
         *
         * @param $wp_query
         */
        public function sniff_requests( $wp_query ) {

            global $wp;

            if ( isset( $wp->query_vars[ static::ENDPOINT_QUERY_PARAM_REDIRECT ] ) ) {

                // page --> service/page

                $redirect = $wp->query_vars[ static::ENDPOINT_QUERY_PARAM_REDIRECT ];
                $new_url  = site_url( $redirect );
                wp_redirect( $new_url, 301 );
                die();
            }
        }
    }

    // Create the class
    $basePageRewrite = new BasePageRewrite();

    // Add individual rules
    $basePageRewrite->add_rule( \'service\', \'page-title\' );
    $basePageRewrite->add_rule( \'another-service\', \'another-page-title\' );

endif; // BasePageRewrite

SO网友:Mark Kaplun

这里需要做的另一部分是,使用page_link 过滤器或the_permalink 滤器

这是你自己的镜像问题-https://stackoverflow.com/questions/27432586/wordpress-page-link-filter

这将执行重定向,因为当访问的url与规范url不同时,wordpress会重定向到规范地址,并且帖子和页面的规范url是它们的永久链接。作为额外的奖励,您可以将其他所有内容都指向正确的URL,而无需重定向。

SO网友:KnightHawk

我知道你特别要求重写规则,但重定向呢?您可以实现相同的最终结果和相同的用户体验。如果需要,可以更改页面的层次结构,以便

sitename.com/service/pagetitle
可用,并且

sitename.com/pagetitle
是重定向到第一个地址的内容。

这将跳过.htaccess 为了简单起见。看起来你真的想学习如何将其作为重写规则来完成,这很酷,但如果你觉得这很困难,你只想找到一个无论你是否学习都能奏效的解决方案,那么有几个不同的重定向插件可以帮你处理这个问题。我个人最喜欢的标题是“重定向”,它可以处理regex(稍加练习),还可以计算使用重定向规则的次数,以便您可以监视是否需要将其保留在适当的位置。

最后,我在开头提到,您可以更改页面层次结构,以反映您希望URL的外观,如果您还没有这样做,您可能应该这样做。否则,您可能会发现自己处于无限重定向的情况。(如果你选择重定向插件路线,也要记住这一点,因为我已经看到,对于拥有大量重定向的用户,这种情况很容易发生,他们会创建一个与现有重定向冲突的新重定向。)

TLDR: 框外答案。有一个或多个插件可以实现此功能,而无需实际重写。

SO网友:Michael Ecklund

我遇到了一个与你的期望非常相似的情况。

我们有一个父页面“我们的服务”(domain.com/services/) ...

我们还有几个子页面,代表父页面“我们的服务”下提供的每个服务。例如:“Web设计”(domain.com/services/web-design/)

现在,我们还有一个“投资组合”。我们没有在网站上为投资组合专门设置一个完整的顶级部分,而是决定将其放在主要的“服务”部分下面(domain.com/services/).

例如,我们投资组合的主要部分将位于此处:domain.com/services/portfolio/

公文包是它自己的自定义帖子类型,包含各个公文包项目。

因此,特定公文包项目的URL如下所示:domain.com/services/portfolio/sample-portfolio-item/.

注册自定义帖子类型时,有一个可配置的参数rewrite[\'slug\']. 这是您要指定的位置$args[\'rewrite\'][\'slug\'] = \'services/portfolio\';

当然,无论何时更改URL重写规则,都需要刷新重写规则。以编程方式使用flush_rewrite_rules(); 对于快速测试,您可以随时导航到Dashboard -> Settings -> Permalinks 因为这会自动为您刷新重写规则,只需访问该管理页面即可。

希望您(或某人)发现我的答案中的信息有用且相关。