GrapesJs and PHP - store and load data to show in editor and as HTML page as well
Question
I am using GrapesJS to build a simple webpage.
I included the script in the following way inside head part :
<script type="text/javascript" src="js/jquery-1.10.2.js"></script>
<link rel="stylesheet" type="text/css" href="grapesjs-dev/dist/css/grapes.min.css">
<script type="text/javascript" src="grapesjs-dev/dist/grapes.min.js"></script>
I am using GrapesJS to build a simple webpage.
I included the script in the following way inside head part :
<script type="text/javascript" src="js/jquery-1.10.2.js"></script> <link rel="stylesheet" type="text/css" href="grapesjs-dev/dist/css/grapes.min.css"> <script type="text/javascript" src="grapesjs-dev/dist/grapes.min.js"></script>HTML:
<div id="gjs" style="height:0px; overflow:hidden;">
</div>
Javascript :
<script>
var editor = grapesjs.init({
showOffsets: 1,
noticeOnUnload: 0,
container: '#gjs',
fromElement: true,
height: '100%',
fromElement: true,
storageManager: { autoload: 0 },
assetManager: {
assets: [
'http://placehold.it/350x250/78c5d6/fff/image1.jpg',
// Pass an object with your properties
{
type: 'image',
src: 'http://placehold.it/350x250/459ba8/fff/image2.jpg',
height: 350,
width: 250
},
{
// As the 'image' is the base type of assets, omitting it will
// be set as `image` by default
src: 'http://placehold.it/350x250/79c267/fff/image3.jpg',
height: 350,
width: 250
},
],
},
storageManager: {
type: 'remote',
stepsBeforeSave: 1,
autosave: true, // Store data automatically
autoload: true,
urlStore: 'save_now.php',
urlLoad: 'load_now.php',
// ContentType: 'application/json',
// For custom parameters/headers on requests
//params: { _some_token: '....' },
contentTypeJson: true,
storeComponents: true,
storeStyles: true,
storeHtml: true,
storeCss: true,
headers: {
'Content-Type': 'application/json'
},
json_encode:{
"gjs-html": [],
"gjs-css": [],
}
//headers: { Authorization: 'Basic ...' },
}
});
window.editor= editor;
var blockManager = editor.BlockManager;
// 'my-first-block' is the ID of the block
blockManager.add('my-first-block', {
label: 'Simple block',
content: '<div class="my-block">This is a simple block</div>',
});
</script>
So I get in the blocks panel a block namely Simple block which I can drag and drop on the editor. When ever any change is made then the autosave is trigerred with an ajax call to save.php file. Inside save.php, I have:
$content_found="";
$content_found= file_get_contents('php://input');
mysqli_real_escape_string($conn, $content_found);
echo " content found = ".$content_found;
$sql = "INSERT INTO `grapes_content` (`content_found`)
VALUES ('".$content_found."')";
But in Chrome developer tool network tab, I can see :

It is not clear what payload variables I should save in database and how . I used $content_found= file_get_contents('php://input'); to get the full content instead.
After saving it into DB, on page refresh, I load the page with load_now.php. Inside load_now.php, I have 👍
$content_found="";
$sql = "SELECT * FROM `grapes_content`";
$result=$conn->query($sql);
$content_found="";
while($row=mysqli_fetch_assoc($result)){
$content_found=$row['content_found'];
}
echo $content_found;
But the editor shows no saved data.
I am pretty sure that the way I save and retrieve data is not correct. So points are:
Q1) What things should I save in database ? And how can I get the variables or data from ajax payload or in any other way ?
Q2) How can I show the saved data into the editor after page reload ?
In the editor, I see a preview option with an eye image that can show me the HTML page without any editor.
Q3) After saving data into database, how can I show the data simply just as a HTML page and not inside any editor ?
Answers (3)
You're supposed to setup a RESTful API, for example:
sql
CREATE DATABASE gjs;
CREATE TABLE IF NOT EXISTS `pages` (
`id` int(20) NOT NULL AUTO_INCREMENT,
`assets` TEXT NOT NULL DEFAULT '[]',
`components` TEXT NOT NULL DEFAULT '[]',
`css` TEXT NOT NULL DEFAULT ' ',
`html` TEXT NOT NULL DEFAULT ' ',
`styles` TEXT NOT NULL DEFAULT '[]',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
db.php
// Enter your Host, username, password, database below.
$con = mysqli_connect("localhost","root","","gjs");
if (mysqli_connect_errno()){
echo "Failed to connect to MySQL: " . mysqli_connect_error();
die();
}
store.php
<?php
header("Content-Type:application/json");
include('db.php');
$data = json_decode(file_get_contents("php://input"));
$assets = $data['gjs-assets'];
$components = $data['gjs-components'];
$css = $data['gjs-css'];
$html = $data['gjs-html'];
$styles = $data['gjs-style'];
if (isset($_POST['id']) && $_POST['id']!="") {
$result = mysqli_query(
$con,
"UPDATE `pages`
SET assets=$assets, components=$components, css=$css, html=$html, styles=$styles
WHERE id=$id");
mysqli_close($con)
}else{
$result = mysqli_query(
$con,
"INSERT INTO `pages` (assets, components, css, html, styles)
VALUES ($assets, $components, $css, $html, $styles");
mysqli_close($con);
}
response($id, $assets, $components, $css, $html, $styles);
function response($id, $assets, $components, $css, $html, $styles){
$response['id'] = $id;
$response['gjs-assets'] = $assets;
$response['gjs-components'] = $components;
$response['gjs-css'] = $css;
$response['gjs-html'] = $html;
$response['gjs-styles'] = $styles;
$json_response = json_encode($response);
echo $json_response;
}
?>
load.php
<?php
header("Content-Type:application/json");
if (isset($_GET['id']) && $_GET['id']!=""
include('db.php');
$id = $_GET['id'];
$result = mysqli_query(
$con,
"SELECT * FROM `pages` WHERE id=$id");
if(mysqli_num_rows($result)>0){
$row = mysqli_fetch_array($result);
$assets = $row['assets'];
$components = $row['components'];
$css = $row['css'];
$html = $row['html'];
$styles = $row['styles'];
response($id, $assets, $components, $css, $html, $styles);
mysqli_close($con);
}else{
response(NULL, NULL, 200,"No Record Found");
}
}else{
response(NULL, NULL, 400,"Invalid Request");
}
function response($id, $assets, $components, $css, $html, $styles){
$response['id'] = $id;
$response['gjs-assets'] = $assets;
$response['gjs-components'] = $components;
$response['gjs-css'] = $css;
$response['gjs-html'] = $html;
$response['gjs-styles'] = $styles;
$json_response = json_encode($response);
echo $json_response;
}
?>
.htaccess
Add this to your
.htaccessfile
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^store store.php [NC,L]
RewriteRule ^store/([0-9a-zA-Z_-]*)$ store.php?id=$1 [NC,L]
RewriteRule ^load/([0-9a-zA-Z_-]*)$ load.php?id=$1 [NC,L]
Given you add the files to a folder called api you'll have the following endpoints:
http://localhost/api/load/{id}
load a project with given idhttp://localhost/api/store/{id}update project with given idhttp://localhost/api/storecreate a project
@Ju99ernaut , Q1) are all my frontend code snippets right ? Q2) How can I get the $_POST variable ? In the browser network inspection tab, I only see request payload. $_POST is empty there. Q3) For loading purpose, will the saved data be automatically attached to the editor ?
I guess the $_POST variable only works for url parameters, I've updated the code to use the $data variable, your front end snippets are fine however on load the data will not be automatically attached to the editor since the load method only sends a GET request, you will have to tell the editor what to do once the data is loaded.
For example:
//append to frontent code
editor.on('load', () => {
const rs = editor.StorageManager.get('remote-storage');
rs.load(res => {
editor.setComponents(JSON.parse(res['gjs-components'].replace(/^"|"$/g, "")));
editor.setStyle(JSON.parse(res['gjs-styles'].replace(/^"|"$/g, "")));
}, err => {
console.log("An error occured", err);
});
});
Also update these in storage manager
autoload: false,
urlStore: 'http://localhost/api/store', //OR 'http://localhost/api/store/{id}' {id} should be the id of page you want to update
urlLoad: 'http://localhost/api/store/{id}', //{id} should be the id of page you want to load
You may also have to setup a way to keep track of which page you are editing
You can also check out this tutorial on RESTful APIs using php.
Related Questions and Answers
Continue research with similar issue discussions.
Issue #890
[Question]: I cannot get the simple example working
I am not new to Javascript but when I try the example: I get a blank page. That is with adding the CSS and Javascript library. Any suggesti...
Issue #1686
CMS: Grapesjs is not defined
I am trying to use basic Grapesjs editor to CMS. Here's my code: I have installed the grapesjs using NPM. Later I tried running this html f...
Issue #597
storageManager: Loading from remote storage
Hi, I'm trying to read the HTML and CSS from my database. When I try to load it into the editor, nothing displays. I can store the data jus...
Issue #2120
CSS properties of body (#wrapper) not editable after editor.setComponents(html);
When I save my page in a database refresh, the html and css are set like so $.ajax({ url: "../feeder.php", type: 'POST', processData: false...
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.