有没有办法在Laravel 4中获得一个分页漂亮的URL?
例如,默认情况下:
http://example.com/something/?page=3
我想得到什么:
http://example.com/something/page/3
此外,分页应该以这种方式呈现,并且附加分页应该以这种方式出现。
答案 0 :(得分:14)
这是一个hacky解决方法。我正在使用Laravel v4.1.23。它假定页码是您网址的最后一位。没有深入测试,所以我对人们可以找到的任何错误感兴趣。我对更好的解决方案更感兴趣: - )
路线:
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');
}
}
答案 1 :(得分:7)
这是可能的,但你需要编写一些代码。
首先,您需要更改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
档案:
<?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' => 'CategoryController@displayList'
])->where('page', '[1-9]+[0-9]*');
如你所见,我们在这里使用as
定义了路由名称(由于上面的Paginator实现,它很重要 - 但你当然可以用不同的方式来实现)。
现在,您可以在displayList
课程的方法CategoryController
中执行以下操作:
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个类。
答案 2 :(得分:1)
希望这对某些人有帮助,我已经做出了在模特中使用的特性。 我们的想法是,这种自定义方法可以检测当前路由并调整链接以使用{page}参数的正确段位置:
答案 3 :(得分:1)
对于使用laravel 5.6+版本的任何人
您可以传递其他参数来设置页码。
根据:https://laravel.com/api/5.6/Illuminate/Database/Eloquent/Builder.html#method_paginate
示例:
StoreController.php
/**
* Show sale item based on given page
*
* @param int $page
* @return \Illuminate\Http\Response
*/
public function showPage($page = 1)
{
$saleItems = SaleItem::paginate(10, array('*'), 'page', $page);
...
}
然后,在刀片服务器模板中。您可以route( ... , array('page' => $page));
答案 4 :(得分:0)
你可能会做一些花哨的路由来让它工作。在某处:
Route::get('something/{page}', function($page)
{
//
})
->where('page', '[0-9]+');
此示例取自文档here。
答案 5 :(得分:0)
我能想到的唯一方法就是扩展Paginator类来进行匹配。但是,只知道它可能与第三方软件包和其他类/库冲突。当前方法旨在与几乎所有类/库/包一起使用。
也许你可以尝试以下方法:
http://packalyst.com/packages/package/desmart/pagination('desmart''''分页')
答案 6 :(得分:0)
对于Laravel 5.8,请在blade.php中使用此解决方案来生成链接:
$links = $data->links();
$patterns = '#\?page=#';
$replacements = '/page/';
$one = preg_replace($patterns, $replacements, $links);
$pattern2 = '#page/([1-9]+[0-9]*)/page/([1-9]+[0-9]*)#';
$replacements2 = 'page/$2';
$paginate_links = preg_replace($pattern2, $replacements2, $one);
echo $paginate_links;