UntitledGraphic
UntitledGraphic

Reputation: 1274

How do I add nested JSON-LD Schema entities in WordPress

Rather than using a plug-in I am in the process of creating my own schema markup for a home page on a WordPress site which makes use of Advananced Custom Fields (ACF) for some of the content relevant to this challenge. My aim is to give me a little more granular control over what is output and as a little personal challenge :)

So far I have successfully created a basic schema, but I have become stuck where I need to create a nested entity for a list of services.

currently I have this in my functions.php file:

function schema() {
    $schema = array(
        '@context'  => "http://schema.org",
        '@type'     => "ProfessionalService",
        'name'      => get_bloginfo('name'),
        'url'       => get_home_url(),
        // ... and so on 
    );

    if ( have_rows('services_list') ) {
        $schema['itemListElement'] = array();
        while (have_rows('services_list')) : the_row();
        $services = array(
            '@type'       => 'Offer',
            'itemOffered' => array (
                '@type'     => 'Service',
                'name'      => get_sub_field('service')
            )
        );
        array_push($schema['itemListElement'], $services);
        endwhile;
    }        
    echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');

Result:

{
    "@context":"http:\/\/schema.org",
    "@type":"ProfessionalService",
    "name":"Name of Company",
    "url":"http:\/\/www.whatever.com",
    and so on...
    "itemListElement": [
        {
            "@type":"Offer",
            "itemOffered": {
                "@type":"Service", 
                "name":"Service One"
            }
        },
        { 
            "@type":"Offer",
            "itemOffered": {
                "@type":"Service",
                "name":"Service Two"
            }
        },
        ... more services
    ]
}

This resulting markup is great, but I need to nest the itemListElement so that it outputs like so:

"hasOfferCatalog": {
    "@type": "OfferCatalog",
    "name": "Some Services",
    "itemListElement": [
        {
            "@type":"Offer",
            "itemOffered": {
                "@type":"Service", 
                "name":"Service One"
            }
        },
        { 
            "@type":"Offer",
            "itemOffered": {
                "@type":"Service",
                "name":"Service Two"
            }
        },
        ... more services

I can't for the life of me work out how this is done. My current best effort is to add it like so:

if ( have_rows('services_list') ) {
    'hasOfferCatalog'   => array(
        '@type'     => 'OfferCatalog',
        'name'      => 'Tree Surgery'
        $schema['itemListElement'] = array();
        while (have_rows('services_list')) : the_row();
        $services = array(
            '@type'       => 'Offer',
            'itemOffered' => array (
                '@type'     => 'Service',
                'name'      => get_sub_field('service')
            )
        );
        array_push($schema['itemListElement'], $services);
        endwhile;
    )
}

However this is not working at all. If anyone can point me in the right direction to the nested entities working in this context I'd be really grateful.

Upvotes: 1

Views: 616

Answers (1)

UntitledGraphic
UntitledGraphic

Reputation: 1274

I did eventually manage to solve my issue. I never got around to posting this at he time, but since here's been a little interest here's what I did.

My 'best effort' was almost there, but I needed to make a few small adjustments. Sadly I sorted this out sometime ago and I forget the resource I used to put things right, but I hope this might be of help to someone else.

if ( have_rows('services_list') ) {
    $schema['hasOfferCatalog'] = array();
    $catalog = array(
        '@type'     => 'OfferCatalog',
        'name'      => 'Tree Surgery'
    );
    if ( have_rows('services_list') ) {
        $catalog['itemListElement'] = array();
        while (have_rows('services_list')) : the_row();
        $services = array(
            '@type'       => 'Offer',
            'itemOffered' => array (
                '@type'     => 'Service',
                'name'      => get_sub_field('service')
            )
        );
        array_push($catalog['itemListElement'], $services);
        endwhile;
        array_push($schema['hasOfferCatalog'], $catalog);
    }
} 

Fr a little bit of context I have this all placed in my functions.php file and is put together like so:

function schema() {
    $schema = array(
        '@context'  => "http://schema.org",
        '@type'     => "ProfessionalService",
        'name'      => get_bloginfo('name'),
        'url'       => get_home_url(),
        'telephone' => '+00 0000 00000',
        'address'   => array(
            '@type'           => 'PostalAddress',
            'streetAddress'   => 'XXXXX',
            'postalCode'      => 'XXX XXX',
            'addressLocality' => 'XXXXXX',
            'addressRegion'   => 'XXXXXXX',
            'addressCountry'  => 'XXXXXXXXXXXX'
        ),
        'logo'      => get_stylesheet_directory_uri() . '/path/to/your/image.svg',
        'image'     => get_stylesheet_directory_uri() . '/path/to/your/image.svg'
    );

    if ( have_rows('services_list') ) {
        $schema['hasOfferCatalog'] = array();
        $catalog = array(
            '@type'     => 'OfferCatalog',
            'name'      => 'Tree Surgery'
        );
        if ( have_rows('services_list') ) {
            $catalog['itemListElement'] = array();
            while (have_rows('services_list')) : the_row();
            $services = array(
                '@type'       => 'Offer',
                'itemOffered' => array (
                    '@type'     => 'Service',
                    'name'      => get_sub_field('service')
                )
            );
            array_push($catalog['itemListElement'], $services);
            endwhile;
            array_push($schema['hasOfferCatalog'], $catalog);
        }
    }    
    echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
}
add_action('wp_head', 'schema');

It seems to do the job.

Upvotes: 1

Related Questions