0

I have problem I can not solve for several days - I have shortcode which displays table with my CPT posts and it works fine standalone (when using of shortcode on one page/post) but not when using mulptile times on one page or post (there is no error but just the first shortcode is printed)

Here is my code:

if ( ! function_exists( 'odwpdp_add_shortcode_1' ) ) :
    function odwpdp_add_shortcode_1( $atts, $content = null ) {    
        global $wp;

        // Collect attributes
        $attrs = shortcode_atts( array(
            'count'           => 5,
            'title'           => __( 'Soubory ke stažení', ODWPDP_SLUG ),
            'show_title'      => 1,
            'show_pagination' => 1,
            'orderby'         => 'title',
            'order'           => 'ASC',
            'enable_sort'     => 1,
        ), $atts );

        // Sanitize attributes
        $attrs['count'] = (int) $attrs['count'] <= 0 ? -1 : (int) $attrs['count'];
        $attrs['show_title'] = (bool) $attrs['show_title'];
        $attrs['show_pagination'] = (bool) $attrs['show_pagination'];
        $attrs['enable_sort'] = (bool) $attrs['enable_sort'];

        $orderby = filter_input( INPUT_GET, 'odwpdp_orderby' );
        $order = filter_input( INPUT_GET, 'odwpdp_order' );

        $attrs['orderby'] = isset( $_GET['odwpdp_orderby'] ) ? $_GET['odwpdp_orderby'] : $attrs['orderby'];
        $attrs['order'] = isset( $_GET['odwpdp_order'] ) ? $_GET['odwpdp_order'] : $attrs['order'];
        $attrs['orderby'] = ! in_array( $attrs['orderby'], array_keys( odwpdp_get_avail_orderby_vals() ) ) ? 'title' : $attrs['orderby'];
        $attrs['order'] = ! in_array( $attrs['order'], array_keys( odwpdp_get_avail_order_vals() ) ) ? 'DESC' : $attrs['order'];

        // Prepare query arguments
        $query_args = array();
        $query_args['post_type'] = ODWPDP_CPT;
        $query_args['nopaging']  = ! $attrs['show_pagination'];
        $query_args['posts_per_page'] = $attrs['count'];
        $query_args['order'] = $attrs['order'];

        if ( $attrs['orderby'] == 'title' ) {
            $query_args['orderby'] = 'title';
        }
        else {
            $query_args['meta_query'] = array();
            $query_args['meta_query'][] = array(
                'key' => 'odwpdp-metabox-1',
                'type' => 'DATE'
            );
        }

        $odwpdp_paged = (int) filter_input( INPUT_GET, 'odwpdp_paged', FILTER_VALIDATE_INT );
        $query_args['paged'] = max( 1, $odwpdp_paged );

        // Create query
        $query = new WP_Query( $query_args );

        // Current URL
        $current_url = home_url( add_query_arg( array(), $wp->request ) );

        // Render template
        ob_start( function() {} );
        include_once( ODWPDP_PATH . '/templates/shortcode-1.phtml' );
        $html = ob_get_flush();

        return $html;
    }
endif;
add_shortcode( 'soubory_ke_stazeni', 'odwpdp_add_shortcode_1' );

And here is template file (shortcode-1.phtml):

<?php
/**
 * Template file for shortcode "Soubory ke stažení".
 * 
 * @todo Format dates by WordPress inner function!
 * 
 * Used variables (initialized in {@see odwpdp_add_shortcode_1()}).
 *
 * @var array    $attrs
 * @var string   $current_url
 * @var WP_Query $query
 * @var integer  $odwpdp_paged
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit();
}

$self_url = $current_url . '?odwpdp_paged=' . $odwpdp_paged;

/**
 * @internal Prints order arrows in files table head.
 * @param string $url
 * @param array  $atrs
 * @param string $cur
 * @return void
 */
function print_order( $url, $atrs, $cur ) {
?>
<span class="order-icons">
    <?php if ( $atrs['orderby'] == $cur && $atrs['order'] == 'ASC' ) : ?>
    <span title="<?php _e( 'Seřazeno vzestupně', ODWPDP_SLUG ); ?>" class="arrow-up used-order"></span>
    <?php  else : ?>
    <a href="<?php echo $url . '&amp;odwpdp_orderby=' . $cur . '&amp;odwpdp_order=ASC'; ?>" title="<?php _e( 'Seřadit vzestupně', ODWPDP_SLUG ); ?>" class="arrow-up"></a>
    <?php endif; ?>
    <?php if ( $atrs['orderby'] == $cur && $atrs['order'] == 'DESC' ) : ?>
    <span title="<?php _e( 'Seřazeno sestupně', ODWPDP_SLUG ); ?>" class="arrow-down used-order"></span>
    <?php else : ?>
    <a href="<?php echo $url . '&amp;odwpdp_orderby=' . $cur . '&amp;odwpdp_order=DESC'; ?>" title="<?php _e( 'Seřadit sestupně', ODWPDP_SLUG ); ?>" class="arrow-down"></a>
    <?php endif; ?>
</span>
<?php
}

?><div class="odwpdp-shortcode-1">
    <?php if ( (bool) $attrs['show_title'] === true && ! empty( $attrs['title'] ) ) : ?>
    <h2 class="odwpdp-shortcode-1-title"><?php echo esc_html( $attrs['title'] ); ?></h2>
    <?php endif;?>
    <table class="files-table">
        <thead>
            <tr>
                <th scope="col">
                    <span class="col-title"><?php _e( 'Název a velikost souboru', ODWPDP_SLUG ); ?></span>
                    <?php if ( $attrs['enable_sort'] === true ) : ?>
                        <?php print_order( $self_url, $attrs, 'title' ); ?>
                    <?php endif; ?>
                </th>
                <th scope="col">
                    <span class="col-title"><?php _e( 'Datum vyvěšení', ODWPDP_SLUG ); ?></span>
                    <?php if ( $attrs['enable_sort'] === true ) : ?>
                        <?php print_order( $self_url, $attrs, 'puton_date' ); ?>
                    <?php endif; ?>
                </th>
                <th scope="col">
                    <span class="col-title"><?php _e( 'Datum stažení', ODWPDP_SLUG ); ?></span>
                    <?php if ( $attrs['enable_sort'] === true ) : ?>
                        <?php print_order( $self_url, $attrs, 'putoff_date' ); ?>
                    <?php endif; ?>
                </th>
            </tr>
        </thead>
        <tbody>
        <?php if( $query->post_count > 0 ) : $posts = $query->get_posts(); ?>
            <?php foreach( $posts as $post ) :
                $puton_date   = get_post_meta( $post->ID, 'odwpdp-metabox-1', true );
                $putoff_date  = get_post_meta( $post->ID, 'odwpdp-metabox-2', true );
                $file_info    = odwpdp_get_file_info( $post->ID ); ?>
            <tr>
                <th scope="row">
                    <div class="file-info-cont">
                        <img src="<?php echo $file_info['icon_32']; ?>" class="file-icon">
                        <span class="file-info">
                            <?php printf(
                                '<a href="%s" class="file-link">%s</a><br><span class="file-size">%s %s</span>',
                                $file_info['url'],
                                $post->post_title,
                                __( 'Velikost:', ODWPDP_SLUG ), $file_info['size']
                            ); ?>
                        </span>
                    </div>
                </th>
                <td>
                    <?php if ( ! empty( $puton_date ) ) : ?>
                    <?php echo date( 'j.n.Y', strtotime( $puton_date ) ); ?>
                    <?php endif; ?>
                </td>
                <td>
                    <?php if ( ! empty( $putoff_date ) ) : ?>
                    <?php echo date( 'j.n.Y', strtotime( $putoff_date ) ); ?>
                    <?php endif; ?>
                </td>
            </tr>
            <?php endforeach; ?>
        <?php else: ?>
            <tr>
                <td colspan="3" class="no_items-row">
                    <p><?php _e( 'Nebyly nalezeny žádné soubory ke stažení.', ODWPDP_SLUG ); ?></p>
                </td>
            </tr>
        <?php endif; ?>
        </tbody>
        <?php if ( $attrs['show_pagination'] === true && $query->max_num_pages > 0 ) : ?>
        <tfoot>
            <tr>
                <td>
                    <?php printf( __( 'Celkem zobrazeno %d z %d položek.', ODWPDP_SLUG ), $query->post_count, $query->found_posts ); ?>
                </td>
                <td colspan="2">
                    <div class="pagination">
                        <?php if ( $odwpdp_paged <= 1 ) : ?>
                        <span title="<?php _e( 'První stránka', ODWPDP_SLUG ); ?>"><span>&laquo;</span></span>
                        <span title="<?php _e( 'Předchozí stránka', ODWPDP_SLUG ); ?>"><span>&lsaquo;</span></span>
                        <?php else : ?>
                        <a href="<?php echo $current_url . '?odwpdp_paged=1'; ?>" title="<?php _e( 'První stránka', ODWPDP_SLUG ); ?>"><span>&laquo;</span></a>
                        <a href="<?php echo $current_url . '?odwpdp_paged=' . ( $odwpdp_paged - 1 ); ?>" title="<?php _e( 'Předchozí stránka', ODWPDP_SLUG ); ?>"><span>&lsaquo;</span></a>
                        <?php endif; ?>
                        <?php for ( $i = 1; $i <= $query->max_num_pages; $i++ ) : ?>
                        <?php if ( $odwpdp_paged == $i ) : ?>
                        <span title="<?php _e( 'Aktuální stránka', ODWPDP_SLUG ); ?>"><span><?php echo $i; ?></span></span>
                        <?php else : ?>
                        <a href="<?php echo $current_url . '?odwpdp_paged=' . $i; ?>" title="<?php printf( __( 'Stránka číslo %d', ODWPDP_SLUG ), $i ); ?>"><span><?php echo $i; ?></span></a>
                        <?php endif; ?>
                        <?php endfor; ?>
                        <?php if ( $odwpdp_paged >= $query->max_num_pages ) : ?>
                        <span title="<?php _e( 'Následující stránka', ODWPDP_SLUG ); ?>"><span>&rsaquo;</span></span>
                        <span title="<?php _e( 'Poslední stránka', ODWPDP_SLUG ); ?>"><span>&raquo;</span></span>
                        <?php else : ?>
                        <a href="<?php echo $current_url . '?odwpdp_paged=' . ( $odwpdp_paged + 1 ); ?>" title="<?php _e( 'Následující stránka', ODWPDP_SLUG ); ?>"><span>&rsaquo;</span></a>
                        <a href="<?php echo $current_url . '?odwpdp_paged=' . $query->max_num_pages; ?>" title="<?php _e( 'Poslední stránka', ODWPDP_SLUG ); ?>"><span>&raquo;</span></a>
                        <?php endif; ?>
                    </div>
                </td>
            </tr>
        </tfoot>
        <?php endif; ?>
    </table>
</div>

Thanks for help. Full codes are on GitHub.

1

There's so much going on it the code in your question that it's hard to follow. Plus, you don't say what happens when you use the shortcode more than once in a given page/post).

Thus, I can't be sure, but I think the problem is that you need to call:

wp_reset_postdata () ;

at the end of your shortcode function, since your shortcode results in a Nested Loop.

Edit: with new solution

The problem is the:

include_once( ODWPDP_PATH . '/templates/shortcode-1.phtml' );

That file is, as the PHP func name implies, is only included the first time your odwpdp_add_shortcode_1() shortcode function is call...and since that file is what produces your output you get no output for other than the 1st use of your shortcode.

Thus, what you need to do is the following:

in shortcode-1.phtml

wrap the func def for print_order() is a !function_exists(), as in:

if (!function_exists ('print_order')) :
    function
    print_order ($url, $atrs, $cur)
    {
       // existing code for body of print_order()
    }
endif;

<!-- existing markup here -->

in file that defines odwpdp_add_shortcode_1()

change

include_once( ODWPDP_PATH . '/templates/shortcode-1.phtml' );

to

include ( ODWPDP_PATH . '/templates/shortcode-1.phtml' );

and you should be golden.

Hope this helps.

6
  • There is no error printed when I have multiple shortcodes on one page. And I do not need wp_reset_postdata because I'm using WP_Query without using methods that interacts with global $post object (but I tried it before). Feb 25 '17 at 22:36
  • What does happen when you use the shortcode twice? YOu don't get any errors, but do you get no output (on the 1st use?, on the second use? on both uses?)? Do you get the wrong output? Feb 25 '17 at 22:49
  • No error and only the first shortcode is printed. Feb 25 '17 at 22:51
  • I added link to full codes at the end of the question. Feb 25 '17 at 22:57
  • @OndřejDoněk: see my editing answer Feb 26 '17 at 0:03

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.