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 = ' '
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 >></a>'
98: aprev = '<a href="page'Right(page-1,2,0)'.html"><< 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 :: </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 = ' '
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}"> 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
|
|
|