Advanced Web Content API

Using the Liferay DXP REST services, you can create and manage your site’s structured content. Structured content is web content that uses a web content structure (or structure). A structure defines the information, such as author(s), a summary, and the content included in an article. Structures ensure that the article includes all the required information. For more information on structures, read Web Content Structures.

Use a pre-built Liferay DXP Docker image with several cURL and Java code samples to learn more about structures and structured content.

Note

See Consuming REST Services for an overview of using the REST API in Liferay DXP and Web Content API Basics for an introduction to the web content API.

Setting Up Your Environment

Start a new Liferay DXP instance by running

docker run -it -m 8g -p 8080:8080 liferay/dxp:2024.q2.11

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, download and unzip the sample project:

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

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

Identify the Site ID

  1. Open the Site menu (Site menu), expand Configuration, and go to Site Settings.

  2. Under the Platform section, click Site Configuration.

    For Liferay DXP versions 7.3 and earlier, click the General tab.

  3. Find the site identifier under Site ID.

    Identify the site Id under the Site Settings and Site Configuration option.

Adding the Images to Liferay DXP

Start with an article containing different content fields, including images. To add these images to the article,

  1. Open the Site menu (Site menu), expand Content & Data, and go to Documents and Media.

  2. Click New and select Multiple Files Upload.

  3. Drag and drop the foo.png, bar.png, and goo.png images from the sample project folder onto the drop area.

  4. Click Publish.

Alternatively, use the Documents_POST_ToSites.sh script to upload each image separately using the REST API’s Document service.

curl \
   "http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/documents" \
   --form "file=@${2}" \
   --header "Content-Type: multipart/form-data" \
   --request "POST" \
   --user "test@liferay.com:learn"

This example posts the foo.png image, using the site ID ({1}) and the relative image file path ({2}) as parameters:

MethodServiceEndpoint
GETDocument/v1.0/sites/${1}/documents
./Documents_POST_ToSites.sh "../images/foo.png" 20125
Parameter #Description
$1siteId
$2Relative path to file

The JSON output includes the image identifier in the id field:

{
   ...
   "encodingFormat" : "image/png",
   "externalReferenceCode" : "44339",
   "fileExtension" : "png",
   "id" : 44339,
   ...
   "title" : "foo.png"
}

For more information on working with documents using the REST API, see Document API Basics.

Or you can use the Documents_POST_ToSites class. Navigate out of the curl folder and into the java folder. Compile the source files:

javac -classpath .:* *.java

Run the Documents_POST_ToSites class. Replace the siteId value with your site ID and the filePath value with the path to the foo.png image:

java -classpath .:* -DfilePath=1234 -DsiteId=5678 Documents_POST_ToSites

Create the Sample Structure

Note

You cannot create a structure programmatically using the REST API.

  1. Open the Site menu (Site menu), expand Content & Data, and go to Web Content.

  2. Select the Structures tab and click New.

  3. Create a new structure with the following information:

    • Name: Foo
    • Fields (in this order): Text, Image, Date, Single Selection
  4. Use these values for the Single Selection field:

    • First option value: Foo
    • Second option value: Goo

    Create a new structure in the user interface.

  5. Click each structure field and update its Field Reference value (see table below). You can find the Field Reference values on the sidebar, under the Advanced section.

  6. Click Save.

FieldNew Field Reference value
TextTextReference
ImageImageReference
DateDateReference
SelectionSingleSelectionReference

Update the Field Reference values.

For more information, see Creating Web Content Structures.

Create the Sample Templates

Note

You cannot create a web content template programmatically using the REST API.

Create a template including the structure’s image field:

  1. Open the Site menu (Site menu), expand Content & Data, and go to Web Content.

  2. Select the Templates tab and click New.

  3. Type Foo as your template name.

  4. From the Properties side panel, click Add (Add) next to the structure field.

    Click Add next to the structure field to link your template to the structure.

  5. Select the Foo structure from the previous section.

  6. Delete the default <#-- --> block comment included in the FreeMarker editor.

  7. On the sidebar, click Elements (Elements).

  8. Under the Fields group, click the Text, Image, Date, and Single Selection fields to add them to your template. Ensure each field starts with a new line in the FreeMarker editor.

    Edit the template fields in the FreeMarker editor.

  9. Click Save.

Create a second template without the structure’s image field:

  1. Under the Templates tab, click Actions (Actions) and select Copy.

    Copy the first template using the Actions menu.

  2. Update the template’s name to Goo and click Copy.

  3. Under the Templates tab, click the new Goo template.

  4. In the template editor, remove the image information <#if (ImageReference.getData())></#if> from the FreeMarker script.

  5. Click Save.

For more information, see Creating Web Content Templates.

Getting Web Content Structures From the Site

To retrieve all existing structures in a specified site, use the ContentStructures_GET_FromSites.sh script. This script uses the ContentStructure service with a GET HTTP method and the site ID parameter.

MethodServiceEndpoint
GETContentStructure/v1.0/sites/${1}/content-structures
./ContentStructures_GET_FromSites.sh 20125
Parameter #Description
$1siteId

In the JSON response, identify the structure id ("id" : 43563) and name ("name" : "Foo"). The contentStructureFields section describes the structure fields. This structure contains four different fields named TextReference, ImageReference, DateReference, and SingleSelectionReference.

{
   "actions" : { },
   "facets" : [ ],
   "items" : [ {
      "availableLanguages" : [ "en-US" ],
      "contentStructureFields" : [ {
         "dataType" : "string",
         "inputControl" : "text",
         "label" : "Text",
         "localizable" : true,
         "multiple" : false,
         "name" : "TextReference",
         "nestedContentStructureFields" : [ ],
         "options" : [ ],
         "predefinedValue" : "",
         "repeatable" : false,
         "required" : false,
         "showLabel" : true
      }, {
         "dataType" : "image",
         "label" : "Image",
         "localizable" : true,
         "multiple" : false,
         "name" : "ImageReference",
         "nestedContentStructureFields" : [ ],
         "options" : [ ],
         "predefinedValue" : "{}",
         "repeatable" : false,
         "required" : false,
         "showLabel" : true
      }, {
         "dataType" : "date",
         "label" : "Date",
         "localizable" : true,
         "multiple" : false,
         "name" : "DateReference",
         "nestedContentStructureFields" : [ ],
         "options" : [ ],
         "predefinedValue" : "",
         "repeatable" : false,
         "required" : false,
         "showLabel" : true
      }, {
         "dataType" : "string",
         "inputControl" : "radio",
         "label" : "Single Selection",
         "localizable" : true,
         "multiple" : false,
         "name" : "SingleSelectionReference",
         "nestedContentStructureFields" : [ ],
         "options" : [ {
         "label" : "Foo",
         "value" : "Option13142925"
         }, {
         "label" : "Goo",
         "value" : "Option50805674"
         } ],
         "predefinedValue" : "[]",
         "repeatable" : false,
         "required" : false,
         "showLabel" : true
      } ],
      "creator" : {
         "additionalName" : "",
         "contentType" : "UserAccount",
         "familyName" : "Bowman",
         "givenName" : "David",
         "id" : 20129,
         "name" : "David Bowman"
      },
      "dateCreated" : "2021-08-25T07:52:46Z",
      "dateModified" : "2021-08-25T08:01:58Z",
      "description" : "",
      "id" : 43563,
      "name" : "Foo",
      "siteId" : 20125
   } ],
   "lastPage" : 1,
   "page" : 1,
   "pageSize" : 20,
   "totalCount" : 1
}

Alternatively, run the ContentStructures_GET_FromSites Java class:

java -classpath .:* -DsiteId=1234 ContentStructures_GET_FromSites

Get the Images IDs

To obtain the IDs of previously posted images, use the Documents_GET_FromSites.sh script. This script uses the Document service with a GET HTTP method and the site ID as parameter.

MethodServiceEndpoint
GETDocument/v1.0/sites/${1}/documents
./Documents_GET_FromSites.sh 20125
Parameter #Description
$1siteId

Alternatively, run the Documents_GET_FromSites Java class:

java -classpath .:* -DsiteId=1234 Documents_GET_FromSites

Getting Web Content Templates From the Site

Use the ContentTemplates_GET_FromSites script to obtain all the site’s templates. This script uses the ContentTemplate service with a GET HTTP method and the site ID as parameter.

MethodServiceEndpoint
GETContentTemplate/v1.0/sites/${1}/content-templates
./ContentTemplates_GET_FromSites.sh 20125
Parameter #Description
$1siteId

The JSON response contains

  • Two templates: "name": "Foo" and "name": "Goo".

  • The contentStructureId that links the structure to the template.

  • The templateScript includes the script written in the specified programmingLanguage. In this example, FreeMarker is used.

  • The templateScript field in the Foo template references the image field with <#if (ImageReference.getData())></#if>. The Goo template does not include this reference.

{
   "actions" : {
      "get" : {
         "method" : "GET",
         "href" : "http://localhost:8080/o/headless-delivery/v1.0/sites/20125/content-templates"
      }
   },
   "facets" : [ ],
   "items" : [ {
      "actions" : {
         "get" : {
         "method" : "GET",
         "href" : "http://localhost:8080/o/headless-delivery/v1.0/sites/20125/content-templates/{contentTemplateId}"
         }
      },
      "availableLanguages" : [ "en-US" ],
      "contentStructureId" : 43563,
      "creator" : {
         "additionalName" : "",
         "contentType" : "UserAccount",
         "familyName" : "Bowman",
         "givenName" : "David",
         "id" : 20129,
         "name" : "David Bowman"
      },
      "dateCreated" : "2021-08-25T13:39:20Z",
      "dateModified" : "2021-08-25T13:39:20Z",
      "description" : "",
      "id" : "43823",
      "name" : "Foo",
      "programmingLanguage" : "ftl",
      "siteId" : 20125,
      "templateScript" : "<#if (TextReference.getData())??>\n\t${TextReference.getData()}\n</#if>\n<#if (ImageReference.getData())?? && ImageReference.getData() != \"\">\n\t<img alt=\"${ImageReference.getAttribute(\"alt\")}\" data-fileentryid=\"${ImageReference.getAttribute(\"fileEntryId\")}\" src=\"${ImageReference.getData()}\" />\n</#if>\n<#assign DateReference_Data = getterUtil.getString(DateReference.getData())>\n\n<#if validator.isNotNull(DateReference_Data)>\n\t<#assign DateReference_DateObj = dateUtil.parseDate(\"yyyy-MM-dd\", DateReference_Data, locale)>\n\n\t${dateUtil.getDate(DateReference_DateObj, \"dd MMM yyyy - HH:mm:ss\", locale)}\n</#if>\n<#if (SingleSelectionReference.getData())??>\n\t${SingleSelectionReference.getData()}\n</#if>"
   }, {
      "actions" : {
         "get" : {
         "method" : "GET",
         "href" : "http://localhost:8080/o/headless-delivery/v1.0/sites/20125/content-templates/{contentTemplateId}"
         }
      },
      "availableLanguages" : [ "en-US" ],
      "contentStructureId" : 43563,
      "creator" : {
         "additionalName" : "",
         "contentType" : "UserAccount",
         "familyName" : "Bowman",
         "givenName" : "David",
         "id" : 20129,
         "name" : "David Bowman"
      },
      "dateCreated" : "2021-08-26T10:10:22Z",
      "dateModified" : "2021-08-26T14:08:53Z",
      "description" : "",
      "id" : "44177",
      "name" : "Goo",
      "programmingLanguage" : "ftl",
      "siteId" : 20125,
      "templateScript" : "<#if (TextReference.getData())??>\n\t${TextReference.getData()}\n</#if>\n<#assign DateReference_Data = getterUtil.getString(DateReference.getData())>\n\n<#if validator.isNotNull(DateReference_Data)>\n\t<#assign DateReference_DateObj = dateUtil.parseDate(\"yyyy-MM-dd\", DateReference_Data, locale)>\n\n\t${dateUtil.getDate(DateReference_DateObj, \"dd MMM yyyy - HH:mm:ss\", locale)}\n</#if>\n<#if (SingleSelectionReference.getData())??>\n\t${SingleSelectionReference.getData()}\n</#if>"
   } ],
   "lastPage" : 1,
   "page" : 1,
   "pageSize" : 20,
   "totalCount" : 2
}

Alternatively, run the ContentTemplates_GET_FromSites Java class:

java -classpath .:* -DsiteId=1234 ContentTemplates_GET_FromSites

Getting a Web Content Template

To retrieve information about a specific template, use the ContentTemplates_GET_ById.sh cURL script, which requires the site and template IDs.

MethodServiceEndpoint
GETContentTemplate/v1.0/sites/${1}/content-templates/${2}
./ContentTemplates_GET_ById.sh 20125 43823
Parameter #Description
$1siteId
$2contentTemplateId

Alternatively, run the ContentTemplates_GET_ById Java class. Replace the values with your site and template IDs:

java -classpath .:* -DcontentTemplateId=1234 -DsiteId=5678 ContentTemplates_GET_ById

Posting a Web Content Article

Use the StructuredContents_POST_ToSites.sh cURL script to create a new article using the POST HTTP method, using the sample structure you created. The script requires the site ID, structure ID, and the image ID for foo.png as parameters.

MethodServiceEndpoint
PUTStructuredContent/v1.0/sites/{siteId}/structured-contents
./StructuredContents_POST_ToSites.sh 20125 43563 43795

cURL script parameters:

Parameter #Description
$1siteId
$2imageId
$3contentStructureId

To find your new article in Liferay DXP, open the Site Menu (Site menu) → Content & DataWeb Content.

The article from the POST HTTP method appears in the UI.

The script posts a new article with the following attributes:

  • "title" : "Able"
  • Four contentFields values defining the article’s body:
    • Text string in TextReference.
    • Image in ImageReference.
    • Date information in DateReference.
    • Radio button control in SingleSelectionReference.
{
   "actions" : {
      ...
   },
   "availableLanguages" : [ "en-US" ],
   "contentFields" : [ {
      "contentFieldValue" : {
         "data" : "This text describes Foo."
      },
      "dataType" : "string",
      "inputControl" : "text",
      "label" : "Text",
      "name" : "TextReference",
      "nestedContentFields" : [ ],
      "repeatable" : false
   }, {
      "contentFieldValue" : {
         "image" : {
         "contentType" : "Document",
         "contentUrl" : "/documents/20125/0/foo.png/50956e56-9571-8f73-ae6e-9fca20fe0e3a?t=1629897455431",
         "description" : "This text describes Foo's image.",
         "encodingFormat" : "image/png",
         "fileExtension" : "png",
         "id" : 43795,
         "sizeInBytes" : 6232,
         "title" : "Foo"
         }
      },
      "dataType" : "image",
      "label" : "Image",
      "name" : "ImageReference",
      "nestedContentFields" : [ ],
      "repeatable" : false
   }, {
      "contentFieldValue" : {
         "data" : "2021-08-30T00:00:00Z"
      },
      "dataType" : "date",
      "label" : "Date",
      "name" : "DateReference",
      "nestedContentFields" : [ ],
      "repeatable" : false
   }, {
      "contentFieldValue" : {
         "data" : "Foo"
      },
      "dataType" : "string",
      "inputControl" : "radio",
      "label" : "Single Selection",
      "name" : "SingleSelectionReference",
      "nestedContentFields" : [ ],
      "repeatable" : false
   } ],
   "contentStructureId" : 43563,
   "creator" : {
      "additionalName" : "",
      "contentType" : "UserAccount",
      "familyName" : "Bowman",
      "givenName" : "David",
      "id" : 20129,
      "name" : "David Bowman"
   },
   "customFields" : [ ],
   "dateCreated" : "2021-08-26T06:14:06Z",
   "dateModified" : "2021-08-26T06:14:06Z",
   "datePublished" : "2021-08-26T06:14:00Z",
   "description" : "",
   "externalReferenceCode" : "43847",
   "friendlyUrlPath" : "able",
   "id" : 43849,
   "key" : "43847",
   "keywords" : [ ],
   "numberOfComments" : 0,
   "relatedContents" : [ ],
   "renderedContents" : [ {
      "contentTemplateId" : "43823",
      "contentTemplateName" : "Foo",
      "markedAsDefault" : true,
      "renderedContentURL" : "http://localhost:8080/o/headless-delivery/v1.0/structured-contents/43849/rendered-content/43823"
   }, {
      "contentTemplateId" : "43868",
      "contentTemplateName" : "Goo",
      "markedAsDefault" : false,
      "renderedContentURL" : "http://localhost:8080/o/headless-delivery/v1.0/structured-contents/44060/rendered-content/43868"
   } ],
   "siteId" : 20125,
   "subscribed" : false,
   "taxonomyCategoryBriefs" : [ ],
   "title" : "Able",
   "uuid" : "01ace059-814a-132d-d46d-21737ef2ec53"
}

Alternatively, run the StructuredContents_POST_ToSites Java class. Replace the values with your structure, site, and image IDs:

java -classpath .:* -DcontentStructureId=1234 -DimageId=5678 -DsiteId=91011 StructuredContents_POST_ToSites

Getting a Web Content Article Rendered with a Particular Template

An article is not linked to a particular template. The template defines how the article renders. You can use different templates for the same article. For more information, read Web Content Structures.

Tip

Because an article is not linked to a particular template, you cannot specify a template when you POST a new article (the HTTP POST method ignores the renderedContents section describing the template.)

Use the ./StructureContents_GET_RenderedContent_ById.sh script to render the article using the chosen article and template. This script uses the GET HTTP method in the StructuredContent service.

MethodServiceEndpoint
PUTStructuredContent/v1.0/structured-contents/${1}/rendered-content/${2}
./StructureContents_GET_RenderedContent_ById.sh 43849 43868

Here is the script output using the template with the image field:

Foo<picture data-fileentryid="43795"><source media="(max-width:300px)" srcset="http://localhost:8080/o/adaptive-media/image/43795/Thumbnail-300x300/foo.png?t=1629897455431, /o/adaptive-media/image/43795/Preview-1000x0/foo.png?t=1629897455431 2x" /><source media="(max-width:600px) and (min-width:300px)" srcset="http://localhost:8080/o/adaptive-media/image/43795/Preview-1000x0/foo.png?t=1629897455431" /><img alt="Foo alt-image description" data-fileentryid="43795" src="http://localhost:8080/documents/20125/0/foo.png/50956e56-9571-8f73-ae6e-9fca20fe0e3a?t=1629897455431" /></picture>30 Aug 2021 - 00:00:00Option1314292

If you specify the template without the image field, the <picture></picture> information doesn’t render in the output. Here is the script output when using the template without the image field:

./StructureContents_GET_RenderedContent_ById.sh 43849 43823
Foo30 Aug 2021 - 00:00:00Option13142925

cURL scripts parameters:

Parameter #Description
$1structuredContentId
$2contentTemplateId

Alternatively, run the StructureContents_GET_RenderedContent_ById Java class. Replace the values with your article and template IDs:

java -classpath .:* -DcontentTemplateId=1234 -DstructuredContentId=5678 StructureContents_GET_RenderedContent_ById

Patching a Web Content Article

Use the PATCH HTTP method with the StructuredContent service to update the original article information partially. The StructuredContents_PATCH_ById script uses the article and structure identifiers to replace the article’s title with Charlie.

MethodServiceEndpoint
PATCHStructuredContent/v1.0/structured-contents/{structuredContentId}
./StructuredContents_PATCH_ById.sh 43849 43563

cURL script parameters:

Parameter #Description
$1structuredContentId
$2contentStructureId

Alternatively, run the StructuredContents_PATCH_ById Java class. Replace the value with your article ID:

java -classpath .:* -DstructuredContentId=1234 StructuredContents_PATCH_ById

Putting a Web Content Article

Use the PUT HTTP method with the StructuredContent service to replace the original article information. The StructuredContents_PUT_ById script uses the article and structure identifiers to replace the article’s name with Baker and the article’s content from Bar to Goo.

MethodServiceEndpoint
PUTStructuredContent/v1.0/structured-contents/{structuredContentId}
./StructuredContents_PUT_ById.sh 43849 43563 43805

cURL script parameters:

Parameter #Description
$1structuredContentId
$2imageId
$3contentStructureId

Alternatively, run the StructuredContents_PUT_ById Java class. Replace the values with your article, image, and structure IDs:

java -classpath .:* -DcontentStructureId=1234 -DimageId=5678 -DstructuredContentId=91011 StructuredContents_PUT_ById

Capabilities

Product

Contact Us

Connect

Powered by Liferay
© 2024 Liferay Inc. All Rights Reserved • Privacy Policy