JVM Scripting Server page (also shortened as JSSP) is a polyglot templating system that embeds JVM scripting language into a text document, similar to JSP, PHP, ASP, and other server-side scripting languages.
docker run --rm redraiment/jssp
Here is a basic example of JSSP.
docker run --rm -v $PWD:/jssp redraiment/jssp \
examples/local-mode/languages.md.groovy
Template: examples/local-mode/languages.md.groovy
# Languages
[! ["JavaScript", "Groovy", "JRuby", "BeanShell"].each { !]
* [= it =]
[! } !]
Output
# Languages
* JavaScript
* Groovy
* JRuby
* BeanShell
JSSP supports the following languages:
- JavaScript
- Groovy
- BeanShell (Java)
- JRuby (Ruby)
JavaScript Template: examples/local-mode/languages.md.js
[! var languages = ['JavaScript', 'Groovy', 'JRuby', 'BeanShell'] !]
# Languages
[! for (var index = 0; index < languages.length; index++) { !]
* [= languages[index] =]
[! } !]
Groovy Template: examples/local-mode/languages.md.groovy
# Languages
[! ["JavaScript", "Groovy", "JRuby", "BeanShell"].each { !]
* [= it =]
[! } !]
BeanShell Template: examples/local-mode/languages.md.bsh
[! String[] languages = new String[] { "JavaScript", "Groovy", "JRuby", "BeanShell" } !]
# Languages
[! for (String language : languages) { !]
* [= language =]
[! } !]
JRuby Template: examples/local-mode/languages.md.rb
# Languages
[! ["JavaScript", "Groovy", "JRuby", "BeanShell"].each do |language| !]
* [= language =]
[! end !]
JSSP deletes spaces around statement patterns ([! !]
and @! !@
) automatically, while it leaves spaces around expression patterns ([= =]
and @= =@
). If you want leave spaces, add command-line option --trim=false
.
docker run --rm -v $PWD:/jssp redraiment/jssp \
--trim=false \
examples/local-mode/languages.md.groovy
Output
# Languages
* JavaScript
* Groovy
* JRuby
* BeanShell
Command-line option -f/--context-file
specifies context data file. JSSP load context data file and use it as context data. Context data file can be JSON file (*.json
) only.
docker run --rm -v $PWD:/jssp redraiment/jssp \
-f examples/context-data/data.json \
examples/context-data/languages.md.rb
Template: examples/context-data/languages.md.rb
# Languages
[! languages.each do |language| !]
* [= language =]
[! end !]
Context Data File: examples/context-data/data.json
{
"languages": [
"JavaScript",
"Groovy",
"JRuby",
"BeanShell"
]
}
Output:
# Languages
* JavaScript
* Groovy
* JRuby
* BeanShell
Command-line option -c/--context-string JSON
enables you to specify JSON format context data in command-line.
docker run --rm -v $PWD:/jssp redraiment/jssp \
-c '{"languages": ["JavaScript", "Groovy", "JRuby", "BeanShell"]}' \
examples/context-data/languages.md.rb
Output:
# Languages
* JavaScript
* Groovy
* JRuby
* BeanShell
You can change embedded pattern to another.
docker run --rm -v $PWD:/jssp redraiment/jssp \
--executing-statement='<!--% %-->' \
--executing-expression='<!--= =-->' \
examples/embedded-patterns/languages.html.groovy
Template: examples/embedded-patterns/languages.html.groovy
<h1>Languages</h1>
<ul>
<!--% ["JavaScript", "Groovy", "JRuby", "BeanShell"].each { %-->
<li><!--= it =--></li>
<!--% } %-->
<ul>
Output:
<h1>Languages</h1>
<ul>
<li>JavaScript</li>
<li>Groovy</li>
<li>JRuby</li>
<li>BeanShell</li>
<ul>
There are two phases during render a template:
- Expanding phase: render repeatedly with expanding patterns, to compute another template which will in turn render, until no more patterns can be found.
- Executing phase: render with executing patterns once.
The include
and includeOnce
functions are read and return the specified file. The argument is a relative path of current working directory.
docker run --rm -v $PWD:/jssp redraiment/jssp \
examples/nested-include/index.css.groovy
Template: examples/nested-include/index.css.groovy
@= includeOnce('examples/nested-include/colors.groovy') =@
[! ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].each { tag -> !]
@= includeOnce('examples/nested-include/highlight.css.groovy') =@
[! } !]
Template: examples/nested-include/highlight.css.groovy
@= includeOnce('examples/nested-include/colors.groovy') =@
[! colors.each { level, color -> !]
[= tag =].[= level =] {
color: [= color =];
}
[! } !]
Template: examples/nested-include/colors.groovy
[!
colors = [
normal: '#777777',
primary: 'blue',
success: 'green',
warning: 'yellow',
danger: 'red'
]
!]
Output:
h1.normal {
color: #777777;
}
h1.primary {
color: blue;
}
...
h6.warning {
color: yellow;
}
h6.danger {
color: red;
}
Run a simple HTTP server:
cd examples/server-mode
docker run --rm -d -v $PWD:/jssp -p 8080:8080 redraiment/jssp -s
http GET 'http://localhost:8080/index.html.groovy'
Template: examples/server-mode/index.html.groovy
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="renderer" content="webkit" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Hello JSSP</title>
<link rel="stylesheet" href="styles/index.css.js" />
</head>
<body>
<h1>Hello JVM Scripting Server Pages</h1>
<dl>
[! request.each { key, value -> !]
<dt>[= escape(key) =]</dt>
<dd>[= escape(value) =]</dd>
[! } !]
</dl>
</body>
</html>
Template: examples/server-mode/styles/index.css.js
[!
var backgroundColor = 'lavender';
var foregroundColor = 'blue';
var fontSize = 12;
var em = function(size) {
if (arguments.length === 0) {
size = 1.0;
}
return Math.floor(fontSize * size) + 'px';
};
!]
body {
background-color: [= backgroundColor =];
color: [= foregroundColor =];
font-size: [= em() =];
}
dt {
font-size: [= em(1.5) =];
}
Output:
Outside mode: to produce a static document offline:
jssp [options] TEMPLATE-FILE
Server-side mode: to run the inner web server:
jssp [-s | --server] [options]
-c, --context-string JSON
: context data string in JSON format, default{}
.-f, --context-file JSON-FILE
: context data JSON file name, it will override context data string above.-t, --trim BOOLEAN
: switch to delete spaces around statement, defaulttrue
.--expanding-statement PATTERN
: expanding statement pattern, default@! !@
.--expanding-expression PATTERN
: expanding expression pattern, default@= =@
.--executing-statement PATTERN
: executing statement pattern, default[! !]
.--executing-expression PATTERN
: executing expression pattern, default[= =]
.-m, --expand-limit TIMES
: set the limit times for expanding phase, it's infinite if not provides.-x, --emit-code
: emit expanded code.-s, --server
: start inner http server.-p, --port PORT
: http server port, default 8080.-h, --help
: show help and exit.
The include
function reads and returns the content of specified file.
It usually used with expanding expression pattern to include a shared fragment context into current template.
The includeOnce
function is identical to include
except JSSP will check if the file has already been included, and if so, not include it again.
The escape
function escapes the characters in a String using HTML entities.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (git checkout -b feature/AmazingFeature)
- Commit your Changes (git commit -m 'Add some AmazingFeature')
- Push to the Branch (git push origin feature/AmazingFeature)
- Open a Pull Request
Distrubuted under the Apache v2 License. See LICENSE
for more information.
- Zhang, Zepeng - @redraiment - redraiment@gmail.com