BUG: Custom component for text node including special characters
Question
GrapesJS version
- I confirm to use the latest version of GrapesJS
What browser are you using?
Chrome v105
Reproducible demo link
https://codesandbox.io/s/fancy-brook-ppyc8v?file=/index.js
Describe the bug
Background: I am trying to configure grapesjs to be able to edit markup that contains the Liquid template language. As such I would like to create two types of custom components.
- A template block in the form of
{{some_variable}} - A condition block in the form of
{% if condition .... %}
The custom components should later be configured to allow the user to modify certain aspects of the components.
However, it appears that there is some issue in achieving the second requirement, having a code block that starts with {%}
How to reproduce the bug?
- Run the code sandbox link
- Observe that the custom component is initialised for the case of
liquid-template-blockbut not for the case of liquid-condition-block
What is the expected behavior? the initialisers for both custom components should be run
What is the current behavior?
only the initialiser for the custom component liquid-template-block is run
If is necessary to execute some code in order to reproduce the bug, paste it here below: just run the code sandbox link
Code of Conduct
- I agree to follow this project's Code of Conduct
Answers (2)
Hi @malonecj I'm not sure how exactly you would expect to see and manage those components (especially when you combine templates inside conditions) but I think your current approach in isComponent is not properly correct as you have to deal with text nodes.
Inside your liquid handle isComponent you use el.textContent which I think should be similar to liquid condition with el.nodeValue as it's only available on text nodes (probably it would be better to check if it's actually a text node el.nodeType === 3).
As a first step try to update your custom components in this way, as currently are skipped from the parser due to this condition
editor.Components.addType("liquid-condition", {
isComponent: (el) => {
const { nodeValue } = el;
const isComponent = nodeValue?.trim().includes("{%");
// This probably will help you understand better how the parser processes nodes
console.log('isComponent liquid-condition', { el, nodeValue, isComponent });
if (isComponent) {
return {
tagName: 'liquid-condition-el',
components: { type: 'textnode', content: nodeValue },
}
}
},
...
editor.Components.addType("liquid-handle", {
isComponent: (el) => {
const { nodeValue } = el;
const isComponent = nodeValue?.trim().includes("{{");
console.log('isComponent liquid-handle', { el, nodeValue, isComponent });
if (isComponent) {
return {
tagName: 'liquid-handle-el',
components: { type: 'textnode', content: nodeValue },
}
}
},
...
But I don't think this approach will work once you start to mix templates with conditions as from the HTML parser perspective you receive something like this:
* div
* textNode - containing content starting from '{% case...' to '{% endcase %}'
* div - containing 'Hello World!!!'
* textNode - containing `{{ some_content }}`
So probably another approach would be to use one custom component as a parser of the template engine
Components.addType("liquid-case-condition", {
// no need for isComponent here, only the parser will output components for the engine
model: {
toHTML(opts) {
return `{% case ${this.get('conditionName')} %}
${this.getInnerHTML(opts)}
{% endcase %}`;
}
},
});
// ... other components to handle better the template engine
Components.addType("template-engine", {
isComponent: (el) => {
const { nodeValue } = el;
if (nodeValue?.trim().includes("{%")) {
const parsedTextNode = parseEngineText(nodeValue);
// transform parsed stuff in components for the editor, eg.
return {
type: 'template-engine',
components: [
{
type: 'liquid-case-condition',
conditionName: 'shop.subscription.currentPlanName',
components: [
// ... other template engine components
]
}
// ...
]
};
}
},
});
I'm closing this one as there are no issues with the core itself, if you have any other questions @malonecj let me know.
Related Questions and Answers
Continue research with similar issue discussions.
Issue #3939
BUG: Disabled drag and drop in preview
GrapesJS version[X] I confirm to use the latest version of GrapesJSWhat browser are you using? v95Reproducible demo link https://codesandbo...
Issue #6081
BUG: Custom Component not able to visible in grapsJs/studio at first rendering
GrapesJS version[X] I confirm to use the latest version of GrapesJSWhat browser are you using? chromeReproducible demo link https://stackbl...
Issue #4906
BUG: Grapesjs fails to recognize component types when setting innerHTML through script.
GrapesJS version [X] I confirm to use the latest version of GrapesJS What browser are you using? chrome v108.0.5359.98 Reproducible demo li...
Issue #6685
BUG: Custom component styles are not applied after deletion and re-addition
GrapesJS version [x] I confirm to use the latest version of GrapesJS What browser are you using? Chrome v143.0.7499.193 Reproducible demo l...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.