Reputation: 13666
I have a custom function in my Wordpress theme that looks for YouTube URLs and automatically converts them to embedded iframes. This works well, but there's one small issue. As it currently stands, the function also replaces YouTube links that are linked to text. So if I have an anchor tag pointing to YouTube, it throws the iframe code into the anchor and causes HTML issues.
So if I have a Wordpress post and I have the following content in the post, I want it to be converted to an iframe:
https://www.youtube.com/watch?v=HDDLTwS4zgs
But if I have text linked to YouTube, I do not want it to be converted:
<a href="https://www.youtube.com/watch?v=HDDLTwS4zgs">Check out Linus' latest video</a>
Here is my PHP function:
function convertYoutube($string) {
return preg_replace(
"/\s*[a-zA-Z\/\/:\.]*youtu(be.com\/watch\?v=|.be\/)([a-zA-Z0-9\-_]+)([a-zA-Z0-9\/\*\-\_\?\&\;\%\=\.]*)/i",
"<div class=\"embed-responsive embed-responsive-16by9 scroll-in\"><iframe width=\"560\" height=\"315\" src=\"//www.youtube.com/embed/$2\" frameborder=\"0\" allowfullscreen></iframe></div>",
$string
);
}
add_filter('the_content', 'convertYoutube');
Upvotes: 2
Views: 211
Reputation: 626728
The pattern can be fixed by adding a <a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|
alternative:
'~<a\b[^>]*>[^<]*</a>(*SKIP)(*FAIL)|\s*[a-zA-Z/:.]*youtu(be\.com/watch\?v=|\.be/)([\w-]+)([\w/*?&;%=.-]*)~'
See the regex demo.
Also note that /
do not need to be escaped if you use different regex delimiters. The .
outside a character class, [...]
, must be escaped to match a literal dot. \w
is equal to [A-Za-z0-9_]
if u
modifier is not used. A -
inside a character class, [...]
, does not have to be escaped at the start/end of the class (and after a range or shorthand character class).
Update pattern details
<a\b
- matchesa whole string <a
- [^>]*
- 0+ chars other than >
- >
- a >
symbol
- [^<]*
- 0+ chars other than <
- </a>
- a literal substring
- (*SKIP)(*FAIL)
- PCRE verbs to skip the match and go on to search for a new match at the end of the previous omitted match.
Upvotes: 1