Display post shortcode content in the sidebar?

I need to display images and other content in the sidebar depending on a page. Pages are added dynamically and information that need to appear in the sidebar is different for each page. So I can’t predict what will go where. So the idea was is to have a page’s content as usual (with all the neccessary shortcodes) and then at the end of page content have a shortcode with all the info that needs to appear in the sidebar for that page.


Original question: displaying shortcodes selectively (suppress in the main content and instead display in a sidebar)

I was wondering if it’s possible to display shortcodes “selectively”.

Read More

For example, a specific shortcode, let’s call it [sc], is specified within a page content. Now, when displaying that page’s content I would like to suppress that specific [sc] shortcode, but instead display it from the sidebar for that page. Content of a page will have other shortcodes. I only want to do selectively display the specific [sc] shortcode and process others as usual – i.e. other shortcodes will be processed within the page’s content.

Is that possible to do? And how?

Related posts

Leave a Reply

5 comments

  1. A shortcode handler doesn’t have to return anything, it can just modify a global variable that you later read in your sidebar widget. If your sidebar is displayed after your post content (most likely if it’s a right sidebar), you can do this without any problem. If your sidebar is displayed before the post content it is more complicated: you have to start output buffering when your widget is called, wait until the rest of the page is displayed, and then do something with the shortcode content and flush the output buffer.

    A simple “proof of concept” that displays the shortcode content not in the post but in the footer:

    $wpse13925_shortcode_content = array();
    
    add_shortcode( '13925', 'wpse13925_shortcode' );
    function wpse13925_shortcode( $shortcode_attr, $shortcode_content )
    {
        $GLOBALS['wpse13925_shortcode_content'][] = $shortcode_content;
        return '';
    }
    
    add_action( 'wp_footer', 'wpse13925_footer' );
    function wpse13925_footer()
    {
        var_dump( $GLOBALS['wpse13925_shortcode_content'] );
    }
    
  2. I have based my solution on Jan Fabry's answer. I don’t have widgets, but simple template files.

    So, what I did is the following:

    1. Specified all the info that needs to appear in the sidebar within a page’s content itself wrapped in [sidebar_content] shortcode.

    2. Specified the following function in the functions.php. This expands all the content of [sidebar_content], but doesn’t display anything, but instead saves it in the global variable.

      global $sidebar_content;
      add_shortcode("sidebar_content", "my_sidebar_content");
      function my_sidebar_content($atts, $content = null){
          global $sidebar_content;
          if( !empty($content) ){
              $sidebar_content = do_shortcode($content);
          }
          return "";
      }
      
    3. In the sidebar.php. I have the following code:

      global $sidebar_content;
      if( isset($sidebar_content) && !empty($sidebar_content) ){
        echo $sidebar_content;
      }
      
  3. You could do it based on a custom field, for example create a custom field named sc_no_show and give it the value of true.
    then in your shortcode function do something like this:

    function what_ever(){
        global $post;
        $no_show = get_post_meta($post->ID,'sc_no_show',true);
        if ($no_show)
            return '';
        //add your normal shortcode stuff here
    }
    

    Now on every page or post you have a custom fields named sc_no_show with the value of true it wont show/

  4. You could use a few well placed actions to look ahead for your shortcode, if it’s found set a flag and run additional actions to first strip the content of that shortcode, then a secondary one to execute that shortcode in the sidebar. Alongside all that create a simple action of your own inside the sidebar file and hook onto that when you need to print out the shortcode.

    Not following? Don’t blame you, i’m not always good at explaining ideas, so here’s an example in code form..

    First, inside your sidebar where you want the shortcode content appear, add something like..

    <?php do_action( 'special_shortcode_content' ); ?>
    

    We now have an action we can hook onto when a flag gets set.

    Next we need to scan the posts, before the loop occurs, check for the existance of a particular shortcode, i’ll use [sc] as per your example and we can do that by hooking onto the_posts. Rather than using a global, i prefer to just wrap the code into a class, and define a class variable inside the class to act as the flag.

    class Page_Shortcode_to_Sidebar {
        private $has_shortcode = false;
        public function __construct() {
            if( is_admin() )
                return;
    
            add_action( 'the_posts', array( $this, 'check_for_shortcode' ) );
            add_filter( 'the_content', array( $this, 'remove_shortcode' ), 1 ); 
        }
        public function check_for_shortcode( $posts ) {
            if( empty( $posts ) )
                return $posts;
    
            if( !is_page() )
                return $posts;
    
            foreach( $posts as $post ) {
                if( !stripos( $post->post_content, '[sc]' ) )
                    continue;
                $this->has_shortcode = true;
            }
            return $posts;
        }
        public function remove_shortcode( $content ) {
    
            if( !$this->has_shortcode )
                return $content;
    
            $content = str_replace( '[sc]', '', $content );
            add_action( 'special_shortcode_content', array( $this, 'do_shortcode' ) );
    
            return $content;
        }
        public function do_shortcode() {
            ?>
            <li><?php do_shortcode('[sc]'); ?></li>
            <?php
        }
    }
    
    $Page_Shortcode_to_Sidebar = new Page_Shortcode_to_Sidebar;
    

    So basically what happens is this..

    1. The callback on the_posts checks each post for the shortcode, if found sets the flag.
    2. The callback on the_content executes later, and checks if the flag is set.
    3. If the flag is set, the shortcode is remove from the content and adds an action onto our custom sidebar action.
    4. It returns the content, minus the specific shortcode.
    5. The sidebar action occurs, and the shortcode content is produced.

    If you’re referring to your own shortcode that you created, and it’s use in this way..

    [sc]something[/sc]
    

    ..then you’ll need something smarter to strip the shortcode contents from the post content.

    If it’s not used like that, then what i’ve provided above should do the job just fine.

    Hope that helps.. 🙂