4

I have created a shortcode that retrives and displays top recommended posts based on a meta_key. There are different attributes, which all work, except for once where the content of the attribute is HTML.

Complete code is:

function dot_irt_top_posts ( $atts ) {

// get our variable from $atts
extract(shortcode_atts(array(
    'before' => '<li>',
    'after' => '</li>',
    'number' => '10',
    'post_type' => 'post',
    'year' => '',
    'monthnum' => '',
    'show_count' => '1',
), $atts));

global $wpdb;

$request = "SELECT * FROM $wpdb->posts, $wpdb->postmeta";
$request .= " WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id";

if ($year != '') {
    $request .= " AND YEAR(post_date) = '$year'";
}

if ($monthnum != '') {
    $request .= " AND MONTH(post_date) = '$monthnum'";
}

$request .= " AND post_status='publish' AND post_type='$post_type' AND meta_key='_recommended'";
$request .= " ORDER BY $wpdb->postmeta.meta_value+0 DESC LIMIT $number";
$posts = $wpdb->get_results($request);

$return = '';


foreach ($posts as $item) {
    $post_title = stripslashes($item->post_title);
    $permalink = get_permalink($item->ID);
    $post_count = $item->meta_value;

    $return .= $before;
    $return .= '<a href="' . $permalink . '" title="' . $post_title.'" rel="nofollow">' . $post_title . '</a> ';

    if ( $show_count == '1') {
        $return .= '<span class="votes">' . $post_count . '</span> ';
    }

    //$return .= get_the_post_thumbnail($item->ID, 'showcase-thumbnail');
    $return .= $after;

}
return '<div class="top_10_posts">' . $return . '</div>';

 }
 add_shortcode('irt_top_posts','dot_irt_top_posts');

Now if I use a shortcode as below, the data is returned properly as list.:

 <ul>
     [irt_top_posts post_type='showcase' number='10']
 </ul>

But if I set 'before' & 'after' attributes then they are displayed as content instead of being executed as html:

 <div>
     [irt_top_posts post_type='showcase'  before='<div>' after='</div>' number='10']
 </div>

Do I need some other functions to disable escaping HTML?

2 Answers 2

3

Pass just the element names and convert them to tags in your shortcode:

[irt_top_posts post_type='showcase'  container='div' number='10']

In your callback:

$return "<$container>$return</$container>";
2
  • This is the better solution.
    – epilektric
    Commented Sep 28, 2013 at 18:59
  • @toscho Thanks buddy. I used this approach as suggested by you in chat and feels more intune with WordPress. Commented Sep 29, 2013 at 1:24
2

Try using html_entity_decode().

function foo ( $atts ) {

    extract(shortcode_atts(array(
        'before' => '<li>',
        'after' => '</li>',
    ), $atts));

    $before = html_entity_decode( $before );
    $after = html_entity_decode( $after );

    $return = $before . 'something' . $after;

    return $return;

}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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