最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - GrapesJs and PHP - store and load data to show in editor and as HTML page as well - Stack Overflow

programmeradmin0浏览0评论

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: [
     '.jpg',
     // Pass an object with your properties
     {
       type: 'image',
       src: '.jpg',
       height: 350,
       width: 250
     },
     {
       // As the 'image' is the base type of assets, omitting it will
       // be set as `image` by default
       src: '.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 ?

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 ?

Share Improve this question asked May 8, 2020 at 13:07 Istiaque AhmedIstiaque Ahmed 6,49826 gold badges81 silver badges144 bronze badges 5
  • @Dharman, what is the solution regarding grapesJS ? – Istiaque Ahmed Commented May 8, 2020 at 13:48
  • As far as I know, you should store all payloads(gjs-assets, gjs-ponents, gjs-css, gjs-html, gjs-styles) to database. And when you view saved page, you should load all data from database again and init grapejs. – glinda93 Commented May 8, 2020 at 15:32
  • @bravemaster, is the way I saved full payload together in DB correct ? While viewing saved page, all data is retrieved from DB as you se in my code. But how to init grapeJS with saved data again ? – Istiaque Ahmed Commented May 8, 2020 at 16:02
  • @IstiaqueAhmed The document says that developers should override storage. But in my case, that didn't work very well. The default implementation is localStorage, so as a workaround I set localStorage when the page is loaded. – glinda93 Commented May 8, 2020 at 17:06
  • @bravemaster, but how to do that with remote storage as I said in OP ? – Istiaque Ahmed Commented May 8, 2020 at 17:13
Add a ment  | 

3 Answers 3

Reset to default 2

for Q3 you can use a "frontend option" like this:

NOTE 1: i'm using angularJS

NOTE 2: $scope.editor is my grapesJs instance

Function to get HTML+CSS inline

$scope.getHtmlCss = function(){
    var html = $scope.editor.runCommand('gjs-get-inlined-html');
    $log.log("-----> HTML & INLINED CSS: ", html);
    return html;
}

In your GrapesJs editor add an new option for "Donwload HTML file"

          $scope.editor.Panels.addButton('options', [ 
            { id: 'save', 
              className: 'fa fa-file-code-o', 
              mand: function(editor1, sender) { 

                if($scope.getHtmlCss()){
                  $scope.generateFile($scope.getHtmlCss());                      
                }

              }, 
              attributes: { title: 'Download HMTL file' } 
            }, ]);

function to generate HTML file:

$scope.generateFile = function(code){

      $(function() 
        {
          console.log( "ready!" );
          // Check for the various File API support.
          if (window.File && window.FileReader && window.FileList && window.Blob) 
          {
            saveText(code, 'text/html;charset=utf-8', 'mailing.html');
          } 
          else 
          {
            alert('The File APIs are not fully supported in this browser.');
          }
        }
       );

      function saveText(text, mime, file)
      {
        var blob = new Blob([text], {type: mime});
        saveAs(blob, file);

        return false;
      }

      function handleFileSelect(code, mimeType) 
      {

        var reader = new FileReader();
        // Closure to capture the file information.
        reader.onload = (
          function(theFile) 
          {
            return function(e) 
            {
              target.html( e.target.result );
            };
          }
        )(file);

        // Read in the image file as a data URL.
        reader.readAsText(file);
      }



}

For your Q3, one solution could be to use generate an HTML file with PHP with fopen and fwrite function. And put the content of the database inside the file. To show the data you can then just show the plain HTML page and after your work is done you can delete the file from the server. This means you will generate the file on the fly and delete it after the use-case.

I found the solution : I used the following table :

CREATE TABLE IF NOT EXISTS `pages` (
   `id` int(20) NOT NULL AUTO_INCREMENT,
   `assets` TEXT  NULL ,
   `ponents` TEXT NULL,
   `css` TEXT NULL ,
   `html` TEXT  NULL ,
   `styles` TEXT NULL ,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;

In Javascrpt , the storageManager part was changed in the following way :

storageManager: {
    type: 'remote',
    stepsBeforeSave: 1,
    autosave: true,         // Store data automatically
    autoload: true,
    urlStore: 'save_now.php',
    urlLoad: 'load_now.php',
    params: { page_id: 11111 },
    contentTypeJson: true,
      storeComponents: true,
    storeStyles: true,
    storeHtml: true,
    storeCss: true,
     headers: {
    'Content-Type': 'application/json'
    }

In save_now.php, I have:

header("Content-Type:application/json");
include('db.php');
$data = json_decode(file_get_contents("php://input"),true);

$assets = $data['gjs-assets'];
$assets=json_encode($assets);
$ponents = $data['gjs-ponents'];
$ponents=json_encode($ponents);
$css = $data['gjs-css'];
$css = json_encode($css);
$html = $data['gjs-html'];
$html= json_encode($html);
$styles = $data['gjs-styles'];
$styles = json_encode($styles);

//$page_id = $data['page_id']; **I did not use it in my code here.. but you might need it. See the last part of this answer.**

 $result = mysqli_query(
 $con,
 "INSERT INTO `pages` (assets, ponents, css, html, styles)
  VALUES ($assets, $ponents, $css, $html, $styles)") or die(mysqli_error($con));

echo "success";

In load_now.php, I have:

header("Content-Type:application/json");

  $result = mysqli_query(
  $con,
  "SELECT * FROM `pages` ");
  if(mysqli_num_rows($result)>0){
    $row = mysqli_fetch_array($result);
    $assets = $row['assets'];
    $ponents = $row['ponents'];
    $css = $row['css'];
    $html = $row['html'];
    $styles = $row['styles'];
    $id=$row['id']; 
    response($id, $assets, $ponents, $css, $html, $styles);
    mysqli_close($con);
  }else{
    response(NULL, NULL,NULL,NULL, 200,"No Record Found");
  }
function response($id, $assets, $ponents, $css, $html, $styles){
 $response['id'] = $id;
 $response['gjs-assets'] = $assets;
 $response['gjs-ponents'] = $ponents;
 $response['gjs-css'] = $css;
 $response['gjs-html'] = $html;
 $response['gjs-styles'] = $styles;

 $json_response = json_encode($response);
 echo $json_response;
}

Notice that in storageManager, I used params: { page_id: 11111 },. You can use this page_id in a column value to identify the certain row for your page as you can have multiple pages as well. I wrote the very basic functionalities i.e: I only showed the insert part without using the update query in case the expected row for the certain page already exists in DB. As to the loading part, you should use the page_id to fetch the certain row. This part I also did not show leaving it to your normal logical sense.

N.B.: I came to the solution from q GitHub question here .

EDIT: As to Q3) , the solution is:

Check out grapesjs-plugin-export for a client side solution. Since the html and css are saved into database, you can also do the same thing the plugin does using a server side script. You can use something like file_put_contents.

发布评论

评论列表(0)

  1. 暂无评论