Skip to content
t-animal edited this page Nov 30, 2015 · 4 revisions

Basic example

    <cmeditor:tabs name="book" options="[defaultContent:'Lorem ipsum sit dolor']" ajax="[getURL:createLink(action: 'ajaxGet')+'?name=']">
      <label for="author"> <g:message code="myLibrary.author.label" default="Author" /></label>
      <g:textField name="author" class="cmeditor-field" /> <br />

      <label for="title"><g:message code="myLibrary.title.label" default="Title" /></label>
      <g:textField name="title" class="cmeditor-field" />
  </cmeditor:tabs>

The resulting CMEditor would be similar to this: Recorded demo

Available attributes

Configure the CMEditor using the attributes of the <cmeditor:tabs-tag. None of them is mandatory, all have sensible default values. These attributes can be set:

  • ajax: paths for the editor to communicate with your controller; all information has to be json encoded
    • listURL: GET, list of available filenames; default: 'ajaxList',
    • getURL: GET, object representing the mapped document: default: 'ajaxGet',
    • updateURL: POST, location to call to save a document; it's passed the document's id; default: 'ajaxUpdate',
    • deleteURL: POST, location to call to delete a document; it's passed the document's id; default: 'ajaxDelete',
  • availableModes: List of Strings, all the modes (CodeMirror lingo for filetypes) the editor should make available. For a list see https://codemirror.net/mode/
  • availableThemes: List of Strings, all the themes the editor should make available. For a list see https://codemirror.net/demo/theme.html
  • binding: the initial key-binding of the editor (e.g. vim)
  • mapping: a collection defining the mapping for your document model (respectively the generated json):
    • content: the file content's variable name; default: content
    • folder: the file's folder; default: folder
    • idField: String, the variable name of the mapped document to use as id; default: id
    • mode: the content's mode's variable name; default: mode
    • name: the filename's variable name; default: name
  • name: the name of the CMEditor instance, useful for calling the javascript API; default: random 125-character-string
  • options: a collection defining additional options:
    • binding: String, overrides the binding-attribute
    • defaultContent: String, the default content of a new file; default: '' (empty string)
    • defaultDiffBeforeSave: Boolean, whether to display a diff before saving; default: true
    • defaultMode: the default mode for new files, preferably as MIME-Type (e.g. text/x-groovy)
    • defaultReadOnly: Boolean, whether to open files read only; default: false
    • menu: Boolean, whether to display a menu bar or not; default: true
    • menuFile: Boolean, whether to display a file menu or not; default: false
    • menuView: Boolean, whether to display a view menu or not; default: true
    • overlayDefinitionsVar: String, a js-variable name in which you can define additional CodeMirror overlays
    • preloadModules: Boolean, whether the editor should load all themes and modes on document load; default: false
    • readOnly: Boolean, whether to make the whole editor readOnly; default: false
    • theme: String, overrides the theme-attribute
    • useSession: Boolean, whether to save editor state in the user's browser; default: true
  • theme: the initial theme to use

##Communication with the Server There are four methods resp. URLs which the CMEditor uses to talk to the server, which can be set via the ajax-attribute. All responses must be JSON. In case of any errors the server should respond by a JSON-object like this

{status: 'error', msg: "<An error message to display to the user>"}

For a reference implementation see our demo application.

Loading a file

This is a GET-Request. Default URL: /ajaxList. Parameters passed to the Server: ?id=<The id of the file to load>

Response if no errors occured:

{
 status: 'success',
 result: {
    id: <fileID (can be any datatype, integer recommended)>,
    name: '<fileName>',
    content: '<fileContent>',
    folder: <'folderName using forward-Slash' or null>,
    mode: '<the codemirror mode to set after loading>',
    //any other data which should be displayed in the editor using input fields matching ".cmeditor-field".
    //use the name-attribute as key and the desired value as value
  }
}

Please note that you can use different keys than id, name, folder, content and mode by setting the mapping-attribute.

Saving a file

This is a POST-Request. Default URL: /ajaxUpdate. Parameters passed to the Server are json encoded:

{
    id: <fileID (can be any datatype, integer recommended)>,
    name: '<fileName>',
    content: '<fileContent>',
    folder: '<folderName using forward-Slash or empty string>',
    mode: '<the current codemirror mode as MIME-Type>',
    //any other data which is displayed in the editor using input fields matching ".cmeditor-field".
    //use the name-attribute as key and the desired value as value
  }

Please note that you can use different keys than id, name, folder, content and mode by setting the mapping-attribute.

Response if no errors occured:

{
 status: 'success', 
 msg: 'a message to display to the user',
 newId: <The id of the document (can be omitted if unchanged)>
}

Deleting a file

This is a GET-Request. Parameters passed to the Server: ?id=<The id of the file to delete>

Response if no errors occured:

{
 status: 'success', 
 msg: 'a message to display to the user'
}

Listing all files

This is a GET-Request. There are no Parameters.

Response if no errors occured:

{
 status: 'success', 
 result: [//list of all files:
             { id: <fileID (can be any datatype, integer recommended)>,
               name: <fileName>,
               folder: <folderName using forward-Slash or empty string>}, ...
          ]
}

Please note that you can use different keys than id, name and folder by setting the mapping-attribute.

Related Projects

  • Grails CMEditor Demo: A very simple demo application
  • Cedit: A larger application using multiple CMEditors for dynamic scripts, templates and DSLs in a Grails application
Clone this wiki locally