2016-09-20 67 views
3

我現在有它顯示一個員工個人資料的模塊。它的工作原理就像這樣:Silverstripe:清理網址

  • 員工持有人:顯示所有工作人員
  • 員工檔案列表:顯示「StaffMember」表的數據庫記錄。

員工資料使用模板「StaffHolder_profile.ss」。顯然,'資料'是顯示員工資料的操作。顯示配置文件操作工作是在這個看起來像這樣的URL:

的 'http:// /人員/資料/ ID記錄的'

我一直要求從這些網址中刪除「個人資料/ ID」。據我所知,這是不可能的,因爲模塊依賴於URL來工作? (它使用URL變量...)

這是真的嗎?有沒有一種方法,我可以基本上「清理」的URL,以便新的URL將「http://domain/staff/staff-member-name

+0

你可以用自定義路由實現這一目標,但據推測會員名稱不是唯一的,所以你會遇到同名會員的問題。 –

+0

您是否將其作爲前端頁面或CMS處理?你有用戶的登錄系統嗎? (然後可以在會話中找到當前用戶,請參閱CMS成員類)您是否使用SiteTree :: nested_urls? (然後StaffProfile可以是嵌套頁面)。是的,你可以在'StaffHolder_Controller :: index($ request)''中處理乾淨的URL,其中'$ name = $ request-> getParam('ID');' –

+0

@GregSmirnov謝謝爲答覆。這是前端。是的,有一個登錄系統,但工作人員頁面將顯示一個數據對象列表作爲頁面。這不是當前用戶的個人資料。什麼是嵌套網址?那個控制器功能到底做了什麼? – Dallby

回答

2

您可以通過覆蓋頁面控制器的索引中的路由參數'Action'來實現該特定的url模式。我不會建議這個。相反,我建議您爲頁面創建一個特定的操作,例如'domain/staff/view/...'。我下面的例子確實覆蓋了路由參數'Action',但只是爲了實現你的問題。

您可以基於一個名字標識符,但是像不一致的細節丟失和/或相匹配的名字產生問題 - 其中大部分並不受這些例子。一個獨特的標識符會好得多。

我還沒有試運行此代碼的任何,錯誤很抱歉。需要慢,但是較少的工作:

實施例1 -

StaffHolder_Controller:

public function index() { 

    /** 
    * @internal This will display the first match ONLY. If you'd like to 
    * account for member's with exactly the same name, generate and store the 
    * slug against their profile... See Example 2 for that. 
    */ 

    // Re-purpose the 'Action' URL param (not advisable) 
    $slug = $this->getRequest()->param('Action'); 

    // Partial match members by first name 
    $names = explode('-', $slug); 
    $matches = Member::get()->filter('FirstName:PartialMatch', $names[0]); 

    // Match dynamically 
    $member = null; 
    foreach($matches as $testMember) { 
     // Uses preg_replace to remove all non-alpha characters 
     $testSlug = strtolower(
      sprintf(
       '%s-%s', 
       preg_replace("/[^A-Za-z]/", '', $testMember->FirstName), 
       preg_replace("/[^A-Za-z]/", '', $testMember->Surname) 
      ) 
     ); // Or use Member::genereateSlug() from forthcoming example MemberExtension 

     // Match member (will stop at first match) 
     if($testSlug == $slug) { 
      $member = $testMember; 
      break; 
     } 
    } 

    // Handle invalid requests 
    if(!$member) { 
     return $this->httpError(404, 'Not Found'); 
    } 

    /** 
    * @internal If you're lazy and want to use your existing template 
    */ 
    return $this->customise(array(
     'Profile' => $member 
     ))->renderWith(array('StaffHolder_profile', 'Page')); 

} 

-

實施例2:

config.yml:

Member: 
    extensions: 
    - MemberExtension 

MemberExtension.php:

class MemberExtension extends DataExtension { 

    private static $db = array(
     'Slug' => 'Varchar' // Use 'Text' if it's likely that there will be a value longer than 255 
    ); 

    public function generateSlug() { 
     // Uses preg_replace to remove all non-alpha characters 
     return strtolower(
      sprintf(
       '%s-%s', 
       preg_replace("/[^A-Za-z]/", '', $this->owner->FirstName), 
       preg_replace("/[^A-Za-z]/", '', $this->owner->Surname) 
      ) 
     ); 
    } 

    public function onBeforeWrite() { 

     // Define slug 
     if(!$this->owner->Slug)) { 
      $slug = $this->generateSlug(); 

      $count = Member::get()->filter('Slug:PartialMatch', $slug)->Count(); 

      // Check for unique 
      $unique = null; 
      $fullSlug = $slug; 
      while(!$unique) { 
       // Add count e.g firstname-surname-2 
       if($count > 0) { 
        $fullSlug = sprintf('%s-%s', $slug, ($count+1)); 
       } 

       // Check for pre-existing 
       if(Member::get()->filter('Slug:PartialMatch', $fullSlug)->First()) { 
        $count++; // (Try again with) increment 
       } else { 
        $unique = true; 
       } 
      } 

      // Update member 
      $this->owner->Slug = $fullSlug; 
     } 

    } 

} 

StaffHolder_Controller:

public function index() { 

    // Re-purpose the action URL param (not advisable) 
    $slug = $this->getRequest()->param('Action'); 

    // Check for member 
    $member = Member::get()->filter('Slug', $slug)->first(); 

    // Handle invalid requests 
    if(!$member) { 
     return $this->httpError(404, 'Not Found'); 
    } 

    /** 
    * @internal If you're lazy and want to use your existing template 
    */ 
    return $this->customise(array(
     'StaffMember' => $member 
     ))->renderWith('StaffHolder_profile'); 

} 
0

嵌套的網址是SiteTree類的默認行爲。每個子頁面URL段都會添加到父完整URL中。因此,與下面的頁面層次結構你乾淨的網址

Staff (StaffHolder, /staff) 
|- John Doe (StaffProfilePage, /staff/john-doe) 
|- Marie Smith (StaffProfilePage, /staff/marie-smith) 

你可以在StaffHolder.ss模板的工作人員的個人資料頁面的列表與

<ul> 
<% loop $Children %> 
    <li><a href="$Link">$Title</a></li> 
<% end_loop %> 
</ul>