ZK CodePress

From Documentation
ZK CodePress

Author
Thomas Müller, Software Architect, empego.net, Germany
Date
January 7, 2008
Version

Motivation

I'm working on a multi site content management system based on ZK, which supports to import existing CSS/HTML templates. The files of a template can be uploaded to the website directory or the content of the files can be stored in the database. Both ways to store templates are supported in parallel. To simplify the workflow, templates are editable at server side with a ZK based WEB frontend. To make it more comfortable the necessity for a source code editor with syntax highlighting came up and I found CodePress. CodePress is a Real Time Syntax Highlighting Editor written in JavaScript which supports csharp, css, generic, html, java, javascript, perl, ruby, php, text, sql, vbscript. You can configure CodePress to be readonly, to show linenumbers and to provide autocomplete. With motivation from Tom Yeh and help from Jumper Chen I created a ZK CodePress component. Code snippets are used from FZKeditor and other component creation smalltalks.


Usage of ZK CodePress

The ZK codepress components supports the configuration parameters as single attributes. You could assign language (String), linenumbers (boolean), readonly (boolean), autocomplete (boolean) to a codepress editor by the corresponding properties. You can specify width and height in the style attribute and set the value with the sourcecode to edit. The CodePress API does not provide events for developers, so codepress needs some components beside to generate the onChange event by a callback mechanism, which can be simply a button as shown in the test zul code below.

<?xml version="1.0" encoding="UTF-8"?>
<zk>
  <zscript>
    languages = org.zkforge.codepress.Codepress.getLanguages();

    changeLanguage(){ 
      codepress.language = languageSelector.selectedItem.label; 
      codepress.invalidate(); 
    }
  </zscript>

  <button label="Copy from Codepress"
    onClick="copy.value = codepress.value" />
  <button label="Copy to Codepress" onClick="codepress.value = copy.value; codepress.invalidate();" />
  
  <listbox id="languageSelector" rows="1" mold="select" onSelect="changeLanguage();">
    <listitem label="${each}" forEach="${languages}" selected="true"/>
  </listbox>
  <codepress id="codepress" language="zul" style="width:100%; height:200px;">
    <attribute name="value"><![CDATA[
    
<textbox id="copy" style="width:100%; height:200px;"rows="20" />
<zscript>
  changeLanguage(){ codepress.language =
  languageSelector.selectedItem.label;
  codepress.invalidate(); }
</zscript>

    ]]></attribute>
  </codepress>
  <textbox id="copy" style="width:100%; height:200px;" rows="20" />

</zk>


This starts a ZK codepress sourcecode editor. The button "Copy from Codepress" triggers the onChange event of codepress to get the code up to the server side and copy the code then to the textbox. With the select listbox you can change the sourcecode language of the editor.

Example1.gif


To get it running simply copy the codepress.jar to your WEB-INF/lib directory and restart your servlet engine. A livedemo is installled on http://codepressdemo.empego.net/ .

Making of ZK CodePress

As mentionesd in some other component creation smalltalks at least 4 files have to be created:

  • langaddon.xml - to let zk know about the new component
  • codepress.dsp - the template of the generated HTML
  • Codepress.java - the server side representation of the component
  • codepressz.js - the integration of the CodePress API in ZK

Further more some minor modifications have to be done in the original CodePress API codepress.js file. To support syntax highlighting for the ZUL syntax, additional language files (zul.css and zul.js) have been created. The language files are copies of the HTML language files with minor changes and should be improved in future.

CodePress expects a HTML textarea with configuration parameters in the class attribute:

<textarea id="myCpWindow" class="codepress javascript linenumbers-off">
   // your code here
</textarea>

So the codepressz.dsp files looks like:

<%@ taglib uri="/WEB-INF/tld/web/core.dsp.tld" prefix="c" %>
<c:set var="self" value="${requestScope.arg.self}"/>
<c:set var="edid" value="${self.uuid}!ed"/>
<textarea id="${self.uuid}"${self.outerAttrs} z.type="codepressz.codepressz.Codepress"
${c:attr('class',self.options)}${c:attr('style',self.style)}>
${c:escapeXML(self.value)}
</textarea>

The getOptions() function in Codepress.java composes the class attribute of the textarea from the configuration as expected from the CodePress API. A utility function getLanguages() returns a alphabethic sorted list of supported languages used in the above sample zul code to generate the language select listbox.

The codepressz.js creates the CodePress component and installs a callback eventlistener, which is always called, when another component of the desktop sends an event (since CodePress API itself does not support events... thanks to Jumper Chen for the hints...). The eventlistener compares the editor content with the textarea content and sends an onChange event for the CodePress component when differences are detected.


Download


Ruler.gif


Thomas Müller is a Software Architect for a Germany site called Empego.




Copyright © Thomas Müller. This article is licensed under GNU Free Documentation License.