Link to home
Start Free TrialLog in
Avatar of helpchrisplz

asked on

.append link inside a <H4> while in a php loop

Hi all

i have a php foreach loop that outputs html to the page with every loop.

i have a variable that stores the html inside it. this variable gets echo out on each loop.

what i want to do is update this variable (before it gets eco out) so that it has its old heading removed and update the contents of the heading to have an <a href> inside it.

The <a href> is also available as a variable with in the loop.

example: this is the output of the variable with <xmp> tags surrounding it

	<div class="lesson-desc-inner top-cat">
                  <div class="w-row">
                    <div class="w-col w-col-4 center">
                      <img class="pad-image" src="/sites/the_english_notebook/themes/theme_by_chris_sowerby/images/book%20icon.png" width="92" alt="52c6d55a9c7b16355f0002bd_book%20icon.png">
                    <div class="w-col w-col-8">
                      <div class="lesson-select-text-area">
                        <h4 class="reusable-heading">Module name will update...</h4>
                        <div class="text-contain">
                          <p>In the 2nd grade you learned to add and subtract 2-digit numbers. Now we take things further by adding and subtracting three-digit numbers. This is good practice for 4th grade where you&#039;ll be expected to add or subtract pretty much any whole number!</p>

Open in new window

so i need to update this part:

<h4 class="reusable-heading">Module name will update...</h4>

Open in new window

to look like this:

<h4 class="reusable-heading">
<a href="/sites/the_english_notebook/index.php/pick-your-key-stage/key-stage-1/verbs-2/" target="_self">verbs 3</a>

Open in new window

the <a href> can be  output within my loop like this:

<a href='<?php  echo $url ?>' target='<?php  echo $target ?>'><?php  echo $title ?></a>

Open in new window

so i just need to replace the old heading with the link but am not sure how i can break apart my html from its variable and add my link variables inside it at the correct places.

Thanks for helping.
Avatar of gr8gonzo
Flag of United States of America image

What does your foreach code look like?
Avatar of helpchrisplz


like this:

<?php  foreach ($pages as $page):
	$title = $th->entities($page->getCollectionName());
	$url = $nh->getLinkToCollection($page);
	$target = ($page->getCollectionPointerExternalLink() != '' && $page->openCollectionPointerExternalLinkInNewWindow()) ? '_blank' : $page->getAttribute('nav_target');
	$target = empty($target) ? '_self' : $target;

<?php $teaser = $plth->getPageTeaser($page, 'Description of this lesson', $teaserBlockCount, $teaserTruncateChars);		?>
	<a href="<?php  echo $url; ?>" target="<?php  echo $target; ?>"><?php  echo $title; ?></a>

	<?php  echo $teaser; // html code output here ?>
<?php  endforeach; ?>

Open in new window

Avatar of gr8gonzo
Flag of United States of America image

Link to home
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
yes that did it :) thanks

looks like i really need to learn how preg_replace works.

This baffles me:

 ("@(<h4 class=\"reusable-heading\">)([^<]+)(</h4>)@","\\1{$link}\\3",$teaser)
It starts with the syntax:



$teaser = preg_replace("/e/","a", $teaser);

...would change every "e" with an "a".

Regular expressions need delimiters to indicate when they should start and stop, which is why there are / around the "e". The delimiter can be just about any non-alpha-numeric character, so you could use @ or %, for example:

$teaser = preg_replace("/e/","a", $teaser);
$teaser = preg_replace("%e%","a", $teaser);
$teaser = preg_replace("@e@","a", $teaser);

All three lines do the exact same thing. The / is simply the most common version. People use different delimiters to avoid having to escape characters in their regular express that also happen to be the delimiter. For example, if you wanted to change all instances of "/h4>" to the word "blah", you might think of doing this:

$teaser = preg_replace("/</h4>/","blah",$teaser);

...however that / right before h4 is also the regular expression delimiter, so this would throw an error because the regular expression engine doesn't know whether you're trying to end the regular expression or if you're looking for the / character. So you can either escape the / with a backslash \ or you can use a different delimiter:

$teaser = preg_replace("/<\/h4>/","blah",$teaser);
$teaser = preg_replace("@</h4>@","blah",$teaser);

When I'm working with HTML, I usually use the @ delimiter so I don't have to keep escaping every forward slash character.

Now, when you use parentheses, you're "capturing" that content temporarily and you can use it in your output. For example:

$teaser = "The quick brown fox.";
$teaser = preg_replace("@(quick) (brown) (fox)@", "\\3, which is \\1 and \\2", $teaser);

The first word "quick" is capture number 1, "brown" is capture number 2, and "fox" is capture number 3. In the second part of preg_replace, you see \\1, which means "the value of capture 1", \\2 which means "the value of capture 2", and \\3, which means "the value of capture 3". So the above would result in $teaser being "The fox, which is quick and brown.";

Finally, the last "magic" piece of the regex was this: [^<]+. Put simply, it means "every character that ISN'T the < character. So if I had this:

$teaser = "The quick brown fox.";
$teaser = preg_replace("@(quick) ([^n]+n) (fox)@", "\\3, which is \\1 and \\2", $teaser);

... I would still get the same result as before. The regular expression in the middle says "any character except for n". The regular expression goes character-by-character. It starts with "b", which is not "n", so it gets added. Then "r", which is not "n", so it also gets added, and so on. It finally gets to the point where "brow" is captured, and then the regular expression sees an "n", so it stops. However, since I want the "n", too, I have it as part of my capture, so the second capture group is really two expressions: [^n]+ and then the letter "n". Together, you get "brown". This isn't the most useful regular expression with that phrase, but in HTML, it's a pretty simple way sometimes to get the inner content of a tag, because it's matching everything EXCEPT for the beginning of the next tag, which starts with <. So:

$teaser = "Hello <sometag>World</sometag>!";
$teaser = preg_replace("@<sometag>([^<]+)</sometag>@", "\\1", $teaser);

...would result in "Hello World!"

So what I did with your content is capture the whole <h4> starting tag as capture #1, all of the content leading up to the </h4> ending tag as capture #2, and then the </h4> ending tag itself as capture #3. Then I replaced it all with capture #1 (the starting H4 tag), followed by the link HTML, followed by capture #3 (the ending H4 tag).

I didn't need to capture the content of your H4 tag as capture #2, but I wasn't sure if you were going to use it, so I figure it would be easier to write the more "complete" regex up front and if you wanted to reuse the content somehow (like as the link text), you could just throw \\2 in there somewhere.

Hopefully that all makes sense. Once you know regular expressions well, this type of stuff isn't very difficult. It looks FAR more complicated than you think it is. I also use a free tool called The Regex Coach all the time to help me see what my regular expressions are doing as I write them.