Search code examples
phphtmlwordpressshortcodewordpress-shortcode

Output content of WordPress Shortcode in text and footer


I'm using a custom WordPress shortcode to add a modal to my content. The content of the modal is based on a Custom Post Type.

The shortcode looks like this:

[term value="Custom Link Title" id="123"]

The value="" argument is for the modal link in the content. The id="" is the ID of the Custom Post Type.

Inside the modal dialog window I display the content from the Custom Post Type based on it's ID.

The problem is, that the link and the modal dialog are outputted togehter. And because of the <div> of the modal, WordPress closes every <p> before it. And now there is a unwanted line break after the modal link.

Is there any way to display the modal link in the content area and put the modal dialog (the <div>) in the footer of the page?

Here's my shortcode:

add_shortcode('btn', 'bs_button');

// [term value="" id=""]
function shortcode_term($atts) {
   extract(shortcode_atts(array(
      'id' => '',
      'value' => '',
   ), $atts));


$modal_term = '<a href="#termModal_'.$id.'" class="" data-toggle="modal" data-target="#termModal_'.$id.'">'.$value.'</a>';

$modal_dialog = '<div class="modal fade" id="termModal_'.$id.'" tabindex="-1" role="dialog" aria-labelledby="termModal_'.$id.'_Title" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="termModal_'.$id.'_Title">'.get_the_title($id).'</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="icon-remove"></i></button>
            </div>
            <div class="modal-body">
                '.get_post_field('post_content', $id).'
            </div>
        </div>
    </div>
</div>';

return $modal_term.$modal_dialog;

}

add_shortcode('term', 'shortcode_term');

It would be nice if $modal_term stays in the content and $modal_dialog goes to the footer of the page.

Or is there any other way to prevent WordPress from adding a </p> before the modal dialog?

Here's whats happening in the frontend:

<p style="text-align: center;">noraml text from the editor <a href="#termModal_123" class="" data-toggle="modal" data-target="#termModal_123">Custom Link Title</a></p>
<div class="modal fade" id="termModal_123" tabindex="-1" role="dialog" aria-labelledby="termModal_123_Title" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="termModal_123_Title">Term Title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="icon-remove"></i></button>
            </div>
            <div class="modal-body">
                <h2>Head</h2>
                Term Content
            </div>
        </div>
    </div>
</div>
Rest of the normal Text from the editor

The </p> after the <a href="">..</a> souldn't be there.


Solution

  • You can hook into wp_footer from your shortcode function to return the modal dialog markup at the end of the document.

    function shortcode_term($atts) {
       extract(shortcode_atts(array(
          'id' => '',
          'value' => '',
       ), $atts));
    
    $modal_term = '<a href="#termModal_'.$id.'" class="" data-toggle="modal" data-target="#termModal_'.$id.'">'.$value.'</a>';
    $modal_dialog = '<div class="modal fade" id="termModal_'.$id.'" tabindex="-1" role="dialog" aria-labelledby="termModal_'.$id.'_Title" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="termModal_'.$id.'_Title">'.get_the_title($id).'</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="icon-remove"></i></button>
                </div>
                <div class="modal-body">
                    '.get_post_field('post_content', $id).'
                </div>
            </div>
        </div>
    </div>';
    
    add_action( 'wp_footer', function() use ( $modal_dialog ) {
      echo $modal_dialog;
    } );
    return $modal_term;
    }
    
    add_shortcode('term', 'shortcode_term');