Laravel分页漂亮的URL

时间:2014-01-07 14:38:58

标签: php laravel laravel-4

有没有办法在Laravel 4中获得一个分页漂亮的URL?

例如,默认情况下:

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

我想得到什么:

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

此外,分页应该以这种方式呈现,并且附加分页应该以这种方式出现。

7 个答案:

答案 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}参数的正确段位置:

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

答案 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;