Skip to content

Store edited templates on backend and load back into editor #264

Open
@berntxspeed

Description

@berntxspeed

I hope this helps anyone who's trying to do the same thing. I was quite unsure of my approach through this process, and I think this can greatly accelerate this process for future devs trying to do this.

referencing issue: #73

I wanted to store my edited emails on my backend db and load them back into the editor in order to pick up where i left off (and saved it to the backend).

Based on @jbaltero 's plugin code serving the 'save' functionality. see gist https://gist.github.com/berntxspeed/ef99309814644a60f415945f125e8842

But the tricky part was loading it back into the editor, and getting the code to call out to my backend rather than localstorage.

So I made a fork of the mosaico repo https://github.com/berntxspeed/mosaico
and edited app.js and /ext/localstorage.js to do so.

But since now we're talking about a asynchronous action i had to change the code flow control a bit.

Also, I didn't want to bake my app specific stuff into the Mosaico code, so I pulled out the code that actually sets up and makes the api call to my backend into my editor.html file.

changes to /ext/localstorage.js:

/* guided by this gist https://gist.github.com/mistaguy/25ae3b8ec8205ea0f3e8   */
var lsLoader = function(hash_key, emailProcessorBackend, templateLoader, callback) {

  templateLoader(hash_key, function(err, mdStr, td){
    if(err){ throw "Error accessing stored data for "+hash_key+" : errror-> "+err; }
    if (mdStr !== null && td !== null) {
      var model = td;
      var md = mdStr;
      var result = {
        metadata: md,
        model: model,
        extension: lsCommandPluginFactory(md, emailProcessorBackend)
      };
      callback(null, result);
    } else {
      callback("Cannot find stored data for "+hash_key);
    }
  });

};

changes to app.js:

var initFromLocalStorage = function(options, hash_key, customExtensions) {
  var lsData;
  localStorageLoader(hash_key, options.emailProcessorBackend, options.templateLoader, function(err, result){
    try {
      if(err){ throw('problem loading from local storage: '+err); }
      lsData = result;
      var extensions = typeof customExtensions !== 'undefined' ? customExtensions : [];
      extensions.push(lsData.extension);
      var template = _canonicalize(lsData.metadata.template);
      start(options, template, lsData.metadata, lsData.model, extensions);
    } catch (e) {
      console.error("TODO not found ", hash_key, e);
    }
  });
};

then to top it off in my editor.html file, i passed in some of my app-specific code to get the template details via API call: (adding this templateLoader option in my Mosaico.init call)

changes to editor.html

var ok = Mosaico.init({
           templateLoader: function(hash_key, callback){
                $.post('{{ url_for('emails.template') }}', {
                    action: 'load',
                    key: hash_key,
                    csrf: '{{ csrf_token() }}'
                }, null, 'html').done(function(){
                    resp = JSON.parse(arguments[0]);
                    var td = resp.content;
                    var mdStr = resp.meta_data;
                    console.log('md: ');
                    console.log(mdStr);
                    console.log('td: ');
                    console.log(td);
                    callback(null, mdStr, td);
                }).fail(function(jqXHR, textStatus, error){
                    console.log(jqXHR);
                    console.log(textStatus);
                    console.log(error);
                    callback(error);
                });
            }, //rest of your init options here
 });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions