I use this code to make clickable links from a string:
$string = "
<h2>This is a test</h2>
<p>Just a test to see if it works!</p>
<img src='./images/test.jpg' alt='test image' />
";
$wordtoconvert = "test";
$content = str_ireplace($wordtoconvert, "<a href='https://www.google.com' class='w3-text-blue'>" . $wordtoconvert . "</a>", $string);
This works almost perfect for me exept that i do NOT want to convert the word 'test' in de heading and image tag. I only want to convert everything between the paragraph tag.
How can that be done please?
CodePudding user response:
PHP - Make anchors of a given word in the paragraphs content of an html string
Here I show and explain a simpe demo implementing the function makeAnchorsOfTargetWordInHtml($html, $targetText)
using the DOMDocument
class available in php. The reason why it's unsafe performing string operations by yourself it's because the input html may have content you are not aware of when doing very basic string replacements that will break the consistency.
How to: parse an html string, make transformations on its nodes and return the resulting html string
As suggested in comments I think it would be much safer if you process the html content using a legit parser.
The idea is, starting from an html content string:
Parse it with
DOMDocument
Select all the
p
elements in the parsed html nodehttps://www.php.net/manual/en/domdocument.getelementsbytagname
Then, for each one of them:
Take the p tag string content (
->nodeValue
)*I think this approach will not work if the p node contains other nodes instead of just text (textNodes)
Split it in text fragments isolating the target word..
the point is producing an array of strings in the order they are found in the p content, including the target text as a separate element. So that for example if you have the string
"word1 word2 word3"
and the target is"ord"
the array we need is["w", "ord", "1 w", "ord", "2 w", "ord", "3"]
Empty the p node content
->nodeValue = ''
For each text fragments we had in the array we got before, create a new node and append it to the paragraph. Such node will be a new anchor node if the fragment is the target word, otherwise it will be a text node.
In the end take the whole parent node processed so far and return its html serialization with
->saveHTML()
Demo
<?php
$html = "<h2>This is a test</h2><p>Just a test to see if it works!</p><img src='./images/test.jpg' alt='test image' />";
$res = makeAnchorsOfTargetWordInHtml($html, 'test');
echo $res;
function makeAnchorsOfTargetWordInHtml($html, $targetText){
//loads the html document passed
$dom = new DOMDocument();
$dom->loadHTML($html);
//find all p elements and loop through them
$ps = $dom->getElementsByTagName('p');
foreach ($ps as $p) {
//grabs the p content
$content = $p->nodeValue;
//split it in text fragment addressing the targetText
$textFragments = getTextFragments($content, $targetText);
//reset the content of the paragraph
$p->nodeValue = '';
//for each text fragment splitting the content in segments delimiting the targetText
foreach($textFragments as $fragment){
//if the fragment is the targetText, set $node as an anchor
if($fragment == $targetText){
$node = $dom->createElement('a', $fragment);
$node->setAttribute('href', 'https://www.google.com');
$node->setAttribute('class', 'w3-text-blue');
}
//otherwise set $node as a textNode
else{
$node = $dom->createTextNode($fragment);
}
//appends the ndoe to the parent p
$p->appendChild($node);
}
}
//return the processed html
return $dom->saveHTML();
}
function getTextFragments($input, $textToFind){
$fragments = explode($textToFind, $input);
$result = array();
foreach ($fragments as $fragment) {
$result[] = $fragment;
if ($fragment != end($fragments)) {
$result[] = $textToFind;
}
}
return $result;
}
CodePudding user response:
You can use a regular expression to match only the text between the <p>
tags and replace the word "test" within that text. Here is an example of how you can accomplish this using the preg_replace()
function:
$content = preg_replace("/<p>(.*?)<\/p>/i", "
<p>".preg_replace("/".$wordtoconvert."/i", "<a href='https://www.google.com'
class='w3-text-blue'>".$wordtoconvert."</a>", "$1")."</p>", $string);
This regular expression matches anything that starts with <p>
and ends with </p>
, and stores the text in between in the first capturing group. The word "test" is then replaced with the desired link within the captured text. The resulting text is then used to replace the original <p>
tags in the input string.