|
| ||||
So with our knowledge of cookies, we will tackle a typical example of a personalized channel. We will also need to draw on some information about forms, which are covered in detail in CHAPTER 7. Managing channel form submissions.
Suppose you were creating The Movie Review Channel, a (fictional) channel that provides new DVD, video, and theater reviews daily. It tends to be a lot of information and the reviews can be pretty long-winded. So it would be nice if you could pre-screen them and only present the ones the user is interested in. Maybe your reader is into action flicks. Or comedies. And maybe the idea of seeing a family-oriented kiddie film makes him break out in a rash.
What you would like is the ability for any user to customize his movie preferences through a form submission. He could go to a form, select the movie genres he prefers, and the next time he syncs, he would be presented with a list of movies that fit into one of those genres.
Here is the high level, birds-eye view of the process involved in creating this channel:
You create a cookie for the user that contains a the user's unique ID. You keep a database on your server that contains a list of every user, along with his genre preferences.
When the AvantGo sync server accesses The Movie Review Channel's front page, you would look up the cookie for the user (retrieved from the AvantGo sync server) to obtain his ID. You can use that ID to look up a list of his preferences and generate a custom list of movie reviews for him to read.
What if he wants to change his preferences? You can provide him with a form that allows him to check or uncheck his movie preferences. This form, once submitted, will alter his preferences stored on your database.
What if this is his first time visiting our channel? We can also determine that by a cookie; specifically, the lack of one. In that case, it is often a good idea to present your user with some default content, along with a prominent message telling him to customize his preferences.
Here are a couple of pages of the Movie Review Channel in action. Figure 6-6 shows the default list of movies that is displayed when user first visits the site, before a cookie has been set up.
Figure 6-7 shows a form on which a user can select custom categories that the user is interested in.
Figure 6-8 shows a standard form submission dialogue box, presented when user taps Submit. (we will improve on this later).
Figure 6-9 shows the customized Movie Channel home page, generated by using ID in cookie to look up user preferences in a database.
Now, hold on a sec. Assume I change my preferences and then sync this channel. At the moment I sync, I will be performing two activities at once. I am going to be submitting the form to change my preferences, but at the same time, I am also going to be grabbing the front page of my channel. How do I know the front page is going to be based on my new preferences instead of my old ones?
Good question. When a form is submitted through the AvantGo sync server, we make sure that all the forms have finished submitting information and all the actions called by those forms have run to completion before we start requesting any pages from that channel.
OK, so you know the basic strategy for approaching personalized channels. The next section takes a closer look at implementing the channel.
If you are comfortable using cookies and the strategy outlined above, you can safely skip the rest of this chapter and move on to the issue of managing the forms your channel users submit see CHAPTER 7. Managing channel form submissions. If you really want the nitty-gritty details of how to implement a personalized channel, read on.
But before we do, a couple of quick disclaimers. First, the Legal Notice of Liability:
The information in this document is distributed on an "As Is" basis, without warranty. While every precaution has been taken in the preparation of the tutorial, neither the author nor AvantGo shall have any liability to any person or entity with respect to loss or damage caused or alleged to be caused directly or indirectly by the instructions contained herein.
And on a more personal level, I would like to mention that the code examples you are about to see should be used as general guidelines only. While the channel works, it probably is not as efficient or as bulletproof as something you could write yourself. So feel free to look at what I have done here and follow the same processes for your channel, but do not reuse my code. I am sure you can do better starting from scratch.
All code was created with Perl 5.005 with the CGI and Perl can sometimes be a confusing language for those not familiar with it, but I tried to avoid some of the crazier idiomatic tricks. Hopefully, if you have some programming experience, you will be able to follow along.
I have created two databases here (they are both simple DBM files). One is a table of users. It contains a Unique ID number, the user's first name, followed by a list of 11 true or false values depending on whether the user likes that corresponding genre or not. Note that simple DBMs only allow one field per record, so my first name and 11 preferences are actually crammed into one large text string.
The other DBM file is a table of movies. It contains a Unique ID number, the name of the movie, followed by a list of 11 true or false values depending on whether the movie belongs in that genre or not. I created the table this way so that a movie can belong in more than one genre (For instance "GalaxyQuest" can be considered both Sci-Fi and Comedy.)
Note: In my current implementation described above, I have to be very careful in ensuring that all the lists of 11-true-or-false values are always in the correct order. Plus, it makes it difficult to add or remove genres later. There are better ways of implementing this through a relational database such as mySQL. But this will do as an example.
This section analyzes the key parts of the sample source code for generating the front page. For a full listing of this source code, see frontpage.pl, basic version.
First, we load some Perl modules, and print out a standard HTTP header (along with a
Next, we retrieve any cookies associated with this page.
If we find a cookie marked
If such a cookie does not exist, we load up some default values and note that we are just loading default values.
We print out some standard text for the beginning of the web page.
This is where the work really happens. We go through every movie and check the genres it fits into. If we find it belongs to one of the genres that our user has selected on his list, then we print a link to the movie with the URL of
We include a link to the personalization page, and some encouragement for users who have not set up their cookies yet.
This will present a front page that looks a little something like this: Figure 6-11 Default home page produced by frontpage.pl script
Listing 2: editprefsform.plFor a full listing of this source code, see editprefsform.pl, basic version. Suppose our user wants to set or alter his preferences. All we really need to do is offer a form consisting of several checkboxes (one for each genre) plus a text field for his name. This could be done with a standard HTML page. But we want to make sure the initial state of the form represents the user's current choices. (In other words, if our user has already asked to receive "comedy" and "drama" reviews, the "comedy" and "drama" fields should already be checked.) So once again, we are creating a script to produce this form. We start with the standard headers.
If a cookie for this person already exists, we use that information to grab his name and preferences from our database as before.
If no cookie is available, we could give him an entirely blank form, or present him with a form where the default categories are already checked. This is a matter of taste, really. I chose to go with the default values already checked.
Print out some HTML:
Now, we print out a checkbox for each genre category. If we find that, according to our user's preferences, he is already subscribed to that category, we mark it checked by default.
Do something similar with the name field:
And we are done, except for a little clean up work. Note the Submit button right now looks like every other submit button you have seen before. We are actually going to change this in the next section, so keep that in mind.
This will give us a checklist that looks a little something like this: Figure 6-12 Form produced by editprefsform.pl script
Listing 3: setprefs.plFor a full listing of this source code, see setprefs.pl, basic version. All we need now is a script to process the results of the form we generated above. In other words, we need to set a cookie for the user, if one is not set already, and edit his preferences in our database. We start off again with the usual headers (plus an
Then we grab the parameters returned by the form. Note that all of our genre preference parameters within the previous form are named "1", "2", "3", and so on. So it is relatively easy to grab their values from a We put the user's name into a variable called username and his preferences into an array of 11 true-or-false values. That last line there replaces any
If the user's cookie indicates he has an ID already, we use it. Otherwise, we generate one using the getrandomID function this is a function created below that generates a random ID for us.
Then we use Perl's CGI::cookie function to create a cookie. I have set the expire time to 10 years from now, since we really do not want our cookies to expire between syncs. (If I wanted to be thorough, I could also define my own domain and path values for the cookie.)
We write the user's preferences into the database, joining them together as a
Finally, we print out our HTML document. Note the set-cookie line among the HTTP headers. This document will be placed in the Forms Manager during the next sync. It is really just a bunch of debug information, and I do not really want our users to see it. (After the next sync, our users will be looking at the new
Last but not least is our
Caution:
Do not use this approach with | ||||
|
