Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to import saved html back to editor #18

Closed
punnawat opened this issue Oct 12, 2015 · 13 comments
Closed

How to import saved html back to editor #18

punnawat opened this issue Oct 12, 2015 · 13 comments
Labels

Comments

@punnawat
Copy link

I design an email template and saved it into html code to my database (as click download button). When I would like to edit it. How to load saved template to the editor again.

@bago
Copy link
Member

bago commented Oct 14, 2015

You have to save and load the "sources" too.

In the app initialization code you can see how it starts the editor from a given metadata+json model:
https://github.com/voidlabs/mosaico/blob/master/src/js/app.js#L62

You can see that methods also adds the localstorage plugin to the editor (the localstorage plugin is the one that will let you save in the localstorage). Have a look at localstorage save implementation:
https://github.com/voidlabs/mosaico/blob/master/src/js/ext/localstorage.js#L22
You can see it saves the metadata+json to the localstorage (the same loaded in the app.js).

So, you will have att your own plugin to deal with "saves" instead of the localstorage plugin and then you will have to invoke the application main "start" method passing metadata, json content, and your plugin instance.

So, you should be able to do all of this without altering mosaico code, but only "using it".

We probably should add some facilities to make this "basic usage" simpler, but we're collecting use-cases first. We need feedback.

@bago bago added the question label Nov 7, 2015
@bwl21
Copy link
Contributor

bwl21 commented Nov 7, 2015

I think saved HTML cannot be brought back to the editor by reading the saved HTML file unless the data from the editor is saved in the HTML -file. You could do this in a <script id="aclvalues" type="application/JSON"> ... </script> element within the exported HTML.

Alternatively: download a email.json - file in parallel to email.html, also implement a drop method which restores from email.json.

@benoitcollet
Copy link

Hi,
My question is complementary to this one: on Mosaico website, we cannot load templates. And there is no login: templates are saved "I don't know how": I cannot clean my cache and browser data, neither modify my template from another computer.
What are the options?
Thanks!

@bago
Copy link
Member

bago commented Mar 29, 2016

On mosaico.io website you currently don't have other options.
We plan to add some feature to mosaico.io in the next months, but at this time your only option is to extend the library on your own.

@ShahVivek
Copy link

ShahVivek commented Aug 2, 2016

@punnawat @bago @bwl21
Hi,
I want to save modified templates in database and again open it in edit mode. Actually I saved the html in database but not able to open it in edit mode.
Any suggestions or code will be helpful.
Thanks!

@bago
Copy link
Member

bago commented Aug 2, 2016

Mosaico is not able to load the saved html. THe output HTML is an "export format" and it loses critical informations when you export in this format, and you can't open a generic html in mosaico.

Mosaico documents are JSON metadata+content and you can save and load them using "viewModel" (viewModel.exportMetadata() viewModel.exportJSON() ) methods or "Mosaico.init" arguments.

@dotsproject
Copy link

dotsproject commented Sep 21, 2016

@bago ,

I used the mosaico editor to create the template and save it in database to edit it again later. so after creating the template, I downloaded it using the download link provided in mosaico editor, it provided the html format which i saved in database. now i want to load this content in mosaico editor to edit it but i didn't find a way to load the saved html source in mosaico editor.Can you please help me out .

I searched on internet and found that mosaico editor saves the created template in json format using two fields.
(1.) metadata
(2.) content

and for both of the fields, mosaico editor provides json format which can be saved in database as a saved template data and in case of edit the saved template , both (metadata and content) are loaded in mosaico editor which loads and shows the saved template in editor.

but I need to save the template data in html format which i have done it now just want to load that saved template(html source) in mosaico editor again soI searched through the internet but didn't find a way to load that html data in mosaico editor.

can you please help me out

@bago
Copy link
Member

bago commented Sep 21, 2016

The output HTML is not a "saving", it is just an output. You can't load it back in mosaico. No way (it seems I already wrote this 3 times just in this issue).

If you want to save and load you have to store the metadata+content JSON. So, just find a place where to store that JSON and then you will be able to load them back.

You can find other issues with suggestions about what to do with metadata/content.

Do you want to do this with "HTML only"? Well.. it is a lot harder, but you can store someway "hidden" in the output html (maybe an html comment) the 2 JSON and then write a tool to extract that data from the comment so you "virtually" load it back (you don't really load the HTML, but you load the data that generated that html).

@dotsproject
Copy link

dotsproject commented Sep 21, 2016

@bago @bwl21

Thanks for your feedback.

But In our application, After creating the template using the mosaico editor, I need to put that template from mosaico editor in another Editor(CK Editor) . that's why i created the template using the mosaico editor first and after downloading the template in html format , i transferred that html in CK editor to show the template there. now if i want to transfer that HTML source from CK editor to mosaico editor again, How it can be achieved.

Any suggestion Or code will be helpful to me.
Looking forward to hear from yours
Thanks

@dotsproject
Copy link

dotsproject commented Sep 30, 2016

@bago @punnawat @bwl21
I have integrated the mosaico editor in my application and it runs successfully at my end, i tested on around 10-15 system and found it running but at client end(UK) , it is not working since template is not loading there on page via ajax. i suggested him to disable the firewall/antivirus and then to check on different browser as well as on different system too and he followed the same but all is vain, even I also tested it on my UK server as well and found it working at my end but is not running there. it is showing following error in browser console while loading the editor at client end.

"xmlhttprequest cannot load ........"

"No access control allow origin header is present on the requested resource
Origin is there not allowed access"

Can you please help me out ?

Any kind of suggestion would be helpful for me.
Looking forward to hear from yourside

@umar-ashrfy
Copy link

Hi guys,

I did by using a simple method.
1 ) Save the Data.
1.1. First in localstorage.
1

1.2. Then save it in Database.
1

  1. Load the data back
raw_data    = <?php echo $magazine["Magazine"]["raw_data"]; ?>;
var id = JSON.parse(raw_data.edits)[0];
localStorage.setItem("edits", raw_data.edits);
localStorage.setItem("template-"+id, raw_data.template);
localStorage.setItem("metadata-"+id, raw_data.metadata);
location.href = "<YOUR URL TO editor.html>#"+id;

Hope it will help.

@manhtien2607
Copy link

simple is the best. many thanks for your post

@losttheplot
Copy link

Thanks Umar-sid; that's a really good idea. I've expanded on your concept and have written the following two JS functions:

// store the Mosaico-related contents of local storage to the database
function storeData() {
    if (localStorage.getItem('edits')) {
        var dataToStore = {};
        dataToStore.edits = localStorage.getItem('edits');
        var editKeys = JSON.parse(dataToStore.edits);
        for (var i = 0; i < editKeys.length; i++) {
            dataToStore['metadata-'+editKeys[i]] = localStorage.getItem('metadata-'+editKeys[i]);
            dataToStore['template-'+editKeys[i]] = localStorage.getItem('template-'+editKeys[i]);
        };
        $.ajax({
            url: '/ajax/mosaicodata/overwrite',
            type: 'post',
            data: { mozData: JSON.stringify(dataToStore), CSRFToken: '#{$csrf_token}'},
            dataType: 'json',
            success: function(response) {
                if (response > 0) {
                    swal({ title: 'Saved to Database', text: '  ', timer: 1000, icon: 'success', buttons: false });
                } else {
                    swal({ title: 'Not Saved to Database', text: ' ', timer: 2000, icon: 'error', buttons: false });
                }
            }
        });
    }
};

// load/replace the Mosaico-related local storage with database-stored data
function fetchStoredData() {
    $.ajax({
        url: '/ajax/mosaicodata/fetch',
        type: 'post',
        data: { csrf_token: '#{$csrf_token}' },
        dataType: 'json',
        success: function(storedData) {
            if (typeof storedData != 'undefined') {
                localStorage.setItem('edits', storedData.edits);
                var editKeys = JSON.parse(storedData.edits);
                for (var i = 0; i < editKeys.length; i++) {
                    var id = JSON.parse(storedData.edits)[i];
                    localStorage.setItem('metadata-'+id, storedData['metadata-'+id]);
                    localStorage.setItem('template-'+id, storedData['template-'+id]);
                };
                location.href = '/interface/mosaico';
            }
        }
    });
};

The storeData() response feedback requires SweetAlert but is only for development. The URLs are specific to my app, so if you don't understand what these need to be for your use-case then this solution is not for you. I call storeData() after any template creation, edit, deletion or rename action. When returning to the index page after an edit and save, I work out if a database update is required like this:

if (localStorage.getItem('edits')) {
    // compare current 'last changed' timestamp string with stored 'last changed' timestamp string
    var stamp = '';
    var lastStamp = '';
    var editKeys = JSON.parse(localStorage.getItem('edits'));
    for (var i = 0; i < editKeys.length; i++) {
        // form concatenated string of 'changed' timestamps
        stamp += JSON.parse(localStorage.getItem('metadata-'+editKeys[i])).changed;
    }
    if (localStorage.getItem('last-stamp')) {
        // fetch last saved string of 'changed' timestamps
        lastStamp = localStorage.getItem('last-stamp');
    }
    if (lastStamp !== stamp) {
        // update database if data has changed
        storeData(); 
    }
    // save current string of 'changed' timestamps
    localStorage.setItem('last-stamp', stamp);
} else {
    // if no locally stored data, fetch and load any data in the database
    fetchStoredData();
}

These are the two methods used to store/access the data in the database. Again, if you don't understand where they belong in the bigger picture, or how to adapt it for your needs, then this solution is not for you.

    //----------------------------------------------------------------------------------------------
    // FETCH the current Mosaico 'work in progress' data
    //----------------------------------------------------------------------------------------------
    public function fetch($moz_ref = 1)
    {
        // kick the user out if the csrf token is invalid
        if (!Csrf::isTokenValid()) { LoginModel::logout(); Redirect::login(); exit(); }
        
        $database = DatabaseFactory::getFactory()->getConnection();
        $sql = "SELECT moz_data FROM mozaico_data WHERE moz_ref = :moz_ref LIMIT 1";
        $query = $database->prepare($sql);
        $query->bindParam(':moz_ref', $moz_ref, PDO::PARAM_INT);
        $query->execute();
        
        if ($query->rowCount() == 1) {
            $row = $query->fetch(PDO::FETCH_ASSOC);
            echo $row['moz_data'];
        } else {
            echo '';
        }
    }

    //----------------------------------------------------------------------------------------------
    // OVERWRITE the current Mosaico 'work in progress' data
    //----------------------------------------------------------------------------------------------
    public function overwrite($moz_ref = 1)
    {
        $submittedData = Request::allPosts();
        $mozData = $submittedData['mozData'];

        // kick the user out if the csrf token is invalid
        if (!Csrf::isTokenValid()) { LoginModel::logout(); Redirect::login(); exit(); }
        
        if ($mozData) {
            $database = DatabaseFactory::getFactory()->getConnection();
            $sql = "UPDATE mozaico_data SET moz_data = :moz_data WHERE moz_ref = :moz_ref LIMIT 1";
            $query = $database->prepare($sql);
            $query->bindParam(':moz_ref', $moz_ref, PDO::PARAM_INT);
            $query->bindParam(':moz_data', $mozData, PDO::PARAM_STR);
            $query->execute();
                
            echo $query->rowCount();

        } else {
            echo 0;
        }
    }

This is my single-record database table:

CREATE TABLE `mozaico_data` (
  `moz_ref` tinyint(3) UNSIGNED NOT NULL AUTO_INCREMENT,
  `moz_data` longtext COLLATE utf8mb4_unicode_ci,
  PRIMARY KEY (`moz_ref`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `mozaico_data` (`moz_ref`, `moz_data`) VALUES (1, '');

At this stage I haven't thoroughly tested the above, but will try to remember to edit it if needed. I'm no expert on this stuff, so if anyone can improve it, please be my guest :)

@voidlabs voidlabs locked and limited conversation to collaborators Apr 27, 2022
@bago bago converted this issue into discussion #637 Apr 27, 2022

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Projects
None yet
Development

No branches or pull requests

9 participants