0

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?

7
  • It's not about WordPress, it's about regexes.
    – Max Yudin
    Commented Mar 2, 2013 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.
    – fuxia
    Commented Mar 2, 2013 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
    Commented Mar 2, 2013 at 21:45
  • @MaxYudin As you can see by the answer this might be a XY problem, the regex might not even be needed.
    – fuxia
    Commented Mar 2, 2013 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
    Commented Mar 2, 2013 at 22:09

2 Answers 2

1

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.

0

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');

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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