<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1784528397507970143</id><updated>2011-06-08T11:02:21.237+02:00</updated><category term='getactionmessages'/><category term='file upload'/><category term='actionSupport'/><category term='no file'/><category term='syntax highlighting'/><category term='struts2'/><category term='blogger'/><category term='action message'/><category term='syntaxhighlighter'/><category term='FileUploadInterceptor'/><category term='syntax coloring'/><category term='blogspot'/><title type='text'>One step forward, two steps back</title><subtitle type='html'>...notes on painfully gaining experience by a J2EE newbie.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://annaskawinska.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://annaskawinska.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anna Skawińska</name><uri>http://www.blogger.com/profile/11821775244963132943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://bp1.blogger.com/_W0399CKKG2Q/SAiFU93w4UI/AAAAAAAAAAU/2hCYAYQAcQE/S220/at_work.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1784528397507970143.post-7070216913548901322</id><published>2008-04-22T16:58:00.011+02:00</published><updated>2008-12-10T03:47:22.829+01:00</updated><title type='text'>Extending a Struts2 theme</title><content type='html'>"Oh, so that's what a &lt;i&gt;theme&lt;/i&gt; is!" - I exclaimed in my mind when I finally found out why my jsp page didn't look as I expected. I had the &lt;code&gt;theme="simple"&lt;/code&gt; set in my &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; tag, as I had blindly copied it from some tutorial long ago, but expected the page to render as if it had the &lt;a href="http://struts.apache.org/2.x/docs/xhtml-theme.html"&gt;&lt;code&gt;xhtml&lt;/code&gt;&lt;/a&gt; theme applied.&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Struts2 themes&lt;/b&gt; are the Fairy Godmother who may turn a plain looking form made out of Struts2 tags to a full-fledged table. Or in general - they may decorate any struts2 tag it with any html you wish, using &lt;a href="http://freemarker.sourceforge.net/"&gt;Freemarker&lt;/a&gt; template engine.
&lt;br/&gt;&lt;br/&gt;For example, the &lt;code&gt;xhtml&lt;/code&gt; theme puts the &lt;code&gt;&amp;lt;s:form&amp;gt;&lt;/code&gt; tag into a table containing two columns: one holding labels, the other one holding inputs. Having a plain form like that:
&lt;textarea name="code" class="xml"&gt;
&lt;s:form action="User" method="post" &gt;
    &lt;s:textfield key="user.email" name="email" /&gt;
    &lt;s:password key="user.password" name="password" /&gt;
    &lt;s:submit key="button.register" /&gt;
&lt;/s:form&gt;
&lt;/textarea&gt;
will result in generating the following html:
&lt;textarea name="code" class="xml"&gt;
&lt;form id="User" name="User" onsubmit="return true;" action="/struts2/User.action" method="post"&gt;
&lt;table class="wwFormTable"&gt;
    &lt;tr&gt;

    &lt;td class="tdLabel"&gt;&lt;label for="User_email" class="label"&gt;Email Address:&lt;/label&gt;&lt;/td&gt;
    &lt;td
&gt;&lt;input type="text" name="email" value="" id="User_email"/&gt;
&lt;/td&gt;
&lt;/tr&gt;

    &lt;tr&gt;
    &lt;td class="tdLabel"&gt;&lt;label for="User_password" class="label"&gt;Password:&lt;/label&gt;&lt;/td&gt;
    &lt;td
&gt;&lt;input type="password" name="password" id="User_password"/&gt;
&lt;/td&gt;
&lt;/tr&gt;
    &lt;input type="hidden" name="emailId" value="" id="User_emailId"/&gt;

        &lt;tr&gt;
    &lt;td colspan="2"&gt;&lt;div align="right"&gt;&lt;input type="submit" id="User_button_register" name="button.register" value="Register"/&gt;
&lt;/div&gt;&lt;/td&gt;
&lt;/tr&gt;   

&lt;/table&gt;&lt;/form&gt;
&lt;/textarea&gt;
It's the xhtml theme, too, who is responsible for rendering form validation errors next to the appropriate fields. Before I learned this, I had been experimenting furiously with my simple-themed form, wondering where my validation messages go!
&lt;br/&gt;&lt;br/&gt;
Well, at least I've found them :). But setting my form's theme to xhtml wasn't really appealing to me. I'd have to rearrange it completely, as I have already designed it as a table. Still, I wanted the errors to appear next to the erroneous fields.&lt;br/&gt;&lt;br/&gt;
Encouraged by &lt;a href="http://www.vitarara.org/cms/struts_2_cookbook/creating_a_theme"&gt;Mark Menard's great post&lt;/a&gt;, I decided to extend the Struts2's &lt;code&gt;simple&lt;/code&gt; theme. Nah, just tweak it a little bit, to be honest.&lt;br/&gt;&lt;br/&gt;
So I started with downloading the original &lt;code&gt;simple&lt;/code&gt; theme from &lt;a href="http://svn.apache.org/repos/asf/struts/struts2/trunk/core/src/main/resources/template/simple"&gt;Struts2's repository&lt;/a&gt; and copying it to my application under the name &lt;code&gt;fieldError&lt;/code&gt;. In Maven2's directory tree, it went in &lt;code&gt;src\main\resources\template\fieldError&lt;/code&gt;. I then replaced the &lt;code&gt;text.ftl&lt;/code&gt; file with the one from &lt;code&gt;xhtml&lt;/code&gt; theme - this is the template responsible for decorating &lt;code&gt;&amp;lt;s:textarea&amp;gt;&lt;/code&gt; tag. If you look inside it you'll see all it does is "calling" three other templates - &lt;code&gt;controlheader.ftl&lt;/code&gt;, &lt;code&gt;text.ftl&lt;/code&gt; from the simple theme and &lt;code&gt;controlfooter.ftl&lt;/code&gt;. These templates in turn extend other templates - and if you dig in, it becomes clear that all the error handling logic resides in &lt;code&gt;controlheader-core.ftl&lt;/code&gt;. This is the fragment that interests us the most:
&lt;textarea name="code" class="xml"&gt;
&lt;#assign hasFieldErrors = parameters.name?exists &amp;&amp; fieldErrors?exists &amp;&amp; fieldErrors[parameters.name]?exists/&gt;
&lt;#if hasFieldErrors&gt;
&lt;#list fieldErrors[parameters.name] as error&gt;
&lt;tr errorFor="${parameters.id}"&gt;
&lt;#if parameters.labelposition?default("") == 'top'&gt;
    &lt;td align="left" valign="top" colspan="2"&gt;&lt;#rt/&gt;
&lt;#else&gt;
    &lt;td align="center" valign="top" colspan="2"&gt;&lt;#rt/&gt;
&lt;/#if&gt;
        &lt;span class="errorMessage"&gt;${error?html}&lt;/span&gt;&lt;#t/&gt;
    &lt;/td&gt;&lt;#lt/&gt;
&lt;/tr&gt;
&lt;/#list&gt;
&lt;/#if&gt;
&lt;/textarea&gt;
Even if you're as much a Freemarker ignoramus as I am, it should be clear, that in the snippet there is a check if there are are errors and then - some kind of iteration. In each iteration there's a table row being rendered. I'm not into having any additional cells in my table, though - say, a html list would do. So here's what I replaced this fragment with:
&lt;textarea name="code" class="xml"&gt;
&lt;#--
 Only show message if errors are available.
 This will be done if ActionSupport is used.
--&gt;
&lt;#assign hasFieldErrors = parameters.name?exists &amp;&amp; fieldErrors?exists &amp;&amp; fieldErrors[parameters.name]?exists/&gt;
&lt;#if hasFieldErrors&gt;
&lt;ul errorFor="${parameters.id}"&gt;
&lt;#list fieldErrors[parameters.name] as error&gt;
    &lt;li&gt;&lt;#rt/&gt;
        &lt;span class="errorMessage"&gt;${error?html}&lt;/span&gt;&lt;#t/&gt;
    &lt;/li&gt;&lt;#lt/&gt;
&lt;/#list&gt;
&lt;/ul&gt;
&lt;/#if&gt;
&lt;/textarea&gt;
Just one more thing and we're done. When I tried to run the app at this point, I got a message from Freemarker who was confused as of where to look for the templates. So I had to inform him of that in my &lt;code&gt;struts.xml&lt;/code&gt; file:
&lt;textarea name="code" class="xml"&gt;
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd"&gt;
&lt;struts&gt;
  &lt;!-- other constants --&gt;
  &lt;constant name="struts.ui.templateDir" value="template"&gt;&lt;/constant&gt;
  &lt;include file="offerings.xml"/&gt; 
&lt;/struts&gt;
&lt;/textarea&gt;
The entire directory with &lt;code&gt;simple&lt;/code&gt; theme also needs to be copied to the &lt;code&gt;template&lt;/code&gt; directory so that Freemarker can include them:&lt;br/&gt;
&lt;pre&gt;
src
  +main
    +resources
       +template
          +simple
          +fieldError
&lt;/pre&gt;

We can now start using the new template:
&lt;textarea name="code" class="xml"&gt;
 &lt;s:form action="Register!doInsert" theme="fieldError" method="post"&gt; 
 &lt;table&gt;&lt;tr&gt;
  &lt;th&gt;
   &lt;s:label key="getText('company.name')"/&gt;
  &lt;/th&gt;&lt;td&gt;   
   &lt;s:textfield name="company.name"  /&gt;
  &lt;/td&gt;
 &lt;/tr&gt;&lt;tr&gt;
  &lt;th&gt;
   &lt;s:label key="getText('company.email')"/&gt;
  &lt;/th&gt;&lt;td&gt;   
   &lt;s:textfield name="company.user.username"  /&gt;
  &lt;/td&gt;
 &lt;/tr&gt;&lt;tr&gt;
  &lt;th&gt;
   &lt;s:label key="getText('company.password')"/&gt;
  &lt;/th&gt;&lt;td&gt;
   &lt;s:textfield name="company.user.password" value=""/&gt;
  &lt;/td&gt;
 &lt;/tr&gt;&lt;tr&gt;
  &lt;th&gt;
   &lt;s:label key="getText('company.password.retype')"/&gt;
  &lt;/th&gt;&lt;td&gt;
   &lt;s:textfield name="reTypePassword" value=""/&gt;
  &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
  &lt;td class="buttonbar" colspan="2"&gt;
       &lt;s:submit cssClass="button" key="button.save"/&gt;
       &lt;s:submit cssClass="button" key="button.cancel" name="redirect-action:OfferingsList"/&gt;
     &lt;/td&gt;
 &lt;/tr&gt;&lt;/table&gt; 
 &lt;/s:form&gt;
&lt;/textarea&gt;
And the result is following:
&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_W0399CKKG2Q/SBBDGG2LgmI/AAAAAAAAAAw/nE4in4-biTc/s1600-h/blog.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_W0399CKKG2Q/SBBDGG2LgmI/AAAAAAAAAAw/nE4in4-biTc/s320/blog.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5192724142554317410" /&gt;&lt;/a&gt;
&lt;a href="http://sinpi.net/anu/download/template.zip"&gt;Here's&lt;/a&gt; the entire &lt;code&gt;template&lt;/code&gt; directory for you to download.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1784528397507970143-7070216913548901322?l=annaskawinska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://annaskawinska.blogspot.com/feeds/7070216913548901322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1784528397507970143&amp;postID=7070216913548901322' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/7070216913548901322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/7070216913548901322'/><link rel='alternate' type='text/html' href='http://annaskawinska.blogspot.com/2008/04/extending-struts2-theme.html' title='Extending a Struts2 theme'/><author><name>Anna Skawińska</name><uri>http://www.blogger.com/profile/11821775244963132943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://bp1.blogger.com/_W0399CKKG2Q/SAiFU93w4UI/AAAAAAAAAAU/2hCYAYQAcQE/S220/at_work.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_W0399CKKG2Q/SBBDGG2LgmI/AAAAAAAAAAw/nE4in4-biTc/s72-c/blog.png' height='72' width='72'/><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1784528397507970143.post-4805560411933020998</id><published>2008-04-21T14:42:00.006+02:00</published><updated>2008-04-21T15:49:41.143+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='no file'/><category scheme='http://www.blogger.com/atom/ns#' term='file upload'/><category scheme='http://www.blogger.com/atom/ns#' term='action message'/><category scheme='http://www.blogger.com/atom/ns#' term='struts2'/><category scheme='http://www.blogger.com/atom/ns#' term='FileUploadInterceptor'/><category scheme='http://www.blogger.com/atom/ns#' term='getactionmessages'/><category scheme='http://www.blogger.com/atom/ns#' term='actionSupport'/><title type='text'>Struts2, uploading a null file and disappearing ActionMessages</title><content type='html'>There are two small errors I found in my Struts2 app today. Two little sneaky bastards, caused by my inattention, and perhaps insufficient documentation of Struts2. I'd like to post them both, in case it saves some other newbie's day.
&lt;br/&gt;&lt;br/&gt;
The first one concerns the use of the &lt;a href="http://struts.apache.org/2.0.6/struts2-core/apidocs/org/apache/struts2/interceptor/FileUploadInterceptor.html"&gt;&lt;code&gt;FileUploadInterceptor&lt;/code&gt;&lt;/a&gt;. It's a really handy class that manages uploading a file from your webapp's form. It's a part of the &lt;code&gt;defaultStack&lt;/code&gt;, so all you need to enable the file upload is one  &lt;code&gt;s:file&lt;/code&gt; tag on your jsp, and a bunch of getters/setters in your Action class, which will allow you to access the uploaded file, already residing on the server. It's all described in details on &lt;a href="http://www.roseindia.net/struts/struts2/struts-2-file-upload.shtml"&gt;RoseIndia&lt;/a&gt;.
&lt;br/&gt;&lt;br/&gt;
However, what I haven't found in any of the example code snippets, is checking whether the user has chosen a file at all. In the case of my application, uploading a company's logo is not mandatory - so I needed a test before loading the image, checking whether there's any file being uploaded. So what did I do? Let's see: the &lt;code&gt;FileUploadInterceptor&lt;/code&gt; fills in three properties of my action:
&lt;textarea name="code" class="java"  rows="15"&gt;
public class CompanyAction extends BaseOfferingsAction implements Preparable {
 private File pic; // the actual file
 private String picContentType;
 private String picFileName;
 public File getPic() {
  return pic;
 }
 /**
  * Allows the FileUploadInterceptor to set the contents 
  * of the uploaded file
  * @param pic the actual file
  */
 public void setPic(File pic) {
  this.pic = pic;
 }

 public String getPicContentType() {
  return picContentType;
 }
 /**
  * Allows the FileUploadInterceptor to set the content type
  * of the uploaded file
  * @param picContentType content type description
  */
 public void setPicContentType(String picContentType) {
  this.picContentType = picContentType;
 }

 public String getPicFileName() {
  return picFileName;
 }
 /**
  * Allows the FileUploadInterceptor to set the name 
  * of the uploaded file
  * @param picFileName absolute path of the uploaded file
  * after it's been transferred onto server
  */
 public void setPicFileName(String picFileName) {
  this.picFileName = picFileName;
 }

}
&lt;/textarea&gt;
&lt;br/&gt;&lt;br/&gt;
Well, if the &lt;code&gt;File pic&lt;/code&gt; references the actual file, I simply checked whether it was null:
&lt;textarea name="code" class="java"&gt;
// if picture is being sent, convert it to Hibernate-compatible
// java.sql.Blob type to save it to database
if (pic != null){
 FileInputStream fis = new FileInputStream(pic);  
 Blob b = Hibernate.createBlob(fis);
 company.setLogo(b);
}
&lt;/textarea&gt;
...which didn't prove to be a good idea. &lt;code&gt;pic&lt;/code&gt; just kept on containing a reference to a nonexistent temp file. At first I thought the &lt;code&gt;params&lt;/code&gt; interceptor somehow "forgot" to set it to null, if a file had been transferred previously. However, this was not the case. Every time the filename was different, but it &lt;b&gt;was&lt;/b&gt; there. What's the solution, then?&lt;br/&gt;&lt;br/&gt;
It seems that the other two properties aren't there without purpose. Apparently, 
&lt;code&gt;FileUploadInterceptor&lt;/code&gt; works this way: every time it runs, it generates a   file name and creates a &lt;code&gt;File&lt;/code&gt; object for it, no matter if a file is actually being uploaded. That's a normal behavior. What I should have done is checking the &lt;code&gt;String picFileName&lt;/code&gt; property, which is empty if there's nothing being sent, like this:
&lt;textarea name="code" class="java"&gt;
// if picture is being sent, convert it to Hibernate-compatible
// java.sql.Blob type to save it to database   
if (picFileName!=null &amp;&amp; !"".equals(picFileName)){
 FileInputStream fis = new FileInputStream(pic);  
 Blob b = Hibernate.createBlob(fis);
 company.setLogo(b);  
}   

cService.update(company);
&lt;/textarea&gt;That's it, worked like a charm. Still, I find it a little misleading and think the javadocs of &lt;a href="http://struts.apache.org/2.0.6/struts2-core/apidocs/org/apache/struts2/interceptor/FileUploadInterceptor.html"&gt;&lt;code&gt;FileUploadInterceptor&lt;/code&gt;&lt;/a&gt;  lack a suitable warning.
&lt;/br&gt;&lt;/br&gt;
The other mistake of mine was while setting the &lt;code&gt;ActionMessages&lt;/code&gt; of my action which extends the Struts2's built-in &lt;a href="http://struts.apache.org/2.0.6/struts2-core/apidocs/com/opensymphony/xwork2/ActionSupport.html"&gt;ActionSupport&lt;/a&gt;. There it is, down in black and white:
&lt;blockquote&gt;getActionMessages

public Collection getActionMessages()

    Description copied from interface: ValidationAware
    Get the Collection of Action-level messages for this action. &lt;b&gt;Messages should not be added directly here, as implementations are free to return a new Collection or an Unmodifiable Collection.&lt;/b&gt;
&lt;/blockquote&gt;
...and so it does. Trying to do:
&lt;textarea name="code" class="java"&gt;
getActionMessages().add(getText("company.message.updateok"));
&lt;/textarea&gt;
resulted in my message "disappearing" in the always empty collection. Man, that felt creepy! ;) It's a pity I haven't noticed this method before:
&lt;textarea name="code" class="java"&gt;
addActionMessage(getText("company.message.updateok"));
&lt;/textarea&gt;
but there's no way I could blame the missing documentation this time - just me and my blondishness :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1784528397507970143-4805560411933020998?l=annaskawinska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://annaskawinska.blogspot.com/feeds/4805560411933020998/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1784528397507970143&amp;postID=4805560411933020998' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/4805560411933020998'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/4805560411933020998'/><link rel='alternate' type='text/html' href='http://annaskawinska.blogspot.com/2008/04/there-are-two-small-errors-i-found-in.html' title='Struts2, uploading a null file and disappearing ActionMessages'/><author><name>Anna Skawińska</name><uri>http://www.blogger.com/profile/11821775244963132943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://bp1.blogger.com/_W0399CKKG2Q/SAiFU93w4UI/AAAAAAAAAAU/2hCYAYQAcQE/S220/at_work.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1784528397507970143.post-8477709620967842580</id><published>2008-04-19T01:42:00.015+02:00</published><updated>2008-04-19T13:30:40.548+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blogger'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax coloring'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax highlighting'/><category scheme='http://www.blogger.com/atom/ns#' term='blogspot'/><category scheme='http://www.blogger.com/atom/ns#' term='syntaxhighlighter'/><title type='text'>SyntaxHighlighter on Blogger</title><content type='html'>Ironically, my first reasonable post here is going to cover Blogspot itself.&lt;br/&gt;&lt;br/&gt;

When I decided to set up a blog, one of the few things I knew it should have was a nice syntax coloring script. The most powerful one I've seen so far is &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;SyntaxHighlighter&lt;/a&gt;, which not only features coloring as such, but also displays the code in a neat, scrollable box with actual &lt;u&gt;line numbering&lt;/u&gt;. Now that's a killer!&lt;br/&gt;&lt;br/&gt;

However, wiring SyntaxHighlighter to your Blogspot site does take some doing. Especially if you tend to thoughtlessly copy someone else's code :)&lt;br/&gt;&lt;br/&gt;

First of all, Blogspot doesn't allow &lt;code&gt;link&lt;/code&gt; tag in your posts. Which is where I put it, having simply copied the sample code from the &lt;a href="http://code.google.com/p/syntaxhighlighter/wiki/Usage"&gt;Usage&lt;/a&gt; page.&lt;br/&gt;&lt;br/&gt;

Luckily, if you go to Layout -&gt; Edit HTML pane, you may edit your blog's template in an XML format. That's where you need to find the &lt;code&gt;head&lt;/code&gt; section and insert the link to your css.&lt;br/&gt;&lt;br/&gt;

Right, the link. Our friends at Blogspot haven't provided for uploading any external files like scripts or CSS, so you either have to host them somewhere else or manually insert the CSS in the CSS section of the Blogger's template. I opted for the latter, courtesy of &lt;a href="http://sinpi.net/"&gt;my dearest Bro&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;

To get SyntaxHighlighter to work, you still need to call some JavaScript functions as well as import a Flash file. I'm pretty unlikely to be blogging about my love life, rather programming issues, so I'll probably include some code on a regular basis. Having to paste those &lt;code&gt;script&lt;/code&gt; lines every time I do it would be an overhead. (My brother deleting the linked scripts is a hazard, too). Thus placing as well the &lt;code&gt;script&lt;/code&gt; includes in the template seems to be a good idea.&lt;br/&gt;&lt;br/&gt;

So you think we've got the syntax coloring configured? Surprise. If you insert some code to your blog, you'll find the &lt;&lt;code&gt;pre&gt;&lt;/code&gt; or &lt;&lt;code&gt;textarea&lt;/code&gt;&gt; contain one line only, with some nasty &lt;code&gt;br&lt;/code&gt; tags in them. Bad, bad Blogger, converting all line breaks into &lt;code&gt;br&lt;/code&gt; tags, even in Html mode! Fortunately there are two solutions to this. Either you disable the "Convert line breaks" option in Settings -&gt; Formatting pane, or you can resort to &lt;a href="http://code.google.com/p/syntaxhighlighter/wiki/BloggerMode"&gt;"blogger mode"&lt;/a&gt;, already implemented in SyntaxHighlighter. Well, &lt;a href="http://quainttech.blogspot.com/2007/04/syntax-highlighting-on-blogger.html"&gt;thanks guys for pointing that out&lt;/a&gt; - nothing is obvious at 2 AM...&lt;br/&gt;&lt;br/&gt;

Just two more hints, in case you've stayed up late as I have:&lt;br/&gt;&lt;br/&gt;

1. The syntax of JavaScript doesn't involve any funny question marks. If you find any in your code, you've probably copied it from a Wiki along with the camel case escape characters.&lt;br/&gt;&lt;br/&gt;

2. If you want test the coloring on your Java code, include &lt;code&gt;shBrushJava.js&lt;/code&gt; instead of the sample &lt;code&gt;shBrushCSharp.js&lt;/code&gt;.&lt;br/&gt;&lt;br/&gt;

So, let's give it a try. These are the vital snippets from my template xml:&lt;br/&gt;&lt;br/&gt;

&lt;textarea name="code" class="xml"&gt;&amp;lt;head&amp;gt;&lt;br /&gt;
&lt;b:include data="'blog'" name="'all-head-content'/"&gt;&lt;br /&gt;
&amp;lt;link href="'http://sinpi.net/anu/dp.SyntaxHighlighter/Styles/SyntaxHighlighter.css'" rel="'stylesheet'" type="'text/css'/"&amp;gt;&lt;br /&gt;
 &amp;lt;title&amp;gt;&lt;data:blog.pagetitle/&gt;&amp;lt;/title&amp;gt;&lt;br /&gt;  &lt;b:skin&gt;
&lt;![CDATA[/* ----------------------------------------------- Blogger Template Style Name:     Rounders 4 /** (...) */ ]]&gt;&lt;br /&gt;
&lt;!-- (...) --&gt;&lt;br /&gt;&lt;br /&gt;
&amp;lt;script language='javascript' src='http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shCore.js'/&amp;gt; 
&amp;lt;script language='javascript' src='http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shBrushJava.js'/&amp;gt;
&amp;lt;script language='javascript' src='http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shBrushXml.js'/&amp;gt;
&amp;lt;script language='javascript'&amp;gt;
dp.SyntaxHighlighter.ClipboardSwf = 'http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/clipboard.swf';
dp.SyntaxHighlighter.HighlightAll('code');
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/textarea&gt;&lt;br/&gt;&lt;br/&gt;

Let's see how this renders... ;)
&lt;br/&gt;&lt;br/&gt;
PS. Oddly enough, the textarea containing code gets doubled on the main page, while all is as expected if you follow the entry's link. No clue why this happens. Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1784528397507970143-8477709620967842580?l=annaskawinska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://annaskawinska.blogspot.com/feeds/8477709620967842580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1784528397507970143&amp;postID=8477709620967842580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/8477709620967842580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/8477709620967842580'/><link rel='alternate' type='text/html' href='http://annaskawinska.blogspot.com/2008/04/syntaxhighlighter-on-blogger.html' title='SyntaxHighlighter on Blogger'/><author><name>Anna Skawińska</name><uri>http://www.blogger.com/profile/11821775244963132943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://bp1.blogger.com/_W0399CKKG2Q/SAiFU93w4UI/AAAAAAAAAAU/2hCYAYQAcQE/S220/at_work.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1784528397507970143.post-1599708137600203984</id><published>2008-04-10T11:31:00.024+02:00</published><updated>2008-04-19T01:41:01.183+02:00</updated><title type='text'>Test...</title><content type='html'>Which is, actually, a common misuse of the term 'test'.

&lt;p&gt;HTML:&lt;/p&gt;
&lt;textarea name="code" class="html" cols="60" rows="10"&gt;

BEGIN --- This is the example code:
&lt;script language="javascript" src="Scripts/shCore.js"&gt;&lt;/script&gt; &lt;script language="javascript" src="Scripts/shBrushCSharp.js"&gt;&lt;/script&gt; &lt;script language="javascript" src="Scripts/shBrushXml.js"&gt;&lt;/script&gt; &lt;script language="javascript"&gt; dp.SyntaxHighlighter.ClipboardSwf = 'Scripts/clipboard.swf'; dp.SyntaxHighlighter.HighlightAll('code'); &lt;/script&gt;

END --- This is the example code:

&lt;/textarea&gt;



&lt;p&gt;Java:&lt;/p&gt;
&lt;textarea name="code"  class="java" cols="60" rows="10"&gt;
package pl.annaskawinska.offerings.dao;


import java.util.List;

import pl.annaskawinska.model.Category;
import pl.annaskawinska.model.Company;
import pl.annaskawinska.model.Offering;


/**
 * Universal Data Access Object (DAO) interface for persistence of
 * any object of Type with an id of ID type
 *
 */
public interface IDao&lt;Type, ID&gt;{
 
 public void update( Type entity);
 public List&lt;Type&gt; getAll(); 
 
 public Type getById(ID id);
 public List&lt;Type&gt; findByExample(Type exampleInstance);
    
    public void delete( Type entity);
   
    
}

&lt;/textarea&gt;

&lt;script language="javascript" src="http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shCore.js"&gt;&lt;/script&gt; &lt;script language="javascript" src="http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shBrushCSharp.js"&gt;&lt;/script&gt; &lt;script language="javascript" src="http://sinpi.net/anu/dp.SyntaxHighlighter/Scripts/shBrushXml.js"&gt;&lt;/script&gt; &lt;script language="javascript"&gt; dp.SyntaxHighlighter.ClipboardSwf = 'Scripts/clipboard.swf'; dp.SyntaxHighlighter.HighlightAll('code'); &lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1784528397507970143-1599708137600203984?l=annaskawinska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://annaskawinska.blogspot.com/feeds/1599708137600203984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1784528397507970143&amp;postID=1599708137600203984' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/1599708137600203984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1784528397507970143/posts/default/1599708137600203984'/><link rel='alternate' type='text/html' href='http://annaskawinska.blogspot.com/2008/04/test.html' title='Test...'/><author><name>Anna Skawińska</name><uri>http://www.blogger.com/profile/11821775244963132943</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://bp1.blogger.com/_W0399CKKG2Q/SAiFU93w4UI/AAAAAAAAAAU/2hCYAYQAcQE/S220/at_work.jpg'/></author><thr:total>1</thr:total></entry></feed>
