【问题标题】:How to remove query string page from the first page of laravel pagination?如何从 laravel 分页的第一页中删除查询字符串页面?
【发布时间】:2017-08-04 04:55:28
【问题描述】:

我正在使用 分页,如下所示:

public function index()
    {
        $jobs = Job::paginate(5);
        return view('job.index', compact('jobs'));
    }

在视图中:

{{ $jobs->links() }}

生成两个典型页面存在问题:/job/job?page=1这两个页面内容相同。

我想做任何从分页第一页中删除查询字符串page 的操作。

我尝试了以下方法:

if ($jobs->onFirstPage()){
  $jobs->setPageName('');
} 

但这会破坏分页,即页面链接无法正确加载,并且所有页面的查询字符串值都保留。

【问题讨论】:

    标签: laravel-5.4 php laravel laravel-5 pagination laravel-5.4


    【解决方案1】:

    我发现这个问题的有效解决方案是编辑分页模板

    首先使用项目根目录下的以下命令从供应商处发布分页模板:

    php artisan vendor:publish --tag=laravel-pagination
    

    现在应该在resources/views/vendor/pagination/default.blade.php 找到一个文件,并且可以使用str_replace() 对每个页面的网址和返回导航按钮进行如下编辑:

    <li><a href="{{str_replace('?page=1','',$paginator->previousPageUrl())}}" title="{{__('Previous')}}" rel="prev">{{$foxPrev}}</a></li>
    

     <li><a href="{{str_replace('?page=1','',$url)}}">{{ $page }}</a></li>
    

    更新:

    ?page=10 中发现了一个错误,因此我们应该使用preg_replace 而不是使用str_replace,如下所示:

    <li><a href="{{preg_replace('/\?page=[1]$/','',$url)}}">{{ $page }}</a></li>
    

    更新 2:

    如果对页码参数使用除page 之外的任何自定义名称,我们可以在分页模板中为$pageName 属性使用分页器getter,如下所示:

    <li><a href="{{preg_replace('/\?'.$paginator->getPageName().'=[1]$/','',$url)}}">{{ $page }}</a></li>
    

    要了解更多关于如何在同一页面上使用多个分页或如何从视图中自定义页码参数$pageName,请查看this answer

    【讨论】:

    • 谢谢!但我认为这样更好; &lt;li class="page-item"&gt;&lt;a class="page-link" href="{{ preg_replace('/(\?|\&amp;)page=[1]$/','',$url) }}"&gt;{{ $page }}&lt;/a&gt;&lt;/li&gt;
    【解决方案2】:

    你可以扩展LengthAwarePaginator方法url($page)

    /**
     * Get the URL for a given page number.
     *
     * @param  int  $page
     * @return string
     */
    public function url($page)
    {
        if ($page <= 0) {
            $page = 1;
        }
    
        // If we have any extra query string key / value pairs that need to be added
        // onto the URL, we will put them in query string form and then attach it
        // to the URL. This allows for extra information like sortings storage.
        $parameters = ($page > 1) ? [$this->pageName => $page] : [];
    
        if (count($this->query) > 0) {
            $parameters = array_merge($this->query, $parameters);
        }
    
        return rtrim($this->path
            .(Str::contains($this->path, '?') ? '&' : '?')
            .http_build_query($parameters, '', '&')
            .$this->buildFragment(), '?');
    }
    

    【讨论】:

    • 这应该是公认的答案。从$parameters 数组中删除['page' =&gt; 1],然后在必要时删除尾随?。 EZPZ。谢谢。 :)
    【解决方案3】:

    如果您关心 SEO,请添加规范标签

    我不知道...

    if($pageNum==1){
        return redirect()->to($path);
    }
    

    $pageNum id 获取 Request 或 urself 类

    $path = "/jobs"

    【讨论】:

    • 这对于搜索引擎优化,那么额外的资源和流量消耗来检索相同的内容呢?!不幸的是,这不是我必须找到的理想解决方案。
    【解决方案4】:

    在您的路线中,为通往您的功能的路线命名:

    Route::get('/yourRoute','YourController@foo')->name('yourRouteName');
    

    然后,在控制器的函数中,使用:

    public function foo() {
        if( request()->page=='1' )
        {
                return redirect()->route('yourRouteName',[$id]);
        }
         else {
                // Your function content
        }
    }
    

    【讨论】:

      【解决方案5】:

      我想你可以试试这个:

      {{ $jobs->links() }}
      

      {{ $jobs->nextPageUrl() }}
      

      希望这对你有用!

      【讨论】:

        【解决方案6】:

        您可以像这样简单地修改视图:

        @if ($page==1)
           <a href="{{ str_replace('?page=1', '', $url) }}">{{ $page }}</a>
        @else
           <a href="{{ $url }}">{{ $page }}</a>
        @endif
        

        【讨论】:

          【解决方案7】:

          我发现以下作品并考虑到page=10问题:

          export your pagination views之后,进行以下2处修改:

          修改 1

          替换这个:

          {{ $paginator-&gt;previousPageUrl() }}

          用这个:

          {{ preg_replace('/(?:(&amp;|\\?)page=[1])(?!\\d)/ui','', $paginator-&gt;previousPageUrl()) }}

          修改 2

          替换这个:

          {{ $url }}

          用这个:

          {{ preg_replace('/(?:(&amp;|\\?)page=[1])(?!\\d)/ui','', $url ) }}

          【讨论】:

            【解决方案8】:

            我是这样做的:

            {{ $posts->currentPage() == 2 ? route('home') : $posts->previousPageUrl() }}
            

            【讨论】:

              【解决方案9】:

              改进的 Aksi 答案

              app/Services/CustomLengthAwarePaginator.php

              <?php
              
              namespace App\Services;
              
              use Illuminate\Pagination\LengthAwarePaginator;
              use Illuminate\Support\Arr;
              use Illuminate\Support\Str;
              
              class CustomLengthAwarePaginator extends LengthAwarePaginator
              {
                  /**
                   * Get the URL for a given page number.
                   *
                   * @param  int  $page
                   * @return string
                   */
                  public function url($page)
                  {
                      if ($page <= 0) {
                          $page = 1;
                      }
              
                      // If we have any extra query string key / value pairs that need to be added
                      // onto the URL, we will put them in query string form and then attach it
                      // to the URL. This allows for extra information like sortings storage.
                      $parameters = ($page > 1) ? [$this->pageName => $page] : [];
              
                      if (count($this->query) > 0) {
                          $parameters = array_merge($this->query, $parameters);
                      }
              
                      return $this->path()
                          . (count($parameters) > 0
                              ? (Str::contains($this->path(), '?') ? '&' : '?')
                              : '')
                          . Arr::query($parameters)
                          . $this->buildFragment();
                  }
              }
              

              在 AppServiceProvider.php 或其他中

              public function boot()
              {
                  app()->bind(LengthAwarePaginator::class, CustomLengthAwarePaginator::class);
              }
              

              【讨论】:

                【解决方案10】:

                使用这个命令创建一个中间件

                php artisan make:middleware RemovePageQuery
                

                在中间件中编写这段代码

                <?php
                
                namespace App\Http\Middleware;
                
                use Closure;
                use Illuminate\Http\Request;
                
                class RemovePageQuery
                {
                    /**
                     * Handle an incoming request.
                     *
                     * @param  \Illuminate\Http\Request  $request
                     * @param  \Closure  $next
                     * @return mixed
                     */
                    public function handle(Request $request, Closure $next)
                    {
                        if ($request->page == 1)
                        {
                            return redirect(url()->current());
                        }
                        
                        return $next($request);
                    }
                }
                

                在 $middleware 内的 App/Http/Kernel.php 中添加中间件全局。

                 protected $middleware = [
                        // \App\Http\Middleware\TrustHosts::class,
                        \App\Http\Middleware\RemovePageQuery::class, //Here
                        \App\Http\Middleware\TrustProxies::class,
                        \Fruitcake\Cors\HandleCors::class,
                        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
                        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
                        \App\Http\Middleware\TrimStrings::class,
                        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
                    ];
                

                【讨论】:

                  【解决方案11】:

                  我正在寻找解决类似问题以防止内容重复,但对于 symfony 而不是 laravel。我以我的方式修复它并决定发布它。也许它会帮助某人。

                  在 symfony 中,我使用 KNP 分页器。它提供了分页器模板,如下所示:

                       <a href="{{ path(route, query|merge({(pageParameterName): page})) }}">{{ page }}</a>
                  

                  'Query' 数组包含路由参数,如果它 == 1,任务是删除页面参数。

                  很简单:

                      {% set page_seo = (page == 1) ? null : page %}
                      <a href="{{ path(route, query|merge({(pageParameterName): page_seo})) }}">{{ page }}</a>
                  

                  实际上 - 如果它 == 1,则设置为空页面。

                  【讨论】:

                    猜你喜欢
                    • 2020-04-20
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-05-28
                    • 2020-04-18
                    • 2016-01-07
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-06-25
                    相关资源
                    最近更新 更多