Setka Editor API Setka Post Editor initialization (JavaScript)

Setka Post Editor initialization (JavaScript)

Contents:

Terms and Definitions

Editor integration steps

1. Initializing the editor

2. Adding the company styles and scripts to the post view page

3. Saving the HTML code to the database and loading it back to the editor

How to get the content from the editor for saving it to the database

How to open the previously saved post in the editor

4. Working with images

Loading images

Deleting images

Editing images

Launching the editor with a set of images

Integration with image storages

Additional initialization parameters

How to set an indent for the Setka Editor header

How to track changes in the editor

Launching the editor inside a scrollable container

How to add your own styles and scripts into the editor preview

Working with the editor functions if requests to external CDNs are not possible

 

Terms and Definitions

Content Design System Manager (CDSM): web interface for creating and editing a branded style of a publication (module grid, text and color styles, icons, etc.). You can find it in your Setka Account.

Post: HTML code of the post wrapped in <div class=“stk-post”>...</div>.

Style: a set of CSS rules for text styles, fonts, colors, dividers, etc. which determines a branded style of a publication. Style is edited in CDSM.

Post layout grid: a set of CSS rules for building grid modules with columns and indents, and for adaptation to mobile devices. The post layout grid is edited in CDSM.

All styles and layout grids within one company are uploaded from CDSM to CDN in the form of a CSS file with styles and a JSON file with meta information to be used in the editor.

The editor requires 5 files to operate properly. These files need to be loaded in the post editing and/or view pages. 

File

Description

Post editing page

Post view page

editor.min.js

Main editor file

yes

 no

editor.min.css

Editor UI styles

yes

 no

company_name.min.css

Styles defined in the CDSM (fonts, colors, grids, etc.)

yes

yes

company_name.json

JSON with metadata required for work of the editor

yes

 no

public.js

JS code required for work of interactive capabilities of the editor (galleries, animation)

no 

yes

 

Editor integration steps

4 initial steps of the integration should be passed to fully use Setka Editor:

1. Load all of the required files to a post editing page and add the editor initialization code.

2. Load all of the required files to a post view page.  

3. Configure saving the post HTML code into a database and load it back into the editor. 

4. Use the editor API to upload and delete images from your server.

 

1. Initializing the editor

Here is the editor initialization sample code:


    // 1. Set paths to editor files:
    // (on the Setka Editor CDN or on your own server):
      
    // Main editor file
    const EDITOR_JS_URL =
    'https://ceditor.setka.io/path/to/editor.v.1.2.3.min.js';
    
    // Editor interface styles
    const EDITOR_CSS_URL =
    'https://ceditor.setka.io/path/to/editor.v.1.2.3.min.css';
    
    // Company styles
    const COMPANY_CSS_URL =
    'https://ceditor.setka.io/path/to/company_name.v.1.2.3.min.css';
    
    // Company metadata
    const COMPANY_JSON_URL =
    'https://ceditor.setka.io/path/to/company_name.v.1.2.3.json';
    
    // 2. Set the container on the page,
    // where the editor is being initialized:
    const CONTAINER = '.setka-editor-container';
    
    // 3. Set the company's public token (public_token)
    // for queries to editor.setka.io API
    // (it is located on the “CMS Integration” tab of the CDSM)
    const PUBLIC_TOKEN = 'my_public_token_123456';
    
    // 4. Load editor files to the page:
    const editorCSS = document.createElement('link');
    editorCSS.rel = 'stylesheet';
    editorCSS.href = EDITOR_CSS_URL;
    document.head.appendChild(editorCSS);
    
    const companyCSS = document.createElement('link');
    companyCSS.rel = 'stylesheet';
    companyCSS.href = COMPANY_CSS_URL;
    document.head.appendChild(companyCSS);
    
    const editorJS = document.createElement('script');
    editorJS.async = true;
    editorJS.src = EDITOR_JS_URL;
    editorJS.onload = initSetkaEditor;
    document.head.appendChild(editorJS);
    
    async function initSetkaEditor() {
      // 5. Load the JSON metadata of the company:
      const res = await fetch(COMPANY_JSON_URL);
      const json = await res.json();
    
      // 6. Set the editor initialization parameters:
      const config = {
        ...json.config,
        container: CONTAINER,
        public_token: PUBLIC_TOKEN,
      };
    
      const { assets } = json;
    
      // 7. Launch the editor
      SetkaEditor.start(config, assets);
    }

Important note: only one instance of Setka Editor can be launched on a page at the moment.

To stop and remove the working editor instance from the page, please use this method:

SetkaEditor.stop()

 

2. Add the company styles and scripts to the post view page

To view posts correctly, load these files to external pages of the site:

company_name.v.1.2.3.min.css — CSS styles of the post.

public.v.1.2.3.js — JS code for launching interactive elements (galleries, animations, footnotes. etc.)

Important note: do not link the public.js file to the post editing page.

 

3. Saving the HTML code to the database and loading it back to the editor

How to get the content from the editor for saving it to the database

There is a specific method to get the post HTML code from the editor:

SetkaEditor.getHTML();

Important note: do not get the content from the editor by queries to DOM elements on a page — they contain some extra elements and attributes, required only for working in the editor. They should not get into the saved post's HTML code. Always use the SetkaEditor.getHTML() method.

How to open the previously saved post in the editor

To open the existing post in the editor, please call the SetkaEditor.replaceHTML() method after the editor initialization:


    async function initSetkaEditor() {
      // ...
    
      // Load the post content from the database
      const postContent = await loadPostContentFromDB();
    
      // ...
    
      // Launch the editor
      SetkaEditor.start(config, assets);
    
      // Put the post content into the editor
      SetkaEditor.replaceHTML(postContent);
    }
  

Important note: do not put the post's HTML code on its' editing page. If <script> and <iframe> tags are present in the code, they will be executed by the browser. Also, animation styles may apply to elements inside the editor.

Important note: Setka Editor works with its' own HTML code structure. The post should be wrapped into the <div class=”stk-post”>...</div> container and contain elements with specific classes and attributes. Unfamiliar elements may come uneditable or cause the editor launch error. There is no sense in trying to open posts created in other editors, in Setka Editor.

 

4. Working with images

Setka Editor interface supports the following operations with images: loading, deleting and editing the alt attribute.

To make Setka Editor able to work with images from your server, please do the following:

1. Build the image operations API on your server or use one of the existing APIs. The implementation fully depends on your preferences.

2. Write JavaScript functions for API interactions (there are some examples below).

3. Specify these functions on editor initialization:


    async function initSetkaEditor() {
      // ...
      config.onFileUpload = uploadFile;
      config.onFileRemove = removeFile;
      config.onFileUpdate = updateFile;
      // ...
      SetkaEditor.start(config, assets);
    }
  

The editor supports the srcset attribute for images, thus you can generate images of various sizes and handle them in the sizes key on editor start and on loading new images. As a result, images that are fit to a user's browser width will be loaded automatically.

 

Loading images


    // Set the file loading callback function
    // It receives the file object as an argument
    // and should return a promise:
    function uploadFile(file) {
      return new Promise(async (resolve, reject) => {
        try {
          // Upload the file on the server/cloud/etc.
          // any convenient way: fetch, axis, ...
          const res = await uploadFileToServer(file);
          if (res.status !== 200) {
            reject({ message: res.statusText });
          }
    
          const json = await res.json();
    
          // Resolve the promise with an object of required properties:
          resolve({
            // id of an image from the server
            id: 'abc-def-123-456',
  
            // image file name
            name: 'image.jpg'
  
            // full path to an image
            url: 'https://example.com/image.jpg',
  
            // full path to a downsized image (optional)
            thumbUrl: 'https://example.com/image_thumb.jpg',
  
            // alt-text of an image (optional)
            alt: 'alternative text',
            
            // image width (optional)
            width: 100,
            // image height (optional)
            height: 100,
            
            // various image sizes for the "srcset" attribute (optional)
            sizes: [
              { width: 100, height: 100, url: 'image-small.jpg' },
              { width: 400, height: 400, url: 'image-medium.jpg' },
              { width: 1000, height: 1000, url: 'image-large.jpg' },
            ]
          });
        }
        catch (ex) {
          reject({ message: ex });
        }
      }
    }
  

 

Deleting images


    // Set the file deletion callback function
    // It receives the file id as an argument
    // and should return a promise
    function removeFile(id) {
      return new Promise(async (resolve, reject) => {
        try {
          // Delete the file from the server
          const res = await removeFileFromServer(id);
    
          // Resolve the promise, if the file was deleted successfully
          if (res.status === 200) {
            resolve();
          }
    
          // Reject the promise if something went wrong
          else {
            reject({ message: res.statusText });
          }
        }
        catch (ex) {
          reject({ message: ex });
        }
      }
    }

 

Editing images


    // Set the file editing callback function
    // It receives the file id as an argument
    // and a props object with updated file preferences,
    // it should return a promise
    function updateFile(id, props) {
      return new Promise(async (resolve, reject) => {
        try {
          // Update the file on the server
          const res = await updateFileOnServer(id, props);
    
          // Resolve the promise on successful update
          if (res.status === 200) {
            resolve();
          }
    
          // Reject the promise if something went wrong
          else {
            reject({ message: res.statusText });
          }
        }
        catch (ex) {
          reject({ message: ex });
        }
      }
    }

 

Launching the editor with a set of images

To start the editor with the specific set of images in the right sidebar (e.g. uploaded with an earlier saved post), this set should be added into the assets object on start.


    async function initSetkaEditor() {
      // ...
      
      // Get images from the database
  // and form the array in the compatible format: const postImages = [ { // id of an image saved on the server id: 'abc-def-123-456', // image file name name: 'image.jpg' // full path to an image url: 'https://example.com/image.jpg', // full path to a downsized image (optional) thumbUrl: 'https://example.com/image_thumb.jpg', // alt-text of an image (optional) alt: 'alternative text', // various image sizes for the "srcset" attribute (optional) sizes: [ { width: 100, height: 100, url: 'image-small.jpg' }, { width: 400, height: 400, url: 'image-medium.jpg' }, { width: 1000, height: 1000, url: 'image-large.jpg' }, ] } ]; // Add images to editor resources assets.images = postImages; // Launch the editor SetkaEditor.start(config, assets); }

 

Integration with image storages

In Setka Editor you can not only download images manually from your PC or via Unsplash library, but can also set an integration with an image storage from your CMS. Such an integration allows you to use images, already downloaded to your storage, in new Setka Editor posts. Once you accomplish this integration, a new option called 'Media Library' (you can set any custom name for it) will be added to the right panel. 

3e9ZPAAaFF4.jpg

Once you click on it, you will see a pop-up window with the pictures from your storage and a search field. You can choose a set of pictures that appears in the pop-up, e.g. choose the most frequently used images or a set of images for any search query (should be set on the side of your CMS), or even not to show any images at all by default. 

Once an image has been chosen, it is being uploaded to the editor's right panel and you can work with it just like you do with any other image in Setka Editor, downloaded in any default ways. 

Here is an example of how this feature works with our WordPress storage:Media_Library.gif

 

Integration description

To run the integration with your media library, you need to send an object `customMediaLibrary` to the editor's configuration. This object should have 4 keys:

  1. isSearchable: true | false
    responsible for a search field in the interface;
  2. title: { en: String, ru: String }
    responsible for the intergration's name in the interface;
  3. onLoadImages: async function() {}
    this function is called during images download to the editor;
  4. onFetchImages: async function() {}
    downloads images, inserted in a post.

An example of a full integration:

const getGiphy = id => loadXHR(`${GIPHY_BASE_URL}/${id}?api_key=${GIPHY_API_KEY}`);
customMediaLibrary: {
  isSearchable: true,
  title: { en: 'Giphy', ru: 'Гифи' },
  onLoadImages: async ({ imagesLoaded, searchValue }) => {
    const response = await searchGiphy(searchValue, 10, imagesLoaded);
    const images = response.data.map(item => ({
      id: item.id,
      filename: item.title || 'Untitled',
      url: item.images.original.url
    }));
    return images;
  },
  onFetchImages: async imagesIds => {
    const responses = await Promise.all(imagesIds.map(id => getGiphy(id)));
    const images = responses
      .filter(Boolean)
      .map(item => item.data)
      .map(item => ({ id: item.id, filename: item.title, url: item.images.original.url }));
    return images;
  }
}

Additional initialization parameters

Setting indents for the Setka Editor header

If you already have an element that sticks on top of the page (e.g., top navigation bar), you can set an indent for the Setka Editor header, to prevent overlay of one panel to another.

Indent size should be equal to the height of your top or bottom sticky panel respectively:


    // upper indent for the editor's top panel
    config.headerTopOffset = 55;

    // lower indent for the editor's bottom panel
    config.footerBottomOffset = 20;
  

 

Tracking changes in the editor

To subscribe on post content changes in the editor, use the onPostContentChange callback function:


    config.onPostContentChange = () => {
      console.log('Post content has changed');
    }
  

 

Launching the editor inside a scrollable container

If you are launching the editor inside the scrollable DOM container, you will need to pass its' CSS selector in the scrollingElement parameter for the correct sticking of the top and bottom bars to the boundaries of this container:

config.scrollingElement = '.scrolling-element';

Default value — window.document.

 

Adding your own styles and scripts into the editor preview

To add your own styles or scripts to the editor preview mode (opens on pressing the TAB button), use previewCSS and previewJS keys, containing arrays with paths to required files of styles and scripts respectively:

config.previewCSS = ['https://example.com/styles.css'];
config.previewJS = ['https://example.com/script.js'];

 

Working with the editor functions if requests to external CDNs are not possible

Even if you save style and editor files on your platform when working with the Content Design System Manager API, some internal functions of the editor ("Enhance Symbols", Unsplash and WordPress Media Library integrations, image editor) are always loaded from the Setka Editor CDN. If requesting files from external resources is prohibited on your platform, save those files on your server and connect them on the editor's initialization.

Please note that the files should be hosted without a redirect. Editor internal functionality files can be received by contacting our support team on support@setka.io or via chat.

 

To get these files on editor initialization, use the featureRootURL key. You will need to pass the path to the folder with the files on your server via this key:

config.featureRootURL = 'https://www.example.com/assets/';

The editor will be requesting such files afterwards:

https://www.example.com/assets/typograph/0.1.0/i_typograph.js
https://www.example.com/assets/unsplash/0.1.0/i_unsplash.js 

Custom integration: