
Recently I found Delink Pages 1.0 plugin by Jennifer Stuart. It promises something I was looking for:
This plugin will allow you to specify certain pages to not be linked when wp_list_pages() is used in a theme. You might want to do this if you want a header for a series of subpages, but don't specifically want that header to be a real page itself.
Instruction says:
To indicate that a page should not be linked when wp_list_pages() is used, edit the page that you do not want linked and create a custom field with a key of "delink" and value of "true".
Simple. Unfortunately it doesn't work. Below is the source code:
<?php add_filter('wp_list_pages', 'scripty_de_link'); function scripty_de_link($output) { $allpageids = get_posts(array('post_type' => 'page', 'numberposts' => -1)); foreach ($allpageids as $eachpage) { //get custom field value for delink $delinkthis = get_post_meta($eachpage->ID, "delink"); if ($delinkthis) { $newurl = preg_quote(get_permalink($eachpage->ID)); $output = preg_replace('@<a href="'.$newurl.'" (.*?)>(.*?)</a>@i', '$2', $output); } } return $output; } ?>
So, what's wrong with this code? Apparently, parameters of preg_replace function are incorrect. I'm too old and too lazy to analyze the regular expression being used. Don't get me wrong. I love regular expressions but I wouldn't use them if there is a simpler solution. By adding one function ( str_replace_count ) and changing two lines of the original code I made it to serve my purpose. The new code follows:
<?php add_filter('wp_list_pages', 'scripty_de_link'); function str_replace_count($find,$replace,$subject,$count) { $subjectnew = $subject; $pos = strpos($subject,$find); if ($pos !== FALSE) { while ($pos !== FALSE) { $nC = $nC + 1; $temp = substr($subjectnew,$pos+strlen($find)); $subjectnew = substr($subjectnew,0,$pos) . $replace . $temp; if ($nC >= $count) { break; } $pos = strpos($subjectnew,$find); } // closes the while loop } // closes the if return $subjectnew; } function scripty_de_link($output) { $allpageids = get_posts(array('post_type' => 'page', 'numberposts' => -1)); foreach ($allpageids as $eachpage) { //get custom field value for delink $delinkthis = get_post_meta($eachpage->ID, "delink"); if ($delinkthis) { $newurl = get_permalink($eachpage->ID); $output = str_replace_count($newurl, '#', $output, 1); } } return $output; } ?>
It does not strip the page link entirely but replaces it with href="#" which causes no action when you click on it. You can see it implemented in one of my websites - synagoguefund.com. Top navigation bar was constructed with wp_list_pages. Three pages - History, Videos, and Donations are dummy pages acting as parents to meaningfull subpages.
Hi Frank, I left you a comment on my site as well – I think you misunderstood the purpose of the plugin. My original intention was not to leave the text linked with href=”#” – it was to REMOVE the A (link) tag *entirely*… so it does work – but maybe not for the purpose you needed it. 🙂
However, it would make sense to make your addition an option. ie. Leave it up to the user to either have the link be removed entirely (no A tag at all) – or just remove the value of the href and have it replaced with “#”…
Hi Jennifer. What I meant saying that plugin didn't work is that it leaves output from wp_list_pages unchanged in any way. It applies to both versions 1.0 and 1.1. When I used standard string functions instead of preg_quote and preg_replace the plugin made intended changes ( delink,true – stripped link entirely, delink,href – made 'href="#"' change with no problem).