Web
Crossing Server-side JavaScript
Creating
users and setting user properties
Introduction
About setUserProperties
A Sample Data File
The JavaScript Source
Testing setUserProperties
How it Works
Where to Go from Here
Troubleshooting
Resources
Introduction
In the
previous section, we learned more
about Web Crossing objects, and how they can be used in Web Crossing's
server-side JavaScript (WCJS). We saw there are objects for all
of Web Crossing's basic data types, including folders, discussions,
links, chat rooms, messages and users. We also learned how to
open a user object, check properties of a user object and add/change
a user's properties.
In this
section we will look at a small, but very powerful and flexible
example function called setUserProperties that reads data
from a comma-delimited file (for example, a Microsoft Excel .csv
file) containing a list of users, property names and property
values and accomplishes the following tasks:
- Register
new users
- Set
standard user properties
- Add
new user properties
- Change
the user properties for existing members
Using
setUserProperties you can maintain a database of your users
and properties off-line and make and change properties conveniently.
About
setUserProperties
Caution:
The setUserProperties function is provided here
as a learning example. Because it is a small example,
safety features (such as validation of correctly formatted
data) have been left out. This function can overwrite
the existing property values of current users, including
passwords, and can be used to add new users to your system.
Please use this function entirely at your own risk. Until
you understand how the function works, it is strongly
recommended that you experiment first with a test server,
rather than with your main production server. A backup
of your Web Crossing server before using setUserProperties
on your production server is also strongly recommended.
|
To use
setUserProperties, you must first create a comma-delimited
text file containing the data you wish to set. Microsoft Excel
.csv files are convenient for creating your data file, although
any ordinary text editor may be used.
The format
of the comma-delimited file is as follows:
- 1st
row: This row is used for comments. It is input and then discarded.
So you can put anything you want in the first row.
- 2nd
row: This row contains the property names (userName, address,
userEmail, etc.).
The first column will be used as userName
data regardless of the name you give to the property in the
first column, so
be sure that rows 3 onward contain only userName data in the
first column.
The rest of the columns in row 2 can contain any number of user
property names in any order. If the property name is not a standard
one (such as userEmail) then a new property with the
specified name (such as phoneNumber) will automatically
be created.
- 3rd
row through the last row: The rest of the rows contain the actual
property data.
When
setUserProperties is invoked, the data is input, and the
userName is looked up in the Web Crossing database to see
if that user exists or not. If no user exists with the specified
name, the user is automatically created.
The specified
user's properties are then updated (overwritten) or created, as
needed. Already-existing properties in the Web Crossing database
which are not specified in the data file are left unchanged. In
other words, you don't have to create a data file containing all
the user properties - just those you want to change or create.
Let's
try the function to see it in action before we explain how it
works.
Sample
Data
Here
is some sample data you can use for testing. Create a file with
the filename students.csv and enter the following data
in it:
this file registers new users for Big U University
studentID,userType,fullName,sex,userEmail,dataCreated,userPassword
kobayashi,3,Kobayashi Hiroichi,1,koba@bigu.ac.jp,2000/09/03,iggi
kurata,3,Kurata Masao,1,kurata@bigu.ac.jp,2000/09/03,agga
matsumoto,3,Matsumoto Eriko,2,matsumoto@bigu.ac.jp,2000/09/03,oggo
yokozawa,3,Yokozawa Nobuo,1,yokozawa@bigu.ac.jp,2000/09/03,umma
The studentID
property name is ignored because it is the property name in the
first column. The data in the first column always becomes
userName (the Web Crossing user name).
The properties
userType, fullName, sex, and dataCreated
are custom property names.
The properties
userEmail and userPassword are standard property
names.
The
JavaScript Source
Next
create a file called setuserproperties.tpl and input the
following WCJS function into the file:
%% command setUserProperties() {
var dataFile = form.data;
if (wctlEval('"' + dataFile + '"' + '.fileExists') !=1)
{ // file exists?
+ '(' + dataFile + ')' + " does not exist<BR>";
return;
}
+'<HTML><BODY BGCOLOR="#FFFFFF">';
var dataInput = wctlEval('"' + dataFile + '"' + '.fileRead()');
+ "data successfully read <P> " ;
var dataRecords = dataInput.split("\r");
var records = dataRecords.length;
+ records-2 + " records of data read <P>" ;
var propertiesList = dataRecords[1].split(",");
var nProperties = propertiesList.length;
for (var i=2; i<records; i++) { // start with row two
var record = dataRecords[i]Split(",");
var curUser = User.lookup(record[0]);
+ '<P>';
if (curUser == null) {
+ "User" + record[0] + " is not registered - Will
automatically register. <BR>";
curUser = new User(record[0]);
}
+ "User " + record[0] + " is registered.<BR>";
var confmsg = "User: " + record[0];
for (var j=1; j<nProperties; j++) {
curUser[propertiesList[j]] = record[j];
confmsg += " " + propertiesList[j] + ": "
+ record[j];
}
+ confmsg + "<BR>";
}
+ 'Done<BR>';
+ '<BODY></HTML>';
} %%
Testing
setUserProperties
To test
the setUserProperties function, move the files you created
(students.csv and setuserproperties.tpl) to your
webx directory, edit your webx.tpl file to include
setuserproperties.tpl and reset the file cache in the Control
Panel.
Note:
For details on editing your webx.tpl file and resetting
the file cache, see the section on JavaScript
functions.
|
Now you are ready to invoke the function using the following
special URL syntax:
http://yourdomain.com/webx?setUserProperties@@!data=students.csv
Just
replace the part of the URL highlighted
in red with your own domain and script name.
When
the function is invoked, the response page will report all the
users it created and the properties set for existing and new users.
How
it Works
Let's
look at setUserProperties in detail to see how this works.
%% command setUserProperties() {
First,
we define setUserProperties as a command (rather
than as a function) so we can invoke it from a URL.
var dataFile = form.data;
The
name of the datafile is stored in a local variable.
if (wctlEval('"' + dataFile
+ '"' + '.fileExists') !=1) { // file exists?
+ '(' + dataFile + ')' + " does not exist<BR>";
return;
}
WCJS
does not have its own file I/O functions, so we use the WCTL
fileExists command to check to make sure that the data
file we specified exists. If the file does not exist, we append
a suitable error message to the response page and immediately
return from the function.
You
can use WCTL expressions inside WCJS with the wctlEval
function.
The
// symbols indicate that the rest of the line is a comment.
+'<HTML><BODY BGCOLOR="#FFFFFF">';
If
the file exists, we append formal HTML tags to the response
page, so we can set the background color (and other page attributes
you might want to set).
var dataInput = wctlEval('"' + dataFile + '"' + '.fileRead()');
+ "data successfully read <P> " ;
We
again use a WCTL command - fileRead - to read the contents
of our comma-delimited file into the local variable dataInput.
This variable now contains the contents of our data file as
one character string.
var dataRecords = dataInput.split("\r");
We
use the JavaScript core method split to convert dataInput
into an array of records, using the linebreak characters in
each line of the data file as a record delimiter. This new array
is stored in the local variable dataRecords. WCJS supports
all JavaScript core methods.
var records = dataRecords.length;
Here
we use the JavaScript core method length to count the
number of records in the file we read in. We store this value
in the local variable records.
+ records-2 + " records of data read <P>" ;
Here
we append the number of data records we input to the response
page. The reason we report records-2 instead of records
is because the first two records contain the comment line and
the line of property names.
var propertiesList = dataRecords[1]Split(",");
We
again use split to create an array. This time we use
comma (,) as a delimiter and break up dataRecords[1]
(the first element of the dataRecords array) into an
array of property names. We store this array in the local variable
propertiesList. (Note that we didn't do anything at all
with dataRecords[0] because it just contains comments
that we don't intend to use anywhere.)
var nProperties = propertiesList.length;
We
use the core JavaScript method length to count the number
of properties and store this number in the local variable nProperties.
for (var i=2; i<records; i++)
{ // start with row two
Here
we begin a JavaScript for loop, going from record
2 (the first record with data) through record records-1,
the last data record.
var record = dataRecords[i]Split(",");
We
again use split (split is really convenient, as
you have noticed!) to split the current row of data into an
array of values. We store this array in the local variable record.
var curUser = User.lookup(record[0]);
OK.
Now we are really getting into the meat of the function. We
use the WCJS user object lookup method to return the
object for the user specified in record[0] (the data
that was in column 1 of your data file). If the user does not
exist, a null value is returned instead. The returned
value is stored in the local variable curUser.
+ '<P>';
Here
we are just starting a new paragraph in the response page.
If (curUser == null) {
+ "User" + record[0] + " is not registered - Will
automatically register. <BR>";
curUser = new User(record[0]);
}
We
check the value of curUser to see if it is null
(which it would be if the user does not already exist). If the
user does not exist, an appropriate message is sent to the response
page.
But
we don't just leave it at that. If the user does not exist we
just march right ahead and create the user!
To
do this, we use the built-in WCJS User constructor function
to create a new user object. As soon as this line is
executed a new user with the name specified in record[0]
is immediately added to the Web Crossing database. At this point,
the new user has no password or email address set - just a userName
and the usual default properties that all new users have.
+ "User " + record[0] +
" is registered.<BR>";
After
either registering the new user, or confirming that the user
already exists, we output an appropriate message to the response
page.
var confmsg = "User: " + record[0];
At
this point we start building a confirmation message in the local
variable confmsg. The confirmation message is output
after all the properties for this user are set. This message
will contain a list of all the properties set for this user
and their values.
For (var j=1; j<nProperties; j++) {
Loops
within loops! This for loop goes through the elements
of record one-by-one extracting the property value and
assigning the value to the property name specified in the corresponding
propertiesList array element.
curUser[propertiesList[j]] = record[j];
Here
we make the actual assignment of the value to the property.
JavaScript associative arrays are used to specify the property
name. That is, the value of properties[j] is the jth
property name.
If
the property already exists for this user, the value is overwritten
with the new value. If the property does not exist, it is created.
confmsg += " " + propertiesList[j]
+ ": " + record[j];
Here
we append the property name and value to the confirmation message.
}
This
parenthesis closes the innermost for loop - the loop
that sets the properties for the current user.
+ confmsg + "<BR>";
After
we are finished with the current user, we append the confirmation
message to the response page.
}
This
parenthesis closes the outermost for loop - the "user loop."
+ 'Done<BR>';
After
we are finished with the last user we append a "Done"
message to the response page.
+ '<BODY></HTML>';
} %%
Finally
we close the HTML tags for the response page and finish the
function definition.
Where
to Go from Here?
After
you feel comfortable with the introduction in these sections on
Web Crossing JavaScript, you will want to experiment with making
your own functions. Your first point of reference should be the
complete list of objects and properties in the online
sysop reference manual.
The potential
for using Web Crossing server-side JavaScript as a complete Internet
applications builder is really limitless. We envision projects
such as calendar systems sharing data between cooperating Web
Crossing servers (using XML-RPC protocol to exchange information),
the building of online, interactive, searchable database systems,
online shopping systems, online auction systems, interactive educational
systems and just about anything you can imagine creating for our
increasingly wired planet.
Troubleshooting
When
I tried setUserProperties it seemed to work for a few users,
but after that the data seemed to get input in a different order
than I expected.
- Look
at your data file: All "empty" values should be represented
by a single comma, as a space filler. Also, make sure that none
of your property values themselves contain commas!
When
I tried this with 600 users, only the first 400 were read in,
and then the function stopped. What can I do to read in large
numbers of users?
- In
Control Panel > General Settings,
increase the number in the Maximum while-loop iterations
per page field to a number larger than the number of users
you are trying to set.
Resources
Sysop
docs:
Recommended
book:
-
JavaScript - The Definitive Guide, 3rd Edition,
David Flanagan, O'Reilly
This book really is the definitive guide. It
is thorough, readable and answers all your questions about JavaScript.
It is an indispensable resource for any serious JavaScript programmer.
In fact, I won't even recommend any other books. Just get this
one!
Web
Crossing Tech Support Forum
Developer
Center
|