2014-01-07 88 views
16

有沒有辦法在Laravel 4中獲得分頁漂亮的URL?Laravel分頁漂亮URL

例如,默認情況下:

http://example.com/something/?page=3 

而我想獲得:

http://example.com/something/page/3 

此外,分頁應該呈現這種方式,並追加到分頁應該出現在這個辦法。

回答

14

這裏是一個哈克的解決方法。我正在使用Laravel v4.1.23。它假定頁碼是你網址的最後一位。沒有深入測試,所以我對任何人都能找到的bug感興趣。我更感興趣的:-)

路線更好的解決方案:

Route::get('/articles/page/{page_number?}', function($page_number=1){ 
    $per_page = 1; 
    Articles::resolveConnection()->getPaginator()->setCurrentPage($page_number); 
    $articles = Articles::orderBy('created_at', 'desc')->paginate($per_page); 
    return View::make('pages/articles')->with('articles', $articles); 
}); 

查看:

<?php 
    $links = $articles->links(); 
    $patterns = array(); 
    $patterns[] = '/'.$articles->getCurrentPage().'\?page=/'; 
    $replacements = array(); 
    $replacements[] = ''; 
    echo preg_replace($patterns, $replacements, $links); 
?> 

型號:

<?php 
class Articles extends Eloquent { 
    protected $table = 'articles'; 
} 

遷移:

<?php 

use Illuminate\Database\Schema\Blueprint; 
use Illuminate\Database\Migrations\Migration; 

class CreateArticlesTable extends Migration { 

    public function up() 
    { 
     Schema::create('articles', function($table){ 
      $table->increments('id'); 
      $table->string('slug'); 
      $table->string('title'); 
      $table->text('body'); 
      $table->timestamps(); 
     }); 
    } 

    public function down() 
    { 
     Schema::drop('articles'); 
    } 
} 
0

你或許可以做一些奇特的路由來讓它工作。沿線的某處:

Route::get('something/{page}', function($page) 
{ 
    // 
}) 
->where('page', '[0-9]+'); 

本示例取自文檔here

+0

但不會更改分頁程序的鏈接 – Adam

0

我能想到這樣做的唯一方法是通過擴展Paginator類來進行匹配。但是,只要知道它可能與第三方包和其他類/庫衝突。目前的方法被設計用於幾乎所有的類/庫/包。

也許你可以嘗試以下方法:

http://packalyst.com/packages/package/desmart/pagination( '分頁' 通過 'desmart')

6

這是可能的,但你需要編碼一點。

首先您需要更改app/config/app.php分頁服務提供商 - 您需要自行編寫。

評論:

// 'Illuminate\Pagination\PaginationServiceProvider', 

,並提供部分添加

'Providers\PaginationServiceProvider', 

現在,您需要創建PaginationServiceProvider使用自定義分頁工廠:

model/Providers/PaginationServiceProvider.php文件:

<?php 

namespace Providers; 

use Illuminate\Support\ServiceProvider; 

class PaginationServiceProvider extends ServiceProvider 
{ 

    /** 
    * Indicates if loading of the provider is deferred. 
    * 
    * @var bool 
    */ 
    protected $defer = true; 

    /** 
    * Register the service provider. 
    * 
    * @return void 
    */ 
    public function register() 
    { 
     $this->app->bindShared('paginator', function ($app) { 
      $paginator = new PaginationFactory($app['request'], $app['view'], 
       $app['translator']); 

      $paginator->setViewName($app['config']['view.pagination']); 

      $app->refresh('request', $paginator, 'setRequest'); 

      return $paginator; 
     }); 
    } 

    /** 
    * Get the services provided by the provider. 
    * 
    * @return array 
    */ 
    public function provides() 
    { 
     return array('paginator'); 
    } 

} 

上面創建Providers\PaginationFactory對象,所以現在我們需要創建這個文件:

model/providers/PaginationFactory.php file:

<?php 


namespace Providers; 

use Illuminate\Pagination\Factory; 


class PaginationFactory extends Factory { 

    /** 
    * Get a new paginator instance. 
    * 
    * @param array $items 
    * @param int $total 
    * @param int|null $perPage 
    * @return \Illuminate\Pagination\Paginator 
    */ 
    public function make(array $items, $total, $perPage = null) 
    { 
     $paginator = new \Utils\Paginator($this, $items, $total, $perPage); 

     return $paginator->setupPaginationContext(); 
    }   
} 

在這裏,您只創建\Utils\Paginator對象,因此現在讓我們來創建它:

model/Utils/Paginator.php文件:

<?php 

namespace Utils; 



class Paginator extends \Illuminate\Pagination\Paginator { 


    /** 
    * Get a URL for a given page number. 
    * 
    * @param int $page 
    * @return string 
    */ 
    public function getUrl($page) 
    { 
     $routeParameters = array(); 

     if ($page > 1) { // if $page == 1 don't add it to url 
     $routeParameters[$this->factory->getPageName()] = $page; 
     } 

     return \URL::route($this->factory->getCurrentUrl(), $routeParameters); 
    } 
} 

在這個文件中,我們終於改寫爲創建分頁網址的默認方法。

讓我們假設你有路線定義是這樣的:

Route::get('/categories/{page?}', 
    ['as' => 'categories', 
    'uses' => '[email protected]' 
    ])->where('page', '[1-9]+[0-9]*'); 

正如你看到的,我們這裏定義使用as路由名稱(這是因爲分頁程序執行上述重要 - 但是你可以用不同的方式做到這一點,當然) 。

現在CategoryController類的方法displayList你可以這樣做:

public function displayList($categories, $page = 1) // default 1 is needed here 
{ 
    Paginator::setCurrentPage($page); 
    Paginator::setBaseUrl('categories'); // use here route name and not the url 
    Paginator::setPageName('page'); 

    $categories = Category::paginate(15); 


    return View::make('admin.category')->with(
     ['categories' => $categories] 
    ); 
} 

當您的視圖添加:

<?php echo $categories->links(); ?> 

,你會得到生成的URL是這樣的:

http://localhost/categories 
http://localhost/categories/2 
http://localhost/categories/3 
http://localhost/categories/4 
http://localhost/categories/5 

沒有?在查詢字符串

但我認爲這樣的東西應該默認添加,或者至少它應該足以擴展一個類,而不是創建3個類只是爲了實現一個方法。

+0

謝謝你的解決方案,我同意你的觀點,在Laravel中重寫某些默認函數是很難的,它總是需要創建一個新的服務提供者,它必須是某種類型的覆蓋生成器。 – Vedmant

1

希望這對某人有用,我已經在模型中使用了一個特徵。 的想法是,這種自定義的方法可以檢測當前的路由和調整鏈接上使用正確的段位置{PAGE}參數:

https://gist.github.com/zofe/ced0054e6ac6eff1ea95