Author Archive
Persistent Cart for Anonymous Users
by Frank Kim on May.03, 2010, under Personalization
Isn’t it iconic? by Mykl Roventine
Convenience
eCommerce sites want to make their users’ experience as convenient and intuitive as possible. One convenience found on most major eCommerce sites is remembering what the user put in his shopping cart, even if that person didn’t log in. Therefore when the user returns to the site he will see what he left in his shopping cart.
Persistent Cart
ATG makes it relatively simple to do this by:
- creating a profile in the repository (database) for all users that visit the website
- automatically logging in users by cookie
Therefore if a user returns, she/he will be automatically logged in and if there were any items in his cart they will be added to the current cart.
Implementation
- Turn on persisting anonymous profiles in the ProfileRequestServlet.
# /atg/dynamo/servlet/dafpipeline/ProfileRequestServlet persistAfterLogout=true persistentAnonymousProfiles=true
- Turn on auto-login by cookie and turn off auto-login by basic authentication.
# /atg/userprofiling/CookieManager sendProfileCookies=true # /atg/userprofiling/ProfileRequestServlet verifyBasicAuthentication=false
- Make all profile properties not required except for login and password in userProfile.xml. Also make autoLogin true.
<table name="dps_user"> <property name="login" required="true" /> <property name="password" required="true" /> <property name="firstName" required="false" /> <property name="lastName" required="false" /> <property name="email" required="false" /> <property name="autoLogin" default="true" /> </table>
Notes
When a profile is created for an anonymous user the login and password are set to the user’s ID (i.e. the profile’s repository ID).
If you are adding this functionality to an existing up and running site you may have to modify your user tables so that there no “not null” columns except for the id, login and password columns, you can leave those as how they were. Also you will need to set auto_login to true for all your existing users.
update dps_user set auto_login = 1;
To determine when the anonymous user was created look at the registrationDate profile property. To determine when was the last time the anonymous user logged in look at the lastActivity profile property. Both of these are updated by ATG’s TrackActivity scenario which is in the DSS folder.
For further reading please see Tracking Guest Users and Tracking Registered Users in the ATG 9.1 Personalization Programming Guide.
Debugging WebSphere Applications with IBM Rational Application Developer
by Frank Kim on Apr.26, 2010, under Eclipse
IBM Rational Application Developer (RAD) is basically a typically IBM heavy version of Eclipse. WebSphere is a typically IBM heavy version of a J2EE server. Therefore you would think you could debug web applications using RAD fairly easily like you can on JBoss or ATG DAS using Eclipse.
However I could not find anyone on my latest project who knew how to do this. Fortunately after much Googling I found this PDF document, Debugging Applications in IBM Rational Application Developer, and on page 12 are instructions on how to do this.
The instructions seem to be a little out of date so here are my instructions.
- Log into your Integrated Solutions Console. The default URL is http://localhost:9060/ibm/console/login.do.
- Navigate using the left side column to Servers –> Application Servers.
- Select the Application server you want to debug from the list of Application servers.
- Under the Configuration tab select the Debugging Service link which is near the bottom right in the Additional Properties section.
- Select the “Enable service at server startup” checkbox. Note the JVM debug port.
- Press the Apply button.
- In the Messages box, which appeared at the top after pressing the Apply button, click on the Save link.
- Stop and start your Application Server. It should now be running in Debug mode.
- In RAD go to the project for the web application you want to debug.
- From the menu select Run –> Debug Configurations.
- Select Remote Java Application and press the New button (it’s the top left button). For the port set it to the JVM debug port (default is 7777).
- Press Apply. Then press Debug. It should connect to WebSphere’s JVM.
Now you can set breakpoints and even change small amounts of code which will be deployed automatically to WebSphere. No more waiting 15 minutes to test every change you make because builds are so brutally long.
Set ATG Repository Item Date or Timestamp Properties to the Current Time
by Frank Kim on Apr.19, 2010, under Repository
*Time* Ticking away… by Michel Filion
This is a neat trick for automatically setting a date or timestamp property to the current time. I learned it while perusing the ATG Repository Guide.
A repository item can use properties whose values are dates or timestamps, with the value set to the current date or time, using the java.util.Date, java.sql.Date, or java.sql.Timestamp classes. You can have a property whose value is set to the current time or date at the moment a repository item is created. You can do this by setting the feature descriptor attribute useNowForDefault. For example:
<property name="creationDate" data-type="timestamp"> <attribute name="useNowForDefault" value="true"/> </property>For more information about this technique, see the Assigning FeatureDescriptorValues with the <attribute> Tag section in this chapter.
Twitter Weekly Updates for 2010-04-04
by Frank Kim on Apr.04, 2010, under Miscellaneous
- Clear Text On Input Field On Click | ErumMunir.com. Sometimes JavaScript is just fun. http://bit.ly/c6D7cR #
Twitter Weekly Updates for 2010-03-28
by Frank Kim on Mar.28, 2010, under Miscellaneous
- Set ATG Property And Popup Window After Clicking on Link. There's the wrong way, the brute force way and the right way. http://bit.ly/9H6P0p #
Set ATG Property And Popup Window After Clicking on Link
by Frank Kim on Mar.26, 2010, under Page Development
Sometimes when you click on a link in an ATG JSP/DSP page you want a property of an ATG component to be set as well. For example:
<dsp:a href="foo.jsp">Foo <dsp:property bean="BarFormHandler.baz" paramvalue="index"/> </dsp:a>
What gets tricky is if you also want a popup window to display the contents of this link.
The Wrong Way
I tried adapting the instructions from the tutorial Popup Windows | open new customised windows with JavaScript.
<dsp:a href="javascript:poptastic('foo.jsp');">Foo
<dsp:property bean="BarFormHandler.baz" paramvalue="index"/>
</dsp:a>
This does not work, i.e. the setter for baz in BarFormHandler is never called.
The Brute Force Way
I then reverted to the original DSP and looked at the outputted HTML. Based on that I updated the DSP like this.
<% atg.servlet.DynamoHttpServletRequest dreq = atg.servlet.ServletUtil.getCurrentRequest(); %>
<a href="javascript:poptastic('foo.jsp?_DARGS=/betweengo/test.jsp_AF&_dynSessConf=<%= dreq.getSessionConfirmationNumber() %>&_D%3A/betweengo/BarFormHandler.baz=+&/betweengo/BarFormHandler.baz=<dsp:valueof param="index" />');">Foo</a>
This works but is grotesque.
The Good Idea That Did Not Work
Then I realized I could just set a parameter in the URL and have the form handler use the value to set the property.
<a href="javascript:poptastic('foo.jsp?index=<dsp:valueof param="index" />');">Foo</a>
And in BarFormHandler
public boolean beforeSet(DynamoHttpServletRequest req,
DynamoHttpServletResponse res) throws DropletFormException {
String indexParam = request.getParameter("index");
setIndex(Integer.parseInt(indexParam));
return super.beforeSet(request, response);
}
This did not work plus I did not really like it because now I have a beforeSet method that is called for every single request.
The Winner
I then realized I did not read the tutorial Popup Windows | open new customised windows with JavaScript carefully. There is a more elegant way to call the JavaScript which degrades gracefully for browsers that don’t support JavaScript.
<dsp:a href="foo.jsp" onclick="poptastic(this.href);return false;">Foo <dsp:property bean="BarFormHandler.baz" paramvalue="index"/> </dsp:a>
This works, is elegant and requires just adding the onclick attribute to the original DSP.
Twitter Weekly Updates for 2010-03-07
by Frank Kim on Mar.07, 2010, under Miscellaneous
- Ignore Files and Directories in Subversion. A little bit of a pain but it works. http://bit.ly/99GLxk #
- How to Achieve Painless Registration. Getting people to register is always bedeviling for web application developers. http://bit.ly/9AJqmg #
Ignore Files and Directories in Subversion
by Frank Kim on Mar.01, 2010, under Subversion
In the course of a project there are always files and directories that you don’t want to check in but which Subversion complains it doesn’t know anything about them. So it makes sense to tell Subversion to ignore them, in other words, keep quiet.
The mechanism for doing this works okay but I wouldn’t say it’s perfect.
This is how I do it one.
- Go to the directory where want to ignore a file or subdirectory.
- Issue the command
svn propedit svn:ignore .
- Your editor then will be launched and you can enter one line at a time those files and/or subdirectories you want to ignore.
some_file some_directory
- Commit your changes.
svn commit -–depth empty
Two things to notice.
-
--depth empty argument
only commit the propedit changes
- Committing your changes means everyone will end up ignoring these files and/or directories so make sure you are ignoring the right ones.
-
- If you don’t want to commit your changes you can revert them.
svn revert .
For further reading please see Ignore Files and Directories in Subversion.
Tweets for 2010-01 and 2010-02
by Frank Kim on Feb.28, 2010, under Miscellaneous
Ruby on Rails
- Numeric data types and zerofill. Explains what all those int(11) columns are in your Ruby on Rails tables. http://bit.ly/9Tcf7q #
- undefined local variable or method "acts_as_list"? – Ruby Forum. Do ruby script/plugin install acts_as_list http://bit.ly/9kFWbG #
- ruby on rails : adding child records to an existing parent without visiting the parent – Stack Overflow http://bit.ly/cQiGSP #
- Multi-Table Inheritance in Rails – When two tables are one… This is not easy and I wish it was. http://bit.ly/9fbzgk #
- has_many :through – count vs length vs size. Use count if u don’t want to load the contents of association into memory. http://bit.ly/dtqXe1 #
- A gentle reminder about pluralizations. config/initializers/inflections.rb to customize pluralizations in Ruby on Rails http://bit.ly/bN9GO5 #
- Ruby on Rails – Rails Migrations Cheatsheet – Dizzy. Pretty helpful. http://bit.ly/9wNvRx #
- RailsGuides Migrations. Nice guide, especially about explaining the naming convention which I don’t like. http://bit.ly/cjZ7aB #
ATG
- Configuring ATG to Send Email via Comcast SMTP – betweenGo. Configuring your ATG app to use your ISP’s SMTP server. http://bit.ly/7M5bhx #
- Enabling non-XA Resources in JBoss 4.2 with ATG – betweenGo. http://bit.ly/aDN3Po #
- Combining XML in ATG – betweenGo. Combining XML files not as straight-forward as w/ properties files but more flexible. http://bit.ly/8kVwvA Jan 12 12:00 PM
Eclipse
- Debugging Applications in IBM Rational Application Developer. Page 12 for how to set up server for debugging. http://bit.ly/aaYUHb #
JavaScript
- How can I submit a form along with some parameters using JavaScript? (JSF forum at JavaRanch). Answer #3 was helpful. http://bit.ly/b17ymm #
JSP
- Testing Which Page Loaded your JSP Page Fragment – betweenGo. Simple enough to do w/ JSTL but I always forget how.
http://bit.ly/cEh7IZ #
Miscellaneous
- Cygwin 1.7.x, mounts and /etc/fstab – betweenGo. Mounts are no longer saved from session to session in Cygwin 1.7. http://bit.ly/bmaYEu #
- Git in 5 Minutes http://bit.ly/bSt3dd and Git for the lazy – Spheriki http://bit.ly/aefD17 #
- The Thing About Git. Nice article describing how flexible Git is, especially compared to SVN. I may never use SVN again http://bit.ly/bD0tuS #
- I use DreamHost and am shamelessly plugging them both for a referral and to try to win an iPad. Honestly they’re great. http://bit.ly/ctYv3Z #
Cygwin 1.7.x, mounts and /etc/fstab
by Frank Kim on Feb.08, 2010, under Cygwin
Sunrise Heron Silhouette by Brandon Godfrey
A few days I installed Cygwin on a new laptop. I saw the warnings that Cygwin 1.7.x is new but I chose to ignore it for now.
I soon noticed that Cygwin was not remembering my mounts. After reading this on the Cygwin front page I realized I needed to do some more research.
… the mount point storage has been moved out of the registry into files. User mount points are NOT copied into the new user-specific /etc/fstab.d/$USER file. Rather, every user has to call the /bin/copy-user-registry-fstab shell script once after the update.
Next I looked at the /etc/fstab file which pointed me to the Cygwin Mount Table documentation. Using this documentation I did the following steps so that my mounts are always remembered.
- Manually mounted the C: drive.
$ mount c: /c
- Ran mount to determine what to add to my /etc/fstab.
$ mount C:/cygwin/bin on /usr/bin type ntfs (binary,auto) C:/cygwin/lib on /usr/lib type ntfs (binary,auto) C:/cygwin on / type ntfs (binary,auto) C: on /c type ntfs (binary,user)
- Based on the output of mount I added this line to my /etc/fstab.
C: /c ntfs binary,user
- Closed the Cygwin shell, opened a new one and verified the C: drive was properly mounted.
Update 06-15-2010: I should have just followed Cygwin’s directions and ran /bin/copy-user-registry-fstab.

