Wordpress: Limit Tag Links in Post Content

2019-08-27 17:52发布

问题:

I really frustrated, I am a novice in wordpress I am trying to Limit Maximum Numbers of Tag Links to appear within post content article. Below is my code. I don't know how to fix it up.

function link_words( $text ) {

    $replace = array();
    $tags = get_tags();
$count=0;
    if ( $tags ) {
        foreach ( $tags as $tag ) {
            $count++;
            $replace[ $tag->name ] = sprintf( '<a href="%s">%s</a>', esc_url( get_term_link( $tag ) ), esc_html( $tag->name ) );
              if( $count > 2 ) break;
        }
    }

    $text = str_replace( array_keys($replace), $replace, $text );
    return $text;
}
add_filter( 'the_content', 'link_words' );

回答1:

If your tags are comma-separated, this might work for you:

            function limit_tags($tags) {
            $tags = substr($tags, 0, strpos($tags, ',', strpos($tags, ',')+1));
            return $tags;
            }
            add_filter('the_tags','limit_tags');

The $tags variable is actually a string...



回答2:

You mention your function works the way you want it to (linking tags) so I won't mess with that. If you look at the docs for get_tags(), you'll see it accepts a few arguments including number which will limit it. This way you won't have a $counter type variable to mess with.

You can also just check to see if the $tags variable gets set to a truthy value, you don't need to define it first.

Your str_replace is also occurring whether or not $tags is defined, which can cause issues if none are found, so you should move that up into the if statement.

For semantic clarity, I've also changed the $text variable to $content since you're using the_content filter.

add_filter( 'the_content', 'link_tags_in_content' );
function link_tags_in_content( $content ){
    if( $tags = get_tags( array( 'number' => 2 ) ) ){
        foreach( $tags as $tag ){
            $tag_link = sprintf( '<a href="%s">%s</a>', esc_url( get_term_link( $tag ) ), esc_html( $tag->name ) );
            $content  = str_replace( $tag->name, $tag_link, $content );
        }
    }

    return $content;
}


回答3:

Ok, so I think I understand what you want better now...

             function link_words( $text ) {
            $tags = get_tags();
            if ( $tags ) {
                foreach ( $tags as $tag ) {
                    $from = '!<h2>[^<>]*<\/h2>(*SKIP)(*F)|<b>[^<>]*<\/b>(*SKIP)(*F)|<a\b[^>]*>.*?</a>(*SKIP)(*F)|(\b'.$tag->name.'\b)(?=[^>]*(?:<|$))!';
                    $to = sprintf( ' <a href="%s">%s</a> ', esc_url( get_term_link( $tag ) ), esc_html( $tag->name ) );
                    $text = preg_replace($from, $to , $text, 2);
                }
            }
            return $text;
        }
        add_filter( 'the_content', 'link_words' );

Because of the limit on preg_replace (2), and it being inside the tag-loop, this replaces two instances of a tag name in the text for every tag... Is this along the lines of what you want? Be aware that this is not case-insensitive, so it will not match if your tag is the first word in a sentence, and is capitalized. To do something like that, maybe take a look at this thread: PHP preg_replace: Case insensitive match with case sensitive replacement