T5中使用FckEditor组件
1,下载FckEditor,解压,将FckEditor目录拷贝到项目的resource下(相应的精简请参考网上FckEdit配置说明),如:
src\main\resources\com\app\sys\components\fckeditor\FCKeditor_2.4.3
2,编写FckEditorModule和FckEditor类
代码如下:
FckEditor类:
package com.app.sys.components.fckeditor;
import org.apache.tapestry.Asset;
import org.apache.tapestry.MarkupWriter;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.Path;
import org.apache.tapestry.corelib.base.AbstractTextField;
import org.apache.tapestry.ioc.annotations.Inject;
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.services.ClasspathAssetAliasManager;
/**
*
* @author guanyq
*
*/
public class FckEditor extends AbstractTextField {
/**
* The height of the editor
*/
@Parameter(defaultPrefix = "literal", value = "300px")
private String height;
/**
* The width of the editor
*/
@Parameter(defaultPrefix = "literal", value = "100%")
private String width;
/**
* The toolbar set to be used with this editor. Toolbar sets can be
* configured in a {@link #customConfiguration custom configuration}.
*/
@Parameter(defaultPrefix = "literal")
private String toolbarSet;
/**
* A custom configuration for this editor, see the fckeditor manual for
* details on custom configurations.
*/
@Parameter
private Asset customConfiguration;
@Inject
private ClasspathAssetAliasManager cpam;
@Inject
private SymbolSource symbolSource;
public String getScript(String value) {
value = value.replace('\r', '\\'); // this is needed for javascript to
// be able to extend a string across
// multiple lines
value = value.replace("'", "'"); // this is needed because the
// string delimiter is ' for the
// script below
return String.format("var oFCKeditor = new FCKeditor( '%s' );\n", getClientId()) + String.format("oFCKeditor.BasePath = '%s';\n", cpam.toClientURL(symbolSource.expandSymbols("${com.app.sys.components.fckeditorscript.path}")) + "/")
+ // todo could this be done in another way?
(customConfiguration == null ? "" : String.format("oFCKeditor.Config[\"CustomConfigurationsPath\"] = '%s';\n", customConfiguration)) + (toolbarSet == null ? "" : String.format("oFCKeditor.ToolbarSet = '%s'\n", toolbarSet)) + String.format("oFCKeditor.Height = '%s';\n", height) + String.format("oFCKeditor.Width = '%s';\n", width)
+ String.format("oFCKeditor.Value = \'%s\';\n", value) + "oFCKeditor.Create() ;\n";
}
@Environmental
private PageRenderSupport _pageRenderSupport;
@Inject
@Path("${com.app.sys.components.fckeditorscript}/fckeditor.js")
private Asset fckeditor;
void beginRender(MarkupWriter writer) {
_pageRenderSupport.addScriptLink(fckeditor);
}
@Override
protected final void writeFieldTag(MarkupWriter writer, String value) {
writer.element("script", "type", "text/javascript");
writer.writeRaw("<!--\n" + getScript(value) + "//-->\n");
}
final void afterRender(MarkupWriter writer) {
writer.end(); // script
}
}FckEditorModule类:
package com.app.sys.components.fckeditor;
import org.apache.tapestry.ioc.Configuration;
import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.annotations.Symbol;
import org.apache.tapestry.services.LibraryMapping;
/**
* FckEditor组件使用的Module
* @author guanyq
*
*/
public class FckEditorModule {
public static void contributeFactoryDefaults(
MappedConfiguration<String, String> configuration) {
configuration
.add("com.app.sys.components.fckeditorscript",
"classpath:${com.app.sys.components.fckeditorscript.path}");
configuration
.add("com.app.sys.components.fckeditorscript.path",
"com/app/sys/components/fckeditor/FCKeditor_2.4.3");
}
public static void contributeClasspathAssetAliasManager(
MappedConfiguration<String, String> configuration,
@Symbol("com.app.sys.components.fckeditorscript.path")
String fckEditorScriptPath) {
configuration.add("FCKeditor/", fckEditorScriptPath + "/");
}
public static void contributeComponentClassResolver(
Configuration<LibraryMapping> configuration) {
configuration.add(new LibraryMapping("fckeditor",
"com.app.sys.components.fckeditorscript"));
}
}3,在SysModule中加载组件:
package com.app.sys.services;
import java.io.IOException;
import java.io.PrintWriter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tapestry.Link;
import org.apache.tapestry.MarkupWriter;
import org.apache.tapestry.internal.services.LinkFactory;
import org.apache.tapestry.internal.services.PageMarkupRenderer;
import org.apache.tapestry.internal.services.PageResponseRenderer;
import org.apache.tapestry.internal.services.RequestPageCache;
import org.apache.tapestry.internal.structure.Page;
import org.apache.tapestry.ioc.MappedConfiguration;
import org.apache.tapestry.ioc.OrderedConfiguration;
import org.apache.tapestry.ioc.ServiceBinder;
import org.apache.tapestry.ioc.annotations.InjectService;
import org.apache.tapestry.ioc.annotations.SubModule;
import org.apache.tapestry.ioc.annotations.Symbol;
import org.apache.tapestry.services.ActionResponseGenerator;
import org.apache.tapestry.services.ApplicationInitializer;
import org.apache.tapestry.services.ApplicationInitializerFilter;
import org.apache.tapestry.services.BindingFactory;
import org.apache.tapestry.services.BindingSource;
import org.apache.tapestry.services.ComponentClassResolver;
import org.apache.tapestry.services.Context;
import org.apache.tapestry.services.Dispatcher;
import org.apache.tapestry.services.MarkupWriterFactory;
import org.apache.tapestry.services.PageRenderRequestHandler;
import org.apache.tapestry.services.Request;
import org.apache.tapestry.services.RequestExceptionHandler;
import org.apache.tapestry.services.RequestFilter;
import org.apache.tapestry.services.RequestGlobals;
import org.apache.tapestry.services.RequestHandler;
import org.apache.tapestry.services.Response;
import com.app.sys.common.exception.RedirectException;
import com.app.sys.components.fckeditor.FckEditorModule;
@SubModule( { FckEditorModule.class })
public class CsmModule {
static Log log = LogFactory.getLog(CsmModule.class);
/**
* 系统启动时、绑定service
*
* @param binder
*/
public static void bind(ServiceBinder binder) {
}
/**
* 初始化上下文
*
* @param configuration
*/
public void contributeApplicationInitializer(OrderedConfiguration<ApplicationInitializerFilter> configuration) {
ApplicationInitializerFilter clearCaches = new ApplicationInitializerFilter() {
public void initializeApplication(Context context, ApplicationInitializer initializer) {
initializer.initializeApplication(context);
}
};
configuration.add("initialDataBase", clearCaches);
}
/**
* PageResponseRenderer UTF-8编码
*
* @param markupRenderer
* @param markupWriterFactory
* @param delegate
* @return
*/
public static PageResponseRenderer decoratePageResponseRenderer(@InjectService("PageMarkupRenderer")
final PageMarkupRenderer markupRenderer, @InjectService("MarkupWriterFactory")
final MarkupWriterFactory markupWriterFactory, final Object delegate) {
return new PageResponseRenderer() {
public void renderPageResponse(Page page, Response response) throws IOException {
MarkupWriter writer = markupWriterFactory.newMarkupWriter();
markupRenderer.renderPageMarkup(page, writer);
PrintWriter pw = response.getPrintWriter("text/html; charset=UTF-8");
writer.toMarkup(pw);
pw.flush();
}
};
}
/**
* RequestFilter UTF-8编码
*
* @param requestGlobals
* @return
*/
public RequestFilter buildUtf8Filter(@InjectService("RequestGlobals")
final RequestGlobals requestGlobals) {
return new RequestFilter() {
public boolean service(Request request, Response response, RequestHandler handler) throws IOException {
requestGlobals.getHTTPServletRequest().setCharacterEncoding("UTF-8");
return handler.service(request, response);
}
};
}
/**
* contributeRequestHandler Utf8Filter
*
* @param configuration
* @param timingFilter
* @param encodingFilter
*/
public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration, @InjectService("Utf8Filter")
final RequestFilter encodingFilter) {
configuration.add("Utf8Filter", encodingFilter);
// configuration.add("TimingFilter", timingFilter);
}
/**
* 扩展binding source,实现一个list的绑定.
*
* @param configuration
* @param bindingSource
*/
public static void contributeBindingSource(MappedConfiguration<String, BindingFactory> configuration, BindingSource bindingSource) {
configuration.add("list", new ListBindingFactory(bindingSource));
}
public void contributeMasterDispatcher(OrderedConfiguration<Dispatcher> configuration, PageRenderRequestHandler pageRenderRequestHandler, ComponentClassResolver componentClassResolver,
@Symbol("tapestry.start-page-name")
String startPageName, @InjectService("PageResponseRenderer")
PageResponseRenderer pageResponseRenderer) {
class RootPathDispatcherFix implements Dispatcher {
private final ComponentClassResolver _componentClassResolver;
private final PageRenderRequestHandler _handler;
@SuppressWarnings("unused")
private final PageResponseRenderer _renderer;
private final String _startPageName;
private final String[] _emptyContext = new String[0];
public RootPathDispatcherFix(final ComponentClassResolver componentClassResolver, final PageRenderRequestHandler handler, final PageResponseRenderer renderer, final String startPageName) {
_componentClassResolver = componentClassResolver;
_handler = handler;
_renderer = renderer;
_startPageName = startPageName;
}
public boolean dispatch(Request request, final Response response) throws IOException {
// Only match the root path
if (!request.getPath().equals("/"))
return false;
if (_componentClassResolver.isPageName(_startPageName)) {
ActionResponseGenerator responseGenerator = _handler.handle(_startPageName, _emptyContext);
if (responseGenerator != null)
responseGenerator.sendClientResponse(response);
return true;
}
return false;
}
}
// Looks for the root path and renders the start page
configuration.add("RootPathFix", new RootPathDispatcherFix(componentClassResolver, pageRenderRequestHandler, pageResponseRenderer, startPageName), "before:RootPath");
}
// handle RedirectException
/**
* 异常处理
*/
public static RequestExceptionHandler decorateRequestExceptionHandler(final Object delegate, final Response response, final RequestPageCache requestPageCache, final LinkFactory linkFactory,
final ComponentClassResolver resolver) {
return new RequestExceptionHandler() {
public void handleRequestException(Throwable exception) throws IOException {
// check if wrapped
Throwable cause = exception;
if (exception.getCause() instanceof RedirectException) {
cause = exception.getCause();
}
// check for redirect
if (cause instanceof RedirectException) {
// check for class and string
RedirectException redirect = (RedirectException) cause;
Link pageLink = redirect.getPageLink();
if (pageLink == null) {
// handle Class (see ClassResultProcessor)
String pageName = redirect.getMessage();
Class<?> pageClass = redirect.getPageClass();
if (pageClass != null) {
pageName = resolver.resolvePageClassNameToPageName(pageClass.getName());
}
// handle String (see StringResultProcessor)
Page page = requestPageCache.get(pageName);
pageLink = linkFactory.createPageLink(page, false);
}
// handle Link redirect
if (pageLink != null) {
response.sendRedirect(pageLink.toRedirectURI());
return;
}
}
// no redirect so pass on the exception
((RequestExceptionHandler) delegate).handleRequestException(exception);
}
};
}
}4,编写FCKConfig.js(拷贝修改)
\src\main\resources\js\fckeditor\FCKConfig.js
内容:
FCKConfig.ToolbarSets["CommunityToolbarSet"] =
[
['Preview','-','Templates'],
['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],
['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
'/',
['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
['OrderedList','UnorderedList','-','Outdent','Indent'],
['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],
['Link','Unlink','Anchor'],
['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak'],
'/',
['Style','FontFormat','FontName','FontSize'],
['TextColor','BGColor'],
['FitWindow','-','About']
];
var FCKeditorAPI;
function InitializeAPI(){
var A = window.parent;
if (!(FCKeditorAPI = A.FCKeditorAPI)) {
var B = 'var FCKeditorAPI = {Version : "2.4.3",VersionBuild : "15657",__Instances : new Object(),GetInstance : function( name ){return this.__Instances[ name ];},_FormSubmit : function(){for ( var name in FCKeditorAPI.__Instances ){var oEditor = FCKeditorAPI.__Instances[ name ] ;if ( oEditor.GetParentForm && oEditor.GetParentForm() == this )oEditor.UpdateLinkedField() ;}this._FCKOriginalSubmit() ;},_FunctionQueue : {Functions : new Array(),IsRunning : false,Add : function( f ){this.Functions.push( f );if ( !this.IsRunning )this.StartNext();},StartNext : function(){var aQueue = this.Functions ;if ( aQueue.length > 0 ){this.IsRunning = true;aQueue[0].call();}else this.IsRunning = false;},Remove : function( f ){var aQueue = this.Functions;var i = 0, fFunc;while( (fFunc = aQueue[ i ]) ){if ( fFunc == f )aQueue.splice( i,1 );i++ ;}this.StartNext();}}}';
if (A.execScript)
A.execScript(B, 'JavaScript');
else {
if (FCKBrowserInfo.IsGecko10) {
eval.call(A, B);
}
else
if (FCKBrowserInfo.IsSafari) {
var C = A.document;
var D = C.createElement('script');
D.appendChild(C.createTextNode(B));
C.documentElement.appendChild(D);
}
else
A.eval(B);
};
FCKeditorAPI = A.FCKeditorAPI;
};
FCKeditorAPI.__Instances[FCK.Name] = FCK;
};
function _AttachFormSubmitToAPI(){
var A = FCK.GetParentForm();
if (A) {
FCKTools.AddEventListener(A, 'submit', FCK.UpdateLinkedField);
if (!A._FCKOriginalSubmit && (typeof(A.submit) == 'function' || (!A.submit.tagName && !A.submit.length))) {
A._FCKOriginalSubmit = A.submit;
A.submit = FCKeditorAPI._FormSubmit;
}
}
};
function FCKeditorAPI_Cleanup(){
delete FCKeditorAPI.__Instances[FCK.Name];
};
FCKTools.AddEventListener(window, 'unload', FCKeditorAPI_Cleanup);4,使用:
页面类中代码如下:
@Inject
@Path("classpath:/js/fckeditor/FCKConfig.js")
private Asset fckConfig;/**
*@returnReturnsthefckConfig.
*/
publicAssetgetFckConfig(){
returnfckConfig;
}tml文件代码如下:
<span t:type="fckeditor/" t:id="content" height="310px" width="100%" customConfiguration="fckConfig" toolbarSet="AppToolbarSet"/>
页面类中通过content获取对应内容
相关推荐
Kafka 2020-09-18
Wepe0 2020-10-30
windle 2020-10-29
mengzuchao 2020-10-22
Junzizhiai 2020-10-10
bxqybxqy 2020-09-30
风之沙城 2020-09-24
kingszelda 2020-09-22
大唐帝国前营 2020-08-18
yixu0 2020-08-17
TangCuYu 2020-08-15
xiaoboliu00 2020-08-15
songshijiazuaa 2020-08-15
xclxcl 2020-08-03
zmzmmf 2020-08-03
newfarhui 2020-08-03
likesyour 2020-08-01