Posted on

Unyson

Unyson is a free drag & drop framework. It stores the content in a custom field fw:opt:ext:pb:page-builder:json. While Relevanssi can index custom fields, the Unyson custom field is a JSON object that’s hard for Relevanssi to index.

Fortunately you can add a function on the relevanssi_custom_field_value filter hook to modify the custom field value before Relevanssi sees it. Set Relevanssi custom field indexing to index fw:opt:ext:pb:page-builder:json and other fields you want to index. Do not use “visible” or “all”, because Unyson has meta data fields you don’t want to index. Then add this to your theme functions.php and build the index:

add_filter( 'relevanssi_custom_field_value', 'rlv_fw_json', 10, 2 );
/**
 * Filters the fw:opt:ext:pb:page-builder:json custom field value.
 *
 * Converts the JSON object to a string containing all title and text
 * elements in the object.
 *
 * @param array  $value All values of the custom field.
 * @param string $key   The name of the custom field.
 *
 * @return string The contents as a string.
 */
function rlv_fw_json( array $value, string $key ) : string {
    if ( 'fw:opt:ext:pb:page-builder:json' === $key ) {
        /**
         * The filter hook gives you an array, with all the values
         * of the named custom field. This custom field should only
         * appear once, so we just take $value[0].
         */
        $content = json_decode( $value[0] );
        $string  = '';
        foreach ( $content as $section ) {
            if ( isset( $section->atts->title ) ) {
                $string .= $section->atts->title;
            }
            if ( isset( $section->atts->text ) ) {
                $string .= $section->atts->text;
            }
            if ( isset( $section->_items ) ) {
                foreach ( $section->_items as $item ) {
                    if ( isset( $item->_items ) ) {
                        foreach ( $item->_items as $child_item ) {
                            if ( isset( $child_item->atts->title ) ) {
                                $string .= $child_item->atts->title;
                            }
                            if ( isset( $child_item->atts->text ) ) {
                                $string .= $child_item->atts->text;
                            }
                        }
                    }
                }
            }
        }
        $value[0] = $string;
    }
    return $value;
}

This function goes through the JSON object and picks up all the title and text elements from the top level of the array, and from all the child items of the top level items. This should cover most of the indexed content. It gets text elements added in the posts, and text elements inside other elements (like columns). The title element gets headings, text gets all the text box contents.

Of course, it’s also possible to modify this function to capture more content, or deeper hierarchies.

Leave a Reply

Are you a Relevanssi Premium customer looking for support? Please use the Premium support form.

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.