Web Content API Basics
Using the Liferay DXP REST services, you can create and manage structured content on your Site. Structured content is Web Content that uses a Web Content Structure. A Structure defines the information, such as author(s), a summary, and the content included in a Web Content Article. Structures ensure that the content includes all the required information. For more information, read Web Content Structures.
You can use a Structure with a Web Content Template to render the structured content, but a Template is not required to create structured content.
See the cURL and Java samples for Structures and structured content 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.112-ga112
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/dxp/latest/en/content-authoring-and-management/web-content/developer-guide/liferay-r4h9.zip -O
unzip liferay-r4h9.zip
NoteThese 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:
StructuredContent
for Web Content Articles.ContentStructure
for Web Content Structures.ContentTemplate
for Web Content Templates.
To identify these services and the available HTTP methods, use the Liferay API Explorer. For more information, read Consuming REST Services.
Identify the Site Id
To identify the Site ID, follow the instructions here.
Create a Basic Web Content Article in the User Interface
To create Web Content, you need a Web Content Structure. When you create Web Content 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.
These examples use a basic Web Content Article with a single Text field and the default Basic Web Content Structure. Use these steps to create the Web Content.
-
Open the Site menu () and go to Content & Data → Web Content.
-
Under the Web Content tab, click Add () and choose Basic Web Content.
-
Enter Foo as the New Web Content name and click Publish.
For more information, see Creating Web Content Articles.
Get Web Content Articles from Site
You can retrieve a site’s Web Content articles by executing the following cURL or Java command. Replace 1234
with your site’s ID.
StructuredContents_GET_FromSite.sh
The StructuredContents_GET_FromSite.sh
cURL script lists all the Site’s Web Content 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_FromSite.sh 1234
Parameter # | Description |
---|---|
$1 | siteId |
Below is the partial JSON output generated by the script. In this output, you can see a single Web Content Article identified by an id
and a friendly URL in friendlyUrlPath
. The Web Content 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.
{
"actions" : {
...
},
"facets" : [ ],
"items" : [ {
"actions" : {
...
},
"availableLanguages" : [ "en-US" ],
"contentFields" : [ {
"contentFieldValue" : {
"data" : ""
},
"dataType" : "string",
"label" : "content",
"name" : "content",
"nestedContentFields" : [ ],
"repeatable" : false
} ],
"contentStructureId" : 40697,
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Bowman",
"givenName" : "David",
"id" : 20129,
"name" : "David Bowman"
},
"customFields" : [ ],
"dateCreated" : "2021-08-10T08:10:21Z",
"dateModified" : "2021-08-10T08:10:21Z",
"datePublished" : "2021-08-10T08:10:00Z",
"description" : "",
"externalReferenceCode" : "41537",
"friendlyUrlPath" : "foo",
"id" : 41539,
"key" : "41537",
"keywords" : [ ],
"numberOfComments" : 0,
"relatedContents" : [ ],
"renderedContents" : [ {
"contentTemplateId" : "BASIC-WEB-CONTENT",
"contentTemplateName" : "Basic Web Content",
"markedAsDefault" : true,
"renderedContentURL" : "http://localhost:8080/o/headless-delivery/v1.0/structured-contents/41539/rendered-content/BASIC-WEB-CONTENT"
} ],
"siteId" : 20125,
"subscribed" : false,
"taxonomyCategoryBriefs" : [ ],
"title" : "Foo",
"uuid" : "162155dc-c9aa-96b0-df5c-a61c591d1389"
} ],
"lastPage" : 1,
"page" : 1,
"pageSize" : 20,
"totalCount" : 1
}
Review the following information in the JSON output:
-
The output shows a single Web Content Article identified by
id: 41539
,title: Foo
, and the friendly URLfriendlyUrlPath: foo
. -
This Web Content uses the default Liferay DXP Web Content Structure identified in
contentStructureId
. -
The Web Content Structure has a single Text field described in the
contentFieldValue
section undercontentFields
. When you include more elements in the Structure, you can see additionalcontentFieldValue
sections describing these elements. -
The Web Content Id in the user interface corresponds to the
key
property in the JSON output.
StructuredContents_GET_FromSite.java
The StructuredContents_GET_FromSite.java
class gets a list of Web Content 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);
}
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.
Below are examples of calling other REST services using cURL and Java.
Get a Web Content Article
The script in the previous step returns all the Site’s Web Content articles. To get a specific article, use the StructuredContent_GET_ById.[java|sh]
script. Replace 1234
with your Web Content article’s ID.
StructuredContent_GET_ById.sh
Command:
./StructuredContent_GET_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/structured-contents/${1}" \
--user "test@liferay.com:learn"
StructuredContent_GET_ById.java
Command:
java -classpath .:* -DstructuredContentId=1234 StructuredContent_GET_ById
Code:
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
System.out.println(
structuredContentResource.getStructuredContent(
Long.valueOf(System.getProperty("structuredContentId"))));
}
The StructuredContent
fields appear in JSON.
Get Web Content Structures
You can retrieve a site’s Content Structures by executing the following cURL or Java command. Replace 1234
with your site’s ID.
The default Basic Web Content Structure is not visible using this endpoint.
ContentStructures_GET_FromSite.sh
Command:
./ContentStructures_GET_FromSite.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/sites/${1}/content-structures" \
--user "test@liferay.com:learn"
ContentStructures_GET_FromSite.java
Command:
java -classpath .:* -DsiteId=1234 ContentStructures_GET_FromSite
Code:
public static void main(String[] args) throws Exception {
ContentStructureResource.Builder builder =
ContentStructureResource.builder();
ContentStructureResource contentStructureResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
Page<ContentStructure> page =
contentStructureResource.getSiteContentStructuresPage(
Long.valueOf(System.getProperty("siteId")), null, null, null,
Pagination.of(1, 2), null);
System.out.println(page);
}
The site’s ContentStructure
objects appear in JSON.
Get Web Content Structure by Id
The default Web Content Structure in the sample Web Content Article is not visible in the Liferay DXP user interface. However, you can use the ContentStructure
service to gather the Structure’s description.
The ContentStructure_GET_ById.[java|sh]
script returns a Web Content Structure description.
ContentStructure_GET_ById.sh
Method | Service | Endpoint |
---|---|---|
GET | ContentStructure | /v1.0/content-structures/{contentStructureId} |
./ContentStructure_GET_ById.sh 40697
Parameter # | Description |
---|---|
$1 | contentStructureId |
Below is the JSON output. You can identify the default Web Content Structure in Liferay DXP by its 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
. In Post a Basic Web Content Article, you create a new Web Content Article adding information to this content field.
{
"availableLanguages" : [ "en-US" ],
"contentStructureFields" : [ {
"dataType" : "string",
"label" : "content",
"localizable" : true,
"multiple" : false,
"name" : "content",
"nestedContentStructureFields" : [ ],
"options" : [ ],
"repeatable" : false,
"required" : false,
"showLabel" : true
} ],
"dateCreated" : "2021-08-09T23:30:23Z",
"dateModified" : "2021-08-09T23:30:23Z",
"description" : "Basic Web Content",
"id" : 40697,
"name" : "Basic Web Content",
"siteId" : 20127
}
ContentStructure_GET_ById.java
Command:
java -classpath .:* -DcontentStructureId=1234 ContentStructure_GET_ById
Code:
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(
contentStructureResource.getContentStructure(
Long.valueOf(System.getProperty("contentStructureId"))));
}
The ContentStructure
fields appear in JSON.
Post a Basic Web Content Article
Use the StructuredContent_POST_ToSite[java|sh]
script to create a new Web Content article. Replace 1234
with a Web Content Structure ID. Replace 5678
with your site’s ID.
StructuredContent_POST_ToSite.sh
The StructuredContent_POST_ToSite.sh
cURL script example creates a new Web Content article using the POST
HTTP method and the default Web Content Structure. The script uses the Site Id and Structure id
as parameters.
Method | Service | Endpoint |
---|---|---|
PUT | StructuredContent | /v1.0/sites/{siteId}/structured-contents |
./StructuredContent_POST_ToSite.sh 20125 40697
cURL script parameters:
Parameter # | Description |
---|---|
$1 | siteId |
$2 | contentStructureId |
To find your new Web Content 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>Foo</p>
HTML string using the Structure contentField
content
as reference.
{
"actions" : {
...
},
"availableLanguages" : [ "en-US" ],
"contentFields" : [ {
"contentFieldValue" : {
"data" : "<p>Foo</p>"
},
"dataType" : "string",
"label" : "content",
"name" : "content",
"nestedContentFields" : [ ],
"repeatable" : false
} ],
"contentStructureId" : 40697,
"creator" : {
"additionalName" : "",
"contentType" : "UserAccount",
"familyName" : "Bowman",
"givenName" : "David",
"id" : 20129,
"name" : "David Bowman"
},
"customFields" : [ ],
"dateCreated" : "2021-08-10T09:19:40Z",
"dateModified" : "2021-08-10T09:19:40Z",
"datePublished" : "2021-08-10T09:19:00Z",
"description" : "",
"externalReferenceCode" : "41569",
"friendlyUrlPath" : "able-article",
"id" : 41571,
"key" : "41569",
"keywords" : [ ],
"numberOfComments" : 0,
"relatedContents" : [ ],
"renderedContents" : [ {
"contentTemplateId" : "BASIC-WEB-CONTENT",
"contentTemplateName" : "Basic Web Content",
"markedAsDefault" : true,
"renderedContentURL" : "http://localhost:8080/o/headless-delivery/v1.0/structured-contents/41571/rendered-content/BASIC-WEB-CONTENT"
} ],
"siteId" : 20125,
"subscribed" : false,
"taxonomyCategoryBriefs" : [ ],
"title" : "Able Article",
"uuid" : "c7005ffb-5677-e030-9eb9-9b1a24a85054"
}
StructuredContent_POST_ToSite.java
The StructuredContent_POST_ToSite.java
class adds a Web Content article by calling the structured content related service.
Command:
java -classpath .:* -DcontentStructureId=1234 -DsiteId=5678 StructuredContent_POST_ToSite
Code:
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
StructuredContent structuredContent =
structuredContentResource.postSiteStructuredContent(
Long.valueOf(System.getProperty("siteId")),
new StructuredContent() {
{
contentFields = new ContentField[] {
new ContentField() {
{
contentFieldValue =
new ContentFieldValue() {
{
data = "<p>Foo</p>";
}
};
name = "content";
}
}
};
contentStructureId = Long.valueOf(
System.getProperty("contentStructureId"));
title = "Charlie Article";
}
});
System.out.println(structuredContent);
}
The StructuredContent
fields appear in JSON.
Patch Web Content Article
Use the PATCH
method with the StructuredContent
service to update the Web Content Article. The StructuredContent_PATCH_ById.[java|sh]
script uses the structured content identifier id
to update the article’s content from ‘Foo’ to ‘Bar’.
StructuredContent_PATCH_ById.sh
Command:
./StructuredContent_PATCH_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/structured-contents/${1}" \
--data-raw '
{
"contentFields": [
{
"contentFieldValue": {
"data": "<p>Bar</p>"
},
"name": "content"
}
]
}' \
--header "Content-Type: application/json" \
--request "PATCH" \
--user "test@liferay.com:learn"
StructuredContent_PATCH_ById.java
Command:
java -classpath .:* -DcontentStructureId=1234 -DstructuredContentId=5678 StructuredContent_PATCH_ById
Code:
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
StructuredContent structuredContent =
structuredContentResource.patchStructuredContent(
Long.valueOf(System.getProperty("structuredContentId")),
new StructuredContent() {
{
contentFields = new ContentField[] {
new ContentField() {
{
contentFieldValue =
new ContentFieldValue() {
{
data = "<p>Bar</p>";
}
};
name = "content";
}
}
};
contentStructureId = Long.valueOf(
System.getProperty("contentStructureId"));
}
});
System.out.println(structuredContent);
}
Put Web Content Article
Use the PUT
method with the StructuredContent
service to replace the original Web Content information. The StructuredContent_PUT_ById.[java|sh]
script uses the Web Content and Structure identifiers to replace the article’s name and the article’s content from Bar
to Goo
.
StructuredContent_PUT_ById.sh
Command:
./StructuredContent_PUT_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/structured-contents/${1}" \
--data-raw '
{
"contentFields": [
{
"contentFieldValue": {
"data": "<p>Goo</p>"
},
"name": "content"
}
],
"contentStructureId": "'"${2}"'",
"title": "Baker Article"
}' \
--header "Content-Type: application/json" \
--request "PUT" \
--user "test@liferay.com:learn"
StructuredContent_PUT_ById.java
Command:
java -classpath .:* -DcontentStructureId=1234 -DstructuredContentId=5678 StructuredContent_PUT_ById
Code:
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
StructuredContent structuredContent =
structuredContentResource.putStructuredContent(
Long.valueOf(System.getProperty("structuredContentId")),
new StructuredContent() {
{
contentFields = new ContentField[] {
new ContentField() {
{
contentFieldValue =
new ContentFieldValue() {
{
data = "<p>Goo</p>";
}
};
name = "content";
}
}
};
contentStructureId = Long.valueOf(
System.getProperty("contentStructureId"));
title = "Dog Article";
}
});
System.out.println(structuredContent);
}
Delete Web Content Article
Use the DELETE
method with the StructuredContent
service to delete a Web Content Article. The StructuredContent_DELETE_ById.[java|sh]
script example uses the Web Content id
to delete the Web Content.
When you delete Web Content using the REST API, it’s deleted permanently, without using the Liferay DXP Recycle Bin.
StructuredContent_DELETE_ById.sh
Command:
./StructuredContent_DELETE_ById.sh 1234
Code:
curl \
"http://localhost:8080/o/headless-delivery/v1.0/structured-contents/${1}" \
--request "DELETE" \
--user "test@liferay.com:learn"
StructuredContent_DELETE_ById.java
Command
java -classpath .:* -DstructuredContentId=1234 StructuredContent_DELETE_ById
Code:
public static void main(String[] args) throws Exception {
StructuredContentResource.Builder builder =
StructuredContentResource.builder();
StructuredContentResource structuredContentResource =
builder.authentication(
"test@liferay.com", "learn"
).build();
structuredContentResource.deleteStructuredContent(
Long.valueOf(System.getProperty("structuredContentId")));
}
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 |
---|---|
StructuredContentFolder_GET_ById.[java\|sh] | Lists a Web Content folder’s fields. |
StructuredContentFolders_GET_FromSite.[java\|sh] | Lists all Web Content folders in the Site. |
StructuredContentFolder_POST_ToSite.[java\|sh] | Posts a Web Content folder to a Site. |
StructuredContentFolder_PATCH_ById.[java\|sh] | Updates a Web Content Folder. |
StructuredContentFolder_PUT_ById.[java\|sh] | Replaces a Web Content Folder. |
StructuredContentFolder_DELETE_ById.[java\|sh] | Deletes a Web Content Folder. |
StructuredContent_POST_ToStructuredContentFolder.[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.