Hello - could you please explain or refer me to docs on how to create and register a custom content in my Forge App and how to register it to be rendered under SpaceCustomContentListView? Thanks a lot!
Hi @AsmaaHadir, thanks for reaching out.
Please refer to this page, which explains how to register custom content with Forge. Let us know if you have follow-up questions.
Hi @OleksandrBeztsinnyi - thank you for your reply. I had actually referred to the same page to understand how to create my custom content for my app but I still have a couple of questions. For instance, I have written the following code based on confluence’s REST API’s to test the creation a custom content ‘keyword’ but I keep getting errors regarding the values of the bodyData
keys indicating that spaceId
for instance is of type Long:
import api, { route } from "@forge/api";
const customContent = async () => {
const {spaceKey, localId, environmentType} = useProductContext();
const type = `forge:${localId}:${environmentType}:keyword`;
var bodyData = `{
"type": "<string>",
"status": "current",
"spaceId": "<string>",
"pageId": "<string>",
"blogPostId": "<string>",
"customContentId": "<string>",
"title": "<string>",
"body": {
"representation": "storage",
"value": "<string>"
}
}`;
const response = await api.asUser().requestConfluence(route`/wiki/api/v2/custom-content`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: bodyData
});
Also, How do I practically register/save the custom content that I have Posted? or the API call all what I need to perform? for context, my manifest.yml
looks like this:
modules:
confluence:spacePage:
- key: keywise-test-space-page-hello-world
function: main
title: KeyWise-test for Asmaa
route: hello-world
function:
- key: main
handler: index.run
app:
id: ari:cloud:ecosystem::app/134c6c41-0af6-4788-adc3-bd01fd2fc3ec
permissions:
scopes:
- read:space:confluence
- read:confluence-content.summary
- read:content-details:confluence
- read:page:confluence
- write:custom-content:confluence
Thanks a lot in advance
Hey @AsmaaHadir ,
thanks for more details.
Do you register keyword
custom content under the space container? (I don’t see this from your manifest example)
What do you put as a spaceId
in bodyData
?
Also, How do I practically register/save the custom content that I have Posted? or the API call all what I need to perform? for context
That’s right. The only way to create custom content is with REST API. Once a custom content module is registered, custom content can be created from any other registered module.
Hi @OleksandrBeztsinnyi - What do I need to modify about my manifest.yml
to register the keyword
custom content?
I have created a helper function to retrieve the current space ID as the following:
export const getSpaceIdByKey = async (spaceKey) => {
const response = await api.asUser().requestConfluence(route`/wiki/api/v2/spaces?${spaceKey}`, {
headers: {
'Accept': 'application/json'
}
});
const data_response = await response.json();
// Iterate through the results to find the space with the matching key
for (const space of data_response.results) {
if (space.key === spaceKey) {
return space.id; // Return the ID of the matching space
}
}
// If no matching space is found, you can return null or handle the error accordingly
console.log("space key not found")
return null;
}
and I insert the number that I retrieve from it into the spaceId
field. Also, How do I add custom fields so that I can render them in the SpaceCutomContentViewList
? Thank you so much for the help.
Hey @AsmaaHadir,
you must register a module for custom content in your manifest. Something like
modules:
confluence:customContent:
- key: keyword
title: Keywords
description: Custom content for keywords
bodyType: raw
supportedContainerTypes:
- space
function: keywordView
confluence:spacePage:
....
having this module gives you the ability to use Custom Content REST API.
The way you get spaceId
should work.
How do I add custom fields so that I can render them in the
SpaceCutomContentViewList
?
SpaceCustomContentListView
is a simple predefined component. It displays only icon, title, contributors, and last modified date. If you want to display your own custom fields in the list the SpaceCustomContentListView
component can’t be used. You should create your own component for this purpose.
Thank you so much @OleksandrBeztsinnyi for the simplified explanation.
Regarding this point:
Even though I can’t display additional properties under the SpaceCustomContentListView
UI, I can still add my own fields to my keyword
custom content type in its bodyData
and use custom UI to display them, right? Otherwise if I choose to use SpaceCustomContentListView
the user would need to click on a custom content key to render the page with additional properties?
One more question: regarding the function
field for my CustomContent
module in manifest.yml
, it is basically a function that I define which makes a REST API call and retrieves a custom content for me, or is it the main
function in App()
which displays the customContent
in the UI? for example, based on the sample manifest.yml
file that you have replied with, I could define a keywordView
function which returns a keyword custom content with API calls and use it inside my App()
main function?
Hey @OleksandrBeztsinnyi - sorry for the multiple questions but I got a bit confused reading the documentation. What does the extractAppId
refer to when defining the type
field for the custom content type below?
// extractAppId implementation omitted
const type = `forge:${extractAppId(localId)}:${environmentType}:note`;
I can still add my own fields to my
keyword
custom content type in itsbodyData
and use custom UI to display them, right?
Right.
Otherwise if I choose to use
SpaceCustomContentListView
the user would need to click on a custom content key to render the page with additional properties?
Correct. SpaceCustomContentListView
displays a list of custom content. However, actual custom content will be rendered when the user clicks on the title.
regarding the
function
field for myCustomContent
module
this function defines the UI that will be rendered for specific custom content (when the user clicks on the title of one of the list items of SpaceCustomContentListView
). This function should fetch the body (or other params) of custom content before being displayed.
What does the
extractAppId
refer to when defining thetype
field for the custom content type below?
As it was mentioned in the documentation, the type for registered Forge custom content will have this format
forge:[APP_ID]:[ENVIRONMENT_ID]:[MODULE_KEY]
For example:
forge:b44c55b2-251f-45e3-8ea4-b56762f82e8a:f7522737-117c-46e7-a7ca-03a73c99afcf:keyword
APP_ID
: The identifier for your Forge app. To get the app ID, use the useProductContext hook. The app ID is a part of thelocalId
attribute.
To get APP_ID
from localId
you should parse it, that’s what extractAppId
does.
Hope this helps