-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathictemplates.sdf
3365 lines (2298 loc) · 129 KB
/
ictemplates.sdf
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
!init OPT_LOOK="icdevgroup"; OPT_STYLE="manual"
# $Id: ictemplates.sdf,v 1.53 2004-05-05 15:22:30 jon Exp $
!define DOC_NAME "Template Guide"
!define DOC_TYPE ""
!define DOC_CODE "ictemplates"
!define DOC_VERSION substr('$Revision: 1.53 $',11, -2)
!define DOC_STATUS "Draft"
!define DOC_PROJECT "Interchange"
!define DOC_URL "http://www.icdevgroup.org/doc/ictemplates.html"
!build_title
H1: Introduction
Interchange is designed to build its pages based on templates from a database. This document describes how to build templates using the Interchange Tag Language (ITL) and explains the different options you can use in a template.
H2: Overview
The search builder can be used to generate very complex reports on the database or to help in the construction of ITL templates. Select a "Base table" that will be the foundation for the report. Specify the maximum number of rows to be returned at one time, and whether to show only unique entries.
The "Search filter" narrows down the list of rows returned by matching table columns based on various criteria. Up to three separate conditions can be specified. The returned rows must match all criteria.
Finally, select any sorting options desired for displaying the results and narrow down the list of columns returned if desired. Clicking "Run" will run the search immediately and display the results. "Generate definition" will display an ITL tag that can be placed in a template and that will return the results when executed.
To build complex order forms and reports, Interchange has a complete tag language with over 80 different functions called Interchange Tag Language (ITL). It allows access to and control over any of an unlimited number of database tables, multiple shopping carts, user name/address information, discount, tax and shipping information, search of files and databases, and much more.
There is some limited conditional capability with the
E<lbracket>{{C[jump="ictags.html#if"]if}}] tag,
but when doing complex operations, use of embedded Perl/ASP should be strongly considered. Most of the tests use Perl code, but Interchange uses the Safe.pm module with its default restrictions to help ensure that improper code will not crash the server or modify the wrong data.
Perl can also be embedded within the page and, if given the proper permission by the system administrator, call upon resources from other computers and networks.
H1: About Variable Replacement
Variable substitution is a simple and often used feature of Interchange templates. It allows you to set a variable to a particular value in the {{FILE:catalog.cfg}} directory. Then, by placing that variable name on a page, you invoke that value to be used. Before anything else is done on a template, all variable tokens are replaced by variable values. There are three types of variable tokens:
C<__VARIABLENAME__> is replaced by the catalog variable called VARIABLENAME.
C<@@VARIABLENAME@@> is replaced by the global variable called VARIABLENAME.
C<@_VARIABLENAME_@> is replaced by the catalog variable VARIABLENAME if it exists; otherwise, it is replaced by the global variable VARIABLENAME.
For more information on how to use the C<Variable> configuration file directive to set global variables in C<interchange.cfg> and catalog variables in C<catalog.cfg>, see the {{1:Interchange Configuration Guide}}.
H1: Using Interchange Template Tags
This section describes the different template specific tags and functions that are used when building a your templates.
H2: Understanding Tag Syntax
Interchange uses a style similar to HTML, but with [square brackets] replacing
<chevrons>. The parameters that can be passed are similar, where
a parameter="parameter value" can be passed.
\Summary:
!block example
[tag parameter] Tag called with positional parameter
[tag parameter=value] Tag called with named parameter
[tag parameter="the value"] Tag called with space in parameter
[tag 1 2 3] Tag called with multiple positional parameters
[tag foo=1 bar=2 baz=3] Tag called with multiple named parameters
[tag foo=`2 + 2`] Tag called with calculated parameter
[tag foo="[value bar]"] Tag called with tag inside parameter
[tag foo="[value bar]"]
Container text. Container tag.
[/tag]
!endblock
Most tags can accept some positional parameters. This makes parsing faster and
is, in most cases, simpler to write.
The following is an example tag:
!block example
E<lbracket>{{C[jump="ictags.html#value"]value}}C< name=city>]
!endblock
This tag causes Interchange to look in the user form value array and return
the value of the form parameter C<city>, which might have been set with:
!block example
City: <INPUT TYPE=text NAME=city VALUE="[value city]">
!endblock
Note: Keep in mind that the value was pre-set with the value of C<city> (if any).
It uses the positional style, meaning C<name> is the first positional parameter
for the [value ...] tag. Positional parameters cannot be derived from other Interchange tags. For example, [value [value formfield]] will not work. But, if the
named parameter syntax is used, parameters can contain other tags. For example:
!block example
E<lbracket>{{C[jump="ictags.html#value"]value}}C< name="[value formfield]"]>]
!endblock
There are exceptions to the above rule when using list tags such as
E<lbracket>{{C[jump="ictags.html#item-list"]item-list}}],
E<lbracket>{{C[jump="ictags.html#loop"]loop}}],
E<lbracket>{{C[jump="ictags.html#query"]query}}] and others.
These tags, and their exceptions, are explained in their corresponding sections.
Many Interchange tags are container tags. For example:
!block example
E<lbracket>{{C[jump="ictags.html#set"]set}} Checkout]
mv_nextpage=ord/checkout
mv_todo=return
[/set]
!endblock
Tags and parameter names are not case sensitive, so C<[VALUE NAME=something]>
and C<[value name=something]> work the same.
The Interchange development convention is to type HTML tags in upper
case and Interchange tags in lower case. This makes pages and tags easier to read.
Single quotes work the same as double quotes and can prevent confusion. For example:
!block example
[value name=b_city set='[value city]']
!endblock
Backticks should be used with extreme caution since they cause the parameter contents to be evaluated
as Perl code using the E<lbracket>{{C[jump="ictags.html#calc"]calc}}]
tag. For example:
!block example
[value name=row_value set=`$row_value += 1`]
!endblock
is the same as
!block example
[value name=row_value set="E<lbracket>{{C[jump="ictags.html#calc"]calc}}]$row_value += 1[/calc]"]
!endblock
Vertical bars can also be used as quoting characters, but have the unique behavior of stripping leading and trailing whitespace. For example:
!block example
[loop list="
k1 A1 A2 A3
k2 B1 B2 B3"]
[loop-increment][loop-code]
[/loop]
!endblock
could be better expressed as:
!block example
[loop list=|
k1 A1 A2 A3
k2 B1 B2 B3
|]
[loop-increment][loop-code]
[/loop]
!endblock
How the result of the tag is displayed depends on if it is a container or a standalone tag. A container tag has a closing tag (for example, C<[tag] stuff [/tag]>). A standalone tag has no end tag (for example,
E<lbracket>{{C[jump="ictags.html#area"]area}}C< href=somepage>].
Note that
E<lbracket>{{C[jump="ictags.html#page"]page}}] and
E<lbracket>{{C[jump="ictags.html#order"]order}}]
are B<not> container tags. (C<[/page]> and C<[/order]> are simple macros.)
A container tag will have its output re-parsed for more Interchange tags by default. To inhibit this behavior, set the attribute reparse to 0. However, it has been found that the default re-parsing is almost always desirable. On the other hand, the output of a standalone tag will not be re-interpreted for Interchange tag constructs (with some exceptions,
like E<lbracket>{{C[jump="ictags.html#include"]include}}C< file>].
Most container tags will not have their contents interpreted (Interchange tags parsed) before being passed the container text. Exceptions include
E<lbracket>{{C[jump="ictags.html#calc"]calc}}],
E<lbracket>{{C[jump="ictags.html#currency"]currency}}] and
E<lbracket>{{C[jump="ictags.html#seti"]seti}}].
All tags accept the C<interpolate=1> tag modifier, which causes the interpretation to take place.
H2: data and field
The E<lbracket>{{C[jump="ictags.html#data"]data}}] and
E<lbracket>{{C[jump="ictags.html#field"]field}}]
tags access elements of Interchange databases. They are the form used outside of the iterating lists, and are used to do lookups when the table, column/field or key/row is conditional based on a previous operation.
The following are equivalent for attribute names:
!block example
table --> base
col --> field --> column
key --> code --> row
!endblock
The E<lbracket>{{C[jump="ictags.html#field"]field}}]
tag looks in any tables defined as C<ProductFiles>, in that order, for the data and returns the first non-empty value. In most catalogs, where C<ProductFiles> is not defined, i.e., the demo, C<[field title 00-0011]> is equivalent to C<[data products title 00-0011]>. For example, [field col=foo key=bar] will not display something from the table "category" because "category" is not in the directive ProductFiles or there are multiple ProductFiles and an earlier one has an entry for that key.
LI1: E<lbracket>{{C[jump="ictags.html#data"]data}}C< table column key>]
.named attributes: C<[data base="database" field="field" key="key"> C<value="value" op="increment]>
.Returns the value of the field in any of the arbitrary databases or from the variable namespaces. If the option C<increment=1> is present, the field will be automatically incremented with the value in value.
.If a DBM-based database is to be modified, it must be flagged writable on the page calling the write tag. For example, use C<[tag flag write]products[/tag]> to mark the C<products> database writable.
.In addition, the C<[data ...]> tag can access a number of elements in the Interchange session database:
!block example; listitem=2
accesses Accesses within the last 30 seconds
arg The argument passed in a [page ...] or [area ...] tag
browser The user browser string
host Interchange's idea of the host (modified by DomainTail)
last_error The last error from the error logging
last_url The current Interchange path_info
logged_in Whether the user is logged in via UserDB
pageCount Number of unique URLs generated
prev_url The previous path_info
referer HTTP_REFERER string
ship_message The last error messages from shipping
source Source of original entry to Interchange
time Time (seconds since Jan 1, 1970) of last access
user The REMOTE_USER string
username User name logged in as (UserDB)
!endblock
.Databases will hide variables, so if a database is named "session," "scratch," or any of the other reserved names it won't be able to use the C<[data ...]> tag to read them. Case is sensitive, so the database could be called "Session," but this is not recommended practice.
LI1: E<lbracket>{{C[jump="ictags.html#field"]field}}C< name code>]
.named attributes: C<[field code="code" name="fieldname"]>
.Expands into the value of the field name for the product as identified by code found by searching the products database. It will return the first entry found in the series of Product Files in the products database. If this needs to constrained to a particular table, use a C<[data table col key]> call.
H2: set, seti, tmp, tmpn scratch and scratchd
Scratch variables are maintained in the user session, which is separate from the form variable values set on HTML forms. Many things can be controlled with scratch variables, particularly search and order processing, the C<mv_click> multiple variable setting facility and key Interchange conditions session URL display.
There are four tags that are used to set the scratch space:
E<lbracket>{{C[jump="ictags.html#set"]set}}C< variable>] value [/set],
E<lbracket>{{C[jump="ictags.html#seti"]seti}}C< variable>] value [/seti],
E<lbracket>{{C[jump="ictags.html#tmp"]tmp}}C< variable>] value [/tmp],
E<lbracket>{{C[jump="ictags.html#tmpn"]tmpn}}C< variable>] value [/tmpn] and
and two tags for reading scratch space:
E<lbracket>{{C[jump="ictags.html#scratch"]scratch}}C< variable>] and
E<lbracket>{{C[jump="ictags.html#scratchd"]scratchd}}C< variable>].
LI1: E<lbracket>{{C[jump="ictags.html#set"]set}}C< variable>] value [/set]
.Sets a scratchpad variable to a value.
.Most of the mv_* variables that are used for search and order conditionals are in another namespace. They can be set through hidden fields in a form.
.An order profile would be set with:
!block example; listitem=2
[set checkout]
name=required Please enter your name.
address=required No address entered.
[/set]
<INPUT TYPE=hidden NAME=mv_order_profile VALUE="checkout">
!endblock
.A search profile would be set with:
!block example; listitem=2
[set substring_case]
mv_substring_match=yes
mv_case=yes
[/set]
<INPUT TYPE=hidden NAME=mv_profile VALUE="substring_case">
!endblock
.To do the same as C<[set foo]bar[/set]> in embedded Perl:
!block example; listitem=2
[calc]$Scratch->{foo} = 'bar'; return;[/calc]
!endblock
LI1: E<lbracket>{{C[jump="ictags.html#seti"]seti}}C< variable>] value [/seti]
.The same as E<lbracket>{{C[jump="ictags.html#set"]set}}]
except it interpolates the container text. The above is the same as:
!block example; listitem=2
E<lbracket>{{C[jump="ictags.html#set"]set}} name=variable interpolate=1] E<lbracket>{{C[jump="ictags.html#value"]value}} something] [/set]
!endblock
LI1: E<lbracket>{{C[jump="ictags.html#tmp"]tmp}}C< variable>] value [/tmp]
.The same as E<lbracket>{{C[jump="ictags.html#seti"]seti}}]
except it does not persist.
LI1: E<lbracket>{{C[jump="ictags.html#tmpn"]tmpn}}C< variable>] value [/tmpn]
.The same as E<lbracket>{{C[jump="ictags.html#set"]set}}]
except it does not persist.
LI1: E<lbracket>{{C[jump="ictags.html#scratch"]scratch}}C< variable>]
.Returns the contents of a scratch variable to the page. C<[scratch foo]> is the same as, but faster than:
!block example; listitem=2
E<lbracket>{{C[jump="ictags.html#perl"]perl}}] $Scratch->{foo} [/perl]
!endblock
LI1: E<lbracket>{{C[jump="ictags.html#scratchd"]scratchd}}C< variable>]
.The same as E<lbracket>{{C[jump="ictags.html#scratch"]scratch}}C< variable>]
except it deletes the value after returning it. Same as C<[scratch foo] [{{C[jump="ictags.html#set"]set}} foo] [/set]>.
LI1: E<lbracket>{{C[jump="ictags.html#if"]if}}C< scratch name op* compare*]> yes C<[else]> no C<[/else][/if]>
.Tests a scratch variable. See the E<lbracket>{{C[jump="ictags.html#if"]if}}]
tag documentation for more information.
H2: loop
Loop lists can be used to construct arbitrary lists based on the contents of a database field, a search or other value (like a fixed list). Loop accepts a C<search> parameter that will do one-click searches on a database table (or file).
To iterate over all keys in a table, use the idiom (C<[loop search="ra=yes/ml=9999"] [/loop]>. C<ra=yes> sets C<mv_return_all>, which means "match everything". C<ml=9999> limits matches to that many records. If the text file for searching an Interchange DBM database is not used, set C<st=db> (mv_searchtype).
When using C<st=db>, returned keys may be affected by C<TableRestrict>. Both can be sorted with C<[sort table:field:mod -start +number]> modifiers. See {{C[jump="icdatabase.html#Sorting"]sorting}}.
The Interchange Tags Reference has more information on the
E<lbracket>{{C[jump="ictags.html#loop"]loop}}] tag.
LI1: E<lbracket>{{C[jump="ictags.html#loop"]loop}}C< item item item]> LIST C<[/loop]>
.named attributes: C<[loop prefix=label* list="item item item"* search="se=whatever"*]>
.Returns a string consisting of the LIST, repeated for every item in a comma-separated or space-separated list. This tag works the same way as the C<[item-list]> tag, except for order-item-specific values. It is intended to pull multiple attributes from an item modifier, but can be useful for other things, like building a pre-ordained product list on a page.
.Loop lists can be nested by using different prefixes:
!block example; listitem=2
[loop prefix=size list="Small Medium Large"]
[loop prefix=color list="Red White Blue"]
[color-code]-[size-code]<BR>
[/loop]
<P>
[/loop]
!endblock
.This will output:
!block example; listitem=2
Red-Small
White-Small
Blue-Small
Red-Medium
White-Medium
Blue-Medium
Red-Large
White-Large
Blue-Large
!endblock
.The search="args" parameter will return an arbitrary search, just as in a one-click search:
!block example; listitem=2
[loop search="se=Americana/sf=category"]
[loop-code] [loop-field title]
[/loop]
!endblock
.The above will show all items with a category containing the whole world "Americana."
LI1: E<lbracket>{{C[jump="ictags.html#if-PREFIX-data"]if-loop-data}}C< table field]> IF C<[else]> ELSE C<[/else][/if-loop-data]>
.Outputs the IF if the C<field> in the C<table> is not empty or the ELSE (if any) otherwise.
Note: This tag does not nest with other C<if-loop-data> tags.
LI1: E<lbracket>{{C[jump="ictags.html#if-PREFIX-field"]if-loop-field}}] IF C<[else]> ELSE C<[/else][/if-loop-field]>
.Outputs the IF if the C<field> in the C<products> table is not empty or the ELSE (if any) otherwise.
Note: This tag does not nest with other C<if-loop-field> tags.
LI1: [loop-alternate N] DIVISIBLE [else] NOT DIVISIBLE [/else][/loop-alternate]
.Set up an alternation sequence. If the loop-increment is divisible by C<N>, the text will be displayed. If C<[else]NOT DIVISIBLE TEXT [/else]> is present, then the NOT DIVISIBLE TEXT will be displayed. For example:
!block example; listitem=2
[loop-alternate 2]EVEN[else]ODD[/else][/loop-alternate]
[loop-alternate 3]BY 3[else]NOT by 3[/else][/loop-alternate]
!endblock
LI1: [/loop-alternate]
.Terminates the alternation area.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-change"]loop-change}}C< marker>]
.Same as C<[item-change]>, but within loop lists.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-code"]loop-code}}]
.Evaluates to the first returned parameter for the current returned record.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-data"]loop-data}}C< database fieldname>]
.Evaluates to the field name fieldname in the arbitrary database table database for the current item.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-description"]loop-description}}]
.Evaluates to the product description for the current item. Returns the <Description Field> from the first products database where that item exists.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-field"]loop-field}}C< fieldname>]
.The E<lbracket>{{C[jump="ictags.html#PREFIX-field"]loop-field}}]
.The E<lbracket>{{C[jump="ictags.html#PREFIX-field"]loop-field}}] tag is special in that it looks in any of the tables defined as C<ProductFiles>, in that order, for the data and returns the value only if that key is defined. In most catalogs, where C<ProductFiles> is not defined C<[loop-field title]> is equivalent to
E<lbracket>{{C[jump="ictags.html#PREFIX-data"]loop-field}}C< products title>].
.Evaluates to the field name fieldname in the database for the current item.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-increment"]loop-increment}}]
.Evaluates to the number of the item in the list. Used for numbering items in the list. Starts from one (1).
LI1: [loop-last]tags[/loop-last]
.Evaluates the output of the ITL tags encased in the [loop-last] tags. If it evaluates to a numerical non-zero number (for example, 1, 23, -10 etc.), the loop iteration will terminate. If the evaluated number is negative, the item itself will be skipped. If the evaluated number is positive, the item itself will be shown, but will be last on the list.
!block example; listitem=2
[loop-last][calc]
return -1 if '[loop-field weight]' eq '';
return 1 if '[loop-field weight]' < 1;
return 0;
[/calc][/loop-last]
!endblock
.If this is contained in your C<[loop list]> and the weight field is empty, a numerical C<-1> will be output from the C<[calc][/calc]> tags; the list will end and the item will B<not> be shown. If the product's weight field is less than 1, a numerical 1 is output. The item will be shown, but it will be the last item on the list.
LI1: [loop-next]tags[/loop-next]
.Evaluates the output of the ITL tags encased in the [loop-next] tags. If it evaluates to a numerical non-zero number (for example, 1, 23, -10 etc.), the loop will be skipped with no output. Example:
!block example; listitem=2
[loop-next][calc][loop-field weight] < 1[/calc][/loop-next]
!endblock
.If this is contained in your C<[loop list]> and the product's weight field is less than 1, a numerical C<1> will be output from the C<[calc][/calc]> operation. The item will not be shown.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-price"]loop-price}}C< n* noformat*>]
.Evaluates to the price for the optional quantity n (from the products file) of the current item, with currency formatting. If the optional "noformat" is set, then currency formatting will not be applied.
LI1: E<lbracket>{{C[jump="ictags.html#PREFIX-calc"]loop-calc}}] PERL C<[/loop-calc]>
.Calls embedded Perl with the code in the container. All C<[loop-*]> tags can be placed inside except for C<[loop-filter ...][/loop-filter]>, C<[loop-exec routine][/loop-exec]>, C<[loop-last][/loop-last]> and C<[loop-next][/loop-next]>.
Note: All normal embedded Perl operations can be used, but be careful to pre-open any database tables with a [perl tables="tables you need"][/perl] tag prior to the opening of the [loop].
LI1: [loop-exec routine]argument[/loop-exec]
.Calls a subroutine predefined either in catalog.cfg with Sub or in a
E<lbracket>{{C[jump="ictags.html#loop"]loop}}]
with C<[loop-sub routine]> PERL C<[/loop-sub]>. The container text is passed as C<$_[0]> and the array (or hash) value of the current row is C<$_[1]>.
LI1: [loop-sub routine]PERL[/loop-sub]
.Defines a subroutine that is available to the current (and subsequent) C<[loop-*]> tags within the same page. See {{CMD[jump="#Programming"]Interchange Programming}}.
H2: if
LI1: E<lbracket>{{C[jump="ictags.html#if"]if}}C< type field op* compare*>]
The Interchange Tags Reference has more information on the
E<lbracket>{{C[jump="ictags.html#if"]if}}] tag.
.named attributes: C<[if type="type" term="field" op="op" compare="compare"]>
LI1: [if !type field op* compare*]
.named attributes: C<[if type="!type" term="field" op="op" compare="compare"]>
Allows the conditional building of HTML based on the setting of various Interchange
session and database values. The general form is:
!block example; listitem=1
[if type term op compare]
[then]
If true, this text is printed on the document.
The [then] [/then] is optional in most
cases. If ! is prepended to the type
setting, the sense is reversed and
this text will be output for a false condition.
[/then]
[elsif type term op compare]
Optional, tested when if fails.
[/elsif]
[else]
Optional, printed on the document when all above fail.
[/else]
[/if]
!endblock
The E<lbracket>{{C[jump="ictags.html#if"]if}}] tag can also have some variants:
!block example; listitem=1
[if explicit]
[condition] CODE [/condition]
Displayed if valid Perl CODE returns a true value.
[/if]
!endblock
Some Perl-style regular expressions can be written:
!block example; listitem=1
[if value name =~ /^mike/i]
This is the if with Mike.
[elsif value name =~ /^sally/i]
This is an elsif with Sally.
[/elsif]
[elsif value name =~ /^barb/i]
[or value name =~ /^mary/i]
This is an elsif with Barb or Mary.
[elsif value name =~ /^pat/i]
[and value othername =~ /^mike/i]
This is an elsif with Pat and Mike.
[/elsif]
[else]
This is the else, no name I know.
[/else]
[/if]
!endblock
While the named parameter tag syntax works for C<[if ...]>, it is more convenient to use the positional syntax in most cases. The only exception is when you are planning to do a test on the results of another tag sequence:
This will not work:
!block example
[if value name =~ /[value b_name]/]
Shipping name matches billing name.
[/if]
!endblock
Do this instead:
!block example
[if type=value term=name op="=~" compare="/[value b_name]/"]
Shipping name matches billing name.
[/if]
!endblock
As an alternative:
!block example
[if type=value term=high_water op="<" compare="[shipping noformat=1]"]
The shipping cost is too high, charter a truck.
[/if]
!endblock
There are many test targets available. The following is a list of some of the available test targets.
LI1: config Directive
.The Interchange configuration variables. These are set by the directives in the Interchange configuration file.
!block example; listitem=2
[if config CreditCardAuto]
Auto credit card validation is enabled.
[/if]
!endblock
LI1: data database::field::key
.The Interchange databases. Retrieves a field in the database and returns true or false based on the value.
!block example; listitem=2
[if data products::size::99-102]
There is size information.
[else]
No size information.
[/else]
[/if]
[if data products::size::99-102 =~ /small/i]
There is a small size available.
[else]
No small size available.
[/else]
[/if]
!endblock
.If another tag is needed to select the key, and it is not a looping tag construct, named parameters must be used:
!block example; listitem=2
[set code]99-102[/set]
[if type=data term="products::size::[scratch code]"]
There is size information.
[else]
No size information.
[/else]
[/if]
!endblock
LI1: discount
.Checks to see if a discount is present for an item.
!block example; listitem=2
[if discount 99-102]
This item is discounted.
[/if]
!endblock
LI1: explicit
.A test for an explicit value. If Perl code is placed between a C<[condition]> C<[/condition]> tag pair, it will be used to make the comparison. Arguments can be passed to import data from user space, just as with the
E<lbracket>{{C[jump="ictags.html#perl"]perl}}] tag.
!block example; listitem=2
[if explicit]
[condition]
$country = $ values =~{country};
return 1 if $country =~ /u\.?s\.?a?/i;
return 0;
[/condition]
You have indicated a US address.
[else]
You have indicated a non-US address.
[/else]
[/if]
!endblock
.The same thing could be accomplished with C<[if value country =~ /u\.?s\.?a?/i]>, but there are many situations where this example could be useful.
LI1: file
.Tests for the existence of a file. This is useful for placing image tags only if the image is present.
!block example; listitem=2
[if file /home/user/www/images/[item-code].gif]
<IMG SRC="[item-code].gif">
[/if]
or
[if type=file term="/home/user/www/images/[item-code].gif"]
<IMG SRC="[item-code].gif">
[/if]
!endblock
.The C<file> test requires that the SafeUntrap directive contain C<ftfile> (which is the default).
LI1: items
.The Interchange shopping carts. If not specified, the cart used is the main cart. This is usually used to test to see if anything is in the cart. For example:
!block example; listitem=2
[if items]You have items in your shopping cart.[/if]
[if items layaway]You have items on layaway.[/if]
!endblock
LI1: ordered
.Order status of individual items in the Interchange shopping carts. Unless otherwise specified, the cart used is the main cart. The following items refer to a part number of 99-102.
!block example; listitem=2
{{2:[if ordered 99-102] ... [/if]}}
Checks the status of an item on order, true if item
99-102 is in the main cart.
{{2:[if ordered 99-102 layaway] ... [/if]}}
Checks the status of an item on order, true if item
99-102 is in the layaway cart.
{{2:[if ordered 99-102 main size] ... [/if]}}
Checks the status of an item on order in the main cart,
true if it has a size attribute.
{{2:[if ordered 99-102 main size =~ /large/i] ... [/if]}}
Checks the status of an item on order in the main cart,
true if it has a size attribute containing 'large'.
THE CART NAME IS REQUIRED IN THE OLD SYNTAX. The new
syntax for that one would be:
[if type=ordered term="99-102" compare="size =~ /large/i"]
To make sure it is the size that is large and not another attribute,
you could use:
[if ordered 99-102 main size eq 'large'] ... [/if]
{{2:[if ordered 99-102 main lines] ... [/if]}}
Special case -- counts the lines that the item code is
present on. (Only useful, of course, when mv_separate_items
or SeparateItems is defined.)
!endblock
LI1: scratch
.The Interchange scratchpad variables, which can be set with the C<[set name] value [/set]> element.
!block example; listitem=2
[if scratch mv_separate_items]
Ordered items will be placed on a separate line.
[else]
Ordered items will be placed on the same line.
[/else]
[/if]
!endblock
LI1: session
.The Interchange session variables. Of particular interest are logged_in, source, browser and username.
LI1: validcc
.A special case, it takes the form C<[if validcc no type exp_date]>. Evaluates to true if the supplied credit card number, type of card and expiration date pass a validity test. It performs a LUHN-10 calculation to weed out typos or phony card numbers.
LI1: value
.The Interchange user variables, typically set in search, control or order forms. Variables beginning with C<mv_> are Interchange special values and should be tested and used with caution.
=item variable
See Interchange I<Variable> values.
=back
The field term is the specifier for that area. For example, C<[if session frames]> would return true if the C<frames> session parameter was set.
As an example, consider buttonbars for frame-based setups. You might decide to display a different buttonbar with no frame targets for sessions that are not using frames:
!block example
[if session frames]
[buttonbar 1]
[else]
[buttonbar 2]
[/else]
[/if]
!endblock
Another example might be the when search matches are displayed. If using the string C<[value mv_match_count] titles found>, it will display a plural result even if there is only one match. Use:
!block example
[if value mv_match_count != 1]
[value mv_match_count] matches found.
[else]
Only one match was found.
[/else]
[/if]
!endblock
The op term is the compare operation to be used. Compare operations are the same as they are in Perl:
!block example
== numeric equivalence
eq string equivalence
> numeric greater-than
gt string greater-than
< numeric less-than
lt string less-than
!= numeric non-equivalence
ne string equivalence
!endblock
Any simple Perl test can be used, including some limited regex matching. More complex tests should be done with C<[if explicit]>.
LI1: [then] text [/then]
.This is optional if not nesting "if" conditions. The text immediately following the C<[if ..]> tag is used as the conditionally substituted text. If nesting C<[if ...]> tags, use C<[then][/then]> on any outside conditions to ensure proper interpolation.
LI1: [elsif type field op* compare*]
.named attributes: C<[elsif type="type" term="field" op="op" compare="compare"]>
.Additional conditions for test, applied if the initial C<[if ..]> test fails.
LI1: [else] text [/else]
.The optional else-text for an if or if-item-field conditional.
LI1: [condition] text [/condition]
.Only used with the C<[if explicit]> tag. Allows an arbitrary expression B<in Perl> to be placed inside, with its return value interpreted as the result of the test. If arguments are added to C<[if explicit args]>, those will be passed as arguments in the
E<lbracket>{{C[jump="ictags.html#perl"]perl}}] construct.
LI1: [/if]
.Terminates an if conditional.
H1: Programming
Interchange has a powerful paradigm for extending and enhancing its functionality. It uses two mechanisms, user-defined tags and user subroutines on two different security levels, global and catalog. In addition, embedded Perl code can be used to build functionality into pages.
User-defined tags are defined with the UserTag directive in either C<interchange.cfg> or C<catalog.cfg>. The tags in C<interchange.cfg> are global and they are not constrained by the C<Safe> Perl module as to which opcodes and routines they may use. The user-defined tags in C<catalog.cfg> are constrained by C<Safe>. However, if the C<AllowGlobal> global directive is set for the particular catalog in use, its UserTag and C<Sub> definitions will have global capability.
H2: Overriding Interchange Routines
Many of the internal Interchange routines can be accessed by programmers who can read the source and find entry points. Also, many internal Interchange routines can be overridden:
!block example
GlobalSub <<EOS
sub just_for_overriding {
package Vend::Module;
use MyModule;
sub to_override {
&MyModule::do_something_funky($Values->{my_variable});
}
}
EOS
!endblock
The effect of the above code is to override the C<to_override> routine in the module C<Vend::Module>. This is preferable to hacking the code for functionality changes that are not expected to change frequently. In most cases, updating the Interchange code will not affect the overridden code.
Note:Internal entry points are not guaranteed to exist in future versions of Interchange.
H2: Embedding Perl Code
Perl code can be directly embedded in Interchange pages. The code is specified as:
!block example
[perl]
$name = $Values->{name};
$browser = $Session->{browser};
return "Hi, $name! How do you like your $browser?";
[/perl]
!endblock
ASP syntax can be used with:
!block example
[mvasp]
<%
$name = $Values->{name};
$browser = $Session->{browser};
%>
Hi, <%= $name %>!
<%
HTML "How do you like your $browser?";
%>
[/mvasp]
!endblock
The two examples above are essentially equivalent. See the {{C[jump="ictags.html#perl"]perl}} and {{C[jump="ictags.html#mvasp"]mvasp}} tags for usage details.
The C<[{{CMD[jump="ictags.html#perl"]perl}}]> tag enforces {{CMD[jump="http://www.perl.com/pub/doc/manual/html/lib/Safe.html"]Safe.pm}} checking, so many standard Perl operators are not available. This prevents user access to all files and programs on the system without the Interchange daemon's permissions. See {{C[jump="icconfig.html#GlobalSub *global*"]GlobalSub}} and {{C[jump="ictags.html#User-defined Tags"]User-defined Tags}} for ways to make external files and programs available to Interchange.
.Named parameters:
.See the {{C[jump="ictags.html#perl"]perl}} tag for a description of the tag parameters and attributes. These N<include:>
!block example
[perl tables="tables-to-open"*
subs=1*
global=1*
no_return=1*
failure="Return value in case of compile or runtime error"*
file="include_file"*]
!endblock
.Required parameters: none
Any Interchange tag (except ones using SQL) can be accessed using the C<$Tag> object. If using SQL queries inside a Perl element, C<AllowGlobal> permissions are required and and the C<global=1> parameter must be set. Installing the module C<Safe::Hole> along with sharing the database table with <tables=tablename> will enable SQL use.
.For example:
!block example; listitem=2
# If the item might contain a single quote
[perl]
$comments = $Values->{comments};
[/perl]
!endblock
Note[label='Important Note: '] Global subroutines are not subject to the stringent security check from the C<Safe> module. This means that the subroutine will be able to modify any variable in Interchange and will be able to write to read and write any file that the Interchange daemon has permission to write. Because of this, the subroutines should be used with caution. They are defined in the main C<interchange.cfg> file and can't be reached by from individual users in a multi-catalog system.
Global subroutines are defined in C<interchange.cfg> with the C<GlobalSub> directive or in user catalogs which have been enabled through C<AllowGlobal>. Catalog subroutines are defined in C<catalog.cfg>, with the C<Sub> directive and are subject to the stringent Safe.pm security restrictions that are controlled by the global directive C<SafeUntrap>.
The code can be as complex as you want them to be, but cannot be used by operators that modify the file system or use unsafe operations like "system," "exec," or backticks. These constraints are enforced with the default permissions of the standard Perl module {{B:Safe}}. Operations may be untrapped on a system-wide basis with the C<SafeUntrap> directive.
The result of this tag will be the result of the last expression evaluated, just as in a subroutine. If there is a syntax error or other problem with the code, there will be no output.
Here is a simple one which does the equivalent of the classic hello.pl program:
!block example
[perl] my $tmp = "Hello, world!"; $tmp; [/perl]
!endblock
There is no need to set the variable. It is there only to show the capability.
To echo the user's browser, but within some HTML tags:
!block example
[perl]
my $html = '<H5>';
$html .= $Session->{browser};
$html .= '</H5>';
$html;
[/perl]
!endblock
To show the user their name and the current time:
!block example
[perl]
my $string = "Hi, " . $Values->{name} ". The time is now ";
$string .= $Tag->time();
$string;
[/perl]
!endblock
H2: ASP-Like Perl
Interchange supports an ASP-like syntax using the E<lbracket>{{C[jump="ictags.html#mvasp"]mvasp}}] tag.
!block example
[mvasp]
<HTML><BODY>
This is HTML.<BR>
<% HTML "This is code<BR>"; %>
More HTML.<BR>
<% $Document->write("Code again.<BR>") %>
[/mvasp]
!endblock
If no closing C<[/mvasp]> tag is present, the remainder of the page will also be seen as ASP.
ASP is simple. Anything between <% and %> is code, and the string %> can not occur anywhere inside. Anything not between those anchors is plain HTML that is placed unchanged on the page. Interchange variables, C<[L][/L]> and C<[LC][/LC]> areas will still be inserted, but any Interchange tags will not.
There is a shorthand <% = $foo %>, which is equivalent to <% $Document->write($foo); %> or <% HTML $foo; %>
!block example
[mvasp]
<HTML><BODY>
This is HTML.<BR>
[value name] will show up as [value name].<BR>
__VARIABLE__ value is equal to: __VARIABLE__
<% = "This is code<BR>" %>
!endblock
The C<__VARIABLE__> will be replaced by the value of C<Variable VARIABLE>, but [value name] will be shown unchanged.
!block note; label="Important Note: "
If using the C<SQL::Statement> module, the catalog must be set to C<AllowGlobal> in C<interchange.cfg>. It will not work in "Safe" mode due to the limitations of object creation in Safe. Also, the C<Safe::Hole> module must be installed to have SQL databases work in Safe mode.
!endblock
H2: Error Reporting
If your Perl code fails with a compile or runtime error, Interchange writes the error message from the Perl interpreter into the catalog's error log. This is usually 'I<catalog_root>/error.log'. Error messages do not appear on your web page as the return value of the Perl tag or routine.
You will not have direct access to the 'C<strict>' and 'C<warnings>' pragmas where Interchange runs your perl code under C<Safe> (for example, within a [perl] or [mvasp] tag).
H1: Interchange Perl Objects
.Interchange gives you access to the power of Perl with the [perl], [calc] and
.[mvasp] tags. They all support the same set of Perl objects and variables.
H2: A note about Safe
You can access all objects associated with the catalog and the user settings with opcode restrictions based on the standard Perl module {{C[jump="http://www.perl.com/pub/doc/manual/html/lib/Safe.html"]Safe.pm}}. There are some unique things to know about programming with Interchange.
Under C<Safe>, certain things cannot be used. For instance, the following can not be used when running Safe:
!block example
$variable = `cat file/contents`;
!endblock
The backtick operator violates a number of the default Safe opcode restrictions. Also, direct file opens can not be used. For example:
!block example
open(SOMETHING, "something.txt")
or die;
!endblock
This will also cause a trap, and the code will fail to compile. However, equivalent Interchange routines can be used:
!block example
# This will work if your administrator doesn't have NoAbsolute set
$users = $Tag->file('/home/you/list');
# This will always work, file names are based in the catalog directory
$users = $Tag->file('userlist');
!endblock
H2: Standard objects and variables
The following is a list of Interchange Perl standard objects are:
LI1: $CGI
.This is a hash reference to C<%CGI::values>, the value of user variables as submitted in the current page/form. To get the value of a variable submitted as
!block example; listitem=2
<INPUT TYPE=hidden NAME=foo VALUE=bar>
!endblock
.use
!block example; listitem=2
[perl]
return "Value of foo is $CGI->{foo}";