2014-01-07 70 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