2.1.8 • Published 3 years ago

@writeaway/spiral-bridge v2.1.8

Weekly downloads
2
License
MIT
Repository
github
Last release
3 years ago

Usage in Spiral Projects

1. Include scripts

Include writeaway-spiral.js in your project. I.e. @writeaway/spiral-bridge/dist/writeaway-spiral.js Include default styles from @writeaway/spiral-bridge/dist/css/writeaway-spiral.css

Typical Spiral Framework PHP initialization sample.

    <script src="@writeaway/spiral-bridge/dist/writeaway-spiral.js" type="text/javascript">
    <script type="text/javascript">
        /**
         * WriteAwayBridge variable is put in global scope in application entry point by front end engineer
         */
        WriteAwayBridge.start({
            imageGalleryUrl: "<?= uri('api_images_list') ?>", // Url to fetch images list
            getPieceBulkUrl: "<?= uri('api_pieces_list', ['action' => 'get']) ?>", // Url to fetch piece data by multiple ids
            getPieceUrl: "<?= uri('api_pieces', ['action' => 'get']) ?>", // Url to fetch piece data. This is fired only for pieces that can't be read directly from DOM
            saveMetaUrl: "<?= uri('api_seo', ['action' => 'save']) ?>", // Url to save SEO data from SEO editor
            savePieceUrl: "<?= uri('api_pieces', ['action' => 'save']) ?>", // Url to save piece. This may be overrided by piece container 'data-save-url' attribute
            uploadUrl: "<?= uri('api_images_upload') ?>", // Url to upload image resources
            deleteImageUrl: "<?= uri('api_images_delete') ?>" // Url to delete image
        },
         "<meta></meta>", // Specify HTML for custom meta page headers here for SEO Editor,
         {
            html: { // Options per editor type, if any
                pickerColors: ["red", "blue"]
            }   
         },
         { // Meta data to attach to pieces when editing them
            id: "user-id",
            label: "John Smith",    
         }          
     );
    </script>

2. Markup

To add piece to editor, mark it up like so

    <element data-piece="Piece Type" data-id="unique id" data-name="Human Readable Name">...</element> 

3. Add additional attributes

Add data-get-url to override get piece URL for specific piece Add data-save-url to override save piece URL for specific piece

4. Add global variable SEO_META for SEO attributes on page.

These variables will be merged to get and save requests for SEO. Put there anything server needs to identify current view.

    <script>
        var SEO_META = {
                            "pageId": "Spiral page id to save meta to"
                       }    
    </script>

5. Ensure server implements following API

Note all urls can be overridden by config and per piece with custom attributes

POST api/pieces/get - getting single piece item

Request

FieldTypeDescription
idstringUnique piece id, extracted from data-id attribute
typestringEditor type, extracted from data-type attribute
dataanyOptionally has current data of a piece
datasetanyHas all data attributes of a node

Response

Response should have data field of following structures:

FieldTypeDescription
idstringPiece id
typestringPiece type
dataanyOptional. Piece data, type is specific for piece type. If not returned piece may not start.
metaIMetaOptional. Piece meta data to control who and when modified piece last. Required for concurrent edit mode, optional otherwise.
messagestringOptional. message to show for piece visible in expert mode
messageTypestringOptional. Message error level: 'error' or 'warning'

data and dataset are passed, but will be deprecated and should be ignored on server

When type=seo id can be missing, but all data from SEO_META variable will present

Request sample

  {
     "id": "unique-id",
     "type": "html"   
  }

Response sample

  {
     "status": 200,
     "data": {
       "id": "unique-id",
       "type": "html",
       "data": {
          "html": "<div>Content</div>"
       },   
       "meta": {
          "id": "user id",
          "label": "Anna",
          "time": 12345
       }      
    }
  }

POST api/pieces/save - saving single piece

FieldTypeDescription
idstringUnique piece id, extracted from data-id attribute
typestringEditor type, extracted from data-type attribute
dataanyOptionally has current data of a piece
metaIMetaOptional. Piece meta data to control who and when modified piece last. Required for concurrent edit mode, optional otherwise.
datasetanyHas all data attributes of a node

data and dataset are passed, but will be deprecated and should be ignored on server

When type=seo id can be missing, but all data from SEO_META variable will present

Request sample

  {
     "id": "unique-id",
     "type": "html",
     "data": {
          "html": "<div>Content</div>"
     },   
     "meta": {
        "id": "user id",
        "label": "Anna",
        "time": 12345
     }      
  }

Response sample

  {
      "status": 200,
      "data": {
         "id": "unique-id",
         "type": "html",
         "data": {
              "html": "<div>Modified Content</div>"
          },   
          "meta": {
             "id": "user id",
             "label": "Anna",
             "time": 12345
          } 
     
      }
  }

POST api/pieces/saveMeta - saving SEO meta

FieldTypeDescription
idstringUnique piece id, extracted from data-id attribute
typestringEditor type, extracted from data-type attribute
dataanyOptionally has current data of a piece
metaIMetaOptional. Piece meta data to control who and when modified piece last. Required for concurrent edit mode, optional otherwise.
datasetanyHas all data attributes of a node

data and dataset are passed, but will be deprecated and should be ignored on server

When type=seo id can be missing, but all data from SEO_META variable will present

Request sample

  {
     "id": "unique-id",
     "type": "html",
      "data": {
          "html": "<div>Content</div>"
      }     
  }

Response sample

  {
      "status": 200,
      "data": {
         "id": "unique-id",
         "type": "html",
         "data": {
              "html": "<div>Modified Content</div>"
          },   
          "meta": {
             "id": "user id",
             "label": "Anna",
             "time": 12345
          }       
      }
  }

POST api/pieces/bulk - getting batch of items

Request

FieldTypeDescription
piecesPieceGetRequest[]array of requests same as in single piece { id: 'id of piece', type: 'type of piece' }

Response

Response should have data field as array of following structures:

FieldTypeDescription
idstringPiece id
typestringPiece type
dataanyOptional. Piece data, type is specific for piece type. If not returned piece may not start.
metaIMetaOptional. Piece meta data to control who and when modified piece last. Required for concurrent edit mode, optional otherwise.
messagestringOptional. message to show for piece visible in expert mode
messageTypestringOptional. Message error level: 'error' or 'warning'

Request sample

  {
     "pieces": [ { "id": "unique-id", "type":  "html" }, { "id": "unique-id-2", "type": "image" }]
  }

Response sample

  {
    "status": 200,
    "data": [
      {
        "id": "unique-id",
        "type": "html",
        "data": {
          "html": "<div>Content</div>"
        }
      },
      {
        "id": "unique-id",
        "type": "html",
        "data": {
          "html": "<div>Content</div>"
        }
      },
      {
        "id": "unique-id",
        "type": "html",
        "message": "Piece does not exist",
        "messageType": "error"
      }
    ]
  }  

POST api/pieces/images - getting images for piece

Request

FieldTypeDescription
idstringOptional. Piece id. If specified, return image uploads only of that piece.
typestringOptional. Piece type. If specified, return image uploads only of that type.

Response

Response should have data field as array of following structures:

FieldTypeDescription
idstringImage id
srcstringImage source URL
thumbnailSrcstringOptional. Image thumbnail URL
titlestringOptional. Image tag default title
altstringOptional. Image tag default alt text
heightnumberOptional. Image height to display
widthnumberOptional. Image width to display

Request sample

  {
     "id": "unique-id",
     "type": "image"
  }

or without payload to fetch all

  {
  }

Response sample

  {
    "status": 200,
    "data": [
      {
        "id": "unique-id",
        "src": "image1.png"
      },
      {
        "id": "unique-id",
        "thumbnailSrc": "image2-th.png",
        "src": "image2.png"
      }
    ]
  }  

POST api/pieces/upload - upload image

Request

FieldTypeDescription
imageFileFormData file item if thats a single file
images[]FileListFormData file list if thats multiple file upload

Response

Response should have data field as array of following structures:

FieldTypeDescription
idstringImage id
srcstringImage source URL
thumbnailSrcstringOptional. Image thumbnail URL
titlestringOptional. Image tag default title
altstringOptional. Image tag default alt text
heightnumberOptional. Image height to display
widthnumberOptional. Image width to display

Response sample

  {
    "status": 200,
    "data": [
      {
        "id": "unique-id",
        "src": "image1.png"
      },
      {
        "id": "unique-id",
        "thumbnailSrc": "image2-th.png",
        "src": "image2.png"
      }
    ]
  }  

POST api/pieces/images/delete - delete image from gallery

Request

FieldTypeDescription
idstringPiece id

Request sample

  {
     "id": "unique-id",
  }

Concurrent Edits

To enable concurrent edits in Spiral WriteAway project

  1. Include Spiral Websockets Client to project

  2. Implement writeaway channel on server that should produce message events with IPiece payloads having real-time updates from other users

    {
         "id": "unique-id",
         "type": "html",
         "data": {
              "html": "<div>Modified Content</div>"
          },   
          "meta": {
             "id": "user id",
             "label": "Anna",
             "time": 12345
          }       
      }
  1. Add writeaway adapter script
    <script src="https://cdn.jsdelivr.net/gh/spiral/websockets/build/socket.js"></script>
    <script type="text/javascript">
        var Socket = SFSocket.SFSocket;
        var connection = new Socket({ host: 'localhost'});
    </script>

    <script src="@writeaway/spiral-bridge/dist/writeaway-spiral.js" type="text/javascript">
    
    <script type="text/javascript">
        /**
         * WriteAwayBridge variable is put in global scope in application entry point by front end engineer
         */
        WriteAwayBridge.start({
            imageGalleryUrl: "<?= uri('api_images_list') ?>", // Url to fetch images list
            getPieceUrl: "<?= uri('api_pieces', ['action' => 'get']) ?>", // Url to fetch piece data. This is fired only for pieces that can't be read directly from DOM
            getPieceBulkUrl: "<?= uri('api_pieces_list', ['action' => 'get']) ?>", // Url to fetch piece data by multiple ids
            saveMetaUrl: "<?= uri('api_seo', ['action' => 'save']) ?>", // Url to save SEO data from SEO editor
            savePieceUrl: "<?= uri('api_pieces', ['action' => 'save']) ?>", // Url to save piece. This may be overrided by piece container 'data-save-url' attribute
            uploadUrl: "<?= uri('api_images_upload') ?>", // Url to upload image resources
            deleteImageUrl: "<?= uri('api_images_delete') ?>" // Url to delete image
        },
         "<meta></meta>", // Specify HTML for custom meta page headers here for SEO Editor,
         {
            html: { // Options per editor type, if any
                pickerColors: ["red", "blue"]
            }   
         },
         { // Meta data to attach to pieces when editing them
            id: "user-id",
            label: "John Smith",    
         },
         WriteAwayBridge.useWS(connection)          
     );
    </script>

Advanced usage

Make a custom bundle yourself based on this package as a sample.