/
tut_tempcode.txt
2257 lines (2055 loc) · 108 KB
/
tut_tempcode.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[title sub="Written by Chris Graham (ocProducts)"]Composr Tutorial: Tempcode programming[/title]
Tempcode is Composr's template programming language. On the simplest level, it provides a substitution mechanism so that parameters and global symbols (like the current user's username, or the time) can be inserted into a template.
It also serves as a complete programming language with support for control structures, built-in core functions and variable substitutions.
[contents]decimal,lower-alpha[/contents]
[title="2"]Syntax[/title]
The "syntax" of a language is simply the grammar. Tempcode's syntax is extremely simple.
Tempcode provides four constructs other than the plain text of the template itself:
1) [b]Parameters[/b]: [tt]{PARAMETER}[/tt] where PARAMETER is a code-name of something that was actually passed to the template.
2) [b]Language strings[/b]: [tt]{!STRING,<parameters>...}[/tt] where STRING is a real language string from a loaded language file (e.g. Banner code could use strings from banners.ini, but most other code could not; global.ini contains strings usable anywhere).
3) [b]Symbols[/b]: [tt]{$SYMBOL,<parameters>...}[/tt] where SYMBOL is a real symbol Composr supports. Embedding a symbol is like making a function call or running a command in the complex place, or a substitution in the simple case.
4) [b]Directives[/b]: [tt]{+START,DIRECTIVE,<parameters>...}...{+END}[/tt] where DIRECTIVE is a real directive Composr supports. Directives essentially wrap portions of the template, controlling that portion; they are generally used for types of condition checking (e.g. IF) or loops. There are also directives like [tt]{+IMPLODE,<parameters>...}[/tt] that do not wrap, but work outside the normal "string manipulation" bounds that symbols do.
[title="3"]Escaping[/title]
Any of the above 4 Tempcode constructs may be escaped. By "escaped", I mean made to fit in an encoding scheme, such as HTML or URLs, such that special text characters do not interact with that encoding scheme in an insecure/corrupting way). This is done with ease using escaping filters, just by placing the character associated with the mode of escaping before the closing '}'.
For example, [tt]{BLAH*}[/tt] will add the parameter BLAH, escaped for HTML output.
The following escaping filters are provided ([color="green"]green[/color] indicates common usage, [color="red"]red[/color] indicates advanced usage)...
[semihtml]
<table class="wide_table columned_table results_table">
<colspan>
<col style="width: 3em" />
<col style="width: 17em" />
<col style="width: 10em" />
<col style="width: 10em" />
</colspan>
<thead>
<tr>
<th>Character</th>
<th>Purpose</th>
<th colspan="2">Example</th>
</tr>
<tr>
<th></th>
<th></th>
<th><em>Before</em></th>
<th><em>After</em></th>
</tr>
</thead>
<thead>
<tr>
<th colspan="4">HTML and XML</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt](*)[/tt]</td>
<td>Text embedded within HTML.</td>
<td>[tt]Hello & Goodbye[/tt]</td>
<td>[tt]Hello &amp; Goodbye[/tt]</td>
</tr>
<tr style="background-color: #FFDDDD">
<td>[tt]=[/tt]</td>
<td>HTML escaping (like above), if you are 100% sure you want the data escaping, even if it comes from something that might already be in HTML such as a language string.</td>
<td colspan="2"><em>as above</em></td>
</tr>
<tr style="background-color: #DDFFDD">
<td>[tt](|)[/tt]</td>
<td>Make something appropriate for use as an HTML/XML ID, usually to be referenced by JavaScript and CSS.</td>
<td>[tt]This is a -terrible- ID[/tt]</td>
<td>[tt]This__is__a____terrible____ID[/tt]</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4">JavaScript</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt](/)[/tt]</td>
<td>Works around a special JavaScript SGML-issue: anything looking like HTML tags within a [tt]<script>[/tt] tag must be specially-escaped.</td>
<td>[tt]print('</p>');[/tt]</td>
<td>[tt]print('<\/p>');[/tt]</td>
</tr>
<tr style="background-color: #DDFFDD">
<td>[tt]%[/tt]</td>
<td>Make something appropriate as a strict codename. This is used where JavaScript code is involved for the highest level of security.</td>
<td>[tt]This[/tt]</td>
<td>[tt]This[/tt]</td>
</tr>
<tr style="background-color: #DDFFDD">
<td colspan="2"></td>
<td>[tt]This is[/tt]</td>
<td><em>Hack-attack triggered</em></td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4">CSS</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt]'[/tt]</td>
<td>Make something appropriate for use as a CSS value (anything that isn't a part of a very constrained non-string value is replaced with underscore).</td>
<td>[tt]green and red[/tt]</td>
<td>[tt]green_and_red[/tt]</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4"><em>Both</em> JavaScript <em>and</em> CSS</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt](;)[/tt]</td>
<td>Make something fit between JavaScript/CSS-style single quotes.</td>
<td>[tt]Who's here[/tt]</td>
<td>[tt]Who\'s here[/tt]</td>
</tr>
<tr style="background-color: #DDFFDD">
<td>[tt](#)[/tt]</td>
<td>Make something fit between JavaScript/CSS-style double quotes.</td>
<td>[tt]She said, "Hello"[/tt]</td>
<td>[tt]She said, \"Hello\"[/tt]</td>
</tr>
<tr style="background-color: #DDFFDD">
<td>[tt](~)[/tt]</td>
<td>Where new lines are not allowed (text is drawn up to reside on a single line).</td>
<td>[tt]a<br />b[/tt]</td>
<td>[tt]ab[/tt]</td>
</tr>
<tr style="background-color: #DDFFDD">
<td>[tt](^)[/tt]</td>
<td>Where new lines become [tt]\n[/tt] (individual lines are drawn together with \n as a separator).</td>
<td>[tt]a<br />b[/tt]</td>
<td>[tt]a\nb[/tt]</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4">Comcode</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt](@)[/tt]</td>
<td>Make sure something doesn't look like a Comcode tag.</td>
<td>[tt]Use the [url] tag[/tt]</td>
<td>[tt]Use the \[url] tag[/tt]</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4">URLs</th>
</tr>
</thead>
<tbody>
<tr style="background-color: #DDFFDD">
<td>[tt]&[/tt]</td>
<td>Make sure something fits in as a URL parameter, with special Comcode URL escaping also.</td>
<td>[tt]a&b[/tt]</td>
<td>[tt]a:amp:b[/tt]</td>
</tr>
<tr style="background-color: #FFDDDD">
<td>[tt].[/tt]</td>
<td>Make sure something fits in as a URL parameter, if you don't want extra Composr URL escaping to happen. Use this when building up non-Composr URLs.</td>
<td>[tt]a&b[/tt]</td>
<td>[tt]a%26b[/tt]</td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="4">Special <em>(not actually for escaping)</em></th>
</tr>
</thead>
<tbody>
<tr style="background-color: #FFDDDD">
<td>[tt]-[/tt]</td>
<td colspan="3">Special code to indicate that a construct should not be pre-processed. This is useful very occasionally if you want to stop something like a block being preloaded if it is buried under a Tempcode IF directive and hence doesn't always run. Stopping pre-processing will stop any JavaScript or [abbr="Cascading Style Sheets"]CSS[/abbr] dependencies being called up, however.</td>
</tr>
<tr style="background-color: #FFDDDD">
<td>[tt]+[/tt]</td>
<td colspan="3">Must be used as the only escaping character. This indicates that something:
[list]
[*] should not be escaped
[*] definitely is passed into the template (no user-friendly warnings will be given if it is not)
[*] should be output directly, the way PHP wants (so will not follows the normal rules for Tempcode display of boolean values or arrays)
[/list]
This is substantially faster in terms of the amount of memory, CPU time, and storage. However, it should only really be used by programmers knowing exactly what they are doing.
</td>
</tr>
</tbody>
</table>
[/semihtml]
It is absolutely crucial that Tempcode programmers use the proper escaping. Without it, all kinds of insecurities and unreliabilities can develop. About 50% of parameters in the default Composr templates actually use HTML escaping so that plain text placed inside a template does not interfere with the HTML structure itself and displays literally.
If you're wondering what the characters refer to: nothing. They are just characters that are easy to type on a regular keyboard. We like the ability to be able to apply the escapings in this shorthand, in the same way that maths benefits from concise symbolic shorthand.
[title="3"]The Tempcode tree (advanced)[/title]
Templates are composed together into a tree structure, and then the tree structure is output. This is discussed in further detail in the [page="_SEARCH:tut_structure"]Composr site structure tutorial[/page].
[title="2"]Philosophy[/title]
Tempcode is quite different from other templating languages, and it's worth covering that.
Most templating languages will try to either:
[list="a"]
[*] use XML, to add programming constructs into the mark-up itself
[*] allow PHP code, or an abstraction of PHP code, to run within the templates
[/list]
Our approach is distinctly different, as we uphold four strong principles:
1) templates should be editable in an HTML editor without Tempcode being broken (although the HTML editor at this time must be able to support 'fragments of HTML')
2) templates should not contain code on the same level as PHP, for security reasons (a theme should not be able to delete files, for instance)
3) there should be a very clear separation of role between templates and code; code should not be put into templates simply because it is convenient, as this muddies the architecture, causing maintenance issues
4) templates should not 'execute': Tempcode should act as a filter/token-placer for output, reshaping output, rather than intertwining code with it. This is again, an architectural issue
[title="3"]Advanced philosophy (experts only)[/title]
For those interested in 'programming language semantics', Tempcode is neither a functional or imperative language, but has aspects of both. A functional language essentially is focused on output being controlled by a complex mathematical expression. An imperative language essentially is focused on output being controlled by a sequence of commands. With Tempcode, output is focused on the stream of text coming from a template, and the composition of these streams; 'symbols' and 'directives' can control, manipulate and add to the stream, but they are more like embedded functional-language function-chains and control-tags than imperative code. Sequences of commands can be simulated by placing symbols and directives next to each other in the output stream and using variable manipulation features to bridge data across the portions of the output stream.
Popular template languages such as 'Velocity' or 'Smarty' are able (and often used) to function in a similar sense to this, but their language design is imperative at core, and the result simply is just far less elegant. Tempcode just 'feels right', with its clean syntax and PHP-separation, while other languages look literally like conventional programming code has been added inside the template in an ad-hoc way (even if the full programming syntax has been simplified a bit).
[title="2"]Placing theme images[/title]
[box="Party like it's 1999" float="right"]
[center][semihtml]
<img src="{$IMG*,under_construction_animated}" alt="Under Construction" title="Under Construction" />
[/semihtml]
(this guy's back must
be really hurting by now)[/center]
[/box]
This is your first practical example of Tempcode, and perhaps the most common use of Tempcode symbols.
To insert an image into your template, use Composr's image symbol: [tt]{$IMG,codename}[/tt]. Replace [tt]codename[/tt] with the image code for the image you want to use. This will turn into the image's URL. Be aware that this does not insert any HTML for you, so to use it fully:
[code="HTML"]<img src="{$IMG*,under_construction_animated}" alt="Under Construction" title="Under Construction" />[/code]
This would insert the image [tt]http://yourbaseurl/themes/default/images/under_construction_animated.png[/tt] into your page, as shown on the right.
The advantage to using the Composr code instead of hand coding the image is two-fold. First, you can have different versions of theme images for different languages and themes. Secondly, if you ever move the image, you don't have to edit every page that ever used it to point to the new location. You can edit images from within the themes management screen (go to Admin Zone > Style > Themes).
[title="2"]Symbols[/title]
[title="3"]Numbers and logic[/title]
Tempcode does not have explicit data-types, everything is text. However we may interpret the text in symbols as follows:
- Tempcode number: the text is assumed to be a number written as a normal decimal string (e.g. 12345). Numbers should not contain any special formatting other than the British English decimal point (.) symbol.
- Tempcode boolean: the text is assumed to be 0 (meaning false) or 1 (meaning true). Actually everything other than 1 is considered false.
[title="3"]Further notes[/title]
If a symbol is missing important parameters, it generally is skipped entirely.
Some of the more advanced symbols are not fully laid-out, but they are all defined in [tt]sources/symbols.php[/tt] or [tt]sources/symbols2.php[/tt] in an obvious way, so advanced users can read this file.
You are very unlikely to ever want to use rows in red, as they are intended for use by core Composr code.
[title="3"]General[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>(blank)</td>
<td>Place a comment. E.g... [/html][tt]{$,this is a comment}[/tt][html]</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$RAND,min,max}</td>
<td>If no parameters are given, it picks a random number between 0 and 2147483647. If one is given it picks a random number between 0 and that parameter. If two are given it picks a number between the first and second parameter.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SET_RAND,a,b,c}</td>
<td>A random choice from the given parameters</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CYCLE,cyclename,a,b,c}</td>
<td>Cycle through parameters in a sequence (intended for use across template calls to create, for example, striping effects). The first parameter is the name of the cycle, and the following parameters are the parameters of the cycle. The pointer for the named cycle will move forward/around each time the cycle symbol is referenced (e.g. [/html][tt]{$CYCLE,mycycle,a,b,c,d}[/tt][html] would produce "a" the first time it's called, "b" the next, "c" next, then "d", then back to "a" again). If you only provide one parameter then the cycles current index is returned. If only two parameters are provided then the second parameter is split up by commas; this is useful for programming cycles on a higher level (e.g. for making chequered patterns using floats).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$RESET_CYCLE,cyclename}</td>
<td>Reset a named cycle sequence</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MAILTO}</td>
<td>Get an obfuscated "mailto: " string (obfuscated to make it hard for e-mail scavengers to detect)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$HONEYPOT_LINK}</td>
<td>If a Project Honeypot script is installed, this will insert a link to it, using a different method for different page names to increase the likeliness of a bot snag.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$INSERT_SPAMMER_BLACKHOLE}</td>
<td>If spammer blackholes are enabled, this inserts a field into a form to create the blackhole. Blackholes allow automatic detection and banning of would-be spammers. Additionally, the CSRF-prevention security token is injected via this symbol.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CSS_DIMENSION_REDUCE,30px,2}</td>
<td>Reduce a CSS dimension by a certain number of px. If the input is not in px, no function is performed and the output stays as the input.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$BETA_CSS_PROPERTY,<css rule>}</td>
<td>Adds browser vendor prefixes to a CSS rule that is not widely supported yet. This effectively marks the CSS rule out, and theoretically allows new Composr versions to alter how that rule is handled without direct changes to your theme CSS.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$REQUIRE_JAVASCRIPT,example}</td>
<td>Include a JavaScript file in the output stream. If you set the second parameter to '1', then loading will be deferred until the end of the page. If you include a template into itself, then it will actually include the original version at the point of your include. This is useful for extending the default templates without duplicating them.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$FACILITATE_AJAX_BLOCK_CALL,block code,differing parameters}</td>
<td>This symbol generates a string parameter suitable for the Composr JavaScript <kbd>call_block</kbd> function, which is used to make an AJAX call to load up a block and overwrite the contents of a specific div with it. Calling this symbol has the side-effects of triggering an include of Composr's AJAX code, and setting up a permission so that the server-side AJAX handler knows that the current session is authorised to load up this pattern of block. The symbol is best used by example -- see how it is currently used by code.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$REQUIRE_CSS,css_example}</td>
<td>Include a CSS file in the output stream</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$ANCHOR,anchorname}</td>
<td>Place a named HTML anchor (intended for use from in Comcode)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$CSS_TEMPCODE}</td>
<td>Get the Tempcode for all the CSS includes for this page</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$PAGE_TITLE}</td>
<td>Get the currently set page title/td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SET_TITLE,xxx}</td>
<td>Set the current page title (affects things like the <kbd><title&rt;</kbd>)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$EXTRA_HEAD}</td>
<td>Get the contents of this global Tempcode variable (used by some parts of the system to inject extra markup)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$EXTRA_FOOT}</td>
<td>Get the contents of this global Tempcode variable (used by some parts of the system to inject extra markup)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$JS_TEMPCODE}</td>
<td>Get the Tempcode for all the JS includes for this page</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Format conversion and obfuscation[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$ESCAPE,what_to_escape,optional_escaping_type}</td>
<td>Perform escaping on the first parameter. Uses the same escaping as integrated template escaping, except a numeric constant (defined in the second parameter) is used to determine the escaping, rather than special characters (see sources/tempcode.php for a list of all the constants). Defaults to HTML escaping.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$OBFUSCATE,to_obfuscate}</td>
<td>Obfuscate a string to make it harder for e-mail scavengers</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$STRIP_TAGS,<strong>example</strong>}</td>
<td>Remove HTML from some text</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$STRIP_HTML,<strong>example</strong>}</td>
<td>Turn some HTML into a plain-text string (i.e. no HTML entities either)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$ENTITY_DECODE,this &amp; that}</td>
<td>Decode XML or HTML entities, so that written-out XML turns into actual parsed XML</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TRUNCATE_LEFT,something long,5,1,0,0,0.2}</td>
<td>Truncate a string, keeping what's on the left as priority. First parameter is the text to truncate. Second parameter is the truncation length. Optional third parameter is a binary value for whether to show a tooltip. Optional fourth parameter is a binary value for whether the input text is already in HTML format (output text is always in HTML format). Optional fifth parameter is a binary value for whether the length desired should be based on readable characters rather than XHTML characters. Optional sixth parameter is a decimal fraction (e.g. 0.2) that represents the tolerance that can be used to preserve grammar (paragraphs and sentence).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TRUNCATE_RIGHT,something long,5,1,0,0,0.2}</td>
<td>As above, truncating to keep what's on the right as priority.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TRUNCATE_SPREAD,something long,5,1,0,0,0.2}</td>
<td>As above, truncating to keep an equal left/right portion.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TRUNCATE_EXPAND,something long,5,1,0,0,0.2}</td>
<td>As above, with any truncated text going underneath an expander.</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$ALTERNATOR_TRUNCATED,something long,5,if truncated,if not truncated,1}</td>
<td>A complex symbol to allow alternation between situations when something would and would not become truncated.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$PARAGRAPH,something}</td>
<td>Add a paragraph around the contents, but only if it does not already contain any block-level elements. This is needed to combine valid (X)HTML for arbitrary Comcode insertion with the desire to have neat semantics and automatic margining.</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$CLEAN_FILE_SIZE,10000}</td>
<td>Convert a number of bytes into a nice clean human readable file size.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TRIM, abc }</td>
<td>Trim any textual or XHTML white-space from the given string.</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$DEEP_CLEAN, abc }</td>
<td>Apply the deep clean process on the parameter. Clean common ugly patterns out, such as leading white-space, all-caps, or paste-from-Word problems.</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Users, Members, and Usergroups[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$MEMBER}</td>
<td>The Member-ID of the current user</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IS_GUEST}</td>
<td>Whether the current user is a Guest</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$USERNAME,2}</td>
<td>The username of the current user / given user (optionally takes a member ID, otherwise assumes the current user). If the second parameter is passed as '1', the display name is used (if configured).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$DISPLAYED_USERNAME,admin}</td>
<td>Turns a username into a display name, using the configured display name generator (if there is one -- otherwise, no change)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$AVATAR,2}</td>
<td>The member's avatar (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MEMBER_EMAIL,2}</td>
<td>The member's e-mail address (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$PHOTO,2}</td>
<td>The member's photo (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MEMBER_PROFILE_URL,2}</td>
<td>The member's profile URL (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CNS_MEMBER_HTML,2}</td>
<td>The member's information box (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CNS_RANK_IMAGE,2}</td>
<td>The member's rank images in composed HTML format (optionally takes a member ID, else assumes current user)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IS_IN_GROUP,1-3}</td>
<td>Find whether the current member is in a usergroup (parameters together constitute an [/html][concept]Selectcode[/concept][html] list, except if the last is primary or secondary then this specifies that the check be limited to checking such usergroup membership).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CPF_VALUE,Some Custom Field}</td>
<td>Find the raw (unrendered) value of a custom profile field (pass in the ID number of a custom profile field, which can be found from the URL of where you to edit it -- or pass in the human-readable name of the field -- or pass in a field name from the <kbd>f_members</kbd> table). If you pass a second parameter, it will specify the member ID to use (if not passed, it will default to the current member). Note that Tempcode is not context-sensitive apart from the parameters passed into a template. The current member is whoever is logged in; if you are editing a template displaying a member's details (e.g. <kbd>CNS_MEMBER_PROFILE_SCREEN</kbd>) then you will need to explicitly specify the member ID in the second parameter using the member ID passed into that template (typically <kbd>{MEMBER_ID}</kbd>).</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Date and time[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$DATE_AND_TIME}</td>
<td>The formatted current date and time (may take optional parameters, not discussed here)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$DATE}</td>
<td>The formatted current date (may take optional parameters, not discussed here)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TIME}</td>
<td>The formatted time (may take optional parameters, not discussed here)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SECONDS_PERIOD,12345}</td>
<td>Show the number of hours/minutes/seconds in a given period of seconds</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$FROM_TIMESTAMP,%d %B %Y,123456780}</td>
<td>Converts a time-stamp to a formatted date/time (optional first parameter is a strftime-style date/time formatting string, optional second parameter is a timestamp). If no parameters given it will simply return the current timestamp. Supports both PHP's <kbd>strftime</kbd> and <kbd>date</kbd> syntaxes, including Composr's [page="_SEARCH:tut_intl"]extensions[/page] such as <kbd>%o</kbd>.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TO_TIMESTAMP,April 1st 2009}</td>
<td>Converts a formatted date/time to a timestamp via auto-recognition (first parameter is a timestamp). If no parameters given it will simply return the current timestamp.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MAKE_RELATIVE_DATE,123456789}</td>
<td>Converts a timestamp into a textually described relative time (e.g. "10 minutes" [ago]).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TIME_PERIOD,1234}</td>
<td>Converts a number of seconds into a textually described time period (e.g. "10 minutes").</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Catalogues[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$CATALOGUE_ENTRY_BACKREFS,123}</td>
<td>Get a comma-separated list of IDs of catalogue entries that reference the given catalogue entry. A second parameter may be given, which is a limit on how many to return. A third parameter may be set as the name of a content type if the backrefs should be resolved to linked content entries (for the case where the linkage is via custom fields rather than a pure catalogue). A fourth parameter of the rating type code may be given if sort-by-rating is needed (highest rated first).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CATALOGUE_ENTRY_FIELD_VALUE,123,0}</td>
<td>Get the value of a field in a specific catalogue entry (example would be 1st field in entry #123).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CATALOGUE_ENTRY_FIELD_VALUE_PLAIN,123,0}</td>
<td>As per <kbd>CATALOGUE_ENTRY_FIELD_VALUE</kbd>, but without any display processing on the value.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CATALOGUE_ENTRY_FOR,download,3}</td>
<td>Get the ID of the auto-maintained catalogue entry bound to the given content entry, i.e. where the content entries custom fields are stored. This can then be used with the <kbd>CATALOGUE_ENTRY_FIELD_VALUE</kbd> symbol (above) or the <kbd>CATALOGUE_ENTRY_ALL_FIELD_VALUES</kbd> symbol (below).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CATALOGUE_ENTRY_ALL_FIELD_VALUES,123}</td>
<td>Show a field-map view of all fields in the entry. You can also pass in a second param with the value '1' if you want raw field rows, rather than a table (useful for adding field-map data into an existing table).</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Galleries[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$GALLERY_VIDEO_FOR_URL,uploads/galleries/foo.mov}</td>
<td>Get the gallery video ID for a named URL, importing to a new video if needed. This is useful for managing documentation out of git, referencing videos that will then be synchronised with Youtube upon first reference. You'll likely use this symbol to pass as a parameter to the <kbd>main_content</kbd> block.</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Locations / Currencies[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$CURRENCY,123,USD}</td>
<td>Do a currency conversion / Get the currency (first parameter is a number for the amount in the site's default currency, second parameter is the source currency, optional third parameter is the target currency [defaults to the site currency])</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CURRENCY_SYMBOL}</td>
<td>Get the nice currency symbol for the site's default currency</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$COUNTRY}</td>
<td>Find the current user's country</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$COUNTRY_CODE_TO_NAME,UK}</td>
<td>Convert an ISO country code to a written country name</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$COUNTRY_NAME_TO_CODE,United Kingdom}</td>
<td>Convert a written country name to an ISO country code</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$REGION}</td>
<td>Find the current user's region (usually the same as the country, but may be customised within Composr to be more-specific)</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Environmental querying[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$_GET,page}</td>
<td>Extract the requested script GET parameter</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IS_VIRTUALISED_REQUEST}</td>
<td>Find if this is a virtualised page load, via something like the <kbd>main_include_module</kbd> block</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$QUERY_STRING}</td>
<td>Extract all requested script parameters (the 'query string', i.e. part of the URL after "?")</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$_POST,title}</td>
<td>Extract the requested script POST parameter</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$_POSTED}</td>
<td>Whether the current request was sent with POST parameters (i.e. it was a form post)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$ZONE}</td>
<td>The zone the user is in</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$PAGE}</td>
<td>The page the user is in</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CANONICAL_URL}</td>
<td>Get the canonical URL (for search engines)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SELF_URL,0,0,0,a=b}</td>
<td>Get URL to current screen. You don't need to give any parameters, but if you do: the first is whether to go to the website home page if you are at where you're at due to a form post, the second is whether to included posted parameters as parameters in the URL, the first is whether to avoid the URL Scheme facility, and further parameters are additional URL parameters.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SELF_PAGE_LINK}</td>
<td>Get page-link to current screen.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$METADATA,created}</td>
<td>Fetch a defined dublin core metadata property (by code name), relating to the current content. Also supports some Facebook connect fields, HTML SEO metadata (keywords, meta_description). You can also query HTML SEO metadata for specific content item, by giving two additional parameters: the content type and the content ID</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$REFRESH}</td>
<td>HTML code for a site refresh, if one is in progress</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$FEEDS}</td>
<td>HTML code for metadata-linkage to RSS/Atom feeds</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$RUNNING_SCRIPT,index}</td>
<td>Find whether an entry script is running</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MATCH_KEY_MATCH,_WILD:downloads:browse}</td>
<td>Whether the given [/html][concept]match-key[/concept][html] matches the current URL</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MOBILE}</td>
<td>Whether a Smartphone (for example) is being used. Composr is designed to be pretty good at detecting this, but if you need to specify additional user agent strings you can make a <kbd>text_custom/mobile_devices.txt</kbd> file with <kbd>mobileuseragentsubstring=0|1</kbd> lines in it (e.g. <kbd>iphone=1</kbd> for iPhone to be detected as mobile, and <kbd>ipad=0</kbd> for iPad to not be detected as mobile). If you want to detect smartphones in CSS we suggest you either use this symbol (which the default theme uses) or if you prefer use <a target="_blank" title="CSS media queries (this link will open in a new window)" href="http://css-tricks.com/css-media-queries/">CSS media queries</a> inside your CSS files to create override rules</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$THEME}</td>
<td>The user's current theme</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$JS_ON}</td>
<td>Whether JavaScript is enabled (Tempcode boolean)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LANG}</td>
<td>The user's current language</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$BROWSER_UA}</td>
<td>The user's browser, based on their user-agent string</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$OS}</td>
<td>The user's OS, based on their user-agent string</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$DEV_MODE}</td>
<td>Whether development mode is on (adds in extra errors, to pick up on coding standard violations)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$NO_SAFE_MODE}</td>
<td>Detect if PHP safe mode isn't on the server</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$BROWSER_MATCHES,wysiwyg}</td>
<td>Find whether the current browser matches a named property / has a feature. Possible properties: wysiwyg, windows, mac, linux, mobile, ie, ie8, ie8+, ie9, ie9+, gecko, safari (covers Google Chrome also), ios, android, bot</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$USER_AGENT}</td>
<td>The user-agent string of the current user</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IP_ADDRESS}</td>
<td>The IP address of the current user</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TIMEZONE}</td>
<td>The server timezone</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$HTTP_STATUS_CODE}</td>
<td>Find the HTTP status code (e.g. 404) for the current request, usually 200</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$BROWSER,wysiwyg,You have WYSIWYG,You do not have WYSIWYG}</td>
<td>Conditionally chooses between two input strings, based on a browser property (see above for a list of properties). First parameter is the property, second and third are the conditional strings.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$GEOLOCATE,12.45.67.89}</td>
<td>Find the/a user's ISO country-code (optionally takes an IP address, otherwise defaults to current user's IP). Requires the stats addon to be installed, and for the geolocation data to have been installed into the database (usually this is automatic)</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$FORCE_PREVIEWS}</td>
<td>Find whether the user has forced previews to show</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$PREVIEW_URL}</td>
<td>Find the URL to perform a preview for the form on the current screen</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$CURRENTLY_INVISIBLE}</td>
<td>Whether the current user is set to be invisible</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$CAN_SPELLCHECK}</td>
<td>Whether spellchecking is possible</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$SESSION}</td>
<td>Get the session ID for the current member</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$VERSION_NUMBER}</td>
<td>Get the Composr version number</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CHARSET}</td>
<td>Get the character set</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$DECIMAL_POINT}</td>
<td>Find the decimal point character for the current locale (e.g. <kbd>.</kbd>)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$HEADER_TEXT}</td>
<td>Get the header text (put in the page title)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SHOW_HEADER}</td>
<td>Whether the header will be shown</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SHOW_FOOTER}</td>
<td>Whether the footer will be shown</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$WIDE}</td>
<td>Whether the side panels will be shown</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$WIDE_HIGH}</td>
<td>Whether the side panels, header, and footer, will be shown</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LOGO_URL}</td>
<td>The logo URL for the current zone</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$HAS_SU}</td>
<td>Whether the current user is allowed to use the Switch User feature</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$STAFF_ACTIONS}</td>
<td>A drop-down of contextual actions for the current screen</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$HELPER_PANEL_TUTORIAL}</td>
<td>The helper panel's tutorial</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$HELPER_PANEL_TEXT}</td>
<td>The helper panel's text</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MESSAGES_TOP}</td>
<td>Attached messages, for prominent display</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MESSAGES_BOTTOM}</td>
<td>Attached messages, for less prominent display</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LATE_MESSAGES}</td>
<td>Attached messages that happened after output started (after main page generation). These will usually be errors relating to the output process itself.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$BREADCRUMBS}</td>
<td>The breadcrumbs</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$FORUM_CONTEXT}</td>
<td>The ID of the forum currently within, or blank</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MATURITY_FILTER_REQUESTED}</td>
<td>Do a header check, to see if family-friendly browsing experience was requested by the user's safe header preference. This symbol only works when Composr is installed on a server with the PHP Apache module, unless a new <kbd>HTTP_PREFER</kbd> server variable is added (see <a href="http://php.net/manual/en/function.apache-request-headers.php">apache-request-headers</a> – read <strong>callum85's</strong> comment for details).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$TAPATALK}</td>
<td>Whether output is being generated for a Tapatalk client</td>
</tr>
</tbody>
</table>
[/html]
[title="3"]Placement, and general Composr interfacing[/title]
[html]
<table class="columned_table results_table wide_table autosized_table">
<thead>
<tr>
<th>Symbol name / example</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr style="background: #DDFFDD">
<td>{$FIND_SCRIPT}</td>
<td>Find the URL to a named Composr entry script (e.g. <kbd>dload</kbd>)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$FIND_SCRIPT_NOHTTP}</td>
<td>Find the URL to a named Composr entry script (e.g. <kbd>dload</kbd>), but as a relative URL to domain name root</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$MAKE_URL_ABSOLUTE,someurl}</td>
<td>Take what may be a relative URL (relative to site base URL), and make sure it is an absolute URL</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$ENSURE_PROTOCOL_SUITABILITY,someurl}</td>
<td>Make sure a URL is safe to embed in the current page if the current page is HTTPS, e.g. by proxying a non-HTTPS URL</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IMG,bottom}</td>
<td>Find a named theme image code's URL (takes the theme image code). Note that this gets the image URL, it does not write the HTML out for an image element based upon it (you need to do that yourself).</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IMG_MTIME,bottom}</td>
<td>Find the last-modification unix timestamp for a theme image. This is useful for adding a cache-busting parameter after an image URL and ?, e.g. <kbd><img src="{$IMG*,bottom}?{$IMG_MTIME%,bottom}" /></kbd>.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IMG_INLINE,bottom}</td>
<td>Find a named theme image code's data URL. It works the same as <kbd>{$IMG,...}</kbd> except the image data gets embedded directly. If there's more than 32kb of data, the normal URL will be used instead.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IMG_WIDTH,bottom}</td>
<td>Find the width of the theme image/URL (particularly useful for making web pages render faster). Uses the persistent cache to remember values, if possible.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$IMG_HEIGHT,bottom}</td>
<td>Find the height of the theme image/URL (particularly useful for making web pages render faster). Uses the persistent cache to remember values, if possible.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$CDN_FILTER,URL}</td>
<td>Take an absolute URL, under the main base URL's domain, and change it to work under the Content Delivery Network. Only use this if you know the particular URL you pass will be available via the CDN.</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$KEEP,0,1}</td>
<td>Stuff to append to a Composr URL for 'keep parameter' passing (Composr passes any parameters between screens if their names start <kbd>keep_</kbd>, and this symbol enables that). The first parameter should be '1' if you need to place this directly on the front of a URL. The second parameter should '1' if you need to always attach a session ID (i.e. if you are creating a link that might be used somewhere outside the current cookie context, e.g. to feed into a download manager)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$EXTEND_URL,http://example.com/index.php?foo=a&bar=b}</td>
<td>Add parameter(s) onto a URL, avoiding unreliable assumptions about how a URL is already structured (URL Schemes may cause a big diversity in the URLs Composr puts out). It puts <kbd>?</kbd> or <kbd>&</kbd> before your parameter correctly based on an analysis of existing URL structure. It does not handle URL encoding of the appended parameter, which you should do first if applicable.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$BLOCK,block=main_search,zone=site}</td>
<td>Place a block into the template. Takes any number of parameters (but at least 1 for the block name), each of which defines a block parameter and its value. Parameters must include the block name, which is encoded against the special reserved name <kbd>block</kbd> (<strong>not</strong> just placed in there as a lone parameter). For example: [/html][tt]{$BLOCK,block=main_news,filter=1\,2\,3}[/tt][html]</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LOAD_PAGE,about,site}</td>
<td>Load a page into a template (first parameter is the page name, optional second parameter is the zone name which defaults to the current zone)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$RATING,downloads,3}</td>
<td>Show a content type's rating. The first parameter is the content-type's code (usually the page name it's viewed from, e.g. downloads) and the second parameter is the ID for the resource. There's an optional third parameter of resource submitter, an optional fourth parameter as the content URL, an optional fifth parameter as the resource title, and an optional sixth parameter as the rating template to use (defaults to showing the raw rating value). Any optional parameters may be left blank to get to the next parameter.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$NUM_RATINGS,downloads,3}</td>
<td>Find the number of users who have rated something.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$SHOW_RATINGS,downloads,3,100}</td>
<td>Show the last 100 ratings on something.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$ALREADY_RATED,downloads,3}</td>
<td>Find if the current user has already rated something.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$VIEWS,download_downloads,download_views,3}</td>
<td>Show how many views a content type has had. The first parameter is the table to read from, the second parameter is the name of the field (it must contain 'views' -- the code will not allow arbitrary field calling for security reasons) the third parameter is the ID for the resource.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$REVIEW_STATUS,download,3}</td>
<td>Show the periodic content review status for the given content, if configured for the content and set as publicly visible.</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LOAD_PANEL,panel_left,site}</td>
<td>Load a panel-page into a template (first parameter is the page name, optional second parameter is the zone name which defaults to the current zone)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$PAGE_LINK,site:about}</td>
<td>Link to a page, using [/html][concept]page-link[/concept][html] syntax (e.g. "_SELF:pagename:type:1")</td>
</tr>
<tr style="background: #FFDDDD">
<td>{$ADDON_INSTALLED,galleries}</td>
<td>Find whether an addon is installed (first parameter is the code-name of the addon)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$AWARD_ID,2}</td>
<td>Find the content ID assigned to the given award</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$NOTIFICATIONS_ENABLED,download,3}</td>
<td>Find whether notifications are enabled for something</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$NOTIFICATIONS_AVAILABLE,download}</td>
<td>Find whether notifications are allowed for this notification type (i.e. not locked down)</td>
</tr>
<tr style="background: #DDFFDD">
<td>{$LAST_VISIT_TIME}</td>
<td>The last visit time of the current user</td>
</tr>
<tr style="background: #DDFFDD">