SilverStripe 3.1+ 使用 PHP 动态更改重定向器的 URL slug

SilverStripe 3.1+ Using PHP to dynamically change the URL slug of a Redirector

这是我原来问题的延伸

我有一个产品页面URL a) www.mysite.com/category/subcat/productid 您可以通过单独的重定向器页面访问此页面 b) www.mysite.com/productid

页面 'a' 包含可以通过以下方式访问的选项卡 c) www.mysite.com/category/subcat/productid/tabid

我想使用 PHP 为每个创建的产品页面动态创建 links / 重定向器,以便可以访问:

1) 仅使用其 'b' 中显示的 'predicted' 的简短 URL(我可以通过创建页面重定向器来做到这一点,但这对于大量产品来说是冗长的. 2) 也为每个选项卡 link 创建一个短 URL,因此 'c' 将从以下位置重定向:d) www.mysite.com/productid/tabid

'tabid' 可以硬编码,在我的例子中是:音频、视频、图片、固件

目前正在使用我的 ProductPage.php

中的代码
class ProductPage_Controller extends Page_Controller {


private static $allowed_actions = array(

    'audio',
    'pictures',
    'firmware',
    'videos',
);


public function audio() {
    $this->redirect($this->Link().'?tab=audio');
}
public function pictures() {
    $this->redirect($this->Link().'?tab=pictures');
}
public function firmware() {
    $this->redirect($this->Link().'?tab=firmware');
}
public function videos() {
     $this->redirect($this->Link().'?tab=videos');
}

允许我从 /video 转到 /?tab=video 但这当然不会缩短 URL 这是我想要的最终结果。 可能这可以在 RedirectorPage.php?

的扩展中完成

因此,如果我要总结一下,您希望 newpage/video 打开正确的页面选项卡,而不是呈现不同页面的操作?

您可以使用 private static $url_handlers 做一些有趣的事情来设置您可以通过 $request->param('Thing').

查询的参数

或者您可以设置 handleAction 来测试 $action 是否是列表中的其中一个(并设置标志以供以后在例如模板中使用),否则 parent::handleAction.

这个答案不是很充实,但应该能为您提供一些关于调查您自己的用例的方向的想法。

您能走的最短时间是 www.mysite.com/product/productid/tabid。没有 product 部分也可以做到这一点,但这会让你的生活变得更加艰难,因为你将不得不经历很多麻烦才能仍然访问 AdminDev 例如。
如果您想要最短的 URL,您应该创建一个新页面,因为您当前的 ProductPage 是另一个页面的子页面,从您的 URL 可以看出:

www.mysite.com/category/subcat/productid

您可以使用此代码实现最佳场景:

class ProductRedirectPage_Controller extends Page_Controller
{
    private static $allowed_actions = [
        'Product'
    ];

    private static $url_handlers = [
        '$ID/$TabID' => 'Product'
    ];

    public function Product()
    {
        // Get your ProductPage, this should work if there is only one ProductPage
        $page = ProductPage::get()->first();

        if(! $productId = $this->request->param('ID'))
            return $this->redirect($page->Link()); // or send them somewhere else

        $tabId = $this->request->param('TabID');

        $link = $page->Link('yourAction/' . $productId . '/' . $tabId);

        return $this->redirect($link);
    }
}


编辑
使用此代码,当访问 www.mysite.com/product/productid/tabid 时,它会将您重定向到 ProductPage 所在的位置。也许您想将 /$tabId 更改为 ?tabId=' . $tabId,但这完全取决于您。

实现此目的的一种方法是使用 onBeforeHTTPError404 挂钩调用 404 错误并重定向找到的任何产品。

我们创建了一个带有 onBeforeHTTPError404 函数的 ProductRedirectExtension。当找不到页面时将调用此函数,但在系统 returns 出现 404 错误之前。此处的代码将检查 ProductPage 是否与 URLSegment 以及用户 URL 字符串的第一部分一起存在。如果找到 ProductPage,我们将检查用户 URL 字符串的第二部分是否是 tab 关键字之一。之后,用户将被重定向到该页面。

ProductRedirectExtension.php

class ProductRedirectExtension extends Extension {

    public function onBeforeHTTPError404( $request ) {
        $urlSegment = $request->param('URLSegment');
        $action = strtolower($request->param('Action'));
        $page = ProductPage::get()->filter('URLSegment', $urlSegment)->first();

        if ($page) {
            $link = $page->Link();

            if ($action == 'audio' || $action == 'pictures' || $action == 'firmware' || $action == 'videos') {
                $link .= '?tab=' . $action;
            }

            $response = new SS_HTTPResponse();
            $response->redirect($link, 301);

            throw new SS_HTTPResponse_Exception($response);
        }
    }
}

我们使用以下配置设置启用此扩展程序。

config.yml

RequestHandler:
  extensions:
    - ProductRedirectExtension

ContentController:
  extensions:
    - ProductRedirectExtension

ModelAsController:
  extensions:
    - ProductRedirectExtension