ATG
Clearing Out BCC Projects
by Frank Kim on Apr.25, 2012, under Publishing
Clean Up or You’re Out! :Brooklyn Street Sign by emilydickinsonridesabmx
This may not be the best way to clear out your BCC projects but it’s quick.
delete from epub_pr_history; delete from epub_project; delete from epub_proc_history; delete from epub_proc_taskinfo; delete from epub_ind_workflow; delete from epub_process; delete from avm_asset_lock; delete from avm_workspace;
Adding a New Link to a Commerce Pipeline
by Frank Kim on Jun.22, 2011, under Commerce
Only as strong as the weakest link. Part 2 by David’n'Sheila
To add new links to a commerce pipeline you need to override the default definition for the appropriate commerce pipeline. Commerce pipelines are defined in XML so you use ATG’s XML combining feature to accomplish this.
For example if you want to add a new link to the ProcessOrder chain in the /atg/commerce/commercepipeline.xml you would create the following commercepipeline.xml in your local config.
<pipelinemanager>
<pipelinechain name="processOrder" xml-combine="append">
<pipelinelink transaction="TX_MANDATORY" name="authorizePayment" xml-combine="replace">
<processor jndi="/atg/commerce/order/processor/AuthorizePayment" />
<transition returnvalue="1" link="updateInventory" />
</pipelinelink>
<pipelinelink name="updateInventory" transaction="TX_MANDATORY">
<processor jndi="/betweengo/commerce/inventory/processor/ProcUpdateInventory" />
<transition returnvalue="1" link="updateGiftRepository" />
</pipelinelink>
</pipelinemanager>
In this example we added the new updateInventory link which is inserted between the authorizePayment and updateGiftRepository links.
Specifying the Calculator per Promotion
by Frank Kim on Mar.07, 2011, under Commerce
(Photo: calculator by ansik)
ATG’s documentation, as far as I can tell, does not document how to specify the calculator for a promotion. Promotion’s have a repository property called pricingCalculatorService. In the ACC you won’t see it by default but you will see it if you show expert-level information. Also you can see it configured in the Promotion repository (/atg/commerce/pricing/Promotions).
Having a repository property for each promotion allows you to specify different calculators for different promotions. But typically you will probably specify the same one for the same class of promotion, e.g. /betweengo/commerce/pricing/calculators/ItemDiscountCalculator.
ATG Confirm Password Bug in ProfileFormHandler
by Frank Kim on Nov.22, 2010, under Personalization
Long-billed Curlew birds by mikebaird
Hi ATG Support,
I noticed a bug in how ATG’s ProfileFormHandler (ATG Java API) handles confirm passwords when creating a new profile. Note that this bug happens only if you persist anonymous profiles.
During registration when you call handleCreate it calls createProfileItem and then updateProfileAttributes. In updateProfileAttributes it checks if the password matches the confirm password. If they don’t match it adds a form exception.
However at this point it has updated the profile attributes including the login. Therefore after the user sees the error about the passwords not matching, corrects it and resubmits the form she will see an error that the login is already taken.
The work around is to set creatNewUser to true but since the default value is false most developers will see this bug.
Update 12-22-2010: ATG confirmed this is a bug.
Hi Frank,
Thanks for the information and details. I’m glad that using ProfileFormHandler.createNewUser=true works for you. You might want to periodically check the size of the dps_user table and purge the anonymous profiles, if needed.
For your reference, I have created PR#DPS-167714 “ProfileFormHandler Confirm Password” to track the issue.
Kind Regards,
Kristi Coleman
Load ATG Order
by Frank Kim on Nov.14, 2010, under Commerce, Programming
You can always look up an order in the repository using it’s ID. But then you want to use the properties of this order object you will always be calling getPropertyValue and casting it to the type you expect.
A better and much simpler way is to look up the order using the OrderManager. Then you get a strongly typed Order object and don’t have have to deal with the repository. Life has become a little easier.
OrderManager orderManager = getOrderManager; Order order = orderManager.loadOrder(orderId);
Now that you have the order you can also get the profile for that order.
RepositoryItem profile = getProfileTools().getProfileForOrder(order);
Turning on Secure for ATG Applications
by Frank Kim on Nov.10, 2010, under Configuration
Closed for business by maistora’s Photostream | Flickr
Almost all web applications have some parts of their site they want to be secure such as login and profile pages.
To enable security ATG has a ProtocolSwitchServlet, located at /atg/dynamo/servlet/dafpipeline/ProtocolSwitchServlet. Set the enable property to true and configure the other properties appropriately.
The only other properties that you will need to configure are the secureList property and the ignoreList property. Examples of how these properties would be configured follow.
secureList=/myapp/account,/myapp/checkout ignoreList=/myapp/css,/myapp/javascript
Optionally you might want to change the secureHostName and the httpsPort but typically it would be better to change siteHttpServerName and httpsPort respectively in /atg/dynamo/Configuration.
The default values for the other properties should be fine.
ATG Log Error from JSP Page
by Frank Kim on Sep.27, 2010, under Page Development
"The page cannot be displayed" by Peter Kaminski
Unlike this IKEA sign, you usually don’t want to display errors on your web pages. ATG allows you to log errors to the server log from a JSP page. Below is an example of how to do this. In this case if we find the price is null we log an error to the server log.
<dsp:getvalueof id="price" idtype="java.lang.Double" param="currentItem.priceInfo.amount"><%if (price == null) { atg.servlet.DynamoHttpServletRequest dreq = atg.servlet.ServletUtil.getDynamoRequest(request); dreq.logError("price is null!”);}%></dsp:getvalueof>
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.
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.
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.






