3

I'm probably doing this all wrong, and there'll be a much simpler solution. Basically, I'm trying to build a table of tour dates that'll be editable by someone with little technical knowledge, but can handle shortcodes. There's also some custom functions in the table (with regards to displaying the date, and having an expiring ticket link) that makes me want to avoid a clunky table plugin.

So here's the code I'm experimenting with, that's working apart from it's introducing a
tag for each new line of and separate short code.

I don't want to disable wpautop completely, as it's used widely throughout the website and elsewhere on the page that this table will be appearing on.

[tour_table tour_name="The Tour Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[tour_table_line tour_date="2011-06-19" ticket_link="http://ticket.link/" venue="The Venue Name"]
[/table]

The parsing of the table is all handled in functions.php by the wrapping function tour_table() and the function [tour_table_line] which is executed inside a do_shortcode() function (from the wrapping function).

So the basic problem is that each new line is earning itself a new
tag, which is placing a massive space above the table.

If anyone has any more elegant solutions, or can help me get the functionality I'm looking for, I'd be very appreciative of your help.

If you need more detail, please let me know.

Edit to add functions (probably quite a bit of convoluted code in there:

function tour_table($atts,$content = null){
    extract( shortcode_atts( array(
        'tour_name' => '',
        'anchor_table' => ''
    ), $atts ) );

    if($anchor_table!=""){
        $hid = "id=\"tourscrollto\"";
    }else{
        $hid = "";
    }

    $theoutput = "<h3 $hid style=\"text-align: left; font-weight: strong; font-size: 12pt; margin-top: 20px;\">";
    $theoutput .= $tour_name;
    $theoutput .= "</h3><table class=\"tourdates\" style=\"font-size: 10pt;\" width=\"100%\"><tbody>";
    $theoutput .= do_shortcode($content);
    $theoutput .= "</tbody></table>";
    return $theoutput;
}

function tour_table_line($atts){
    extract( shortcode_atts( array(
        'tour_date' => '',
        'ticket_link' => '',
        'venue' => 'The Venue'
    ), $atts ) );

    $date_original = $tour_date;
    $date_unix = strtotime($tour_date);

    $theoutput = "<tr><td>";
    $theoutput .= date('D',$date_unix);
    $theoutput .= "</td><td>";
    $theoutput .= date('j M',$date_unix);
    $theoutput .= "</td><td>";
    $theoutput .= $venue;
    $theoutput .= "</td><td>";
    //$ticketlink = ticketlinkexpire($date_original,"<a href=\"$ticket_link\" target=\"_blank\">Buy Tickets</a>","");
    //$theoutput .= $ticketlink;
    $theoutput .= "</td></tr>";

    return $theoutput;

}

add_shortcode( 'tour_table' , 'tour_table' );
add_shortcode( 'tour_table_line' , 'tour_table_line' );
4
  • can you post your functions?
    – Bainternet
    Commented May 14, 2011 at 12:43
  • No probs (the ticketlinkexpire function isn't finished yet)
    – Will
    Commented May 14, 2011 at 13:48
  • Sidenotes: Single quotes are faster than double quotes and avoid escaping html-double quotes. Question: Doesn't the whole thing throw an error if not all $atts are set (see extract)? Also: Have you tried remove_action() for wp_autop at the beginning of the function and add_action() at it's end? Basically this just removes/adds the function to a global array.
    – kaiser
    Commented May 14, 2011 at 14:17
  • There's no error, as the => '' covers that (sets a default value if the attribute isn't set, at least according to WP documentation). Going from: codex.wordpress.org/Shortcode_API According to the page above, shortcode tags are parsed after wpautop, so removing it from the function itself won't do much good. I'll have another go though, and let you know if that was the solution.
    – Will
    Commented May 14, 2011 at 14:55

3 Answers 3

1

The extra space comes from wpautop(), which inserts <br /> on every line break. You have to strip these out before calling do_shortcode().

Additionally, use add_filter( 'the_content', 'shortcode_unautop' );. From my experience, you need both. Probably a bug.

See my shortcode plugin for an example. It has shortcodes for tables too.

Aside: Shortcodes should never be part of a theme, because you lock yourself or your client into using that theme now. See Justin Tadlock’s article.

2
  • Thank you for this! For others, the relevant line to strip <br/> tags from shortcodes is simply $content = str_replace('<br />', '', $content);
    – Nick
    Commented Jan 26, 2012 at 10:33
  • This solution works to remove the p tags, but leaves wpautop injected br tags in place (at least until this bug is resolved: core.trac.wordpress.org/ticket/14050). To get this to work, I had to also use Nick's solution in the comments. Commented Mar 22, 2012 at 21:24
1

I use this in functions.php and then bracket the code in the editor I don't want autop'd with <!-- noformat on --> and <!-- noformat off --> lines.

   // <!-- noformat on --> and <!-- noformat off --> function

function newautop($text)
{
    $newtext = "";
    $pos = 0;

    $tags = array('<!-- noformat on -->', '<!-- noformat off -->');
    $status = 0;

    while (!(($newpos = strpos($text, $tags[$status], $pos)) === FALSE))
    {
        $sub = substr($text, $pos, $newpos-$pos);

        if ($status)
            $newtext .= $sub;
        else
            $newtext .= convert_chars(wptexturize(wpautop($sub)));      //Apply both functions (faster)

        $pos = $newpos+strlen($tags[$status]);

        $status = $status?0:1;
    }

    $sub = substr($text, $pos, strlen($text)-$pos);

    if ($status)
        $newtext .= $sub;
    else
        $newtext .= convert_chars(wptexturize(wpautop($sub)));      //Apply both functions (faster)

    //To remove the tags
    $newtext = str_replace($tags[0], "", $newtext);
    $newtext = str_replace($tags[1], "", $newtext);

    return $newtext;
}

function newtexturize($text)
{
    return $text;   
}

function new_convert_chars($text)
{
    return $text;   
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'newautop');

remove_filter('the_content', 'wptexturize');
add_filter('the_content', 'newtexturize');

remove_filter('the_content', 'convert_chars');
add_filter('the_content', 'new_convert_chars');
0

Have you heard of gigpress ? This would give you the functionality you want in a nice wordpress like way (user friendly input). It would mean you'd have to throw some code away and modify your theme, but would save you a lot of time in the long run.

1
  • Yes, I've used it a few times before, but in this instance, we wanted to have more control over the output. Thanks for the suggestion though.
    – Will
    Commented May 14, 2011 at 13:47

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.