# script.demo.txt
# NOTE:
This script mix different types of code and content, this is not how you would
write an application. This is a demo, it is written this way to demonstrate
different features and hopefully to make it easier to see what is going on.
!if PHP_SAPI == 'cli':
"Run in browser!
!return
<!doctype html>
$width = '500px';
$ErrorMessage = false
# utility for constructing statements from strings
=do:!param string
!php static::run_script($_param);
#### Language settings
# supported languages
$valid_languages = array(
'en'=>'english',
'no'=>'norwegian');
$default_language = 'en'
# Get and validate language selected by user
$lang = isset($_GET['lang']) ? $_GET['lang'] : $default_language;
!if !in_array($lang,array_keys($valid_languages)):
$lang = $default_language
$lang_label = $valid_languages[$lang]
# Load language file
!if file_exists("lang-$lang_label".SCRIPT_EXTENSION):
# Reading language specific content
do:lang-$lang_label
!else:
# Can not read language file, can not display error here
$ErrorMessage = "lang-$lang_label".SCRIPT_EXTENSION.' was not found'
lang-english
=LanguagePicker:
!scope caller $lang,$valid_languages
<span style="padding-left:3em;">Language: </span>
<select onchange="location.href='?lang='+this.value">
!loop $valid_languages as $lang_code=>$lang_label:
$sel = ($lang == $lang_code) ? ' selected="selected"' : ''
"<option value="$lang_code"$sel>$lang_label</option>
</select>
#### CSS
$nav_style = '
font-size:120%;
margin:1em; padding:.5em;
border:solid 1px black;
border-radius:5px;
display:inline-block;
'
=Demo_style:
!scope caller $width
" .demo {
border: solid 1px silver;
border-radius:5px;
width:$width;
height:110px;
padding:5px;
margin:0;
}
# This CSS example shows three different ways to send some variable into a layout:
We call it with $width parameter, the $nav_style (defined above) is picked from
the caller scope, and Demo_style is defined as a separate layout above.
=CSS:!param string:$width
!scope caller $nav_style
# !! The space between { and $nav_style below is required, otherwise PHP removes the {}
" p {width:$width;}
p.intro {font-weight:bold;}
.nav { $nav_style }
.demo1 {color:green;}
.demo2, .demo_viewer {color:blue;}
.demo3 {color:purple;}
.demo4 {color:red;}
Demo_style
#### 4 demo boxes defined here
=demo1:
# defining a placeholder
=Greeting:"Hello world
# using it
<div class="demo demo1">
Greeting
</div>
=demo2:
# defining a basic template
=MyTemplate:"<div class="demo demo2">$_param</div>\n
# calling template with parameter
MyTemplate:Hello world
=demo3:
# defining a template with resolved parameter
=MyTemplate: !param $msg:string
"<div class="demo demo3">$msg</div>\n
# defining a variable
$who = 'world'
# calling the template using the variable
MyTemplate:Hello $who
=demo4:
# defining a template, fetching variable from caller
=MyTemplate: !scope caller $msg
"<div class="demo demo4">$msg</div>\n
# defining a variable
$msg = 'Hello world'
# calling the template
MyTemplate
#### Start of HTML output
<html><head>
<meta charset="utf-8">
<title>
Title
</title>
<style>
CSS:$width
</style>
</head>
# For making internal links, lang parameter is set automatically
=Link:!param string colon:$src,$label
!scope from script:$lang
"<a href="?lang=$lang&src=$src">$label</a>
# The 'override_demo' layout is used to override the demo1-demo4 layouts defined
above, this is done for demonstration purposes. In general we can just redefine
the layout with = prefix. In this case we need to store the content of the demo
layouts in string variables, then redefine them so that they will display these
strings in a <pre>. Explaining this code in detail is beyond the scope of this
demo, but $$ is a special placeholder for the input, in this case it is replaced
with 1, 2, 3 and 4.
=override_demo: !scope caller $demo$$_script
$demo$$_script = htmlentities(self::$layouts['demo$$']['content']);
=demo$$:!scope caller $demo$$_script
"<pre class="demo demo$$">$demo$$_script</pre>
=Content:
# Content_intro, Example_explanation and Example_invitation
are defined in the lang-*.demo.txt files
!if $_param == 'show_src':
# override the demos, make them display the source
override_demo:1
override_demo:2
override_demo:3
override_demo:4
Content_intro
<div>
demo1
demo2
demo3
demo4
</div>
!if $_param == 'show_src':
Example_explanation
!else:
Example_invitation
=View source:
# This is the application part, showing different sources depending on URL parameter 'src'
This layout has a space in the name for no particular reason, just showing that it works
# This input is whitelisted, we check for specific values, no need for extra validation
$src = $_GET['src']
# Simple navigation to take the user back to start or to the next relevant page
=Navigation:!param raw:$target
!scope from script:
$lang, $back_to_start, $link_separator,
$show_PHP_demo_source, $show_demo_viewer_source
$links = array(
'demo_source'=>$show_demo_viewer_source,
'php_source'=>$show_PHP_demo_source
)
<div class="nav">
"<a href="?lang=$lang">$back_to_start</a>
!if $target:
"$link_separator
Link:$target:$links[$target]
</div>
!if $src == 'examples':
# This is an alternative to overriding a layout: send in a parameter and use conditonal
statements to have different behaviour (see Content definition above).
Content:show_src
Content_demo_source_invitation
Navigation:demo_source
!elseif $src == 'demo_source':
Demo_source_intro
# reading the script from the internal $layouts array
$script = htmlentities(self::$layouts['script']['content']);
"<pre class="demo_viewer">$script</pre>
Demo_source_description
Navigation:php_source
!elseif $src == 'footer':
$footer_file = 'footer'.SCRIPT_EXTENSION;
Footer_intro:$footer_file
# reading footer from file, it is not yet loaded
$footer = htmlentities(file_get_contents($footer_file));
"<pre class="demo_viewer">$footer</pre>
Footer_description
Navigation:demo_source
!elseif $src == 'lang':
!scope from script: $valid_languages,$lang
$lang_label = $valid_languages[$lang]
$lang_source = self::$layouts['lang-'.$lang_label]['content']
# Language file is in UTF-8 format, if internal encoding is
not UTF-8 it must be decoded before using htmlentities()
!if mb_internal_encoding() != 'UTF-8':
$lang_source = utf8_decode($lang_source);
$lang_source = htmlentities($lang_source)
Language_intro
"<pre class="demo_viewer">$lang_source</pre>
Language_description
Navigation:demo_source
!elseif $src == 'php_source':
PHP_source_intro
$php_source = highlight_file('demo.php',true);
"$php_source
PHP_source_description
Navigation:demo_source
!elseif $src == 'log':
# show the tail of the log file
$size = 2500
$fh = file_exists(LOGFILE) ? fopen(LOGFILE,'r') : false
!if $fh:
$res = fseek($fh,-$size,SEEK_END)
!if $res == -1:
# smaller than $size, read entire file
$log_content = htmlentities(file_get_contents(LOGFILE))
!else:
$ignore = fgets($fh); # ignore first (incomplete) line
$log_content = htmlentities(fread($fh,$size))
!php fclose($fh);
"<pre class="demo_viewer">$log_content</pre>
Logfile_description
!if !DEBUG_MODE:
Warning:DEBUG_MODE is disabled, messages might be old
!elseif DEBUG_MODE:
Warning: DEBUG_MODE is enabled but the log file was not found!
!else:
Warning: Log file not found, enable DEBUG_MODE
Navigation:php_source
!else:
Warning: Unexpected src parameter
Navigation
=Warning:
!param string: $msg
"<p style="color:red">$msg</p>
<body>
<h1>
Title
</h1>
<p class="intro">
Intro
</p>
!if $ErrorMessage:
Warning:$ErrorMessage
!if isset($_GET['src']):
View source
!else:
Content
<div class="nav">
Link:examples:$show_template_definitions
LanguagePicker
</div>
# The footer is defined in a separate file
footer:black|silver;
font-family:Verdana,sans-serif;
width:$width;
border-radius:5px;
</body>
</html>
|