0

I'm using ACF advanced custom fields plugin to create custom fields for my CPT where i replaced the content editor of my CPTs with a custom Wysiwyg Editor field (field name: full_text) from ACF in which i enter the main text of the CPT(I really need that for specific reasons). But, when i tried to use toc+ to generate a table of content from the text in the custom field editor it shows nothing. Actually on the plugin page they wrote that:

Custom post types are supported, however, auto insertion works only when `the_content()` has been used by the custom post type. Each post type will appear in the options panel, so enable the ones you want.

In the plugin toc.php file I noticed that exactly:

        public function extract_headings( &$find, &$replace, $content = '' )
    {
        $matches = array();
        $anchor = '';
        $items = false; 
        // reset the internal collision collection as the_content may have been triggered elsewhere
        // eg by themes or other plugins that need to read in content such as metadata fields in
        // the head html tag, or to provide descriptions to twitter/facebook
        $this->collision_collector = array();
        if ( is_array($find) && is_array($replace) && $content ) {
            // get all headings
            // the html spec allows for a maximum of 6 heading depths
            if ( preg_match_all('/(<h([1-6]{1})[^>]*>).*<\/h\2>/msuU', $content, $matches, PREG_SET_ORDER) ) {
                // remove undesired headings (if any) as defined by heading_levels
                if ( count($this->options['heading_levels']) != 6 ) {
                    $new_matches = array();
                    for ($i = 0; $i < count($matches); $i++) {
                        if ( in_array($matches[$i][2], $this->options['heading_levels']) )
                            $new_matches[] = $matches[$i];
                    }
                    $matches = $new_matches;
                }
                // remove specific headings if provided via the 'exclude' property
                if ( $this->options['exclude'] ) {
                    $excluded_headings = explode('|', $this->options['exclude']);
                    if ( count($excluded_headings) > 0 ) {
                        for ($j = 0; $j < count($excluded_headings); $j++) {
                            // escape some regular expression characters
                            // others: http://www.php.net/manual/en/regexp.reference.meta.php
                            $excluded_headings[$j] = str_replace(
                                array('*'), 
                                array('.*'), 
                                trim($excluded_headings[$j])
                            );
                        }
                        $new_matches = array();
                        for ($i = 0; $i < count($matches); $i++) {
                            $found = false;
                            for ($j = 0; $j < count($excluded_headings); $j++) {
                                if ( @preg_match('/^' . $excluded_headings[$j] . '$/imU', strip_tags($matches[$i][0])) ) {
                                    $found = true;
                                    break;
                                }
                            }
                            if (!$found) $new_matches[] = $matches[$i];
                        }
                        if ( count($matches) != count($new_matches) )
                            $matches = $new_matches;
                    }
                }
                // remove empty headings
                $new_matches = array();
                for ($i = 0; $i < count($matches); $i++) {
                    if ( trim( strip_tags($matches[$i][0]) ) != false )
                        $new_matches[] = $matches[$i];
                }
                if ( count($matches) != count($new_matches) )
                    $matches = $new_matches;
                // check minimum number of headings
                if ( count($matches) >= $this->options['start'] ) {
                    for ($i = 0; $i < count($matches); $i++) {
                        // get anchor and add to find and replace arrays
                        $anchor = $this->url_anchor_target( $matches[$i][0] );
                        $find[] = $matches[$i][0];
                        $replace[] = str_replace(
                            array(
                                $matches[$i][1],                // start of heading
                                '</h' . $matches[$i][2] . '>'   // end of heading
                            ),
                            array(
                                $matches[$i][1] . '<span id="' . $anchor . '">',
                                '</span></h' . $matches[$i][2] . '>'
                            ),
                            $matches[$i][0]
                        );
                        // assemble flat list
                        if ( !$this->options['show_heirarchy'] ) {
                            $items .= '<li><a href="#' . $anchor . '">';
                            if ( $this->options['ordered_list'] ) $items .= count($replace) . ' ';
                            $items .= strip_tags($matches[$i][0]) . '</a></li>';
                        }
                    }
                    // build a hierarchical toc?
                    // we could have tested for $items but that var can be quite large in some cases
                    if ( $this->options['show_heirarchy'] ) $items = $this->build_hierarchy( $matches );
                }
            }
        }
        return $items;
    }

where you can notice that the function works with $content. But is there any way to make it work with the custom field created with ACF? or, have ou any suggestions to solve this problem?

0

You can use the the acf/save_post action to copy the content from your custom 'full_text' field over to the normal post content field, so it can automatically be accessed by toc+ and other plugins.

add_action( 'acf/save_post', 'wpse199256', 20 );

function wpse199256( $post_ID ) {
    global $wpdb;
    $post = get_post( $post_ID );
    $wpdb->update( $wpdb->posts, array( 'post_content' => get_field( 'full_text', $post_ID ), array( 'ID' => $post_id ) );
}

Depending on how you use your CPT this will lead to some templates etc. having to be adapted, if they were outputting the content field (which was empty until now).

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.