Abstract | The CMS addon for the SREhttp/2 web server for OS/2 is a moderately powerful content management system (CMS). The power of CMS lies in it's ability to quickly create HTML documents that use stored data. In particular, with CMS it is easy to create "blogs", and other types of repetitive HTML documents. |
---|
CMS is multi-host aware. You can use CMS to create dataseries across different hosts on the same server machine -- a single installation of CMS will keep track of which dataseries belongs to which host.
Assuming the CMS was properly installed on your OS/2 computer that is running SREhttp/2, to access the database component simply fire up your web-browser, and request:
Technical
Notes:
- As a security measure, only users with either
are allowed to create dataseries! - a SREhttp/2 SUPERUSER privilege
- a CMS_DEF privilege
- The maximum size of a record is 10000 bytes (you can change this by editing the CMS_ADD.CMD, CMS_MOD.CMD, and other files).
/CMS/CMS?This will bring up a menu of choices.
Use this to define a new CMS dataseries.
You will be asked to specify its name, the names and "types" of variables,
and some descriptive information.
The several variable "types" are:
An Abstract | A 50 character or less abstract, that is used for informational purposes (i.e.; when displaying lists of dataseries to choose from) |
---|---|
String | A text string, without CRLFs. |
Number | an integer or real number (with '' treated as 0) |
DateTime | a date (day/month/year) and time (hour:minute) |
Select List | a selection list. See below for further details. |
Poll | a poll (running count of several choices). See below for further details. |
Lines of Text | Multiple lines of text |
Checkbox | A checkbox -- when checked, a value of 1 is stored. When not checked, a value of '' is stored |
File or URL | Allows the user to upload the contents of a file
(assuming she is using a reasonably modern browser);
or grab the contents of a URL. If you specify any "File or URL types, you should also specify (in the field provided) the upload storage directory. This directory is where these uploaded files will be stored. Note that when CMS generates output, it will use the contents of the file, not the file name. Furthermore, this file (or URL) can be of any mimetype, it need not be a text file. If you do not specify a "uploads storage directory", the UPLOADS subdirectory of the CMS directory is used. |
You can also specify:
Remove template definitions, or add new "template definitions", to a
dataseries.
Note that when you define a dataseries, you can specify several
"template definitions". These are stored in the .DEF file
(in the CMS\INDEX) subdirectory for this dataseries.
This option allows you to chanage these template
definitions.
Other variables in the .DEF file can be modified by the restructure a CMS dataseries
option that is described below.
You'll be asked to select one of the currently defined CMS dataseries. Then, you will be asked to choose one (or several) output files to generate. This is done by selecting appropriate template and "output" files(from those you specified when when you defined the CMS dataseries). You can also choose to "sort" the documents in different orders. You can also choose to view only the most "recent" documents. Note that output files include the "current" listing of records, archives (singleton and subset), and comment files.
You can add new records to one of the defined data series. When you add a record, you will be shown an HTML form listing the "types" of variables; with input fields suitable to the "type".
You can remove one, or several, records from a CMS dataseries. You can also view the records before removing them.
You can modify a record that currently exists in a CMS dataseries. For file types, you can change the original filename (as provided by the client), as well as the local file name (its name on the server machine, which will be relative to the file-storage directory). You can also view the uploaded file's contents.
You can add comments to existing records at any time -- old comments (for this record) will be retained.
You can remove one or several comments on existing records at any time.
You can modify comments to existing records at any time.
This will shutdown and reopen all currently open CMS dataseries. This is sometimes necessary when an error occurs.
This will do maintainance and repair on a selected CMS dataseries.
The selected dataseries will first be closed. Each record will
then be examined, with deleted records removed, and
bad records (that were somehow corrupted) are also removed.
This should not need to be done, since CMS will do occassional cleanups of deleted records. Thus, the best use of this when you think CMS has been lax about removing deleted records, or , forcing a fix & repair if you think some records have been corrupted and need to be removed.
You can delete a dataseries-- removing its several data and index files. You will be asked to verify this action!
Backup up the main, comments, and definitions file of a CMS dataseries (dated filenames are written to the DATA\ARCHIVE subdirectory of CMS). You can also use this to restore a CMS dataseries from a backup.
Remove, add, and re-define the variables in a CMS dataseries. It's a good idea to backup the dataseries before restructuring it!
Create a new dataseries, that retains the attributes (such as the variables, directories, and template files) of an existing data-series. You can modify these attributes (for example, you can remove variables).
Create a blog using one of CMS's pre-defined templates.
Descriptions of CMS's customizable forms; with a simple tool for helping you get started using them. Note: for details on the structure of CMS data files, see the appendix.
Templates are simply HTML documents that contain special CMS elements that contain CMS keywords. These give you access to a number of CMS functions. In particular, you can use these CMS "keywords" to output the values of variables stored in a CMS dataseries. And you can easily do this REPEATedly -- for each record in a dataseries.
In addition, CMS templates allow for a limited amount of program control -- IF, ELSE, and GOTO statements are supported. For example, IF is used to selectively include blocks of HTML content, based on the values of user-defined variables or of variables from a CMS dataseries.
For those who can work with REXX, the templates allow you to CALL (or INTERPRET) your own REXX procedures. These procedures will be given access to a number of the CMS variables (such as the values of the variables in the currently active record).
The user-defined REXX procedure can return an arbitrarily long string for writing to the output file, and it can set the values of variables that will be available to other CMS elements.
The general syntax of these CMS elements is:
<? keyword opt1 opt2 ... >
<? keyword ?opt1 opt2 ..>The next two sections describes the keywords, and their options.
Note: | before reading this, you may want to read the Appendix section that discusses ARCHIVE |
Using LINK requires a bit of coordination: you need to create a "subset" ARCHIVE element with specifications that match what you use in the LINK element and you need to add a <?A ...> element to your ARCHIVE template with specifications that match LINK.
In particular, for the LINK and ARCHIVE elements:
See the description of LINK for further details.
All in all, we recommend creating subset achives, and using LINK (and an A element in the archive's template file that has a matching ?NAME).
Hint: you can use the link creator tool to semi-automate the construction of thes LINK and ARCHIVE elements.
You can save processing time by selecting the
update latest archives
option when you
generate output files from an existing CMS dataseries.
This option effects how CMS creates "subset" archives. Basically, when checked, CMS will only create the "latest" archive file (the archive file covering the most recent records).
More precisely, CMS will
There are a few considerations:
Note that many advanced CMS features (such as VAR and IF)
only work within a REPEAT block.
Therefore, using a REPEAT block within
a singleton-archive template-file is often
necessary and/or convenient.
|
Keyword | Description |
---|---|
!-- & -- | Insert start of HTML comment (a <!-- ) and end of an HTML comment (a --> ) |
A | Create a <A ..> element, with a variable value used as the HREF |
ARCHIVE | Generate archive files |
CALL | Call a file as a REXX procedure, output what it returns |
CASES, /CASES, CASE, and /CASE | A case statement (a multiple block IF) |
COMMENT | Create a link to a listing of a record's comments |
DEFINE and /DEFINE | Define a subroutine |
ELSE and /ELSE | Jump here if an IF condition is false |
GOSUB | Insert contents of a subroutine |
GOTO | Jump to a LABEL |
HTML | Insert an HTML element, with substitutions |
IF and /IF | Skip to the /IF if the IF condition is not met |
INC | Increment a user-defined numeric variable |
ITER (and DROP) | Stop processing this record (go to next record) |
INTERPRET | Call a block of rexx code as a procedure, output what it returns |
LABEL | Jump to here (using GOTO) |
LEAVE | Stop processing all records |
LINK | Create a link to this records "permanent" location |
POLL | Display current poll results, or ask client to add a vote to the poll |
READFILE | Read a file |
REPEAT and /REPEAT | Repeat content, one time for each record in dataseries |
REM | A comment, that will NOT be written to the output file |
SERIES | Write some information on this CMS dataseries |
SET | Set a user-defined variable |
SORT | Sort the records on one of the "sortable" variables |
SHOW | Show user-defined variables, and "system" variables (eg; time) |
SHRINK and /SHRINK | Remove extra linefeeds, tabs, and spaces |
TEMPLATE | Display information the CMS template being used |
TR, TH, and TD | Write HTML table elements, with alternating colors |
VAR | Lookup the value of a variable in the current CMS dataseries |
Example:
<? !-- Uncomment this to show attributes > <UL> <li><? var color > <li><? Var weight > </ul> <? -- End of show attributes block >Note that the Uncomment this to show attributes and the End of show attributes block will NOT be written to the output file.
If you just want to include a comment in the template file, that will NOT be written to the output file, use the REM element.
<? < >Input type="hidden" name="series" value="<? series name>" <? /< >If you use "<" instead of "<? < >", the SERIES name CMS element will NOT be processed by CMS!
?URL=varname | the varname variable will be used as the value of href=
("s will be added)
Note: ?URL checks both the list of dataseries variables, and the list of user-defined variables. |
---|---|
?URL_FILE=varname | use, as the value of href=,
the local filename used to store a uploaded file
type of variable. This is a convenient way to create a link to the locally stored version of an uploaded file (or of a downloaded web resource). Note that for other types of variables, URL_FILE and URL are the same |
?BASE=url_base | an optional "url" base, used if the ?URL does not
contain path info (such as http://" or "foo.bar.net) ?BASE can also be used with ?NAME. Example: ?BASE=http://foo.bar.net/pictures/ then, if the value of a ?URL varname is "hello.gif", a <A href="http://foo.bar.net/pictures/hello.gif"> element will be created Hint: to use ?URL to jump to an internal location (to a <A NAME="..">), use ?BASE="#" Hint: you can use ?BASE and ?NAME to create a NAME target that has a common prefix and a variable suffix. Example (assuming the dataseries has a FAMILY variable): <? A ?NAME=family ?BASE="F_NAME_">New family<? /a> Then, if FAMILY=Jones, the following will be output: <? A NAME="F_NAME_Jones"">New family</a> Hint: to force SREhttp/2 to return the file using a specific mimetype, use ?BASE=/!SENDAS_type_subtype/dir1/dir2/ For example: ?BASE=/!SENDAS_text_plain/mydir/textdocs/ tells SREhttp/2 to return the document (the target of the A) as a plain-text mimetype. |
?NAME=varname | the varname
variable (or the varname user-defined variable)
will be used as the value of a name=
option ("s will be added)
Note: ?NAME checks both the list of dataseries variables, and the list of user-defined variables. |
&anopt=varname or anopt="a string" | add an anopt option,
set equal to the value
of the varname variable.
Or, if a multiple word string is used, anopt will equal the value of this string. As with the ?NAME and ?URL options, varname can be a dataseries or a user-defined variable. These options will be added at the end of the url, after a ?. You can specify many &optname options, they will be seperated by & characters (and will be properly URL-encoded). |
Examples:
Example 1: <repeat> <? A ?url=sitename target="info1"> <? var sitedesc></a><br> </repeat> could generate <a url="http://www.foo.net/hi.htm" target="info1">The foo hello</a><br> <a url="http://www.bar.net/bye.htm" target="info1">The bar goodbye</a><br> Example 2: <repeat> <? A ?url=pagename ?base="http://foo.bar.net/" target="info1">Try this</a><br> </repeat> could generate <a url="http://foo.bar.net/intro.htm" target="info1">Try this</a><br> <a url="http://foo.bar.net/summary.htm" target="info1">Try this</a><br> Example 3: <repeat> <? A ?name=!ID"> Info for <? var username> </a><br> ... <? A ?url="!ID" ?base="#">Top of entry</a> (for <? var username>) could generate <a name="5243_625">Info for Joe</a><br> ... <a href="#5243_625">Top of entry</a> (for Joe) Example 4: <? A target=apps ?name="/myaddon.cmd" &visitor=NAME &Entry=!ID "> Run my application? </a> could generate <a url="/myaddon.cmd?visitor=joe&Entry=2004>Run my application?</a> Example 5: <? if length(upfile) gt 1 > <? a ?url_file=descrip_file ?base=/calendar/files/>View attached file</a> (< ?a ?url_file=descrip_file ?base=/!sendas_text_plain/calendar/files/ >as text</a>) < ? /IF > could generate <a href="/calendar/files/MY_party.DOC" >View attached file</a> (<a href="/!sendas_text_plain/calendar/files/MY_party.DOC">as text</a>)
Syntax. |
|
The options are: | FILE=template_file TYPE=nnn|HOUR|DAY|WEEK|WEEK2|MONTH|MONTH2|YEAR|SORT LIST=ul|ol|table|ulA|olA|tableA OUTPUT=output_file_pattern or $varname URL=base_url or $varname MESSAGE="a message" UPDATE=0|1|AUTO #FIELD="field contents" |
filename | A CMS-procedure. CMS-procedures are
files containing a REXX procedure (i.e.; that contain
REXX code and that return a value). If no path information, filename is assumed to be in the CMS\LIB directory. Otherwise, filename should either be a fully qualified file, or relative to the CMS directory. If no extension is given, an extension of .CMS is used. |
---|---|
userarg | A single (possibly multiple-word) argument to be sent to the procedure (that is contained in filename). |
<? Repeat ID=ddd.ffff > <? CALL ... ) <? /REPEAT >where ddd.ffff is the record you whose values you want to manipulate.
Hint: you can use the CALL_ID to save variables (in the INFO. stem variable) for use in the next invocation of this same procedure.
To read these arguments, you can use the following REXX code:
parse arg myargs,kId
where myargs is the USERARG, and kid is the CALL_ID.
INFO. can contain the following:
INFO.!!VARNAMES | A space delimited list of the CMS variables (in the current CMS dataseries) |
INFO.!VAR1 ... | The value, for the current record, for each variable listed in
INFO.!!VARNAMES.
Thus, if INFO.!!VARNAMES='INCHES, POUNDS, and COLOR' Then INFO.!HEIGHT might be "68", INFO.!WEIGHT might be "150", and INFO.!COLOR might be "BROWN" |
INFO.!!FILE_VAR | INFO.!!FILE_VARS contains a list of the CMS
variables that are uploaded files. If the dataseries does
not contain this type of CMS variable, then INFO.!!FILE_VARS
will be empty.
To save space and time, instead of including the contents of the file in INFO., some locational information is given.
The format of these "file type" CMS variables is: Example: if MYDOC is a CMS variable that was defined as a file-upload, then INFO.!!FILE_VARS='MYDOC' and INFO.!MYDOC='FooBar.TXT=D:\myarea\fooBar_01.txt; content-type=text/plain' To read the contents of this uploaded file, you can use: parse var INFO.!MYDOC . '=' dafile . dafile_contents=sre_read_file(dafile,2,2,1) (if this file doesn't exist, dafile_contents will be empty) |
Special variables | Several special variables, such as the record ID, the series
name, and the current record number. Note that these
start with !!.
Examples: INFO.!!FileDir : The fully-qualified FileDir for this dataseries. INFO.!!UpLoadDir : The fully-qualified UploadDir for this dataseries. |
User-defined variables | For example, a <? SET SECTION="My book" > means that INFO.!SECTION will have a value of"My book" (without the ") You can modify values of these user defined variables, and they will be available to other procedures (or the modified values can be displayed using SHOW elements). You can also define new user-defined variables. To do this, just set INFO.!UserVar='some value' Example: <? Set astatus="unknown" > <? Call astatus_redo Joe_Jones > New Status: <? Show Astatus>, set on <? show Astatus_date>and .. status_redo contains INFO.!ASTATUS='augmented' INFO.!ASTATUS_DATE='Monday'The New Status... last line will become: New Status: augmented, set on Monday Note that Astatus was first defined using a SET element, while Astatus_datewas first defined in the status_redo CMS-procedure.
|
<? CALL $FILE example > <? CALL $FILE myprocs\foo 105.3 > <? CALL $FILE d:\mystuff\bar.int >
Syntax: |
|
The condition-list has the following possible formats: |
|
Example: | <? cases education > <? case eq "1" > Education is HS dropout <?cases age> <?case le "6"> Less then or equal to 6 years old <? /case> <?case lt "18"> Less then 18 years old <? /case> <?case ge "18" , le "21" > between 18 and 21 ? <?/case> <? case ini "NA DK " > age not reported <? /case> <? case > Older than 21 <? /case> <? /cases (age) > <? /case (1) > <? case ge "2" , le "3" > Education is ge Some College and le BA <? /case > <? case ne "4" > Education is not equal to Masters <? /case > <? case > The default: other eduction <? /case (default education) > <? /cases (education) > |
---|
The important options are:
?FILE=template_file ?OUTPUT=output_file_pattern ?URL=base_url ?MODE=SHOW|UPDATE|CREATE|ADD|NAME|AUTO ?RETAIN=varname ?RESPFILE=response_file_name ?QUIET=0|1
?OUTPUT : default value is a modification of the current output name ?URL : default value is "" (pathless links are created) ?MODE: default value is SHOW ?RETAIN: default is not to retain any variables ?RESPFILE: default value is to use the generic response ?QUIET: default value is 1However, ?FILE is not optional!
Example:
#comments for this record: <? var status(cmt_cnt) > <? comment ?url=/blogs/comments/* target=vu2>View comments?<? /comment>For further details on COMMENT, please see the appendix.
Syntax:
<? DEFINE sub_name sub_arg >
stuff
<? /DEFINE >
where: |
|
Notes |
|
---|
Example: | <? DEFINE sub2 $yibble > Welcome <? show $Yibble> . This is the sub2 definition. It calls sub1: <? gosub sub1 $yibble > <? /DEFINE> |
---|
Basically,
Notes: |
|
---|
Example: | <? If male eq 1 > This record is for a man. <? if height gt 72> He is taller then 6 feet <? /if> <? Else > He is shorter then 6 feet <? /else > <? /if > <? else (a woman) > This record is for a woman. <? if height gt 66> She is taller then 5.5 feet <? /if> <? Else > She is shorter then 5.5 feet <? /else > <? /else (end of woman else) > |
---|
Syntax:
<? GOSUB subname gosub_value >
where: |
|
Example: | <? gosub sub2 !count > <? gosub subs2 hello world > |
---|
GOTO is an unconditional goto. Typically, it is used within a IF group. This can be convenient when you have large blocks of code that should be skipped.
In addition, it can be used to implement a primitive loop.
Example: | <UL> <? Set II=0 > <? Label LoopTop > <? IF II le 10> <? Inc ii> <li> This is line <? Show ii > <? goto looptop > </if> <? REM End of II loop > </ul> |
---|---|
Notes: |
|
Syntax:
<? HTML element opt1="a value" ?opt2=varname ... >
Where:
Example: | <? var name=datetime(edate) assign=tdate nodisplay=1> <? html Hnew ?java1=tdate ?java1a=edate java2="goodbye" >Hello!</a> might create <hnew JAVA1="20040320" JAVA1A="5174.140277778" JAVA2="goodbye">Hello!</a> |
---|---|
Notes: |
|
DROP is used to drop the record -- skip processing and discard any of the output that may have been written for this record. Furthermore, the processed records count will not be incremented.
Note that DROP is synonymous with ITER DROP.
ITER and DROP are typically combined with an IF to suppress (further, or any) display of particular records (say, records older then a chosen date).
Examples: | <? iter > <? drop > <? iter drop > <? if age gt 40 then {? drop} > |
Long Syntax:
<? IF var1 cond var2 > .. <? /IF >, or
<? IF var1 cond > .. <? /IF > (for event tracking)
Compressed Syntax:
<? IF var1 cond var2 then ... else ... >, or
<? IF var1 cond then ... else ... > (for event tracking)
where: |
var1 is usually a variable name. Or, it can be an if-function var2 is usually a value. cond is the condition then and else signify what to do if the cond is true or false |
Basically, if the condition (comparing var1 and var2) is met ... |
|
If the condition is not met. |
|
<? Set local1 eq 3 > ... <? IF local1 eq 3> ... <? /IF >
EQ : equal GT : greater then GE : greater then or equal LT : less then LE : less then or equal NE : not equalNote: we use these FORTRAN style conditions due to the difficulties of using < and > characters inside of HTML elements!
If you do not specify var2, then the prior value (from
the record processed before this one) of var1 is
used. This allows you to process content conditional on whether a
change occurs (or did not occur).
Example:
<? If datetime(M) NE >
will be true, for record n, when
the nth record's value of MONTH is
different than MONTH value of the nth-1 record.
Examples: | <? IF !ID EQ 5213.512431> <? If AUTHOR NE "JOE FLOE" > <? If DUE_DATE GT SUBMIT_DATE > <? IF DATETIME(W) NE > <? IF DATETIME(Y,BIRTHDAY) GT 1945 > <? IF AUTHOR NE > |
The informational variables: |
Several "information and status" variables can be used by IF.
All of them start with !.!SERIES : the name of this CMS dataseries !ARG : the argument (entered by the client from the Generate output files form).Example: <? If !CURRENT eq !LOOP_E > This is the last record! </if> Note that these special variables can also be read in CALLed procedures.
|
Example: | <? IF NEED_EDIT_FLAG eq 1> The <? var filename=document> file needs to be edited <? /IF> <? If NEED_Edit_flag ne 1> Mr.<? var Editor> has completed editing <? var filename=document> <? /if > |
Example of embedded IF | <? If type eq "WILD" > <?IF species eq "LAND"> <h3>Wild Land Animals</h3> <? /IF> <?IF species eq "AIR"> <h3>Wild Birds</h3> <? /IF> <? /IF > <? If type ne "WILD" > <h3>Domesticated Animals </h3> <? /IF > |
Example of compressed syntax | <? IF NEED_EDIT_FLAG eq 1 then This needs editing else Editing not required > <? IF species eq "LAND" then {? var animalname} is a land dweller else {? var animalname} is {b}not{/b} a land dweller > <? IF datetime(Y,starttime) lt 2004 then {? iter drop } > |
The REXX code contained within the code-block will be called as a procedure. It should "return" results. These results will be written to the output file.
Hence, when CALL (or INTERPRET) is used within a REPEAT block, the CALL_ID will remain the same across all records.
Hint: you can use the CALL_ID to save variables (in the INFO. stem variable) for use in the next invocation of this same procedure.
To read the CALL_ID, you can use the following REXX code:
parse arg foo,kId
where foo will always equal ''
<? INTERPRET t1=time('s') if t1>(86400/2) then do return 'Hello '||INFO.!FIRSTNAME||', it is the afternoon ' end else do return 'It is the morning.' end >Notice that you can use temporary variables (t1 above). You can also set other INFO (say, INFO.!CTIME), providing the leaf (i.e.; CTIME) does not conflict with one of the CMS dataseries's variables.
<? Repeat ID=ddd.ffff > <? INTERPRET ... ) <? /REPEAT >where ddd.ffff is the record you whose values you want to manipulate.
Examples: |
<? INC II > <? INC JTH -1 > |
Typically, this is used with an IF .. /IF. For example, to suppress display of newer records.
LEAVE can take one option: DROP. If drop is specified, output for the current record will NOT be written to the file, and the "processed records" count will not be incremented.
Example:
<? leave > <? leave drop >
?TYPE = nnn|HOUR|DAY|WEEK|WEEK2|MONTH|MONTH2|YEAR|SORT ?OUTPUT = output_file_pattern ?URL = base_url ?NAME = cms_varExcept for the use of a ? prefix, the TYPE, OUTPUT, and URL options are similar to the similarly named ARCHIVE options (see the appendix for details).
NAME is used to form locald in url#locald. We recommend that you use ?NAME=!ID (to use a special variant of the record's ID).
Basically, LINK is meant to be used with an ARCHIVE element specified with the
exact same values of TYPE, OUTPUT, and URL.
Furthermore,
the FILE (template file) referenced by this ARCHIVE should contain
a <? A ?NAME=cms_var> element, where the cms_var is the same as the cms_var
used in the NAME option of LINK.
As noted above, we recommend using !ID in both places.
<? link type=WEEK output=f:\www\blogs\sports$A*.html url="/blogs/" name=!ID >permanent link<? /link>which could create statements of the form:
Syntax:
<? POLL option=value option=value ... >
or..
<? POLL auto=ask option=value ... > a link <? /POLL >
The case-insensitive options are:
VAR = varname : The Poll type CMS variable to ASK, UPDATE, or SHOW. ID = record_id : The record containing this Poll. If ID is not specified, then use the current record id. If POLL is used outside of a REPEAT loop, then ID must be specified. AUTO=ask|show|update: CMS will automatically ... ASK = create a link, that when clicked, will bring up a questionaire for client to fill out, SHOW = display current counts for this poll's choices UPDATE = create a link, that when clicked, will display the current counts for this poll CNUMBER = a_number : The choice number. Several of the INFOoptions require that you select a choice number. If you use AUTO, CNUMBER is ignored. TARGET=window_name : Used with AUTO=ask -- the link will contain a TARGET="window_name" option. Note: we highly recommend using TARGET with ASK=update H3="a H3 string" :Used with AUTO=ask and AUTO=update -- a string to put in a <H3> (at the top of the questionaire). DESC="a B string" : Used with AUTO=ask and AUTO=update. A string to put in <B> (at the top of the questionaire,underneath the H3). BGCOLOR="acolor" : background color for document (only used with AUTO=ASK and AUTO=UPDATE) INFOoption[=uservar] : Information about this poll, or this response INFOoption can be one of the following. (general info) CHOICES : # of choices for this poll RESPONSES : current total number of responses HEADER : the header (if one was defined) FOOTER : the footer (if one was defined) COLOR : the questionaire-table background color (if one was defined) (choice specific info -- requires CNUMBER) CT : current number of responses (that chose this choice) STORE : the "stored" value for this choice DISP : the "displayed value" for this choice (statistics) ALLSTAT : do all the stats & responses WEIGHT : used "stored value" when computing MEAN, SUM, and SD MEAN : mean MEDIAN : median (by choice #) MAX : max (by choice #) SUM : sum SD : standard deviation CHART : make a primitive bar chart CHARTSPEC : what to output, width and height of bars, and list of colors The equal sign, and the uservar, are optional. If uservar is specified, the value of the option will be saved to the uservar user-defined variable. If uservar is not specified the value will be written to the output file. Examples: CHOICES FOOTER=Save_footer FORM=survey_form : Optional, and only used with AUTO=ASK. A file containing specifications for constructing the questionaire. In addition to the POLL variable, this file can specify other input fields. These values will be written to the survey-output file (using the survey output format) that is specified in the poll-definition file. #other="stuff" : Optional, used only with AUTO=ASK and AUTO=UPDATE. Other fields to include in a link (you can specify zero, one, or many "other" fields. The # is dropped, and the other="stuff" is included verbatim (including the "s). Example: #onClick="window.alert('The test results'); return false; "
For example: CHARTSPEC=1,100,10.
or:CHARTSPEC=CR,100,10,RED,GREEN,BLUE,YELLOW.
UPDATE is dynamic (no results are written to the output file, but a link can be pressed to generate the up-to-date results).
$VARNAME=avarname is replaced by the value of the avarname variable (avarname can be either a dataseries variable or a user-defined variable).
Examples | <? POLL var=RANK1 AUTO=show > <? POLL var=RANK1 AUTO=show ID=5651.1265126 > <? POLL var=QUALIITY CNUMBER=3 CT=USER_CT DISP=RESP1 > <? POLL var=U_JUDGE AUTO=ask target=vu1 h3="A Simple Poll" >You be the judge<? /POLL> <? POLL var=MEASURE1 ALLSTATS AUTO=show > <? POLL var=MEASURE1 MEDIAN=astat1 MAX=astat2 RESPONSES=astat3 > <? POLL var=MEASURE1 CHART=mychart chartspec=1,200,10,RED,CYAN,BLACK,GREY > <? POLL var=MEASURE1 h3="Current results for $VARNAME=SenateRace " AUTO=update target=VIEWR > <? POLL var=RANK1 h3="Your ranking of this story: $VARNAME=$ABSTRACT " AUTO=ask #onClick="window.alert('Results will be aggregated')" target=VIEWR > |
where
varname is CMS dataseries variable, or a user-defined variable.
filename is a relative, or fully qualified, filename
READFILE complements the FILENAME option of the VAR CMS-element, which is used to read the contents of file or url type of CMS variables. The variables point to files (on your server's hard drive) that have been uploaded by clients; either from their own machines, or from a URL they specified.
In contrast, READFILE can be used to read the contents of any file on your server's hard drive. Furthermore, the varname should be a string type of CMS variable.
If no path information is specified (in varname or in filename.ext), filenames specified in READFILE are assumed to be relative to the FileDir specified for the CMS dataseries.
The first format (<? READFILE varname > ) will look for the filename (with a name specified in varname) in the FileDir directory. If it is not there, an empty string is returned. If it is there, the contents of this file are written to the output file.
The second format (<? READFILE filename.ext > ) will look for the filename
with the name fileame.ext -- note that you must include a period!
If no such file exists, an empty string is returned.
If filename.ext contains no path information, look in the FileDir.
The third format can be used to specify a different directory, and to save the contents to a variable (rather then immediately write the contents to the output file).
The case-insensitive options are:
name=vfame | This is either the variable containing the name of the file to read; or the relative or fully qualified filename (to specify a filename, include a period in vfname) |
save=uvarname | If specified, CMS will store the contents of the file to the uvarname user-defined variable. You can then use SHOW to write these contents to the output file; perhaps after first modifying them with SET. |
dir=dirname | dirname will be used as the base-directory for the filename (specified in varname). That is, dirname will be used instead of the FileDir. |
NoDisplay=1 | If NoDisplay=1 is used, then nothing will be written to the output file. Otherwise, the contents will be written to the output file. |
Notes |
|
---|
Examples |
<? READFILE resume > <? READFILE name=oldresume save=oldstuff dir=archive\old nodisplay=1 > |
Where option is one of the following
AGE=ddd | Use records entered within the last ddd days (ddd can
be fractional, so that AGE=0.5 means "last 12 hours")
Example: <?Repeat age=7 > |
DATERANGE=d1-d2 | Use records entered between date d1 and date d2 Format of d1 and d2 is yyyymmdd:hr:min where hr:min are optional (leave them out to mean anytime within this date) Example: <?Repeat daterange=20030925:10:00-20030926:13:30 > |
ID = an_id | Just process the record with an ID equal to "an_id". Reminder: CMS ids all have the form dddd.ffff; where dddd refers to the day, and ffff to the fraction of a day. Example: <?Repeat ID=5017.09565973>
|
RANGE=n1-n2 | Use record numbers n1 to n2 (inclusive)
Example: <?Repeat range=100-199 >
|
If you want to include a HTML comment in the output file, you can use:
<!-- My comment -->
Or, for long comments that may include HTML elements (or CMS elements):
<? !-- > My long comment <? -- >
NAME | data series name |
---|---|
CREATION | creation date |
MODIFIED | last modified |
RECORDS | current number of records |
DESC | description |
VARS | variables in this CMS dataseries |
SORTABLE | "sortable" variables in this CMS dataseries |
Syntax: one of the following ...:
<? SET expression>
where expression should have the form:
Examples: | <? SET section="Introduction" > <? SET page=102 > <? Set Cnt1 > <? Set where1=pos('1',numbers) > <? Set midwords=subword(myreport2,20,10) > <? var name=report nodisplay=1 assign=tmp1> <? set tmp2=wordpos("Two",tmp1,,I)> Location of the word <tt>two</tt>: <? show tmp2> |
  | |
Notes: |
|
---|
Syntax:
SORT name=varname order=xx
where:
varname | : one of the "sortable" variables in the CMS dataseries |
xx | either A (ascending) or D (descending). Default is A. |
Examples: | <? Sort name=city order=A> <? REPEAT > Hello to <? var name=customer> from <? var name=city> <? /repeat>or, a little more fancy: <? Sort name=city order=A> <? REPEAT > <? if city ne >Customers from <? var city ><br> <? /if> Hello to <? var name=customer> <br> <? /repeat> <? Sort name=!ID > |
User-defined variables are created (and modified) by the SET and INC keywords. They can also be set within CALLs (as stored in the INFO. stem).
System variables are general information. The currently available system variables are:
$TIME fmt: | current time |
$DATE fmt: | current date |
Examples: | <?Set Fruit="grapes"> <? Show fruit > <? Show !LOOP_S > <? Show $DATE > <? SHOW $TIME S > |
Notes: |
|
---|
Syntax: | <? SHRINK > lines of code including CMS elements <? /SHRINK > |
---|
This can be useful when you have a large block of CMS elements, such as a complicated set of CASE statements. CMS will output all the CRLFs, even though nothing on the lines containing the CRLFs (say, CASE statements that are not true) is used.
You can use SHRINK ... /SHRINK to get rid of this (possibly annoying) extraneous white space.
NAME | name of template file |
---|---|
FULLNAME | fully qualified name of template file |
DESC | description |
TR | -- a <TR ...> element (used in tables) |
TH | -- a <TH ...> element (used in tables) |
TD | -- a <TD ...> element (used in tables) |
|
?COLORS=$user_var
Note: any options following a ?TR, ?TD, or ?TH (and before the terminating >) that does not begin with ? are included in all TR elements (or TD or TH elements).
Thus,
<? TR ?colors=AAAAAA,929192 align="left">
means
where the following options can be used:
NAME=varname | Extract the value of the varname variable
(from the CMS dataseries). Or, extract some meta-data about the record (see below). |
||||||
FILENAME=varname and FILENAME_LOCAL=varname |
If the type of the varname variable is uploaded file (or a
uploaded web resource),
then:
Notes:
|
||||||
ASSIGN=user_defined_variable | Assign the value of the variable, after any var-function modifications, to a user defined variable (just like a user defined variable created with the SET keyword). | ||||||
NODISPLAY=1 | If NODISPLAY=1 is used, then nothing will be written to the output file. This is meant to be used with ASSIGN (so that you can assign a value, without writing anything). | ||||||
ID=record_id | Extract the value of VARNAME from the record with
an id of record_id.
Note that CMS record_ids all have the format: dddd.tttttttt, |
Examples: | <? VAR UserName > <? Var name=DOCUMENT_1 > <? Var filename=document_1 > <? Var name=subject_a assign=subject_ab > <? Var name=subword(subject_a,1,3) assign=subject_3words > <? var name=$Abstract id=5014.87653513 > |
---|
The currently supported meta-data items are:
TIME(tfmt) -- time of record creation DATE(dfmt) -- date of record creation STATUS(StatusVar[,dfmt,tfmt]) -- # of comments, last comment added time, modification time. StatusVar can be CMT_CNT, CMT_MOD, or MOD. Dfmt, and Tfmt (which are optional) are time and date display formats (see the appendix for a description of the time and date display formats).
Examples: | <?Var time() > <?VAR name=date(u) id=5012.89388889 > <?VAR status(CMT_CNT) > <? VAR status(CMT_MOD,N,C) > |
---|
The currently supported var-functions are:
(varname) -- returns the value of varname. This is used in SET: i.e.; ?SET myvar_copy=(my_var) DATETIME(fmt,varname) -- day, year, or other format of the datetime value. Varname should be !ID, or one of the CMS datetime type of variables For the details, see the description of DATETIME in the If-functions appendix. HTML_REMOVE(varname) -- encode special HTML characters (i.e.; < betcomes <) HTML_REMOVE(varname,DROP) -- remove HTML elements (stuff between < and >) HTML_MAKE(varname) -- convert text into HTML friendly text. This entails adding <P> (to replace blank lines), adding <A href=".." > elements whenever a URL is detected (a word with more then one period), and adding characters when tabs (or leading spaces) are found. INC(varname) -- increment a variable. If varname is not-numeric, return '' Note: for more complicated math, you can use the MATH CMS procedure. LENGTH(varname) -- length (in characters) of varname LINES(varname) -- # of lines in this varname (crlf delimited) POS(substring,varname,[iat],[i]) -- position of substring within varname. Optional offset of iat (default of 1). If I specified, case insensitive search. If no match, returns 0. SUBSTR(varname,iat,ilen) -- substring, starting at character #iat, with ilen characters, extracted from varname. SUBWORD(varname,iat,ilen) -- substring, starting at word # iat, with ilen words, extracted from varname. Note that prior to extraction, all CRLFs and TABS are converted to spaces (so the returned result will NOT have CRLFs or TABS). SUBLINE(varname,iat,ilen) -- substring, starting at line # iat, with ilen lines. CRLFs and TABS are not removed! WORDS(varname) -- length (in words) of varname (space, CRLF, and TAB are word delimiters) WORDPOS(aword,varname,[iat],[i]) -- word position of aword within varname. Optional offset of iat words (default of 1). If I specified, case insensitive search. If no match, returns 0. Space, CRLF, and TAB are word delimiters.
Notes: |
|
---|---|
Examples: | <?Var length(report) > <?Var wordpos("dog",pets,,I) > |
Note that these formats are also used in <? SHOW $DATE fmt>.
The FMTs basically follow the syntax of the REXX DATE function (with the addition of the 'WN', 'WB', 'WB2', 'Y', and 'J' options). Note: the default is N
Option Desc Example ==== ===== ======= B basedate: 729627 D day (of year): 240 E European: 27/08/98 J basedate 1/1/80: 3160 L local-version: 27 August 1998 (this may vary across nations) M month: August N Normal: 27 Aug 1998 (this is the default) O Ordered: 98/08/27 S Sorted: 19980827 U USA: 08/27/98 W Day of Week: Saturday WN Week number: 451 (week, since Sunday, 1/6/90) WB Week bounds: 23 Aug 1998 to 29 Aug 1998 (Sunday to Saturday of this day's week) WB2 Week bounds, US: 08/23/98-08/29/98 (Sunday to Saturday of this day's week) Y Year 1998Examples:
<? var date(B) > <? VAR DATE() > <? var date(WB2> <? Show date M>
The FMT specifies how the date will be displayed.
Note that these formats are also used in <? SHOW $TIME fmt>.
Basically, they follow the syntax of the REXX TIME function (with the addition of the 'F' option). Note: the default is N.
Option Desc Example ==== ===== ======= L long 16:54:22.120000 H hour 16 M minutes 1014 (54 + 60*16) S second 60862 (22 + 60*(54+60*16) N normal 16:54:22 (the default) C civil 4:54pm F fraction 0.70442130 (*86400=seconds)Examples:
<? Var time(c) > <? Show time L>
The DFMT and TFMT formats are used with CMT_MOD and MOD. They control how the date
and time will be displayed (seperated by a space).
DFMT and TFMT take the format codes listed above. The default
is N (for both date and time).
In addition, a "0" format is supported -- it means don't display" (either the date or the time).
Examples:
<? var status(cmt_cnt) > <? var status(MOD) > <? var status(CMT_MOD,D,S) > <? var status(MOD,N,0) >
!SERIES : the name of this CMS dataseries
!ARG : the argument (entered by the client from the Generate output files form).
and several that only are used inside of REPEAT blocks
!ID : the id of the current record !LOOP_S : record number of first record examined (by default, 1) !LOOP_E : record number of last record examined !CURRENT : current record number (between LOOP_S and LOOP_E) Example: <? If !CURRENT eq !LOOP_E > This is the last record! </if> !DEFFILE: Name (no path) of the ".DEF" file used to define the current dataseries. This is useable by CALLable procedures. !NUMREC : total number of records (often the same as LOOP_E) !FILE_VARS : list of CMS dataseries variables that are of FILE type. !COUNT : number of records processed (including current record). If a DROP option is used with ITER or LEAVE, then the record is NOT considered to be processed. Otherwise, the record is considered to be processed, even if nothing was actually written to the output file. Example: <!-- display only females --> <? REPEAT > <? If SEX="MALE" > <? Comment If here, MALE entry. So skip it > <? ITER DROP > <? /IF > <? SHOW !COUNT >: Hello <? Var name > <? /REPEAT> This will produce a consecutively numbered list of FEMALE records, with interleaved MALE records ignored. Notes: * the count is maintained across the entire output file. That is, it is not reset when a second, third, or later REPEAT block is processed. !COUNT_BLOCK This is the same as !COUNT, but only for records written within this REPEAT block (it is reset to 0 for each REPEAT block).
Example: | <? repeat > <? REM update or create comments, based on argument string > <? if !arg="UPDATE"> <? Comment ?output=f:\www\blogs\comments\T1$CMT_*.HTML ?url=/blogs/comments/ ?quiet=1 ?mode=update > <? /if> <? if !arg="CREATE"> <? Comment ?output=f:\www\blogs\comments\T1$CMT_*.HTML ?url=/blogs/comments/ ?quiet=1 ?mode=create > <? /if> <? /repeat > |
Note that these special variables can also be used in CALLed procedures.
Examples |
|
COUNT(nth,[B]) -- the "nth" group of the !COUNT or !COUNT_BLOCK counters. nth is an integer number greater than 0. B is optional. If present, then work with the !COUNT_BLOCK counter. Otherwise, work with the !COUNT counter. The COUNT "meta-data" function will return what "group of n" the counter's value lies within. For example, for the !COUNT value ..... COUNT(3) yields 1 1 2 1 3 1 4 2 5 2 6 2 7 3 etc. DATETIME(opt) -- information about the date and time of entry or DATETIME(opt,varname) -- information about the varname variable (varname should be a "datetime" type of CMS-variable) or DATETIME(opt,"") -- information about the current date and time or DATETIME(opt,"date time") -- information about the current "normal" date and time. "Date time" format should either be: Normal; eg. "03 Jun 2004 16:31:03" or CMS-datetime; eg. 5020.4389 Opt can be: (examples) N = normal (30 Sep 2003 10:32). This is the default. N = normal long (30 September 2003 10:32) Y = year (2003) MO = month (200309) MO_Y = month within year (9) MO_80 = month since 1 Jan 1980 (285) W = week (717 -- week since Sunday, 5 jan 1980) W_Y = week within year (39) W_80 = same as W (717) W_IS = the date of the sunday of this week (28 Sep 2003) D = day (20030930) D_Y = day within year (273) D_M = day within month (30) D_80 = day since 1 Jan 1980 (8672) H = hour (20030930:10) H_D = hour within day (10) MI = minute (20030930:0623) MI_D = minute within day (623) MI_H = minute within hour (32) S = second (20030930:37388) S_D = second within day (37388) S_M = second within minute (32) CMS = cms-format datestamp (5020.43890046) Notes: * in the H, M, and S outputs, the stuff after the ":" will be left-padded with zeros if necessary. * if opt is not specified, N is used * use the *_80 functions if you want to compare (or do math) on dates * M, M_Y, and M_80 are synonymous with MO, MO_Y, and MO_80 (respectively) FILE_EXISTS(varname) If varname is of File type, check to see if a file was actually uploaded, and still exists. If so, return the fully qualified filename. If not, return a "" If varname is not of File type, return a "". Thus, to check if there is a file available (say, for use in a ?A URL_FILE=varname), use FILE_EXISTS in an ?IF, and check for ne "" . LENGTH(varname) The length, in bytes, of the varname. If varname is of File type, the length of the uploaded file (or downloaded URL). LINE(varname) The length, in lines, of the varname. If varname is of File type, the length of the uploaded file (or downloaded URL). Note that files are delimited by CRLF ('0d0a'x). POS(substring,varname,[istart],[I]) Position of substring inside of a string. Similar to the REXX POS function. varname is a cms variable. It's value will be searched. substring can be within " " characters. Note: Sorry, but substring must NOT contain spaces, commas or, = signs. istart is optional -- if specified, start the search at the istart'th character (of varname's value). I is optional. If specified, case insensitive search. If no match occurs, a 0 is returned. Examples: if the PRODUCT variable has a value of "Summer squirt Gun" Then pos("squirt",product) -- returns 8 pos("quirt",product) -- returns 9 pos("SQUIRT",product) -- returns 0 pos("gun",product) -- returns 0 pos("gun",product,,I) -- returns 15 pos("s",product,3,I) -- returns 8 STATUS(opt[,dfmt,tfmt]) STATUS, as with its use in a VAR element, extracts status information on the current record. Three options are currently supported: i) CMT_CNT : The number of comments associated with this record ii) CMT_MOD : Time the most recent comment was added iii) MOD : Time the record was last modified. Note that CMT_MOD and MOD both can take a "date format" and a "time format" (dfmt and tfmt respectively). SUBSTR(varname,[istart],[ilen]) Extracts ilen characters from varname, starting at character istart.
Examples: 123456789a123456789a1 if the PRODUCT variable has a value of "ABC = 5567 : candle" Then (without the "s). substr(product,1,3) -- returns "ABC" substr(product,10) -- returns "67 : candle" substr(product,8,2) -- returns "55" SUBWORD(varname,[istart],[ilen]) Extracts ilen words from varname, starting at word istart.
- Before extraction, all CRLFs and TABs are converted to spaces (so that tabs and CRLFs become valid word delimiters). Hence, the returned result will NOT have CRLFs or TABs.
- varname is a cms variable name. It's value is used as the string (from which a substring will be extracted).
- istart is the starting position (first word is 1). The default value is 1.
- ilen is the length of the substring. If not specified, all remaining words (after istart) will be extracted.
- Similar to the REXX SUBWORD function.
SUBLINE(varname,[istart],[ilen]) Extracts ilen lines from varname, starting at line istart.WORDPOS(subword,varname,[istart],[I]) Position of subword, inside a string containing multiple words. Similar to pos, except a "word" search is done. SImilar to the REXX WORDPOS function. See POS for the description of istart and I. Note: Sorry, but subword must NOT contain spaces, commas, or = signs. The word position (not character position) is returned. As with POS, 0 is returned if there is no word match. Examples if the PRODUCT variable has a value of "Summer squirt Gun squirt" Then pos("squirt",product) -- returns 2 pos("quirt",product) -- returns 0 pos("SQUIRT",product) -- returns 0 pos("SQUIRT",product,3,I) -- returns 4 pos("gun",product) -- returns 0 pos("gun",product,,I) -- returns 3 pos("s",product,,I) -- returns 0
- The extracted string will have CRLFs and TABS.
- varname is a cms variable name. It's value is used as the string (from which a substring will be extracted).
- istart is the starting position (first word is 1). The default value is 1.
- ilen is the length of the substring. If not specified, all remaining words (after istart) will be extracted.
The OWNERS field is used to limit access to one, or several, users. To do this, enter a space delimited list of "usernames", where "usernames" are defined by the SREhttp/2 username/password/privilege utilties.
Or, enter * to allow access to any client with a valid username for this site.
If you define such a list, then before any CMS action is done to this dataseries (such as generating an output file), CMS will check that the client has a valid username (has been granted a username and password for this site).
If this username does not exist, the user will be sent an authorization request. He can keep trying until he gets it right (in other words, there is only minimal security).
In addition to the OWNERS list, CMS supports a OWNERS_COMMENT list. The OWNERS_COMMENT list works just like OWNERS, but is used only when comments are being added to a CMS record. The notion is that you may want control who can add and manipulate records in your database, but you will let anyone add comments to these records. Using OWNERS (say, with a list of usernames), and a less stringeng OWNERS_COMMENT (say, leave it blank or use *), you can do this.
ARCHIVE makes this easy -- just specify a general rule to use in determining how to create these subsets, and CMS will do the rest -- including creating a list of links to these documents!
There are basically two kinds of archive documents:
For subset archives: | <? Archive option=value option=value ..> |
For singleton archives: | <? Archive option=value option=value ..> link-string <? /ARCHIVE> |
FILE = template_file TYPE = nnn|HOUR|DAY|WEEK|WEEK2|MONTH|MONTH2|YEAR|SORT LIST = ul|ol|table|ulA|olA|tableA OUTPUT = output_file_pattern UPDATE = 0|1|AUTO URL = base_url MESSAGE = "a message" #FIELD = "field contents"Note that FIELD in #FIELD can be any field name.
FILE=template_file The template_file should be a file containing CMS elements. It will be used to determine how to display the subset of records. Template_file, if not fully specified, is relative to the current template file. Note that the template file can contain a SORT element -- which will cause a sorting of the subset of records within a given archive document (say, a descending sort of the records in a week). TYPE=one of the various types: nnn|HOUR|DAY|WEEK|WEEK2|MONTH|MONTH2|YEAR|SORT TYPE is used to specify how to divide all the records in the dataseries into "subsets". == If you are creating a singleton (by specifying ARCHIVE == inside of a REPEAT block), TYPE is ignored. nnn, where nnn is a number > 0 Create subsets, with each one containing nnn records. Before dividing into subsets, CMS will sort the records in order of entry (by entry time). The first subset starts with the earliest entry. Thus, the last subset will frequently contain less than nnn records. hour Include records entered in the same hour (where hours change across days). Note that this does NOT mean the creation of one document per hour (with lots of documents having no records). day and day2 Include records entered in the same day day2 leads to a more compact list of entries then day. week and week2 Include records entered in the same week (Sunday to Saturday). week2 leads to a more compact list of entries then week. month and month2 Include records entered in the same calendar month (Jan, Feb,...). month2 leads to a more compact list of entries then month. year Include records entered in the same calendar year (2003, 2004, ...). sort The SORT type means "by value of current sort variable" If no sort variable currently selected, use of SORT yields an error/ You can specify the SORT variable either when you invoke CMS, or by including a <? SORT ..> element before the <? ARCHIVE ..> element. Note that a <? SORT element > overrides the SORT variable chosen at invocation. For all of the types, NO observations are de-selected (all records in the dataseries will be available in one, and only one, of the archive documents). Of course, if the template has additional logic in it (such as IF statements), it is possible that a record "available" to an archive document will not be displayed. list List specifies how to create the links to the archive files. UL and OL are HTML bulleted lists. == If you are creating a singleton (by specifying ARCHIVE == inside of a REPEAT block), LIST is ignored. TABLE is an HTML table ULA, OLA, and TABLEA are the same as above, except entries are displayed in "ascending" order (the top most bullet or row will point to the archive document with the oldest records). OUTPUT Output is used to specify the names of files used for the several archive documents. The output_file_pattern must either: i) contain a * (the * will be replaced by a number). ii) be $varname, where varname is an existing CMS dataseries, or user-defined variable. THIS CAN ONLY BE USED WITH SINGLETON ARCHIVES. iii) Not be specified. If not specified, a suitable modification of the current output file will be used. If specified, and relative, a file relative to the default output directory will be created (or to the CMS\FILES directory, if no default output directory is defined for this dataseries). For example: if * the output directory is F:\WWW\BLOG * you specify OUTPUT="*.SHT" then F:\WWW\BLOG\_4Nov2003.SHT could be a name of a "daily" archive file. Or, if there is NAME CMS variable with a value of Joe_Bloe <? call concat useme="f:\www\archives\" $+ name $+".SHT" > <? archive file=single.tpl url="/ARCHIVES/" output=$useme> <? var name><? /archive> then F:\WWW\ARCHIVES\JOE_BLOE.SHT would be the name used for a "singleton" archive. UPDATE If UPDATE=AUTO, or if UPDATE is not specified, then UPDATE is set by whether the the client checked the Only update (the latest archives & possibly comments) checkbox (when he generates the output file). Thus: If UPDATE=1, then UPDATE=1 If UPDATE=0, then UPDATE=0 If UPDATE=AUTO or if UPDATE is not specified, then UPDATE=1 if the box is checked otherwise UPDATE=0 The effect of UPDATE depends on whether you are creating subsets or singletons. Subsets: If UPDATE=1, or if UPDATE is not specified, then update files that have changed, and update the most-recent archive (i.e.; the archive for this month). Note: the "most recent" archive will always be re-written, even if nothing has changed. If UDPATE=0, then create all archives (if necessary, overwriting any pre-existing files). Singletons: If UPDATE=1, or is not specified then only create singleton archives if no singleton archive file exists for this record, or if the record has changed since its singleton archive was created. If UPDATE=0, write singleton archive files for all records (overwriting pre-existing records if necessary). URL A "base_url" that will be used in the list of links to the archive documents. Each of the filenames (of the files created using the OUTPUT option) will be appended to this "base url". Obviously, the result (base_url + filename) should be a valid url to the document The base_url can either be a string (without quotes), or can be a variable name (either user defined or dataseries). To specify a variable name, use a $ before the base_url. Examples: url=/people/results url=$my_dir Thus, you should use a OUTPUT option that writes the archive documents to a subdirectory that is web-accessible (using the base_url), or you should be sure not to forget to move them to this web-accessible directory (after CMS finishes running). MESSAGE A text sentence that can be accessed (within the archive template file) by using <? SHOW !ARG > or <? SHOW !MESSAGE > Note: you can use <? TEMPLATE DESC >, or <? SHOW !DESC > to display a short description of the "subset" of the recores. For example, "November 2003". Note: you can use r <? SHOW !ARCHIVE_TITLE > to both the "message" and the "description" For example, "The blog monthly archives: November 2003". #FIELD FIELD can be any field name. After removing the leading # character, it will be included as is in the <A ... > links created by ARCHIVE. For example: #Target="ae_window" Note: In the LINK, COMMENT, and A elements, options that start with a ? are processed by CMS, while all other options are used as is. In contrast, in ARCHIVE options that start with a # are used as is, while other options are either processed by CMS, or ignored. And yes, the fact that ARCHIVE is different then these other elements really can not be called a residue of good design. But at this point it's hard to rectify.
<? archive file=arc1.tpl type=DAY message="A daily archive" list=UL url="/BLOGS/" output=f:\www\blogs\*.sht update=1 #target="windowA" >Could yield the following list written to your output file:
<UL> <li><a href="BLOGS/_4Nov2003.SHT" target="windowA" > 4 Nov 2003</a> <li><a href="BLOGS/_6Nov2003.SHT" target="windowA" > 6 Nov 2003</a> </ul>where each of these files (i.e.; _4Nov2003.SHT) will be in the F:\WWW\BLOGS directory.
Hint: |
If arc1.tpl (which will be in the same directory as the template file
containing this <? ARCHIVE ...> element) contains: This is <? show !arg> [ <? template desc > ] then the archive documents will contain lines like... This is A daily archive [6 Nov 2003 ] (the 6 Nov 2003 will vary across the different documents). |
---|
<? archive file=arc1.tpl message="A weekly archive" url="/BLOGS/RECS/" output=f:\www\blogs\recs\rec1$*.html update=1 >Just this record<? /archive>This will yield a seperate file for EVERY record. If you have a lot or records, this might take a while to process. Note that by using update=1 (the default), CMS will not attempt to overwrite files that have been already created for this record -- which can save processing time.
Note: |
When creating singleton archives...
you must follow the <? ARCHIVE ..> with a link string
and a <? /ARCHIVE>
(the link string is what the browser displays, and <? /ARCHIVE> is replaced by </A>). |
---|
COMMENT is similar to ARCHIVE -- you specify a general rule to use in determining how to create these comment documents, and CMS will do the rest -- including creating links to these documents!
Note that as of this implementation, COMMENT can only be used inside of a REPEAT block.
Syntax:
<? COMMENT option=value option=value ..> link-string <? /COMMENT>
The important options are:
?FILE=template_file ?OUTPUT=output_file_pattern ?URL=base_url ?MODE=UPDATE|CREATE|AUTO|SHOW|ADD ?RETAIN=varname ?RESPFILE=response_file_name ?QUIET=0|1The link-string is any string -- it is what the browser will display. The <? /COMMENT > will be converted to a </A>.
Note: if ?QUIET=1, then do NOT include the "link-string <? /COMMENT>"
Other options, that do not start with a ?, can also be included -- these will be inserted verbatim into the <A..> elements inserted into the output file.
OUTPUT, URL, and FILE are the same as in ARCHIVE
Notes: |
---|
UPDATE : update comment files. Thus, if a comment file (for this record) exists, and no new comments have been added (for this record) since this file was created, then do NOT (re)create the comment file (for this record). Technical note: this works by comparing the file's datestamp with the datestamps of the comments. If you modify the file (say, with a text editor), the datestamp will be updated; which may inappropriately indicate that the file does not need to be updated. Thus, if are likely to hand-edit comment-files, you probably should not use UPDATE. CREATE: always create a comment file, even if one currently exists. AUTO: Use either UPDATE or CREATE, depending on whether the user checked the Only update (the latest archives & possibly comments) checkbox. If checked: UPDATE mode. Otherwise: CREATE mode. NAME: Return the name of the comment document, constructed using the file name and the URL. This will NOT create the comment file, it just returns the name that is used. SHOW: Create a link to the comment file for the current record. Basically, SHOW uses NAME to create a link. ADD: create a link to the "add comments" CMS input form. This lets you put a "would you like to add a comment" link in your output file. URL and OUTPUT are ignored. FILE can point to a "comments template file", and RESPFILE can point to a response file. Both of these are located either in the LIB subdirectory of the CMS directory, or in the FileDIR specifed for this series (a FileDIR version takes precedence). Interested in more details on working with CMS customizable forms?
Example: in the comment's template file, you can use this to extract these values just once:
<? repeat range=1-1> # of comments<? var status(CMT_CNT) > Record abstract: <? var $abstract> <? /repeat> <? repeat > Comment ID and sender's name <? Var !ID > <? var name> <? /repeat >
Examples: |
|
<? Comment ?file=do_cmt.tpl ?output=d:\www\blog\comments\cm*.htm ?retain=keywords ?mode=update ?quiet=1 >This will create comment-documents (1 for each article in the CMS dataseries).
<? Comment target="j_cmt" ?file=do_cmt.tpl ?url=/comments/ ?output=d:\www\blog\comments\cm*.htm ?retain=keywords ?mode=auto > View comments <? /comment >Similar to above.
<? Comment ?output=d:\www\blog\comments\cm*.htm ?url=/comments/ ?mode=name >
<? Comment ?output=d:\www\danielh\blog\jokes\comments\cm*.htm ?url=/jokes/comments/ ?mode=show > View the comments <? /comment>
A useful trick: |
|
---|
Creating your own, custom-designed, pre-defined blog template is fairly straightforward. These are specifying using xxx.DEF files. These .DEF files contain instructions on how to create the blog from a set of pre-defined template files, response files, and other such files. Of course, it is your responsibility to create these other pre-defined files.
Both the .DEF file, and the other pre-defined files, must be stored in the LIB\PREDEF subdirectory of your CMS directory (say, in D:\SRE2003\SREHTTP2\ADDON\CMS\PREDEF.
For details on how the specific of .DEF files, see BLOG1.DEF in this CMS\PREDEF directory.
The .SDS files are stored in the DATA subdirectory of the CMS directory. These are structured text files. They can be viewed with a text editor, but they should NOT be modified!
In addition, CMS uses "index" files to store meta-data on the data series, such as names of variables and the location of the upload directory (to use for this data series). These index files, which are located in the INDEX subdirectory of the CMS directory, are simple text files.
If you are careful and ambitious, you can modify these index files using a text editor.
The following is a sample of an index file:
; CMS index file created 19:31:53 26 Oct 2003 Series: t6 File: F:\test\srehttp2\ADDON\CMS\DATA\t6 CommentFile: F:\test\srehttp2\ADDON\CMS\DATA\t6_CMT Created: 19:31:53 26 Oct 2003 Desc: Job applicants Owners: me OwnersComment: VarNames: $STATUS $ABSTRACT NAME AGE EDUCATION SYNOPSIS RESUME REJECT RANK VarTypes: N A 1 N S M F C P Pack: NAME SYNOPSIS RESUME REJECT Specials: $ABSTRACT $CMT_CNT AGE EDUCATION POLL Select: EDUCATION = education7; Poll: RANK = rank_choices ; FileDir: F:\test\srehttp2\ADDON\CMS\FILES UploadDir: F:\test\srehttp2\ADDON\CMS\UPLOADS Template: T6.OUT T6.TPL , THIS IS FOR T6 output file Template: Index.HTML I1.TPL , Use this for the main page Hint: Although the Abstract and Synopsis are similar,
Hint: keep qualitative statements in the synopsis
DATA: the CMS dataseries files (.SDS files) are stored here INDEX: the CMS "index" files (.IND files) are stored here LIB: .OPT files (for Select List variables) are stored here. In addition, this is the default location for "CALLable" CMS procedures LIB\POL: .POL files (poll-definitions) are stored here. UPLOADS: The default location for uploaded files (or uploaded contents of URLS). FILES: The default location for output files, archive files, and template files.Files in the LIB directory.
The .OPT files are used with Select-List variables nations.opt : List of nations months.opt : 12 months of the year education7.opt : Seven education levels (no HS to phd) states.opt : List of 51 states (DC included) Income_levels.OPT : Several income levels yes_no.OPT : A YES / NO list sex.OPT : A Male / Female list The .CMS files are "CALLable" CMS procedures example.cms : Simple example of a CALLable CMS procedure comment1.cms : Create a FORM to use to add comments to a record cms_cmt.htm : An example of a "comment" template file (used with ?COMMENT ?MODE=ADD) Example files (in CMS directories):INDEX\DEFAULT_exampl_001.DEF : the "definition" file for the EXAMPLE dataseries DATA\EXAMPLE.SDS : the main database for the EXAMPLE dataseries DATA\EXAMPLE_CMT.SDS : the "comments" database for the EXAMPLE dataseries DATA\*.SDI : index files for the above .SDS files FILES\*.TPL : several template files used to generate files from the EXAMPLE dataseries You can look at, and modify, these .TPL files with your favorite text editor
Would you like to read about the CALL CMS_element?
CMS customizable forms are used to customize the pages shown to clients interested/allowed
to enter new records and comments.
Would you like to read more about customizable forms?
To implement these SELECT variables, a .OPT file must be specified. These .OPT files contain a list of the selections to be included in the drop-down list. The syntax of these files is fairly simple: Each selection list will variable typically contain a unique set of choices (for example, the nations of the world, or gender information)
Example of an option file.; DESC= income levels, roughly us quintiles ;Created 4 Oct 2003 08:50:33 1 = < 10,000 2 = 10,000-25,000 3 = 25,000-50,000 4 = 50,000-75,000 5 = 75,000-125,000 6 = >125,000 $ = user entered value |
which would create...
|
POLL variables are qualitiatively different from other CMS-database variables:
To implement these POL variables, a .POL file must be specified. These .POL files contain a list of the choices to be chosen from, as well as instructions on how to construce the the questionaire (within which the choices are embedded).
For example ...use the information in a .POL file to construct a questionaire. - The POLL keyword, and the
- The CMS add-record option
Example of a poll file.; this is an example of a poll definition file ; DESC = Vote on how interesting. ?: How would you rate this article? 1: Uninteresting 2: Mildly interesting 3: Interesting 4: Uninteresting Footer: <tt>(your answer is anonymous)</tt> Footer: <p><em>Thanks for your input</em> SOutput: SvyOut.1 SFormat: _ID : _POLL _DATETIME REGION color: yellow |
which would create...
|
In a sense, POLL allows a quick means of recording comments about an article (albeit in an aggregated format).
To extend the capabilities of POLL, you can use several SURVEY options. Basically, these allow you to save the responses to the poll, along with a number of other varibles, to a specified survey-output file. As of this writing, CMS will not attempt to analyze this output file. However, you can structure the output file (which will be written as a simple text file) so it can be read by spreadsheet or statistical packages.
The relevant options are SOutput and SFormat (specified in the poll-definition file), and Form (an option of <? POLL AUTO=ASK ... > CMS-elements).
This file will always be written to the POLLS subdirectory of the series-specific output directory.
If you do not specify SOutput, CMS will not attempt to save responses (where would it put them?).Note that all data for a single response is written to a single line of the SOutput file.
Example: | SOutput: survey_voters.out |
SFormat uses a very flexible format. Basically, you should specify a line that contains formatting elements (including spaces, commas, and notes) and variable names. CMS will replace these variable names with the response-specific values (corresponding to these variable names).
Example: | SFormat: _ID _VAR _DATETIME : _POLL City VCITY Age VAGE |
The variable names, whose values are to be written to SOutput, are specified in this survey questionaire file, using standard HTML-form elements.
Example: | <? POLL auto=ASK form=svyform.htm var=election target=win1>Fill out a survey <? /poll> |
In addition to variables explicitily specified in the FORMsurvey questionaire file, several other variables will be looked for:
Example: | Assume that...
|
This survey questionaire file should contain descriptive text; and input, textarea, and other such elements supported by HTML forms. It should not contain the FORM, BODY, or HEAD HTML elements.
There is one special element that CMS will check for:
<!--_POLL-->
You must use this exact syntax: capitalize _POLL, and have no spaces between both the
-- and the _POLL
This element will be replaced by the poll questionaire.
Instead of <!--_POLL-->, you can specify your own custom-design form elements (such as a selection box) to ask the client to choose a poll choice. This custom-design must use _POLL as the NAME.
Example: | <Select name="_POLL"> <Option value="1">Dislike <Option value="10">Okay <Option value="50">Good <Option value="100">Great </Select"> |