How to create store-wide parameters accessible anywhere
Introduction
As you get deeper into programming in AC7, you might find the need have a parameter specified on the Admin side that needs to be acted upon on the store side. All of the AC7 store-wide settings are stored in the ac_StoreSettings table. What's interesting is the CommerceBuilder API gives you some *very* easy methods to store and retrieve your own custom settings.
An Example Goal
The best way to learn is by-example, so let's make up a need and accomplish that need using this technique. For today's example, we have a request to create a catch-all AC7 page for visitors who request a missing product. Apparently the site admin recently decided to rebuild part of the product catalog. Well, that "broke" all those product URLs since the Product ID is tied to the URL and alot of visitor landings are getting the generic IIS "page missing" errors. The sales manager says "fix it, make it clean and don't you dare hard-code it!". Pffft like the sales manager even KNOWS what hard-coding means, but that's a debate for another time.
Project Definition
1. Failed product lookups must redirect to an AC7-controlled page. The server administrator doesn't want you playing with IIS site settings.
2. The designated redirect page must be configurable on the Admin side. The only other thing managers do well besides creating unrealistic expectations is changing their minds AFTER you coded everything.
3. Programming testing if the value has been specified on the Admin side should be easy to do. You're the one stuck with this project and that Friday night trip to the riverboat casino didn't help getting you up for work this morning.
The Admin Side Changes
Every good project has an even better foundation. We're going to integrate this change right into the main AC7 Store, Configure menu option. The site admin will be pleased. Let's start by editing the ~/Admin/Store/StoreSettings.aspx and adding a text box control with label to the page. Look for this code in the page near the bottom:
<asp:Label ID="ProductPurchasingDisabledLabel" runat="server" Text="Enabling this feature will hide the add to basket button for all products, so customers can browse your catalog but are unable to purchase directly online."></asp:Label><br /> <asp:CheckBox ID="ProductPurchasingDisabled" runat="server" Text="Enable Catalog Mode"/>
and replace it with this code:
<asp:Label ID="ProductPurchasingDisabledLabel" runat="server" Text="Enabling this feature will hide the add to basket button for all products, so customers can browse your catalog but are unable to purchase directly online."></asp:Label><br /> <asp:CheckBox ID="ProductPurchasingDisabled" runat="server" Text="Enable Catalog Mode"/> <br /> <asp:Label ID="lbl_ProductMovedPage" runat="server" Text="Redirect page for invalid Products (blank redirects to home page):"></asp:Label><br /> <asp:TextBox ID="txt_ProductMovedPage" runat="server" Width="310px"></asp:TextBox><br />
Once you've added the text box, we have to modify both the Load section and the Save section of the page. The site admin will be able to always see what the current setting is and make changes to it all on the same page. Look towards the top of the page in the Page_Load function for this code:
//GIFT CERTIFICATE EXPIRY GiftCertExpireDays.Text = settings.GiftCertificateDaysToExpire.ToString();
and replace it with:
//GIFT CERTIFICATE EXPIRY GiftCertExpireDays.Text = settings.GiftCertificateDaysToExpire.ToString(); //BEGIN: Solunar.com Mod // Moved Product Page URL txt_ProductMovedPage.Text = settings.GetValueByKey("CUSTOM:BadProductPage"); //END: Solunar Mod
All done? Perfect. But we still have to make the system save any changes made. So let's move down into the SaveSettings() function and find this section of code:
//Gift Certificate Days to Expire settings.GiftCertificateDaysToExpire = AlwaysConvert.ToInt(GiftCertExpireDays.Text); //BEGIN: Solunar Mod //Missing Page URL settings.SetValueByKey("CUSTOM:BadProductPage", txt_ProductMovedPage.Text); //END: Solunar Mod
Save your changes and test the page. You should have a new text box field located on the bottom-right of the Configure, Store page. Enter something (anything) in the field and save the settings. Now switch to another page and then back again to the Configure, Store page to ensure the changes you made were saved. If you did everything right, you'll see the test value you entered already populated in the text box.
The Store Side
So all this work just to store one value on the Admin side was fun, but how does it help you? Well, we now have a custom user-specified value that is easily editable on the Admin side. All we have to do now is know how to retrieve that value on the store side. For our example today, we're going to edit the BuyProductDialog.ascx user control. Every product page uses it, so it's a good place to put in a test for an invalid product and redirect to our new custom URL.
Let's start by editing the BuyProductDialog.ascx.cs code file located in the ~/ConLib/ folder. Look for this code at the end of the Page_Init function, directly above the start of the next subroutine UpdateInventoryDetails():
else { Response.Redirect(NavigationHelper.GetHomeUrl()); }
and replace it with:
else { //BEGIN: Solunar Mod // ProductId not found, redirect to the badproductpage // Retrieve redirect URL for missing products StoreSettingCollection settings = Token.Instance.Store.Settings; string _BadProductPage = settings.GetValueByKey("CUSTOM:BadProductPage"); if (string.IsNullOrEmpty(_BadProductPage)) { Response.Redirect(NavigationHelper.GetHomeUrl()); } else { Response.Redirect(_BadProductPage); } //this.Controls.Clear(); //END: Solunar Mod }
Save it.
What's Happening?
Study the above code for a minute. Retrieving a value in the StoreSettings table is incredibly easy. It's always available because the Store data class is always available. So first things first, we grab the store settings collection from the Store data class and assign it to a seperate variable. While this is an extra step, it makes for easy-to-read code and that's always a good programming practice. By calling the GetValuebyKey() function, we've told the data class to search the ac_StoreSettings table for a key named "CUSTOM:BadProductPage" and return the value assigned to that key. If no value is returned i.e. the key couldn't be found, the code will simply redirect the user to the home page. But if a value is returned, then use that value as the destination redirect page
Testing
Let's test all of this now. Build a web page you want to be displayed for missing products. Call it MovedProduct.aspx and store in the root of your store. Now go back into the Admin side of the store and enter ~/MovedProduct.aspx as the value for the your new custom field in the Configure, Store page. Finally, the test. Fire up your browser and enter your store URL with a bad ProductId value like http://mystoreurl/Product.aspx?ProductId=99999 and see what happens. The original AC7 design would have dumped you back to the home page - not terribly intuitive from a visitor perspective. But you should be redirected to your brand new MovedProduct page instead. Now you can offer the visitor additional search options, explain why they got there or even offer to sell a substitute product.
Conclusion
Creating admin-side custom settings that can be retrieved on the store side is very powerful. It gives the developer the ability to offer admin-manageable features without hard-coding or repeated programming changes. AC7 gives you all the tools you need to create and access customized settings from anywhere within the store front.
Reference
Originally posted in forums by Joe Payne http://forums.ablecommerce.com/viewtopic.php?f=47&t=7037