Laravel 分页漂亮的 URL

Posted

技术标签:

【中文标题】Laravel 分页漂亮的 URL【英文标题】:Laravel pagination pretty URL 【发布时间】:2014-01-25 07:11:08 【问题描述】:

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

例如,默认情况下:

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

我想得到什么:

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

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

【问题讨论】:

对于 Laravel 5.8 - 请参阅 ***.com/a/58005778/1916821 【参考方案1】:

对于 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;

【讨论】:

我正在使用 laravel 8,这应该标记为正确答案【参考方案2】:

对于使用 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));

【讨论】:

请解释您的答案,因为这不清楚如何使用您的方法构建 /some-url/page/2 而不是 /some-url?page=2。【参考方案3】:

希望这对某人有所帮助,我已经制作了一个用于模型的特征。 这个想法是这个自定义方法可以检测当前路线并调整链接以使用正确的段位置 page 参数:

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

【讨论】:

【参考方案4】:

这是可能的,但您需要编写一些代码。

首先你需要更改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);
    

在这个文件中,我们最终覆盖了创建分页 url 的默认方法。

假设您已经这样定义了路由:

Route::get('/categories/page?',
    ['as'   => 'categories',
     'uses' => 'CategoryController@displayList'
    ])->where('page', '[1-9]+[0-9]*');

如您所见,我们在这里使用as 定义了路由名称(这很重要,因为上面的 Paginator 实现 - 但您当然可以用不同的方式来做)。

现在在 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(); ?>

您将通过这种方式获得生成的网址:

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

没有?在查询字符串中

但是在我看来,应该默认添加这样的东西,或者至少应该足以扩展一个类,而不是仅仅为了实现一种方法而创建 3 个类。

【讨论】:

感谢您的解决方案,我同意您的观点,在 Laravel 中覆盖一些默认功能真的很难,它总是需要创建新的自己的服务提供者,它必须是某种覆盖生成器。跨度> 【参考方案5】:

这是一个 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');
    

【讨论】:

【参考方案6】:

我能想到的唯一方法是扩展 Paginator 类来进行匹配。但是,只要知道它可能与第三方包和其他类/库冲突。当前方法旨在与几乎所有类/库/包一起使用。

或许您可以尝试以下方法:

http://packalyst.com/packages/package/desmart/pagination(“desmart”的“分页”)

【讨论】:

以上是关于Laravel 分页漂亮的 URL的主要内容,如果未能解决你的问题,请参考以下文章

Laravel5.1 分页展示

Laravel 5.1使用分页自动递增行号

Laravel 在本地 ubuntu 20 中显示空白页

试图从 url Laravel 中删除 public

从 url laravel 5.4 中删除公共

从 URL Laravel 5.3 中删除公共