Message Boards

Adding structured-content through headless API (part2)

thumbnail
Fernando Fernandez, modified 3 Years ago.

Adding structured-content through headless API (part2)

Expert Posts: 396 Join Date: 8/22/07 Recent Posts

Hi guys,

Some days ago I posted here about a project we're working to migrate sharepoint content to Liferay DXP SP2. The answers I got allowed me to create a webcontent with a simple structure, multi-language, with an image reference and categories.

Now I'm working with the structure the client really needs and I'm having some strange problems with language fields. On my dev machine I was getting error 400 "Validation error: Invalid available locales set for field name title" and I had to reduce the structure to a en-US only structure on a clean site to make uploads work. 

Now I'm trying to make the processo work on the client's dev machine and I'm not able to work around the same error.

My structure is like this:

{
    "availableLanguageIds": [
        "pt_PT",
        "en_US"
    ],
    "defaultLanguageId": "en_US",
    "fields": [
        {
            "label": {
                "pt_PT": "Título",
                "en_US": "Title"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "title",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "pt_PT": "Subtítulo",
                "en_US": "Subtitle"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "subtitle",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "pt_PT": "Data",
                "en_US": "Date"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "date",
            "fieldNamespace": "ddm",
            "indexType": "keyword",
            "localizable": true,
            "name": "newsDate",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-date"
        },
        {
            "label": {
                "pt_PT": "Imagens",
                "en_US": "Images"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "image",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "newsImg",
            "readOnly": false,
            "repeatable": true,
            "required": false,
            "showLabel": true,
            "type": "ddm-image"
        },
        {
            "label": {
                "pt_PT": "Corpo da notícia",
                "en_US": "News Body"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "html",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "HTMLj7zr",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-text-html"
        },
        {
            "label": {
                "pt_PT": "Link YouTube",
                "en_US": "Link YouTube"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "idVideo",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        }
    ]
}

  

As I wrote, I had to "downgrade" the structure to single-language to get around the error on local dev environment. The simpler structure looks like:

{
    "availableLanguageIds": [
        "en_US"
    ],
    "defaultLanguageId": "en_US",
    "fields": [
        {
            "label": {
                "en_US": "Title"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "title",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "en_US": "Subtitle"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "subtitle",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "en_US": "Date"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "date",
            "fieldNamespace": "ddm",
            "indexType": "keyword",
            "localizable": true,
            "name": "newsDate",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-date"
        },
        {
            "label": {
                "en_US": "Images"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "image",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "newsImg",
            "readOnly": false,
            "repeatable": true,
            "required": false,
            "showLabel": true,
            "type": "ddm-image"
        },
        {
            "label": {
                "en_US": "News Body"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "html",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "HTMLj7zr",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-text-html"
        },
        {
            "label": {
                "en_US": "Link YouTube"
            },
            "predefinedValue": {
                "en_US": ""
            },
            "style": {
                "en_US": ""
            },
            "tip": {
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "idVideo",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        }
    ]
}

 

I'm using this endpoint:

http://10.99.99.53:8080/o/headless-delivery/v1.0/sites/20124/structured-contents/

And I'm sending this body:

{
    "siteId": 20124,
    "contentStructureId": 69782,
    
    "title": "Noticia Dois",
    "description": "<p>Summary</p>",
    "contentFields": [
        {
            "name": "title",
            "value": {
                "data": "Story one"
            }
        },
        {
            "name": "subtitle",
            "value": {
                "data": ""
            }
        },
        {
            "name": "newsDate",
            "value": {
                "data": "2020-11-14T00:00:00Z"
            }
        },
        {
            "name": "HTMLj7zr",
            "value": {
                "data": "<p>Story Body</p>"
            }
        },
        {
            "name": "newsImg",
            "value": {
                "image": {
                    "id": 69726,
                    "description": "foto"
                }
            }
        }
    ]
}

Still I get:

{
    "status": "BAD_REQUEST",
    "title": "Validation error: Invalid available locales set for field name title"
}

 

I'm at a loss on why this is working on a local machine but now working on a simular setup (only it's not a freshly installed site).

Any ideas on how to work around this problem? 

TIA

Fernando

thumbnail
Javier De Arcos, modified 3 Years ago.

RE: Adding structured-content through headless API (part2)

New Member Posts: 9 Join Date: 7/16/20 Recent Posts

The error description means that the content field "title" is not getting all the locales it needs to update. It migth have more languages and you have to add the remaining ones in the data_i18n property, or it might need a different language than the one defined in the Accept-Language header (or the default language configured in the Portal if you are not setting the header).

thumbnail
Fernando Fernandez, modified 3 Years ago.

RE: RE: Adding structured-content through headless API (part2)

Expert Posts: 396 Join Date: 8/22/07 Recent Posts

Hi Javier,

I've gone back to the intended config and tried again (so forget the previous code), with the same result.

At this point:

  • default language in portal-ext-properties is company.default.locale=pt_PT
  • default language for the instance (in control panel) is pt-PT, with pt-PT and en-US available
  • default language for site is pt-PT with pt-PT and en-US available
  • default language for structure is pt_PT and pt_PT and en_US available (struct source below)
  • both locales are being sent in i18n attributes on POST (see below)
  • I'm not sending the Accept-Language  with the POST

(I'm not sure what you mean by "the default language configured in the Portal" so I'm assuming you're referring to the instance configuration)

 

Thanks

Fernando

 

Structure code:

{
    "availableLanguageIds": [
        "pt_PT",
        "en_US"
    ],
    "defaultLanguageId": "pt_PT",
    "fields": [
        {
            "label": {
                "pt_PT": "Titulo",
                "en_US": "Title"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "Titulo",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "pt_PT": "Subtitulo",
                "en_US": "Subtitle"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "Subtitulo",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        },
        {
            "label": {
                "pt_PT": "Data",
                "en_US": "Date"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "date",
            "fieldNamespace": "ddm",
            "indexType": "keyword",
            "localizable": true,
            "name": "Data",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-date"
        },
        {
            "label": {
                "pt_PT": "Imagens",
                "en_US": "Images"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "image",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "Imagens",
            "readOnly": false,
            "repeatable": true,
            "required": false,
            "showLabel": true,
            "type": "ddm-image"
        },
        {
            "label": {
                "pt_PT": "Corpo notícia",
                "en_US": "News Body"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "html",
            "fieldNamespace": "ddm",
            "indexType": "text",
            "localizable": true,
            "name": "HTMLj7zr",
            "readOnly": false,
            "repeatable": false,
            "required": true,
            "showLabel": true,
            "type": "ddm-text-html"
        },
        {
            "label": {
                "pt_PT": "Link YouTube",
                "en_US": "Link YouTube"
            },
            "predefinedValue": {
                "pt_PT": "",
                "en_US": ""
            },
            "style": {
                "pt_PT": "",
                "en_US": ""
            },
            "tip": {
                "pt_PT": "",
                "en_US": ""
            },
            "dataType": "string",
            "indexType": "keyword",
            "localizable": true,
            "name": "idVideo",
            "readOnly": false,
            "repeatable": false,
            "required": false,
            "showLabel": true,
            "type": "text"
        }
    ]
}

 

POSTed data:

{
    "siteId": 20124,
    "contentStructureId": 69782,
    "title": "Noticia Um",
    "title_i18n": {
        "pt-PT": "Noticia Um",
        "en-US": "Noticia Um"
    },
    "description": "<p>Summary</p>",
    "description_i18n": {
        "pt-PT": "<p>Sumário</p>",
        "en-US": "<p>Summary</p>"
    },
    "contentFields": [
        {
            "name": "title",
            "value": {
                "data": "Story one"
            },
            "value_i18n": {
                "pt-PT": {
                    "data": "Noticia Um"
                },
                "en-US": {
                    "data": "Story one"
                }
            }
        },
        {
            "name": "subtitle",
            "value": {
                "data": ""
            },
            "value_i18n": {
                "pt-PT": {
                    "data": ""
                },
                "en-US": {
                    "data": ""
                }
            }
        },
        {
            "name": "newsDate",
            "value": {
                "data": "2020-11-14T00:00:00Z"
            },
            "value_i18n": {
                "pt-PT": {
                    "data": "2020-11-14T00:00:00Z"
                },
                "en-US": {
                    "data": "2020-11-14T00:00:00Z"
                }
            }
        },
        {
            "name": "HTMLj7zr",
            "value": {
                "data": "<p>Story Body</p>"
            },
            "value_i18n": {
                "pt-PT": {
                    "data": "<p>Corpo da notícia</p>"
                },
                "en-US": {
                    "data": "<p>Story Body</p>"
                }
            }
        },
        {
            "name": "newsImg",
            "value": {
                "image": {
                    "id": 69726,
                    "description": "foto"
                }
            },
            "value_i18n": {
                "pt-PT": {
                    "image": {
                        "id": 69726,
                        "description": "foto"
                    }
                },
                "en-US": {
                    "image": {
                        "id": 69726,
                        "description": "foto"
                    }
                }
            }
        }
    ]
}

 

thumbnail
Fernando Fernandez, modified 3 Years ago.

RE: RE: Adding structured-content through headless API (part2)

Expert Posts: 396 Join Date: 8/22/07 Recent Posts

Meanwhile, Javier, I've opened a ticket for your coleagues in support. Just letting you know, so there's no double work.

Thanks

 

Fernando

thumbnail
Fernando Fernandez, modified 3 Years ago.

RE: Adding structured-content through headless API (part2) (Answer)

Expert Posts: 396 Join Date: 8/22/07 Recent Posts

The problem was, finally, a bug on the handling of non US default languages, but also the need of sending the Accept-languages header with the default language selection.

This post works:

 

{
    "availableLanguages": ["en-US","pt-PT"],
    "taxonomyCategoryIds":[40745],
    "contentStructureId": 40463,
    "siteId": 40428,
    "title": "Lorem lacinia sed amet culpa integer",
    "title_i18n": {
        "pt-PT": "Rem cubilia, turpis eos",
        "en-US": "Lorem lacinia sed amet culpa integer"
    },
    "description": "<p>Summary</p>",
    "description_i18n": {
        "pt-PT": "<p>Sumário</p>",
        "en-US": "<p>Summary</p>"
    },
    "contentFields": [
        {
            "contentFieldValue": { "data": "Lorem lacinia sed amet" },
            "contentFieldValue_i18n": {
                "pt-PT": {"data": "Rem cubilia, turpis eos"},
                "en-US": {"data": "Lorem lacinia sed amet"}
            },
            "name": "Titulo"
        },
        {
            "contentFieldValue": {"data": ""},
            "contentFieldValue_i18n": {
                "pt-PT": {"data": ""},
                "en-US": {"data": ""}
            },
            "name": "Subtitulo"
        },
        {
            "contentFieldValue": {"data": "2020-11-17T00:00:00Z"},
            "contentFieldValue_i18n": {
                "pt-PT": {"data": "2020-11-17T00:00:00Z"},
                "en-US": {"data": "2020-11-17T00:00:00Z"}
            },
            "name": "Data"
        },
        {
            "contentFieldValue": {
                "image": {"id": 41239}
            },
            "contentFieldValue_i18n": {
                "pt-PT": {"image": {"id": 41236}},
                "en-US": {"image": {"id": 41239}}
            },
            "name": "Imagens"
        },
        {
            "contentFieldValue": {
                "data": "<p>Lorem lacinia sed amet.</p>"
            },
            "contentFieldValue_i18n": {
                "pt-PT": {"data": "<p>Rem cubilia, turpis eos! </p>"},
                "en-US": {"data": "<p>Lorem lacinia sed amet. /p>"}
            },
            "name": "Corpo"
        },
        {
            "contentFieldValue": {"data": ""},
            "contentFieldValue_i18n": {
                "pt-PT": {"data": ""},
                "en-US": {"data": ""}
            },
            "name": "idVideo"
        }
    ]
}

 

Hope this helps

thumbnail
Jonathan HELL, modified 1 Month ago.

RE: RE: Adding structured-content through headless API (part2)

New Member Posts: 3 Join Date: 11/25/20 Recent Posts

Thank you Fernando, you answer helped me a lot.

I came across another issue giving me an error message "Invalid available locales set for field name". For those wondering what is going on, the structure you are using MUST be translated in order for the API call to work. I don't know why but Liferay seems to check if the structure locales match the contentFieldValue locales. I doesn't make sense but it works.

So if you get the message "Invalid available locales set for field name", be sure to:

  1. Send the correct Accept-Language header
  2. Have translations available for the structure you are using (contentStructureId)

Jonathan.