Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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".

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?

share|improve this question
    
I rewrote your question using your new explanation. It's an interesting approach to solve this problem! There are other ways to do it (custom metadata), but this is probably the easiest to implement. –  Jan Fabry Apr 6 '11 at 14:19
add comment

5 Answers

up vote 0 down vote accepted

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'] );
}
share|improve this answer
    
Thanks a lot Jan, helped me a lot! I don't have widgets, but simple template files and right hand-side sidebar. So all worked well. Thanks a lot! :) –  dashaluna Apr 6 '11 at 14:08
add comment

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;
    }
    
share|improve this answer
    
I fixed your code formatting: you need four extra spaces because you are in a list. So the first four spaces are to add an extra line to the same list item, and the next four to start your code block. Trial and error can be a good teacher :-) –  Jan Fabry Apr 6 '11 at 14:14
    
@Jan Fabry: Thanks a lot! :) –  dashaluna Apr 11 '11 at 20:02
add comment

You can use conditional tags and do_shortcode. http://codex.wordpress.org/Function_Reference/do_shortcode
http://codex.wordpress.org/Conditional_Tags

A simple example for a single page with an ID of 12.

if is_single(12){
do_shortcode('[shortcode]');
}

If instead you wrote this shortcode yourself, you can create a function to give it a display parameter, like [shortcode('page=5, 6, 7', 'category', 'exclude=posts', 'whatever')]

share|improve this answer
    
Sorry I still not sure how I can do what I need. I want to display a specific [sc] shortcode within the sidebar (sidebar template) and suppress it when outputing the page's content where it's specified. Hope that makes sense. –  dashaluna Apr 4 '11 at 20:54
    
Unless you give specific code in your question, you're not going to get a specific answer back. –  Wyck Apr 4 '11 at 22:56
add comment

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/

share|improve this answer
add comment

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.. :)

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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