February 15, 2011

Razor-Like Script in Delphi Relax

This post to introduce the Razor-like support, part of the Delphi Relax project, and available online (source and documentation).

This post to introduce the Razor-like support, part of the Delphi Relax project. This part of the project is available online (source and documentation). It is released under MPL license. First of all, the project web site is at  http://code.marcocantu.com/p/delphirelax .

To get the actual source code refer to the SVN information at http://code.marcocantu.com/p/delphirelax/source/tree/HEAD/. There is the source code of a component plus the Delphi XE package to install it. There is also a half-baked demo using WebBroker (remember, the goal is to use it as a plug-in to the DataSnap REST Application Architecture, which uses WebBroker underneath). The demo is the one covered in the documentation.

The documentation is a PDF of 28 pages, which took me quite some effort to prepare. It covers the relax syntax and the use of the two components. In this blog post there is only a short summary of the two parts, you'll find much more in the docs of course.

Razor Delphi Syntax


The adaptation of Razor used in Delphi Relax has a rather simple syntax. First, it uses the @ symbol as marker, rather than tags or other notations. The symbol is followed by a special processing keyword or by a value, generally indicated with a dot notation as object.value, so you'll see tags like: @object.value.


The object name might come from a specific registration in a dictionary, and the value is the nasme of a property (for a generic object) or a field name (if the object is a TDataset). As an alternative, the value can be provided by the OnValue event handler.

There are several special tags:


  • @if object.value { ... }: executes the following block among braces only if value is "true"
  • @ForEach object { ... }: executes the following block among braces as many times as there are elements in the enumerator. Currently supports datasets and TList.
  • @loop is used within a loop to access to the current object / record
  • @LayoutPage: indicate the HTML page to use for the structure, a sort of HTML template
  • @RenderBody: where to place the actual content of the page within the layout page or template
  • @LoginRequired will stop processing and return an error in case the user is not logged
  • @Lang is part of the language / translation support


The Delphi Razor Components

The Razor package (or the razor portion of the overall Delphi Relax package) installs two different components, a single file processor and an engine which can instantiate individual processors and provides global configuration for either the dynamic processors or those manually connected with it.

RlxRazorProcessor: This is the core component, capable of taking an HTML file embedding the razor notation and converting it to plain HTML after processing the @ tags.


RlxRazorEngine: This is the engine component, which can be used in two different scenarios: (i) You can connect it to one ore more RazorProcessor components, to provide shared settings and behavior, rather than customizing each specific processor. (ii) You can let is create RazorProcessors when needed, and place only this component on your web modules.

In Development

This is only one part of an overall project, but feel free to start playing with it. It is still an early beta, many features are likely to change. Help is welcome. Not only suggestions, but actual coding help. For example, a person willing to write unit testing for the project (following the doc) would add a lot of value! Contact me for this or if you are interested and want a consultant to help you use this architecture fro your code (this is where I hope I'll have some benefit...)

Again, this is only a small part of a larger project. And stay tuned, hope to have an introductory video for the demo that's available in a day or two. Also willing to schedule an open chat (on http://chat.stackoverflow.com/rooms/50/delphi unless there are better suggestions) if there is interest in discussing the project a little more. For now, feel free to comment on this blog post. 

PS: Please no "Dephi is for client only, you are wasting your time", thanks. Got already quite a few of those.






Razor-Like Script in Delphi Relax 

 Great start Marco,

I just downloaded the pdf and skimmed it.

You know what would help me understand the
architecture better?  A diagram.

Even better - three diagrams: 1) Typical Web Broker,
2) Typical DataSnap, and 3) Delphi Relax.

This way, I could quickly understand their differences
and similarities.

Thank you so much.

Comment by Keith on February 15, 19:00

Razor-Like Script in Delphi Relax 

 Any chance of a jquery grid with paging example ?

Also the current demo/test fails with duplicate
Dictionary entry if you go to the say company page, move off
It and come back.

Otherwise very impressed so far.
Comment by Andrew Tierney [http://Www.castlesoft.com.au] on February 20, 10:33

Razor-Like Script in Delphi Relax 


  the duplicate should be fixed in the latest version of 
the demo.

I've posted the first part of the database mapping 
(documentation is coming) and will add the grid 
pagination to it shortly.
Comment by Marco Cantu [http://www.marcocantu.com] on February 21, 07:55

Razor-Like Script in Delphi Relax 

Thanks Marco.. as usual.. Brilliant stuff.

Can't wait to see the jquery grid stuff. !!

On another note.. Any new books in the works ?

Comment by Andrew Tierney [http://www.castlesoft.com.au] on February 21, 10:06

Razor-Like Script in Delphi Relax 


There still appears to be a bug in the demo..

'Internal Application Error

Duplicates not allowed


If you press F5 when on the /Company page.

I patched my RlxRazor.pas as follows:

procedure TRlxRazorProcessor.AddToDictionary(aName:
string; theObject: TObject;
  Owned: Boolean);
  item: TRazDictItem;
  if FDataObjects.ContainsKey(aName) then

  item := TRazDictItem.Create;
  if theObject is TDataSet then
    item.FKind := rdikDataset
    item.FKind := rdikObject;
  item.TheObject := theObject;
  item.Owned := Owned;
  FDataObjects.Add (aName, item);

Just checked for ContainsKey and it seem to solve the

PS.. Playing with the jqgrid now.

Comment by Andrew Tierney [http://www.castlesoft.com.au] on February 22, 13:38

Razor-Like Script in Delphi Relax 

Andrew, good point. I have (partially) fixed the 
demo but this is likkely to become a common issue, so I 
did add a new property, futher extending your code:

proprty DictionaryDuplicates, indicates what to do in 
case you are adding the same “name” twice to the 
internal dictionary. Alternative options are ddIgnore 
(default), ddReplace, and ddError. Actual code is in the 
AddToDictionary method.

Will be available in the next update.
Comment by Marco Cantu [http://www.marcocantu.com] on February 24, 14:59

Post Your Comment

Click here for posting your feedback to this blog.

There are currently 0 pending (unapproved) messages.