Hi I'm using the smarty templating engine in wordpress to generate HTML like the one below:

 <div class="checkbox_container" data-asin="B0009Y7APU"><input type="checkbox" class="ecom_compare_products" data-asin="B0009Y7APU" value="B0009Y7APU"/>
 <div class="small_img_container"><img class="related_product_image" src="img.jpg" alt="Case Logic JDS-2 USB Drive Shuttle 2-Capacity (Black/Blue)">
 <div class="title_container"><a href="">Case Logic JDS-2 USB Drive Shuttle 2-Capacity (Black/Blue)</a>

The problem is that it seems like Wordpress is removing the data attributes from this markup when the post is published. The markup above is what I actually got when I sent an email to myself.

$post_content = $smarty->fetch( 'product_detail.tpl' );

wp_mail('mymail@gmail.com', 'debug posting of products', 'content: ' . $post_content);

$post = array(
    'post_title' => $item_name,
    'post_content' => $post_content,
    'post_type' => 'post',
    'tags_input' => $amazon_keywords,
    'comment_status' => $allow_comments,
    'ping_status' => $allow_pingbacks,
    'post_status' => 'publish'


But when I edited the post that was published here's what I got:

   <div class="checkbox_container"></div><div class="small_img_container">
   <img class="related_product_image" src="img.jpg" alt="Case Logic JDS-2 USB Drive Shuttle 2-Capacity (Black/Blue)">
   <div class="title_container">
    <a href="">Case Logic JDS-2 USB Drive Shuttle 2-Capacity (Black/Blue)</a>

Its really weird. I don't have an idea how it turned out to be like this. But what's even weirder is that this only happens when the post is published using a scheduled event which I trigger by calling it from AJAX. The code for the mons_post_product is the actual publishing of the post.

add_action('ecom_scheduler', 'mons_post_product');

function ecom_schedule_event(){

    wp_schedule_single_event(time(), 'mons_scheduler');

add_action('wp_ajax_schedule', 'mons_schedule_event');
add_action('wp_ajax_nopriv_schedule', 'mons_schedule_event'); 

When hook up the method in the admin_menu there's no problem:

add_action('admin_menu', function(){

Any ideas?

  • Somewhat related, but I have a multisite installation and I'm able to add in code with data attributes, but it strips it out for another user once he hits publish. I've even tried to bump this user as an Admin but he is still having the same issue. Any idea? – rmlumley Jan 20 '16 at 20:59

Found the answer. I hope this would be useful to others that might have this problem in the future. All you have to do is remove the content_save_pre filter and content_filtered_save_pre this will remove all Kses input form content filters.

//temporarily disable
remove_filter('content_save_pre', 'wp_filter_post_kses');
remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');


//bring it back once you're done posting
add_filter('content_save_pre', 'wp_filter_post_kses');
add_filter('content_filtered_save_pre', 'wp_filter_post_kses');

This works with wp_insert_post as well.


I had the same issue, and the solution of Wern Ancheta worked for me BUT kses.

KSES is a recursive acronym which stands for “KSES Strips Evil Scripts". You don't want to disable that, right?! Especially, when automatically working with external contents.

My problem was, I updated a certain post via cron and i also inserted some data attributes and they got stripped, when the cron run. Btw. this problem didn't occur, when updating a custom field (update_post_meta), only on post_content (wp_update_post).

So the mission was, to make KSES accept my custom attributes, not to disable it.

So in the following solution KSES will not strip my custom data-start nor data-end attributes on posts and pages, when found inside the <tr> tag.

function jnz_add_kses_attributes($allowed, $context){
  if (is_array($context)) {
    return $allowed;

  if ($context === 'post' || $context === 'page') {
    $allowed['tr']['data-start'] = true;
    $allowed['tr']['data-end'] = true;
  return $allowed;
add_filter('wp_kses_allowed_html', 'jnz_add_kses_attributes', 10, 2);

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.