0

I am currently working on a shortcode function, where I need to access the content of a post, before its rendering.

If I do it like this

$content = get_the_content( get_the_ID() );

It gives me the already rendered content. How can I access the content before rendering?

What I'm trying to do is create a shortcode, that generates a table of content from specific headlines that are placed with shortcodes. For that reason, the content still needs to have the unrendered shortcodes in it.

As requested, here is the complete code, so you might get an idea of what I am trying to do.


function nimaji_shortcodes() {

    add_shortcode( 'nimaji_toc', 'generate_toc' );

}

add_action( 'wp_head', 'nimaji_shortcodes' );

function generate_toc() {

    $content = get_the_content( get_the_ID() );
    krumo($content);

    // Look for specific shortcode, that has information about headlines in it
    $pattern = '/\[x_custom_headline level="(.*?)"(.*?)\](.*?)\[\/x_custom_headline\]/';

    preg_match_all( $pattern, $content, $matches );

    $levels = $matches[1];
    $titles = $matches[3];

    $toc_meta = generate_toc_meta( $levels, $titles );

    $html = '<ol>';

    foreach ( $toc_meta as $key_2 => $level2 ) {

        foreach ( $level2 as $key_3 => $level3 ) {

            if ( $key_3 == 0 ) {
                $html .= "<li>$level3</li>";
            } else if ( $key_3 == 1 ) {
                $html .= "<ol>";
                $html .= "<li>$level3</li>";
            } else if ( $key_3 == sizeof( $level2 ) - 1 ) {
                $html .= "<li>$level3</li>";
                $html .= "</ol>";
            } else {
                $html .= "<li>$level3</li>";
            }
        }

    }

    $html .= '</ol>';

    return $html;

}

function generate_toc_meta( array $levels, array $title ) {

    $new_levels = array();

    $i = - 1;
    $j = 0;
    foreach ( $levels as $key => $level ) {

        if ( $level == 'h2' ) {

            $i ++;
            $j                      = 0;
            $new_levels[ $i ][ $j ] = $title[$key];

        } else if ( $level == 'h3' ) {

            $j ++;
            $new_levels[ $i ][ $j ] = $title[$key];

        } else {

            continue;

        }

    }

    return $new_levels;
}
  • i think you have to use wordpress action , you may have to explain more about "before it is rendering" , is it after publishing a post? is it after every time a post loads? – Latheesh V M Villa Nov 21 '18 at 17:26
  • get_the_content() does not echo (print/output) content. But if you get_the_content() and then return $content, the shortcode itself is going to output that. So you might want to post more (if not all) of the shortcode function to provide context. – butlerblog Nov 21 '18 at 17:27
  • Ok, I added my code. "Before it is rendering" means, it still has the shortcodes in it, in plain text. – TheKidsWantDjent Nov 21 '18 at 17:38
  • 1
    Note that this won't work if any shortcodes add their own headings, those headings would be missing. I see you're trying to do this because you're using shortcodes for each heading though, would it not be easier to use the_content filter to insert the table of contents after the fact? – Tom J Nowell Nov 21 '18 at 17:43
  • Then I wouldn't be able to control where the toc appears. I want to be able to place it in specific posts. – TheKidsWantDjent Nov 21 '18 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.