2012-01-03 48 views
3

我的任務是重寫現有的大型網站鏈接目錄。爲了論證的緣故,讓我們假設我們不能做任何會改變鏈接目錄的事情。下面是我們正在使用的鏈接結構的幾個例子:定製鋰路由方案

  1. 商品頁面將是:

    www.domain.com/widgets/some-totally-awesome-large-purple-widget 
    
  2. 一個類別子頁面頁面將是:

    www.domain.com/widgets/purple-widgets 
    
  3. 類別父頁面頁面:

    www.domain.com/widgets/ 
    
  4. 自定義頁面可能是:

    www.domain.com/some-random-page 
    

的各種頁面類型不勝枚舉編寫單獨的路由器。

使用路由器連接::我可以很容易地解釋使用類似的第一和第二方案:

Router::connect('/{:pageroot}/{:pagekey}', 'Pages::index'); 

反過來,網頁::指數方法尋找的「鑰匙」在我們的數據庫中的條目'/ widgets/purple-widgets'。

但是,框架默認爲第三個和第四個頁面的「/ {:controller}/{:action}/{:args}」路線。我知道這是框架的正確行爲。此外,最佳做法是聲明我應該編寫網站以匹配此行爲。但是,這不是一個選擇。

我需要的是一個路由器,它允許第三個和第四個例子的功能與第一個相同。所有的例子都應該被髮送到Pages :: index控制器,該控制器依次使用URL路徑作爲關鍵字來查詢數據庫。

回答

2

如果在頁面,項目和類別之間的URL中沒有任何約定。我會用一個非常通用的路由器。

Router::connect('/{:category}/{:page}/{:item}', 'Pages::any'); 
Router::connect('/{:category}/{:page}', array('Pages::any', 'item' => null)); 
Router::connect('/{:category}', array('Pages::any', 'page' => null, 'item' => null)); 

並在Pages::any()搜索正確的東西。畢竟(例4)是category a page?是pageitem(例1)?

您存儲URL的地方(例如,在數據庫中的映射表),並使用pattern版本lithium Route的。

Router::connect(new Route(array(
    'pattern' => '@^/(?<path>.+)[email protected]', 
    'params' => array('controller' => 'pages', 'action' => 'any'), 
    'keys' => array('path' => 'path'), 
    // extra stuff, if the path is `tata`, it skips this route and uses 
    // any of the following ones that matches. 
    'handler' => function($request) { 
     if ($request->params['path'] == 'tata') { 
      return false; 
     } else { 
      return $request; 
     } 
    } 
))); 

從這一點,你會得到完整的URL。

+0

我喜歡指定一個自定義的Route(),但我無法讓它工作;我會稍後再玩。第一個解決方案經過一些調整,效果很好。我忘了你可以爲Router :: connect()指定一個$ params數組。 – 2012-01-04 14:43:32

+0

@EricC關鍵的'keys'參數丟失了,它在你的控制器收到的正則表達式和'Request :: $ params'之間進行了匹配。 – greut 2012-01-04 16:29:37

1

你可能應該編寫一個智能的路由器幫助程序,它可以根據你的數據庫定義的路線處理你的請求。

看看到:net/http/Router.php

特別是連接(),解析()和匹配()

我會開始寫某種匿名函數,並將其發展爲位於一個可測試類在/擴展..?