HTML templates

With P*, you don't need any external template engine. Templates are in-language!

Templates look like blocks and are defined in the main scope of the program. When a template is called, it inherits all variables available from the location of the call.

Inside templates, you can use the special syntax {@variable} to interpolate variables. You can also use while loops with the syntax {@LOOP (expression) text}

Example of a program using a HTML template

HTML_TEMPLATE document {
	<!DOCTYPE HTML>
	<html>
	<head>
	<title>{@title}</title>
	</head>
	<body>
	</body>
	</html>
}

SCENE main {
	string title = "P* Web Programming Language test page";

	#CONTENT_TYPE text/html;
	#HTML_TEMPLATE document;
}
			

In the above example, the template document is called statically, the name is resolved and validated at parse-time. You can also store the name of the template in a variable an call it dynamically using the expression-starter @ at run-time like this:

HTML_TEMPLATE test_template {
	Test output
}

HTML_TEMPLATE test_template_again {
	Test output again
}

SCENE main {
	array<string> names;
	names[0] = "test_template";
	names[1] = "test_template_again";

	/* Loop the array with the two template names */
	int i = 0;
	while (i < @names) {
		#HTML_TEMPLATE @names[i];
		i++;
	}
	return 0;
}
			

TEMPLATE blocks

You can call another template from within another template by using the {@TEMPLATE template_name;} syntax. The template you call inherits all variables from the caller.

CONDITION and LOOP blocks

You can make the template behave in different ways depending on input data by using the LOOP and CONDITION blocks. The CONDITION block works the same way as and if-block, the data inside it is printed out if the specified expression returns TRUE. The LOOP block is the same as a while-block. The data inside it is printed out repeatedly while the specified expression returns TRUE. This is useful for printing out arrays.

Here is an example program which loops an array of struct to print out all its data:

HTML_TEMPLATE row {
	<tr>
		<td>{@rows[row_counter]->id}</td>
		<td>{@rows[row_counter]->description}</td>
	</tr>
}

HTML_TEMPLATE document {
	<!DOCTYPE HTML>
	<html>
	<head>
	<title>{@title}</title>
	</head>
	<body>
{@CONDITION (@rows > 0)
	<p>We have rows to print!</p>
	<table>
		<tr>
			<th>ID</th>
			<th>Description</th>
		</tr>
{@LOOP (++row_counter < @rows) {@TEMPLATE row} }
	</table>
}
	</body>
	</html>
}

SCENE main {
	string title = "P* Web Programmin Language test page";

	struct row {
		public int id;
		public string description;
		row (int _id, string _description) {
			id = _id;
			description = _description;
		};
	};

	array<row> rows;

	rows[@rows](1, "First row");
	rows[@rows](2, "Second row");
	rows[@rows](3, "Third row");

	#CONTENT_TYPE text/html;

	int row_counter = "-1";
	#HTML_TEMPLATE document;
}
			

AJAX output

P* supports common AJAX-operations like replacing text inside a <div>. If you want to output a variable interpolated into the template, the id-tag of the previous element in you HTML is used as variable name when the JSON is generated. In the example below, a jQuery scripts does this job.

You can also have P* generate JSON output for you. You can choose variables to output from a template, and P* will create a key/value pair to output to the browser. The key is taken from the previous expression preceeded by the text "id=" from where in the template the variable was. Under follows an example which outputs a variable using JSON if the GET-variable do_ajax is set.

Here is an example program which uses templates and JSON output:

HTML_TEMPLATE document {
	<!DOCTYPE HTML>
	<html>
	<head>
	<title>P* Web Programming Language</title>
	</head>
	<body>
	<h1 id="{@"header"}">{@header}</h1>
	</body>
	</html>
}

SCENE main {
	GET get;
	string header = "This is the header";
	if (*get["do_ajax"]) {
		#JSON_BEGIN;
		#HTML_TEMPLATE_VAR document header;
		#JSON_END;
	}
	else {
		#CONTENT_TYPE text/html;
		#HTML_TEMPLATE document;
	}
}
			

Output of program when "do_ajax" is not set

Content-type: text/html;

<!DOCTYPE HTML>
<html>
<head>
<title>P* Web Programming Language</title>
</head>
<body>
<h1 id="header">This is the header</h1>
</body>
</html>
			

Output of program when "do_ajax" is set

Content-type: application/json

{
	"header": "This is the header",
	"": ""
}
			

Output templates as JSON variables

To output a whole template as a JSON variable, you can use the #HTML_TEMPLATE_AS_VAR template_name-pragma. The JSON variable name is set to be the same as the name of the template. This output method is useful if you want to output larger parts of a page.

HTML_TEMPLATE_AS_VAR-Example

HTML_TEMPLATE head {
	<!DOCTYPE html>
	<html>
	<head>
	<title>P* template as var output test</title>
	</head>
	<body>
	<div id="body">
}

HTML_TEMPLATE body {
	This is the body
}

HTML_TEMPLATE foot {
	</div>
	</body>
	</html>
}

SCENE main {
	GET get;
	if (*get["do_ajax"]) {
		#JSON_BEGIN;
		#HTML_TEMPLATE_AS_VAR body;
		#JSON_END;
	}
	else {
		#CONTENT_TYPE text/html;
		#HTML_TEMPLATE head;
		#HTML_TEMPLATE body;
		#HTML_TEMPLATE foot;
	}
}
			

Output of program when "do_ajax" GET variable is not set

Content-type: text/html;

<!DOCTYPE html>
<html>
<head>
<title>P* template as var output test</title>
</head>
<body>
<div id="body">
This is the body
</div>
</body>
</html>
			

Output with the "do_ajax" GET variable set

Content-type: application/json

{
	"body": "\tThis is the body\n",
			"": ""
}