upgrade to TinyMCE 2.09

TinyMCE new version 2.09 came. What's the new feature? Let's have a compare with the 2.02....
TinyMCE new version 2.09 came.

What's the new feature?

Let's have a compare with the 2.02.

The interface with full features of 2.02

TinyMCE 2.02 full feature Interface

The interface with full features of 2.09 

TinyMCE 2.09 full feature interface

Lots of changes, include: (I only list the changes which are most important for me. I didn't check the change logs, this info just for reference. )

  • New fullscreen mode, I'm editing on this mode, like it very much!
  • New tags supported
    • cite
    • abbr
    • del
    • ins
    • acronym
  • New development kit, powerful and helpfule!
  • Some tiny changes, such as:
    • nicer formating on HTML source window.
    • won't link the followed text after a link new generated.

Development kit interface

TinyMCE Development kit interface

This kit interface is able to collsape and expand.

Download and Upgrade in MT

Donwload the package file at here. Unpackage it and prepare to upgrade. Here's the steps:

  • Backup the old directory and files.
mt-static\plugins\Ajaxify\tinymce\
\cgi-bin\mt\plugins\Ajaxify\EnhancedEntryEditing.pl (You won't have and don't need to backup this file if you don't use the plugin EnhancedEntryEditing.) 
  • Replace all things in mt-static\plugins\Ajaxify\tinymce\ with the new version.
  • Open \cgi-bin\mt\plugins\Ajaxify\EnhancedEntryEditing.pl to edit. (no need do this if you don't have.)
  • Comment out all old settings from last installation within:
    settings => new MT::PluginSettings([
        ['tinymce_config', { Default => q{
        old setttings here
        }}]
    ]),

 

  • Copy new settings from the source(View->Page Source) of mt-static/plugins/Ajaxify/tinymce/examples/example_full.htm to the place of old settings.

    settings => new MT::PluginSettings([
        ['tinymce_config', { Default => q{
        /* old settings here */
        new setttings here
        }}]
    ]),
  • Make some neccesory changes on the new settings.
mode : "textareas",
mode : "exact"
elements : "text,text_more",
content_css : "example_full.css",
content_css : "/css/extend.css",

  • Save changes, then logon MT management to new an entry(might need a refresh here, F5), the new interface will take effect.
  • Done!

Here's the new interface in MT, a little fat for MT got overflow, but not a big problem. Enjoy it!

TinyMCE 2.09 interface in MT

The full code section in \cgi-bin\mt\plugins\Ajaxify\EnhancedEntryEditing.pl

settings => new MT::PluginSettings([
['tinymce_config', { Default => q{
/** This section was used by TinyMCE v2.01
mode : "exact",
elements : "text,text_more,excerpt",
theme : "advanced",
plugins : "iespell, emotions, inlinepopups",
theme_advanced_blockformats : "p,h1,h2,h3,h4,h5,h6",
theme_advanced_buttons1 : "formatselect,bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bullist,numlist,outdent,indent,separator,undo,redo,separator,link,unlink,separator,image,emotions,iespell,help",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],span[class|align|style]",
force_p_newlines : true,
relative_urls : false,
remove_script_host : false,
button_tile_map : true,
ask : false,
auto_cleanup_word : true,
theme_advanced_path_location : "bottom",
theme_advanced_resizing : true,
theme_advanced_resize_horizontal : false,
safari_warning: false,
oninit: "quicktagsHide"
**/
/** This section was used by TinyMCE v2.02
//mode : "textareas",
mode : "exact",
elements : "text,text_more",
//editor_selector : "mceEditor",
theme : "advanced",
//plugins : "table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,zoom,flash,searchreplace,print,contextmenu",
plugins : "table,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,zoom,flash,searchreplace,print,contextmenu",
//theme_advanced_buttons1_add_before : "save,separator",
theme_advanced_buttons1_add : "fontselect,fontsizeselect",
theme_advanced_buttons2_add : "separator,insertdate,inserttime,preview,zoom,separator,forecolor,backcolor",
theme_advanced_buttons2_add_before: "cut,copy,paste,separator,search,replace,separator",
theme_advanced_buttons3_add_before : "tablecontrols,separator",
theme_advanced_buttons3_add : "emotions,iespell,flash,advhr,separator,print",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_path_location : "bottom",
plugin_insertdate_dateFormat : "%Y-%m-%d",
plugin_insertdate_timeFormat : "%H:%M:%S",
extended_valid_elements : "a[name|href|target|title|onclick],img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
external_link_list_url : "example_data/example_link_list.js",
external_image_list_url : "example_data/example_image_list.js",
flash_external_list_url : "example_data/example_flash_list.js",
content_css : "/css/extend.css",
theme_advanced_resizing : true,
theme_advanced_resize_horizontal : false,
oninit: "quicktagsHide"
**/
/** This section was used by Tiny MCE v2.09 **/
//mode : "textareas",
mode : "exact",
elements : "text,text_more",
theme : "advanced",
plugins : "devkit,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras",
theme_advanced_buttons1_add_before : "save,newdocument,separator",
theme_advanced_buttons1_add : "fontselect,fontsizeselect",
theme_advanced_buttons2_add : "separator,insertdate,inserttime,preview,separator,forecolor,backcolor,advsearchreplace",
theme_advanced_buttons2_add_before: "cut,copy,paste,pastetext,pasteword,separator,search,replace,separator",
theme_advanced_buttons3_add_before : "tablecontrols,separator",
theme_advanced_buttons3_add : "emotions,iespell,media,advhr,separator,print,separator,ltr,rtl,separator,fullscreen",
theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,|,visualchars,nonbreaking",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_path_location : "bottom",
content_css : "/css/extend.css",
plugin_insertdate_dateFormat : "%Y-%m-%d",
plugin_insertdate_timeFormat : "%H:%M:%S",
extended_valid_elements : "hr[class|width|size|noshade],font[face|size|color|style],span[class|align|style]",
external_link_list_url : "example_link_list.js",
external_image_list_url : "example_image_list.js",
flash_external_list_url : "example_flash_list.js",
media_external_list_url : "example_media_list.js",
file_browser_callback : "fileBrowserCallBack",
theme_advanced_resize_horizontal : false,
theme_advanced_resizing : true,
nonbreaking_force_tab : true,
apply_source_formatting : true
}}]
]), 

 

Editlet 调整

让Editlet 编辑器产生<br /> ,而不是<br>在editor.html 中进行替换%3Cbr%3E%3Cbr%20/%3E 去除Editlet 自动添加的:<link xhref="css/sample.css" mce_href="css/sample.css" rel="stylesheet" type="text/css"> 编辑editor.html ,在getXHTML() 中注释://outStr='<link type="text/css" rel="stylesheet"...

让Editlet 编辑器产生<br /> ,而不是<br>

在editor.html 中进行替换
%3Cbr%3E
%3Cbr%20/%3E

去除Editlet 自动添加的:

<link xhref="css/sample.css" mce_href="css/sample.css" rel="stylesheet" type="text/css">

编辑editor.html ,在getXHTML() 中注释:

//outStr='<link type="text/css" rel="stylesheet" xhref="'+css_url+'" mce_href="'+css_url+'" />';

在setMode() 中修改:

//objEditArea.document.body.innerHTML = html.toString()+'<link type="text/css" rel="stylesheet" xhref="'+css_url+'" mce_href="'+css_url+'">';
objEditArea.document.body.innerHTML = html.toString();//+'<link type="text/css" rel="stylesheet" xhref="'+css_url+'" mce_href="'+css_url+'">';
//objEditArea.document.body.innerHTML = document.frmShowEditor.txtSource.value+'<link type="text/css" rel="stylesheet" xhref="'+css_url+'" mce_href="'+css_url+'">' ;
objEditArea.document.body.innerHTML = document.frmShowEditor.txtSource.value;//+'<link type="text/css" rel="stylesheet" xhref="'+css_url+'" mce_href="'+css_url+'">' ;
以上改动没有起到作用,由于源代码结构比较混乱,还有一层encode,要搞清楚需要很大精力,已经决定放弃继续在这套源码之上的refines了。

Editlet 功能扩展:增加标题<Hn>和预定格式<PRE>

需求 Editlet 当前版本未提供标题定义功能<H1>...<H6>,虽然可以通过定义<P class="header1"></p> 来达到相同的显示效果,但真正的标题可以反映良好的页面结构,对于自动抓取网页的程序也更友好(Crawl-Friendly),有关标题的使用可以参见使用真正的标题,这是网站亲和力设计的一部分。 预定格式<PRE>标签,用于在网页上保持文本的原有格式,对于在网页上显示程序源代码十分有用。 本文内容基于已经解除限制的Editlet 版本。 代码 将文本Text加入形如<TAG>Text</TAG> 这样的标签,DHTML 提供了标准的命令:FormatBlock,该命令可通过如下方式调用:execCommand('FormatBlock', false, '<H1>')HRESULT execCommand(          BSTR...

需求

Editlet 当前版本未提供标题定义功能<H1>...<H6>,虽然可以通过定义<P class="header1"></p> 来达到相同的显示效果,但真正的标题可以反映良好的页面结构,对于自动抓取网页的程序也更友好(Crawl-Friendly),有关标题的使用可以参见使用真正的标题,这是网站亲和力设计的一部分。

预定格式<PRE>标签,用于在网页上保持文本的原有格式,对于在网页上显示程序源代码十分有用。

本文内容基于已经解除限制的Editlet 版本

代码

将文本Text加入形如<TAG>Text</TAG> 这样的标签,DHTML 提供了标准的命令:FormatBlock,该命令可通过如下方式调用:

execCommand('FormatBlock', false, '<H1>')

HRESULT execCommand(          BSTR cmdID,
    VARIANT_BOOL showUI,
    VARIANT value,
    VARIANT_BOOL *pfRet
);

参数value 可以是一个HTML 标签,取值依赖于cmdID,当cmdID='FormatBlock' 时,已知的有效标签包括:

<H1>...<H6>,<P>,<DIV>,<PRE>,<UL>,<OL>,<DD>

首先将editlet.html 进行解码。为了需要,进行一下简单重构。

原来程序中用两个函数csslist() 与fontlist() 分别生成CSS与字体的下拉菜单,重构为一个通用的函数fmtList(),并更改原来函数的调用。原字体大小的下拉菜单采用硬编码,也改为使用fmtList() 生成。

原函数:

function fontList(l_str_fontnames)
{
 //alert("inside 1"+l_str_fontnames);
 var fontnames=l_str_fontnames;
 var lastfont=fontnames.substring(fontnames.lastIndexOf(",")+1,fontnames.length);
 //alert("inside 1");
 document.write('<OPTION selected value=Font>Font');
 document.write('<OPTION value="Arial">Arial');
 document.write('<OPTION value="Times New Roman">Times New Roman');
 document.write('<OPTION value="Verdana">Verdana');
 if(fontnames.length>0)
 {
 while(fontnames.indexOf(",")>=0)
 {
  var str=fontnames;
  var commaindex=fontnames.indexOf(",");
  var font=fontnames.substring(0,commaindex);
  fontnames=fontnames.substring(commaindex+1);
  document.write('<OPTION value='+font+'>'+font+'</OPTION>');
 }
 document.write('<OPTION value='+lastfont+'>'+lastfont+'</OPTION>');
 }
 //alert("Fontname="+font_name);
 setFontName(font_name);
}

重构后:

function fmtList(l_str_list, style)
{
 var item;
 var commaindex=l_str_list.indexOf(",");
 var first_item=l_str_list.substring(0,commaindex);
 l_str_list=l_str_list.substring(commaindex+1);
 document.write('<OPTION selected value='+first_item+'>'+first_item+'</OPTION>');
 while(1)
 {
  commaindex=l_str_list.indexOf(",");
  if(commaindex==-1)
  {
   if(l_str_list=="" || l_str_list==null)
    break;
   else
    item=l_str_list;
    l_str_list=null;
  }else
  {
   item=l_str_list.substring(0,commaindex);
   l_str_list=l_str_list.substring(commaindex+1);
  }
  document.write('<OPTION ');
  if(style=1) // show this item with css
   document.write('class='+item+' ');
  document.write('value='+item+'>'+item+'</OPTION>');
 } 

增加一个函数setBlock() ,在下拉菜单的onChange事件中调用。

function setBlock(formatblock)
{
 if(formatblock=="Block")
 {
  return;
 }
 cmdExec('formatblock',formatblock);
}

定义下拉菜单:

<TD>
<SELECT class="formfield" id=Block
onchange="setBlock('&lt;'+this[this.selectedIndex].value+'&gt;'); Block.value='Block';"
name=Block style="LEFT: 0px; TOP: 10px">
<script>fmtList(block_list,0);</script>
</SELECT>
</TD>  

在editor.html 中添加相关变量:

var l_str_block_flag = window.parent.block_flag;
var font_size_list = window.parent.font_size_list;
var block_list = window.parent.block_list;

var l_str_flist="function%20fmtList%28l_str_list%2C%20style%29%0D%0A%7B%0D%0A%09var%20item%3B%0D%0A%09var%20commaindex%3Dl_str_list.indexOf%28%22%2C%22%29%3B%0D%0A%09var%20first_item%3Dl_str_list.substring%280%2Ccommaindex%29%3B%0D%0A%09l_str_list%3Dl_str_list.substring%28commaindex+1%29%3B%0D%0A%09document.write%28%27%3COPTION%20selected%20value%3D%27+first_item+%27%3E%27+first_item+%27%3C/OPTION%3E%27%29%3B%0D%0A%09while%281%29%0D%0A%09%7B%0D%0A%09%09commaindex%3Dl_str_list.indexOf%28%22%2C%22%29%3B%0D%0A%09%09if%28commaindex%3D%3D-1%29%0D%0A%09%09%7B%0D%0A%09%09%09if%28l_str_list%3D%3D%22%22%20%7C%7C%20l_str_list%3D%3Dnull%29%0D%0A%09%09%09%09break%3B%0D%0A%09%09%09else%0D%0A%09%09%09%09item%3Dl_str_list%3B%0D%0A%09%09%09%09l_str_list%3Dnull%3B%0D%0A%09%09%7Delse%0D%0A%09%09%7B%0D%0A%09%09%09item%3Dl_str_list.substring%280%2Ccommaindex%29%3B%0D%0A%09%09%09l_str_list%3Dl_str_list.substring%28commaindex+1%29%3B%0D%0A%09%09%7D%0D%0A%09%09document.write%28%27%3COPTION%20%27%29%3B%0D%0A%09%09if%28style%3D1%29%20//%20show%20this%20item%20with%20css%0D%0A%09%09%09document.write%28%27class%3D%27+item+%27%20%27%29%3B%0D%0A%09%09document.write%28%27value%3D%27+item+%27%3E%27+item+%27%3C/OPTION%3E%27%29%3B%0D%0A%09%7D%09%0D%0A%7D"
//var l_str_script = l_str_script_start+l_str_script_button+l_str_script_table+l_str_script_image+l_str_script_link+l_str_script_clear+l_str_script_symbols+l_str_script_color+l_str_script_init+l_str_font+l_str_script_cleanhtml+l_str_script_open+l_str_fcss+l_str_copy+l_str_script_end;
var l_str_script = l_str_script_start+l_str_script_button+l_str_script_table+l_str_script_image+l_str_script_link+l_str_script_clear+l_str_script_symbols+l_str_script_color+l_str_script_init+l_str_font+l_str_script_cleanhtml+l_str_script_open+l_str_flist+l_str_copy+l_str_script_end;

var l_str_td_block = "%3CTD%3E%3CSELECT%20%20class%3D%22formfield%22%20id%3DBlock%20%0D%0A%09%20%20onchange%3D%22setBlock%28%27&lt;%27+this%5Bthis.selectedIndex%5D.value+%27&gt;%27%29%3B%20Block.value%3D%27Block%27%3B%22%20%0D%0A%09%20%20name%3DBlock%20style%3D%22LEFT%3A%200px%3B%20TOP%3A%2010px%22%3E%20%0D%0A%09%20%20%20%20%3Cscript%3EfmtList%28block_list%2C0%29%3B%3C/script%3E%3C/SELECT%3E%20%3C/TD%3E%20%20%20%20%20%20%20%20%20%20%20%20%20%20";

var l_str_td_font_type = "%3CTD%3E%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CDIV%20class%3Dbutton%20onclick%3D%22cmdExec%28%27bold%27%29%22%3E%3CIMG%20align%3DabsMiddle%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Bold%20text%22%20class%3Dicon%20src%3D%22"+icons_path+"/bold.gif%22%3E%20%3C/DIV%3E%3C/TD%3E%0D%0A%20%20%20%20%20%20%20%20%20%20%3CTD%3E%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CDIV%20class%3Dbutton%20onclick%3D%22cmdExec%28%27italic%27%29%22%3E%3CIMG%20align%3DabsMiddle%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20title%3D%22Italic%20text%22%20class%3Dicon%20src%3D%22"+icons_path+"/italic.gif%22%3E%20%3C/DIV%3E%3C/TD%3E%0D%0A%20%20%20%20%20%20%20%20%20%20%3CTD%3E%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%3CDIV%20class%3Dbutton%20onclick%3D%22cmdExec%28%27underline%27%29%22%3E%3CIMG%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20align%3DabsMiddle%20title%3D%22Underlined%20text%22%20class%3Dicon%20%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20src%3D%22"+icons_path+"/under.gif%22%3E%20%3C/DIV%3E%3C/TD%3E";
var l_str_td_font_style = "%3CTD%3E%3CSELECT%20class%3D%22formfield%22%20onchange%3D%22setFont%28this%5Bthis.selectedIndex%5D.value%29%3B%20select1.value%3D%27Font%27%3B%22%20%0D%0A%09%20%20id%3Dselect1%20name%3Dselect1%20style%3D%22LEFT%3A%200px%3B%20TOP%3A%2010px%22%3E%20%0D%0A%09%20%20%20%20%3Cscript%3EfmtList%28font_list%2C0%29%3B%3C/script%3E%0D%0A%09%20%20%20%20%3C/SELECT%3E%20%3C/TD%3E%0D%0A%09%3CTD%3E%3CSELECT%20%20class%3D%22formfield%22%20id%3DFontSize%20%0D%0A%09%20%20onchange%3D%22setSize%28this%5Bthis.selectedIndex%5D.value%29%3B%20FontSize.value%3D%27Size%27%3B%22%20%0D%0A%09%20%20name%3DFontSize%20style%3D%22LEFT%3A%200px%3B%20TOP%3A%2010px%22%3E%20%0D%0A%09%20%20%20%20%3Cscript%3EfmtList%28font_size_list%2C0%29%3BsetFontSize%28font_size%29%3B%3C/script%3E%3C/SELECT%3E%20%3C/TD%3E";
var l_str_css="%3CTD%3E%3CSELECT%20class%3D%22cmbtext%22%20style%3D%22width%3A%20150px%3Bheight%3A%2019px%3B%22%20onchange%3DsetStyle%28editArea%2CHTMLMode%2C%22%22%2Cthis%5Bthis.selectedIndex%5D.text%29%3B%20css1.value%3D%27CSS%27%3B%0D%0A%09%20%20%20%09%20%20id%3Dcss1%20name%3Dcss1%20style1%3D%22LEFT%3A%200px%3B%20TOP%3A%2010px%22%3E%20%0D%0A%09%20%20%20%09%20%20%20%20%3Cscript%3EfmtList%28css_list%2C1%29%3B%3C/script%3E%0D%0A%09%20%20%20%09%20%20%20%20%3C/SELECT%3E%20%3C/TD%3E%0D%0A%09%20%20%20";

if(l_str_block_flag==1)
{
  l_str_piece_tr2_all += l_str_td_block + l_str_td_sep ;
  l_int_tr2_count++;
 } 

在editor.js 中修改并添加新的变量:

var block_flag   = 1 ;
var css_list   = "Choose Style,big-font,middle-font,small-font";
var font_list   = "Font,Arial,Times New Roman,Verdana,ËÎÌå,ºÚÌå";
var font_size_list  = "Size,1,2,3,4,5,6,7"
var block_list   = "Block,H1,H2,H3,H4,H5,PRE"

修改完成,今后只需对以上的变量进行维护即可。

参考资源

MT整合HTML在线编辑器Editlet(三)——统一CSS

正文 Editlet 提供了默认的CSS,可以在编辑界面为所选文字指定样式。此CSS 文件位置为:editlet 主目录/css/sample.css 如果你在编辑界面使用了此样式单定义,则Editlet 会自动在文章末尾加入外联样式单的链接,否则发布的文章将无法正确显示Editlet 中定义的样式。<LINK xhref="css/sample.css" mce_href="css/sample.css" type=text/css rel=stylesheet> 一般我们在MT 当中已经定义好了一套CSS,让Editlet 使用MT 的CSS...

正文

Editlet 提供了默认的CSS,可以在编辑界面为所选文字指定样式。此CSS 文件位置为:

editlet 主目录/css/sample.css

如果你在编辑界面使用了此样式单定义,则Editlet 会自动在文章末尾加入外联样式单的链接,否则发布的文章将无法正确显示Editlet 中定义的样式。

<LINK xhref="css/sample.css" mce_href="css/sample.css" type=text/css rel=stylesheet>

一般我们在MT 当中已经定义好了一套CSS,让Editlet 使用MT 的CSS 只需很简单的几步。

打开editor.js 进行编辑,首先确定没有关闭CSS 功能按钮,应有如下定义:

var css_flag    = 1 ;

然后修改CSS 文件指向,如果你的CSS 文件名称为:style.css,放在web 根目录下的css 文件夹中,则修改如下:

//var css_url   = "css/sample.css";
var css_url   = "/css/style.css";

接下来告诉Editlet 如何生成用于选择样式单的下拉列表,需要把你在style.css 中定义的样式名称,组成一个用逗号分隔的字符串,赋给变量css_list 。

//var css_list   = "header1,header2,text,pageheader,boldtext,tableheader1,tablecolor,italictext,textbg,tableheader2,tableheader3,graytext,smalltext,header3,header4,graytextbold,redtext,footertext";
var css_list   = "big-font,middle-font,small-font";

editor.js 修改完毕。

接着打开editor.html 进行编辑,只需修改一处,找到CSS 链接,修改如下:

<!--
<link type="text/css" rel="stylesheet" xhref="css/sample.css" mce_href="css/sample.css">
-->
<link type="text/css" rel="stylesheet" xhref="/css/style.css" mce_href="/css/style.css">

在此文件中链接CSS 文件,是为了使用实际的样式来格式化编辑界面中的每一个CSS 选项,实现“所见即所得”编辑。

修改完成,现在就可以在Editlet 的界面中使用MT 的CSS 了。

参考资源

MT整合HTML在线编辑器Editlet(二)

整合Editlet到MT 首先将Editlet上传到MT所在的Web服务器,可以放在任意目录,我的目录结构如下:/index.html /archives/ /weblog/static/ /weblog/editlet/ /weblog/editlet/editlet.html /weblog/editlet/editor.html MT模板 MT的后台管理页面均使用了模板,存放在目录 /tmpl/cms/ 。有两个模板与Entries的新增与编辑相关,分别是:header.tmpl、edit_entry.tmpl 。 editlet.html 主要做了如下几件事: 在head 部装载editor.js...

整合Editlet到MT

首先将Editlet上传到MT所在的Web服务器,可以放在任意目录,我的目录结构如下:

/index.html 
/archives/
/weblog/static/
/weblog/editlet/
/weblog/editlet/editlet.html
/weblog/editlet/editor.html
MT模板

MT的后台管理页面均使用了模板,存放在目录 /tmpl/cms/ 。有两个模板与Entries的新增与编辑相关,分别是:header.tmpl、edit_entry.tmpl 。

editlet.html 主要做了如下几件事:

  1. 在head 部装载editor.js 脚本,并定义Editlet程序文件的存放路径。
  2. 在body 标签中定义事件处理。
  3. 生成编辑工具条与文本区域。
  4. 为文本区域设定初始编辑内容。
  5. 保存文本区域的内容。

要实现整合,我们就需要把这几项功能实现在MT的以上两个模板中。

修改MT部分

我们把第1、2项功能放到header.tmpl 中实现。

打开header.tmpl 进行编辑,在<head>与</head>之间加入editlet.html 头部的脚本:

<script type="text/javascript" xsrc="/weblog/editlet/editor.js" mce_src="/weblog/editlet/editor.js"></script>
<script type="text/javascript">
var path="/weblog/editlet/";
</script>

其中变量path 指定为editlet目录的web绝对路径。

在<body>标签中加入editlet.html <body>标签中的script:
<body onafterprint="return window_onafterprint()" LANGUAGE="javascript">

保存header.tmpl ,注意修改文件之前先进行备份。

打开edit_entry.tmpl 进行编辑。先找到<form> 标签,在标签中加入:

onsubmit="return getContent();"
<form name="entry_form" method="post" onsubmit="return getContent();" action="<TMPL_VAR NAME=SCRIPT_URL>">

接着找到那个叫做Entry Body 的文本区域(textarea),将其注释掉:

<!--
<textarea class="full-width" name="text" id="text" tabindex="3" rows="<TMPL_IF NAME=DISP_PREFS_SHOW_EXTENDED>10<TMPL_ELSE>20</TMPL_IF>"><TMPL_VAR NAME=TEXT ESCAPE=HTML></textarea>
-->

在后面使用MT的<INCLUDE> 标签将editlet.html页面包含到这里,路径要写成editlet.html 在服务器上的文件系统绝对路径,写成web的绝对或相对路径都无法工作。

<INCLUDE TMPL="/var/www/html/weblog/editlet/editlet.html">

为了装载和保存编辑内容,添加一个隐含的文本框,id、name、value等属性与注释掉的<textarea> 相同:

<input name="text" id="text" type=hidden value="<TMPL_VAR NAME=TEXT ESCAPE=HTML>">

对MT的修改到此结束。

修改Editlet部分

打开Editlet.html 进行编辑。首先删除<table> 标签之前以及</table> 标签之后的所有代码,以上部分已经在MT模板中实现了。

接下来删除<form> 与</form> 标签之间的所有代码,保存的功能将通过在MT模板中定义的onsubmit 事件在editor.js中完成。

函数setContent() 用于设置文本区域的初始内容,我们将其改为:

//setContent('Your Content');
setContent(document.entry_form.text.value);

text 在edit_entry.tmpl 中定义,打开一个Entry 时,MT将数据写入这个文本框,保存时,MT读取其内容并保存。

函数setEditlet(path) 用于生成工具条和文本区域,保留这个部分。

为了使文本区域的宽度适合MT,修改<table> 标签:

<!--
<table border="0" width="760" cellspacing="0" cellpadding="2" style="HEIGHT: 151px; WIDTH: 760px">
-->
<table border="0" width="580" cellspacing="0" cellpadding="0" style="HEIGHT: 151px; WIDTH: 580px">

打开editor.js 进行编辑。

函数getContent() 将会在编辑内容被提交时执行,我们只需将此函数获得的文本区域内容交给MT来处理,修改如下:

//document.form1.hid_out_content.value = content1;
//document.form1.submit();
document.entry_form.text.value = content1;

变量content1 是Editlet 获取的文本区域内容。

找到函数setEditlet() 的定义,将其中的函数调用replace() 注释掉,replace() 所处理的一些转换,MT已经做过了,否则会重复处理。修改后如下:

function setEditlet(path){
 setEditor(path);
 //replace();
}

接下来修改一些配置参数。

将编辑区域的宽度缩小,以适合MT:

//var editorwidth  = 900 ;
var editorwidth  = 580 ;

关闭一些不使用的按钮,以使工具条宽度不超过580,只需要设置哪些后缀为"_flag" 的参数,将值改为0 即可。

var table_flag   = 0 ;
var help_flag    = 0 ;
var clean_html_flag   = 0 ;
var spellcheck_flag   = 0 ;
var save_flag    = 0 ;
var open_flag   = 0 ;
var xhtml_flag    = 0 ;

在编辑区域中按回车键,默认会产生一个<br> 标签,如下修改后,将产生<p> </p>标签,依个人编辑喜好而设定。

//var CarriageReturn  = false;
var CarriageReturn  = true;

Editlet 部分修改完毕。

测试

至此,基本功能整合完毕,进入MT后台管理,进行测试。

选择“NEW ENTRY”,应该可以看到新的编辑界面,测试一下各编辑按钮是否正常工作,测试保存功能。

选择“ENTRIES”,选择一篇已有文章打开编辑,测试原有内容是否正常装入,有无重复转换字符(比如空格、双引号"、连接符&)的问题,测试保存功能。

参考资源

MT整合HTML在线编辑器Editlet(一)——解除限制

前言 Movable Type 是一个非常不错的Blog网站发布和管理系统,目前最新版本是v3.14,后台提供了带有简单超文本编辑功能的文章编辑界面。 但缺乏诸如标题、字体、CSS、项目列表、表格和图片等内容的支持。虽然对于一个熟练的bloger来说,以上这些都可以通过手工在文章内容中嵌入超文本标签来完成,但却无法使其更专注于内容。在比较了多个超文本在线编辑器组件和产品之后,笔者选择了Editlet ,其在IE浏览器中运行的界面如下,本文就是在类似这样一个界面中发布的,比如我可以随意在其它网页或者word文件中拷贝一个与下面类似的图表,粘贴在这里。本文介绍把Editlet整合到MT后台发布管理系统的过程。 准备工作 系统应该先安装好MT,相关信息请参考车东的MT安装笔记:初始化和安全配置。 下载Editlet,目前Editlet提供JSP、PHP,PERL三个版本,不过网站以及程序包内均未标识版本信息。免费下载版本增加了一些限制:只能在运行Editlet的本机上访问,就是说只能通过http://localhost 或者http://127.0.0.1 进行访问;另外增加了时间限制,只能免费试用一个月。 下载地址:http://www.editlet.com 我下载了PHP版本。 笔者的安装环境: RedHat Linux...

前言

Movable Type 是一个非常不错的Blog网站发布和管理系统,目前最新版本是v3.14,后台提供了带有简单超文本编辑功能的文章编辑界面。

但缺乏诸如标题、字体、CSS、项目列表、表格和图片等内容的支持。虽然对于一个熟练的bloger来说,以上这些都可以通过手工在文章内容中嵌入超文本标签来完成,但却无法使其更专注于内容。在比较了多个超文本在线编辑器组件和产品之后,笔者选择了Editlet ,其在IE浏览器中运行的界面如下,本文就是在类似这样一个界面中发布的,比如我可以随意在其它网页或者word文件中拷贝一个与下面类似的图表,粘贴在这里。本文介绍把Editlet整合到MT后台发布管理系统的过程。

Editlet Full feature interface

准备工作

  1. 系统应该先安装好MT,相关信息请参考车东的MT安装笔记:初始化和安全配置
  2. 下载Editlet,目前Editlet提供JSP、PHP,PERL三个版本,不过网站以及程序包内均未标识版本信息。免费下载版本增加了一些限制:只能在运行Editlet的本机上访问,就是说只能通过http://localhost 或者http://127.0.0.1 进行访问;另外增加了时间限制,只能免费试用一个月。
    下载地址:http://www.editlet.com
    我下载了PHP版本。
  3. 笔者的安装环境:
    RedHat Linux
    Movable Type 3.14

解除Editlet的限制

Editlet程序的所有文件都在一个压缩包内,HTML和JS代码无需编译,虽然主要代码经过了加密处理,但也很容易找到限制的部分并去除。

如果仅仅使用Editlet的基本编辑功能(除去打开文件、保存文件、上载图片、拼写检查),甚至无需将其放在一个Web服务器上,就可以测试。

我们将其解压到web服务器根目录下的editlet目录,在editlet根目录有以下几个重要的文件:

  • editor.html
  • editor.js
  • editlet.html
  • multi_editlet.html

其中,editor.html包含了程序的核心代码,editlet.html是程序运行的主页面,它通过editor.js调用核心文件editor.html的代码。

multi_editlet.html是另外一个主页面,当在同一个页面需要使用多个编辑器窗口时使用,我们这里暂不考虑。

分析editor.html

程序以函数Decode2() 作为入口,函数内部首先进行软件是否过期检查,然后检查访问链接是否包含localhost或是127.0.0.1来确认是否在本机运行程序。

如果以上两项测试通过,程序执行函数enable() 和b() 。在enable() 中,判断是被editlet.html、multi_editlet.html 哪一个调用,并分别作出不同的配置。这个程序的作者很有意思,函数b(z) 中放了一堆迷惑的代码,实际只做了一件事:调用函数a() ,而核心的主体代码全部在函数a() 中。

函数a() 的主要作用:读取文件editor.js中以及本文件中的的配置参数,根据这些参数,动态生成用于显示编辑器页面的代码,然后调用解码函数写到浏览器。

这些动态组合的代码使用内置函数escape() 进行了编码,这样可以避免一些特殊字符在组合过程中出错。在根据配置参数组合完成之后,调用函数c(y) ,同样使用内置函数unescape() 进行解码,然后写到浏览器。函数c(y) 只有一行代码:

window.document.write(unescape(y));

如果需要查看这些编码了的代码到底做了什么,可以使用这个工具

了解程序流程后,去除限制,只需要删除掉相关函数并清理变量定义,然后以函数enable() 和a() 作为入口函数即可。具体的过程较为繁琐,不祥述,下面提供修改后的程序文件下载。

修正的文件中,也包含了editor.js,不仅去除了editlet.html 的限制代码,也重整了两个文件之间的配置参数调用关系,重整后,所有参数均在editor.js 中一处配置。

运行Editlet

在浏览器中运行editlet.html 所在的链接,这里是带全部编辑按钮的Editlet 演示页面。如果使用非IE浏览器,比如Firefox,会有部分调用了IE组件的按钮——比如表格——会被隐含起来。为了安全起见,该测试页面链接的所有动态程序文件(PHP)被删除。

(未完待续)

参考资源

mail.png


标签订阅|Tag Subscription

If you use an RSS reader, you can subscribe to a feed of all future entries tagged 'wysiwyg'. [What is this?]

Subscribe to feed Subscribe to feed

最近更新|Recent Entries

不定期更新|Handy Entries

其它标签|Other Tags

分类栏目|Categories

按月归档|By Month

2008
11
10
07
05
04
03
02
01
2007
12
10
07
06
05
04
03
02
01
2006
12
11
10
09
08
07
06
05
04
03
02
01
2005
11
10
09
08
07
04
03
2004
12
11
10
09
08
07
06
05
04
03
02
01
2003
12
10
09
08
06
2002
09
08
04
03
02
2001
12
09
07
06
05

站内链接|Site Links

Powered by
Movable Type 3.34