Search code examples
phpcakephppaginationellipsis

CakePHP link on Paginator ellipsis


I want to put a link on an ellipsis in the Paginator. When the pagination has 2 ellipsis's the ellipsis must have different link.

My code is:

echo $this->paginator->numbers(array(
        'tag'          => 'li',
        'separator'    => '',
        'currentTag'   => 'a',
        'currentClass' => 'active',
        'modulus'      => 2,
        'first'        => 1,
        'last'         => 1,
        'ellipsis'     => "<li><a href='#' class='hellip'>...</a></li>"
    ));

So the result I want to create is:

1 ...(link) 6 7 8 ...(link) 12


Solution

  • In short, the Paginator doesn't support what you want it to do and so your only option is to modify the CakePHP source code. Specifically PaginatorHelper.php

    First thing you'll need to do is modify the $defaults variable on line 720, and add leftEllipsis and rightEllipsis fields. This means that we can maintain consistent behavior when we don't set these fields in the $options variable.

    $defaults = array('tag' => 'span', 'before' => null, 'after' => null,
    'model' => $this->defaultModel(), 'class' => null,'modulus' => '8',
    'separator' => ' | ', 'first' => null, 'last' => null, 'ellipsis' => '...',
    'currentClass' => 'current', 'currentTag' => null, 'leftEllipsis' => null,
    'rightEllipsis' => null);
    

    Probably should unset our two new fields too (lines 735 - 738):

    unset($options['tag'], $options['before'], $options['after'], $options['model'],
    $options['modulus'], $options['separator'], $options['first'], $options['last'],
    $options['ellipsis'], $options['class'], $options['currentClass'], $options['currentTag'],
    $options['leftEllipsis'], $options['rightEllipsis']
        );
    

    The next bit is a tad tricky because it would be nice to be able to specify one of the ellipsis without the other, and in the absence of either, fallback onto whatever the original ellipsis field was set to. But the developers have used the magical extract and compact functions coupled with the first(...) and last(...) functions depending on certain fields being set in the $options parameter.

    After line 756 insert the following code to default the $leftEllipsis to whatever $ellipsis is set to:

    if(isempty($leftEllipsis)) {
      $leftEllipsis = $ellipsis;
    }
    

    Next we need to modify what gets passed as the $options parameter to the first(...) function on lines 758 - 761.

    if ($offset < $start - 1) {
      $out .= $this->first($offset, compact('tag', 'separator', 'class') + array('ellipsis' => $leftEllipsis));
    } else {
      $out .= $this->first($offset, compact('tag', 'separator', 'class') + array('after' => $separator, 'ellipsis' => $leftEllipsis));
    }
    

    You can use this pattern to attack the right ellipsis too.

    The proper way to do this is to fork the project on GitHub, make the changes to your version of the code base and create a pull request so you give the developers a chance to integrate your feature into the mainline. This way everyone can benefit from your work!

    Good luck!