Closed mapsmarketing closed 12 months ago
Hi @mapsmarketing currently GrapesJS is not able to properly import HTML documents as string, so the parser skips elements like html
, head
, body
and returns only what is parsed inside the body
, one workaround you could do right now is to pass component as object
component: {
attributes: { id: 'ignt' },
components: '<div class="my-el">Testing world!</div>',
},
Regarding the styles, it's the browser's default CSSOM parser issue, please refer to this plugin
Hi @artf ,
I've found a way to get the body
attributes along with the styles saving correctly via the following method:
const pageManager = editor.Pages;
const page = pageManager.get('my-page-id').toJSON();
const component = pageManager.get('my-page-id').getMainComponent();
page.styles = editor.getCss({ component });
I noticed that your Page.toJSON outputs everything of the specified page. However, it doesn't seem to output the styles
correctly (it's always set as undefined for me), so I retrieve the styles for the active page via the editor and override the ones in the JSON. I believe styles
are not set due to the if (!props.frames)
check you have in Page.ts
The below is an example of how I'm loading in the HTML. I am using frames
since component
doesn't work with the supplied structure. I am loading in the styles without the use of the parser plugin and it seems to be loading in without issues.
const pageJSON = {...}; // Contains the `frames` and `styles`
const editor = grapesjs.init({
pageManager: {
pages: [
{
id: 'my-page-id',
frames: pageJSON.frames,
styles: pageJSON.styles,
}
]
}
});
I also noticed that the PageManager.select function doesn't update styles when switching between the pages which forces me to run: editor.setStyle(pageJSON.styles);
One annoying thing is that the editor is prepending the below default styles which when saving the styles has numerous duplicates of it:
* {
box-sizing: border-box;
}
body {
margin: 0;
}
Edit: Looking at the docs I finally managed to find protectedCss
and when set to empty stops the styles being prepended.
I'd suggest you following this to properly load your JSON projects. Styles are stored in a separate module, that's the reason why you don't see them per pages.
Hi @artf ,
I saw that in your docs. I am storing the pages separately in my database at the moment which is why I was approaching it in the way I have.
I might abandon this and try and make it work with your Storage Manager instead in some way.
Have an awesome weekend Artf
I've managed to get the HTML and CSS for each page correctly and save it to the DB without the use of storeManager
. I just didn't like the way storeManager
did things.
Here is how I'm putting it together (this also saves/loads the <body>
correctly):
const editorPages = [
{
id: id,
name: title,
frames: frames, // i'm not using `component`
styles: styles,
}
];
editorRef.current.Commands.add("savePage", async () => {
const pageManager = editorRef.current.Pages;
const selectedPage = pageManager.getSelected();
const component = selectedPage.getMainComponent();
const selectedPageJSON = selectedPage.toJSON();
const Html = editorRef.current.getHtml({
component: component,
cleanId: true,
});
const Css = editorRef.current.getCss({
component: component,
avoidProtected: true,
});
pageManager.getAll().map((item) => {
if (item.getId() === selectedPage.getId()) {
item.set("styles", Css);
item.set("frames", selectedPageJSON.frames);
pageManager.add(item);
}
});
dispatch(
updatePage({
_id: selectedPage.getId(),
frames: selectedPageJSON.frames,
component: Html, // saving it, but not using it
styles: Css,
})
);
});
I'm setting avoidProtected
to true
as otherwise it infinitely continues to append the default styling to the CSS.
Here is my init
purely for completions sake:
editorRef.current = grapesjs.init({
autoload: true,
container: `#editor`,
plugins: [
grapesjsPresetWebPage,
grapesjsParserPostCSS,
grapesjsPluginsBlocksBasic,
grapesjsPluginsCKEditor,
],
pluginsOpts: {
[grapesjsPresetWebPage]: {},
[grapesjsParserPostCSS]: {},
[grapesjsPluginsBlocksBasic]: {},
[grapesjsPluginsCKEditor]: {},
},
selectorManager: { componentFirst: true },
storageManager: false,
pageManager: {
pages: editorPages,
},
});
The styles need to be re-set when navigating between pages to maintain any new changes:
const pageManager = editorRef.current.Pages;
pageManager.select(page._id);
editorRef.current.setStyle(page.styles);
GrapesJS version
What browser are you using?
Chrome v117.0.5938.149
Reproducible demo link
https://jsfiddle.net/9oLrsvya/
Describe the bug
How to reproduce the bug?
pageManager
object in the jsfiddleWhat is the expected behavior? Looking at the following documentation: https://grapesjs.com/docs/api/pages.html#pages
It should load in the
component
andstyles
from thepageManager
correctly into the editor.What is the current behavior? When you check the code via "view code" in the editor you'll notice neither the exact HTML neither the styles have correctly loaded. The
body
tag does not retain theID
tag that the editor adds when applying any kind of styling to it which means the styling won't work. And the CSS hasn't loaded in correctly at all.If it is a confirmed bug, I'd be happy to attempt to fix it. It would be great to roughly know where the
component
andstyles
are being loaded from as I am not intimately familiar with the project files.Code of Conduct