Browse Source

* Attila Borka adapted examples from Lazarus so they do not rely on the LCL. Moving them to FPC

git-svn-id: trunk@17742 -
michael 14 years ago
parent
commit
b50a3bfd5d
100 changed files with 4867 additions and 0 deletions
  1. 146 0
      .gitattributes
  2. 117 0
      packages/fcl-web/examples/echo/README.txt
  3. 88 0
      packages/fcl-web/examples/echo/apache/echo.lpi
  4. 37 0
      packages/fcl-web/examples/echo/apache/echo.lpr
  5. BIN
      packages/fcl-web/examples/echo/apache/echo.res
  6. 83 0
      packages/fcl-web/examples/echo/cgi/echo.lpi
  7. 14 0
      packages/fcl-web/examples/echo/cgi/echo.lpr
  8. BIN
      packages/fcl-web/examples/echo/cgi/echo.res
  9. 83 0
      packages/fcl-web/examples/echo/fcgi/echo.lpi
  10. 15 0
      packages/fcl-web/examples/echo/fcgi/echo.lpr
  11. BIN
      packages/fcl-web/examples/echo/fcgi/echo.res
  12. 9 0
      packages/fcl-web/examples/echo/webmodule/wmecho.lfm
  13. 53 0
      packages/fcl-web/examples/echo/webmodule/wmecho.pas
  14. 63 0
      packages/fcl-web/examples/fptemplate/README.txt
  15. 144 0
      packages/fcl-web/examples/fptemplate/embedtemplates/README.txt
  16. 88 0
      packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpi
  17. 36 0
      packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpr
  18. BIN
      packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.res
  19. 83 0
      packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpi
  20. 13 0
      packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpr
  21. BIN
      packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.res
  22. 83 0
      packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpi
  23. 14 0
      packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpr
  24. BIN
      packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.res
  25. 14 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/body.html
  26. 9 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_left.html
  27. 9 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_right.html
  28. 11 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/bottom.html
  29. 13 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/maintemplate.html
  30. 11 0
      packages/fcl-web/examples/fptemplate/embedtemplates/templates/top.html
  31. 15 0
      packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.lfm
  32. 77 0
      packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.pas
  33. 149 0
      packages/fcl-web/examples/fptemplate/fileupload/README.txt
  34. 88 0
      packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpi
  35. 37 0
      packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpr
  36. BIN
      packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.res
  37. 83 0
      packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpi
  38. 13 0
      packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpr
  39. BIN
      packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.res
  40. 83 0
      packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpi
  41. 14 0
      packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpr
  42. BIN
      packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.res
  43. 67 0
      packages/fcl-web/examples/fptemplate/fileupload/templates/uploadform.html
  44. 17 0
      packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.lfm
  45. 233 0
      packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.pas
  46. 141 0
      packages/fcl-web/examples/fptemplate/listrecords/README.txt
  47. 88 0
      packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpi
  48. 37 0
      packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpr
  49. BIN
      packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.res
  50. 83 0
      packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpi
  51. 13 0
      packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpr
  52. BIN
      packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.res
  53. 83 0
      packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpi
  54. 14 0
      packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpr
  55. BIN
      packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.res
  56. 38 0
      packages/fcl-web/examples/fptemplate/listrecords/templates/mytemplate3.html
  57. 15 0
      packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.lfm
  58. 125 0
      packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.pas
  59. 145 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/README.txt
  60. 88 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpi
  61. 37 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpr
  62. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.res
  63. 83 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpi
  64. 14 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpr
  65. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.res
  66. 83 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpi
  67. 14 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpr
  68. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.res
  69. 25 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/templates/autosession-template.html
  70. 19 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.lfm
  71. 148 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.pas
  72. 164 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/README.txt
  73. 88 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpi
  74. 37 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpr
  75. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.res
  76. 83 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpi
  77. 14 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpr
  78. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.res
  79. 83 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpi
  80. 14 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpr
  81. BIN
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.res
  82. 22 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogin.html
  83. 10 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogout.html
  84. 15 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testsomepage.html
  85. 17 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testwelcome.html
  86. 2 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/userdb.txt
  87. 29 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.lfm
  88. 381 0
      packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.pas
  89. 153 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/README.txt
  90. 88 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpi
  91. 36 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpr
  92. BIN
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.res
  93. 83 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpi
  94. 13 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpr
  95. BIN
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.res
  96. 83 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpi
  97. 14 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpr
  98. BIN
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.res
  99. 23 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogin.html
  100. 10 0
      packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogout.html

+ 146 - 0
.gitattributes

@@ -2369,6 +2369,148 @@ packages/fcl-web/examples/combined/wmlogin.lfm svneol=native#text/plain
 packages/fcl-web/examples/combined/wmlogin.pp svneol=native#text/plain
 packages/fcl-web/examples/combined/wmusers.lfm svneol=native#text/plain
 packages/fcl-web/examples/combined/wmusers.pp svneol=native#text/plain
+packages/fcl-web/examples/echo/README.txt svneol=native#text/plain
+packages/fcl-web/examples/echo/apache/echo.lpi svneol=native#text/plain
+packages/fcl-web/examples/echo/apache/echo.lpr svneol=native#text/plain
+packages/fcl-web/examples/echo/apache/echo.res -text
+packages/fcl-web/examples/echo/cgi/echo.lpi svneol=native#text/plain
+packages/fcl-web/examples/echo/cgi/echo.lpr svneol=native#text/plain
+packages/fcl-web/examples/echo/cgi/echo.res -text
+packages/fcl-web/examples/echo/fcgi/echo.lpi svneol=native#text/plain
+packages/fcl-web/examples/echo/fcgi/echo.lpr svneol=native#text/plain
+packages/fcl-web/examples/echo/fcgi/echo.res -text
+packages/fcl-web/examples/echo/webmodule/wmecho.lfm svneol=native#text/plain
+packages/fcl-web/examples/echo/webmodule/wmecho.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.res -text
+packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.res -text
+packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.res -text
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/body.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_left.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_right.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/bottom.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/maintemplate.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/templates/top.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.res -text
+packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.res -text
+packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.res -text
+packages/fcl-web/examples/fptemplate/fileupload/templates/uploadform.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.res -text
+packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.res -text
+packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.res -text
+packages/fcl-web/examples/fptemplate/listrecords/templates/mytemplate3.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/templates/autosession-template.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.res -text
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogin.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogout.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testsomepage.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testwelcome.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/userdb.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.res -text
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.res -text
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.res -text
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogin.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogout.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurlsomepage.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurlwelcome.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/userdb.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/apache/simpletemplate.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/apache/simpletemplate.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/apache/simpletemplate.res -text
+packages/fcl-web/examples/fptemplate/simpletemplate/cgi/simpletemplate.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/cgi/simpletemplate.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/cgi/simpletemplate.res -text
+packages/fcl-web/examples/fptemplate/simpletemplate/fcgi/simpletemplate.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/fcgi/simpletemplate.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/fcgi/simpletemplate.res -text
+packages/fcl-web/examples/fptemplate/simpletemplate/templates/mytemplate1.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/simpletemplate/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/README.txt svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/apache/tagparam.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/apache/tagparam.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/apache/tagparam.res -text
+packages/fcl-web/examples/fptemplate/tagparam/cgi/tagparam.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/cgi/tagparam.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/cgi/tagparam.res -text
+packages/fcl-web/examples/fptemplate/tagparam/fcgi/tagparam.lpi svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/fcgi/tagparam.lpr svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/fcgi/tagparam.res -text
+packages/fcl-web/examples/fptemplate/tagparam/templates/mytemplate2.html svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/fptemplate/tagparam/webmodule/webmodule.pas svneol=native#text/plain
+packages/fcl-web/examples/helloworld/README.txt svneol=native#text/plain
+packages/fcl-web/examples/helloworld/apache/helloworld.lpi svneol=native#text/plain
+packages/fcl-web/examples/helloworld/apache/helloworld.lpr svneol=native#text/plain
+packages/fcl-web/examples/helloworld/apache/helloworld.res -text
+packages/fcl-web/examples/helloworld/cgi/helloworld.lpi svneol=native#text/plain
+packages/fcl-web/examples/helloworld/cgi/helloworld.lpr svneol=native#text/plain
+packages/fcl-web/examples/helloworld/cgi/helloworld.res -text
+packages/fcl-web/examples/helloworld/fcgi/helloworld.lpi svneol=native#text/plain
+packages/fcl-web/examples/helloworld/fcgi/helloworld.lpr svneol=native#text/plain
+packages/fcl-web/examples/helloworld/fcgi/helloworld.res -text
+packages/fcl-web/examples/helloworld/webmodule/webmodule.lfm svneol=native#text/plain
+packages/fcl-web/examples/helloworld/webmodule/webmodule.pas svneol=native#text/plain
 packages/fcl-web/examples/httpapp/testhttp.lpi svneol=native#text/plain
 packages/fcl-web/examples/httpapp/testhttp.pp svneol=native#text/plain
 packages/fcl-web/examples/httpclient/httpget.lpi svneol=native#text/plain
@@ -2395,6 +2537,10 @@ packages/fcl-web/examples/jsonrpc/extdirect/extdemo.lpr svneol=native#text/plain
 packages/fcl-web/examples/jsonrpc/extdirect/extdirect.in svneol=native#text/plain
 packages/fcl-web/examples/jsonrpc/extdirect/wmext.lfm svneol=native#text/plain
 packages/fcl-web/examples/jsonrpc/extdirect/wmext.pp svneol=native#text/plain
+packages/fcl-web/examples/session/sessiondemo.lpi svneol=native#text/plain
+packages/fcl-web/examples/session/sessiondemo.lpr svneol=native#text/plain
+packages/fcl-web/examples/session/wmsession.lfm svneol=native#text/plain
+packages/fcl-web/examples/session/wmsession.pp svneol=native#text/plain
 packages/fcl-web/examples/webdata/demo/createusers.lpi svneol=native#text/plain
 packages/fcl-web/examples/webdata/demo/createusers.lpr svneol=native#text/plain
 packages/fcl-web/examples/webdata/demo/extgrid-json.html svneol=native#text/plain

+ 117 - 0
packages/fcl-web/examples/echo/README.txt

@@ -0,0 +1,117 @@
+Responds with the calling and system parameters, example
+================================================
+Demonstrates how to create a basic fpweb application. It responds to a request 
+with a list of received/sent parameters, server settings and variables.
+
+Note, that other than the main project file (echo.lpr) there is not much that 
+needs to change with using fpweb, no matter if we create CGI/FCGI applications 
+or Apache modules. The web server config is different for each, of course.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule echo.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the choosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+
+2.a; as CGI
+-----------
+http://<WebServer>/cgi-bin/<CGIExecutableName>/ should start the example if 
+everything is set up properly.
+ex: http://127.0.0.1:8080/cgi-bin/echo.exe/
+
+Note: You need to change the CGI application name if needed (for example, on 
+Linux it is not echo.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+http://<WebServer>/<ApacheLocationName>/ should start the example if 
+everything is set up properly.
+ex: http://127.0.0.1:8080/myapache/
+
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule mod_echo "<path_to_mod>/echo.dll"
+<Location /myapache>
+    SetHandler mod_echo
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module can be libecho.so or just simply libecho and not echo.dll .
+
+Note: If you recompile an Apache module while the module itself is loaded into
+the Apache server, the compilation will fail, because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+Apache server before you recompile or before you copy over the new version of 
+the created module.
+
+
+2.c; as FCGI
+------------
+http://<WebServer>/<ApacheScriptAliasName>/ should start the example if 
+everything is set up properly.
+ex: http://127.0.0.1:8080/myfcgi/
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+#    Options +ExecCGI  <- not needed if ScriptAlias is used below
+    Order allow,deny
+    Allow from all
+  </Directory>
+#External FCGI app, has to start manually, Apache will not do it
+  FastCgiExternalServer "<path_to_fcgi_app>/echo.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+#optionally, to shorten the calling URL and to not display the executable file name (if used, no +ExecCGI is needed above)
+  ScriptAlias /myfcgi "<path_to_fcgi_app>/echo.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (echo.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/echo/apache/echo.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="echo.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="echo"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\wmecho.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="EchoModule"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="wmecho"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 37 - 0
packages/fcl-web/examples/echo/apache/echo.lpr

@@ -0,0 +1,37 @@
+Library echo;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, wmecho;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_echo';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.
+

BIN
packages/fcl-web/examples/echo/apache/echo.res


+ 83 - 0
packages/fcl-web/examples/echo/cgi/echo.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="echo.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="echo"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\wmecho.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="EchoModule"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="wmecho"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/echo/cgi/echo.lpr

@@ -0,0 +1,14 @@
+program echo;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, wmecho;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.
+

BIN
packages/fcl-web/examples/echo/cgi/echo.res


+ 83 - 0
packages/fcl-web/examples/echo/fcgi/echo.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="echo.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="echo"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\wmecho.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="EchoModule"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="wmecho"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 15 - 0
packages/fcl-web/examples/echo/fcgi/echo.lpr

@@ -0,0 +1,15 @@
+program echo;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, wmecho;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.
+

BIN
packages/fcl-web/examples/echo/fcgi/echo.res


+ 9 - 0
packages/fcl-web/examples/echo/webmodule/wmecho.lfm

@@ -0,0 +1,9 @@
+object EchoModule: TEchoModule
+  OldCreateOrder = False
+  OnRequest = EchoModuleRequest
+  CreateSession = False
+  Height = 282
+  HorizontalOffset = 153
+  VerticalOffset = 411
+  Width = 316
+end

+ 53 - 0
packages/fcl-web/examples/echo/webmodule/wmecho.pas

@@ -0,0 +1,53 @@
+unit wmecho;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, httpdefs, fpHTTP, fpWeb, webutil;
+
+type
+
+  { TEchoModule }
+
+  TEchoModule = class(TFPWebModule)
+    procedure EchoModuleRequest(Sender: TObject; ARequest: TRequest;
+      AResponse: TResponse; var Handled: Boolean);
+  private
+    { private declarations }
+  public
+    { public declarations }
+  end; 
+
+var
+  EchoModule: TEchoModule;
+
+implementation
+
+{$R *.lfm}
+
+{ TEchoModule }
+
+procedure TEchoModule.EchoModuleRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+Var
+  S : TStrings;
+
+begin
+  S:=TStringList.Create;
+  try
+    // Analyze request.
+    DumpRequest(ARequest,S);
+
+    AResponse.Contents:=S;
+    Handled:=True;
+  finally
+    S.Free;
+  end;
+end;
+
+initialization
+  RegisterHTTPModule('TEchoModule', TEchoModule);
+end.
+

+ 63 - 0
packages/fcl-web/examples/fptemplate/README.txt

@@ -0,0 +1,63 @@
+FPTemplate examples
+===================
+These examples are demonstrating some uses of templates (with FPTemplate) when 
+generating HTML pages by CGI/FCGI programs or Apache modules.
+
+The main idea is to leave the web page designing and look&feel to the web page 
+designers. Separating the web page design from the back-end CGI/FCGI/Apache 
+application makes it possible to design, change or redesign a whole website 
+without modifying a single line of code in the CGI/FCGI/Apache application. 
+Back-end programmers and web page designers can work parallel easily, and 
+neither side needs extensive knowledge of the other (does not hurt, just not 
+necessary most of the time). 
+
+With all this said, none of the examples are focusing on nice look and feel in 
+their template designs, merely on demonstrating the functionality and use of 
+templates, template-tags and template-tag-parameters with live applications.
+
+
+Examples list:
+
+1. /simpletemplate/*.*
+The simplest template with one template tag in it to be replaced by the 
+CGI/FCGI/Apache application when generating the response page -> {TagName1}
+See README.txt
+
+2. /tagparam/*.*
+Demonstrating the set up and use of template tag parameter(s) 
+-> {+DATETIME [-FORMAT=MM/DD hh:mm:ss-]+}
+
+3. /listrecords/*.*
+Demonstrates the use of a template tag with multiple template tag parameters 
+to list multiple records, tables, lists, etc.
+See README.txt
+
+4. /fileupload/*.*
+Demonstrates uploading file(s) to a web server with the help of a CGI/FCGI 
+program or Apache module by using so called "multipart" html forms.
+See README.txt
+                                
+5. /sessions/*.*
+These examples demonstrate three different ways to maintain and use sessions 
+when building web sites that need to carry over or store information to 
+following web pages, differentiate between visitors, etc.
+
+5.a. /sessions/cookiesessions-auto/*.*
+See README.txt
+
+5.b. /sessions/cookiesessions-login/*.*
+See README.txt
+
+5.c. /sessions/urlsessions-login/*.*
+See README.txt
+
+6. /embedtemplates/*.*
+An example to show how to implement recursively embedded templates with fpweb.
+See README.txt
+
+Note: All of the examples have CGI, FCGI and Apache variations. The web 
+modules (webmodule.pas, webmodule.lfm) and template html files for the paired 
+CGI/FCGI/Apache applications are exactly the same, showing that from a 
+developer standpoint there is not too much difference between writing CGI/FCGI 
+programs or Apache modules with fcl-web (fpweb). The main differences are in 
+the main project files (.lpr) and in the web server configurations.

+ 144 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/README.txt

@@ -0,0 +1,144 @@
+Recursively embedded templates, example
+===============================
+Demonstrates how to recursively embed templates using template tags.
+Note, that the only difference between CGI/FCGI and Apache module is in the 
+main project .lpr file and the web server (Apache) configuration.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule embedtemplates.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template file(s).
+It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: TMPTemplate.FileName := '/full/path/to/templates/'+TemplateFile+'.html';
+
+
+2.a; as CGI
+-----------
+Usually it works if you put the templates next to the CGI executable file 
+under a /templates subdirectory. 
+(ex: ...cgi-bin/templates/maintemplate.html , etc.)
+Adjust the file path in the web module (webmodule.pas) accordingly.
+
+http://<WebServer>/cgi-bin/<CGIExecutableName>/func1call should start the 
+example if everything is set up properly, and the executable is copied into 
+the Apache cgi-bin directory with the template files under ./templates .
+ex: http://127.0.0.1:8080/cgi-bin/embedtemplates.exe/func1call
+
+If the calling URL looks too long, or you want to hide it a little bit more, 
+you can use a ScriptAlias in the Apache configuration file to make it shorter.
+ex: ScriptAlias /mycgi "<path_to_cgi_app>/embedtemplates.exe" in your conf 
+file will make http://127.0.0.1:8080/mycgi/func1call work the same way.
+
+Note: You need to change the URLs if "cgi-bin" or "embedtemplates.exe" 
+changes (for example on Linux it is not embedtemplates.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the templates into the Apache main directory (not 
+the DocumentRoot, but the main Apache directory).
+(.../templates/maintemplate.html , etc.)
+Adjust the file path in the web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/func1call should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/myapache/func1call
+or  http://127.0.0.1/myapache/func1call
+if in httpd.conf it was set up as:
+LoadModule mod_embedtemplates "<path_to_mod>/embedtemplates.dll"
+<Location /myapache>
+    SetHandler mod_embedtemplates
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "myapache" or the 
+module name changes. For example on Linux the module can be 
+libembedtemplates.so and not embedtemplates.dll
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the templates next to the FCGI executable file 
+under a /templates subdirectory. 
+(..../templates/maintemplate.html , etc.)
+Adjust the file path in the web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/func1call should start the example 
+if everything is set up properly.
+ex: http://127.0.0.1:8080/myfcgi/func1call
+or  http://127.0.0.1/myfcgi/func1call
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+#    Options +ExecCGI  <- not needed if ScriptAlias is used below
+    Order allow,deny
+    Allow from all
+  </Directory>
+#External FCGI app, has to start manually, Apache will not do it
+  FastCgiExternalServer "<path_to_fcgi_app>/embedtemplates.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+#optionally, to shorten the calling URL and to not display the executable file name (if used, no +ExecCGI is needed above)
+  ScriptAlias /myfcgi "<path_to_fcgi_app>/embedtemplates.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (embedtemplates.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="embedtemplates.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="embedtemplates"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 36 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.lpr

@@ -0,0 +1,36 @@
+Library embedtemplates;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_embedtemplates';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.

BIN
packages/fcl-web/examples/fptemplate/embedtemplates/apache/embedtemplates.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="embedtemplates.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="embedtemplates"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 13 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.lpr

@@ -0,0 +1,13 @@
+program embedtemplates;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/embedtemplates/cgi/embedtemplates.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="embedtemplates.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="embedtemplates"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.lpr

@@ -0,0 +1,14 @@
+program embedtemplates;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/embedtemplates/fcgi/embedtemplates.res


+ 14 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/body.html

@@ -0,0 +1,14 @@
+<!-- body.html start -->
+<br>
+Something here for the body
+
+<table border=1>
+ <tr>
+  <td valign="center" width=200 height=200>
+{+INCLUDETEMPLATE [-TEMPLATEFILE=body_left.html-]+}
+  </td><td valign="center" width=200 height=200>
+{+INCLUDETEMPLATE [-TEMPLATEFILE=body_right.html-]+}
+  </td>
+ </tr>
+</table>
+<!-- body.html end -->

+ 9 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_left.html

@@ -0,0 +1,9 @@
+<!-- body_left.html start -->
+Body left
+<ul>
+<li>a
+<li>b
+<li>c
+<li>d
+</ul>
+<!-- body_left.html end -->

+ 9 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/body_right.html

@@ -0,0 +1,9 @@
+<!-- body_right.html start -->
+Body right
+<ul>
+<li>1
+<li>2
+<li>3
+<li>4
+</ul>
+<!-- body_right.html end -->

+ 11 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/bottom.html

@@ -0,0 +1,11 @@
+<!-- bottom.html start -->
+<br>
+<table border=1>
+ <tr>
+  <td>
+<b>Bottom part</b>
+Powered by FPC/Lazarus (c){+DATETIME [-FORMAT=YYYY-]+}
+  </td>
+ </tr>
+</table>
+<!-- bottom.html end -->

+ 13 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/maintemplate.html

@@ -0,0 +1,13 @@
+<html>
+<body>
+<!-- maintemplate.html start -->
+
+{+INCLUDETEMPLATE [-TEMPLATEFILE=top.html-]+}
+
+{+INCLUDETEMPLATE [-TEMPLATEFILE=body.html-]+}
+
+{+INCLUDETEMPLATE [-TEMPLATEFILE=bottom.html-]+}
+
+<!-- maintemplate.html end -->
+</body>
+</html>

+ 11 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/templates/top.html

@@ -0,0 +1,11 @@
+<!-- top.html start -->
+<table border=1>
+ <tr>
+  <td>
+Embedding templates example:<br>
+<b>TOP template</b><br>
+DateTime in format "MM/DD hh:mm:ss": <b>{+DATETIME [-FORMAT=MM/DD hh:mm:ss-]+}</b>
+  </td>
+ </tr>
+</table>
+<!-- top.html end -->

+ 15 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.lfm

@@ -0,0 +1,15 @@
+object FPWebModule1: TFPWebModule1
+  OldCreateOrder = False
+  Actions = <  
+    item
+      Name = 'func1call'
+      Default = True
+      OnRequest = func1callRequest
+      Template.AllowTagParams = False
+    end>
+  CreateSession = False
+  Height = 300
+  HorizontalOffset = 210
+  VerticalOffset = 204
+  Width = 400
+end

+ 77 - 0
packages/fcl-web/examples/fptemplate/embedtemplates/webmodule/webmodule.pas

@@ -0,0 +1,77 @@
+unit webmodule; 
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, httpdefs, fpHTTP, fpWeb, fpTemplate;
+
+type
+
+  { TFPWebModule1 }
+
+  TFPWebModule1 = class(TFPWebModule)
+    procedure func1callRequest(Sender: TObject; ARequest: TRequest;
+      AResponse: TResponse; var Handled: Boolean);
+  private
+    { private declarations }
+    procedure func1callReplaceTag(Sender: TObject; const TagString:String; 
+      TagParams: TStringList; Out ReplaceText: String);
+    function UseTemplate(TemplateFile:String; TagHandler:TReplaceTagEvent):String;
+  public
+    { public declarations }
+  end; 
+
+var
+  FPWebModule1: TFPWebModule1; 
+
+implementation
+
+{$R *.lfm}
+
+{ TFPWebModule1 }
+
+procedure TFPWebModule1.func1callRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+begin
+  //func1callReplaceTag is recursively processing the template tags for all
+  //embedded templates (INCLUDETEMPLATE tag defines a new template to embed)
+  AResponse.Content := UseTemplate('maintemplate', @func1callReplaceTag);
+  Handled := true;
+end;
+
+function TFPWebModule1.UseTemplate(TemplateFile:String; TagHandler:TReplaceTagEvent):String;
+var TMPTemplate:TFPTemplate;
+begin
+  TMPTemplate := TFPTemplate.Create;
+  TMPTemplate.FileName := '/path/to/templates/' + TemplateFile + '.html';
+  TMPTemplate.AllowTagParams := true;
+  TMPTemplate.StartDelimiter := '{+';
+  TMPTemplate.EndDelimiter := '+}';
+  TMPTemplate.OnReplaceTag := TagHandler;
+  Result  := TMPTemplate.GetContent;
+  TMPTemplate.Free;
+end;
+
+procedure TFPWebModule1.func1callReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+begin//HTML template tag handling for an html template file
+  if AnsiCompareText(TagString, 'DATETIME') = 0 then
+  begin
+    ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
+  end else
+
+  if AnsiCompareText(TagString, 'INCLUDETEMPLATE') = 0 then
+  begin
+    ReplaceText := UseTemplate(TagParams.Values['TEMPLATEFILE'], @func1callReplaceTag);
+  end else begin
+
+//Not found value for tag -> TagString
+    ReplaceText := 'Template tag {+' + TagString + '+} is not implemented yet.';
+  end;
+end;
+
+initialization
+  RegisterHTTPModule('TFPWebModule1', TFPWebModule1); 
+end.

+ 149 - 0
packages/fcl-web/examples/fptemplate/fileupload/README.txt

@@ -0,0 +1,149 @@
+File upload from html form, example
+==========================
+Demonstrates how to handle the file upload (multipart) html forms with 
+templates.
+
+Note, that the only difference between CGI/FCGI and Apache module is in the 
+main project .lpr file and the web server (Apache) configuration.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule fileupload.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template file(s).
+It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: ModuleTemplate.FileName := '/full/path/to/templates/uploadform.html';
+
+It needs read/write access to create the file database filelist.txt
+ex: FileDB := '/full/path/to/templates/filelist.txt';
+
+Also, it needs an "/upfiles" directory with read/write access where the files 
+will be uploaded to.
+ex: UploadDir := '/full/path/to/upfiles/';
+
+
+2.a; as CGI
+-----------
+Usually it works if you put the template (uploadform.html) next to the CGI 
+executable file in the Apache cgi-bin directory. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/listfiles should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/fileuploader/listfiles
+if in the Apache configuration file (ex: httpd.conf) it was set up as 
+ScriptAlias /fileuploader "<path_to_app>/<app_name>"
+ex:
+ScriptAlias /fileuploader "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/fileupload.exe"
+(uploadform.html is copied next to fileupload.exe into cgi-bin, and cgi-bin 
+has a subdirectory called "upfiles")
+
+Note: You need to change the URLs or the Apache configuration if "fileuploader"
+ or "fileupload.exe" changes (for example on Linux it is not fileupload.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL:
+http://127.0.0.1/fileuploader/listfiles
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the template (uploadform.html) into the Apache 
+main directory (not the DocumentRoot, but the main Apache directory), under 
+sub-directory "templates" or something similar. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/listfiles should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/fileuploader/listfiles
+or http://127.0.0.1/fileuploader/listfiles
+if in httpd.conf it was set up as:
+LoadModule mod_fileupload "<path_to_mod>/fileupload.dll"
+<Location /fileuploader>
+    SetHandler mod_fileupload
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "fileuploader" changes. 
+Also, for example on Linux the module can be libfileupload.so and not 
+fileupload.dll 
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the template (uploadform.html) next to the FCGI 
+executable file. Adjust the file path in the web module (webmodule.pas) 
+accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/listfiles should start the example 
+if everything is set up properly.
+ex: http://127.0.0.1:8080/fileuploader/func1call
+or  http://127.0.0.1/fileuploader/func1call
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+    Order allow,deny
+    Allow from all
+  </Directory>
+  FastCgiExternalServer "<path_to_fcgi_app>/fileupload.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+  ScriptAlias /fileuploader "<path_to_fcgi_app>/fileupload.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (fileupload.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="fileupload.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fileupload"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 37 - 0
packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.lpr

@@ -0,0 +1,37 @@
+Library fileupload;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_fileupload';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/fileupload/apache/fileupload.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="fileupload.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fileupload"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 13 - 0
packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.lpr

@@ -0,0 +1,13 @@
+program fileupload;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/fileupload/cgi/fileupload.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="fileupload.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="fileupload"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.lpr

@@ -0,0 +1,14 @@
+program fileupload;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/fileupload/fcgi/fileupload.res


+ 67 - 0
packages/fcl-web/examples/fptemplate/fileupload/templates/uploadform.html

@@ -0,0 +1,67 @@
+<html>
+<head>
+<script type="text/javascript" language="JavaScript1.2">
+
+function chkFields(){
+
+  var Error = false;
+
+  if ( document.DataForm.uploaderperson.value == '')
+    { alert('Please enter an uploader person.'); }
+  else if ( (document.DataForm.file1.value == '') && (document.DataForm.file2.value == '') )
+    { alert('Please select a file to upload.'); }
+  else
+    Error = true;
+
+  return Error;
+}
+
+</script>
+</head>
+<body>
+File upload screen<br>
+<small>Last refresh: {+DATETIME [-FORMAT=MM/DD/YYYY hh:mm:ss.zzz-]+}</small><br><br>
+
+{+MESSAGES [-TOOBIG=<font color="red">You have tried to upload a file that exceeds the size limit.</font>-]
+           [-NOTFOUND=<font color="red">File not found for delete.</font>-]
++}
+
+<br><br>Maximum allowed file size to be stored: {+MAX_SIZE+}MB<br>
+
+ <form action="/fileuploader/listfiles" method="post" enctype="multipart/form-data" name="DataForm" onsubmit="return chkFields();">
+         
+  <table>
+   <tr>
+    <td>Uploader:</td>
+    <td><input type="text" name="uploaderperson" value=""></td>
+   </tr>
+   <tr>
+    <td>File1:</td>
+    <td><input name="file1" type="file" size="60"></td>
+   </tr>
+   <tr>
+    <td>File2:</td>
+    <td><input name="file2" type="file" size="60"></td>
+   </tr>
+   <tr>
+    <td colspan=2 align="center"><input type="submit" value="Upload"></td>
+   </tr>
+  </table>
+
+ </form><br><br>
+
+Uploaded File List (.../{+UPLOAD_DIR+}):
+ <table border=1>
+  <tr><th>File Name</th><th>Uploader</th></tr>
+{+FILELIST
+ [-ONE_ROW=
+  <tr><td><pre>~FILENAME</pre></td><td>~UPLOADER</td><td><a href="/fileuploader/listfiles?delete=~DFILENAME">Delete</a></td></tr>
+ -]
+ [-NOTHINGTOLIST=
+  <tr><td colspan=3>No files to list</td></tr>
+ -]
++}
+ </table>
+
+</body>
+</html>

+ 17 - 0
packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.lfm

@@ -0,0 +1,17 @@
+object FPWebModule1: TFPWebModule1
+  OnCreate = DataModuleCreate
+  OldCreateOrder = False
+  Actions = <  
+    item
+      Name = 'listfiles'
+      Default = True
+      OnRequest = listfilesRequest
+      Template.AllowTagParams = False
+    end>
+  AfterResponse = DataModuleAfterResponse
+  CreateSession = False
+  Height = 300
+  HorizontalOffset = 290
+  VerticalOffset = 149
+  Width = 400
+end

+ 233 - 0
packages/fcl-web/examples/fptemplate/fileupload/webmodule/webmodule.pas

@@ -0,0 +1,233 @@
+unit webmodule; 
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, httpdefs, fpHTTP, fpWeb;
+
+type
+
+  { TFPWebModule1 }
+
+  TFPWebModule1 = class(TFPWebModule)
+    procedure DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
+    procedure DataModuleCreate(Sender: TObject);
+    procedure listfilesRequest(Sender: TObject; ARequest: TRequest;
+      AResponse: TResponse; var Handled: Boolean);
+  private
+    { private declarations }
+    UploadDir:String;
+    FileDB:String;
+    MaxSize:Integer;
+    procedure DeleteTheFile(const FN:String);
+    procedure HandleUploadedFiles;
+    procedure listfilesReplaceTag(Sender: TObject; const TagString:String;
+      TagParams: TStringList; Out ReplaceText: String);
+  public
+    { public declarations }
+  end; 
+
+var
+  FPWebModule1: TFPWebModule1; 
+
+implementation
+
+{$R *.lfm}
+
+{ TFPWebModule1 }
+
+//In real applications, CopyFile should be used from unit FileUtil of the LCL
+function CopyTheFile(const SrcFilename, DestFilename: String): Boolean;
+var SrcFS, DestFS: TFileStream;
+begin
+  Result := False;
+  SrcFS := TFileStream.Create(SrcFilename, fmOpenRead or fmShareDenyWrite);
+  try
+    DestFS := TFileStream.Create(DestFilename, fmCreate);
+    try
+      DestFS.CopyFrom(SrcFS, SrcFS.Size);
+    finally
+      DestFS.Free;
+    end;
+  finally
+    SrcFS.Free;
+  end;
+  Result := True;
+end;
+
+procedure TFPWebModule1.DataModuleAfterResponse(Sender: TObject;
+  AResponse: TResponse);
+begin
+  //reset global variables for apache modules for the next incoming request
+
+  //
+end;
+
+procedure TFPWebModule1.DataModuleCreate(Sender: TObject);
+begin
+  UploadDir := 'upfiles/';
+  FileDB := 'filelist.txt';
+  MaxSize := 2;//MB
+end;
+
+procedure TFPWebModule1.DeleteTheFile(const FN:String);
+var
+  FDB: TStringList;
+  s:String;
+begin
+  FDB := TStringList.Create;
+  if FileExists(FileDB) then
+    FDB.LoadFromFile(FileDB);
+
+  s := FDB.Values[FN];
+  if s <> '' then
+  begin
+    FDB.Delete(FDB.IndexOfName(FN));
+    FDB.SaveToFile(FileDB);
+    FDB.Free;
+  end else begin
+    FDB.Free;
+    Request.QueryFields.Add('_MSG=NOTFOUND');//NOTFOUND message will be displayed on the response page
+    Exit;
+  end;
+
+  //delete the file
+  s := UploadDir + FN;
+  if FileExists(s) then
+    DeleteFile(s);
+end;
+
+procedure TFPWebModule1.HandleUploadedFiles;
+var
+  i:Integer;
+  all_ok:Boolean;
+  FDB: TStringList;
+  Uploader, FN:String;
+begin
+  if Request.Files.Count <= 0 then Exit;
+
+  //process the uploaded files if there was any
+  all_ok := true;
+  for i := 0 to Request.Files.Count - 1 do
+  begin//check sizes
+    if Request.Files[i].Size > (MaxSize * 1024 * 1024) then
+    begin//exceeds size limit
+      all_ok := false;
+      Request.QueryFields.Add('_MSG=TOOBIG');//TOOBIG message will be displayed on the response page
+      break;
+    end;
+  end;
+
+  if all_ok then //copy the file(s) to the upload directory (the temporary files will be deleted automatically after the request is handled)
+  begin
+    Uploader := Request.ContentFields.Values['UPLOADERPERSON'];
+    if Uploader = '' then
+      Uploader := '-';
+    FDB := TStringList.Create;
+    if FileExists(FileDB) then
+      FDB.LoadFromFile(FileDB);
+    for i := 0 to Request.Files.Count - 1 do
+    begin
+      FN := Request.Files[i].FileName;
+      if (FN <> '')and(Request.Files[i].Size > 0) then
+      begin
+        CopyTheFile(Request.Files[i].LocalFileName, UploadDir + FN);//copy (or overwrite) the file to the upload dir
+        if FDB.Values[FN] <> '' then
+          FDB.Values[FN] := Uploader                              //overwrite the previous uploader
+        else
+          FDB.Add(FN + '=' + Uploader);                           //store the file and the uploader into the file database
+      end;
+    end;
+    FDB.SaveToFile(FileDB);
+    FDB.Free;
+  end;
+end;
+
+procedure TFPWebModule1.listfilesRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+var
+  FN:String;
+begin
+  //ModuleTemplate is a web module global property
+  //To use the Template propery of the current web action (which is visible in
+  //the object inspector for every Action), use
+  //(Sender as TFPWebAction).Template.FileName := 'mytemplate1.html'; and so on.
+  ModuleTemplate.FileName := 'uploadform.html';
+  ModuleTemplate.AllowTagParams := true;
+  ModuleTemplate.StartDelimiter := '{+';
+  ModuleTemplate.EndDelimiter := '+}';
+  ModuleTemplate.OnReplaceTag := @listfilesReplaceTag;
+
+  FN := ARequest.QueryFields.Values['DELETE'];
+  if FN <> '' then
+    DeleteTheFile(FN)
+  else
+    HandleUploadedFiles;
+
+  AResponse.Content := ModuleTemplate.GetContent;//Generate the response page using the template
+
+  Handled := true;
+end;
+
+procedure TFPWebModule1.listfilesReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+var
+  SL:TStringList;
+  i:Integer;
+  FileName, Uploader, One_Row:String;
+begin
+  if AnsiCompareText(TagString, 'DATETIME') = 0 then
+  begin
+    ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
+  end else
+
+  if AnsiCompareText(TagString, 'MAX_SIZE') = 0 then
+  begin
+    ReplaceText := IntToStr(MaxSize);
+  end else
+
+  if AnsiCompareText(TagString, 'UPLOAD_DIR') = 0 then
+  begin
+    ReplaceText := UploadDir;
+  end else
+
+  if AnsiCompareText(TagString, 'MESSAGES') = 0 then
+  begin
+    ReplaceText := TagParams.Values[Request.QueryFields.Values['_MSG']];
+  end else
+
+  if AnsiCompareText(TagString, 'FILELIST') = 0 then
+  begin
+    SL := TStringList.Create;
+    if FileExists(FileDB) then
+      SL.LoadFromFile(FileDB);
+    if SL.Count > 0 then
+    begin
+      One_Row := TagParams.Values['ONE_ROW'];
+      for i := 0 to SL.Count - 1 do
+      begin
+        FileName := SL.Names[i];
+        Uploader := SL.Values[FileName];
+        if (FileName <> '')and(Uploader <> '') then
+          ReplaceText := ReplaceText + StringReplace(StringReplace(StringReplace(One_Row
+                                       ,'~FILENAME', FileName, [])
+                                       ,'~UPLOADER', Uploader, [])
+                                       ,'~DFILENAME', HTTPEncode(FileName), []) + #13#10;
+      end;
+    end else begin
+      ReplaceText := TagParams.Values['NOTHINGTOLIST'];
+    end;
+    SL.Free;
+  end else
+
+  {Message for tags not handled}
+  begin
+    ReplaceText := '[Template tag {+' + TagString + '+} is not implemented yet.]';
+  end;
+end;
+
+initialization
+  RegisterHTTPModule('TFPWebModule1', TFPWebModule1); 
+end.

+ 141 - 0
packages/fcl-web/examples/fptemplate/listrecords/README.txt

@@ -0,0 +1,141 @@
+List records using template tags, example
+================================
+Demonstrates how to list multiple records using templates and template tags.
+Note, that the only difference between CGI/FCGI and Apache module is in the 
+main project .lpr file and the web server (Apache) configuration.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule listrecords.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template file(s).
+It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: ModuleTemplate.FileName := '/full/path/to/template/mytemplate3.html';
+
+2.a; as CGI
+-----------
+Usually it works if you put the template (mytemplate3.html) next to the CGI 
+executable file in the Apache cgi-bin directory. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/cgi-bin/<CGIExecutableName>/func1call should start the 
+example if everything is set up properly, and the executable is copied into 
+the Apache cgi-bin directory with the template file.
+ex: http://127.0.0.1:8080/cgi-bin/listrecords.exe/func1call
+
+If the calling URL looks too long, or you want to hide it a little bit more, 
+you can use a ScriptAlias in the Apache configuration file to make it shorter.
+ex: ScriptAlias /mycgi "<path_to_cgi_app>/listrecords.exe" in your conf 
+file will make http://127.0.0.1:8080/mycgi/func1call work the same way.
+
+Note: You need to change the URLs if "cgi-bin" or "listrecords.exe" 
+changes (for example on Linux it is not listrecords.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the template (mytemplate3.html) into the Apache 
+main directory (not the DocumentRoot, but the main Apache directory), under 
+sub-directory "templates" or something similar. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/func1call should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/myapache/func1call
+or  http://127.0.0.1/myapache/func1call
+if in httpd.conf it was set up as:
+LoadModule mod_listrecords "<path_to_mod>/listrecords.dll"
+<Location /myapache>
+    SetHandler mod_listrecords
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "myapache" changes. 
+Also, for example on Linux the module can be liblistrecords.so and not 
+listrecords.dll
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the template (mytemplate3.html) next to the FCGI 
+executable file. Adjust the file path in the web module (webmodule.pas) 
+accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/func1call should start the example 
+if everything is set up properly.
+ex: http://127.0.0.1:8080/myfcgi/func1call
+or  http://127.0.0.1/myfcgi/func1call
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+#    Options +ExecCGI  <- not needed if ScriptAlias is used below
+    Order allow,deny
+    Allow from all
+  </Directory>
+#External FCGI app, has to start manually, Apache will not do it
+  FastCgiExternalServer "<path_to_fcgi_app>/listrecords.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+#optionally, to shorten the calling URL and to not display the executable file name (if used, no +ExecCGI is needed above)
+  ScriptAlias /myfcgi "<path_to_fcgi_app>/listrecords.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (listrecords.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="listrecords.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="listrecords"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 37 - 0
packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.lpr

@@ -0,0 +1,37 @@
+Library mod_listrecords;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_listrecords';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/listrecords/apache/listrecords.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="listrecords.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="listrecords"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 13 - 0
packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.lpr

@@ -0,0 +1,13 @@
+program listrecords;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/listrecords/cgi/listrecords.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="listrecords.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="listrecords"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.lpr

@@ -0,0 +1,14 @@
+program listrecords;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/listrecords/fcgi/listrecords.res


+ 38 - 0
packages/fcl-web/examples/fptemplate/listrecords/templates/mytemplate3.html

@@ -0,0 +1,38 @@
+<html>
+<body>
+DateTime in format "MM/DD hh:mm:ss": <b>{+DATETIME [-FORMAT=MM/DD hh:mm:ss-]+}</b>
+
+<br>
+
+List of records:
+<table class="beautify1">
+ <tr class="beautify2">
+  <td class="beautify3">
+
+  {+REPORTRESULT 
+   [-HEADER=
+    <table bordercolorlight="#6699CC" bordercolordark="#E1E1E1" class="Label">
+     <tr class="Label" align=center bgcolor="#6699CC">
+      <th><font color="white">~Column1</font></th>
+      <th><font color="white">~Column2</font></th>
+     </tr>
+   -]
+   [- ONEROW =
+     <tr bgcolor="#F2F2F2" class="Label3" align="center">
+      <td>~Column1Value</td><td>~Column2value</td>
+     </tr>
+   -]
+.
+.snip, and so on more parameters if needed
+.
+   [- NOTFOUND=
+    <tr class="Error"><td>There are no entries found.</td></tr> 
+   -]
+   [-FOOTER=    </table>-]
+  +}
+
+  </td>
+ </tr>
+</table>
+</body>
+</html>

+ 15 - 0
packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.lfm

@@ -0,0 +1,15 @@
+object FPWebModule1: TFPWebModule1
+  OldCreateOrder = False
+  Actions = <  
+    item
+      Name = 'func1call'
+      Default = True
+      OnRequest = func1callRequest
+      Template.AllowTagParams = False
+    end>
+  CreateSession = False
+  Height = 300
+  HorizontalOffset = 290
+  VerticalOffset = 149
+  Width = 400
+end

+ 125 - 0
packages/fcl-web/examples/fptemplate/listrecords/webmodule/webmodule.pas

@@ -0,0 +1,125 @@
+unit webmodule; 
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, httpdefs, fpHTTP, fpWeb;
+
+type
+
+  { TFPWebModule1 }
+
+  TFPWebModule1 = class(TFPWebModule)
+    procedure func1callRequest(Sender: TObject; ARequest: TRequest;
+      AResponse: TResponse; var Handled: Boolean);
+  private
+    { private declarations }
+    procedure func1callReplaceTag(Sender: TObject; const TagString:String; 
+      TagParams: TStringList; Out ReplaceText: String);
+  public
+    { public declarations }
+  end; 
+
+var
+  FPWebModule1: TFPWebModule1; 
+
+implementation
+
+{$R *.lfm}
+
+{ TFPWebModule1 }
+
+procedure TFPWebModule1.func1callRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+begin
+  //ModuleTemplate is a web module global property
+  //To use the Template propery of the current web action (which is visible in
+  //the object inspector for every Action), use
+  //(Sender as TFPWebAction).Template.FileName := 'mytemplate1.html'; and so on.
+  ModuleTemplate.FileName := 'mytemplate3.html';{template file with the template tag -> REPORTRESULT}
+  ModuleTemplate.AllowTagParams := true;
+  ModuleTemplate.StartDelimiter := '{+';
+  ModuleTemplate.EndDelimiter := '+}';
+  ModuleTemplate.OnReplaceTag := @func1callReplaceTag;
+
+  AResponse.Content := ModuleTemplate.GetContent;
+
+  Handled := true;
+end;
+
+procedure TFPWebModule1.func1callReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+var
+   header, footer, onerow:String;
+   NoRecordsToShow:Boolean;
+   ColumnHeaders:array[1..2] of String;
+   ColumnValues:array[1..3,1..2]of String;
+   I:Integer;
+begin//HTML template tag handling for an html template file
+
+  if AnsiCompareText(TagString, 'DATETIME') = 0 then
+  begin
+    ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
+  end else 
+
+  //Replace the REPORTRESULT html tag using it's tag parameters
+  if AnsiCompareText(TagString, 'REPORTRESULT') = 0 then
+  begin
+    //fill up some arrays with data (could come from a SQL query)
+    NoRecordsToShow := false;
+
+    ColumnHeaders[1] := 'Amount';
+    ColumnHeaders[2] := 'Percentage';
+
+    ColumnValues[1,1] := '10.00';
+    ColumnValues[1,2] := '5';
+
+    ColumnValues[2,1] := '15.00';
+    ColumnValues[2,2] := '4';
+
+    ColumnValues[3,1] := '20.00';
+    ColumnValues[3,2] := '3';
+
+    //NoRecordsToShow could be something like SQL1.IsEmpty , etc.
+    if NoRecordsToShow then
+    begin  //if there's nothing to list, just replace the whole tag with the 
+           //"Not Found" message that the template contains
+      ReplaceText := TagParams.Values['NOTFOUND'];
+      Exit;
+    end;
+
+    header := TagParams.Values['HEADER'];
+    //insert header parameters
+    header := StringReplace(header, '~Column1', ColumnHeaders[1], []);
+    header := StringReplace(header, '~Column2', ColumnHeaders[2], []);
+
+    ReplaceText := header;//done with the header (could have been looping 
+			  //through table field names also)
+    //insert the rows
+    onerow := TagParams.Values['ONEROW'];//template for 1 row
+    //loop through the rows, it could be someting like "while not SQL1.EOF do"
+    for I := 1 to 3 do
+    begin
+      ReplaceText := ReplaceText + StringReplace(StringReplace(onerow
+                       ,'~Column1Value', '$' + ColumnValues[I, 1], [])
+                       ,'~Column2value', ColumnValues[I, 2] + '%', []) + #13#10;
+    end;
+
+    //insert the footer
+    footer := TagParams.Values['FOOTER'];
+    //replace footer parameters if needed
+    //...
+
+    ReplaceText := ReplaceText + footer;
+  end else begin
+
+//Not found value for tag -> TagString
+    ReplaceText := 'Template tag {+' + TagString + '+} is not implemented yet.';
+  end;
+end;
+
+initialization
+  RegisterHTTPModule('TFPWebModule1', TFPWebModule1); 
+end.

+ 145 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/README.txt

@@ -0,0 +1,145 @@
+Sessions stored in cookies, Autosession example
+==========================
+
+Every visitor automatically gets a session ID (no login required) passed in a 
+cookie to the web visitor's browser and stored on the web server until it 
+expires.
+This way, for example the previously entered data can be carried forward to 
+the following pages.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule autosession.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template (autosession-template.html) 
+file. It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: ModuleTemplate.FileName := '/full/path/to/autosession-template.html';
+
+The fpweb generated cookie session files usually need to be deleted after 
+expiration manually or by a periodic cleaning program, because they are piling 
+up in the default temporary directory if the session is not terminated with a 
+Session.Terminate; somewhere within the web module after the sessions is no 
+longer used (ex: after the last submit of a multi-page data entry form, etc.).
+
+
+2.a; as CGI
+-----------
+Usually it works if you put the template (autosession-template.html) next to 
+the CGI executable file in the Apache cgi-bin directory. Adjust the file path 
+in the web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/gotonextpage should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/autosession/gotonextpage
+if in the Apache configuration file (ex: httpd.conf) it was set up as 
+ScriptAlias /autosession "<path_to_app>/<app_name>"
+ex:
+ScriptAlias /autosession "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/autosession.exe"
+
+Note: You need to change the URLs if "cgi-bin" or "autosession.exe" changes 
+(for example on Linux it is not autosession.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the template (autosession-template.html) into the 
+Apache main directory (not the DocumentRoot, but the main Apache directory), 
+under sub-directory "templates" or something similar. Adjust the file path in 
+the web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/gotonextpage should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/autosession/gotonextpage
+if in httpd.conf it was set up as:
+LoadModule mod_autosession "<path_to_mod>/autosession.dll"
+<Location /autosession>
+    SetHandler mod_autosession
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "/autosession" 
+changes. Also, for example on Linux the module can be libautosession.so and 
+not autosession.dll 
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the template (autosession-template.html) next to 
+the FCGI executable file. Adjust the file path in the web module 
+(webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/gotonextpage should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/autosession/gotonextpage
+or  http://127.0.0.1/autosession/gotonextpage
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+    Order allow,deny
+    Allow from all
+  </Directory>
+  FastCgiExternalServer "<path_to_fcgi_app>/autosession.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+  ScriptAlias /autosession "<path_to_fcgi_app>/autosession.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (autosession.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="autosession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="autosession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 37 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.lpr

@@ -0,0 +1,37 @@
+Library autosession;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_autosession';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/apache/autosession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="autosession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="autosession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.lpr

@@ -0,0 +1,14 @@
+program autosession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/cgi/autosession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="autosession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="autosession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.lpr

@@ -0,0 +1,14 @@
+program autosession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/fcgi/autosession.res


+ 25 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/templates/autosession-template.html

@@ -0,0 +1,25 @@
+<html>
+<body>
+You can test automatic session handling by opening multiple browsers 
+(not multiple tabs or multiple windows of the same browser! Ex: Firefox and 
+Internet Explorer), or by using two separate computers.<br>
+By submitting data from the different browsers you can see the session information.<br>
+Note: Cookies must be enabled for this website for it to work.
+
+<br><br>Last submit: <b>{+DATETIME [-FORMAT=MM/DD/YYYY hh:mm:ss.zzz-]+}</b><br><br>
+
+<form action="/autosession/gotonextpage" method="Post">
+ <input type="submit" class="button" value="Submit">
+</form>
+
+{+EXPIREDMESSAGE [-MESSAGE=Your session has expired.-]+}<br>
+{+NEWSESSIONMESSAGE [-MESSAGE=A new session started.-]+}<br>
+
+<br>Your session ID is: <b>{+SESSIONID+}</b><br>
+
+Expires in <b>{+TIMEOUTMINUTES+}</b> minutes unless it is updated.<br>
+
+The file "<b>{+SESSIONFILE+}</b>" stores this session information on the web server.<br>
+
+</body>
+</html>

+ 19 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.lfm

@@ -0,0 +1,19 @@
+object FPWebModule1: TFPWebModule1
+  OnCreate = DataModuleCreate
+  OldCreateOrder = False
+  Actions = <  
+    item
+      Name = 'gotonextpage'
+      Default = True
+      OnRequest = gotonextpageRequest
+      Template.AllowTagParams = False
+    end>
+  AfterResponse = DataModuleAfterResponse
+  CreateSession = False
+  OnNewSession = DataModuleNewSession
+  OnSessionExpired = DataModuleSessionExpired
+  Height = 300
+  HorizontalOffset = 290
+  VerticalOffset = 149
+  Width = 400
+end

+ 148 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-auto/webmodule/webmodule.pas

@@ -0,0 +1,148 @@
+unit webmodule; 
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  Classes, Sysutils, HTTPDefs, fpHTTP, fpWeb, iniwebsession;
+
+type
+
+  { TFPWebModule1 }
+
+  TFPWebModule1 = class(TFPWebModule)
+    procedure DataModuleCreate(Sender: TObject);
+    procedure DataModuleNewSession(Sender: TObject);
+    procedure DataModuleSessionExpired(Sender: TObject);
+    procedure gotonextpageRequest(Sender: TObject; ARequest: TRequest;
+      AResponse: TResponse; var Handled: Boolean);
+    procedure DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
+  private
+    { private declarations }
+    NewSessionCreated : Boolean;
+    ASessionExpired : Boolean;
+    MySessionDir : String;
+//    procedure GetSessionEvent(Var ASession : TCustomSession);
+    procedure AutoSessionTemplateReplaceTag(Sender: TObject; const TagString:String;
+      TagParams: TStringList; Out ReplaceText: String);
+  public
+    { public declarations }
+  end; 
+
+var
+  FPWebModule1: TFPWebModule1; 
+
+implementation
+
+{$R *.lfm}
+
+{ TFPWebModule1 }
+
+procedure TFPWebModule1.DataModuleCreate(Sender: TObject);
+begin
+  NewSessionCreated := false;
+  ASessionExpired := false;
+  ModuleTemplate.AllowTagParams := true;
+  ModuleTemplate.StartDelimiter := '{+';//The default is { and } which is usually not good if we use Javascript in our templates
+  ModuleTemplate.EndDelimiter := '+}';
+
+  CreateSession := true;                //Turn on automatic session handling for this web module
+  MySessionDir := '';//'/Path/To/A/Directory/';{Use this if you don't want the automatic Temp dir to store the sessionID files under "fpwebsessions" sub-directory}
+  with (SessionFactory as TIniSessionFactory) do
+  begin
+    DefaultTimeoutMinutes := 2;         //Session timeout in minutes
+    SessionDir := MySessionDir;
+//    SessionCookie:='ACustomCookieName'; {Use this to set the cookie name that will be used for the session management. Default is 'FPWebSession'}
+  end;
+end;
+
+procedure TFPWebModule1.DataModuleNewSession(Sender: TObject);
+begin {Sender as TIniWebSession}
+  NewSessionCreated := true;
+end;
+
+procedure TFPWebModule1.DataModuleSessionExpired(Sender: TObject);
+begin {Sender as TIniWebSession}
+  ASessionExpired := true;
+end;
+
+procedure TFPWebModule1.gotonextpageRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+begin     //ModuleTemplate:TFPTemplate is a property of the web module
+  ModuleTemplate.FileName := 'autosession-template.html';
+  ModuleTemplate.OnReplaceTag := @AutoSessionTemplateReplaceTag;
+
+  AResponse.Content := ModuleTemplate.GetContent;
+
+  Handled := true;
+end;
+
+procedure TFPWebModule1.AutoSessionTemplateReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+begin
+  if AnsiCompareText(TagString, 'DATETIME') = 0 then
+  begin
+    ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
+  end else
+
+  if AnsiCompareText(TagString, 'SESSIONID') = 0 then
+  begin
+    if Assigned(Session) then
+      ReplaceText := Session.SessionID;
+  end else
+
+  if AnsiCompareText(TagString, 'TIMEOUTMINUTES') = 0 then
+  begin
+    if Assigned(Session) then
+      ReplaceText := IntToStr(Session.TimeOutMinutes);
+  end else
+
+  if AnsiCompareText(TagString, 'SESSIONFILE') = 0 then
+  begin
+    if Assigned(Session) then
+      if MySessionDir = '' then
+        ReplaceText := IncludeTrailingPathDelimiter(GetTempDir(True)) + IncludeTrailingPathDelimiter('fpwebsessions') + Session.SessionID
+      else
+        ReplaceText := IncludeTrailingPathDelimiter(MySessionDir) + Session.SessionID;
+{NOTE: GetTempDir
+used by the session manager returns the OS temporary directory if possible, or from the
+environment variable TEMP . For CGI programs you need to pass global environment
+variables, it is not automatic. For example in the Apache httpd.conf with a
+"PassEnv TEMP" or "SetEnv TEMP /pathtotmpdir" line so the web server passes this
+global environment variable to the CGI programs' local environment variables.
+}
+  end else
+
+  if AnsiCompareText(TagString, 'EXPIREDMESSAGE') = 0 then
+  begin
+    if Assigned(Session) and ASessionExpired then
+      ReplaceText := TagParams.Values['MESSAGE'];
+  end else
+
+    if AnsiCompareText(TagString, 'NEWSESSIONMESSAGE') = 0 then
+  begin
+    if Assigned(Session) and NewSessionCreated then
+      ReplaceText := TagParams.Values['MESSAGE'];
+  end else
+
+
+  begin
+    //Not found value for tag -> TagString
+    ReplaceText := '[Template tag {+' + TagString + '+} is not implemented yet.]';
+  end;
+end;
+
+procedure TFPWebModule1.DataModuleAfterResponse(Sender: TObject;
+  AResponse: TResponse);
+begin
+  //reset global variables for apache modules and FCGI applications for the next incoming request
+  NewSessionCreated := false;
+  ASessionExpired := false;
+  ModuleTemplate.FileName := '';
+  //
+end;
+
+initialization
+  RegisterHTTPModule('TFPWebModule1', TFPWebModule1); 
+end.

+ 164 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/README.txt

@@ -0,0 +1,164 @@
+Sessions stored in cookies with Login, example
+======================================
+
+Note: Cookies must be enabled for the website in the visitor's browser for it 
+to work.
+
+Every visitor needs to log in (using userdb.txt for the user names and 
+passwords in the example) to get a session ID that is passed in a cookie to 
+the web visitor's browser and stored on the web server until it expires.
+This way fully functional web sites can be built without mixing the different 
+visitor's screens.
+
+Note: This example can not distinguish between sessions on the same computer, same 
+browser but different tabs. If for example someone opens three tabs and logs in 
+with all of them, all three browser tabs will be the same session.
+In order to handle sessions differently by browser tabs the best way to go is 
+to store session IDs in the URLs, Links, etc. for all pages the web application
+ generates (this way cookies are not needed to maintain the session).
+The sample user logins are stored in userdb.txt .
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule cookiesession.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template (test*.html) files.
+It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: ModuleTemplate.FileName := '/full/path/to/templates/testlogin.html';
+and so on for all the other templates.
+
+The web server application needs read/write access to the file where the session
+ information will be stored with the login names (sessiondb.txt by default).
+ex: sessiondbfile := '/full/path/to/sessiondb.txt';
+The sessiondb.txt can be created empty, and needs read/write access.
+
+It also needs read access to the user database (userdb.txt)
+ex: userdbfile := '/full/path/to/userdb.txt';
+
+The fpweb generated cookie session files usually need to be deleted after 
+expiration manually or by a periodic cleaning program, because they are piling 
+up in the default temporary directory if the sessions are not terminated (ie. 
+if people are not logging out).
+
+
+2.a; as CGI
+-----------
+Usually it works if you put the templates (test*.html) next to the CGI 
+executable file in the Apache cgi-bin directory. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/login should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/cookiesession/login
+if in the Apache configuration file (ex: httpd.conf) it was set up as 
+ScriptAlias /cookiesession "<path_to_app>/<app_name>"
+ex:
+ScriptAlias /cookiesession "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/cookiesession.exe"
+
+Note: You need to change the URLs if "cgi-bin" or "cookiesession.exe" changes 
+(for example on Linux it is not cookiesession.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the templates (test*.html) into the Apache 
+main directory (not the DocumentRoot, but the main Apache directory), under 
+sub-directory "templates" or something similar. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/login should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/cookiesession/login
+if in httpd.conf it was set up as:
+LoadModule mod_cookiesession "<path_to_mod>/cookiesession.dll"
+<Location /cookiesession>
+    SetHandler mod_cookiesession
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "/cookiesession" changes. 
+Also, for example on Linux the module can be libcookiesession.so and not 
+cookiesession.dll 
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the templates (test*.html) next to the FCGI 
+executable file. Adjust the file path in the web module (webmodule.pas) 
+accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/gotonextpage should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/cookiesession/login
+or  http://127.0.0.1/cookiesession/login
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+    Order allow,deny
+    Allow from all
+  </Directory>
+  FastCgiExternalServer "<path_to_fcgi_app>/cookiesession.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+  ScriptAlias /cookiesession "<path_to_fcgi_app>/cookiesession.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (cookiesession.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="cookiesession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="cookiesession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 37 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.lpr

@@ -0,0 +1,37 @@
+Library cookiesession;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_cookiesession';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/apache/cookiesession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="cookiesession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="cookiesession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.lpr

@@ -0,0 +1,14 @@
+program cookiesession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.
+

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/cgi/cookiesession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="cookiesession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="cookiesession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.lpr

@@ -0,0 +1,14 @@
+program cookiesession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/fcgi/cookiesession.res


+ 22 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogin.html

@@ -0,0 +1,22 @@
+<html>
+<body>
+
+ {+MESSAGE
+   [-NORMAL  =Welcome to the cookiesession test login screen-]
+   [-MISSING =<font color="red"><small>Please enter both a login name and a password.</small></font>-]
+   [-INVLOGIN=<font color="red"><small>Invalid login name or password. Please try again.</small></font>-]
+   [-SESSIONEXPIRED=<font color="orange"><small>Your session has expired. Please log in again</small></font>-]
+ +}
+ <br>
+ <form action="/cookiesession/login" method="Post">
+
+  Login Name:<input type="text" name="LoginName" value="{+LOGINNAME+}"> 
+
+  Password:<input type="password" name="Password"> 
+ 
+  <input type="submit" class="button" value="Login">
+
+ </form>
+
+</body>
+</html>

+ 10 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testlogout.html

@@ -0,0 +1,10 @@
+<html>
+<body>
+Logout screen<br><br>
+
+You have successfully logged out <b>{+LOGINNAME+}</b> .<br><br>
+
+You can log in again <a href="/cookiesession/login">here</a><br><br>
+
+</body>
+</html>

+ 15 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testsomepage.html

@@ -0,0 +1,15 @@
+<html>
+<body>
+Somepage screen
+<br><br>Entered this screen at <b>{+DATETIME [-FORMAT=MM/DD/YYYY hh:mm:ss.zzz-]+}</b><br><br>
+
+<b>{+LOGINNAME+}</b>, you can log out <a href="/cookiesession/logout">here</a><br><br>
+
+Your session will expire in <b>{+MINUTESLEFT+}</b> minutes unless it is refreshed by<br> 
+clicking <a href="/cookiesession/someaction">here</a> before then<br><br>
+
+Your session ID is: <b>{+SESSIONID+}</b><br>
+
+The file "<b>{+SESSIONFILE+}</b>" stores this session information on the web server.<br>
+</body>
+</html>

+ 17 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/testwelcome.html

@@ -0,0 +1,17 @@
+<html>
+<body>
+Welcome screen
+<br><br>Entered this screen at <b>{+DATETIME [-FORMAT=MM/DD/YYYY hh:mm:ss.zzz-]+}</b><br><br>
+
+You have successfully logged in <b>{+LOGINNAME+}</b> .<br><br>
+
+You can log out <a href="/cookiesession/logout">here</a><br><br>
+
+Your session will expire in <b>{+MINUTESLEFT+}</b> minutes unless it is refreshed by<br> 
+clicking <a href="/cookiesession/someaction">here</a> before then<br><br>
+
+Your session ID is: <b>{+SESSIONID+}</b><br>
+
+The file "<b>{+SESSIONFILE+}</b>" stores this session information on the web server.<br>
+</body>
+</html>

+ 2 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/templates/userdb.txt

@@ -0,0 +1,2 @@
+joe=joepassword
+jane=janepassword

+ 29 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.lfm

@@ -0,0 +1,29 @@
+object FPWebModule1: TFPWebModule1
+  OnCreate = DataModuleCreate
+  OldCreateOrder = False
+  Actions = <  
+    item
+      Name = 'login'
+      Default = True
+      OnRequest = loginRequest
+      Template.AllowTagParams = False
+    end  
+    item
+      Name = 'logout'
+      Default = False
+      OnRequest = logoutRequest
+      Template.AllowTagParams = False
+    end  
+    item
+      Name = 'someaction'
+      Default = False
+      OnRequest = someactionRequest
+      Template.AllowTagParams = False
+    end>
+  AfterResponse = DataModuleAfterResponse
+  CreateSession = True
+  Height = 202
+  HorizontalOffset = 207
+  VerticalOffset = 166
+  Width = 173
+end

+ 381 - 0
packages/fcl-web/examples/fptemplate/sessions/cookiesessions-login/webmodule/webmodule.pas

@@ -0,0 +1,381 @@
+unit webmodule;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, httpdefs, fpHTTP, fpWeb, iniwebsession;
+
+type
+
+  { TFPWebModule1 }
+
+  TFPWebModule1 = class(TFPWebModule)
+    procedure DataModuleAfterResponse(Sender: TObject; AResponse: TResponse);
+    procedure DataModuleCreate(Sender: TObject);
+    //web action handlers
+    procedure loginRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
+    procedure logoutRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
+    procedure someactionRequest(Sender: TObject; ARequest: TRequest; AResponse: TResponse; var Handled: Boolean);
+  private
+    { private declarations }
+    MySessionDir : String;
+    LoggedInLoginName : String;
+    SessionDBFile : String;
+    UserDBFile : String;
+    function NotLoggedIn:Boolean;
+    function CommonTemplateTagReplaces(const TagString:String; TagParams: TStringList; out ReplaceText: String):Boolean;
+    //template tag handlers
+    procedure loginReplaceTag(Sender: TObject; const TagString: String; TagParams: TStringList; Out ReplaceText: String);
+    procedure welcomeReplaceTag(Sender: TObject; const TagString:String; TagParams: TStringList; Out ReplaceText: String);
+    procedure logoutReplaceTag(Sender: TObject; const TagString:String; TagParams: TStringList; Out ReplaceText: String);
+    procedure someactionReplaceTag(Sender: TObject; const TagString:String; TagParams: TStringList; Out ReplaceText: String);
+  public
+    { public declarations }
+  end; 
+
+var
+  FPWebModule1: TFPWebModule1; 
+
+implementation
+
+{$R *.lfm}
+
+{ TFPWebModule1 }
+
+function FindNameInList(const SL:TStrings; const N:String):String;
+var
+    i : Integer;
+begin
+  Result := '';
+  for i := 0 to SL.Count - 1 do
+    if SL.Names[i] = N then
+    begin
+      Result := SL.Values[SL.Names[i]];//return with the sessionID
+      break;
+    end;
+end;
+
+procedure RemoveValueIfExists(SL:TStrings; const S_ID:String);
+var
+  s : String;
+  i : Integer;
+begin
+  if SL.Count <= 0 then Exit;
+  s := '=' + S_ID;
+  i := 0;
+  repeat
+    if pos(s, SL[i]) > 0 then
+      SL.Delete(i)
+    else
+      inc(i);
+  until i >= SL.Count;
+end;
+
+function FindValueInList(const SL:TStrings; const Sess:String):String;
+var
+  s : String;
+  i : Integer;
+begin
+  Result := '';
+  if SL.Count <= 0 then Exit;
+  s := '=' + Sess;
+  i := 0;
+  repeat
+    if pos(s, SL[i]) > 0 then
+    begin
+      Result := SL.Names[i];
+      break;
+    end;
+    inc(i);
+  until i >= SL.Count;
+end;
+
+procedure RemoveNameIfExists(SL:TStrings; const N:String);
+var
+  i: Integer;
+begin
+  if SL.Count <= 0 then Exit;
+  i := 0;
+  repeat
+    if SL.Names[i] = N then
+      SL.Delete(i)
+    else
+      inc(i);
+  until i >= SL.Count;
+end;
+
+procedure TFPWebModule1.DataModuleAfterResponse(Sender: TObject;
+  AResponse: TResponse);
+begin
+  //reset global variables for apache modules and fcgi applications for the next incoming request
+  LoggedInLoginName := '';
+  //
+end;
+
+procedure TFPWebModule1.DataModuleCreate(Sender: TObject);
+begin
+  ModuleTemplate.AllowTagParams := true;
+  ModuleTemplate.StartDelimiter := '{+';   //The default is { and } which is usually not good if we use Javascript in our templates
+  ModuleTemplate.EndDelimiter := '+}';
+
+  CreateSession := true;                   //Turn on automatic session handling for this web module
+  MySessionDir := '';//'/Path/To/A/Directory/';{Use this if you don't want the automatic Temp dir to store the sessionID files under "fpwebsessions" sub-directory}
+  with (SessionFactory as TIniSessionFactory) do
+  begin
+    DefaultTimeoutMinutes := 2;            //Session timeout in minutes
+    SessionDir := MySessionDir;
+//    SessionCookie:='ACustomCookieName'; {Use this to set the cookie name that will be used for the session management. Default is 'FPWebSession'}
+  end;
+
+  sessiondbfile := 'sessiondb.txt';        //This will contain the name=sessionID pairs to simulate the session database
+  userdbfile := 'userdb.txt';              //This simulates a user database with passwords
+end;
+
+procedure TFPWebModule1.loginRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+var
+  loginname, pwd, pwd1 : String;
+  userdatabase, sessiondatabase : TStringlist;
+begin
+  Handled := true;
+  ModuleTemplate.FileName := 'testlogin.html';
+  ModuleTemplate.OnReplaceTag := @loginReplaceTag;
+  AResponse.CustomHeaders.Add('Pragma=no-cache');//do not cache the response in the web browser so the Back key can not be used to see the pages without reloads.
+
+  if FindNameInList(ARequest.ContentFields, 'LoginName') = '' then
+  begin//called the login action without parameters -> display the login page
+    ARequest.QueryFields.Add('MSG=NORMAL');
+    AResponse.Content := ModuleTemplate.GetContent;
+    Exit;
+  end;
+
+  loginname := Trim(ARequest.ContentFields.Values['LoginName']);
+  pwd := Trim(ARequest.ContentFields.Values['Password']);
+  if (pwd = '') or (loginname = '') then
+  begin//empty login name or password -> return to the login screen
+    ARequest.QueryFields.Add('MSG=MISSING');
+    AResponse.Content := ModuleTemplate.GetContent;
+    Exit;
+  end;
+
+  //simulate a user database loaded into a stringlist
+  userdatabase := TStringlist.Create;
+  userdatabase.LoadFromFile(userdbfile);
+  pwd1 := userdatabase.Values[LoginName];//get the correct password for the LoginName if it is there
+  userdatabase.free;
+  //
+
+  if pwd <> pwd1 then
+  begin//either the password or the login name was invalid
+    ARequest.QueryFields.Add('MSG=INVLOGIN');
+    AResponse.Content := ModuleTemplate.GetContent;
+    Exit;
+  end;
+
+  //successful login
+  LoggedInLoginName := loginname;
+
+  //session starting, need to store it somewhere next to the name of the logged in person
+  sessiondatabase := TStringList.Create;
+  if FileExists(sessiondbfile) then
+    sessiondatabase.LoadFromFile(sessiondbfile);              //simulating the session database access
+  if sessiondatabase.Count > 0 then
+    RemoveValueIfExists(sessiondatabase, Session.SessionID);  //New login, kill all sessions with this session ID (same computer, same browser, multiple persons)
+  if FindNameInList(sessiondatabase, LoginName) <> '' then
+    sessiondatabase.Values[LoginName] := Session.SessionID    //overwrite with the new session ID
+  else
+    sessiondatabase.Add(LoginName + '=' + Session.SessionID); //create a new entry for this person
+  sessiondatabase.SaveToFile(sessiondbfile);                  //simulating the session database update
+  sessiondatabase.Free;
+
+  //generate the Welcome page content
+  ModuleTemplate.FileName := 'testwelcome.html';
+  ModuleTemplate.OnReplaceTag := @welcomeReplaceTag;
+  AResponse.Content := ModuleTemplate.GetContent;
+end;
+
+procedure TFPWebModule1.loginReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+begin
+  {Handle tags used in multiple templates}
+  if CommonTemplateTagReplaces(TagString, TagParams, ReplaceText) then
+    Exit;
+
+  {Handle tags specific to this template if there are any}
+  if AnsiCompareText(TagString, 'MESSAGE') = 0 then
+  begin
+    ReplaceText := TagParams.Values[Request.QueryFields.Values['MSG']];
+  end else
+
+  {Message for tags not handled}
+  begin
+    ReplaceText := '[Template tag "' + TagString + '" is not implemented yet.]';
+  end;
+end;
+
+procedure TFPWebModule1.welcomeReplaceTag(Sender: TObject; const TagString:String;
+      TagParams: TStringList; Out ReplaceText: String);
+begin
+  {Handle tags used in multiple templates}
+  if CommonTemplateTagReplaces(TagString, TagParams, ReplaceText) then
+    Exit;
+
+  {Handle tags specific to this template if there are any}
+
+  {Message for tags not handled}
+  begin
+    ReplaceText := '[Template tag "' + TagString + '" is not implemented yet.]';
+  end;
+end;
+
+function TFPWebModule1.CommonTemplateTagReplaces(const TagString:String;
+  TagParams: TStringList; out ReplaceText: String):Boolean;
+begin
+  Result := true;
+
+  if AnsiCompareText(TagString, 'DATETIME') = 0 then
+  begin
+    ReplaceText := FormatDateTime(TagParams.Values['FORMAT'], Now);
+  end else
+
+  if AnsiCompareText(TagString, 'SESSIONID') = 0 then
+  begin
+    if Assigned(Session) then
+      ReplaceText := Session.SessionID;
+  end else
+
+  if AnsiCompareText(TagString, 'MINUTESLEFT') = 0 then
+  begin
+    if Assigned(Session) then
+      ReplaceText := IntToStr(Session.TimeOutMinutes);
+  end else
+
+  if AnsiCompareText(TagString, 'SESSIONFILE') = 0 then
+  begin
+    if Assigned(Session) then
+      if MySessionDir = '' then
+        ReplaceText := IncludeTrailingPathDelimiter(GetTempDir(True)) + IncludeTrailingPathDelimiter('fpwebsessions') + Session.SessionID
+      else
+        ReplaceText := IncludeTrailingPathDelimiter(MySessionDir) + Session.SessionID;
+{NOTE: GetTempDir
+used by the session manager. Returns the OS temporary directory if possible, or from the
+environment variable TEMP . For CGI programs you need to pass global environment
+variables, it is not automatic. For example in the Apache httpd.conf with a
+"PassEnv TEMP" or "SetEnv TEMP /pathtotmpdir" line so the web server passes this
+global environment variable to the CGI programs' local environment variables.
+}
+  end else
+
+  if AnsiCompareText(TagString, 'LOGINNAME') = 0 then
+  begin
+      ReplaceText := LoggedInLoginName;
+  end else
+
+  Result := false;
+end;
+
+function TFPWebModule1.NotLoggedIn:Boolean;
+var
+  sessiondatabase : TStringlist;
+begin
+  Result := false;
+
+  //check if the current sessionID is in the sessionDB
+  sessiondatabase := TStringList.Create;
+  if FileExists(sessiondbfile) then
+    sessiondatabase.LoadFromFile(sessiondbfile);
+  LoggedInLoginName := FindValueInList(sessiondatabase, Session.sessionID);
+  sessiondatabase.Free;
+  //
+
+  if LoggedInLoginName = '' then
+  begin
+    Result := true;   //not found -> not logged in or previous session has expired
+
+    //show the login screen again with the expired session message
+    ModuleTemplate.FileName := 'testlogin.html';
+    ModuleTemplate.OnReplaceTag := @loginReplaceTag;
+    Request.QueryFields.Add('MSG=SESSIONEXPIRED');
+    Response.Content := ModuleTemplate.GetContent;
+  end;
+end;
+
+procedure TFPWebModule1.logoutRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+var
+  sessiondatabase : TStringList;
+begin
+  Handled := true;
+
+  if NotLoggedIn then Exit;
+
+  //delete the sessionID and all occurences of the login name assigned to it from the sessiondb
+  sessiondatabase := TStringList.Create;
+  if FileExists(sessiondbfile) then
+    sessiondatabase.LoadFromFile(sessiondbfile);
+  if sessiondatabase.Count > 0 then
+  begin
+    RemoveValueIfExists(sessiondatabase, Session.SessionID);
+    RemoveNameIfExists(sessiondatabase, LoggedInLoginName);
+    sessiondatabase.SaveToFile(sessiondbfile);
+  end;
+  sessiondatabase.Free;
+  //
+
+  //terminate the session
+  Session.Terminate;
+
+  //Generate the response page
+  ModuleTemplate.FileName := 'testlogout.html';
+  ModuleTemplate.OnReplaceTag := @logoutReplaceTag;
+  AResponse.Content := ModuleTemplate.GetContent;//generate the Logout page content.
+end;
+
+procedure TFPWebModule1.logoutReplaceTag(Sender: TObject; const TagString:String;
+  TagParams: TStringList; Out ReplaceText: String);
+begin
+  {Handle tags used in multiple templates}
+  if CommonTemplateTagReplaces(TagString, TagParams, ReplaceText) then
+    Exit;
+
+  {Handle tags specific to this template if there are any}
+
+  {Message for tags not handled}
+  begin
+    ReplaceText := '[Template tag "' + TagString + '" is not implemented yet.]';
+  end;
+end;
+
+procedure TFPWebModule1.someactionRequest(Sender: TObject; ARequest: TRequest;
+  AResponse: TResponse; var Handled: Boolean);
+begin
+  Handled := true;
+
+  if NotLoggedIn then Exit;
+
+  ModuleTemplate.FileName := 'testsomepage.html';
+  ModuleTemplate.OnReplaceTag := @someactionReplaceTag;
+  AResponse.Content := ModuleTemplate.GetContent;//generate the testpage content
+end;
+
+procedure TFPWebModule1.someactionReplaceTag(Sender: TObject; const TagString:
+  String; TagParams: TStringList; Out ReplaceText: String);
+begin
+  {Handle tags used in multiple templates}
+  if CommonTemplateTagReplaces(TagString, TagParams, ReplaceText) then
+    Exit;
+
+  {Handle tags specific to this template if there are any}
+
+  {Message for tags not handled}
+  begin
+    ReplaceText := '[Template tag {+' + TagString + '+} is not implemented yet.]';
+  end;
+end;
+
+initialization
+  RegisterHTTPModule('TFPWebModule1', TFPWebModule1); 
+end.
+

+ 153 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/README.txt

@@ -0,0 +1,153 @@
+Sessions stored in the URLs with Login (no cookies needed), example
+==========================================================
+
+Every visitor needs to log in (using userdb.txt for the user names and 
+passwords in the example) to get a session ID that is always passed in the 
+URLs of the response pages as a query parameter and stored on the web server 
+until it expires.
+This way fully functional web sites can be built without mixing the different 
+visitor's screens and without using cookies to keep the session separated.
+
+Note: Because the session ID is stored dynamically in the generated pages, all
+web browser tabs will have separate sessions after logging in with them.
+The sample user logins are stored in userdb.txt for the example.
+
+=====================
+1. Compiling
+1.a; with FPC
+1.b; with Lazarus
+2. Setup
+2.a; as CGI
+2.b; as Apache module
+2.c; as FCGI
+=====================
+
+1. Compiling:
+-------------
+We can either use FPC directly, or Lazarus to compile the CGI/FCGI/Apache 
+module application. The main project .lpr file, as well as the Lazarus .lpi is 
+in the cgi/fcgi/apache directories.
+
+1.a; with FPC
+-------------
+Enter to the directory (cgi/fcgi/apache) that has the .lpr file you wish to 
+compile, and then execute the command 
+
+fpc -Fu../webmodule urlsession.lpr
+
+The -Fu parameter shows FPC where to find the web module source code. All 
+three web applications share the same web module code.
+
+1.b; with Lazarus
+-----------------
+It needs the WebLaz Package installed. Open the .lpi file from the chosen 
+application directory (cgi/fcgi/apache), and then 
+
+Run -> Build from the menu.
+
+
+2. Setup:
+---------
+The application needs read access to the template (testurl*.html) files.
+It is best to use full paths with the file names in the web module 
+(webmodule.pas), because Apache will probably look relative to the / (main 
+root) directory or main Apache directory and not relative to the application 
+file location.
+ex: ModuleTemplate.FileName := '/full/path/to/templates/testurllogin.html'; 
+and so on for all the other templates.
+
+It needs read/write access to the file where the session informations will be 
+stored with the login names (session-db.txt).
+ex: sessiondbfile := '/full/path/to/session-db.txt';
+The session-db.txt can be created empty, and needs read/write access.
+
+It also needs read access to the user database (userdb.txt)
+ex: userdbfile := '/full/path/to/userdb.txt';
+
+
+2.a; as CGI
+-----------
+Usually it works if you put the templates (testurl*.html) next to the CGI 
+executable file in the Apache cgi-bin directory. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/login should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/urlsession/login
+if in the Apache configuration file (ex: httpd.conf) it was set up as 
+ScriptAlias /urlsession "<path_to_app>/<app_name>"
+ex:
+ScriptAlias /urlsession "C:/Program Files/Apache Software Foundation/Apache2.2/cgi-bin/urlsession.exe"
+
+Note: You need to change the URLs if "cgi-bin" or "urlsession.exe" changes 
+(for example on Linux it is not urlsession.exe).
+Also, if your server is listening on port 80 instead of 8080, you can leave 
+the :8080 part from the calling URL.
+
+
+2.b; as Apache module
+---------------------
+Usually it works if you put the templates (testurl*.html) into the Apache 
+main directory (not the DocumentRoot, but the main Apache directory), under 
+sub-directory "templates" or something similar. Adjust the file path in the 
+web module (webmodule.pas) accordingly.
+
+http://<WebServer>/<ApacheLocationName>/login should start the 
+example if everything is set up properly.
+ex: http://127.0.0.1:8080/urlsession/login
+if in httpd.conf it was set up as:
+LoadModule mod_urlsession "<path_to_mod>/urlsession.dll"
+<Location /urlsession>
+    SetHandler mod_urlsession
+    Order allow,deny
+    Allow from all
+</Location>
+
+Note: You need to change the URLs in the templates if "urlsession" changes. 
+Also, for example on Linux the module can be liburlsession.so and not 
+urlsession.dll 
+
+Note: If you recompile an apache module while the module itself is loaded into
+the Apache server, the compilation might fail because the file is in use 
+(Apache modules stay in the memory). So first, you always need to stop the 
+server before you recompile or before you copy over the new version of the 
+newly created module.
+On Linux, it is enough to simply reload Apache after recompile.
+
+
+2.c; as FCGI
+------------
+Usually it works if you put the templates (testurl*.html) next to the FCGI 
+executable file. Adjust the file path in the web module (webmodule.pas) 
+accordingly.
+
+http://<WebServer>/<ApacheScriptAliasName>/login should start the example 
+if everything is set up properly.
+ex: http://127.0.0.1:8080/urlsession/login
+or  http://127.0.0.1/urlsession/login
+if in the Apache configuration file (ex: httpd.conf) it was set up as:
+
+LoadModule fastcgi_module "<path_to_mod>/mod_fastcgi-2.4.6-AP22.dll"
+<IfModule mod_fastcgi.c>
+  <Directory "<path_to_fcgi_app>">
+    Order allow,deny
+    Allow from all
+  </Directory>
+  FastCgiExternalServer "<path_to_fcgi_app>/urlsession.exe" -host 127.0.0.1:2015 -idle-timeout 30 -flush
+  ScriptAlias /urlsession "<path_to_fcgi_app>/urlsession.exe"
+</IfModule>
+
+Note: You need to change the module name if needed. For example on Linux, 
+the module is not mod_fastcgi-2.4.6-AP22.dll but mod_fastcgi.so (need to be 
+compiled from sources found at http://www.fastcgi.com/dist/ ).
+The port (2015 in this example) must match the one set in the project main 
+file (urlsession.lpr).
+The FCGI application must be running in order for this demo to work (external 
+FCGI server setup). Do not forget to restart it after changes and 
+recompilation.
+Also, mod_fastcgi is not the same as mod_fcgid that the Apache project is 
+developing. The latter does not support external FCGI server apps.
+There are other ways than external FCGI server apps to handle the FCGI 
+protocol and both mod_fastcgi and mod_fcgid supports that. However, external 
+FCGI servers are the best for debugging and development, that is why the 
+examples do it that way.

+ 88 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpi

@@ -0,0 +1,88 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="urlsession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="urlsession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Linking>
+      <Options>
+        <ExecutableType Value="Library"/>
+      </Options>
+    </Linking>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 36 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.lpr

@@ -0,0 +1,36 @@
+Library urlsession;
+
+{$mode objfpc}{$H+}
+
+Uses
+{$ifdef unix}
+  cthreads,
+{$endif}
+  httpd,fpApache, webmodule;
+
+Const
+
+{ The following constant is used to export the module record. It must 
+  always match the name in the LoadModule statement in the apache
+  configuration file(s). It is case sensitive !}
+  ModuleName='mod_urlsession';
+
+{ The following constant is used to determine whether the module will
+  handle a request. It should match the name in the SetHandler statement
+  in the apache configuration file(s). It is not case sensitive. }
+
+  HandlerName=ModuleName;
+
+Var
+  DefaultModule : module; {$ifdef unix} public name ModuleName;{$endif unix}
+
+Exports defaultmodule name ModuleName;
+
+{$R *.res}
+
+begin
+  Application.ModuleName:=ModuleName;
+  Application.HandlerName:=HandlerName;
+  Application.SetModuleRecord(DefaultModule);
+  Application.Initialize;
+end.

BIN
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/apache/urlsession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="urlsession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="urlsession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 13 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.lpr

@@ -0,0 +1,13 @@
+program urlsession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/cgi/urlsession.res


+ 83 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpi

@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<CONFIG>
+  <ProjectOptions>
+    <Version Value="9"/>
+    <PathDelim Value="\"/>
+    <General>
+      <Flags>
+        <SaveOnlyProjectUnits Value="True"/>
+        <MainUnitHasCreateFormStatements Value="False"/>
+        <Runnable Value="False"/>
+      </Flags>
+      <SessionStorage Value="InProjectDir"/>
+      <MainUnit Value="0"/>
+      <ResourceType Value="res"/>
+      <UseXPManifest Value="True"/>
+    </General>
+    <i18n>
+      <EnableI18N LFM="False"/>
+    </i18n>
+    <VersionInfo>
+      <StringTable ProductVersion=""/>
+    </VersionInfo>
+    <BuildModes Count="1">
+      <Item1 Name="Default" Default="True"/>
+    </BuildModes>
+    <PublishOptions>
+      <Version Value="2"/>
+      <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
+      <ExcludeFileFilter Value="*.(bak|ppu|o|so);*~;backup"/>
+    </PublishOptions>
+    <RunParams>
+      <local>
+        <FormatVersion Value="1"/>
+        <LaunchingApplication PathPlusParams="\usr\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/>
+      </local>
+    </RunParams>
+    <RequiredPackages Count="1">
+      <Item1>
+        <PackageName Value="WebLaz"/>
+      </Item1>
+    </RequiredPackages>
+    <Units Count="2">
+      <Unit0>
+        <Filename Value="urlsession.lpr"/>
+        <IsPartOfProject Value="True"/>
+        <UnitName Value="urlsession"/>
+      </Unit0>
+      <Unit1>
+        <Filename Value="..\webmodule\webmodule.pas"/>
+        <IsPartOfProject Value="True"/>
+        <ComponentName Value="FPWebModule1"/>
+        <ResourceBaseClass Value="DataModule"/>
+        <UnitName Value="webmodule"/>
+      </Unit1>
+    </Units>
+  </ProjectOptions>
+  <CompilerOptions>
+    <Version Value="10"/>
+    <PathDelim Value="\"/>
+    <SearchPaths>
+      <IncludeFiles Value="$(ProjOutDir)"/>
+    </SearchPaths>
+    <Other>
+      <CompilerMessages>
+        <UseMsgFile Value="True"/>
+      </CompilerMessages>
+      <CompilerPath Value="$(CompPath)"/>
+    </Other>
+  </CompilerOptions>
+  <Debugging>
+    <Exceptions Count="3">
+      <Item1>
+        <Name Value="EAbort"/>
+      </Item1>
+      <Item2>
+        <Name Value="ECodetoolError"/>
+      </Item2>
+      <Item3>
+        <Name Value="EFOpenError"/>
+      </Item3>
+    </Exceptions>
+  </Debugging>
+</CONFIG>

+ 14 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.lpr

@@ -0,0 +1,14 @@
+program urlsession;
+
+{$mode objfpc}{$H+}
+
+uses
+  fpFCGI, webmodule;
+
+{$R *.res}
+
+begin
+  Application.Port:=2015;//Port the FCGI application is listening on
+  Application.Initialize;
+  Application.Run;
+end.

BIN
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/fcgi/urlsession.res


+ 23 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogin.html

@@ -0,0 +1,23 @@
+<html>
+<body>
+
+ {+MESSAGE
+   [-NORMAL  =Welcome to the URL-session test login screen-]
+   [-MISSING =<font color="red"><small>Please enter both a login name and a password.</small></font>-]
+   [-INVLOGIN=<font color="red"><small>Invalid login name or password. Please try again.</small></font>-]
+   [-NODB=<font color="red"><small>Cannot find the user DB or it is empty.</small></font>-]
+   [-SESSIONEXPIRED=<font color="orange"><small>Your session has expired. Please log in again</small></font>-]
+ +}
+ <br>
+ <form action="/urlsession/login" method="Post">
+
+  Login Name:<input type="text" name="LoginName" value="{+LOGINNAME+}"> 
+
+  Password:<input type="password" name="Password"> 
+ 
+  <input type="submit" class="button" value="Login">
+
+ </form>
+
+</body>
+</html>

+ 10 - 0
packages/fcl-web/examples/fptemplate/sessions/urlsessions-login/templates/testurllogout.html

@@ -0,0 +1,10 @@
+<html>
+<body>
+Logout screen<br><br>
+
+You have successfully logged out <b>{+LOGINNAME+}</b> .<br><br>
+
+You can log in again <a href="/urlsession/login">here</a><br><br>
+
+</body>
+</html>

Some files were not shown because too many files changed in this diff