Opened 8 years ago
Last modified 7 years ago
#40108 new enhancement
Pagination Enhancement wp_link_pages()
Reported by: | mshumacher | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | |
Component: | Themes | Keywords: | has-screenshots needs-refresh |
Focuses: | template | Cc: |
Description
Current implementation of the function is not well suited for posts containing 10+ pages, this creates usability issues for desktop and especially mobile users. Most popular themes which rely on this built-in function are affected. Popular hosting providers such as Wordpress.com do not allow 3rd party plugins or any enhancements to work around this issue.
Example:
Goal:
Provide theme creators posibility to reduce the number of visible page links and enhance CSS theming by wrapping the current page in CSS selectable tag, allowing improved usability on mobile devices and reducing the reliance of wider community on 3rd party plugins or custom code.
Solution:
Accept additional 'mixed' value for the [next_or_number] parameter and create a helper parameter to control the max number of outputted page links. Wrap the current page in a <span> to allow CSS theming.
The looks/functionality as per the screenshot above can be achieved with only ~20 additional lines of code (below)
It accounts for any edge cases and ensures full backwards compatibility, however, additional testing is needed.
Enhanced wp_link_pages Function:
<?php function wp_link_pages( $args = '' ) { global $page, $numpages, $multipage, $more; $defaults = array( /** *Start of New code for making pagination into CSS friendly */ 'before' => '<p>' . __( 'Pages:' ), 'after' => '</p>', 'link_before' => '', 'link_after' => '', 'next_or_number' => 'number', // new param for controling max link number in 'mixed' mode 'navwidth' => '3', //number of links displayed before and after current page 'separator' => ' ', 'separator' => ' ', 'nextpagelink' => __( 'Next page' ), 'previouspagelink' => __( 'Previous page' ), 'pagelink' => '%', 'echo' => 1 ); $params = wp_parse_args( $args, $defaults ); /** * Filters the arguments used in retrieving page links for paginated posts. * * @since 3.0.0 * * @param array $params An array of arguments for page links for paginated posts. */ $r = apply_filters( 'wp_link_pages_args', $params ); $output = ''; if ( $multipage ) { if ( 'number' == $r['next_or_number'] ) { $output .= $r['before']; for ( $i = 1; $i <= $numpages; $i++ ) { $link = $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after']; if ( $i != $page || ! $more && 1 == $page ) { $link = _wp_link_page( $i ) . $link . '</a>'; } /** * Filters the HTML output of individual page number links. * * @since 3.6.0 * * @param string $link The page number HTML output. * @param int $i Page number for paginated posts' page links. */ $link = apply_filters( 'wp_link_pages_link', $link, $i ); // Use the custom links separator beginning with the second link. $output .= ( 1 === $i ) ? ' ' : $r['separator']; $output .= $link; } $output .= $r['after']; } elseif ( $more ) { $output .= $r['before']; $prev = $page - 1; if ( $prev > 0 ) { $link = _wp_link_page( $prev ) . $r['link_before'] . $r['previouspagelink'] . $r['link_after'] . '</a>'; /** This filter is documented in wp-includes/post-template.php */ $output .= apply_filters( 'wp_link_pages_link', $link, $prev ); } /** *Start of New Code for 'mixed' navigation mode */ // Output number of links equal to $navwidth before current page if ( 'mixed' == $r['next_or_number'] ) { For ( $i = $page - $navwidth; $i < $page; $i++) { if ( $i > 0) { $link = _wp_link_page( $i ) . $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'] . '</a>'; $link = apply_filters( 'wp_link_pages_link', $link, $i ); // Use the custom links separator beginning with the second link. $output .= ( 1 === $i ) ? ' ' : $r['separator']; $output .= $link } } // Output current page within <span> tags for enhanced styling capability if ( $prev ) { $output .= $r['separator']; } $output .= $r['link_before'] . ('<span>') . str_replace( '%', $i, $r['pagelink'] ) . ('</span>') . $r['link_after']; // Output number of links equal to $navwidth after current page For ($i = $page + 1; $i <= $numpages; $i++) { $link = _wp_link_page( $i ) . $r['link_before'] . str_replace( '%', $i, $r['pagelink'] ) . $r['link_after'] . '</a>'; $link = apply_filters( 'wp_link_pages_link', $link, $i ); $output .= $r['separator'] . $link; } } /** *End of New Code for 'mixed' navigation mode */ $next = $page + 1; if ( $next <= $numpages ) { if ( $prev ) { $output .= $r['separator']; } $link = _wp_link_page( $next ) . $r['link_before'] . $r['nextpagelink'] . $r['link_after'] . '</a>'; /** This filter is documented in wp-includes/post-template.php */ $output .= apply_filters( 'wp_link_pages_link', $link, $next ); } $output .= $r['after']; } } /** * Filters the HTML output of page links for paginated posts. * * @since 3.6.0 * * @param string $output HTML output of paginated posts' page links. * @param array $args An array of arguments. */ $html = apply_filters( 'wp_link_pages', $output, $args ); if ( $r['echo'] ) { echo $html; } return $html; }
Let me know if I can further help to get this be pushed into the next release.
Martin
https://martinshreder.com
Attachments (2)
Change History (12)
#2
@
8 years ago
- Keywords needs-testing added
@dingo_bastard thanks a lot for the patch!
I would appreciate if anyone can do a basic test and see if the code works as expected.
Basic test scenario:
- Create a 10+ page post using either the <!--nextpage--> tag or Alt+Shift+P keyboard shortcut
- Open the post and inspect the resulting pagination HTML (copy it somewhere)
- Apply the patch;
- Reload the page ignoring cache Control+Shift+R
- Compare the resulting pagination HTML
(the only difference between the HTML output should be the current page which will become wrapped in a <span> tag)
Advanced test scenario:
- Modify the wp_link_pages() function call inside the theme loop (usually called from content.php in the theme components folder) with the following code:
<?php wp_link_pages( array( 'before' => '<div class="pagination"> <p>' . __( 'Page ' ) . $page . __( ' of ' ) . $numpages . __( ' pages' ) . '</p> <ul>', 'after' => '</ul> </div>', 'link_before' => '<li>', 'link_after' => '</li>', 'navwidth' => 3, 'next_or_number' => 'mixed', 'separator' => ' ', 'nextpagelink' => __( 'Next' ) . ' >', 'previouspagelink' => '< ' . __( 'Previous' ), ) );
- Navigate to a multi page page post
- Check the pagination html section for errors
(output should be similar to the example provided in my original post)
Themes that call wp_link_pages() function:
- IXION
- Twenty Sixteen
- Twenty Fifteen
- Others1
[1]: Any theme is suitable for testing as long as it makes a call to the wp_link_pages function
Martin
https://martinshreder.com
This ticket was mentioned in Slack in #core by martinshreder. View the logs.
8 years ago
This ticket was mentioned in Slack in #core by martinshreder. View the logs.
7 years ago
#7
follow-up:
↓ 8
@
7 years ago
Re: the CSS part, worth noting [42440] added a couple new CSS classes: post-nav-links
and post-page-numbers
, together with an aria-current
attribute for the current page.
#8
in reply to:
↑ 7
@
7 years ago
Replying to afercia:
Re: the CSS part, worth noting [42440] added a couple new CSS classes:
post-nav-links
andpost-page-numbers
, together with anaria-current
attribute for the current page.
Thanks, I've reviewed [42440] and updated the patch to include both the aria-current
and my next_or_number
enhancements.
@afercia would you be able to review and move this forward? I am happy to help with updating documentation and such
This ticket was mentioned in Slack in #core by martinshreder. View the logs.
7 years ago
#10
@
7 years ago
- Keywords needs-refresh added; needs-testing has-patch removed
Can you double check 40108.2.patch?
I applied it and it has a Parse error: syntax error, unexpected '}' in /srv/www/wordpress-develop/public_html/src/wp-includes/post-template.php on line 969
error from the preceding line lacking a ;
. Fixing that yielded an unexpected end of file error, so something is lacking a brace somewhere. I didn't keep digging though since I presume you have working code on your box and it was an issue in the patching.
Hi @mshumacher
You can always submit a patch, and see if it'll pass.
I have one ready with the changes you've made, if you're not familiar with how patches work, I can upload it here.