Common sections (header/footer) in a multipage context #555
Replies: 1 comment 1 reply
-
@johann-taberlet I have implemented the functionality of reusable components and I think that is what you are looking for. You have to save the nodeTree of the node in Serialized form in the database. After saving the nodeTree, you can use convert the serilized nodeTree back to its original form and reuse them in any page and also in a single page multiple times. Code for saving a node (and all its children of course):function saveNode(nodeId) {
var nodeTree = node(nodeId).toNodeTree()
// we need to serialize the nodes in the node tree for storage
nodeTree.nodes = nodesToSerializedNodes(nodeTree.nodes)
// save the component in database with other data like name of component, description etc:
saveNodeInDatabase({
name: "header",
nodeTree: nodeTree
})
}
function nodesToSerializedNodes (nodes) {
// getSerializedNodes is present in the useEditor hook
const serializedNodes = getSerializedNodes()
const result = {}
Object.keys(nodes).forEach(key => {
result[key] = serializedNodes[key]
})
return result
} Code for using/adding the saved node in craft editor:// component is the node that was saved in database.
const nodeTree = cloneSerializedNodeTreeToNodeTree(component.nodeTree)
const parentNodeId = "some-parent";
// addNodeTree is present inside actions from useEditor hook. The component can be inserted inside any parent at any index:
addNodeTree(nodeTree, parentNodeId, 0)
// This function converts the nodes inside the nodeTree to their original form.
// The returned nodeTree is actually a kind of clone (with new ids for nodes but same structure).
// This is done so that we can add the same component multiple times in the craft editor (each clone is a different component).
function cloneSerializedNodeTreeToNodeTree (serializedNodeTree) {
const treeNodes = {}
const serializedNodes = serializedNodeTree.nodes
function changeNodeId(node, newParentId) {
const newNodeId = getRandomId()
const childNodes = node.nodes
? node.nodes.map(childId =>
changeNodeId(serializedNodes[childId], newNodeId)
)
: []
treeNodes[newNodeId] = parseSerializedNode(node).toNode(
node => {
node.id = newNodeId
node.data.parent = newParentId ?? node.data.parent
node.data.nodes = childNodes
}
)
return newNodeId
}
const rootNodeId = changeNodeId(serializedNodes[serializedNodeTree.rootNodeId])
return {
rootNodeId,
nodes: {
...treeNodes
}
}
}
I didn't quite understand what you meant by circular structure. The json structure you shared does not seem to have any circular dependency. I just hope my solution was something you were looking for. |
Beta Was this translation helpful? Give feedback.
-
Hi,
I'm encountering some challenges while trying to implement a new feature in my project. Up until now, I have successfully developed a multipage editor. This involved persisting a compressed version of each page's state in the database and loading it into the editor whenever the user switches pages.
Now, I'm working on implementing a feature that would allow the header and footer sections to be common across all pages, similar to how it works in platforms like Wix. To achieve this, I've created an initial state for each page, with three containers: header, main content, and footer. Each container is assigned a specific ID. My intention is to extract the nodeTree for these sections, persist these trees in the database, and then "inject" them (by deleting and adding nodeTree nodes) when a page is loaded, ensuring consistency across all pages.
However, I've encountered an issue that I'm struggling to resolve. When attempting to stringify the nodeTrees, I run into problems with circular structures, making the process difficult.
Has anyone else implemented a similar feature? I'm curious to know what approaches others have taken to address this issue and successfully implement this functionality.
Your insights would be greatly appreciated.
Beta Was this translation helpful? Give feedback.
All reactions