Issue #2763Opened May 10, 2020by ghuser1233 reactions

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 : 1

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)

Ju99ernautMay 10, 20203 reactions

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 .htaccess file

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 id http://localhost/api/store/{id} update project with given id http://localhost/api/store create a project

ghuser123May 10, 20200 reactions

@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 ?

Ju99ernautMay 11, 20200 reactions

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.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.