Here's the code. Help please.
<?php $prevpost = substr(previous_post_link('<li>%link</li>', '« %title'),0,14); echo $prevpost; if (strlen($prevpost) > 14 ){ echo ' ...'; } ?>
Here's the code. Help please.
<?php $prevpost = substr(previous_post_link('<li>%link</li>', '« %title'),0,14); echo $prevpost; if (strlen($prevpost) > 14 ){ echo ' ...'; } ?>
I've been trying to solve the problem of too-long-titles myself.
The problem you're having is that the previous_post_link function echoes its output directly. It doesn't return a string for substr to then chop up and echo manually. The moment previous_post_link gets called in your code, BOOM, it gets echoed. So it's not being processed. A lot of WordPress functions are like this. If you want to capture the output to shorten it, you have to use output buffering, like this:
ob_start();
next_post_link('%link');
$next_post_link = ob_get_contents();
ob_clean();
previous_post_link('« %link');
$previous_post_link = ob_get_clean();
Now you have the links output as variables you can process, and nothing has been echoed to the screen yet.
But there still remains a problem. If you use the above code, the content of the $next_post_link variable is HTML and wrapped in an A tag. So you'll have succesfully captured, for example:
« Previous Post Title
Now if you try to run substr on that and add ellipses, you'll be butchering the HTML and breaking the page. It'll create something like:
« Previous Post Title<...
So you can see, it breaks the closing A tag and doesn't actually shorten the title. So if you did this you'd have to use a regular expression (like preg_replace) to find and shorten the title inside the tag. (WordPress should really add an argument to the functions to allow you to shorten it.)
The output buffer + regular-expression approach is the only one I've found so far, and I haven't implemented it yet because regular expressions are a colossal pain in the ass.
Darnit, the comment system converted some of what I typed above to code, so let me try again starting with the paragraph "But there still remains a problem:"
*snip*
But there still remains a problem. If you use the above code, the content of the $next_post_link variable is HTML and wrapped in an A tag. So you'll have succesfully captured, for example:
« <a href="http://www.example.com/prevpost">Previous Post Title</a>
Now if you try to run substr on that and add ellipses, you'll be butchering the HTML and breaking the page. It'll create something like:
« <a href="http://www.example.com/prevpost">Previous Post Title<...
*/snip*
A simpler way would be to notice that previous_post_link has a filter on it, so you can define a function to do what you like with it.
function my_filter($post_link_string, $link);
// modify $post_link_string here as you see fit, then return it.
// $link contains just the link, if you need to know that.
return $post_link_string;
}
add_filter('previous_post_link','my_filter');
No need to use output buffering.
Same goes for next_post_link, BTW.
I was just about to post my regex solution to this, but that's a brilliant find. I had no idea such a filter existed.
One problem though: there doesn't seem to be an actual 'previous_post_link' filter in the API (http://codex.wordpress.org/Plugin_API/Filter_Reference), just one for 'post_link' -- which the documentation seems to suggest would apply to all permalinks, which is not what I want. Am I wrong here? The filter documentation is:
post_link
applied to the calculated post permalink by the get_permalink function, which is also called by thethe_permalink,post_permalink,previous_post_link, andnext_post_linkfunctions. Filter function arguments: permalink URL, post data list.
Okay, I found out that the filter DOES exist, it's just not on the Plugin API page. It's here:
http://adambrown.info/p/wp_hooks/hook/%7B$adjacent%7D_post_link
So, thank you Otto! Now here is my solution:
function filter_shorten_linktext($linkstring,$link) {
$characters = 33;
preg_match('/<a.*?>(.*?)<\/a>/is',$linkstring,$matches);
$displayedTitle = $matches[1];
$newTitle = shorten_with_ellipsis($displayedTitle,$characters);
return str_replace('>'.$displayedTitle.'<','>'.$newTitle.'<',$linkstring);
}
function shorten_with_ellipsis($inputstring,$characters) {
return (strlen($inputstring) >= $characters) ? substr($inputstring,0,($characters-3)) . '...' : $inputstring;
}
// This adds filters to the next and previous links, using the above functions
// to shorten the text displayed in the post-navigation bar. The last 2 arguments
// are necessary; the last one is the crucial one. Saying "2" means the function
// "filter_shorten_linktext()" takes 2 arguments. If you don't say so here, the
// hook won't pass them when it's called and you'll get a PHP error.
add_filter('previous_post_link','filter_shorten_linktext',10,2);
add_filter('next_post_link','filter_shorten_linktext',10,2);
You simply place this in your theme folder's "functions.php" file and it will start working. Change $characters = 33; to the number of characters you want it to cut off at. I may write a plugin to do this, too; we'll see.
The documentation, as you have discovered, is incomplete. I suggest referring to the actual code in WordPress instead, it's easier to understand.
I put together a plugin to automate this fix. I applied for an account to post the plugin officially but haven't heard back yet, so for now, find the plugin and instructions and screenshots here:
http://www.filmtraveler.com/2008/11/18/wordpress-plugin-shorten-link-text/
Thanks for your help, Otto, in recommending the filter!
This topic has been closed to new replies.