I'm creating a plugin that enables the user to highlight certain words (long words, long sentences etc.) in the TinyMCE Editor.

You can see a live version here: https://tekstr.dk/app

I'm converting this into a WordPress plugin.

Marking the text with a yellow highlight works fine. I load my JS and alter the content of the TinyMCE editor. And bam. Highlights are made.

Trouble is that the highlights are made as actual markup in the HTML. Which means the content saved to the database contains sections such as this

This <mark class="highlighter"  data-markjs="true">sentence</mark> has one long word.

And then suddenly text is highlighted on the frontend too.

So I need a way to either disable the highlight via JS or PHP before the content is saved to the database.

I've tried a bunch of different options. Each have their own flaw.

Using content_save_pre to sanitize my way out of this

The code below works really well if I was to remove just <mark>something</mark>. But it simply doesn't remove anything when I include the class and data-markjs.

Am I targeting the tag in a wrong way when it includes attributes?

function remove_marks( $content ) {
    $output = str_replace( '<mark class="highlighter" data-markjs="true">', '', $content );
    $output = str_replace( '</mark>', '', $content);
    return $output;
add_filter( 'content_save_pre' , 'remove_marks' , 10, 1);

I also tried with the extra step like below. It actually works. All the tags are gone. Trouble is that it gives a lot of line breaks.

function remove_marks( $content ) {
    $string_html_on_lines = str_replace (array(" <mark",">"),array("\n<mark",">\n"), $content );
    $string_attribute_free = preg_replace("/\n(<[\w123456]+)\s.+/i","\n$1>",$string_html_on_lines);
    $output = str_replace( '<mark>', ' ', $string_attribute_free );
    $output = str_replace( '</mark>', ' ', $output );
    return $string_attribute_free;
add_filter('content_save_pre', 'remove_marks', 10, 1);

Using preg_replace and regex

I've also tried with preg_replace and a simple regex pattern. Not exactly a pattern, I know. But I thought it would work

function remove_marks( $content ) {
    $output = preg_replace("/<mark class=\"highlighter\" data-markjs=\"true\">/", "", $content);
    $output = preg_replace( '/<\/mark>/', '', $output );
    return $output;
add_filter('content_save_pre', 'remove_marks', 10, 1);

However it seems, that the first preg_replace regex do not work. I've tested the patterne here: https://en.functions-online.com/preg_replace.html?command={"pattern":"//","replacement":"","subject":"This sentence</mark> has one loing word","limit":-1}

In the tester it works fine. The start of the tag and attributes are removed. But when I use it in my function it doesn't work.

Triggering JavaScript before postupdate

Another thought was to simply trigger the simple JS function highlighting the text and thereby removing the highlight.

And I thought I could do this right before the save to database was made.

I've tried to fire this piece of JavaScript. It visually removes the highlights before post is updated. But the data is already sent to the database, so on load the tags are back in.

// Listen for submission on the post/update button
document.getElementById('post').submit(e => {
    // Sets the radio button to 'remove all highlights'
    document.getElementById('markerState0').checked = true;
    // Runs the function I use to highlight the text and removes it when markerState 0 is checked

Where do I go from here?

I can't seem to find the right way to clean up the tags with PHP or the right way to fire my JavaScript before the content is saved.

Any suggestions on how to do this seemingly simple task, the right hook to use or a better way to go about it are much appreciated.

Thanks in advance Mark

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.