Web Content API Basics
Using Liferay DXP REST services, you can create and manage structured content on your site. Structured content refers to web content articles that use a web content structure to enforce a consistent format and organization by defining the specific fields and information required for each article, such as author, summaries, and other relevant content elements.
While you can use a structure with a web content template to render structured content, a template is not required for creating structured content.
See the cURL and Java samples for structures and articles below. For more advanced examples of managing structured content, see Advanced Web Content API. For an overview of using the REST API in Liferay DXP, see Consuming REST Services.
Setting Up Your Environment
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.132-ga132
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
Then, follow these steps:
-
Download and unzip the Web Content API Basics files:
curl https://resources.learn.liferay.com/examples/liferay-r4h9.zip -Ounzip liferay-r4h9.zipNoteThese scripts use basic authentication and are designed for testing. Do not use basic authentication in a production Liferay DXP environment.
-
Complete these steps to set up the environment:
Identify the Services to Consume
Use the following services in the Liferay DXP Headless Delivery API to manage web content:
StructuredContentfor articles.ContentStructurefor structures.ContentTemplatefor templates.
To view detailed information on these APIs, use your browser and access Liferay’s API Explorer at [server]:[port]/o/api (e.g. http://localhost:8080/o/api). For more information, read Consuming REST Services.
Identifying the Site ID
When signed in, retrieve the site ID. Use this ID in several service calls. In this example, the ID is 20117.
Create a Web Content Structure in the User Interface
To create an article, you need a structure. When you create articles in the user interface without declaring a structure, Liferay DXP uses a default Basic Web Content structure.
The Basic Web Content structure is not visible in the Liferay DXP user interface.
Instead of using the Basic Web Content structure, create a new one:
-
Open the Site Menu (../../../../images/icon-menu.png), expand Content & Data, and go to Web Content.
-
Select the Structures tab and click New.
-
Name it Foo Structure. In the Builder menu on the right, select, drag, and drop a Text field to the form area.
-
In the contextual menu that opens on the right, select the Advanced tab and change the Field Reference to
Content. -
Click Save.
For more information, see Creating Structures.
Create a Web Content Article in the User Interface
Now you can create an article based on the Foo Structure:
-
Open the Site Menu (../../../../images/icon-menu.png), expand Content & Data, and go to Web Content.
-
Under the Web Content tab, click New and choose Foo Structure.
-
Enter Foo Article as the new name and click Publish.

For more information, see Creating Web Content Articles.
Getting Web Content Articles from the Site
Use the REST API to retrieve a list of the site’s articles by executing the following cURL script or Java class. Replace 1234 with your site’s ID.
StructuredContents_GET_FromSites.sh
The StructuredContents_GET_FromSites.sh cURL script lists all the site’s articles. This script uses the StructuredContent service with a GET HTTP method, with the site ID as the only parameter.
| Method | Service | Endpoint |
|---|---|---|
GET | StructuredContent | /v1.0/sites/{siteID}/structured-contents |
./StructuredContents_GET_FromSites.sh 1234
| Parameter # | Description |
|---|---|
$1 | siteId |
Below is the partial JSON output generated by the script. In this output, you can see a single article identified by an id and a friendly URL in friendlyUrlPath. The article uses the structure in contentStructureId.
This structure has a single text field described in the contentFieldValue section under contentFields. When you include more elements in your structure, you can see additional contentFieldValue sections describing these elements.
{
{
...
"items": [
{
...
"availableLanguages": [
"en-US"
],
"contentFields": [
{
"contentFieldValue": {
"data": ""
},
"dataType": "string",
"inputControl": "text",
"label": "Text",
"name": "Content",
"nestedContentFields": [],
"repeatable": false
}
],
"contentStructureId": 32122,
"creator": {
"additionalName": "",
"contentType": "UserAccount",
"familyName": "Administrator",
"givenName": "Master",
"id": 20123,
"name": "Master Administrator"
},
"customFields": [],
"dateCreated": "2024-10-02T11:29:20Z",
"dateModified": "2024-10-02T11:29:20Z",
"datePublished": "2024-10-02T11:29:00Z",
"description": "",
"externalReferenceCode": "0b1a40b2-687e-c88a-f8d9-5270ec94fdd6",
"friendlyUrlPath": "foo-article",
"id": 32147,
"key": "32145",
"keywords": [],
"neverExpire": true,
"numberOfComments": 0,
"priority": 0,
"relatedContents": [],
"renderedContents": [],
"siteId": 20117,
"structuredContentFolderId": 0,
"subscribed": false,
"taxonomyCategoryBriefs": [],
"title": "Foo Article",
"uuid": "0b1a40b2-687e-c88a-f8d9-5270ec94fdd6"
}
],
"lastPage": 1,
"page": 1,
"pageSize": 20,
"totalCount": 1
}
Review the following information in the JSON output:
-
The output shows a single article identified by
id: 32147,title: Foo Article, and the friendly URLfriendlyUrlPath: foo-article. -
This article uses the Foo Structure identified by the
contentStructureId. -
The structure has a single text field described in the
contentFieldValuesection undercontentFields. When you include more elements in the structure, you can see additionalcontentFieldValuesections describing these elements. -
The
IDvalue displayed in the user interface corresponds to thekeyproperty in the JSON output.
StructuredContents_GET_FromSites.java
The StructuredContents_GET_FromSites.java class gets a list of articles by calling the structured content related services.
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
Page<StructuredContent> page =
structuredContentResource.getSiteStructuredContentsPage(
Long.valueOf(System.getProperty("siteId")), null, null, null,
null, Pagination.of(1, 2), null);
System.out.println(page.getItems());
}
This class invokes the REST service using only three lines of code:
| Line (abbreviated) | Description |
|---|---|
StructuredContentResource.Builder builder = ... | Gets a Builder for generating a StructuredContentResource service instance. |
StructuredContentResource structuredContentResource = builder.authentication(...).build(); | Specifies basic authentication and generates a StructuredContentResource service instance. |
Page<StructuredContent> page = structuredContentResource.getSiteStructuredContentsPage(...); | Calls the structuredContentResource.getSiteStructuredContentsPage method and retrieves the data. |
Note that the project includes the com.liferay.headless.delivery.client.jar file as a dependency. You can find client JAR dependency information for all REST applications in the API explorer in your installation at /o/api.
The main method’s comment demonstrates running the class.
The other example Java classes are similar to this one, but call different StructuredContentResource methods.
See StructuredContentResource for service details.
Get a Web Content Article
While the script in the previous step returns all the site’s articles, you can get a specific article by using the StructuredContents_GET_ById.[java|sh] script/class and specifying the article’s ID.
Commands:
Replace [articleId] and the value in -DstructuredContentId=1234 with the article’s ID
./StructuredContents_GET_ById.sh [articleId]
java -classpath .:* -DstructuredContentId=1234 StructuredContents_GET_ById
The StructuredContent fields appear in JSON.
Getting Web Content Structures from the Site
Use the REST API to retrieve a list of the site’s structures by executing the following cURL script or Java class. Replace [siteId] and the value in -DsiteId=1234 with the site ID.
The default Basic Web Content structure is not visible using this endpoint.
Commands:
./ContentStructures_GET_FromSite.sh [siteId]
java -classpath .:* -DsiteId=1234 ContentStructures_GET_FromSite
The site’s ContentStructures appear in JSON. As the Basic Web Content structure is not visible, it doesn’t show in the response:
{
"actions" : { },
"facets" : [ ],
"items" : [ {
"availableLanguages" : [ "en-US" ],
"contentStructureFields" : [ {
"dataType" : "string",
"inputControl" : "text",
"label" : "Text",
"localizable" : true,
"multiple" : false,
"name" : "Content",
"nestedContentStructureFields" : [ ],
"options" : [ ],
"predefinedValue" : "",
"repeatable" : false,
"required" : false,
"showLabel" : true
} ],
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Administrator",
"givenName" : "Master",
"id" : 20123,
"name" : "Master Administrator"
},
"dateCreated" : "2024-10-01T18:34:15Z",
"dateModified" : "2024-10-01T18:34:15Z",
"description" : "",
"id" : 32122,
"name" : "Foo Structure",
"siteId" : 20117
} ],
"lastPage" : 1,
"page" : 1,
"pageSize" : 20,
"totalCount" : 1
}
You can see details about the creator of the structure, its id, name, and contentStructureFields where you can find information about the fields used in the structure.
Get a Web Content Structure
Use the ContentStructure service to retrieve the description of a specific structure by providing its ID as a parameter.
ContentStructures_GET_ById.sh
| Method | Service | Endpoint |
|---|---|---|
GET | ContentStructure | /v1.0/content-structures/{contentStructureId} |
./ContentStructures_GET_ById.sh 1234
| Parameter # | Description |
|---|---|
| $1 | contentStructureId |
Below is the JSON output. You can identify the structure’s id and name. The contentStructureFields section contains a description of the structure fields. Notice that this structure contains a single content field of type string and name Content.
{
"availableLanguages" : [ "en-US" ],
"contentStructureFields" : [ {
"dataType" : "string",
"inputControl" : "text",
"label" : "Text",
"localizable" : true,
"multiple" : false,
"name" : "Content",
"nestedContentStructureFields" : [ ],
"options" : [ ],
"predefinedValue" : "",
"repeatable" : false,
"required" : false,
"showLabel" : true
} ],
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Administrator",
"givenName" : "Master",
"id" : 20123,
"name" : "Master Administrator"
},
"dateCreated" : "2024-10-02T10:50:55Z",
"dateModified" : "2024-10-02T10:50:55Z",
"description" : "",
"id" : 33862,
"name" : "Foo Structure",
"siteId" : 20117
}
Similarly, you can run the ContentStructures_GET_ById Java class:
java -classpath .:* -DcontentStructureId=1234 ContentStructures_GET_ById
The ContentStructure description appears in JSON.
Posting a Web Content Article
Use the StructuredContents_POST_ToSite[java|sh] script/class to create a new article using the Foo Structure.
StructuredContents_POST_ToSite.sh
The StructuredContents_POST_ToSite.sh cURL script creates a new article using the POST HTTP method and the Foo Structure. The script uses the site ID and the structure ID as parameters.
| Method | Service | Endpoint |
|---|---|---|
PUT | StructuredContent | /v1.0/sites/{siteId}/structured-contents |
./StructuredContents_POST_ToSite.sh [siteId] [structureId]
cURL script parameters:
| Parameter # | Description |
|---|---|
| $1 | siteId |
| $2 | contentStructureId |
To find your new article in Liferay DXP, open the Site Menu (
) and go to Content & Data → Web Content.
Below is the partial JSON output generated by the script. The script posts a simple <p>Goo</p> HTML string using the Structure contentField content as reference.
{
...
"availableLanguages" : [ "en-US" ],
"contentFields" : [ {
"contentFieldValue" : {
"data" : "<p>Goo</p>"
},
"dataType" : "string",
"inputControl" : "text",
"label" : "Text",
"name" : "Content",
"nestedContentFields" : [ ],
"repeatable" : false
} ],
"contentStructureId" : 32122,
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Administrator",
"givenName" : "Master",
"id" : 20123,
"name" : "Master Administrator"
},
"customFields" : [ ],
"dateCreated" : "2024-10-02T11:57:26Z",
"dateModified" : "2024-10-02T11:57:26Z",
"datePublished" : "2024-10-02T11:57:00Z",
"description" : "",
"externalReferenceCode" : "009a771b-2e71-de18-83e2-6ae165ce93c5",
"friendlyUrlPath" : "goo-article",
"id" : 32177,
"key" : "32175",
"keywords" : [ ],
"neverExpire" : true,
"numberOfComments" : 0,
"priority" : 0.0,
"relatedContents" : [ ],
"renderedContents" : [ ],
"siteId" : 20117,
"structuredContentFolderId" : 0,
"subscribed" : false,
"taxonomyCategoryBriefs" : [ ],
"title" : "Goo Article",
"uuid" : "009a771b-2e71-de18-83e2-6ae165ce93c5"
}
Similarly, the StructuredContents_POST_ToSite.java class adds an article by calling the structured content related service.
Command:
Replace the values in -DcontentStructureId=1234 and -DsiteId=5678 with the structure’s and the site’s ID respectively.
java -classpath .:* -DcontentStructureId=1234 -DsiteId=5678 StructuredContents_POST_ToSite
The StructuredContent fields appear in JSON.
Patch a Web Content Article
Use the PATCH method with the StructuredContent service to update the article. The StructuredContent_PATCH_ById.[java|sh] script/class uses the structured content identifier id to update the article’s content from ‘Goo’ to ‘Foo’.
Commands:
./StructuredContent_PATCH_ById.sh [articleId]
Replace the values in -DcontentStructureId=1234 and -DstructuredContentId=5678 with the structure’s and the article’s ID respectively.
java -classpath .:* -DcontentStructureId=1234 -DstructuredContentId=5678 StructuredContents_PATCH_ById
Putting a Web Content Article
Use the PUT method with the StructuredContent service to replace the original article’s information. The StructuredContents_PUT_ById.[java|sh] script/class uses the article and structure identifiers to replace the article’s name and the article’s content from Foo to Bar.
Commands:
./StructuredContents_PUT_ById.sh [articleId] [structureId]
Replace the values in -DcontentStructureId=1234 and -DstructuredContentId=5678 with the structure’s and the article’s ID respectively.
java -classpath .:* -DcontentStructureId=1234 -DstructuredContentId=5678 StructuredContents_PUT_ById
Deleting a Web Content Article
Use the DELETE method with the StructuredContent service to delete an article. The StructuredContents_DELETE_ById.[java|sh] script/class example uses the article’s id to delete it.
When you delete articles using the REST API, it’s deleted permanently, without using the Liferay DXP Recycle Bin.
Commands:
./StructuredContents_DELETE_ById.sh [articleId]
Replace the value in -DstructuredContentId=1234 with the article’s ID.
java -classpath .:* -DstructuredContentId=1234 StructuredContents_DELETE_ById
More Web Content and Web Content Folder Services
The other cURL commands and Java classes demonstrate more StructuredContent and StructuredContentFolder services. You can find these in Web Content API Basics.
| File | Description |
|---|---|
StructuredContentFolders_GET_ById.[java\|sh] | Lists a web content folder’s fields. |
StructuredContentFolders_GET_FromSites.[java\|sh] | Lists all web content folders in the site. |
StructuredContentFolders_POST_ToSites.[java\|sh] | Posts a web content folder to a site. |
StructuredContentFolders_PATCH_ById.[java\|sh] | Updates a web content folder. |
StructuredContentFolders_PUT_ById.[java\|sh] | Replaces a web content folder. |
StructuredContentFolders_DELETE_ById.[java\|sh] | Deletes a web content folder. |
StructuredContents_POST_ToStructuredContentFolders.[java\|sh] | Posts a web content article to a folder. |
When you delete a Web Content Folder using the REST API, the folder and its content are deleted permanently, without using the Liferay DXP Recycle Bin.