UPDATE: After I needed this myself, I reworked it completely.
The Goal
I wanted to point every get_permalink()
call directly to the paged post page – without any exception. At least this is the function used by nearly every other function that needs to link somewhere, so it imo also is the most reliable.
What the plugin does
It jumps in when WP is fully loaded and adds an action/callback function to the the_post
-hook. There it then checks the globals $numpages
(holds the number of pages a post has) and $pages
(holds the parts a post is splitted up by using <!--nextpost-->
in the content). If the number of pages is not larger than 1
, it aborts. Else it searches through the posts pages for the searched string. If it was found, then it sets the $link
class property to the page link using _wp_link_page()
. This link then gets attached inside the filters offered by get_permalink()
.
What for does it work?
It works for posts, pages & custom post types
The plugin
As everytime: Free for use. Grab it, use it. Have fun with it.
<?php
/**
* Plugin Name: (#31913) Search Results - direct link to page
*/
add_action( 'wp', array( 'search_direct_page_links', 'init' ) );
class search_direct_page_links
{
public static $instance;
public static $s;
public $link;
public static function init()
{
is_null( self :: $instance ) AND self:: $instance = new self;
return self :: $instance;
}
public function __construct()
{
if ( ! is_search() )
return;
is_null( self :: $s ) AND self :: $s = get_query_var( 's' );
add_action( 'the_post', array( $this, 'is_paged' ) );
}
public function is_paged( $post )
{
global $numpages, $pages;
// reset link:
$this->link = get_permalink();
// Remove filters attached from the last post
foreach ( array( 'post_link', 'page_link', 'post_type_link' ) as $filter )
{
remove_filter( $filter, array( $this, 'alter_link' ) );
}
if ( 1 >= $numpages )
return;
$target = 1;
foreach ( $pages as $i => $p )
{
if ( is_int( strpos( $p, self :: $s ) ) )
{
$target = absint( $i ) +1;
// Get the link now, as _wp_link_page()
// calls get_permalink() internally,
// which would lead to an endless nested loop.
$this->link = str_replace(
array( '<a href="', '">' )
,''
,_wp_link_page( $target )
);
}
}
if ( 1 < $target )
{
add_filter( 'post_link', array( $this, 'alter_link' ), 10, 3 );
add_filter( 'page_link', array( $this, 'alter_link' ), 10, 3 );
add_filter( 'post_type_link', array( $this, 'alter_link' ), 10, 4 );
}
}
public function alter_link( $permalink, $post, $leavename, $sample )
{
return $this->link;
}
}