Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

For some reason I can not find any good solution to making the post images link to the post.

I found a script on http://wpguy.com/plugins/linked-image/ which works - but does not remove the old link, instead it wraps the old link and the image in a new a tag.

What I want is for the old link to be removed so the image is only wrapped in one a tag.

This is the script I currently have:

function wpguy_linked_image($content){

    $searchfor = '/(<img[^>]*\/>)/';
    $replacewith = '<a href="'.get_permalink().'">$1</a>';

    if (is_single() === FALSE){
        $content = preg_replace($searchfor, $replacewith, $content, 1);
    }
    return $content;

}

add_filter('the_content', 'wpguy_linked_image');

Does anyone have an idea?

share|improve this question
    
It's not about WordPress, it's about regexes. –  Max Yudin Mar 2 '13 at 17:22
    
@MaxYudin This is about WordPress. What tool one uses to solve a WordPress problem doesn’t matter: HTTP, JavaScript, PHP or regular expressions. –  toscho Mar 2 '13 at 18:37
    
@toscho I disagree. Original Poster already got the answer here:. This is not a place to fight. But I don't see regexes as part of WordPress. It's PERL legacy and so on. –  Max Yudin Mar 2 '13 at 21:45
    
@MaxYudin As you can see by the answer this might be a XY problem, the regex might not even be needed. –  toscho Mar 2 '13 at 21:48
    
Yes, @toscho. I agree, but how can we avoid XY? Nobody is reading FAQ, which is not full and is under construction for months. –  Max Yudin Mar 2 '13 at 22:09
show 2 more comments

2 Answers

Yes, don't use regex for parsing HTML but use DOM instead.

This is how I would work it out :

In your toolbox, a function to get innerDOM of a node :

// GET INNER HTML OF A NODE
function DOMinnerHTML($element)  
{ 
    $innerHTML = ""; 
    $children = $element->childNodes; 
    foreach ($children as $child) 
    { 
        $tmp_dom = new DOMDocument(); 
        $tmp_dom->appendChild($tmp_dom->importNode($child, true)); 
        $innerHTML.=trim($tmp_dom->saveHTML()); 
    } 
    return $innerHTML; 
} 

Then a filter to apply a custom function :

function change_destination_links_for_images( $content ) {   
    $dom = new DOMDocument();
    // THIS IS HACK TO LOAD STRING WITH CORRECT ENCODING
    // JUST OUTPUT <--?xml encoding="UTF-8"--> IN HTML SO NO HARM
    $dom->loadHTML( '<?xml encoding="UTF-8">' .  $content );

    // GET ALL <a> NODE
    foreach ( $dom->getElementsByTagName('a') as $node ) {
        // GET HREF 
        $link_href = $node->getAttribute( 'href' );
        // USE INNER OF THIS <a> NODE AS NEW DOC TO EXTRACT IMG
        $dom_node = new DOMDocument();
        $inner = DOMinnerHTML($node);
        $dom_node->loadHTML($inner);
        // CHECK IF IMAGE INSIDE THE LINK
        if ( $dom_node->getElementsByTagName('img') {
           // IF SO REPLACE HREF
           $node->setAttribute('href', get_permalink() );
           // RETURN MODIFIED DOM
           $content = $dom->saveHTML();
        }
    }
// RETURN CONTENT
return $content;
}
// APPLY FILTER
add_filter( 'the_content', 'change_destination_links_for_images' );

This is a quick adaptation of a working job I have done for another purpose so it may have errors in it. Hope this helps.

share|improve this answer
add comment

I finally found a soloution, I combined the script with a script which removes the orginal image links:

/**
 * Remove links from images
  */
add_filter( 'the_content', 'attachment_image_link_remove_filter' );
function attachment_image_link_remove_filter( $content ) {
    $content =
        preg_replace(array('{<a[^>]*><img}','{/></a>}'), array('<img','/>'), $content);
    return $content;
}


/**
 * Link images to post
 */
function wpguy_linked_image($content){

    $searchfor = '/(<img[^>]*\/>)/';
    $replacewith = '<a href="'.get_permalink().'">$1</a>';

    if (is_single() === FALSE){
        $content = preg_replace($searchfor, $replacewith, $content, 1);
    }
    return $content;

}

add_filter('the_content', 'wpguy_linked_image');
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.