RSP Overview
RSP (Rikulo Stream Page) is a template technology that helps developers create dynamically generated web pages based on HTML, XML or other text documents. A RSP page is a text document that contains two types of text: static data, which can be expressed in any text-based format (such as HTML, CSS, and XML), and RSP tags which generate the dynamic content.
Notice that the dynamic content is generated at the server side.
Example
Here is a RSP page:
[:page partOf="hello.rsp.dart"]
<!DOCTYPE html>
<html>
<head>
<title>Stream: Hello RSP</title>
<link href="theme.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Stream: Hello RSP</h1>
<p>Now is [=new DateTime.now()].</p>
<p>This page is served by Rikulo Stream [=connect.server.version].</p>
<p>Please refer to
<a href="https://github.com/rikulo/stream/tree/master/example/hello-rsp">Github</a> for how it is implemented.</a>
</body>
</html>
where [:page] and [= ...] are RSP tags. They generate the dynamic content, while the rest are static data that are output directly.
How it Works
Each RSP page will be compiled into a request handler and put into a Dart file. The recommended file extension for a RSP page is .rsp.html
(or .rsp.xml
, depending on the file type), and the generated Dart file will be named by changing the file extension to .rsp.dart
.
You can control the name of the request handler and additional arguments by use of the [:page] tag. If omitted, the filename will be assumed.
How to Compile
There are two ways to compile RSP files into Dart files: automatic building with Dart Editor or manual compiling.
Build with Dart Editor
To compile your RSP files automatically, you just need to add a build.dart
file in the root directory of your project, with the following content:
import 'package:stream/rspc.dart' show build;
void main(List<String> arguments) {
build(arguments);
}
With this build.dart
script, whenever your RSP is modified, it will be re-compiled automatically.
Compile Manually
To compile a RSP file manually, you can run rspc
(RSP compiler) to compile it into the Dart file with command line interface as follows:
dart bin/rspc.dart your-rsp-file(s)
A Dart file is generated for each RSP file you gave.
File Location
You can put RSP files (*.rsp.*
) under any folder you'd like. The generated Dart files (*.rsp.dart
) will be always generated under the webapp
folder.
If RSP files are already under the webapp
folder (such as webapp/rsp/signup
), the generated Dart files will be put in the same folder.
If not, for example, let us say we put signupView.rsp.html
under the rsp/signup
folder, then signupView.rsp.dart
will be generated under the webapp/rsp/signup
folder.
Notice that the folder of a RSP file resides has no effect how it behaves. What does matter is how it is imported and used in your application.
Also notice that RSP files can't be accessed directly from client, even if it is not put under the
webapp
folder. By default, they are mapped toHttp404
.
Put Together
The generated Dart files shall be part of your Dart server application. There are a few ways to do it.
Generated as an Independent Library
By default, the generated Dart file is an independent library. All you need to do is to import it in your main program.
//your_main.dart
import 'rsp/signup/signupView.rsp.dart';
In the generated Dart file, dart:io
, dart:async
and package:stream/stream.dart
will be imported by default. If you'd like to import others, you can specify them in the import
attribute with the [:page] tag. For example,
[:page import="dart:async, dart:collection show HashMap"]
...
Notice that you can split the value of the import attribute into multiple lines (for better readability).
Generated as Part of Another Library
Making every RSP file as an independent library can end up with too many libraries. It is usually more convenient to manage if you group several RSP files into a single library.
It can be done by making the generate Dart file as part of another library with the [:page] tag as follows:
[:page partOf="your_lib.dart"]
...
As shown, the partOf
attribute specifies the path of the library file. In this example, it is your_lib.dart
. RSP compiler will maintain your_lib.dart
automatically. If it doesn't exists, it will be created. If exists, the part
statement will be inserted to your_lib.dart
if necessary.
Furthermore, you can specify the import
attribute in the [:page] tag too. The libraries specified in the import
attribute will be updated to your_lib.dart
too.
Alternatively, if you prefer to maintain the relationship among these Dart files manually, you can specify the library's name (rather than a file path) in the partOf
attribute. For example,
[:page partOf="one_of_your_library"]
...
Then, you can include the generated Dart file in your library (manually with the part
statement in Dart).
//your_lib.dart
library one_of_your_library;
part "your.rsp.dart";