Expand my Community achievements bar.

SOLVED

Enable JSON+LD Components in few pages

Avatar

Level 4

 i dont have much idea on JSON+LD
but i want to map the JSON+LD attributes to data we have available in my components , for few pages

what is best approach ?

1 Accepted Solution

Avatar

Correct answer by
Level 5

Hi @user96222 

Few links about what Schema Markup have already been posted. In addition you need to read about the specific structured data JSON-LD.

Now, about your question, you will need to design a good solution that reads that data stored in properties within those components you want and from the pages you want. I assume you will need to be able to control on which page you want the Schema Markup (SM) to be generated and with data from which components from that page. Because you will probably don't want a generic solution that automatically adds the SM for all pages using the whole data within that page.


At first sight I would say you can go with a global page sling model, that you can invoke probably in customheaderlibs.html (if you have one), and which will write the JSON structure in your HTML output:

 

<sly data-sly-use.model="com.domain.core.models.GlobalPageModel">
    <script type="application/ld+json">
    {
      "@context": "https://schema.org/",
      "@type": "Recipe",
      "name": "Party Coffee Cake",
      "author": {
        "@type": "Person",
        "name": "Mary Stone"
      },
      "datePublished": "2018-03-10",
      "description": "This coffee cake is awesome and perfect for parties.",
      "prepTime": "PT20M"
    }
    </script>
</sly>

 

(JSON example is from https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data)

In the model you can retrieve the current page:

 

@ScriptVariable private Page currentPage;

 

  • If you have one template for each page group for which you want to generate SM, you can use the template to check in the code for which page to generate the SM
  • If you have multiple pages with same template but still want to generate SM only for some of them, you can enhance your template definition and add an extra page property, a flag, that Editors can use to instruct your code to either generate or not SM for that given page instance.

Once you have established that you want to generate SM for the given requested page, then you can dive in through the components that were added to that page and get the data for the SM. Assuming you already have a Sling model for each component, you can enhance it and have a method that return a SM portion specific for that component. And then in the page model you can simply take each component resource, adapt it to the expected model, call the method to get the SM portion, and aggregate it with the rest of portions from the other components and obtain the final SM. Expose the SM and there you have it, you can add it in the HTML.

 

Few small notes:
- You can use Visitor pattern to traverse each component added in the list and based on the component type to adapt it to specific model: https://refactoring.guru/design-patterns/visitor
- Check to see if this library may help: https://github.com/Kobee1203/schema-org-java
- More info on schemas: https://schema.org/docs/schemas.html
- If you have CFs included in components or other references to data locations, from which some data you want to be in your SM, you will need ways to retrieve those also

- Consider to also have a way to validate your schemas. You can either do it manually using https://validator.schema.org/, or programmatically using a library like https://github.com/networknt/json-schema-validator (I don't know other)


I hope this helps !

View solution in original post

3 Replies

Avatar

Correct answer by
Level 5

Hi @user96222 

Few links about what Schema Markup have already been posted. In addition you need to read about the specific structured data JSON-LD.

Now, about your question, you will need to design a good solution that reads that data stored in properties within those components you want and from the pages you want. I assume you will need to be able to control on which page you want the Schema Markup (SM) to be generated and with data from which components from that page. Because you will probably don't want a generic solution that automatically adds the SM for all pages using the whole data within that page.


At first sight I would say you can go with a global page sling model, that you can invoke probably in customheaderlibs.html (if you have one), and which will write the JSON structure in your HTML output:

 

<sly data-sly-use.model="com.domain.core.models.GlobalPageModel">
    <script type="application/ld+json">
    {
      "@context": "https://schema.org/",
      "@type": "Recipe",
      "name": "Party Coffee Cake",
      "author": {
        "@type": "Person",
        "name": "Mary Stone"
      },
      "datePublished": "2018-03-10",
      "description": "This coffee cake is awesome and perfect for parties.",
      "prepTime": "PT20M"
    }
    </script>
</sly>

 

(JSON example is from https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data)

In the model you can retrieve the current page:

 

@ScriptVariable private Page currentPage;

 

  • If you have one template for each page group for which you want to generate SM, you can use the template to check in the code for which page to generate the SM
  • If you have multiple pages with same template but still want to generate SM only for some of them, you can enhance your template definition and add an extra page property, a flag, that Editors can use to instruct your code to either generate or not SM for that given page instance.

Once you have established that you want to generate SM for the given requested page, then you can dive in through the components that were added to that page and get the data for the SM. Assuming you already have a Sling model for each component, you can enhance it and have a method that return a SM portion specific for that component. And then in the page model you can simply take each component resource, adapt it to the expected model, call the method to get the SM portion, and aggregate it with the rest of portions from the other components and obtain the final SM. Expose the SM and there you have it, you can add it in the HTML.

 

Few small notes:
- You can use Visitor pattern to traverse each component added in the list and based on the component type to adapt it to specific model: https://refactoring.guru/design-patterns/visitor
- Check to see if this library may help: https://github.com/Kobee1203/schema-org-java
- More info on schemas: https://schema.org/docs/schemas.html
- If you have CFs included in components or other references to data locations, from which some data you want to be in your SM, you will need ways to retrieve those also

- Consider to also have a way to validate your schemas. You can either do it manually using https://validator.schema.org/, or programmatically using a library like https://github.com/networknt/json-schema-validator (I don't know other)


I hope this helps !

Avatar

Community Advisor

Hi, 

You can wrap the data within a script tag and then fill this info using the data retrieved from your sling Model, something like this:

<!-- /* HelloWorld.html */-->
<div class="cmp-helloworld" data-cmp-is="helloworld" data-sly-use.model="com.yourproject.core.models.HelloWorldModel">
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Person",
      "message": "${model.message @ context='text'}"
      "otherAttribute": "${model.otherAttribute @ context='html'}"
    }
    </script>
...

 So you can embed this at page level preferable, or at component level as well. Create a Sling Model that gives you all the data you need to expose in the JSON+LD script

 

 

I hope this helps.



Esteban Bustamante