3

I'm using the following code (from here) to paginate links:

function custom_pagination() {
    global $wp_query;
    $big = 999999999; // need an unlikely integer
    $pages = paginate_links( array(
            'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
            'format' => '?paged=%#%',
            'current' => max( 1, get_query_var('paged') ),
            'total' => $wp_query->max_num_pages,
            'prev_next' => false,
            'type'  => 'array',
            'prev_next'   => TRUE,
            'prev_text'    => __('«'),
            'next_text'    => __('»'),
        ) );
        if( is_array( $pages ) ) {
            $paged = ( get_query_var('paged') == 0 ) ? 1 : get_query_var('paged');
            echo '<ul class="pagination">';
            foreach ( $pages as $page ) {
                    echo "<li>$page</li>";
            }
           echo '</ul>';
        }
}

The output of this is using echo custom_pagination();:

<ul class="pagination">
    <li class="page-item">
        <a class="page-numbers" href="example.com/page/1">1</a>          
    </li>
</ul>

How can I change the output to this?:

<ul class="pagination">
    <li class="page-item">
        <a class="page-link" href="example.com/page/1">1</a>          
    </li>
</ul>

I'm trying to make a bootstrap theme, but I can't seem to replace the page-numbers class with the bootstrap page-link class.

5 Answers 5

4

The paginate_links() function, located in wp-includes/general-template.php, doesn't allow for certain parts of the HTML (such as the page-numbers class) to be customized.

A simple string replacement will not work due to the way that the classes are generated, as highlighted in this excerpt of code from paginate_links():

    $page_links[] = '<a class="prev page-numbers" href="' . esc_url( apply_filters( 'paginate_links', $link ) ) . '">' . $args['prev_text'] . '</a>';
endif;
for ( $n = 1; $n <= $total; $n++ ) :
    if ( $n == $current ) :
        $page_links[] = "<span class='page-numbers current'>" . $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number'] . "</span>";

Here is an updated version of your custom_pagination() function, which uses DOMXpath to to find instances elements with the page-numbers class, then a string replacement is done to change the class to page-link. For better compatibility with Bootstrap, the current class is also replaced with active. Finally, class="mynewclass" is added to the <li> which contains the current item.

function wpse247219_custom_pagination() {
    global $wp_query;
    $big = 999999999; // need an unlikely integer
    $pages = paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'current' => max( 1, get_query_var('paged') ),
        'total' => $wp_query->max_num_pages,
        'prev_next' => false,
        'type'  => 'array',
        'prev_next'   => true,
        'prev_text'    => __( '«', 'text-domain' ),
        'next_text'    => __( '»', 'text-domain'),
    ) );
    $output = '';

    if ( is_array( $pages ) ) {
        $paged = ( get_query_var('paged') == 0 ) ? 1 : get_query_var( 'paged' );

        $output .=  '<ul class="pagination">';
        foreach ( $pages as $page ) {
            $output .= "<li>$page</li>";
        }
        $output .= '</ul>';

        // Create an instance of DOMDocument 
        $dom = new \DOMDocument();

        // Populate $dom with $output, making sure to handle UTF-8, otherwise
        // problems will occur with UTF-8 characters.
        $dom->loadHTML( mb_convert_encoding( $output, 'HTML-ENTITIES', 'UTF-8' ) );

        // Create an instance of DOMXpath and all elements with the class 'page-numbers' 
        $xpath = new \DOMXpath( $dom );

        // http://stackoverflow.com/a/26126336/3059883
        $page_numbers = $xpath->query( "//*[contains(concat(' ', normalize-space(@class), ' '), ' page-numbers ')]" );

        // Iterate over the $page_numbers node...
        foreach ( $page_numbers as $page_numbers_item ) {

            // Add class="mynewclass" to the <li> when its child contains the current item.
            $page_numbers_item_classes = explode( ' ', $page_numbers_item->attributes->item(0)->value );
            if ( in_array( 'current', $page_numbers_item_classes ) ) {          
                $list_item_attr_class = $dom->createAttribute( 'class' );
                $list_item_attr_class->value = 'mynewclass';
                $page_numbers_item->parentNode->appendChild( $list_item_attr_class );
            }

            // Replace the class 'current' with 'active'
            $page_numbers_item->attributes->item(0)->value = str_replace( 
                            'current',
                            'active',
                            $page_numbers_item->attributes->item(0)->value );

            // Replace the class 'page-numbers' with 'page-link'
            $page_numbers_item->attributes->item(0)->value = str_replace( 
                            'page-numbers',
                            'page-link',
                            $page_numbers_item->attributes->item(0)->value );
        }

        // Save the updated HTML and output it.
        $output = $dom->saveHTML();
    }

    return $output;
}

Usage:

echo wpse247219_custom_pagination();

Generated HTML:

<ul class="pagination">
    <li class="mynewclass"><span class="page-link active">1</span></li>
    <li><a class="page-link" href="http://localhost/page/2/">2</a></li>
    <li><a class="page-link" href="http://localhost/page/3/">3</a></li>
    <li><span class="page-link dots">…</span></li>
    <li><a class="page-link" href="http://localhost/page/5/">5</a></li>
    <li><a class="next page-link" href="http://localhost/page/2/">»</a></li>
</ul>
6
  • This code works great, but one last thing, how would I go about in changing "$page_links[] = "<span class='page-numbers current'>' " as well? I would like to change the class=''page-numbers current' to class=''page-numbers active'
    – Tom
    Nov 24, 2016 at 3:19
  • Glad that worked out for you! I've updated my answer so that current has been replaced with active :-) Nov 24, 2016 at 5:31
  • Actually, how there a way to add a class just to the <li> when I'm on the the <span class="page-link active">1</span>? e.g <li class='mynewclass'><span class="page-link active">1</span></li>.
    – Tom
    Nov 24, 2016 at 14:07
  • That's doable. Updated my answer so that the <li> containing the current item gets class="mynewclass" added to it. Nov 25, 2016 at 2:57
  • 1
    Wonderful! Everything is working now.
    – Tom
    Nov 25, 2016 at 3:18
1

Work on this today, compatible wordpress 5.5.1 with bootstrap 4 :

        <?php
            $pagination = paginate_links( array(
              'base' => str_replace( 999999999, '%#%', esc_url( get_pagenum_link( 999999999 ) ) ),
              'format' => '?paged=%#%',
              'current' => max( 1, get_query_var('paged') ),
              'total' => $query_accueil->max_num_pages,
              'prev_text' => '<i class="fas fa-angle-double-left"></i>',
              'next_text' => '<i class="fas fa-angle-double-right"></i>',
              'type' => 'array'
            ) );
        ?>
        <?php if ( ! empty( $pagination ) ) : ?>
          <nav aria-label="page navigation">
            <ul class="pagination">
              <?php foreach ( $pagination as $key => $page_link ) : ?>
                <li class="page-item
                  <?php
                      $link = htmlspecialchars($page_link);
                      $link = str_replace( ' current', '', $link);
                      if ( strpos( $page_link, 'current' ) !== false ) { echo ' active'; }
                  ?>
                ">
                  <?php
                    if ( $link ) {
                      $link = str_replace( 'page-numbers', 'page-link', $link);
                    }
                    echo htmlspecialchars_decode($link);
                  ?>
                </li>
              <?php endforeach ?>
            </ul>
          </nav>
        <?php endif ?>
0

Tracking through this, it appears that there isn't a way to pass a class through the paginate_links function. So based on the custom_pagination function, here's how I'd rewrite it:

function custom_pagination() {
    global $wp_query;

    // No idea why this line was in the if statement originally...
    $paged = ( get_query_var('paged') ? get_query_var('paged') : 1 );

    $big = 999999999; // need an unlikely integer

    $pages = paginate_links( array(
        'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format' => '?paged=%#%',
        'current' => $paged,
        'total' => $wp_query->max_num_pages,
        'prev_next' => false,
        'type'  => 'array',
        'prev_next'   => TRUE,
        'prev_text'    => __('«'),
        'next_text'    => __('»'),
    ) );

    if( is_array( $pages ) ) {

        echo '<ul class="pagination">' .
                 str_replace( 'class="page-numbers"', 'class="page-link"', implode( '', $pages ) .
             '</ul>';

    }
}

Didn't test this, please let me know if you have any issues.

0

In your last line of code you forgot a closing ). Here is the correct line:

echo '<ul class="pagination">' . str_replace( 'class="page-numbers"', 'class="page-link"' ), implode( '', $pages ) . '</ul>';
0

A simpler solution using jQuery

jQuery(document).ready(function ($) {

    $(".pagination .page-item .page-numbers").addClass("page-link");
    $(".pagination .page-item .page-link").removeClass("page-numbers");

});

Same approach can be used for other classes like current etc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.