mosaico icon indicating copy to clipboard operation
mosaico copied to clipboard

Store edited templates on backend and load back into editor

Open berntxspeed opened this issue 9 years ago • 3 comments

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
 });

berntxspeed avatar Jan 07 '17 02:01 berntxspeed

I made exactly what you're trying to do(loading back the template) without forking the project.

jbalatero avatar Jan 09 '17 09:01 jbalatero

Cool. How did you do that? Always better not to change the source code.

berntxspeed avatar Jan 09 '17 17:01 berntxspeed

Listen to @bago in the #73 : "@JbalTero you can use Mosaico.start method instead of Mosaico.init if you don't want to enable the "localstorage" built-in plugin login."

MrCsabaToth avatar Aug 07 '17 20:08 MrCsabaToth