Extend GrapesJs to build your Own Web Builder Framework

GrapesJS is a Free and Open Source Web Builder Framework that provides an extensive

set of HTML elements from which you can build HTML templates without any knowledge of coding.  You can see a demo, and you can add new building blocks according to your need. GrapesJS was designed to create dynamic templates faster and easier.

 

This post is about to give you an idea of what is Grapesjs and how you can extend it to build your own web-builder. You will get to know how to do initialization and how can you add different blocks and components, how you can use built-in component types and create your own custom types, and also how to style your components.

 

Initialization:

 

First, you have to install grapesjs and then initialize the editor.

 

<link rel="stylesheet" href="path/to/grapes.min.css">
<script src="path/to/grapes.min.js"></script>
<div id="gjs"></div>
<script type="text/javascript">
  var editor = grapesjs.init({
      container : '#gjs',
      plugins: ['grapesjs-preset-webpage', customBlocks, customTypes]
  });
</script>

Plugins contain all the building blocks which you can use to make Html templates, grapesjs-preset-webpage is a dependency that provides default building blocks of grapesjs.

 

Blocks:

Block is a group of components that you can easily drag and drop in the editor canvas and you are able to remove, copy and move that block inside the canvas. GrapesJS provides built-in blocks but you can also make your own custom blocks using BlockManager. e.g.

const myFirstBlock = editor = {
 var blockManager = editor.BlockManager;
 // 'my-first-block' is the ID of the block
 blockManager.add('my-first-block', {
  label: 'Button',
  content: {
    type: button, 
    tagName: 'button',
    draggable: false,
    attributes: { class: 'container'},
    style: { 'background-color': '#ffffff' },
    content: "Change Title",
  }
 });
}

In this way, you can make your own custom blocks and add different attributes in it. You can also set default styling and different attributes such as draggable: false. After creating blocks you have to add the block name to the plugins array at the time of initializing the editor. e.g.

var editor = grapesjs.init({
      container : '#gjs',
      plugins: ['grapesjs-preset-webpage', myFirstBlock ]
 });

Now our first block has been added to the editor at the end of collections as you can see in the screenshot below.

 

 

You can also update existing blocks e.g.

 

blockManager.get('my-first-block').set({
  label: 'Updated simple block',
  attributes: {
    title: 'Updated title'
  }
})
 

Component: 

 

Each element you dropped in the canvas is transformed into a GrapesJS component. You can also add different components in a block and you can nest components as much as you can, and then rearrange the element with the help of the editor. Grapesjs editor provides the ability to see the HTML and CSS code structure and you can also see the design on different screen sizes to check responsiveness.

{
  tagName: 'div',
  components: [
    {
      type: 'image',
      attributes: { src: 'https://path/image' },
    }, {
      tagName: 'span',
      style: {
       'background-color': '#ffffff',
       'font-family': 'Ubuntu, sans-serif',
      },
      type: 'text',
      attributes: { title: 'foo' },
      components: [{
        type: 'textnode',
        content: 'Hello world!!!'
      }]
    }
  ]
}

Component Type:

 

You can use built-in types for elements and also create custom types and can customize different traits for it. Traits are the element attributes such as title, placeholder, checkbox, and dropdown. You can bind different input traits on elements and react to change.

editor.DomComponents.addType('my-cusotm-type', {
  isComponent: el => el.tagName === 'INPUT',
  // Model definition
  model: {
    // Default properties
    defaults: {
      tagName: 'input',
      draggable: 'form, form *', // Can be dropped only inside `form` elements
      droppable: false, // Can't drop other elements inside
      attributes: { // Default attributes
        type: 'text',
        name: 'default-name',
        placeholder: 'Insert text here',
      },
      traits: [
        'name',
        'placeholder',
        { type: 'checkbox', name: 'required' },
      ],
    }
  }
});

isComponent method receives a parsed HTMLElementNode which makes the editor understand when to apply my-custom-type. The model property, which holds the description of your component, and you can access all the child elements through the model and modify it. You have to add custom types in the plugins array as we did for blocks during initialization. You can also update component types using the AddType method.

 

You can also add event listeners on props or attributes changes in init function and trigger functions on changes while adding custom types. e.g.

editor.DomComponents.addType('my-custom-type', {
  // ...
  model: {
    defaults: {
        // defined above
    },
    init() {
      // Listen to any attribute change
      this.on('change:attributes', this.handleAttrChange);
      // Listen to title attribute change
      this.on('change:attributes:title', this.handleTitleChange);
    },
    handleAttrChange() {
      console.log('Attributes updated: ', this.getAttributes());
    },
    handleTitleChange() {
      console.log('Attribute title updated: ', this.getAttributes().title);
    },
  }
});

After initializing, you can get a component instance, that instance will be responsible for the final data of your template which you can use and change accordingly. e.g.

const components = editor.getComponents()

Then you can find your required component based on its type, attributes, or identifiers. 

You can use different methods such as getAttributes, setAttributes, etc.

const componentHTML = component.toHTML();
const componentType = component.get('type'); // eg

Each component triggers a lifecycle hook method based on the actions such as it triggers updated hook method when model updated and triggers removed hook method when the model is removed.

 

StyleManager:

 

GrapesJS provides a StyleManager module, which helps you to style any component which is present in the canvas.

styleManager : {
    sectors: [{
      name: 'Dimension',
      buildProps: ['width', 'min-height']
    }]
}

You can add any CSS property in buildprops array, and then apply it to blocks using the editor.

Through the component model, you can change and get the style of every component.

const models = editor.getComponents().models

 

 model.addStyle({
    'height': '50px',
 });
 const style = model.getStyle();

 

StyleManager also allows you to set CSS for different states such as hover, active using editor and you can also change CSS for hover state dynamically with the CssComposer module.

const id = model.getId();
editor.CssComposer.setRule(`#${id}:hover`, { 'color': 'red'  });

Moreover, GrapesJS provides a lot more features that can make your life easier by minimizing the codebase.

 

Share this article

Leave a comment