Synopsis
Some sites may need to store information for products/entities that does not have a field set up in the software 'out of the box'. The easiest way to do this is with the ExtensionData fields, which are stored in the database but not used anywhere on the site.
Procedure
This example shows how relatively easy it is to make use of entity ExtensionData to store a wide variety of data if you store it in an xml format.
This will show how one can set per-entity priority in Google site maps, something you cannot do using the GoogleSiteMap AppConfigs.
Starting out, let's say we have the following in our ExtensionData of one of our categories:
Code:
<LastEditedBy>
<Who>Lisa</Who>
<When>2/10/2008</When>
</LastEditedBy>
<GoogleSiteMapPriority>.3</GoogleSiteMapPriority>
<DayOfTheWeekSkinsAndTemplates>
<Monday skin="1" template="backtoworkblues.ascx" />
<Tuesday skin="2" template="limbo.ascx" />
<Wednesday skin="3" template="humpday.ascx" />
<Thursday skin="2" template="theslide.ascx" />
<Friday skin="1" template="tgif.ascx" />
<Saturday skin="4" template="tequilashots.ascx" />
<Sunday skin="5" template="sleepingin.ascx" />
</DayOfTheWeekSkinsAndTemplates>
As you can see, you can store a variety of data in ExtensionData and make use of it wherever you need. How do you access it? EntityHelpers! AppLogic has a public static set of EntityHelpers available whenever you need them. Just make a call to obtain one, for example AppLogic.LookupHelper("Category") to get the Category EntityHelper. These EntityHelpers are initialized during the starting up of the application. If you make changes to your ExtensionData, you can use the Admin's Reset Cache link to reload the EntityHelpers.
The data that these EntityHelpers cache is the same data provided to XML Packages! That is why it is most convenient to store XML data in ExtensionData. You can use XPath to access it in packages!
The data that these EntityHelpers cache is determined by the EntityHelper\EntityMgr.xml.config file. The following additions to this xml package file will store ExtensionData in this cache.
Add this additional query to the package:
Code:
<query name="EntityData" rowElementName="Entity">
<sql>
<![CDATA[
EXEC('SELECT ' + @EntityName + 'ID as EntityID,Name,ExtensionData FROM ' + @EntityName + ' WHERE Published >= ' + @PublishedOnly);
]]>
</sql>
<queryparam paramname="@EntityName" paramtype="runtime" requestparamname="EntityName" sqlDataType="varchar" defvalue="" validationpattern= ""/>
<queryparam paramname="@PublishedOnly" paramtype="runtime" requestparamname="PublishedOnly" sqlDataType="tinyint" defvalue="0" validationpattern= ""/>
</query>
In the entityTmpl template, inside of the <xsl:copy></xsl:copy> section add:
Code:
<xsl:value-of select="/root/EntityData/descendant-or-self::Entity[EntityID = current()/EntityID]/ExtensionData" disable-output-escaping="yes"/>
NOTE: The disable-output-escaping is very important in merging our ExtensionData into the XML tree!!
To complete our Google Site Map example, all we have to do is modify googleentity.aspx.cs a little bit.
Code:
/*Line 33*/
EntityHelper eHlp = AppLogic.LookupHelper(EntityName);
System.Xml.XmlNode n = eHlp.m_TblMgr.SetContext(EntityID);
n = n.SelectSingleNode("ExtensionData/GoogleSiteMapPriority/text()");
and
Code:
/*Line 42 -- fall back to AppConfigs if ExtensionData not present. */
Response.Write("<priority>" + ((n != null) ? n.Value : AppLogic.AppConfig("GooleSiteMap. EntityPriority")) + "</priority> ");
The only caveat to remember is that this data is cached. If you have a lot of ExtensionData and/or a lot of entities, then you will probably want to implement some other scheme.