18

I am using codesample plugin of tinymce which is mentioned here https://www.tinymce.com/docs/plugins/codesample/ in my custom portal.

Everything works fine, until, I have to "re-edit" the data stored in database.

When i go to edit, all data stored in database within

<pre><code>&lt;html&gt; &lt;p&gt;Text&lt;/p&gt; &lt;/html&gt; </code></pre>

is stripped and shown as only

<pre><code>Text </code></pre>

when viewed from "Tools > Source"

I am already using "htmlentities" in my textarea like :-

<textarea><?php echo htmlentities($content); ?></textarea>

It still strips all html tag used inside the tag created by codesample plugin.

FAQ : 1. When adding data for the first time everything works fine. 2. Problem is only when i go to edit page. Tinymce strips only HTML code from codesample plugin. Rest all code that has been added using codesample like "css,python,php" etc., are displayed in editor.

John Cargo
  • 1,839
  • 2
  • 29
  • 59
  • 1
    `htmlentities` will have no effect on text which has already been converted to html entities. Your problem is probably somewhere else. – apokryfos Aug 09 '16 at 14:09
  • 1
    what does the raw data in the database look like? To establish if this htmlentities change is occuring on save or retrevial of said data. – Martin Aug 13 '16 at 12:26
  • It is exactly , what it is in "tools > source code" of tinymce. – John Cargo Aug 14 '16 at 10:08

4 Answers4

5

The correct way to insert data into tinymce would not be to print it out or even using htmlentities. Consider the following code

<div class="editor" id="editor">
</div>
<script>
    tinymce.init({
      selector: 'div.editor',
      theme: 'inlite',
      plugins: 'image table link paste contextmenu textpattern autolink',
      insert_toolbar: 'quickimage quicktable',
      selection_toolbar: 'bold italic | quicklink h1 h2 h3 blockquote',
      inline: true,
      paste_data_images: true,
      automatic_uploads: true,
      init_instance_callback : function(ed) {
        // ed.setContent("<h1>Title</h1><p>Content...</p>");
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
           if (xhttp.readyState == 4 && xhttp.status == 200) {
              ed.setContent(xhttp.responseText);
           }
        };
        xhttp.open("GET", "content.php", true);
        xhttp.send();
      },
      content_css: [
        '//www.tinymce.com/css/codepen.min.css'
      ]
    });
</script>

and the file content.php should just simply print the html content

<?php
    $content = ''; // Fetch from database
    print $content;
?>

notice the function at init_instance_callback while i initialize tinymce. That is the function called after tinymce is initialized. Now rather that directly using print inside the editor, make a ajax call inside init_instance_callback and render it there. I have put in a sample commented line just to help you out with the same. This will also take care of security validation (no script tag execution if any).

Also at the same time to get the contents of the editor while saving it to database is

var content = tinyMCE.get('editor').getContent();

And then you can make an ajax post request to save data to database.

Now why am i using ajax is important. I tried a lot of other methods where i could get away with directly printing it. But that causes a security flaw as script tags could run before the editor is initialized.

I used div in this example but it would be all the same even for text area. Also don't use htmlentities because that would escape the html content and you want to see the content rendered in tinymce and not the escaped version.

georoot
  • 3,557
  • 1
  • 30
  • 59
  • I have tried earlier, the instance callback, but i try this after saving data in ajax mode. – John Cargo Aug 14 '16 at 10:12
  • It gives `Invalid or Unexpected token error` due to content being in multiple line - how to avoid that ? – John Cargo Aug 14 '16 at 10:59
  • @JohnCargo can you post some snippet so i can help better :) – georoot Aug 14 '16 at 15:04
  • Snippet ? my `$content` = "This is HTML line with some line break \n and some html code \n again with line break" – John Cargo Aug 14 '16 at 23:23
  • @JohnCargo read my answer, you can't render in the same request. You need to make a different ajax request when the editor is loaded in `init_instance_callback` and only then can you render that using setContent in tinymce. In example where i set content, fetch that using ajax call – georoot Aug 14 '16 at 23:32
  • Did you read my comment, when i said, data, that is getting fetched via ajax has multiple line in its content. All contents are not in 1 single line. it has multiple line and if you know, javascript doesn't support multiple line . – John Cargo Aug 15 '16 at 00:46
  • I don't know what you mean by js not supporting multiple line. Anyway i added more code, that should give you a more complete picture. Remember content.php is no where you render the html. It is just for ajax calls – georoot Aug 15 '16 at 01:19
  • just copy pasted your code in codesample and saved it and ran exactly inch by inch your code and here is response `
     

     

    ` If you see your whole javascript has gone and text too
    – John Cargo Aug 15 '16 at 01:40
  • Can you see the same mentioned bug ? – John Cargo Aug 15 '16 at 11:58
4

Ok, after lots of research, I found that it is an encoding issue. One need to encode each entity like :- < , > to &lt; , &gt; .

And & character inside <code> tag to &amp; , that means &lt; within <code></code> tag becomes &amp;lt;.

Thus, Code like below :-

<pre><code>&lt;html&gt; &lt;p&gt;Text&lt;/p&gt; &lt;/html&gt; </code></pre>

should be like

&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt; &amp;lt;p&amp;gt;Text&amp;lt;/p&amp;gt; &amp;lt;/html&amp;gt; &lt;/code&gt;&lt;/pre&gt;

So, for all users who are finding solution. This is the solution.

Remember, & inside <code> &amp;lt; </code> tag should only be converted to &amp; . Notice &lt; inside <code> tag is &amp;lt;

Cheers

John Cargo
  • 1,839
  • 2
  • 29
  • 59
0

Use setContent function to add the content once TinyMCE is loaded:

setup: function (editor) {
    editor.on('init', function () {
    var theContent = '<pre><code>&lt;html&gt; &lt;p&gt;Text&lt;/p&gt; &lt;/html&gt; </code></pre>';
    this.setContent(theContent);
    });
}

Source: Tags Get Removed When Using Codesample Plugin with TinyMCE

Community
  • 1
  • 1
T.Todua
  • 53,146
  • 19
  • 236
  • 237
0

Sorry to say but I find TinyMCE just too convoluted in dealing with "code". I put up with the numerous & n b s p ; that appear everywhere – but I've resorted to just adding images for code snippets or linking out to a modal popup.

anakowi
  • 1
  • 5