Reputation: 11
I'm trying to write a function that will overwrite any <a>
tag with a .mp3 URL with the Wordpress audio shortcode.
I'm pulling posts into Wordpress from an api — so I can't manually add the audio shortcode to mp3 links in each post — or even have the mp3 URL on its own line, which would automatically generate the shortcode. The posts are radio stories. Each begins with an <a>
tag structured exactly like this:
<a href="https:storyurl.mp3" class="asset-audio">Hear the radio version of this story.</a>
And I believe this is what I need to convert that tag into:
[audio mp3="https:storyurl.mp3" class="asset-audio" title="Hear the radio version of this story."]
There are audio player plugins that will recognize any mp3 and wrap it in its own shortcode, but Wordpress doesn't do this by default with its core mediaelement.js. I hope to accomplish that in my child theme's functions.php.
Upvotes: 1
Views: 685
Reputation: 1
Paste the code in your javascript file and it will solve your issue. I hope so.
$('.asset-audio').each(function(){
var newtag = "[audio mp3="+ $(this).attr('href') +" class="+
$(this).attr('class') +" title="+ $(this).html() +"]";
$(this).after(newtag);
$(this).remove();
});
Upvotes: 0
Reputation: 729
Yeah, Regex (Regular Expressions) are pretty powerful. Here's how I'd do the replace:
$reg = "#<a [^>]*href=['\"]([^\"']+\.mp3)['\"][^>]*>(.*?)</a>#";
$content = preg_replace($reg, "[audio mp3='$1' class='asset-audio' title='$2']", $content);
Where $content
is whatever variable that holds the content of the post. I'll explain what the regex is doing:
"#" - The first and last characters are delimiters. They're not actually part of the match
"<a " - The start of a link tag
"[^>]" - the [] means it's looking for any of a group of characters. The ^ is a negator, meaning "NOT." The "" means 0 or more of these characters. Altogether it means "Look for 0 or more of any character accept ">", which keeps us inside the "a" tag.
"href=" - just to find that text
"['\"]" - The opening quotation mark
"([^\"']+.mp3)" - The parenthesis lets us access this string later (in the replace part). the bracketed part means we're looningh for any character accept the closing quote (since neither quote characters usually show up in a link, we're mostly safe doing this). The "+" means it's looking for 1 or more of these characters. The . means a literal period chacacter, and mp3 (so we only match mp3 links!)
"['\"]" - The closing quote
"[^>]*>" - Any number of non-">" characters, followed by >
"(.*?)" - Parenthesis again to capture this string. The "." means any character, the * means 0 or more, and the "?" means to not be aggressive... as in to match as few characters as possible (otherwise it will keep going until the closing tag of the last link in the post
"</a" - to make sure we get all the way to the closing tag
In the replacement part, notice $1 and $2. Those refer to the first and second parenthesis in the match.
This is not a complete explanation of all that's going on with regex, and it's not a 100% perfect solution, but it should work in your case at almost 100%. Regex is practically a language unto itself and there's a lot to research there. I encourage you to learn it and get good at it, because there are a lot of uses for it!
I also didn't answer the rest of your question, namely how to intercept and change the post content on its way from the database to the screen. If you need help on that side, too, let me know.
EDIT------------------------
Here's how I'd do it in a plugin or functions.php file:
add_filter( 'the_content', 'myprefix_use_audio_short_tag' );
function myprefix_use_audio_short_tag( $content ) {
$reg = "#<a [^>]*href=['\"]([^\"']+\.mp3)['\"][^>]*>(.*?)</a#";
$content = preg_replace($reg, "[audio mp3='$1' class='asset-audio' title='$2']", $content);
return $content;
}
The "Add Filter" function with "the_content" as the filter adds your function to the queue of functions that have to run against the post content every time it's accessed from the database. This should have your desired result.
Upvotes: 2