oo

Managing Web Content Structures and Templates by Using the REST API

Web content structures define the information included in a web content article. Structures facilitate creating and managing web content while ensuring that the content includes all the required information.

You can associate a structure with a web content template. A template determines how content fields are rendered on a page. The following table summarizes the available options using the Liferay DXP REST API with web content structures and templates:

Available Options Unavailable Options
Gather Structures and Templates information Create Structures or Templates
Replace Structures permissions Delete Structures or Templates

Use a pre-built Liferay DXP Docker image with several cURL code samples to learn how to manage structured content:

Setting Up Your Environment

Start a new Liferay DXP instance by running

docker run -it -m 8g -p 8080:8080 liferay/dxp:2024.q1.1

Sign in to Liferay at http://localhost:8080 using the email address test@liferay.com and the password test. When prompted, change the password to learn.

Then, follow these steps:

  1. Download and unzip the sample project:

    curl https://resources.learn.liferay.com/dxp/latest/en/content-authoring-and-management/web-content/developer-guide/liferay-m7b1.zip -O
    
    unzip liferay-m7b1.zip
    
    Warning

    These scripts use basic authentication and are designed for testing. Do not use basic authentication in a production Liferay DXP environment.

Identifying the Site ID

  1. Open the Site menu (Site menu) and go to ConfigurationSite Settings.

  2. Under the Platform section, click Site Configuration.

  3. Find the Site identifier under Site ID.

    Find the Site ID under the Site Settings and Site Configuration option.

Creating the Web Content Structure and Template Samples

Note

You can only create structures or templates manually through the user interface.

Create a basic web content structure and a basic web content template based on the structure. This tutorial uses a basic structure with a single Text field to demonstrate the ContentStructure service.

Basic sample web content structure using a single Text field.

Identifying the Web Content Structure ID

  1. Open the Site menu (Site menu) and go to Content & DataWeb Content.

  2. Click the Structures tab.

  3. Under the ID column, identify the ID for your structure.

    In the Structures tab, identify the ID for your web content structure under the ID column.

Identifying the Service to Consume

Use the StructuredContent service in the Liferay DXP Headless Delivery API to manage web content. To identify this service and all the different HTTP methods, use the Liferay API Explorer. For more information, see Consuming REST Services.

Getting the Web Content Structures

The ContentStructures_GET_FromSite.sh cURL script lists the existing web content structures. This script uses the ContentStructure service with the GET HTTP method, using the site ID as the only parameter.

Method Service Endpoint
GET ContentStructure /v1.0/sites//content-structures

In the ContentStructures_GET_FromSite.sh script, the ${1} parameter refers to siteID. Use your site ID instead of the one in the example (20125) when running the script.

./ContentStructures_GET_FromSite.sh 20125

The following code shows the JSON output generated by the script. The script returns all the structures in the site. In this example, you can see a single structure identified by an id and a name.

{
   "actions" : { },
   "facets" : [ ],
   "items" : [ {
      "availableLanguages" : [ "en-US" ],
      "contentStructureFields" : [ {
      "dataType" : "string",
      "inputControl" : "text",
      "label" : "Text",
      "localizable" : true,
      "multiple" : false,
      "name" : "Text86549034",
      "nestedContentStructureFields" : [ ],
      "options" : [ ],
      "predefinedValue" : "",
      "repeatable" : false,
      "required" : false,
      "showLabel" : true
      } ],
      "creator" : {
      "additionalName" : "",
      "contentType" : "UserAccount",
      "familyName" : "Bowman",
      "givenName" : "David",
      "id" : 20129,
      "name" : "David Bowman"
      },
      "dateCreated" : "2021-08-02T13:15:42Z",
      "dateModified" : "2021-08-02T13:16:57Z",
      "description" : "",
      "id" : 41837,
      "name" : "Simple Structure",
      "siteId" : 20125
   } ],
   "lastPage" : 1,
   "page" : 1,
   "pageSize" : 20,
   "totalCount" : 1
}

The structure has a single Text field described in the dataType section under contentStructureFields. When you include more elements on the structure, you can see additional sections under contentStructureFields. Below is the partial JSON output for a structure with a Text ("dataType": "string") and an Image field ("dataType": "image"):

{
  "actions": {},
  "facets": [],
  "items": [
    {
      "availableLanguages": ["en-US"],
      "contentStructureFields": [
        {
          "dataType": "string",
          "inputControl": "text",
          "label": "Text",
          "localizable": true,
          "multiple": false,
          "name": "Text86549034",
          "nestedContentStructureFields": [],
          "options": [],
          "predefinedValue": "",
          "repeatable": false,
          "required": false,
          "showLabel": true
        },
        {
          "dataType": "image",
          "label": "Image",
          "localizable": true,
          "multiple": false,
          "name": "Image96876678",
          "nestedContentStructureFields": [],
          "options": [],
          "predefinedValue": "{}",
          "repeatable": false,
          "required": false,
          "showLabel": true
        }
      ]
    }
  ]
}

The REST service can also be called using the Java client.

  1. Navigate out of the curl folder and into the java.

  2. Compile the source files:

    javac -classpath .:* *.java
    
  3. Run the ContentStructures_GET_FromSite.java class. Replace the siteId value with your site’s ID:

    java -classpath .:* -DsiteId=1234 ContentStructures_GET_FromSite
    

See the code and its comments for more information below:


public class ContentStructures_GET_FromSite {

   // Builds an instance of ContentStructureResource.
   public static void main(String[] args) throws Exception {
      ContentStructureResource.Builder builder =
         ContentStructureResource.builder();

      // Provides authentication credentials to the ContentStructureResource and constructs the contentStructureResource object (.build()).
      ContentStructureResource contentStructureResource =
         builder.authentication(
            "test@liferay.com", "learn"
         ).build();

      // System.out.println prints the returned information in one line.
      System.out.println(
         // Calls the getSiteContentStructuresPage() method with these parameters: Long siteId, String search, List<String> aggregations, String filterString, Pagination pagination, and String sortString.
         contentStructureResource.getSiteContentStructuresPage(
            // Long.valueOf(System.getProperty("siteId")); retrieves the value of the system property named siteId and converts it to a Long object representing the site Id.
            Long.valueOf(System.getProperty("siteId")), null, null, null,
            Pagination.of(1, 2), null));
   }

}

Getting the Web Content Templates

The ContentTemplates_GET_FromSite.sh cURL script lists the existing web content templates. This script uses the ContentTemplate service with the GET HTTP method, using the site ID as the only parameter.

Method Service Endpoint
GET ContentTemplate /v1.0/sites//content-templates

In the ContentTemplates_GET_FromSite.sh script, the ${1} parameter refers to siteID. Use your site ID instead of the one in the example (20125) when running the script.

./ContentTemplates_GET_FromSite.sh 20125

Below is the partial JSON output generated by the script. The script returns all the templates in the site. In this example, you can see a single template identified by an id and a name. The contentStructureId corresponds to the associated structure ID and the templateScript corresponds to the FreeMarker Template Language describing the template.

{
  (...)
    "availableLanguages" : [ "en-US" ],
    "contentStructureId" : 41837,
    "creator" : {
      "additionalName" : "",
      "contentType" : "UserAccount",
      "familyName" : "Bowman",
      "givenName" : "David",
      "id" : 20129,
      "name" : "David Bowman"
    },
    "dateCreated" : "2021-08-02T13:24:32Z",
    "dateModified" : "2021-08-02T14:33:24Z",
    "description" : "",
    "id" : "41847",
    "name" : "Simple Template",
    "programmingLanguage" : "ftl",
    "siteId" : 20125,
    "templateScript" : "<#if (Text86549034.getData())??>\n\t${Text86549034.getData()}\n</#if>"
  } ],
  "lastPage" : 1,
  "page" : 1,
  "pageSize" : 20,
  "totalCount" : 1
}

The REST service can also be called using the Java client.

  1. Navigate out of the curl folder and into the java.

  2. Compile the source files (you don’t have to repeat this step if you have already compiled the files):

    javac -classpath .:* *.java
    
  3. Run the ContentTemplates_GET_FromSite.java class. Replace the siteId value with your site’s ID:

    java -classpath .:* -DsiteId=1234 ContentTemplates_GET_FromSite
    

    The ContentTemplates_GET_FromSite.java works similarly to the ContentStructures_GET_FromSite.java file. The only difference is that it builds an instance of ContentTemplateResource. Consequently, it needs different imports, and it uses a getSiteContentTemplatesPage method instead.

Getting the Web Content Structure Permissions

The ContentStructure_GET_Permissions.sh cURL script lists the web content structure’s permissions. This script uses the ContentStructure service with the GET HTTP method, using the structure’s ID as the only parameter.

Method Service Endpoint
GET ContentStructure /v1.0/content-structures/{contentStructureId}/permissions

In the ContentStructure_GET_Permissions.sh script, the ${1} parameter refers to contentStructureId. Use your structure’s ID instead of the one in the example (41837) when running the script.

./ContentStructure_GET_Permissions.sh 41837

The JSON output includes the permissions under the items section. In this example, there is only one role with permissions on the sample structure in roleName, with the list of permissions in actionIds:

{
  "actions": {
    "get": {
      "method": "GET",
      "href": "http://localhost:8080/o/headless-delivery/v1.0/content-structures/41837/permissions"
    },
    "replace": {
      "method": "PUT",
      "href": "http://localhost:8080/o/headless-delivery/v1.0/content-structures/41837/permissions"
    }
  },
  "facets": [],
  "items": [
    {
      "actionIds": ["DELETE", "PERMISSIONS", "UPDATE", "VIEW"],
      "roleName": "Owner"
    }
  ],
  "lastPage": 1,
  "page": 1,
  "pageSize": 2,
  "totalCount": 2
}
Note

To learn how to manage permissions, see Assigning Permissions to Web Content Structures and Templates.

The REST service can also be called using the Java client.

  1. Navigate out of the curl folder and into the java.

  2. Compile the source files (you don’t have to repeat this step if you have already compiled the files):

    javac -classpath .:* *.java
    
  3. Run the ContentStructures_GET_Permissions.java class. Replace the contentStructureId value with your web content structure’s ID:

    java -classpath .:* -DcontentStructureId=1234 ContentStructures_GET_Permissions
    

    The ContentStructures_GET_Permissions.java works similarly to the ContentStructures_GET_FromSite.java file. The only difference is that the method receives a Long contentStructureId (instead of the siteId) and a String roleNames as parameters. roleNames is set as null to return all permissions available.

Replacing the Web Content Structure Permissions

The ContentStructure_PUT_Permissions.sh cURL script uses the PUT HTTP method with the ContentStructure service to replace the original web content structure permission. This script includes the DELETE and VIEW permissions for the Power User role.

Method Service Endpoint
PUT ContentStructure /v1.0/content-structures/{contentStructureId}/permissions

In the ContentStructure_PUT_Permissions.sh script, the ${1} parameter refers to contentStructureId. Use your structure’s ID instead of the one in the example (41837) when running the script.

./ContentStructure_PUT_Permissions.sh 41837

The JSON output shows two entries under the items section, one for each role:

{
  "actions": {
    "get": {
      "method": "GET",
      "href": "http://localhost:8080/o/headless-delivery/v1.0/content-structures/41837/permissions"
    },
    "replace": {
      "method": "PUT",
      "href": "http://localhost:8080/o/headless-delivery/v1.0/content-structures/41837/permissions"
    }
  },
  "facets": [],
  "items": [
    {
      "actionIds": ["DELETE", "PERMISSIONS", "UPDATE", "VIEW"],
      "roleName": "Owner"
    },
    {
      "actionIds": ["DELETE", "VIEW"],
      "roleName": "Power User"
    }
  ],
  "lastPage": 1,
  "page": 1,
  "pageSize": 2,
  "totalCount": 2
}

The Power User now has the Delete and View permissions.

The REST service can also be called using the Java client.

  1. Navigate out of the curl folder and into the java.

  2. Compile the source files (you don’t have to repeat this step if you have already compiled the files):

    javac -classpath .:* *.java
    
  3. Run the ContentStructures_PUT_Permissions.java class. Replace the contentStructureId value with your web content structure’s ID, the actionIds value for an action or a list of actions (separate them with commas), and the roleName value with the desired role for updating permissions:

    java -classpath .:* -DcontentStructureId=1234 -Dactions="DELETE, UPDATE, VIEW" -Drole="Power User" ContentStructures_GET_Permissions
    

See the code and its comments for more information below:

public class ContentStructures_PUT_Permissions {

   public static void main(String[] args) throws Exception {
      ContentStructureResource.Builder builder =
         ContentStructureResource.builder();

      ContentStructureResource contentStructureResource =
         builder.authentication(
            "test@liferay.com", "learn"
         ).build();

      System.out.println(
         // Calls the putContentStructurePermissionsPage() method with these parameters: Long contentStructureId, Permission[] permissions
         contentStructureResource.putContentStructurePermissionsPage(
            Long.valueOf(System.getProperty("contentStructureId")),
            // An array of Permission objects is created.
            new Permission[] {
               // This anonymous inner class instantiation sets the action IDs and the role for the permission.
               new Permission() {
                  {
                     // Sets the action IDs by splitting and placing the actions in an array of action IDs.
                     actionIds = System.getProperty(
                        "actionIds"
                     ).split(
                        "\\s*,\\s*"
                     );
                     // Sets the role for the permission.
                     roleName = System.getProperty("roleName");
                  }
               }
            }));
   }
}