1

I have 2 shortcodes, [ref] and [references]. I need to get the content inside the [ref] shortcode and output it when the [references] shortcode is called.

For an example;

  • INPUT - This is some content in the webpage outside the shortcode. [ref] This is some content inside the shortcode "ref". [/ref] This is some other content. References : [references]

  • EXPECTED OUTPUT - This is some content in the webpage outside the shortcode. This is some other content. References : This is some content inside the shortcode "ref".

Here's the code that I've tried using, but I can't get it to display the content.

function ref_shortcode( $atts , $content = null ){
    ob_start();
    static $i=1;
    $return_value = '<a href="https://localhost/reference-list/?page_id=12&preview=true#references"><sup>['.$i.']</sup></a>';
    $i++;
    return $return_value;
    return ob_get_clean();
}
global $my_content;
$my_content = add_shortcode( 'ref', 'ref_shortcode' );

function references_shortcode( $atts , $content = null ){
    ob_start();
    global $my_content;
    return '<li>' . $my_content . '</li>';
    return ob_get_clean();
}
add_shortcode( 'references' , 'references_shortcode');

I have no issue with the function for the "ref" shortcode, if there's some way I can get content inside it to the "references" shortcode that would be great!

2

There is no definitive way of doing that in WordPress, but here are some options for you:

  1. Use a global variable to store the reference list, i.e. the content as in [ref]content here[/ref]. But I personally don't recommend and wouldn't be using global variable.

  2. Use a custom PHP class and add the shortcode functions as methods in that class, then use a property (e.g. private $ref_list = [];) to store the reference list. So for example inside the ref_shortcode() method, you could do $this->ref_list[] = $content;.

  3. Use the object caching API in WordPress, e.g. use wp_cache_set() to store the reference list.

And I'm not asking you to use the third option above, but since your code originally not in a PHP class, then here's a working example using the object caching API:

function ref_shortcode( $atts = array(), $content = null ) {
    if ( ! empty( $content ) ) {
        $post_id = get_the_ID();

        // Retrieve current list of references for the current post.
        $refs = wp_cache_get( "post_{$post_id}_references" );
        $refs = is_array( $refs ) ? $refs : array();

        // Then add the current reference to the list.
        $refs[] = $content;
        wp_cache_set( "post_{$post_id}_references", $refs );

        $j = count( $refs );
        return "<a href='#ref-$post_id-$j'><sup>[$j]</sup></a>";
    }

    return '';
}
add_shortcode( 'ref', 'ref_shortcode' );

function references_shortcode( $atts = array(), $content = null ) {
    $post_id = get_the_ID();
    $refs = (array) wp_cache_get( "post_{$post_id}_references" );
    $output = '';

    if ( ! empty( $refs ) ) {
        $output = '<h3>References</h3>';
        $output .= '<ul>';

        foreach ( $refs as $i => $ref ) {
            $j = $i + 1;
            $output .= "<li id='ref-$post_id-$j'>$ref</li>";
        }

        $output .= '</ul>';
    }

    return $output;
}
add_shortcode( 'references' , 'references_shortcode' );
3
  • Thanks a lot @Sally CJ, the code worked perfectly. Also the answer was really descriptive that really helped me a lot. May 31 '21 at 10:05
  • Is there any downside of using the object caching API in wordpress? I'll try do achieve this using a custom PHP class and share the code if it works. May 31 '21 at 10:07
  • The only maybe-a-downside is that the ref list will be, well, cached. Other than that, the default/core object caching class works pretty much like what I stated in the second option above.
    – Sally CJ
    May 31 '21 at 10:26

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.