File: developer-guide.xml

package info (click to toggle)
velocity 1.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 6,000 kB
  • ctags: 5,029
  • sloc: java: 37,878; xml: 14,959; sh: 172; makefile: 27; jsp: 24; sql: 18
file content (2737 lines) | stat: -rw-r--r-- 96,031 bytes parent folder | download
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
<?xml version="1.0" encoding="UTF-8"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one
 or more contributor license agreements.  See the NOTICE file
 distributed with this work for additional information
 regarding copyright ownership.  The ASF licenses this file
 to you under the Apache License, Version 2.0 (the
 "License"); you may not use this file except in compliance
 with the License.  You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.    
-->

<document>

 <properties>
  <title>Developer's Guide</title>
  <author email="dev@velocity.apache.org">Velocity Documentation Team</author>
 </properties>

<body>

<section name="Developer Guide - Contents" href="developer_guide_-_contents">

<p>
<ol>

<li>
<a href="#Introduction">Introduction and Getting Started</a>
</li>

<li>
<a href="#Resources">Resources</a>
</li>

<li>
<a href="#How_Velocity_Works">How Velocity Works</a>
<ul>
 <li><a href="#thefundamentalpattern">The Fundamental Pattern</a></li>
</ul>
</li>

<li>
<a href="#To_Singleton_Or_Not_To_Singleton...">To Singleton Or Not To Singleton...</a>
<ul>
  <li><a href="#singleton">Singleton Model</a></li>
  <li><a href="#separate">Separate Instance</a></li>
</ul>
</li>

<li>
<a href="#The_Context">The Context</a>
<ul>
<li><a href="#thebasics">The Basics</a></li>
<li><a href="#supportforiterativeobjectsforforeach">Support for Iterative Objects for #foreach()</a></li>
<li><a href="#supportforstaticclasses">Support for "Static Classes"</a></li>
<li><a href="#contextchaining">Context Chaining</a></li>
<li><a href="#objectscreatedinthetemplate">Objects Created by the Template</a></li>
<li><a href="#othercontextissues">Other Context Issues</a></li>
</ul>
</li>

<li>
<a href="#Using_Velocity">Using Velocity in General Applications</a>
<ul>
<li><a href="#thevelocityhelperclass">The Velocity Helper Class</a></li>
<li><a href="#exceptions">Exceptions</a></li>
<li><a href="#miscellaneousdetails">Miscellaneous Details</a></li>
</ul>
</li>

<li>
  <a href="#Application_Attributes">Application Attributes</a>
</li>

<li>
<a href="#Configuring_Event_Handlers">Configuring Event Handlers</a>
</li>

<li>
<a href="#Velocity_Configuration_Keys_and_Values">Velocity Configuration Keys and Values</a>
</li>

<li>
<a href="#Configuring_Logging">Configuring Logging</a>
 <ul>
  <li>
    <a href="#usinglog4jwithexistinglogger">Using Log4j With Existing Logger</a>
  </li>
  <li>
    <a href="#simpleexampleofacustomlogger">Simple Example of a Custom Logger</a>
  </li>
 </ul>
</li>

<li>
<a href="#Configuring_Resource_Loaders">Configuring the Resource Loaders (template loaders)</a>
<ul>
  <li>
    <a href="#resourceloaders">Resource Loaders</a>
  </li>
  <li>
    <a href="#configurationexamples">Configuration Examples</a>
  </li>
  <li>
    <a href="#resourcemanagerandcache">Pluggable Resource Manager and Resource Cache</a>
  </li>
 </ul>
</li>

<li>
<a href="#Template_Encoding_for_Internationalization">Template Encoding for Internationalization</a>
</li>

<li>
<a href="#Velocity_and_XML">Velocity and XML</a>
</li>

<li>
<a href="#Summary">Summary</a>
</li>

</ol>
</p>
</section>

<section name="Introduction" href="Introduction">
<p>
Velocity is a Java-based template engine, a simple and powerful development tool
that allows you to easily create and render documents that format and present
your data. In this guide, we hope to give an overview of the basics of
development using Velocity.

<p>
<strong>Building Web Applications with Velocity</strong>
</p>
Velocity is often used for building web applications
In order to use Velocity in a web app you'll need a servlet or servlet-based
framework. The easiest way to get started is with
<a href="http://velocity.apache.org/tools/devel/view/">VelocityViewServlet</a> in the
<a href="http://velocity.apache.org/tools/devel/">Velocity Tools</a>
subproject.  You can also use any of a number of
<a href="http://wiki.apache.org/velocity/PoweredByVelocity">third party frameworks</a>
or build your own servlet using the techniques described in this document.
</p>

<p>
We suggest you read this article on
<a href="../webapps.html">getting started with web applications</a> for
more detail on the various options.
</p>

<p>
<strong>Downloading Velocity</strong>
</p>

<p>
    You can download the latest release version of
    <a href="http://velocity.apache.org/download.cgi#engine">Velocity</a>
    or <a href="http://velocity.apache.org/download.cgi#tools">Velocity Tools</a>
    from the main Apache Velocity download site.  For Velocity itself, source is included with the binary download.
</p>

<p>
    If you want to download the latest source, you can do so via the Subversion (svn)
    source control system, or download a complete
    <a href="http://svn.apache.org/snapshots/velocity/">nightly snapshot.</a>
</p>

<p>
    Instructions for building Velocity from source can be found in the
    <a href="build.html">Build</a> document.
</p>


<strong>Dependencies</strong>

<p>
Velocity uses elements of the Java 2 API such as collections, and therefore
building requires the Java 2 Standard Edition SDK (Software Development Kit).
To run Velocity, the Java 2 Standard Edition RTE (Run Time Environment)
is required (or you can use the SDK, of course).
</p>
<p>
Velocity also is dependent upon a few packages for general functionality.  They
are included in the <code>build/lib</code> directory for convenience, but
the default build target (see above) does not include them.  If you use the
default build target, you must add the dependencies to your classpath.
</p>

<ul>
<li>
  <a href="http://jakarta.apache.org/commons/collections">
  <b>Jakarta Commons Collections</b></a> - required.
</li>
<li>
  <a href="http://jakarta.apache.org/commons/lang">
  <b>Jakarta Commons Lang</b></a> - required.
</li>
<li>
  <a href="http://excalibur.apache.org/logger.html">
  <b>Excalibur (ex-Avalon) Logkit</b></a> - optional, but very common.
  Needed if using the default file-based logging in Velocity.
</li>
<li>
  <a href="http://jakarta.apache.org/oro/index.html"><b>Jakarta ORO</b></a>
   - optional.  Needed when using the
   <code>org.apache.velocity.convert.WebMacro</code> template conversion
   utility.
 </li>
</ul>


</section>

<section name="Resources" href="Resources">
<p>
There are quite a few resources and examples available to the programmer, and we
recommend that you look at our examples, documentation and even the source code.
Some great sources are:
</p>

<ul>
  <li>
     The user and developer community: join us via the
     <a href="http://velocity.apache.org/contact.html">mail-lists</a>. Mail list archives are available from that page, too.
  </li>
  <li>
    Wiki:
    <a href="http://wiki.apache.org/velocity/">http://wiki.apache.org/velocity/</a>
    The Velocity wiki contains articles, sample code, and other community-written content.
  </li>
  <li>
    Frequently Asked Questions (FAQ):
    <a href="http://wiki.apache.org/velocity/VelocityFAQ">http://wiki.apache.org/velocity/VelocityFAQ</a>
    please visit this page to read the latest FAQ and to contribute your own answers.
  </li>
  <li>
    source code: <code>src/java/...</code>: all the source code to the
    Velocity project
  </li>
  <li>
    application example 1: <code>examples/app_example1</code>: a simple
    example showing how to use Velocity in an application program.
  </li>
  <li>
    application example 2: <code>examples/app_example2</code>: a simple
    example showing how to use Velocity in an application program using the
    Velocity application utility class.
  </li>
  <li>
    logger example: <code>examples/logger_example</code>: a simple example
    showing how to create a custom logging class and register it with
    Velocity to receive all log messages.
  </li>
  <li>
    XML example: <code>examples/xmlapp_example</code>: a simple example
    showing how to use JDOM to read and access XML document data from
    within a Velocity template.  It also includes a demonstration of
    a recursive Velocimacro that walks the document tree.
  </li>
 <li>
    event example: <code>examples/event_example</code>: An example that
    demonstrates the use of the event handling API.
  </li>
  <li>
    Anakia application: <code>examples/anakia</code>: example application
    showing how to use Velocity for creating stylesheet renderings of xml data
  </li>
  <li>
    documentation: <code>docs</code>: all the generated documentation for the
    Velocity project in html
  </li>
  <li>
    API documentation: <code>docs/api</code>: the generated Javadoc
    documentation for the Velocity project
  </li>
  <li>
    templates: <code>test/templates</code>: a large collection of template
    examples in our testbed directory, these are a great source of useage
    examples of VTL, the Velocity Template Language
  </li>
  <li>
    context example: <code>examples/context_example</code>: two examples
    showing how the Velocity context can be extended. For advanced users.
  </li>
</ul>

<p>
All directory references above are relative to the distribution root directory.
</p>
</section>

<section name="How Velocity Works" href="How_Velocity_Works">

<p>
<a name="thefundamentalpattern"><strong>'The Fundamental Pattern'</strong></a>
</p>

<p>
When using Velocity in an application program or in a servlet
(or anywhere, actually), you will generally do the following:
</p>

<ol>
<li>Initialize Velocity. This applies to both usage patterns for Velocity,
    the Singleton as well as the 'separate runtime instance' (see more on this
    below), and you only do this once.</li>
<li>Create a Context object (more on what that is later).</li>
<li>Add your data objects to the Context.</li>
<li>Choose a template.</li>
<li>'Merge' the template and your data to produce the ouput.</li>
</ol>

<p>
In code, using the singleton pattern via the
<code>org.apache.velocity.app.Velocity</code> class,
this looks like
</p>

<source><![CDATA[
import java.io.StringWriter;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.MethodInvocationException;

Velocity.init();

VelocityContext context = new VelocityContext();

context.put( "name", new String("Velocity") );

Template template = null;

try
{
   template = Velocity.getTemplate("mytemplate.vm");
}
catch( ResourceNotFoundException rnfe )
{
   // couldn't find the template
}
catch( ParseErrorException pee )
{
  // syntax error: problem parsing the template
}
catch( MethodInvocationException mie )
{
  // something invoked in the template
  // threw an exception
}
catch( Exception e )
{}

StringWriter sw = new StringWriter();

template.merge( context, sw );

]]></source>

<p>
That's the basic pattern. It is very simple, isn't it?  This is generally what
happens when you use Velocity to render a template. You probably won't be
writing code exactly like this - we provide a few tools to help make it even
easier.  However, no matter how to use Velocity the above sequence is what is happening
either explicitly, or behind the scenes.
</p>


</section>

<section name="To Singleton Or Not To Singleton..." href="To_Singleton_Or_Not_To_Singleton...">

<p>
As of Velocity 1.2 and later, developers now have two options
for using the Velocity engine, the singleton model and the separate instance
model.  The same core Velocity code is used for both approaches, which are
provided to make Velocity easier to integrate into your Java application.
</p>

<p>
<a name="singleton"><strong>Singleton Model</strong></a>
</p>

<p>
   This is the legacy pattern, where there is only one instance of the Velocity
   engine in the JVM (or web application, depending) that is shared by all.
   This is very convenient as it
   allows localized configuration and sharing of resources.  For example, this
   is a very appropriate model for use in a Servlet 2.2+ compliant web application
   as each web application can have its own instance of Velocity, allowing
   that web application's servlet to share resources like templates, a logger, etc.
   The singleton is accessable via the <code>org.apache.velocity.app.Velocity</code>
   class, and and example of use:
</p>
<source><![CDATA[

import org.apache.velocity.app.Velocity;
import org.apache.velocity.Template;

...

/*
 *  Configure the engine - as an example, we are using
 *  ourselves as the logger - see logging examples
 */

Velocity.setProperty(
    Velocity.RUNTIME_LOG_LOGSYSTEM, this);

/*
 *  now initialize the engine
 */

Velocity.init();

...

Template t = Velocity.getTemplate("foo.vm");
]]></source>

<p>
<a name="separate"><strong>Separate Instance</strong></a>
</p>

<p>
   New in version 1.2, the separate instance allows you to create, configure
   and use as many instances of Velocity as you wish in the same JVM
   (or web application.)  This
   is useful when you wish to support separate configurations, such as template
   directories, loggers, etc in the same application.  To use separate
   instances, use the <code>org.apache.velocity.app.VelocityEngine</code>
   class.  An example, which parallels the above singleton example, looks
   like:
</p>

<source><![CDATA[

import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.Template;

...

/*
 *  create a new instance of the engine
 */

VelocityEngine ve = new VelocityEngine();

/*
 *  configure the engine.  In this case, we are using
 *  ourselves as a logger (see logging examples..)
 */

ve.setProperty(
    VelocityEngine.RUNTIME_LOG_LOGSYSTEM, this);

/*
 *  initialize the engine
 */

ve.init();

...

Template t = ve.getTemplate("foo.vm");
]]></source>

<p>
As you can see, this is very simple and straightforward.  Except for some simple
syntax changes, using Velocity as a singleton or as separate instances requires
no changes to the high-level structure of your application or templates.
</p>

<p>
As a programmer, the classes you should use to interact with the Velocity
internals are the <code>org.apache.velocity.app.Velocity</code> class if
using the singleton model, or <code>org.apache.velocity.app.VelocityEngine</code>
if using the non-singleton model ('separate instance').
</p>
<p>
At no time should an application use the internal <code>Runtime, RuntimeConstants,
RuntimeSingleton or RuntimeInstance</code> classes in the
<code>org.apache.velocity.runtime</code> package, as these are intended for
internal use only and may change over time.  As mentioned above,
the classes you should use
are located in the <code>org.apache.velocity.app</code> package, and are the
<code>Velocity</code> and <code>VelocityEngine</code> classes.  If anything is
missing or needed from those classes, do not hesitate to suggest changes - these
classes are intended for the application developer.
</p>
</section>

<section name="The Context" href="The_Context">

<a name="thebasics"><strong>The Basics</strong></a>
<p>
The concept of the 'context' is central to Velocity, and is a common technique
for moving a container of data around between parts of a system. The idea is
that the context is a 'carrier' of data between the Java layer (or you the
programmer) and the template layer ( or the designer ). You as the programmer
will gather objects of various types, whatever your application calls for, and
place them in the context.  To the designer, these objects, and their methods
and properties, will become accessable via template elements called
<a href="vtl-reference-guide.html"> references</a>. Generally, you will work
with the designer to determine the data needs for the application. In a sense,
this will become an 'API'  as you produce a data set for the designer to access
in the template.  Therefore, in this phase of  the development process it is
worth devoting some time and careful analysis.
</p>

<p>
While Velocity allows you to create your own context classes to support special
needs and techniques (like a context that accesses an LDAP server directly, for
example), a good basic implementation class called VelocityContext is provided
for you as part of the distribution.
</p>
<p>
VelocityContext is suitable for all general purpose needs, and we strongly
recommended that you use it. Only in exceptional and advanced cases will you
need to extend or create your own context implementation.
</p>
<p>
Using VelocityContext is as simple as using a normal Java Hashtable class.
While the interface contains other useful methods, the two main methods you
will use are
</p>

<source><![CDATA[
public Object put(String key, Object value);
public Object get(String key);
]]></source>

<p>
Please note that like a Hashtable, the value must be derived from
java.lang.Object, and must not be null. Fundamental types like int or float must
be wrapped in the appropriate wrapper classes.
</p>
<p>
That's really all there is to basic context operations. For more information,
see the API documentation included in the distribution.
</p>

<p>
<a name="supportforiterativeobjectsforforeach"><strong>Support for Iterative Objects for
#foreach()</strong></a>
</p>

<p>
As a programmer, you have great freedom in the objects that you put into the
context.  But as with most freedoms, this one comes with a little bit of
responsibility, so understand what Velocity supports, and any issues that may
arise.  Velocity supports serveral types of collection types  suitable for use
in the VTL <code>#foreach()</code> directive.
</p>

<ul>

<li> <code>Object [] </code>  Regular object array, not much needs to be said
here. Velocity will internally wrap your array in a class that provides an
Iterator interface,  but that shouldn't concern you as the programmer, or the
template author.  Of more interest, is the fact that Velocity will now
allow template authors to treat arrays as fixed-length lists (as of Velocity 1.6). 
This means they may call methods like <code>size()</code>,
<code>isEmpty()</code> and <code>get(int)</code> on both arrays and standard
java.util.List instances without concerning themselves about the difference.
</li>

<li> <code>java.util.Collection</code>  Velocity will use the
<code>iterator()</code> method to get an Iterator to use in the loop,
so if you are implementing a Collection interface on your object, please
ensure that <code>iterator()</code> returns a working  Iterator.
</li>

<li> <code>java.util.Map </code> Here, Velocity depends upon the
<code>values()</code> method of the interface to get a <code>Collection</code>
interface, on which <code>iterator()</code> is called to retrieve an Iterator
for the loop.
</li>

<li> <code>java.util.Iterator</code> USE WITH CAUTION: This is currently
supported only provisionally - the issue of concern is the
'non-resettablity' of the Iterator.  If a 'naked' Iterator is placed into
the context, and used in more than one #foreach(), subsequent #foreach()
blocks after the first will fail, as the Iterator doesn't reset.
</li>

<li> <code>java.util.Enumeration</code> USE WITH CAUTION: Like
<code>java.util.Iterator</code>, this is currently
supported only provisionally - the issue of concern is the
'non-resettablity' of the Enumeration.  If a 'naked' Enumeration
is placed into the context, and used in more than one #foreach(),
subsequent #foreach() blocks after the first will fail,
as the Enumeration doesn't reset.
</li>

<li> Any public class with a <code>public Iterator iterator()</code> method
that never returns <code>null</code>.  As a last resort, Velocity will
look for an <code>iterator()</code> method. This provides great flexibility
and automatic support for Java 1.5's <code>java.util.Iterable</code> interface.
</li>

</ul>

<p>
In the case of the <code>Iterator</code> and <code>Enumeration</code>, it is
recommended that they are placed in the context only when it cannot be avoided,
and you should let Velocity find the appropriate reusable iterative interface when
that is sufficient and possible.
</p>

<p>
There are good reasons to use the <code>java.util.Iterator</code> interface
directly (large data sets via JDBC, for example), but if it can be
avoided, it might be better to use something else. By 'directly' , we meant
doing something like:
</p>

<source><![CDATA[
Vector v = new Vector();
v.addElement("Hello");
v.addElement("There");

context.put("words", v.iterator() );
]]></source>

<p>
where the Iterator itself is placed into the context. Instead, if you
simply did:
</p>

<source><![CDATA[
context.put("words", v );
]]></source>

<p>
then all would be fine: Velocity would figure out that Vector implement
Collection (via List), and therefore will find the <code>iterator()</code>
method, and use that to get a 'fresh' Iterator for its use each time
it needs to.  With just a plain Iterator (the first snippet above...),
once velocity has used it in a <code>#foreach()</code>, Velocity has
no way of getting a new one to use for the next <code>#foreach()</code>
it is used in.  The result is no output from any subsequent
<code>#foreach()</code> blocks using that reference.
</p>

<p>
This above isn't meant to give the impression that iterating over
collections in Velocity is something that requires great care and
thought.  Rather, the opposite is true, in general.  Just be
careful when you place an Iterator into the context.
</p>

<a name="supportforstaticclasses"><strong>Support for "Static Classes"</strong></a>

<p>Not all classes are instantiable.  Classes like <code>java.lang.Math</code>
do not provide any public constructor, and yet may contain useful static methods.
In order to access these static methods from a template, you can simply add the
class itself to the context:
</p>

<source><![CDATA[
context.put("Math", Math.class);
]]></source>

<p>This will allow you to call any public static method in <code>java.lang.Math</code>
on the <code>$Math</code> reference in the template.
</p>

<a name="contextchaining"><strong>Context Chaining</strong></a>

<p>
An innovative feature of Velocity's context design is the concept
of <i>context chaining</i>. Also sometimes referred to as
<i>context wrapping</i>, this advanced feature allows you to connect
separate contexts together in a manner that makes it appear as one
'contiguous' context to the template.
</p>
<p>
This is best illustrated by an example:
</p>
<source><![CDATA[
VelocityContext context1 = new VelocityContext();

context1.put("name","Velocity");
context1.put("project", "Jakarta");
context1.put("duplicate", "I am in context1");

VelocityContext context2 = new VelocityContext( context1 );

context2.put("lang", "Java" );
context2.put("duplicate", "I am in context2");

template.merge( context2, writer );
]]></source>

<p>
In the code above, we have set up context2 such that it <i>chains</i>
context1.  This means that in the template, you can access any of
the items that were put into either of the two VelocityContext objects,
as long as there is no duplication of the keys used to add objects.
If that is the case, as it is above for the key 'duplicate', the object
stored in the nearest context in the chain will be available.  In this
example above, the object returned would
be the string "I am in context2".
</p>
<p>
Note that this duplication, or 'covering', of a context item does not in
any way harm or alter the covered object.  So in the example above, the
string "I am in context1" is alive and well, still accessable via
context1.get("duplicate").  But in the example above, the value of the
reference '$duplicate' in the template would be 'I am in context2',
and the template has no access to the covered string 'I am in context1'.
</p>
<p>
Note also that you have to be careful when you are relying on the template
to add information to a context that you will examine later after the
rendering.  The changes to the context via <code>#set()</code> statements
in a template will affect only the outer context.  So make sure that you
don't discard the outer context, expecting the data from the template to
have been placed onto the inner one.
</p>
<p>
This feature has many uses, the most common so far is providing layered
data access and toolsets.
</p>
<p>
As mentioned before, the Velocity context mechanism is also extendable,
but beyond the current scope of this guide. If you are interested,
please see the classes in the package <code>org.apache.velocity.context</code>
to see how the provided contexts are put together.  Futher, there are a few
examples in the <code>examples/context_example</code> directory in the
distribution which show alternate implementations, including [a goofy] one
that uses a database as the backing storage.
</p>
<p>
Please note that these examples are unsupported and are there for
demonstration/educational purposes only.
</p>

<a name="objectscreatedinthetemplate"><strong>Objects Created in the
Template</strong></a>

<p>
 There are two common situations where the Java code must deal with objects
 created at runtime in the template:
</p>

<p>
When a template author calls a method of an object placed into
the context by Java code.
</p>

<source><![CDATA[
#set($myarr = ["a","b","c"] )
$foo.bar( $myarr )
]]></source>

<p>
When a template adds objects to the context, the Java code can access
those objects after the merge process is complete.
</p>

<source><![CDATA[
#set($myarr = ["a","b","c"] )
#set( $foo = 1 )
#set( $bar = "bar")
]]></source>

<p>
Dealing with these cases if very straighforward, as there are just a few
things to know:
</p>

  <ul>
    <li>
    The VTL RangeOperator  [ 1..10 ]  and  ObjectArray ["a","b"] are
    <code>java.util.ArrayList</code> objects when placed in the context
    or passed to methods.   Therefore, your methods that are designed to
    accept arrays created in the template should be written with this
    in mind.
    </li>
    <li>VTL Map references are unsurprisingly stored as <code>java.util.Map</code>.</li>
    <li>
    Decimal numbers will be Doubles or BigDecimals in the context, integer numbers will be
    Integer, Long, or BigIntegers, and strings will be, of course, Strings.
    </li>
    <li>
    Velocity will properly 'narrow' args to method calls, so calling
    <code>setFoo( int i )</code> with an int placed into the
    context via <code>#set()</code> will work fine.
    </li>
  </ul>

<a name="othercontextissues"><strong>Other Context Issues</strong></a>

<p>
One of the features provided by the VelocityContext
(or any Context derived from AbstractContext) is
node specific introspection caching.  Generally, you as a the developer
don't need to worry about this when using the VelocityContext
as your context.  However, there is currently one
known usage pattern where you must be aware of this feature.
</p>

<p>
The VelocityContext will accumulate intropection information about the
syntax nodes in a template as it visits those nodes.  So, in the following
situation:
</p>

<ul>
<li>
  You are iterating over the same template using the same VelocityContext
  object.
</li>
<li>
Template caching is off.
</li>
<li>
You request the Template from getTemplate() on each iteration.
</li>
</ul>

<p>
It is possible that your VelocityContext will appear to 'leak' memory
(it is really just gathering more introspection information.)  What
happens is that it accumulates template node introspection information
for each template it visits, and as template caching is off, it appears
to the VelocityContext that it is visiting a new template each time.
Hence it gathers more introspection information and grows. It is highly
recommended that you do one or more of the following:
</p>

<ul>
<li>Create a new VelocityContext for each excursion
down through the template render process.   This will prevent the accumulation
of introspection cache data.  For the case where you want to reuse the
VelocityContext because it's populated with data or objects,
 you can simply wrap the populated
VelocityContext in another, and the 'outer' one will accumulate the
introspection information, which you will just discard.  Ex.
<code>VelocityContext useThis = new VelocityContext( populatedVC );</code>
This works because the outer context will store the introspection
cache data, and get any requested data from the inner context (as it is empty.)
Be careful though - if your template places data into the context and it's
expected that it will be used in the subsequent iterations, you will need to do
one of the other fixes, as any template #set() statements will be stored in
the outermost context. See the discussion in
<a href="#contextchaining"><b>Context chaining</b></a> for more
information.
</li>

<li>
Turn on template caching.  This will prevent the template from being re-parsed
on each iteration, resulting the the VelocityContext being able to not only
avoid adding to the introspection cache information, but be able to use it
resulting in a performance improvement.
</li>

<li>
Reuse the Template object for the duration of the loop iterations.
Then you won't be forcing Velocity, if the cache is turned off, to
reread and reparse the same template over and over, so the VelocityContext
won't gather new introspection information each time.
</li>
</ul>

</section>

<section name="Using Velocity" href="Using_Velocity">

<p>If you are using <a href="http://velocity.apache.org/tools/devel/view/">VelocityViewServlet</a>
or other web frameworks, you may never call Velocity directly.  However, if you use
Velocity for non-web purposes, or create your own web framework you will need
to directly call the Velocity Engine similar to
<a href="#thefundamentalpattern">the fundamental pattern</a> shown earlier.
One important additional thing to remember is to initialize the Velocity Engine before
using it to merge templates.

</p>

<a name="thevelocityhelperclass"><strong>The Velocity Helper Class</strong></a>

<p>
Velocity contains an application utility class called Velocity
( <code>org.apache.velocity.app.Velocity</code> ).  The purpose of this class
is to provide the necessary methods required to initialize Velocity, as well as
useful utility routines to make life easier in using Velocity. This class is
documented  in the project's javadoc, so please look there for definitive
details. This documentation is intended to be of a tutorial nature; therefore
for compete API information, the Javadoc is the definitive source.
</p>
<p>
The Velocity runtime engine is a singleton instance that provides resource,
logging and other services to all Velocity users running in the same JVM.
Therefore, the runtime engine is initialized only once.  You can attempt to
initialize Velocity more than once, but only the first initialization will
apply.  The rest of the attempts will be ignored.  The Velocity utility
class currently provides five methods used in configuration of the runtime engine.
</p>

<p>
The five configuration methods are:
</p>

<ul>

<li><code>setProperty( String key, Object o )</code><br/>
Sets the property <code>key</code> with the value <code>o</code>. The value
is typically a String, but in special cases can also be a comma-separated
list of values (in a single String, ex."foo, bar, woogie") as well as other
things that will arise.
</li>

<li><code>Object getProperty( String key )</code><br/>
Returns the value of the property key.  Note that you must be aware of the
type of the return value, as they can be things other than Strings.
</li>

<li><code>init()</code><br/>
Initializes the runtime with the default properties provided in the
distribution.(These are listed below in the section pertaining to
properties.)
</li>

<li><code>init( Properties p )</code><br/> Initialize the runtime with the
properties contained in the <code>java.util.Properties</code> object passed
as an argument.
</li>

<li><code>init( String filename )</code><br/> initilizes the runtime
using the properties found in the properties file filename
</li>

</ul>

<p>
Note that in each case, the default properties will be used as a base
configuration, and any additional properties specified by the application
will replace individual defaults.  Any default properties not overwritten
will remain in effect.  This has the benefit that only the properties
you are interested in changing need to be specified, rather
than a complete set.
</p>

<p>
Another thing to note is that the <code>init()</code> calls may be called
more than once without harm in an application.  However, the first call to any
of the <code>init()</code> functions will configure the engine with the
configuration properties set at that point, and any further configuration
changes or <code>init()</code> calls will be ignored.
</p>

<p>
The most common approaches to initializing Velocity will be something like:
</p>

<ol>
<li> Setup the configuration values you wish to set in a file in the same
format as org/apache/velocity/runtime/defaults/velocity.properties
(the default set),  or in a <code>java.util.Properties</code>, and then
call either <code>init( filename )</code> or <code>init( Properties )</code>
</li>

<li> Set the configuration values individually using <code>setProperty()</code>
and then call <code>init()</code>.  This method is generally used by more advanced
applications that already have their own configuration management system -
this allows the application so configure Velocity based upon values it generates
at runtime, for example.
</li>
</ol>

<p>
Once the runtime is initialized, you can do with it what you wish.. This mostly
revolves around rendering templates into an output stream, and the Velocity
utility class allows you to do this easily.  Currently, here are the methods
and a brief description of what they do:
</p>

<ul>
  <li>
     <code> evaluate( Context context,  Writer out, String logTag,
     String instring )</code><br/>
     <code>evaluate( Context context, Writer writer, String logTag,
     InputStream instream )</code><br/>
     These methods will render the input, in either the form of String or
     InputStream to an output Writer, using a Context that you provide.
     This is a very convenienient method to use for token replacement of
     strings, or if you keep 'templates' of VTL-containing content in a
     place like a database or other non-file storage, or simply generate such
     dynamically.
  </li>

  <li>
    <code>invokeVelocimacro( String vmName, String namespace, String params[],
    Context context, Writer writer )</code><br/>
    Allows direct access to Velocimacros.  This can also be accomplished
    via the <code>evaluate()</code> method above  if you wish.  Here you
    simply name the vm you wish to be called, create an array of args to the VM,
    a Context of data, and Writer for the output.  Note that the VM args
    must be the 'keys' of the data objects in the Context, rather than
    literal data to be used as the arg.  This will probably change.
  </li>

  <li>
    <code>mergeTemplate( String templateName, Context context, Writer writer )
    </code><br/>
    Convenient access to the normal template handling and rendering services
    of Velocity.  This method will take care of getting and rendering the
    template.  It will take advantage of loading the template according
    to the properties setting for the file resource loader, and therefore
    provides the advantage of file and parsed template caching that Velocity
    offers.  This is the most efficient way to access templates,
    and is recommended unless you have special needs.
  </li>

  <li>
    <code> boolean templateExists( String name ) </code><br/>
    Determines if a template <code>name</code> is able to be found by
    the currently configured resource loaders.
  </li>
</ul>

<p>
Once we know about these basic helpers, it is easy to write Java program
that uses Velocity.  Here it is:
</p>

<source><![CDATA[
import java.io.StringWriter;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.VelocityContext;

public class Example2
{
    public static void main( String args[] )
    {
        /* first, we init the runtime engine.  Defaults are fine. */

        Velocity.init();

        /* lets make a Context and put data into it */

        VelocityContext context = new VelocityContext();

        context.put("name", "Velocity");
        context.put("project", "Jakarta");

        /* lets render a template */

        StringWriter w = new StringWriter();

        Velocity.mergeTemplate("testtemplate.vm", context, w );
        System.out.println(" template : " + w );

        /* lets make our own string to render */

        String s = "We are using $project $name to render this.";
        w = new StringWriter();
        Velocity.evaluate( context, w, "mystring", s );
        System.out.println(" string : " + w );
    }
}
]]></source>

<p>
When we run this program, and have the template <code> testtemplate.vm</code>
in the same directory as our program (because we used the default
configuration properties, and the defaul place to load templates
from is the current directory...), our output should be:
</p>

<source><![CDATA[
template : Hi!  This Velocity from the Jakarta project.

string : We are using Jakarta Velocity to render this.
]]></source>

<p>
where the template we used, testtemplate.vm, is
</p>

<source><![CDATA[
Hi!  This $name from the $project project.
]]></source>

<p>
That's all there is to it!  Note that we didn't have to use both
<code>mergeTemplate()</code> and <code>evaluate()</code> in our
program.  They are both included there for demonstration purposes.
You will probably use only one of the methods, but depending
on you application requirements,  you are free to do what you wish.
</p>

<p>
This appears to be a little different from the 'fundamental pattern'
that was mentioned at the beginning of this guide, but it really is the
same thing.  First, you are making a context and filling it with
the data needed.  Where this examples differs is that in the part of
the above example where <code>mergeTemplate()</code> is used,
<code>mergeTemplate()</code> is doing the work of getting the template
and merging it for you, using the lower-level calls in the Runtime class.
In the second example, you are making your template dynamically via the
String, so that is analgous to the 'choose template' part of the process,
and the <code>evaluate()</code> method does the merging for you using
lower level calls.
</p>

<p>
So the example above sticks to the same simply pattern of using the Velocity
template engine, but the utility functions do some of
the repeated drudge work, or allow you other options for your
template content other than template files.
</p>

<a name="exceptions"><strong>Exceptions</strong></a>

<p>
Velocity may throw one of several exceptions during the parse / merge cycle.  These 
exceptions extend RuntimeException and do not need to explicitly caught,
although each includes specific properties that may help in presenting
useful error messages to the end user.  The exceptions 
are found in the package <code>org.apache.velocity.exception</code> and are:
</p>

<ol>
<li>
<code>ResourceNotFoundException</code><br/>
Thrown when the resource managment system cannot find a resource (template) that
was requested.
</li>

<li>
<code>ParseErrorException</code><br/>
Thrown when a VTL syntax error is found when parsing a resource (template).
</li>

<li>
<code>TemplateInitException</code><br/>
Thrown during the first pass of template parsing; reports problems with macro and
directive initialization.
</li>

<li>
<code>MethodInvocationException</code><br/>
Thrown when a method of object in the context thrown an exception during
render time.  This exception wraps the thrown exception and propogates it
to the application.  This allows you to handle problems in your own objects
at runtime.
</li>
</ol>

<p>
In each case, a message is put into the runtime log.  For more information,
see the Javadoc API documentation.
</p>

<a name="miscellaneousdetails"><strong>Miscellaneous Details</strong></a>

<p>
While the above example used the default properties, setting your own
properties is very simple. All you have to do is make a properties file
somewhere and pass the name of that file to the <code>init(String)</code>
method of the Velocity utility class, or make a
<code>java.util.Properties</code> object, add the desired properties and
values, and pass that to the <code>init(Properties)</code> method.
The latter method is convenient, because you can either fill it directly
from a separate properties file via the <code>load()</code>  method, or even
better, you can fill it dynamically from your own application / framework's
property set at runtime.  This gives you the freedom to combine all of the
properties for your app into one properties file.
</p>
<p>
If we wanted to use a different directory than the current directory to
load our template from, we could do something like this:
</p>

<source><![CDATA[
 ...

import java.util.Properties;
 ...

public static void main( String args[] )
{
    /* first, we init the runtime engine.  */

    Properties p = new Properties();
    p.setProperty("file.resource.loader.path", "/opt/templates");
    Velocity.init( p );

    /* lets make a Context and put data into it */

 ...
]]></source>

<p>
And, assuming you have a directory <code>/opt/templates</code> and the template
<code>testtemplate.vm</code> is in there, then things would work just fine.
If you try this and have a problem, be sure to look at the velocity.log for
information - the error messages are pretty good for figuring out what is wrong.
</p>

<p>
If you need to place objects into the Velocity properties then you cannot use
the Velocity.init(Properties p) method.  Instead you should create a new instance
of the <code>org.apache.commons.collections.ExtendedProperties</code> class, copy
all properties from an existing Properties object into the ExtendedProperties and
then add new properties with your objects to the ExtendedProperties object.
</p>

<source><![CDATA[    ...

    VelocityEngine velocityEngine = new VelocityEngine();
    ExtendedProperties eprops = null;
    if (props==null) {
       eprops = new ExtendedProperties();
    } else {
       eprops = ExtendedProperties.convertProperties(props);
    }

    // Now set the property with your object instance
    eprops.setProperty("name", object);

    ...
    velocityEngine.setExtendedProperties(eprops);
    velocityEngine.init();
    ...
]]>
</source>

<p>
You may want to also consider using the Application Attributes feature described
in the following section.
</p>

</section>

<section name="Application Attributes" href="Application_Attributes">
<p>
<i>Application Attributes</i> are name-value pairs that can be associated with
a RuntimeInstance (either via the <code>VelocityEngine</code> or
the <code>Velocity</code> singleton) and accessed from any part of the Velocity
engine that has access to the RuntimeInstance.
</p>

<p>
This feature was designed for applications that need to communicate between
the application layer and custom parts of the Velocity engine, such as
loggers, resource loaders, resource managers, etc.
</p>

<p>
The Application Attribute API is very simple.  From the application layer, there
is a method of the <code>VelocityEngine</code> and the <code>Velocity</code>
classes:
</p>

<source>
<![CDATA[
    public void setApplicationAttribute( Object key, Object value );
]]>
</source>

<p>
through which an application can store on Object under an application (or
internal component) specified key.  There are no restrictions on the key
or the value.  The value for a key may be set at any time - it is not required
that this be set before init() is called.
</p>

<p>
Internal components can access the key-value pairs if they have access to the
object via the <code>RuntimeServices</code> interface, using the method
</p>

<source>
<![CDATA[
    public Object getApplicationAttribute( Object key );
]]>
</source>

<p>
Note that internal components cannot set the value of the key, just get it.
if the internal component must communicate information to the application layer,
it must do so via the Object passed as the value.
</p>
</section>

<section name="Configuring Event Handlers" href="Configuring_Event_Handlers">

<p>
Velocity contains a fine-grained event handling system that allows you to customize the operation of the engine.  For example, you may change the text of references that are inserted into a page, modify which templates are actually included with <code>#include</code> or <code>#parse</code>, or capture all invalid references.
</p>

<p>All event handler interfaces available in Velocity are in the package <code>org.apache.velocity.app.event</code>.  You may create your own implementation or use one of the sample implementations in the package <code>org.apache.velocity.app.event.implement</code>.  (See the javadocs for more details on the provided implementations).
</p>

<p>
<i><code>org.apache.velocity.app.event.IncludeEventHandler</code></i>
<blockquote>
The <code>IncludeEventHandler</code> can be used to modify the template that is included 
in a page with <code>#include</code> or <code>#parse</code>.  For example, this may be used to make all includes relative to the current directory or to prevent access to unauthorized resources.
Multiple <code>IncludeEventHandler</code>'s may be chained, with the return value of the final
call used as the name of the template to retrieve.
<pre>
public IncludeEventHandler extends EventHandler
{
    public String includeEvent( String includeResourcePath, 
                                String currentResourcePath, 
                                String directiveName );
}
</pre>
<br/>
Available implementations include:
<dl>
<li><code>org.apache.velocity.app.event.implement.IncludeNotFound</code></li>
<li><code>org.apache.velocity.app.event.implement.IncludeRelativePath</code></li>
</dl>
</blockquote>

<i><code>org.apache.velocity.app.event.InvalidReferenceEventHandler</code></i>
<blockquote>
Normally, when a template contains a bad reference an error message is logged and (unless it is part of a <code>#set</code> or <code>#if</code>), the reference is included verbatim in a page.  With the <code>InvalidReferenceEventHandler</code> this behavior can be changed.  Substitute values can be inserted, invalid references may be logged, or an exception can be thrown.  Multiple <code>InvalidReferenceEventHandler</code>'s may be chained.  The exact manner in which chained method
calls behave will differ per method.  (See the javadoc for the details).
<pre>
public InvalidReferenceEventHandler extends EventHandler
{
    public Object invalidGetMethod( Context context, 
                                    String reference, 
                                    Object object, 
                                    String property, 
                                    Info info);

    public boolean invalidSetMethod( Context context, 
                                     String leftreference, 
                                     String rightreference, 
                                     Info info);

    public Object invalidMethod( Context context, 
                                 String reference,  
                                 Object object, 
                                 String method, 
                                 Info info);
}
</pre>
<br/>
Available implementations include:
<dl>
<li><code>org.apache.velocity.app.event.implement.ReportInvalidReferences</code></li>
</dl>
</blockquote>

<i><code>org.apache.velocity.app.event.MethodExceptionEventHandler</code></i>
<blockquote>
When a user-supplied method throws an exception, the
<code>MethodExceptionEventHandler</code> is invoked with the Class, method name
and thrown Exception.  The handler can either return a valid Object to be used
as the return value of the method call or throw the passed-in or new Exception,
which will be wrapped and propogated to the user as a
<code>MethodInvocationException</code>.  While <code>MethodExceptionEventHandler</code>'s can be 
chained only the first handler is actually called -- all others are ignored.
<pre>
public interface MethodExceptionEventHandler extends EventHandler
{
    public Object methodException( Class claz, 
                                   String method, 
                                   Exception e )
         throws Exception;
}
</pre>
<br/>
Available implementations include:
<dl>
<li><code>org.apache.velocity.app.event.implement.PrintExceptions</code></li>
</dl>
</blockquote>

<i><code>org.apache.velocity.app.event.NullSetEventHandler</code></i>

<blockquote>
When a #set() rejects an assignment due to the right hand side being an invalid
or null reference, this is normally
logged.  The <code>NullSetEventHandler</code> allows you to 'veto' the
logging of this condition.  Multiple <code>NullSetEventHandler</code>'s can
be chained; each event handler is called in sequence until a false is returned.
<br/>
<pre>
public interface NullSetEventHandler extends EventHandler
{
    public boolean shouldLogOnNullSet( String lhs, 
                                       String rhs );
}
</pre>
<br/>
Available implementations include:
<dl>
<li><i>none provided</i></li>
</dl>
</blockquote>

<i><code>org.apache.velocity.app.event.ReferenceInsertionEventHandler</code></i>
<blockquote>
A <code>ReferenceInsertionEventHandler</code> allows the
developer to intercept each write of a reference ($foo) value to the output
stream and modify that output.  Multiple <code>ReferenceInsertionEventHandler</code>'s 
may be chained with each step potentially altering the inserted reference.
<pre>
public interface  ReferenceInsertionEventHandler extends EventHandler
{
    public Object referenceInsert( String reference, 
                                   Object value  );
}
</pre>
<br/>
Available implementations include:
<dl>
<li><code>org.apache.velocity.app.event.implement.EscapeHtmlReference</code></li>
<li><code>org.apache.velocity.app.event.implement.EscapeJavascriptReference</code></li>
<li><code>org.apache.velocity.app.event.implement.EscapeSqlReference</code></li>
<li><code>org.apache.velocity.app.event.implement.EscapeXmlReference</code></li>
</dl>
</blockquote>

</p>

<p>
<strong>Registering Event Handlers</strong>
</p>

<p>You may register event handlers in either of two manners.  The easiest way to register event handlers is to specify them in velocity.properties.  (Event handlers configured in this manner are referred to as "global" event handlers).  For example, the following property will escape HTML entities in any inserted reference.
</p>

<blockquote>
<pre>eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
</pre>
</blockquote>

<p>Most event handler interfaces will also permit event handlers to be chained together.  Such a chain may be in a comma separated list or as additional lines with a property/value pair. For example, the following event handler properties install two <code>ReferenceInsertionEventHandler</code>'s.  The first will apply to references starting with &quot;msg&quot; (for example <code>$msgText</code>) and will escape HTML entities (e.g. turning <code>&amp;</code> into <code>&amp;amp;</code>).  The second will escape all references starting with &quot;sql&quot; (for example <code>$sqlText</code>) according to SQL escaping rules. (note that in these examples, the first two properties given relate to the event handler configuration while the second two properties are used by the specific event handler implementation).
</p>

<blockquote>
<pre>eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeHtmlReference
eventhandler.referenceinsertion.class = org.apache.velocity.app.event.implement.EscapeSqlReference
eventhandler.escape.html.match = /msg.*<!-- -->/
eventhandler.escape.sql.match = /sql.*<!-- -->/
</pre>
</blockquote>

<p>Event handlers may also be attached to a context via an <code>EventCartridge</code>.  This allows event handlers to be tied more closely to a specific template merge or group of merges.  The event handler will automatically be injected with the current context if it implements the <code>ContextAware</code> interface.  (Due to thread-safety reasons this is not possible with global event handlers).
</p>

<p>
The following code shows how to register an event handler with an EventCartridge and a context.
</p>

<source><![CDATA[
 ...

import org.apache.velocity.app.event.EventCartridge;
import org.apache.velocity.app.event.ReferenceInsertionEventHandler;
import org.apache.velocity.app.event.implement.EscapeHtmlReference;
import org.apache.velocity.app.event.implement.EscapeSqlReference;

 ...

public class Test
{
  public void myTest()
  {
    ....

    /**
     * Make a cartridge to hold the event handlers 
     */
    EventCartridge ec = new EventCartridge();

    /*
     * then register and chain two escape-related handlers 
     */
    ec.addEventHandler(new EscapeHtmlReference());
    ec.addEventHandler(new EscapeSqlReference());

    /*
     * and then finally let it attach itself to the context
     */
    ec.attachToContext( context );

    /*
     * now merge your template with the context as you normally
     * do
     */

    ....
  }

}
]]></source>

</section>

<section name="Velocity Configuration Keys and Values" href="Velocity_Configuration_Keys_and_Values">

<p>
Velocity's runtime configuration is controlled by a set of configuration keys
listed below.  Generally, these keys will have values that consist of either a
String, or a comma-separated list of Strings, referred to as a CSV for
comma-separated values.
</p>

<p>
There is a set of default values contained in Velocity's jar, found in
/src/java/org/apache/velocity/runtime/defaults/velocity.defaults, that
Velocity uses as its configuration baseline.
This ensures that Velocity will always have a 'correct' value
for its configuration keys at startup, although it may not be what you want.
</p>

<p>
Any values specified before init() time will replace the  default values.
Therefore, you only have toconfigure velocity with the values for the keys
that you need to change, and not worry about the rest.  Further, as we add more
features and configuration capability, you don't have to change your
configuration files to suit - the Velocity engine will always have default
values.
</p>

<p>
Please sees the section above <a href="#Using_Velocity"><b>Using
Velocity</b></a> for discussion on the configuration API.
</p>

<p>
Below are listed the configuration keys that control Velocity's behavior.
Organized by category, each key is listed with its current default value
to the right of the '=' sign.
</p>

<p>
<strong>Runtime Log</strong>
</p>

<p>
<code>runtime.log = velocity.log</code><br/>
Full path and name of log file for error, warning,
and informational messages.  The location, if not absolute, is
relative to the 'current directory'.
</p>

<p>
<code>runtime.log.logsystem</code><br/>
This property has no default value.  It is used to give Velocity an
instantiated instance of a logging class that supports the interface
<code>org.apache.velocity.runtime.log.LogChute</code>, which allows
the combination of Velocity log messages with your other application
log messages.  Please see the section
<a href="#Configuring_Logging"><b>Configuring Logging</b></a>
for more information.
</p>

<p>
<code>runtime.log.logsystem.class =
org.apache.velocity.runtime.log.AvalonLogChute</code><br/>
Class to be used for the Velocity-instantiated log system.
</p>

<p>
<code>runtime.log.invalid.references = true </code><br/>
Property to turn off the log output when a reference isn't valid.
Good thing to turn off in production, but very valuable
for debugging.
</p>

<p>
<code>runtime.log.logsystem.avalon.logger = <i>name</i> </code><br/>
Allows user to specify an existing logger <i>name</i>
in the Avalon hierarchy
without having to wrap with a LogChute interface.  <b>Note:</b>
You must also specify
<code>runtime.log.logsystem.class =
org.apache.velocity.runtime.log.AvalonLogChute</code> as the default
logsystem may change.  There is <b>no</b> guarantee that the Avalon
log system will remain the default log system.
</p>

<p>
<strong>Character Encoding</strong>
</p>

<p>
<code>input.encoding = ISO-8859-1</code><br/>
Character encoding for input (templates).  Using this, you can use
alternative encoding for your templates, such as UTF-8.
</p>

<p>
<code>output.encoding = ISO-8859-1</code><br/>
Character encoding for output streams from the VelocityServlet and Anakia.
</p>

<p>
<strong>#evaluate() Directive</strong>
</p>

<p>
<code>directive.evaluate.context.class = org.apache.velocity.VelocityContext</code><br/>
Used in the #evaluate() directive, defines the class that is used for the
context local to the argument for #evaluate().
</p>

<p>
<strong>#foreach() Directive</strong>
</p>

<p>
<code>directive.foreach.counter.name = velocityCount</code><br/>
Used in the #foreach() directive, defines the string to be used as the
context key for the loop count. A template would access
the loop count as $velocityCount.
</p>

<p>
<code>directive.foreach.iterator.name = velocityHasNext</code><br/>
Used in the #foreach() directive, defines the string to be used as the
context key for the "has next" value. A template would access
this as $velocityHasNext.
</p>

<p>
<code>directive.foreach.counter.initial.value = 1</code><br/>
Default starting value for the loop counter reference in a #foreach() loop.
</p>

<p>
<code>directive.foreach.maxloops = -1</code><br/>
Maximum allowed number of loops for a #foreach() statement.
</p>

<p>
<code>directive.foreach.skip.invalid = true</code><br/>
Tells #foreach to simply skip rendering when the object it is
iterating over is not or cannot produce a valid Iterator.
</p>

<p>
<strong>#set() Directive</strong>
</p>

<p>
<code>directive.set.null.allowed = false</code><br/>
If true, having a right hand side of a #set() statement with
an invalid reference or null value will set the left hand side to null.
If false, the left hand side will stay the same.
</p>

<p>
<strong>#include() and #parse() Directive</strong>
</p>

<p>
<code>directive.include.output.errormsg.start
= <![CDATA[ <!-- include error : ]]> </code><br/>
<code>directive.include.output.errormsg.end
=  <![CDATA[ see error log --> ]]></code><br/>
Defines the beginning and ending tags for an in-stream error message in the
case of a problem with the #include() directive. If both the .start and .end
tags are defined, an error message will be output to the stream, of the
form '.start msg .end' where .start and .end refer to the property values.
Output to the render stream will only occur if both the .start and .end
(next) tag are defined.
</p>
<p>
<code>directive.parse.max.depth = 10</code><br/>
Defines the allowable parse depth for a template. A template may #parse()
another template which itself may have a #parse() directive.  This value
prevents runaway #parse() recursion.
</p>

<p>
<strong>Math</strong>
</p>

<p>
<code>resource.manager.logwhenfound = true</code><br/>
Switch to control logging of 'found' messages from resource manager.
When a resource is found for the first time, the resource name
and classname of the loader that found it will be noted in the
runtime log.
</p>

<p>
<strong>Resource Management</strong>
</p>

<p>
<code>resource.manager.logwhenfound = true</code><br/>
Switch to control logging of 'found' messages from resource manager.
When a resource is found for the first time, the resource name
and classname of the loader that found it will be noted in the
runtime log.
</p>

<p>
<code>resource.manager.cache.class</code>  
<br/>
Declares the class to be used
for resource caching.  The current default is
<code>org.apache.velocity.runtime.resource.ResourceCacheImpl</code>
which uses a LRU Map to prevent data from being held forever.  You can
set the size of the LRU Map using the parameter
<code>resource.manager.defaultcache.size</code>.  The dafault value
of the default cache size is currently 89.
</p>

<p>
<code>resource.manager.defaultcache.size</code> 
    <br/>
    Sets the size of the
    default implementation of the resource manager resource cache.
</p>

<p>
<code>resource.loader = &lt;name&gt; (default = file)</code><br/>
<i>Multi-valued key.  Will accept CSV for value.</i>  Public name of a
resource loader to be used.  This public name will then be used
in the specification of the specific properties for that resource loader.
Note that as a multi-valued key, it's possible to pass
a value like "file, class" (sans quotes), indicating that following
will be configuration values for two loaders.
</p>

<p>
<code>&lt;name&gt;.loader.description
= Velocity File Resource Loader</code><br/>
Description string for the given loader.
</p>

<p>
<code>&lt;name&gt;.resource.loader.class
= org.apache.velocity.runtime.resource.loader.FileResourceLoader</code><br/>
Name of implementation class for the loader.  The default loader
is the file loader.
</p>

<p>
<code>&lt;name&gt;.resource.loader.path = .</code><br/>
<i>Multi-valued key.  Will accept CSV for value.</i> Root(s) from which the
loader loads templates. Templates may live in  subdirectories of this root.
ex. homesite/index.vm   This configuration key applies currently to the
FileResourceLoader and JarResourceLoader.
</p>

<p>
<code>&lt;name&gt;.resource.loader.cache = false</code><br/>
Controls caching of the templates in the loader.  Default is false, to make
life easy for development and debugging.  This should be set to true for
production deployment.  When 'true', the <code>modificationCheckInterval</code>
property applies.  This allows for the efficiency of caching, with the
convenience of controlled reloads - useful in a hosted or ISP environment
where templates can be modifed frequently and bouncing the application or
servlet engine is not desired or permitted.
</p>

<p>
<code>&lt;name&gt;.resource.loader.modificationCheckInterval = 2</code><br/>
This is the number of seconds between modification checks when caching is
turned on.  When this is an integer &gt; 0, this represents the number of
seconds between checks to see if the template was modified.  If the
template has been modified since last check, then it is reloaded and
reparsed.  Otherwise nothing is done.  When &lt;= 0, no modification
checks will take place, and assuming that the property <code>cache</code>
(above) is true, once a template is loaded and parsed the first time it is used,
it will not be checked or reloaded after that until the application or
servlet engine is restarted.
</p>


<p> To illustrate, here is an example taken right from the default Velocity
properties, showing how setting up the FileResourceLoader is managed
</p>

<source><![CDATA[
resource.loader = file

file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = .
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 2
]]></source>

<p>
<strong>Velocimacro</strong>
</p>

<p>
<code>velocimacro.library = VM_global_library.vm </code><br/>
<i>Multi-valued key.  Will accept CSV for value.</i>
Filename(s) of Velocimacro library to be loaded when the Velocity
Runtime engine starts.  These Velocimacros are accessable to all
templates.  The file is assumed to be relative to the root of the
file loader resource path.
</p>

<p>
<code>velocimacro.permissions.allow.inline = true</code><br/>
Determines of the definition of new Velocimacros via the #macro() directive
in templates is allowed.   The default value is true, meaning any template
can define and use new Velocimacros.  Note that depending on other properties,
those #macro() statements can replace global definitions.
</p>

<p>
<code>velocimacro.permissions.allow.inline.to.replace.global = false </code><br/>
Controls if a Velocimacro defind 'inline' in a template can replace
a Velocimacro defined in a library loaded at startup.
</p>

<p>
<code>velocimacro.permissions.allow.inline.local.scope = false</code><br/>
Controls 'private' templates namespaces for Velocimacros.  When true, a #macro()
directive in a template  creates a Velocimacro that is accessable only from the
defining template.  This means that Velocimacros cannot be shared unless they
are in the global or local library loaded at startup. (See above.)  It also means
that templates cannot interfere with each other.  This property also allows a technique
where there is a 'default' Velocimacro definition in the global or local library,
and a template can 'override' the implementation for use within that template.
This occurrs because when this property is true, the template's namespace is
searched for a Velocimacro before the global namespace, therefore allowing
the override mechanism.
</p>
<p>
<code>velocimacro.context.localscope = false</code><br/>
Controls whether reference access (set/get) within a Velocimacro will change
the context, or be of local scope in that
Velocimacro.
</p>

<p>
<code>velocimacro.library.autoreload = false</code><br/>
Controls Velocimacro library autoloading.  When set to <code>true</code>
the source Velocimacro library for an invoked Velocimacro will be checked
for changes, and reloaded if necessary.  This allows you to change and
test Velocimacro libraries without having to restart your application or
servlet container, just like you can with regular templates.
This mode only works when caching is <i>off</i>
in the resource loaders (e.g. <code>file.resource.loader.cache = false</code> ).
This feature is intended for development, not for production.
</p>

<p>
<code>velocimacro.arguments.strict = false</code><br/>
When set to true, will throw a <code>ParseErrorException</code> when
parsing a template containing a macro with an invalid number of arguments.
Is set to false by default to maintain backwards compatibility with 
templates written before this feature became available.
</p>

<p>
<strong>Strict Reference Setting</strong>
</p>

<p>
<code>runtime.references.strict = false</code><br/>

New in Velocity 1.6, when set to true Velocity will throw a
<code>MethodInvocationException</code> for references that are not
defined in the context, or have not been defined with a #set
directive.  This setting will also throw an exception if an attempt is
made to call a non-existing property on an object or if the object is
null.  When this property is true then property
'directive.set.null.allowed' is also set to true. Also,
'directive.foreach.skip.invalid' defaults to true when this property
is true, but explicitly setting 'directive.foreach.skip.invalid' will
override this default. For a complete discussion see <a
href="user-guide.html#strictreferences">Strict References Setting</a>.
</p>

<p>
<strong>String Interpolation</strong>
</p>

<p>
<code>runtime.interpolate.string.literals = true</code><br/>
Controls interpolation mechanism of VTL String Literals.  Note that a VTL
StringLiteral is specifically a string using double quotes that is used
in a #set() statement, a method call of a reference, a parameter to a VM,
or as an argument to a VTL directive in general.  See the VTL reference for
further information.
</p>

<p>
<strong>Math</strong>
</p>

<p>
<code>runtime.strict.math = false</code><br/>
Affects all math operations in VTL. If changed to true, this will cause
Velocity to throw a MathException whenever one side of a math operation
has a null value (e.g. <code>#set( $foo = $null * 5 )</code>) or when
trying to divide by zero.  If this value is left <code>false</code>,
then rendering will continue and that math operation will be ignored.
</p>

<p>
<strong>Parser Configuration</strong>
</p>
<p>
<code>parser.pool.class = org.apache.velocity.runtime.ParserPoolImpl</code><br/>
This property selects the implementation for the parser pool.  This class
must implement ParserPool. Generally there is no reason to change this though
if you are building a high volume web application you might consider including
an alternate implementation that automatically adjusts the size of the pool.
</p>
<p>
<code>parser.pool.size = 20</code><br/>
This property is used by the default pooling implementation to
set the number of parser instances that Velocity will
create at startup and keep in a pool.  The default of 20 parsers
should be more than enough for most uses.  In the event that Velocity
does run out of parsers, it will indicate so in the log, and
dynamically create overflow instances as needed.  Note that these
extra parsers will not be added to the pool, and will be discarded
after use.  This will result in very slow operation compared to the
normal usage of pooled parsers, but this is considered an exceptional
condition.  A web application using Velocity as its view engine might
exhibit this behavior under extremely high concurrency (such as when
getting Slashdotted).  If you see a corresponding message referencing
the <code>parser.pool.size</code> property in your log files, please
increment this property immediately to avoid performance degradation.
</p>

<p>
<strong>Pluggable Introspection</strong>
</p>

<p>
<code>runtime.introspector.uberspect =
org.apache.velocity.util.introspection.UberspectImpl</code>
<br/>
This property sets the 'Uberspector', the introspection package that
handles all introspection strategies for Velocity. You can specify a
comma-separated list of Uberspector classes, in which case all Uberspectors are
chained. The default chaining behaviour is to return the first non-null value
for each introspection call among all provided uberspectors. You can modify
this behaviour (for instance to restrict access to some methods) by subclassing
org.apache.velocity.util.introspection.AbstractChainableUberspector (or
implementing directly
org.apache.velocity.util.introspection.ChainableUberspector).  This
allows you to create more interesting rules or patterns for Uberspection,
rather than just returning the first non-null value.
</p>

</section>

<section name="Configuring Logging" href="Configuring_Logging">

<p>
Velocity has a few nice logging features to allow both simplicity and
flexibility. Without any extra configuration, Velocity will setup a
file-based logger that will output all logging messages to a file
called <code>velocity.log</code> in the 'current directory' where
Velocity was initialized.   For more advanced users, you may integrate
your current logging facilities with Velocity to have all log messages
sent to your logger.
</p>

<p>
Starting with version 1.3, Velocity will automatically use either the
<a href="http://jakarta.apache.org/avalon/logkit/index.html">
Jakarta Avalon Logkit</a> logger, or the
<a href="http://jakarta.apache.org/log4j/">Jakarta Log4j</a> logger.
It will do so by using whatever it finds in the current classpath, starting
first with Logkit.  If Logkit isn't found, it tries Log4j.
</p>

<p>
To utilize this feature, simply use the 'non-dependency' Velocity jar
(because Logkit is baked into the jar with dependencies) and place
either the logkit or log4j jar in your classpath.
</p>

<p>
In general, you have the following logging options:
</p>

<ul>

<li>
<b>Default Configuration</b><br/>
By default, Velocity will create a file-based logger in the current
directory.  See the note above regarding automatic detection of
Logkit or Log4j to use as the default logging system.
</li>

<li>
<b>Existing Log4j Logger</b><br/>
Starting with version 1.3, Velocity will log its output to an existing
Log4j Logger setup elsewhere in the application. To use this feature you must
  <ol>
    <li>
    Make sure that the Log4j jar is in your classpath. (You would do this
    anyway since you are using Log4j in the application using Velocity.)
    </li>
    <li>Configure Velocity to use the <code>Log4JLogChute</code> class by
    specifying the name of the existing Logger to use via the
    'runtime.log.logsystem.log4j.logger' property.
    </li>
  </ol>

Note that this support for Logger is in version 1.5 of Velocity.  Further,
in version 1.5 we removed the now-ancient and very deprecated original
Log4JLogSystem class and replaced with the current Log4JLogChute class which
uses the Logger class.  We apologize for the confusion, but we needed to move
on.
</li>

<li>
<b>Custom Standalone Logger</b><br/>
You can create a custom logging class - you just need to implement the
interface <code>org.apache.velocity.runtime.log.LogChute</code> and
then simply set the  configuration property
<code>runtime.log.logsystem.class</code> with the
classname, and Velocity will create an instance of that class at init time.
You may specify the classname as you specify any other properties. See
the information on the
<a href="#thevelocityhelperclass">
Velocity helper class</a> as well as the
<a href="#Velocity_Configuration_Keys_and_Values">
configuration keys and values.</a>
Please note that the old <code>org.apache.velocity.runtime.log.LogSystem</code>
interface has been deprecated for v1.5 in favor of the new LogChute interface.
This is due to significant upgrades to our logging code that could not be
supported by the LogSystem interface.  But don't worry, if you specify a
custom class that implements the LogSystem interface, it will still work.
However, it will generate deprecation warnings.  You should upgrade your
custom logger to implement LogChute as soon as possible.
</li>

<li>
<b>Integrated Logging</b><br/>
You can integrate Velocity's logging capabilities with your applications
existing logging system, simply by implementing the
<code>org.apache.velocity.runtime.log.LogChute</code> interface.  Then,
pass an instance of your logging class to Velocity via the
<code>runtime.log.logsystem</code> configuration key before
initializing the Velocity engine,
and Velocity will log messages to your application's logger.
See the information on the
<a href="#thevelocityhelperclass">Velocity helper class</a>
as well as the
<a href="#Velocity_Configuration_Keys_and_Values">configuration keys and values.</a>
</li>

</ul>

<a name="usinglog4jwithexistinglogger"><strong>Using Log4j With Existing Logger</strong></a>

<p>
Here is an example of how to configure Velocity to log to an existing Log4j
Logger.
</p>

<source><![CDATA[
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;

import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;

public class Log4jLoggerExample
{
  public static String LOGGER_NAME = "velexample";

  public static void main( String args[] )
    throws Exception
  {
    /*
     *  configure log4j to log to console
     */

    BasicConfigurator.configure();

    Logger log = Logger.getLogger( LOGGER_NAME );

    log.info("Log4jLoggerExample: ready to start velocity");

    /*
     *  now create a new VelocityEngine instance, and
     *  configure it to use the category
     */

    VelocityEngine ve = new VelocityEngine();

    ve.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
      "org.apache.velocity.runtime.log.Log4JLogChute" );

    ve.setProperty("runtime.log.logsystem.log4j.logger",
                    LOGGER_NAME);

    ve.init();

    log.info("follows initialization output from velocity");
  }
}
]]></source>

<p>
Note that the above example can be found in <code>examples/logger_example</code>.
</p>

<a name="simpleexampleofacustomlogger"><strong>Simple Example of a Custom Logger</strong></a>

<p>
Here is an example of how to use an instantiation of your class that implements
Velocity's logging system as the logger.  Note that we are not passing the name
of the class to use, but rather a living, existing instantiation of the class
to be used.  All that is required is that it support the
<code>LogChute</code> interface.

</p>

<source><![CDATA[
import org.apache.velocity.runtime.log.LogChute;
import org.apache.velocity.runtime.RuntimeServices;
...

public class MyClass implements LogChute
{

...

  public MyClass()
  {
    ...

    try
    {
      /*
       *  register this class as a logger with the Velocity singleton
       *  (NOTE: this would not work for the non-singleton method.)
       */
      Velocity.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM, this );
      Velocity.init();
    }
    catch (Exception e)
    {
      /*
       *  do something
       */
    }
  }

  /**
   *  This init() will be invoked once by the LogManager
   *  to give you the current RuntimeServices intance
   */
  public void init(RuntimeServices rsvc)
  {
    // do nothing
  }

  /**
   *  This is the method that you implement for Velocity to
   *  call with log messages.
   */
  public void log(int level, String message)
  {
    /*  do something useful */
  }

  /**
   *  This is the method that you implement for Velocity to
   *  call with log messages.
   */
  public void log(int level, String message, Throwable t)
  {
    /*  do something useful */
  }

  /**
   *  This is the method that you implement for Velocity to
   *  check whether a specified log level is enabled.
   */
  public boolean isLevelEnabled(int level)
  {
    /*  do something useful */
    return someBooleanValue;
  }
...
}
]]></source>

</section>

<section name="Configuring Resource Loaders" href="Configuring_Resource_Loaders">

<a name="resourceloaders"><strong>Resource Loaders</strong></a>

<p>
One of the fundamental and important parts about Velocity is the resource
management system and the resource loaders.  They are referred to as 'resources'
here rather than 'templates' because the resource management system will also
handle non-template reasources, specifically things that are loaded via the
#include() directive.
</p>

<p>
The resource loader system if very flexible, allowing one or more resource
loaders to be in operation at the same time.  This allows tremendous
flexibility in configuration and resource managment, and futher allows you
to write your own resource loaders for your special needs.
</p>

<p>
There are currently four kinds of resource loaders that are included with Velocity,
each described below.  Note that in the example configuration properties given,
a common name for the loader is shown
(ex.'file' in <code>file.resource.loader.path</code>). This 'common name'
may not work for your configuration. Please read the section on
<a href="#Velocity_Configuration_Keys_and_Values">resource configuration properties</a>
 to understand how this system works.  Also, each of these loaders is
located in the package <code>org.apache.velocity.runtime.resource.loader</code>.
</p>

<ul>
<li>
  <b>FileResourceLoader :</b> This loader gets resources from the filesystem. Its
  configuration properties include:
  <ul>
    <li>
      <code>file.resource.loader.path</code> = &lt;path to root of templates&gt;
    </li>
    <li>
      <code>file.resource.loader.cache</code> = true/false
    </li>
    <li>
      <code>file.resource.loader.modificationCheckInterval</code> = &lt;seconds between checks&gt;
    </li>
  </ul>
  This is the default loader, and is configured, by default to get templates from the
  'current directory'.  In the case of using Velocity with servlets, this can be a problem
  as you don't want to have to keep your templates in the directory from which you start
  your servlet engine.  See the documentation for your servlet or web framework (for example
  <a href="http://velocity.apache.org/tools/devel/view/">VelocityViewServlet</a>) for more
  info on how to configure the location of the Velocity templates.
</li>
<li>
  <b>JarResourceLoader :</b> This loader gets resource from specific jar files.  It is very
  similar to the FileResourceLoader, except that you have the convenience of bundling
  your templates into jars.  The properties are identical, except for
  <code>jar.resource.loader.path</code>, where you provide the full location of
  the jar(s) you wish to load resources from.  To specify a jar for the loader.path
  you use the standard JAR URL syntax of <code>java.net.JarURLConnection</code>.
</li>
<li>
  <b>ClasspathResourceLoader :</b> This loader gets resources from the classloader.
  In general, this means that the ClasspathResourceLoader will load
  templates placed in the classpath (in jars, for example)
  While the
  classpath is a source of great pain and suffering in general, it is a very useful
  mechanism when working on a Servlet Spec 2.2 (or newer) compliant servlet runner.
  <a href="http://jakarta.apache.org/tomcat/">Tomcat</a>
  is an example of such.  To use this loader effectively, all you must do is
  jar your templates, and put that jar into the WEB-INF/lib directory of your
  webapp.  There are no configuration options to worry about, nor is the absolute vs.
  relative path an issue, as it is with Jar and File resource loaders.
  Again, please note that the ClasspathResourceLoader is not only for use with a
  servlet container, but can be used in any application context.
</li>
<li>
  <b>URLResourceLoader :</b> This loader gets resources from a URL connection. Its
  configuration properties include:
  <ul>
    <li>
      <code>url.resource.loader.root</code> = &lt;root URL path of templates&gt;
    </li>
    <li>
      <code>url.resource.loader.cache</code> = true/false
    </li>
    <li>
      <code>url.resource.loader.modificationCheckInterval</code> = &lt;seconds between checks&gt;
    </li>
  </ul>
  This loader simply downloads resources from configured URLs.  It works much like
  the FileResourceLoader, however, it can pull templates down from any valid URL
  to which the application can create a connection.
</li>
<li>
  <b>DataSourceResourceLoader :</b>  This loader will load resources from a DataSource
such as a database.  This loader is only available under JDK 1.4 and later.
For more information on this loader, please see the javadoc for the class
<code>org.apache.velocity.runtime.resource.loader.DataSourceResourceLoader</code>.
</li>

</ul>

<a name="configurationexamples"><strong>Configuration Examples</strong></a>

<p>
Configuring the resource loaders for Velocity is straightforward.
The properties that control the are listed in the
<a href="#Configuring_Resource_Loaders">resource configuration</a>
section, for further reference.
</p>

<p>
The first step in configuring one or more resource loaders is do
'declare' them by name to Velocity.  Use the property
<code>resource.loader</code> and list one or more loader names.
You can use anything you want - these names are used to associate
configuration properties with a given loader.
</p>

<source><![CDATA[
resource.loader = file
]]></source>

<p>
That entry declares that we will have a resource loader known as 'file'.
The next thing to do is to set the important properties.  The most critical
is to declare the class to use as the loader:
</p>

<source><![CDATA[
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
]]></source>

<p>
In this case, we are telling velocity that we are setting up
a resource loadercalled 'file', and are using the class
<code>
org.apache.velocity.runtime.resource.loader.FileResourceLoader
</code>
to be the class to use.
The next thing we do is set the properties important
to this loader.
</p>

<source><![CDATA[
file.resource.loader.path = /opt/templates
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 2
]]></source>

<p>
Here, we set a few things.  First, we set the path to find
the templates to be <code>/opt/templates</code>.  Second, we
turned caching on, so that after a template or static file
is read in, it is cached in memory.  And finally, we set
the modification check interval to 2 seconds, allowing Velocity
to check for new templates.
</p>

<p>
Those are the basics.  What follows are a few examples of different configuraitons.
</p>

<p>
<b>Do-nothing Default Configuration: </b> As the name says, there is nothing
you have to do or configure to get the default configuration.  This configuration
uses the FileResourceLoader with the current directory as the default resource
path, and caching is off.  As a properties set, this is expressed as:
</p>

<source><![CDATA[
resource.loader = file

file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = .
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 0
]]></source>

<p>
<b>Multiple Template Path Configuration: </b> This configuration
uses the FileResourceLoader with several directories as 'nodes' on the
template search path. We also want to use caching, and have the templates
checked for changes in 10 second intervals.  As a properties set, this is expressed as:
</p>

<source><![CDATA[
resource.loader = file

file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = /opt/directory1, /opt/directory2
file.resource.loader.cache = true
file.resource.loader.modificationCheckInterval = 10
]]></source>

<p>
<b>Multiple Loader Configuration :</b>  This configuration sets up
three loaders at the same time, the FileResourceLoader,
the ClasspathResourceLoader, and the JarResourceLoader.
 The loaders are set-up such that the
FileResourceLoader is consulted first, then the
ClasspathResourceLoader, and finally the JarResourceLoader.
This would allow you to qickly
drop a template into the file template area to replace on of the
templates found in the classpath (usually via a jar) without
having to rebuild the jar.
</p>

<source><![CDATA[
#
# specify three resource loaders to use
#
resource.loader = file, class, jar

#
# for the loader we call 'file', set the FileResourceLoader as the
# class to use, turn off caching, and use 3 directories for templates
#
file.resource.loader.description = Velocity File Resource Loader
file.resource.loader.class = org.apache.velocity.runtime.resource.loader.FileResourceLoader
file.resource.loader.path = templatedirectory1, anotherdirectory, foo/bar
file.resource.loader.cache = false
file.resource.loader.modificationCheckInterval = 0

#
#  for the loader we call 'class', use the ClasspathResourceLoader
#
class.resource.loader.description = Velocity Classpath Resource Loader
class.resource.loader.class = org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader

#
# and finally, for the loader we call 'jar', use the JarResourceLoader
# and specify two jars to load from
#
jar.resource.loader.description = Velocity Jar  Resource Loader
jar.resource.loader.class = org.apache.velocity.runtime.resource.loader.JarResourceLoader
jar.resource.loader.path = jar:file:/myjarplace/myjar.jar, jar:file:/myjarplace/myjar2.jar
]]></source>

<p>
Node that the three names 'file', 'class', and 'jar' are merely for your convenience and
sanity.  They can be anything you want - they are just used to associate a set of
properties together.  However, it is recommended that you use names that give some hint
of the function.
</p>

<p>
Note that while all three require very little configuration information
for proper operation, the ClasspathResourceLoader is the simplest.
</p>


<a name="resourcemanagerandcache"></a>
<strong>Pluggable Resource Manager and Resource Cache</strong>

<p>
The Resource Manager is the main part of the resource (template and static content)
management system, and is responsible for taking application requests for
templates, finding them in the available resource loaders, and then optionally
caching the parsed template.  The Resource Cache is the mechanism that the
Resource Manager uses to cache templates for quick reuse. While the default
versions of these two facilities are suitable for most
applications, for advanced users  it now is possible
to replace the default resource manager
and resource cache with custom implementations.
</p>

<p>
A resource manager implementation must implement the
<code>org.apache.velocity.runtime.resource.ResourceManager</code> interface.
A description of the requirements of a resource manager is out of scope for
this document.  Implementors are encouraged to review the default implementation.
To configure Velocity to load the replacement implementation, use the
configuration key:
</p>

<source><![CDATA[
resource.manager.class
]]></source>

<p>
This key is also defined as a contstant
<code>RuntimeConstants.RESOURCE_MANAGER_CLASS</code>
</p>

<p>
A resource cache implementation must implement the
<code>org.apache.velocity.runtime.resource.ResourceCache</code> interface
As with the resource manager, a description of the requirements of a
resource manager is out of scope for
this document.  Implementors are encouraged to review the default implementation.
To configure Velocity to load the replacement implementation, use the
configuration key:
</p>

<source><![CDATA[
resource.manager.cache.class
]]></source>

<p>
This key is also defined as a contstant
<code>RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS</code>
</p>

<p>
A resource cache implementation may want to limit the cache size
(rather than providing an unbounded cache which could consume all
available memory).  To configure Velocity to set the size for your
cache, use the configuration key:
</p>

<source><![CDATA[
resource.manager.cache.size
]]></source>

<p>
This key is also defined as a contstant
<code>RuntimeConstants.RESOURCE_MANAGER_CACHE_SIZE</code>
</p>

</section>

<section name="Template Encoding for Internationalization" href="Template_Encoding_for_Internationalization">

<p>
Velocity allows you to specify the character encoding of your
template resources on a template by template basis.  The normal resource
API's have been extended to take the encoding as an argument:
</p>

<p>
<code>org.apache.velocity.app.Velocity</code>: <br/>
<blockquote>
  <i><code>public static Template getTemplate(String name, String encoding)</code></i>
  <br/>
  <br/>
  <i><code>public static boolean mergeTemplate( String templateName, String encoding, Context context, Writer writer )</code></i>
  <br/>
  <i><code> </code></i>
</blockquote>
</p>

<p>
The value for the <i>encoding</i> argument is the conventional encoding specification
supported by your JVM, for example "UTF-8" or "ISO-8859-1".  For the official names
for character sets, see <a href="http://www.iana.org/assignments/character-sets">here</a>.
</p>

<p>
Note that this applies only to the encoding of the template itself - the output
encoding is an application specific issue.
</p>

</section>

<section name="Velocity and XML" href="Velocity_and_XML">

<p>
Velocity's flexibility and simple template language makes it an ideal environment
for working with XML data.  <a href="anakia.html">Anakia</a> is an example of how
Velocity is used to replace XSL for rendering output from XML.  The Velocity site,
including this documentation, is generated from XML source using Anakia.
The Jakarta site is also rendered using Anakia.
</p>

<p>
Generally, the pattern for dealing with XML in Velocity is to use something like
<a href="http://www.jdom.org/">JDOM</a> to process your XML into a data structure with
convenient Java access.  Then, you produce templates that access data directly
out of the XML document - directly though the JDOM tree.  For example, start
with an XML document such as:
</p>

<source><![CDATA[

<document>
 <properties>
  <title>Developer's Guide</title>
  <author email="geirm@apache.org">Velocity Doc Team</author>
 </properties>
</document>
]]></source>

<p>
Now make a little Java program that includes code similar to:
</p>

<source><![CDATA[
...

SAXBuilder builder;
Document root = null;

try
{
    builder = new SAXBuilder(
             "org.apache.xerces.parsers.SAXParser" );
    root = builder.build("test.xml");
}
catch( Exception ee)
{}

VelocityContext vc = new VelocityContext();
vc.put("root", root.getRootElement());


...
]]></source>

<p>
(See the Anakia source for details on how to do this, or the Anakia
example in the <code>examples</code> directory in the distribution.)
Now, make a regular Velocity template:
</p>

<source><![CDATA[
<html>
  <body>
    The document title is
    $root.getChild("document").getChild("properties")
            .getChild("title").getText()
  </body>
</html>
]]></source>

<p>
and render that template as you normally would, using the Context
containing the JDOM tree. Of course, this isn't the prettiest of
examples, but it shows the basics - that you can easily access XML data
directly from a Velocity template.
</p>

<p>
One real advantage of styling XML data in Velocity is that you have
access to any other object or data that the application provides.  You
aren't limited to just using the data present in the XML document.
You may add anything you want to the context to provide additional
information for your output, or provide tools to help make working
with the XML data easier.  Bob McWhirter's
<a href="http://sourceforge.net/projects/werken-xpath/"> Werken Xpath</a>
is one such useful tool - an example of how it is used in Anakia can be
found in <code>org.apache.velocity.anakia.XPathTool</code>.
</p>

<p>
One issue that arises with XML and Velocity is how to deal with XML
entities. One technique is to combine the use of Velocimacros
when you need to render an entity into the output stream:
</p>

<source><![CDATA[
## first, define the Velocimacro somewhere

#macro(xenc $sometext)$tools.escapeEntities($sometext)#end

## and use it as

#set( $sometext = " < " )
<text>#xenc($sometext)</text>
]]></source>

<p>
where the escapeEntities() is a method that does the escaping
for you. Another trick would be to create an encoding utility that takes the
context as a constructor parameter and only implements a method:
</p>

<source><![CDATA[
public String get(String key)
{
    Object obj = context.get(key)
    return (obj != null)
        ? Escape.getText( obj.toString() )
        : "";
}
]]></source>

<p>
Put it into the context as "xenc". Then you can use it as:
</p>

<source><![CDATA[
<text>$xenc.sometext</text>
]]></source>

<p>
This takes advantage of Velocity's introspection process - it will try
to call get("sometext") on the $xenc object in the Context - then the
xenc object can then get the value from the Context, encode it, and
return it.
</p>

<p>
Alternatively, since Velocity makes it easy to implement custom Context
objects, you could implement your own context which always applies the
encoding to any string returned. Be careful to avoid rendering the
output of method calls directly, as they could return objects or strings
(which might need encoding). Place them first into the context with a
#set() directive and the use that, for example:
</p>

<source><![CDATA[
#set( $sometext = $jdomElement.getText() )
<text>$sometext</text>
]]></source>

<p>
The previous suggestions for dealing with XML entities came from
Christoph Reck, an active participant in the Velocity community.
</p>

</section>

<section name="Summary" href="Summary">

<p>
We hope this brief guide was a helpful introduction to using Velocity in
your Java projects, and thank you for you interest in Velocity.  We
welcome any and all comments you may have about this documentation and
the Velocity template engine itself.
</p>
<p>
Please submit all detailed, thoughtful and constructive feedback through our
<a href="http://velocity.apache.org/contact.html">mailing lists</a>.
</p>
</section>

</body>
</document>