Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

RWT: Rebol Server Pages the Manual

 [1/4] from: maarten:koopmans:surfnet:nl at: 3-Mar-2003 19:40

Introduction to REBOL Server Pages (RSP). Ernie van der Meer ([e--a--vdmeer--net--hcc--nl]) Q: REBOL Server Pages? That sounds familiar! A: It should! The idea for REBOL Server Pages (RSP) was borrowed directly from Java Server Pages (JSP). Those familiar with JSP should feel right at home. Q: So what does it do? A: Well, generally speaking, it allows you to write a template and then have the process-rsp function fill it in for you. The template can be stored in a file or in a REBOL string. Q: Okay, so I need to write a template. How do I go about that? A: The template text is just a normal piece of text like any other. However, it includes specially tagged sections, delimited by <% and %>. When run through the process-rsp function, all the tagged sections are processed and the result of that processing is returned to you as a string. There are two types of sections: code sections and value sections. Code sections are delimited by <% and %>, while value sections are delimited by <%= and %>. Q: I understand ... sort of. Why have code and value sections? I'm not sure I understand the difference. A: The difference it quite subtle, but very important. A value section must contain REBOL code that reduces to a single value. The value will replace the value section in the text. The content of a code section, however, is executed as-is. No direct output of a code section will be visible. The section will simply disappear completely. Unlike a value section, a code section need not contain valid REBOL code in itself. It can be combined with other code sections to make the REBOL code complete. Q: That all sounds pretty confusing. Can you give me an example? A: Its really not as difficult as it sounds. Consider the following template text: text: "Today is <% if not windy [ %>not<% ] %>windy" By changing the value of the word 'windy, we can conditionally include the word "not" in the output of the template:
>> windy: yes
== true
>> process-rsp text
== "Today is windy"
>> windy: no
== false
>> process-rsp text
== "Today is not windy" If you look more closely at 'text, you can see that there are two code sections in it. the first contains " if not windy [ ", and the second contains only a closing bracket " ] ". Neither code section contains valid REBOL code in itself, but when combined, they result in conditional inclusion of a section of text. Consider another example: text: "<% foreach item [ 1 2 3 4 ] [ %>item: <%= item %> <% ] %>" Passing this through the RSP processor yields the following result:
>> text: "<% foreach item [ 1 2 3 4 ] [ %>item: <%= item %> <% ] %>"
== {<% foreach item [ 1 2 3 4 ] [ %>item: <%= item %> <% ] %>}
>> process-rsp text
== "item: 1 item: 2 item: 3 item: 4 " Once again we have two code sections that, together, form valid REBOL code. However, in between, we have a value section. The value section is evaluated for every iteration of the surrounding 'foreach code section. Q: Cool! Is there anything else I should be aware of? A: Yeah, sure. Template code, generated from your template text by process-rsp will ONLY be able to access variables in the GLOBAL context. That means that locals in a function and/or context/object are not accessible! So don't go doing stuff like this and expect it to work: do %rsp.r f: func [ /local template my-name ] [ my-name: "Ernie" template: "My name is <%= my-name %>" print process-rsp template ] if you execute f, you will get the following output:
>> f
** Script Error: my-name has no value ** Where: process-rsp ** Near: append/only result my-name Since 'my-name is a local, it is not accessible in the global context. Q: Hey! That's lame! How come you don't fix that? A: I would if I knew an elegant way to do it. The problem here is a very basic problem in REBOL. As we all know, words in REBOL have a binding to a context in which they are defined. Words can be rebound to any other context using the 'bind function. Values, however, also seem to have a binding in REBOL. This is nicely illustrated by the following function: g: func [ /local text ] [ text: "hello" do "print text" ] Executing this yields:
>> g
** Script Error: text has no value ** Where: g ** Near: print text That's the whole problem in a nutshell. When 'do evaluates the code passed to it, it automatically evaluates it in the global context. Therefore, it can't access the locally defined variable. As far as I know, there is no way to get 'do to evaluate the code in the string while having access to local variables. Q: How do I create a template that includes "<%" and/or "%>" as normal text? I don't want them processed as tags! A: Sorry! Some things were just not meant to be. This would boost the complexity of the processor by at least an order of a magnitude. Maybe you can work around the problem by using "< %" and/or "% >" instead. Q: How come I need both the "<%" and the "<%=" tags? Surely I can do everything with only the "<%=" tag? A: Like I said before, the difference between the two tag types is subtle. The answer to your question is, of course, no. You need both tag types. A good example is the 'foreach loop described above. You definitely don't want to see the return value of the foreach loop (being the last value of the last iteration of the block) added to the output. In other cases, however, you must have the return value of the statement in the output. Since REBOL is completely dynamic, there is no chance of guessing which output should be included and which shouldn't. That's why you need the different tag types so you can specify which statements should produce output. Consider the following two templates: t1: "<%= mold foreach x [ 1 2 3 ] [ append [] x * x ] %>" t2: "[<% foreach x [ 1 2 3 ] [ %><%= x * x %> <% ] %>]"
>> process-rsp t1
== "[1 4 9]"
>> process-rsp t2
== "[1 4 9 ]" Both give similar, if not identical results. Both use a 'foreach loop to produce the output. The use of "<%=" versus "<%" is essential to force different behavior for both 'foreach statements. Q: What does this give me that rejoin doesn't? A: Functionally: nothing! However, it is very inconvenient to use double quotes or braces/brackets ({) around all your strings. This is especially true when the bulk of your template is text. It's a bit similar to the discussion in JSP. When is it profitable to use JSP? General rule of thumb: when most of your template is static and only a small part is dynamic. Q: Okay. Filling in a template is nice, but what can I do with RSP in the real world? A: Like JSP, you could use RSP to create dynamic web pages. Most HTML editing tools will ignore <%..%> sections in a page. They will not be touched and will be displayed by some small icon only. This allows you to edit the main content/layout of your page with your favorite HTML tool. But why limit yourself to HTML? Consider the following XML template: xml-template: { <?xml version="1.0" ?><% foreach record get-my-data [ %> <transaction> <name><%= record/1 %></name> <street><%= record/2 %></street> <product> <id><%= record/3 %></id> <version><%= record/4 %></version> </product> </transaction><% ] %>} This must be the easiest way to produce XML! All that's needed is a single function 'get-my-data that retrieves the source data for you. When combined with REBOL database access, it becomes really easy to obtain data from your favorite database product in XML. RSP can also be very helpful when sending out bulk email messages where a small personal touch is required. Just write the email once and send it out running through your customer database one record at a time. Q: I want to print a block of data like this: process-rsp "<%= [ 1 2 3 ] %>" and all it produces is "123"! That ain't right! A: Actually, it is. Have you tried "append {} [1 2 3]" in REBOL? This produces exactly the output you got. If you need a block as a block, try using "<%= mold [1 2 3] %>" "<%= form [1 2 3] %>" instead.

 [2/4] from: maarten::koopmans::surfnet::nl at: 3-Mar-2003 20:13

RWT: email ddress in manual

Hi list, I accidentally included a very old email address in the manual, of Ernie. Please remove that before republishing. I have contacted escribe to request removal of the email. --Maarten

 [3/4] from: chalz::earthlink::net at: 3-Mar-2003 21:25

Re: RWT: Rebol Server Pages the Manual

Actually, I have a question I haven't seen. What version of REBOL is needed to run all of this? Is plain /Core OK, or is /Command required? What version of which? Thanks Maarten! Looks pretty wild. Might try convincing my webhost provider to let me use it ;) --Charles

 [4/4] from: maarten:koopmans:surfnet:nl at: 4-Mar-2003 8:24

Core is enough. If you can upload core you can adapt your htaccess file (this works with --Maarten Charles wrote: