GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
Other
22.61k stars 4.09k forks source link

[Question] Losing the component information on saving the code from Code Editor #2691

Closed sathyanarayananaCES closed 4 years ago

sathyanarayananaCES commented 4 years ago

I have integrated the code edit option in the Web builder.

Issues

  1. On Saving the html from the code editor, it loses all the old component related information and acts as a new component with default values in the traits.
  2. data-gjs-type becomes default and it is not recognizing the custom components.

Anaysis & Thoughts On checking it seems like,

  1. when we use editor.getHtml() it gives the final html without any data-gjs-* attributes.
  2. editor.setComponents() method seems to override the old component information.

Questions

  1. In order to retain all the old component information and use it after editing the HTML in the editor, how can we do that?
  2. If it is by using editor.getComponents(), how can we store and reuse after saving the content from the code editor? set_content save_content
pouyamiralayi commented 4 years ago

Hi @sathyanarayananaCES you must call editor.getComponents and editor.getStyle in order to retrieve the components details; then you can return to the stored state by calling editor.setComponents and editor.setStyle with the result of above mentioned function calls. Cheers!

jenter commented 4 years ago

@pouyamiralayi could you expand on your answer please? Meaning, what function would you string with getComponents to render the HTML for the htmlCodeViewer and then how would you properly return that when saving?

pouyamiralayi commented 4 years ago

@jenter #1331 comment and #2644 comment are good examples. Also checkout #2664 comment which is a pitfall to avoid! Cheers!

sathyanarayananaCES commented 4 years ago

Thank you @pouyamiralayi for your responses.

@jenter , I was also having the same question.

I took a look at those reply comments, from which I got the component tree using JSON.parse(JSON.stringify(editor.getComponents())). I think htmlCodeViewer content should be set with the old components JSON, by which the html content can be edited and saved using editor.setComponents.

I am facing an issue while doing that. Since htmlCodeViewer.setContent() expects a string, I could not set the getComponents JSON. I also tried without JSON.parse, it throws an error in the console.

Do we have any other function to set it as a JSON to the htmlCodeViewer?

Please correct me If I am understanding it in the different way.

jenter commented 4 years ago

@pouyamiralayi thanks so much for the references. Just as a fyi, I used getEl() to render the complete HTML for the modal. https://grapesjs.com/docs/api/component.html#getel

noogen commented 4 years ago

@sathyanarayananaCES First, to echo others that it is best to use get/setComponents and get/setStyle to save the content of the editor. If I understand your usage correctly, that you want HTML for htmlCodeEditor and be able to import back into the editor after user edit. Take a look at the demo of the editor import which simply call setComponents with raw HTML. Refs - https://github.com/artf/grapesjs/blob/dev/docs/api/editor.md#examples and https://github.com/artf/grapesjs/blob/dev/test/specs/grapesjs/index.js#L180

To do what you want will require call to editor.genHtml() for the htmlCodeViewer.setContent and import back with editor.setComponents with the raw HTML from htmlCodeViewer instead of dealing with components array. The gotcha/pitfall that you have to understand is, internally, grapejs try its best to parse that raw HTML back into components array. Parsing HTML is difficult even with valid HTML. Therefore, you will get unexpected result and may lose data that grapejs cannot parse. This is the reason why everyone is suggesting to use getComponents and getStyle if you ever want to store and load it back. I hope that provide some clarity into why you are losing data? It's because you are using import/grapesjs HTML parsing.

sathyanarayananaCES commented 4 years ago

@noogen , Thank you for your time and perfect explanation!!

It provides better clarity on the reason behind data loss. Those references helped a lot to understand better.

For others who face this problem, I have solved using editor.getHtml() and editor.setComponents as mentioned above.

Just take care of the following things to avoid this scenario.

I am closing this issue. Thanks @pouyamiralayi , @noogen for your help.