• Resolved ermitanyo

    (@ermitanyo)


    Here’s the code. Help please.

    <?php
    $prevpost = substr(previous_post_link('<li>%link</li>', '&laquo; %title'),0,14);
    echo $prevpost;
    if (strlen($prevpost) > 14 ){
    echo ' ...';
    }
    ?>
Viewing 7 replies - 1 through 7 (of 7 total)
  • frame25

    (@frame25)

    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('&laquo; %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.

    frame25

    (@frame25)

    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:
    &laquo; <a href="https://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:
    &laquo; <a href="https://www.example.com/prevpost">Previous Post Title<...

    */snip*

    Moderator Samuel Wood (Otto)

    (@otto42)

    www.ads-software.com Admin

    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.

    frame25

    (@frame25)

    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 (https://codex.www.ads-software.com/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 the the_permalink, post_permalink, previous_post_link, and next_post_link functions. Filter function arguments: permalink URL, post data list.

    frame25

    (@frame25)

    Okay, I found out that the filter DOES exist, it’s just not on the Plugin API page. It’s here:
    https://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.

    Moderator Samuel Wood (Otto)

    (@otto42)

    www.ads-software.com Admin

    The documentation, as you have discovered, is incomplete. I suggest referring to the actual code in WordPress instead, it’s easier to understand.

    frame25

    (@frame25)

    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:
    https://www.filmtraveler.com/2008/11/18/wordpress-plugin-shorten-link-text/

    Thanks for your help, Otto, in recommending the filter!

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘substr() still echoing whole string | help’ is closed to new replies.