Advanced data modeling with Fragment References

It is possible to reference a Content Fragment from within another Content Fragments. This enables a user to build complex data models with relationships between Fragments.

In this chapter you will update the Adventure model to include a reference to the Contributor model using the Fragment Reference field. You will also learn how to modify a GraphQL query to include fields from a referenced model.

Prerequisites

This is a multi-part tutorial and it is assumed that the steps outlined in the previous parts have been completed.

Objectives

In this chapter, we’ll learn how to:

  • Update a Content Fragment Model to use the Fragment Reference field
  • Create a GraphQL query that returns fields from a referenced model

Add a Fragment Reference

Update the Adventure Content Fragment Model to add a reference to the Contributor model.

  1. Open a new browser and navigate to AEM.

  2. From the AEM Start menu navigate to Tools > Assets > Content Fragment Models > WKND Site.

  3. Open the Adventure Content Fragment Model

    Open the Adventure Content Fragment Model

  4. Under Data Types, drag and drop a Fragment Reference field into the main panel.

    Add Fragment Reference field

  5. Update the Properties for this field with the following:

    • Render As - fragmentreference
    • Field Label - Adventure Contributor
    • Property Name - adventureContributor
    • Model Type - Select the Contributor model
    • Root Path - /content/dam/wknd

    Fragment reference properties

    The property name adventureContributor can now be used to reference a Contributor Content Fragment.

  6. Save the changes to the model.

Assign a Contributor to an Adventure

Now that the Adventure Content Fragment model has been updated, we can edit an existing fragment and reference a Contributor. It should be noted that editing the Content Fragment model affects any existing Content Fragments created from it.

  1. Navigate to Assets > Files > WKND Site > English > Adventures > Bali Surf Camp.

    Bali Surf Camp folder

  2. Click into the Bali Surf Camp content fragment to open the Content Fragment Editor.

  3. Update the Adventure Contributor field and select a Contributor by clicking the folder icon.

    Select Stacey Roswells as contributor

    Select a path to a Contributor Fragment

    populated path to contributor

    Notice that only fragments created using the Contributor model are able to be selected.

  4. Save the changes to the fragment.

  5. Repeat the above steps to assign a contributor to adventures like Yosemite Backpacking and Colorado Rock Climbing

Query nested Content Fragment with GraphiQL

Next, perform a query for an Adventure and add nested properties of the referenced Contributor model. We will use the GraphiQL tool to quickly verify the syntax of the query.

  1. Navigate to GraphiQL tool in AEM: http://localhost:4502/content/graphiql.html

  2. Enter the following query:

    {
      adventureByPath(_path:"/content/dam/wknd/en/adventures/bali-surf-camp/bali-surf-camp") {
         item {
           _path
           adventureTitle
           adventureContributor {
             fullName
             occupation
             pictureReference {
            ...on ImageRef {
              _path
            }
          }
        }
      }
     }
    }
    

    The above query is for a single Adventure by it’s path. The adventureContributor property references the Contributor model and we can then request properties from the nested Content Fragment.

  3. Execute the query and you should get a result like the following:

    {
      "data": {
        "adventureByPath": {
            "item": {
                "_path": "/content/dam/wknd/en/adventures/bali-surf-camp/bali-surf-camp",
                "adventureTitle": "Bali Surf Camp",
                "adventureContributor": {
                    "fullName": "Stacey Roswells",
                    "occupation": "Photographer",
                    "pictureReference": {
                        "_path": "/content/dam/wknd/en/contributors/stacey-roswells.jpg"
                    }
                }
            }
         }
      }
    }
    
  4. Experiment with other queries like adventureList and add properties for the referenced Content Fragment under adventureContributor.

Update the React app to display Contributor content

Next, update the queries used by the React Application to include the new Contributor and display information about the Contributor as part of the Adventure details view.

  1. Open the WKND GraphQL React app in your IDE.

  2. Open the file src/components/AdventureDetail.js.

    Adventure Detail component IDE

  3. Find the function adventureDetailQuery(_path). The adventureDetailQuery(..) function simply wraps a filtering GraphQL query, which uses AEM’s <modelName>ByPath syntax to query a single Content Fragment identified by its JCR path.

  4. Update the query to include information about the referenced Contributor:

    function adventureDetailQuery(_path) {
        return `{
            adventureByPath (_path: "${_path}") {
            item {
                _path
                adventureTitle
                adventureActivity
                adventureType
                adventurePrice
                adventureTripLength
                adventureGroupSize
                adventureDifficulty
                adventurePrice
                adventurePrimaryImage {
                    ... on ImageRef {
                    _path
                    mimeType
                    width
                    height
                    }
                }
                adventureDescription {
                    html
                }
                adventureItinerary {
                    html
                }
                adventureContributor {
                    fullName
                    occupation
                    pictureReference {
                        ...on ImageRef {
                            _path
                        }
                    }
                }
              }
           }
         }
        `;
    }
    

    With this update additional properties about the adventureContributor, fullName, occupation, and pictureReference will be included in the query.

  5. Inspect the Contributor component embedded in the AdventureDetail.js file at function Contributor(...). This component will render the Contributor’s name, occupation and picture if the properties exist.

    The Contributor component is referenced in the AdventureDetail(...) return method:

    function AdventureDetail(props) {
        ...
        return (
            ...
             <h2>Itinerary</h2>
            <hr />
            <div className="adventure-detail-itinerary"
                 dangerouslySetInnerHTML={{__html: adventureData.adventureItinerary.html}}></div>
            {/* Contributor component is instaniated and 
                is passed the adventureContributor object from the GraphQL Query results */}
            <Contributer {...adventureData.adventureContributor} />
            ...
        )
    }
    
  6. Save the changes to the file.

  7. Start the React App, if not already running:

    $ cd aem-guides-wknd-graphql/react-app
    $ npm start
    
  8. Navigate to http://localhost:3000 and click an Adventure that has a referenced Contributor. You should now see the Contributor information listed below the Itinerary:

    Contributor Added in the App

Congratulations!

Congratulations! You’ve updated an existing Content Fragment Model to reference a nested Content Fragment using the Fragment Reference field. You also learned how to modify a GraphQL query to include fields from a referenced model.

Next Steps

In the next chapter, Production deployment using an AEM Publish environment, learn about AEM Author and Publish services and the recommended deployment pattern for headless applications. You will update an existing application to use environment variables to dynamically change a GraphQL endpoint based on the target environment. You will also learn how to properly configure AEM for Cross-Origin resource sharing (CORS).

On this page