blogging california england firefox glassfish google hacking j2ee java openid opensource roller skype soccer sun sunray thewaronliquid travel treo ubuntu vaio voip web2 work yahoo
Jun
6

I already touched on a neat feature of OpenID - you can have a plain old web page URI act as a proxy / alias for your openid. Well now the Sun OpenID IdP is up and running, I can test the theory.

Per the FAQ, you need to add a couple of lines to your web page - in the case of a Roller template this needs to be close to the outside of the HTML; in my case that's in the _decorator template. 

openid

OK, let's try it. First over to LiveJournal :

Click, over to the Sun IdP :


I type in my credentials and ...


Yes I do, and I'm in :

 


Yeah - it works !!
 

 

 

 

Jan
8

OK, I just tidied up the tag cloud code a bit; there's now some scaling to ensure the 'intensity' is sensible. The template code relies on some styles which set the font size and opacity.

    <div class="tagcloud">
       #set ( $maxtags = 25)

       #set($mytags = $model.weblog.getPopularTags(-1, $maxtags))

       #set($maxtagcount = 0)
       #set($mintagcount = 99999)

       ## number of styles s1-s10
       #set($steps = 10)

       ## determine min and max tag count so we can scale the fonts and opacity
       #foreach ($tag in $mytags)
          #if($tag.count > $maxtagcount)
             #set($maxtagcount=$tag.count)
          #end 
          #if($tag.count < $mintagcount)
             #set($mintagcount=$tag.count)
          #end 
       #end

       ## generate the link for each tag assigning style accordinly
       ## the styles : s1-s10 increase in font size and opacity   
       #foreach ($tag in $mytags)
          #set ($intensity=(${tag.count}-${mintagcount})*${steps}/(${maxtagcount}-${mintagcount}))
          <a class="tag s${intensity}"  href="$url.tag($tag.name)" 
             title="$tag.count entries">$tag.name</a>
       #end
    </div>
     
Relevant fragments from the stylesheet follow, first I set the abolsute position of the tag cloud then  reduce the line-height for effect. Then I define s1-s10, increasing the font size and opacity proportionally. The opacity requires different hacks for different browsers and I still don't think I have all the IE versions covered. Sigh.
   div.tagcloud
   {
      line-height:18px;
      position: absolute; 
      text-align: right; 
      top: 90px; 
      right: 20px;   
      left: 600px; 
   }

   .s1 {
     font-size:18px;
     filter:alpha(opacity=20); 
     filter:progid:DXImageTransform.Microsoft.Alpha(opacity=20);
     opacity:.2;
   }

Dec
27

The Christmas break gave me some time to play around with Roller's new tagging support - a feature I've been wanting for quite a while. I don't see any need for categories anymore so I've removed the Dojo-enabled category chooser and replaced it with a tag cloud. The code is simpler and it doesn't need a big wad of JavaScript to run. The only tricky bit is my choice to use transparent text (using CSS's opacity property) or rather the fact that as with most things you have to code for Mozilla and various versions of Explorer. I'll rant about that at some future point when I've debugged the Explorer CSS code a bit more.

The macro to get at the tags is $model.weblog.getPopularTags(a1, a2) - I've no idea what the first argument is but -1 seems to work; the second argument specifies the number of tags to return. There another entry you can use within a post that will display the tags associated with the post - #showEntryTags($entry) - unfortunately the resulting markup doesn't have any styles associated so I may need to override the macro and add some.

The one thing that's still bugging me is the default Roller pager (ie. the text that says "Main | Next page >>") - I'll need to customize that macro so it says something like "Latest | Older >" and ensure it sits in one of the CSS containers so I can control it's location easier.

At some point I'll post the code - but I'll need to tidy it up a little first and make it a smart enough to scale as tag counts increase.

Dec
3

A couple of months ago I added a category chooser that uses Dojo (a powerful JavaScript library) to create a Fisheye effect. So, somewhat belatedly and as promised here's the code and a bit of explanation. Note, this was pre-Roller 3.0 so uses some of the old Roller macros.

First, you need to pull in the right JS libraries. On blogs.sun.com - the Dojo library is installed under roller-ui/dojo.


<script type="text/javascript">
    var djConfig = {isDebug: true, debugAtAllCosts: false};
</script>
<script type="text/javascript" src="$url.absoluteSite/roller-ui/dojo/dojo.js"></script>
<script language="JavaScript" type="text/javascript">
    dojo.require("dojo.widget.FisheyeList");
    dojo.hostenv.writeIncludes();
</script>


Next is a little JS function to display a category :


<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
  function selectCategory(catname){
    var url;

    if (catname == 'All' ) {
      url="$url.home"
    }
    else {
      url="${url.home}category/"+catname
    }

    window.location.replace ( url );
  }
</SCRIPT>


Next you create the Dojo Fisheye component :


<div class="chooser">
    <div class="dojo-FisheyeList"
        dojo:itemWidth="110" dojo:itemHeight="40"
        dojo:itemMaxWidth="250" dojo:itemMaxHeight="90"
        dojo:orientation="horizontal"
        dojo:effectUnits="1"
        dojo:itemPadding="0"
        dojo:attachEdge="top"
        dojo:labelEdge="bottom"
        dojo:enableCrappySvgSupport="false" >

        <div class="dojo-FisheyeListItem" onClick="selectCategory('All');"
            dojo:iconsrc="$IMAGES/cat-All.png"
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('About Me');"
            dojo:iconsrc="$IMAGES/cat-AboutMe.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('Books');"
            dojo:iconsrc="$IMAGES/cat-Books.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('Roller');"
            dojo:iconsrc="$IMAGES/cat-Hacking.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('General');"
            dojo:iconsrc="$IMAGES/cat-General.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('Java');"
            dojo:iconsrc="$IMAGES/cat-Java.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('Home Life');"
            dojo:iconsrc="$IMAGES/cat-HomeLife.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('Gadgets');"
            dojo:iconsrc="$IMAGES/cat-Gadgets.png">
        </div>

        <div class="dojo-FisheyeListItem" onClick="selectCategory('W3');"
            dojo:iconsrc="$IMAGES/cat-W3.png">
        </div>
    </div>
</div>

You should make this code generic by iterating through the categories but you'd need to label your images consistently. The only reason I did this cut and paste iteration was to aid debugging. I'll tidy it up at some point.

All the code above is in the Weblog template - which I have uploaded here. You'll also need some CSS so I've uploaded my template here. Feel free to hack, use, abuse as you see fit but shoot me a mail or leave a comment if you make any useful improvements.

I'm well aware this doesn't work in MS IE - I have no idea why; and don't have the tools to debug it. As Dojo is browser independent (or claims to be) - the problem is likely mine. Leave a comment if you can see what is wrong.

Sep
6

[note for non-US readers - by pimped I mean - 'tricked out' or 'blingbling' as in Pimp My Ride - nothing to do with prostitution]

Recently, I managed to convince the nice folks that run blogs.sun.com to host the Dojo toolkit - which they did. Subsequently I've been meaning to find the time to add some Dojo widgets to this blog and finally got around to it - see the Fisheye Category chooser at the top of the page. Hold off with the feedback for now - this is just a first hack and I know it needs some buffing.

What I thought might take an hour or so took much longer. My initial inclination was to use a tabbed layout for the categories but I ran into considerable 'impedence mismatch' between Roller's model and Dojo's so I dropped it and went for the much less intrusive FishEye instead. The tabbed layout will be a much better fit for the right-hand nav bar (and save space too). There are some other layout containers that might be a good fit for actual entries.

I've noticed that the image scaling is rather sucky with Firefox but is much cleaner on IE - though on IE the whole thing is badly broken - sorry IE users - you'll need one of these :) - I probably need to experiment with larger image sizes but I was trying to keep them as lean as possible. Note - I used transparent PNGs (ie. they have no background) - that's a pretty neat Photoshop trick.

I'll post some code when it's been tidied up a bit

Technorati Tags: , , ,

Jul
28

To keep things clean and save space on The Aquarium - I compressed the entry timestamp like this :

This involved a simple trick - I simply extract the month and day in month parts of the timestamp then applied some styles - with a background image (the orange bit). I got the inspiration from here.

Here are the styles :

.ta-cal {
    display:block;
    float:left;
    width:44px;
    height:47px;
    background:url("http://blogs.sun.com/roller/resources/theaquarium/cal.gif") no-repeat;
    text-align:center;
    margin-top:-10px;
    margin-right:8px;
}

.ta-cal-month {
    color:#fff;
    font:bold 13px Arial, Verdana;
    text-transform:uppercase;
    margin:4px;
}

.ta-cal-day {
    color:#fff;
    font:bold 26px Arial, Verdana;
    margin:-10px 0 0 0;

}

I'm sure there;s some redundancy in there and don't doubt this could be simplified - but it works. The way you use them is nest the ta-cal-month and ta-cal-day styled elements inside the ta-cal styled element, eg.

 <div class="ta-cal">
      <div class="ta-cal-month">#formatDate ( "MMM" $day )</div>
      <div class="ta-cal-day">#formatDate ( "d" $day )</div>
 </div>

$day is provided by Roller and the handy #formatDate macro is used to extract various bits of the timestamp (using java.text.SimpleDateFormat patterns).

Technorati Tags:

Jul
23

Apologies for the mess.

I decided to give my blog a bit of a face-lift over the weekend but unfortunately ran out of time before I'd finished. Hopefully - I'll get it ship-shape over the next week (time permitting).

- Rich

Jul
21

I'm sharing some my experiences of hacking Roller templates in support of The Aquarium. Previous entries in the series :

Something I did recently was tidy up the _day template; I replaced some of the text links with icons and added icons for sending an entry to the reader's favourite social bookmarking service. Here's what the icons look like :

From left to right : del.icio.us, digg, Furl, simpy, Add or view comments and Edit the entry.

The comment and edit icons came from the Silk icons collection - which are very neat and very free.

OK, here's the code behind the icons. The tough part was understanding the request formats for each particular service - none of them are well documented so I had to hunt around a fair bit; which means youwon't have to (unless they change).

1  #macro ( entryButtons $entry )
2
3     #set ( $IMAGES = "http://blogs.sun.com/roller/resources/theaquarium/" )
4
5     #set ( $entryURL = "$absBaseURL/page/$userName?anchor=$entry.anchor" )
6     #set ( $commentCount = $pageModel.getCommentCount($entry.id) )
7
8     #if ( $commentCount == 1 )
9        #set($numCommentsStr="1 Comment")
10       #set($commentIcon="commentAdded.gif")
11    #elseif ($commentCount > 1)
12       #set($numCommentsStr="$commentCount Comments")
13       #set($commentIcon="commentAdded.gif")
14    #else
15       #set($numCommentsStr="No Comments")
16       #set($commentIcon="comment.gif")
17    #end
18
19    #set ( $catname = $entry.Category.Name )
20
21    <div class="ta-entry-footer">
22
23       <a href="http://del.icio.us/post?url=$entryURL;title=$entry.title">
24          <img src="$IMAGES/delicious.gif" title="Post to de.licio.us"></a>
25
26       <a href="http://digg.com/submit?phase=2&url=$entryURL&title=$entry.title">
27          <img src="$IMAGES/digg.png" title="Digg this entry"></a>
28
29       <a href="http://www.furl.net/storeIt.jsp?t=$entry.title&u=$entryURL=$entry.anchor">
30          <img src="$IMAGES/furl.png" title="Save to furl"></a>
31 
32        <a  href="http://www.simpy.com/simpy/LinkAdd.do?title=$entry.title&href=$entryURL=$entry.anchor">
33          <img src="$IMAGES/simpy-icon-16x16.png" title="Save to Simpy"></a>
34
35       <a href="$entryURL#comments">
36          <img src="$IMAGES/$commentIcon" title="$numCommentsStr"></a>
37
38
39       #if ($pageHelper.isUserAuthorizedToEdit())
40          <a href="$pageHelper.getEntryEditUrl($entry)">
41             <img src="$IMAGES/page_white_edit.png" title="Edit entry"></a>
42       #end
43
44    </div>
45 #end

OK, some of this requires a bit of an explanation, the macro takes one argument - the current $entry.

Lines 3-6 just define some convenient vars. to make the code a little less unreadable.

Lines 8-17 uses the comment count of the current entry to determine which icon to use (there's a different icon if comments already exist) as well as set the floatover text (which indicates the number of comments).

Lines 23-33 display the icons and form the URLs for each service - typically each service has a post / submit method followed by a title and URL parameter.

Lines 39-41 check to see if the current logged in user is authorized to edit entries and if so displays the edit button and link.

I also apply the following style :

.ta-entry-footer {
        margin: 15px 30px; 
        padding-bottom: 15px; 
        border-bottom: 5px 
}

That's it.

Jul
14

Previous entries in the series :


Before we dive into example code - a necessary preamble :

Disclaimer : If, as a result of following these tips or using this code, you break your blog, crash your machine or ruin your marriage - it's not my fault, or my employer's (Sun Microsystems).

License : You have my persmission to use, modify and re-distribute this code for fun, love or profit. If you improve it - please share the improvements.

Sorry about that.

Now some more practical advice - if you are using a hosted Roller and don't have access to the log files (like me) - debuging template hacks is a bitch. Often all you'll have to go on is a blank HTML page as a reult of your endeavours. So what I do (mostly) is  try the hacks out on a non-public server (we have internal Roller servers in Sun) and also use an XML aware editor (NetBeans) to avoid the simple (but generally catastrophic and hard to debug) missing quote / closing tag errors. As far as I can tell - Roller insulates markup problems pretty well - I don't think you can screw up other's blogs by hacking your templates so don't be too paranoid.

The Aquarium covers a lot of subjects so we have a lot of categories. At some point Roller will have true tagging support so our use of categories will diminish. I wanted to keep the main page fairly clean (the content being the focus) so I knocked up a little JavaScript pulldown menu, populated from The Aquarium's category list.

Roller template code is not nice, it mixes VTL (Velocity Template Language), JavaScript and HTML in a way that can be a bit hard on the eyes.

First the JavaScript handler :

<SCRIPT LANGUAGE="JavaScript" type="text/javascript">
   function selectCategory(catname){
   var url;
   #set( $blogURL = "$baseURL/page/$userName" )
   if (catname == "All" )
       {url="$blogURL" }
   else
       { url="$blogURL/?catname=/"+catname }
   window.location.replace ( url ); }
</SCRIPT>
Most of it is standard JavaScript but there's some VTL in there as well - the line that begins with "#" just defines a VTL variable which specifies the URL of the roller site. As you can see, string concatenation in VTL is pretty flexible but you do have to be aware of the various ways to escape VTL variables under certain circumstances. In this case nothing special is needed.

Next is a bit of VTL to build the category list :

<FORM style="margin:0;padding:0"> 
   <p><SELECT Id="categ" ONCHANGE="selectCategory(this.value)">
       <OPTION>--Select a Category--</OPTION>
       <OPTION value="All">All</OPTION>
           #set( $catlist = $pageModel.getWeblogCategories("/") )
           #foreach( $cat in $catlist )
               <OPTION value="$cat.Name">$cat.Name</OPTION>
           #end
   </SELECT></p>
</FORM>
Nothing too complex here -  I generally find the hardest bit is determining what information roller gives you access to; which is a lot. I haven't found a comprehensive list yet and usually resort to the Roller JavaDocs - things like $pageModel are just Java objects (beans) maintained by Roller (eg. you could equally well just call $cat.getName())

Anyway, you can throw this code into your Weblog template and it should work but to ensure the template is readable you'd probably want to turn it into a macro and hide it somewhere. Exactly how to do that I'll touch on some other time.


Jul
14

Inbetween my day job and family life I'm a contributing editor with The Aquarium. I'm also the 'webmaster'  - funny how, out of a group of super smart, senior engineers - the marketing guy ended up being the hacker :)

Anyway - I've invested a fair amount of time hacking Roller templates (Roller is the blogging software that powers blogs.sun.com among others) and thought it would be good to share some of my experiences here (where else but my Roller powered blog). I'm doing this for a number of reasons. Firstly - I didn't find many code fragments and samples on the web so I'd like to improve that situation; secondly - I really hacked some of this stuff together - I'm certain there are numerous better ways of doing some of these things - let me know.

OK, onto today's subject - what's a template and how to you modify it ?

Roller uses the Velocity template language which allows you to render Roller's object model onto your customized blog page. If you are familiar with JSP, PHP or other templating languages - nothing about Velocity will surprise you.

When you start out with Roller - you're going to be using an existing theme (there are 18 to choose from) and you access them under "Preference | Templates"



The first time you do this you won't see any templates because by default roller shares templates with other roller users until such time you need to modify your own local copy. I don't remember how Roller presents this but I seem to think it was pretty obvious what you have to do to get your own copy of the templates.

You'll now have a list of the templates. The exact list you'll see depends on which template you use. But the ones you're most likely to want to modify are Weblog and _day - these are standard templates that all themes require.



The _day template iterates through the blog entries for 1 day and presents them - so this is where you want to make changes the change the way blog entries are rendered.

The Weblog template is where you make changes to the site page (eg banners and side menus). Some templates may break this template into searate sub-templates to handle sidebars, headers and footers.

Another slightly interesting template is _decorator - (or it could be called _header) which wraps the Weblog template and defines things at the <head> / <body> level for your site. Eg. if you wanted to add <meta> tags or include stylesheets.

OK, that's a start - maybe some code next time.


Find it

Subscribe

Contact Me

My status

follow pixelfodder at http://twitter.com

Links

The Aquarium (from the source)

Images

sharps. Get yours at flagrantdisregard.com/flickr