Last active
January 4, 2018 21:27
-
-
Save kingkool68/9277919 to your computer and use it in GitHub Desktop.
Plugin for handling the URLs to make infinite scrolling work properly on pages like this http://www.pewresearch.org/category/publications/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
jQuery(document).ready(function() { | |
//Set-up some constants. | |
var scrollTimeout; | |
var scrollUsePushStateInstead = false; //Set to true to make the history stack of the browser include every point when posts were loaded. It's kind of annoying. | |
var scrollDelay = 200; //Milliseconds | |
var scrollLoading = false; | |
var triggerOffset = $(document).height() - $('#pagination').siblings().eq(-4).offset().top; //The point of this is to do one calculation up front instead of multiple calculations every time the infinite scroll is triggered. | |
// Simple feature detection for History Management (borrowed from Modernizr) | |
function supportsHistory() { | |
return !!(window.history && history.pushState); | |
} | |
if( supportsHistory() ) { | |
$(window).on('scroll', function() { | |
toInfinityAndBeyond(); | |
}); | |
} | |
//The function that does all of the work. | |
function toInfinityAndBeyond() { | |
if( scrollLoading ) { | |
return; | |
} | |
//if( scrollTrigger < $(document).scrollTop()) { | |
if( $(document).height() - triggerOffset < $(document).scrollTop() + $(window).height() ) { | |
var nextURL = $('#pagination').find('.next').eq(0).attr('href'); | |
if( !nextURL ) { | |
return; | |
} | |
$.ajax({ | |
type: 'GET', | |
url: nextURL, | |
beforeSend: function() { | |
// block potentially concurrent requests | |
scrollLoading = true; | |
}, | |
success: function(data) { | |
$('#pagination').before( $(data).find('#content').html() ).remove(); | |
var newPageNum = nextURL.match(/\/page\/(\d+)\//)[1]; | |
regexp = /\/(pages?)\/([0-9]+)-?([0-9])*\/?$/; | |
var newPath = window.location.href; | |
if( regexp.test(newPath) ) { | |
parts = regexp.exec(newPath); | |
//Assign different parts to more understandable labels. Assume the following example: http://example.com/thing/pages/2-4/ | |
matchingPattern = parts[0]; // -> /pages/2-4/ | |
pageLabel = parts[1].toLowerCase(); // -> pages | |
pageStart = parts[2]; // -> 2 | |
pageEnd = parts[3]; // -> 4 | |
if( pageEnd > 0 && pageStart == 1 ) { | |
pageStart = pageEnd; | |
pageEnd = false; | |
} | |
var blackMagic = new RegExp(matchingPattern, 'ig'); | |
//We're dealing with /pages/x-x/ | |
replacement = '/pages/' + pageStart + '-' + newPageNum + '/'; | |
if( !pageEnd ) { | |
//We're dealing /page/x/ or /pages/x/ | |
replacement = '/pages/' + newPageNum + '/'; | |
if( pageLabel == 'page' ) { | |
replacement = '/pages/' + pageStart + '-' + newPageNum + '/'; | |
} | |
} | |
newPath = newPath.replace( blackMagic, replacement); | |
} else { | |
//There is no /page/ or /pages/ in the URL. We'll assume we can just append a new /pages/ path to the current URL. | |
newPath += 'pages/' + newPageNum + '/'; | |
} | |
newPath = '/' + newPath.split('/').slice(3).join('/'); | |
if( scrollUsePushStateInstead ) { | |
window.history.pushState(null, null, path); | |
} else { | |
window.history.replaceState(null, null, newPath); | |
} | |
// unblock more requests (reset loading status) | |
scrollLoading = false; | |
}, | |
dataType: "html" | |
}); | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Plugin Name: Pew Infinite Scroll | |
Description: "To infinity... and beyond!" | |
Author: Russell Heimlich | |
Author URI: http://www.russellheimlich.com/ | |
Version: 0.1 | |
*/ | |
//Lets make rewrites work properly | |
//$pageregex = $this->pagination_base . '/?([0-9]{1,})/?$'; | |
function pew_infinite_scroll_rewrite_rules() { | |
/* | |
global $wp_rewrite; | |
$rewrite_tags = array( | |
array( '%pages%', '/?([0-9]{1,}\-[0-9]{1,})/?$', 'pages='), | |
); | |
foreach( $rewrite_tags as $tag ): | |
$wp_rewrite->add_rewrite_tag( $tag[0], $tag[1], $tag[2] ); | |
endforeach; | |
*/ | |
add_rewrite_endpoint( 'pages', EP_ALL ); | |
} | |
add_action('init', 'pew_infinite_scroll_rewrite_rules'); | |
function pew_infinite_scroll_pre_get_posts( $query ) { | |
if ( is_admin() || !$query->is_main_query() ) | |
return; | |
if ( $query->is_archive() && ( $pages = pew_infinite_scroll_get_pages() ) ) { | |
$start = $pages->start; | |
if( $start == -1 ) { | |
$query->set( 'nopaging', true ); | |
} else { | |
$query->set( 'paged', $start ); | |
} | |
return; | |
} | |
} | |
add_action( 'pre_get_posts', 'pew_infinite_scroll_pre_get_posts' ); | |
function pew_infinite_scroll_post_limits( $limit ) { | |
global $wp_query; | |
if ( is_admin() || !$wp_query->is_main_query() ) { | |
return $limit; | |
} | |
if( $pages = pew_infinite_scroll_get_pages() ) { | |
if( $pages->start == -1 ) { | |
return $limit; | |
} | |
$new_limit = $pages->diff * $pages->posts_per_page + $pages->posts_per_page; | |
$limit = str_replace(', ' . $pages->posts_per_page, ', ' . $new_limit, $limit); | |
} | |
return $limit; | |
} | |
add_filter( 'post_limits', 'pew_infinite_scroll_post_limits' ); | |
function pew_infinite_scroll_wp() { | |
global $wp_query, $paged; | |
$pages = pew_infinite_scroll_get_pages(); | |
if( !$pages || !$pages->end ) { | |
return; | |
} | |
$wp_query->set('paged', $pages->end); | |
$paged = get_query_var( 'paged' ); | |
} | |
add_action( 'wp', 'pew_infinite_scroll_wp' ); | |
function pew_infinite_scroll_redirect_canonical( $redirect_url, $requested_url ) { | |
//Kill the canonical 'paged' redirect if the pages query var is set. In other words we don't want /category/publications/?pages=1-10 to redirect to /category/publications/page/10/?pages=1-10 which is what would happen by default. | |
if( get_query_var('pages') ) { | |
$redirect_url = trailingslashit($requested_url); | |
} | |
return $redirect_url; | |
} | |
add_filter( 'redirect_canonical', 'pew_infinite_scroll_redirect_canonical', 10, 2 ); | |
function pew_infinite_scroll_get_pagenum_link($result) { | |
if( $pages = pew_infinite_scroll_get_pages() ) { | |
$result = preg_replace('/pages\/([\d\-]+|all)\//i', '', $result); //Strip out anything that matches pages/{any digit or hypen or the word all}/ | |
} | |
return $result; | |
} | |
add_filter('get_pagenum_link', 'pew_infinite_scroll_get_pagenum_link'); | |
function pew_infinite_scroll_enqueue_script() { | |
if( is_archive() ) { | |
wp_enqueue_script( 'pew-infinite-scroll' ); | |
} | |
} | |
add_action( 'wp_enqueue_scripts', 'pew_infinite_scroll_enqueue_script' ); | |
/*** | |
* Helper Functions | |
***/ | |
function pew_infinite_scroll_get_pages() { | |
$pages_var = get_query_var('pages'); | |
if( !$pages_var ) { | |
return false; | |
} | |
$start = 1; | |
$end = false; | |
$pages = explode( '-', $pages_var ); | |
if( count($pages) < 2 && isset($pages[0]) && !empty( $pages[0] ) ) { | |
if( strtolower($pages[0]) == 'all' ) { | |
$start = -1; | |
$end = false; | |
} else { | |
$end = intval($pages[0]); | |
} | |
} else { | |
$pages = array_map('intval', $pages); | |
if( isset($pages[0]) && !empty( $pages[0] ) ) { | |
$start = $pages[0]; | |
} | |
if( isset( $pages[1] ) && !empty( $pages[1] ) ) { | |
$end = $pages[1]; | |
} | |
} | |
return (object) array( | |
'start' => $start, | |
'end' => $end, | |
'diff' => abs( $end - $start ), | |
'posts_per_page' => intval(get_option('posts_per_page')) | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Recommended reading: