Symfony World blog is not maintained anymore. Check new sys.exit() programming blog.

Using tinyMCE with Symfony

Scene from "Dirty Dancing" by Emile Ardolino (1987)

Symfony gives you a possibility to use lots of third party libraries. One of them, extremely useful while developing backend of your application, is tinyMCE.

The symfony core team has created the sfFormExtraPlugin which helps you to attach tinyMCE to your projects. But there's a lot more you can do to make this editor satisfy your needs.

Configuring tinyMCE

  • I'm assuming you have properly installed the sfFormExtraPlugin inside your project.
  • First of all, you need to install tinyMCE on your own. Go to the download page, and put the extracted content inside your project's web directory. The downloaded archive includes tinyMCE usage examples, you may remove them and include only the tiny_mce directory inside your /web/js directory.
  • Right after including the tinyMCE files don't forget to attach them to the application: go to the backend/config/view.yml file and add the tiny_mce.js file. It should look similar to the following:
    javascripts:    [ /js/tiny_mce/tiny_mce.js ]
    TinyMCE is properly installed in our app already. Now it's time to set the inputs to use it.
  • Edit any of your lib/form classes and set the appropriate widget:
    class SubpageForm extends BaseSubpageForm
    {
      public function configure()
      {
        $this->widgetSchema['content'] =
          new sfWidgetFormTextareaTinyMCE();
      }
    }
    Run your backend application and check if everything is OK.

Advanced tinyMCE configuration

Lots of us may create websites for non-English communities, therefore custom language support is needed. Of course, there are more specific attributes you may want to change. Unfortunately, the sfWidgetFormTextareaTinyMCE class provided with the plugin is hardly configurable. The best solution is to create a custom class extending it and override all the attributes you need.

  • Create a sfWidgetFormTextareaTinyMCECustom class in the /lib/widget directory of your project:
    class sfWidgetFormTextareaTinyMCECustom extends sfWidgetFormTextareaTinyMCE
  • Override the render method. The main code that we are interested in is:
    $js = sprintf(<<<EOF
    <script type="text/javascript">
    tinyMCE.init({
        mode:                              "exact",
        elements:                          "%s",
        theme:                             "%s",
        plugins : "safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,imagemanager,filemanager",
        language: "pl",
        %s
        %s
        theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
        theme_advanced_toolbar_location:   "top",
        theme_advanced_toolbar_align:      "left",
        theme_advanced_statusbar_location: "bottom",
        theme_advanced_resizing:           true
        %s
      });
     
    </script>
    EOF
  • Let's get our custom language working with the tinyMCE now. Go to the language pack download page. Choose the language(s) you want to install, check them (do not download the xml files since you'd have to compile them into the .js files) and press the download just below the end of the list. Move the zip archive into the tiny_mce directory and extract it there. All language files will be extracted in the appropriate places. So far, so good.
  • Edit the render method - add the following code inside the javascript code mentioned above:
    language: "pl",
    and your language pack should already work fine.
  • Since the default tinyMCE configuration doesn't include all possible features, you may add the following lines to enable all features:
    plugins : "safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,imagemanager,filemanager",
    
    and
    theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
    
  • After those modifications your code should look like the following:
    $js = sprintf(<<<EOF
    <script type="text/javascript">
      tinyMCE.init({
        mode:                              "exact",
        elements:                          "%s",
        theme:                             "%s",
        plugins : "safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,imagemanager,filemanager",
        language: "pl",
        %s
        %s
        theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,spellchecker,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,blockquote,pagebreak,|,insertfile,insertimage",
        theme_advanced_toolbar_location:   "top",
        theme_advanced_toolbar_align:      "left",
        theme_advanced_statusbar_location: "bottom",
        theme_advanced_resizing:           true
        %s
      });
    </script>
    EOF
    
    Of course, you may not need all of the tinyMCE features, feel free to modify the code.
  • Just to make sure, such installation enables all tinyMCE features on your frontend application, such as emoticon images. Play with it!

Hope everything will work fine. Any feedback is appreciated.

19 comments:

  1. thanks it worked!:)...What was missing out before was the adding of the JavaScript directory in the view.yml file. I wonder why Fabien didn't give a detailed explanation in the documentation.

    By the way Tiny MCE doesn't allow you to upload an image directly rather asks you to enter the image URL...any ideas or way around this?

    thanks again you made my day.

    ReplyDelete
  2. Hi Zubair, if you have an admin panel that manages images, drag-and-drop should be enough for backend users.

    ReplyDelete
  3. Zubair you can also download TinyMCPUK with TinyMCE 2.0.6. TinyMCPUK has a file / image manager where you can crop, resize, rotate images.

    ReplyDelete
  4. I want '<'textarea'>' $data_from_database '<'/textarea'>'
    How can i do it with sfWidgetFormTextareaTinyMCE ?

    ReplyDelete
  5. implemented it and its great. however, when i retrieve the results from the database. it shows all the mark up....like '<'p'>'some text '<'/p'>'. know a way to stop this?

    ReplyDelete
  6. Just for future reference, this is because Symfony escapes the data. You can get the raw data with getRaw('text') instead of getText(), getRaw('summary') instead of getSummary etc

    ReplyDelete
  7. A more simple an eficient way:

    $this->widgetSchema['description'] = new sfWidgetFormTextareaTinyMCE(array(
    'width' => 550,
    'height' => 350,
    'config' => 'theme_advanced_disable: "anchor,image,cleanup,help"',
    'config' => 'language: "es"'
    ));

    ReplyDelete
  8. I think you've got an error here - you're defining the 'config' array key twice.

    ReplyDelete
  9. i love you thank you so much.

    ReplyDelete
  10. I have found this site many times in my searches while learning Symfony at a break-neck pace. Thank you for providing a solution that saved me hours and I'm quite sure at least one headache.

    ReplyDelete
  11. Thanks Sean :) This is what Fabien writes from time to time - a positive feedback helps to make your work better and better :)

    ReplyDelete
  12. Thanks...............

    ReplyDelete
  13. Is this still good for symfony2?

    ReplyDelete
  14. file browser is not appear . please help me

    ReplyDelete
  15. $this->widgetSchema['comment'] = new sfWidgetFormTextareaTinyMCE(array(
    'width' => 400,
    'height' => 100,
    'theme' => 'modern'
    ));

    ReplyDelete
  16. Is there any hope to validate element using jQuery Validate library?

    I tried so many codes, but didn't get any success.

    Please help...!!

    ReplyDelete
  17. Hello,

    I tried all this stuffs, but for me in place of textarea nothing is coming.
    i have copied the sfFormExtraPlugin in plugins folder and made the desired change in projectConfiguration file
    i have downloded the Tinymyce inside web/js folder
    i have changed the view.yml file
    And now when i am calling it with $form its displaying nothing (visibility is hidden.
    What can be the problem? I am using symfony 1.4
    Please suggest

    ReplyDelete