At line 1 added 74 lines |
!! RIFE templates |
[RIFE|http://rifers.org] is pleasant in many ways, and ranks as a "very near miss" - like [Tapestry], it is one of the enlightened applications which allows pure HTML templating, but also, like Tapestry misses fire in making the structure of the templates somewhat baffling and containing "cryptic" (i.e. hiding in the gaps of the HTML structure) information. For example, here is a RIFE template, taken from chapter 4 of the user guide: |
|
{{{ |
<html> |
<head><title>Perform a guess</title></head> |
<body> |
<p>Guess a number from 0 to 100</p> |
<!--V 'warning'--><!--/V--> |
<!--B 'invalid'--> |
<p><font color="#990000">The guess is invalid.</font></p> |
<!--/B--> |
<p><i><!--V 'indication'--><!--/V--></i></p> |
<!--B 'lower'-->The answer is lower.<!--/B--> |
<!--B 'higher'-->The answer is higher.<!--/B--> |
<form action="[!V 'SUBMISSION:FORM:perform_guess'/]" method="post"> |
<!--V 'SUBMISSION:PARAMS:perform_guess'/--> |
<input type="text" name="guess" |
value="[!V 'PARAM:guess'][!/V]" /><br /> |
<input type="submit" value="Guess" /><br /> |
</form> |
<script language="javascript">document.forms[0].guess.focus();</script> |
</body> |
</html> |
}}} |
|
As you can see, RIFE uses a slightly offputting syntax for encoding special information in HTML/XML comments. Not only that, but you can see from the form of some of the entries, e.g. {{[[!V 'SUBMISSION:FORM:perform_guess'/]]}} and {{[[!V 'PARAM:guess']]}} that there is clearly some EL-like scheme to allow these entries to refer into a data model, which forever couples this presentation file with the logical structure of the app. Another issue is that the nesting model of the comments does not seem to be tied to the tag structure of the document - the parser has a somewhat Velocity-like ignorance of the content between its special markup. This may give some extra expressive power in awkward situations, but probably allows too much scope for accidental creation of invalid templates. However, the simpler entries are slightly reminiscent of the IKAT scheme, e.g. the "B" comments play the role of peers of RSF "leaf" components - {{<!--B 'lower'-->The answer is lower.<!--/B-->}} might be rendered in RSF as {{<div rsf:id="lower">The answer is lower</div>}}. |
|
As a general summary though, RIFE templates seem too fragile to be safely let loose in the hands of general HTML developers, and also do indeed couple presentation and logic together. |
|
!! RIFE ORM |
RIFE actually positions itself as a "one-stop shop" for web applications, in that it contains its own ORM infrastructure that could be seen to directly compete against standalone solutions such as Hibernate, JDO and IBatis. I haven't looked at the details, but this actually might be relatively nice - the syntax appears a "genericised", type-safe rendering very close to the underlying SQL, e.g. |
{{{ |
public void add(Friend friend) |
throws DatabaseException |
{ |
Insert insert = new Insert(getDatasource()); |
insert |
.into("Friend") |
.fieldsParameters(Friend.class); |
|
DbPreparedStatement insert_stmt = getPreparedStatement(insert); |
insert_stmt.setBean(friend); |
insert_stmt.executeUpdate(); |
} |
}}} |
I always felt that Hibernate just did "a little too much", and all one really wanted was a scheme, that, like this, simply automated the tedium of converting JDBCResultSets to and from POJOs, and abstracted over the obnoxious variety of SQL dialects. However, Hibernate proxying and laziness tricks do seem to offer powerful potential benefits in some scenarios... |
|
!! RIFE webapp |
|
RIFE falls down IMO in the global picture in being full of odd sorts of configuration files, and imposing dependence on the framework in too many parts of the code (Elements, Participants, etc.). |
e.g. this sort of code (taken from section 3.9 of the RIFE manual): |
|
{{{ |
import com.uwyn.rife.engine.Element; |
public class Guess extends Element { |
[[lines omitted]] |
public void processElement() |
{ |
Game game = Contest.getGame(getInput("gameid")); |
if (null == game) |
{ |
exit("start"); |
} |
|
mTemplate = getHtmlTemplate("guess"); |
[[lines omitted]] |
}}} |
firmly marks RIFE as one of the "1st-generation" "beanless" frameworks (in contrast to JSF and WebWorks). The {{getHtmlTemplate}} call marks a particularly egregious coupling. However, all this is moot in the face of the most marvellous invention, being ''[RIFE Continuations|RIFEContinuations]''. For code which implements a continuation it is quite acceptable to be coupled to a framework interface, since the code simply cannot function without framework support. Since the RIFE project has admirable unbundled its continuations library from the rest of its framework, and is being rapidly deployed throughout the community (WebWork announces support as of 9/2005). This part of the framework would also be a valuable and highly complementary asset to RSF. |
|
!!Comments |
Notes from Geert Bevin (Lead developer of RIFE) : RIFE is totally bean driven, but not solely so. This example is just one that doesn't use the bean-related features. Also, it supports both IoC and service lookup so that you can use what's the most appropriate for your situation. Templates (just like most things) can be injected through properties or looked up explicitly. This example just looks it up explicitly. |
|
Response from Antranig Basman : Thanks for the comments, and for dropping by, Geert. My point about the "template" issue is that whether injected or looked up, the manipulation of the template still marks a serious framework coupling since it is being done through direct coding. In general I find that one can't become any kind of RIFE citizen without at least becoming an "Element", and even the "bean-driven" example, the "Friends listing" app doesn't contain any framework-free code - even the "Friend" "bean" implements the framework Validation interface. Also, IoC in RIFE seems not to be first-class yet - is there a more recent status summary than this page? [http://rifers.org/wiki/display/RIFE/Add+full+IoC+support] |