REXXTAGS.org :: Samples: A sample page tag
Home Samples

File: rexxtags.page.tag [download (.tag file, 13 KB)]

Author: José María Blasco<jm@jmblasco.com>

Contributed on: 2002-12-13

Description: This is the tag used in the REXXTAGS site to provide a standard look for all the pages, show access counters, collect statistics, etc. It is very simple, and relies on a back-end database. It's not usable as a drop-in tag, but can be used as a model to write your own page tags.

Examples: All the pages in this site are examples of use of the <rexxtags:page> tag. For example, this page is bracketed between <rexxtags:page title="Samples: A sample page tag"> and </rexxtags:page> tags.

Program code:



  1:/* <rexxtags:page>: Define www.rexxtags.org pages                             */
  2:/*                                                                            */
  3:/* Parameters:                                                                */
  4:/*   title="page title"  Mandatory (not checked)                              */
  5:/*   type="page type"    Optional; default: "" (ommited): standard page       */
  6:/*                       Other values:      "Tutorial"  : tutorial page       */
  7:/*   request="apache request"  Automatic                                      */
  8:/*                                                                            */
  9:/* Version:     1.0                                                           */
 10:/*                                                                            */
 11:/* Author:      (c) Jose Maria Blasco <jm@jmblasco.com>                       */
 12:/*                                                                            */
 13:/* This software is subject to the terms of the Common Public License. You    */
 14:/* must accept the terms of this license to use this software. Refer to       */
 15:/* the license at the following URL for more information:                     */
 16:/* http://oss.software.ibm.com/developerworks/opensource/CPLv1.0.htm          */
 17:/*                                                                            */
 18:/* This is the tag used in http://www.rexxtags.org to describe pages. It is   */
 19:/* provided AS A SAMPLE so that others can start writing page tags.           */ 
 20:/*                                                                            */
 21:/* Modifications:                                                             */
 22:/*                                                                            */
 23:/* Date       Author      Description                                         */
 24:/* ---------- ----------- --------------------------------------------------- */
 25:/* 2002/12/13 J.M.Blasco  v1.0 Initial release                                */
 26:
 27:Parse arg verb, parms
 28:
 29:  If verb == 'START' Then Signal StartTag     /* Handle start tag             */
 30:  If verb == 'END'   Then Signal EndTag       /* Handle end tag               */
 31:  If verb == 'QUERY APACHE REQUEST' Then      /* Get the apache request as..  */
 32:     Return 1                                 /* ..a parameter                */ 
 33:
 34:Return 0                                      /* Standard rexx tag exit       */
 35:
 36:/*----------------------------------------------------------------------------*/
 37:/* Common 'get parameters' routine. Used by both 'StartTag' and 'EndTag'      */
 38:/*----------------------------------------------------------------------------*/
 39:
 40:GetParms:
 41:
 42:  Parse value ' 'parms with ' title="'title'"'
 43:  Parse value ' 'parms with ' type="'type'"'
 44:  Parse value ' 'parms with ' request="'request'"'
 45:
 46:  /* Store a boolean indicating whether this is a tutorial page               */
 47:
 48:  tutorial = Translate(type) = 'TUTORIAL'
 49:
 50:  /* If this is a tutorial page, store the page number and alter the title.   */
 51:
 52:  If tutorial Then Do
 53:    Parse var wwwfilename 'tutorial/page'page'.html'
 54:    page = page + 0
 55:    title = 'Tutorial -' page':' title
 56:  End
 57:
 58:  /* This will allow for future support of different header and title         */
 59:
 60:  header = title
 61:
 62:  title = 'REXXTAGS - 'title
 63:
 64:Return
 65:
 66:/*----------------------------------------------------------------------------*/
 67:/* Start tag handling                                                         */
 68:/*----------------------------------------------------------------------------*/
 69:
 70:StartTag:
 71:
 72:  /* 1: Get the parameters                                                    */
 73:
 74:  Call GetParms
 75:
 76:  /* 2: Connect to a back-end database. In the rexxtags site we use DB2.      */
 77:  /*    We are connecting to the database at the start tag, and resetting..   */
 78:  /*    ..the connection at the end tag. This way, all intermediate tags..    */
 79:  /*    ..can benefit from the same connection (and don't have to establish.. */
 80:  /*    ..their own connection.                                               */ 
 81:
 82:  Call SqlExec "Connect to G0BCN"
 83:
 84:  /* 3: Special handling of tutorial pages.                                   */
 85:  /*    If this is a tutorial page, we build a small navigation bar with..    */
 86:  /*    ..'home', 'prev' and 'next' links. The later are only displayed..     */
 87:  /*    ..when needed (i.e., no 'next' link for the last page, etc)           */
 88:
 89:  nl = '00'x             /* new line indicator                                */
 90:  extra = ''             /* This will get the extra 'tutorial page' html code */
 91:
 92:  If tutorial Then Do
 93:    prevnext = '&nbsp;'
 94:    p = LastPos('/',wwwFileName)
 95:    nextfile = Left(wwwFileName,p)'page'Right(page+1,2,0)'.html'
 96:    nextfile = Stream(nextFile,'C','QUERY EXISTS')
 97:    anext = '<a href="page'Right(page+1,2,0)'.html">Next &gt;&gt;</a>'
 98:    aprev = '<a href="page'Right(page-1,2,0)'.html">&lt;&lt; Prev</a>'
 99:    If page = 1 Then prevnext = anext
100:    Else If nextfile = '' Then prevnext = aprev
101:    Else prevnext = aprev '|' anext
102:    extra = nl'<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td align="left">' ,
103:      nl'<a href="/">Home</a> <img src="/images/flechader.gif" width="4" height="7" alt="" /> <a href="/tutorial">Tutorial</a>' ,
104:      nl'</td><td align="right">' ,
105:      nl prevnext ,
106:      nl '</td></tr></table>'
107:  End
108:
109:  /* 4: Return html for the startting part of the page                         */
110:
111:  Return '<?xml version="1.0" encoding="windows-1252" ?>',
112:    nl'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
113:    nl'<html>' ,
114:    nl'<head>' ,
115:    nl'<title>'title'</title>' ,
116:    nl'<style type="text/css">' ,
117:    nl'<!--' ,
118:    nl'body {  font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 8pt}' ,
119:    nl'tr {  font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 8pt} ',
120:    nl'a:active {  color: #003366; text-decoration: none}',
121:    nl'a:link {  color: #003366; text-decoration: none}',
122:    nl'a:visited {  color: #003366; text-decoration: none}',
123:    nl'a:hover {  color: #FF0000; text-decoration: underline}',
124:    nl'-->',
125:    nl'</style>',
126:    nl'</head>' ,
127:    nl'<body bgcolor="#FFFFFF" text="#000000">' ,
128:    nl'<table width="100%" border="0" cellspacing="0" cellpadding="2">' ,
129:    nl'  <tr bgcolor="#FFCC66"> ',
130:    nl'    <td><font size="5"><b>REXXTAGS<font color="#999999">.org&nbsp;::&nbsp;</font></b></font></td><td width="90%"><font size="+1"><b>'header'</b></font></td>',
131:    nl'  </tr>' ,
132:    nl'</table>' ,
133:    extra
134:
135:/*----------------------------------------------------------------------------*/
136:/* End tag handling                                                           */
137:/*----------------------------------------------------------------------------*/
138:
139:EndTag:
140:
141:  /* 1: Get the parameters                                                    */
142:
143:  Call GetParms
144:
145:  /* 2: Evaluate the URI for stats collection                                 */
146:  /*    We discard the path info part, if any, and normalize indexes          */
147:
148:  uri = wwwuri
149:  uri = left(uri,length(uri)-length(wwwpath_info))
150:  if right(uri,11) = '/index.html' then uri = left(uri,length(uri)-11)
151:
152:  /* 3: Collect statistics                                                    */
153:  /*    EZSelect interacts with DB2 and returns a rexx stem for every column  */
154:
155:  Call EZselect "Select N, date From Web.Counters Where URI='"uri"' and SERVER='"wwwServer_Name"'"
156:  If n.0 = 0 Then n = 0
157:  Else n = n.1
158:  If n.0 = 0 Then date.1 = date('e')                 /* First visit to a page */
159:
160:  If Left(wwwremote_addr,12) <> '192.168.2.11' Then Do /* Developer's IP      */
161:
162:      n = n + 1
163:
164:      /* We keep a separate fast table of counters                            */
165:
166:      if n.0 = 0 then stmt = "Insert into web.counters(uri,n,date,Server) values('"uri"',"n",current date,'"wwwServer_name"')"
167:      else stmt = "Update web.counters set n = n + 1 where uri='"uri"' and server='"wwwServer_Name"'"
168:      Call SqlExec "Execute immediate :stmt"
169:
170:      Call SqlExec "Commit"
171:
172:      /* Because of these two calls, we needed the apache request parameter   */
173:
174:      referer = WWWReqRecHeader_in(request, "Referer")
175:      Call WWWGetCookies request
176:
177:      /* Log everything                                                       */
178:
179:      stmt = "Insert into web.log (Server, uri, date, time, user_agent, user, referer, visitor, ip)",
180:      "Values('"wwwServer_Name"','"uri"',current date, current time,'"add_quotes("'",WWWHTTP_USER_AGENT)"','"add_quotes("'",WWWRemote_USER)"',
181:         '"add_quotes("'",referer)"','"wwwcookies.visitor"','"wwwRemote_addr"')"
182:      Call SqlExec "Execute immediate :stmt"
183:
184:  End
185:
186:  Call SqlExec "Commit"
187:
188:  /* 4: Reset the SQL connection                                              */
189:
190:  Call SqlExec "Connect reset"
191:
192:  /* 5: Build the page footer                                              */
193:
194:  Parse value stream(wwwfilename,'C','QUERY DATETIME') with mm'-'dd'-'aa' 'h':'m':'s
195:
196:  If n = 1 Then visitas = "1 visit"
197:  Else visitas = n "visits"
198:
199:  /* 6: Special handling of tutorial pages                                 */
200:  /*    We parse the next page, look for its title, and display it in the..*/
201:  /*    ..current page as a link after 'Next section:'                     */
202:
203:  nl = '00'x
204:  extra = ''
205:
206:  If tutorial Then Do
207:    p = LastPos('/',wwwFileName)
208:    nextfile = Left(wwwFileName,p)'page'Right(page+1,2,0)'.html'
209:    nextfile = Stream(nextFile,'C','QUERY EXISTS')
210:    If nextFile <> '' Then Do
211:      Do While lines(nextFile) > 0
212:        l = LineIn(nextFile)
213:        Parse var l '<rexxtags:page title="'nextChapter'"'
214:        If nextChapter <> '' Then Leave
215:      End
216:      Call Stream nextFile,'C','CLOSE'
217:      If nextChapter <> '' Then nextSection = '<a href="page'Right(page+1,2,0)'.html">Next section: 'nextChapter'</a>'
218:      Else nextSection = '<a href="page'Right(page+1,2,0)'.html">Next section</a>'
219:      End
220:    Else nextSection = '&nbsp;'
221:    extra = '<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td align="left">'nextsection'</td>' nl,
222:'<td align="right"><a href="showpage.html?page='wwwfilename'">View the XML code for this page</a></td></tr></table>'
223:  End
224:
225:  /* 7: Return the footer                                                    */
226:
227:  Return extra '<hr size="1" width="100%" align="left" />' ,
228:  ||'00'x||'<table width="100%" border="0" cellspacing="0" cellpadding="0">' ,
229:  ||'00'x||'  <tr>' ,
230:  ||'00'x||'    <td><font face="Verdana, Arial, Helvetica, sans-serif" size="1" color="#FF9900"><u>'uri'</u> ['visitas 'since' date.1']<br />' ,
231:  ||'00'x||'      Last update: 'dd'/'mm'/'aa' at 'h':'m ,
232:  ||'00'x||'      </font></td>' ,
233:  ||'00'x||'    <td>' ,
234:  ||'00'x||'      <div align="center"><table><tr><td><a href="mailto:webmaster@rexxtags.org">' ,
235:  ||'00'x||'<img src="/images/email20x15.gif" alt="" border="0" align="middle" /><font face="Verdana, Arial, Helvetica, sans-serif" style="{font-size: 8pt}">&nbsp;Comments</font></a>' ,
236:   '</td></tr></table></div>' ,
237:  ||'00'x||'    </td>' ,
238:  ||'00'x||'    <td>' ,
239:  ||'00'x||'      <div align="right"><a href="http://validator.w3.org/check/referer"><img border="0" src="/images/valid-xhtml10.gif" alt="Valid XHTML 1.0!" height="31" width="88" /></a> ' ,
240:  ||'00'x||'        <a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="/images/vccs.gif" width="88" height="31" alt="Valid CSS!" border="0" /></a></div>' ,
241:  ||'00'x||'    </td>' ,
242:  ||'00'x||'  </tr>' ,
243:  ||'00'x||'</table>' ,
244:  ||'00'x||'</body>' ,
245:  ||'00'x||'</html>'
246:
247:MonthName:
248:  Select
249:    When arg(1) = 1 Then Return "jan"
250:    When arg(1) = 2 Then Return "feb"
251:    When arg(1) = 3 Then Return "mar"
252:    When arg(1) = 4 Then Return "apr"
253:    When arg(1) = 5 Then Return "may"
254:    When arg(1) = 6 Then Return "jun"
255:    When arg(1) = 7 Then Return "jul"
256:    When arg(1) = 8 Then Return "aug"
257:    When arg(1) = 9 Then Return "sep"
258:    When arg(1) = 10 Then Return "oct"
259:    When arg(1) = 11 Then Return "nov"
260:    When arg(1) = 12 Then Return "dec"
261:    Otherwise Return ""
262:  End
263:
264:Syntax:
265:  Return "Syntax error at line" sigl
266:
267:/* From rspcomp.rex */
268:
269:add_quotes: procedure
270:quote = arg(1)
271:line = arg(2)
272:x = pos(quote, line)
273:do while x > 0
274:   line = substr(line, 1, x) || quote || substr(line, x + 1)
275:   x = pos(quote, line, x + 2)
276:   end
277:return line
278:

/samples/rexxtags.page.html
Last update: 13/12/02 at 12:43
 Comments
Valid XHTML 1.0! Valid CSS!