Important Notice from AspDotNetStorefront
It is with dismay that we report that we have been forced, through the action of hackers, to shut off write-access to this forum. We are keen to leave the wealth of material available to you for research. We have opened a new forum from which our community of users can seek help, support and advice from us and from each other. To post a new question to our community, please visit: http://forums.vortx.com
Results 1 to 10 of 10

Thread: Facebook App = Editing Left Entity Menu

  1. #1
    hunter0781 is offline Member
    Join Date
    Apr 2010
    Posts
    34

    Thumbs up Facebook App = Editing Left Entity Menu

    My overall goal (almost completed) is to write a XML package which I can post on facebook as a application. This xmlpackage will be controlled as a category within my admin but will have modified absolute product links. Before I use it I need a way to restrict this facebook category from showing up in my store menu, but it still needs to be published in the admin.

    Unfortunately, from what I understand editing the entity menu can only be done via the source code because it's hard coded. Can anyone shed light on how to restrict a particular category from the entity menus without unpublishing it? I'm having a hard time finding where in the code to start this mod. Any help is greatly appreciated.

    Thanks!

  2. #2
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Hi

    What we usually do is replace the standard entity menu(s) with XMLPackages. This gives you complete control over how the menus are rendered, stops some unnecessary javascript being inserted into the page and controls which items appear in the menu.

    The XMLPackage for the menu uses the EntityHelper and just goes through the Category/Manufacturer etc displaying the appropriate items, usually in a <ul><li> format with the styling controlled by CSS.

    You can hide items within the XMLPackage using hard coded <xsl:if EntityID=123> statements, or by adding flags into ExtensionData fields.

    Adam

  3. #3
    hunter0781 is offline Member
    Join Date
    Apr 2010
    Posts
    34

    Thumbs up

    Thanks for your reply.

    I'm attempting to use the rev.categories.xml.config and I'm running into a problem.

    This package is old and I assume outdated but I'm trying to fix it. It generates all entity's on the root level without issue. However it won't populate subcats and I've found where it's broken.

    Code:
    <xsl:param name="CategoryID">
                    <xsl:choose>
                        <xsl:when test="/root/System/PageName = 'showmanufacturer.aspx' or /root/System/PageName = 'showsection.aspx' or /root/System/PageName = 'showdistributor.aspx' or /root/System/PageName = 'showvector.aspx' or /root/System/PageName = 'showgenre.aspx'">0</xsl:when>
                        <xsl:when test="/root/System/PageName = 'showcategory.aspx' and boolean(/root/QueryString/categoryid)">
                            <xsl:value-of select="/root/QueryString/categoryid"/>
                        </xsl:when>
                        <xsl:when test="(/root/System/PageName = 'showcategory.aspx' or /root/System/PageName = 'showproduct.aspx') and boolean(/root/Cookies/LastViewedEntityInstanceID) and /root/Cookies/LastViewedEntityName = 'Category'">
                            <xsl:value-of select="/root/Cookies/LastViewedEntityInstanceID"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="0"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:param>
    The package is always setting the CategoryID to 0. What I did next was I looked for the category ID in the runtime xml so I could define it in the xml above, only to find it's not available to use and only the cat url is populated.

    I'm not sure how to proceed. I need to find or write the catid to the runtime xml or handle it a different way. Any ideas?

    Btw - I was able to easily exclude categories from the menu just like you explained. Thanks!

    Below is the entire xml pkg.

    Code:
    <?xml version="1.0" standalone="yes" ?>
    <!-- ###################################################################################################### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2010.  All Rights Reserved.					                -->
    <!-- http://www.aspdotnetstorefront.com														                -->
    <!-- For details on this license please visit  the product homepage at the URL above.		                -->
    <!-- THE ABOVE NOTICE MUST REMAIN INTACT.                                                                   -->
    <!-- ###################################################################################################### -->
    <package version="2.1" displayname="Categories" debug="true" includeentityhelper="true">
        <PackageTransform>
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aspdnsf="urn:aspdnsf" exclude-result-prefixes="aspdnsf">
                <xsl:output method="html" omit-xml-declaration="yes"/>
    
                <xsl:param name="CategoryID">
                    <xsl:choose>
                        <xsl:when test="/root/System/PageName = 'showmanufacturer.aspx' or /root/System/PageName = 'showsection.aspx' or /root/System/PageName = 'showdistributor.aspx' or /root/System/PageName = 'showvector.aspx' or /root/System/PageName = 'showgenre.aspx'">0</xsl:when>
                        <xsl:when test="/root/System/PageName = 'showcategory.aspx' and boolean(/root/QueryString/categoryid)">
                            <xsl:value-of select="/root/QueryString/categoryid"/>
                        </xsl:when>
                        <xsl:when test="(/root/System/PageName = 'showcategory.aspx' or /root/System/PageName = 'showproduct.aspx') and boolean(/root/Cookies/LastViewedEntityInstanceID) and /root/Cookies/LastViewedEntityName = 'Category'">
                            <xsl:value-of select="/root/Cookies/LastViewedEntityInstanceID"/>
                        </xsl:when>
                        <xsl:otherwise>
                          <xsl:value-of select="0"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:param>
    
                <xsl:param name="AncestorID">
                    <xsl:for-each select="/root/EntityHelpers/Category//Entity[EntityID = $CategoryID]">
                        <xsl:value-of select="ancestor::*/EntityID"/>
                    </xsl:for-each>
                </xsl:param>
    
                <xsl:param name="ParentID">
                    <xsl:for-each select="/root/EntityHelpers/Category//Entity[EntityID = $CategoryID]">
                        <xsl:value-of select="parent::*/EntityID"/>
                    </xsl:for-each>
                </xsl:param>
    
    
                <xsl:template match="/">
                    <xsl:element name="ul">
                        <xsl:attribute name="class">
                            <![CDATA[tame]]>
                        </xsl:attribute>
    
                        <xsl:apply-templates select="/root/EntityHelpers/Category/Entity">
                            <xsl:with-param name="prefix" select="''"/>
                        </xsl:apply-templates>
    
                    </xsl:element>
                </xsl:template>
    
    			<xsl:template match="Entity">
                    <xsl:param name="prefix"></xsl:param>
                    <xsl:param name="eName" select="aspdnsf:GetMLValue(Name)" />
    
    
                    <li class="tame">
                        <xsl:value-of select="$prefix" />
                        <xsl:if test="number(ParentEntityID) != 0">
                            <span class="catMark">&gt;&gt;</span>*
                        </xsl:if>
                      <xsl:if test="EntityID != 58">
                        <a href="{concat('c-',EntityID,'-',SEName,'.aspx')}">
                            <xsl:if test="EntityID = $CategoryID or descendant::Entity/EntityID = $CategoryID">
                                <xsl:attribute name="style">font-weight:bold;</xsl:attribute>
                            </xsl:if>
                            <xsl:value-of select="$eName"/>
                        </a>
                      </xsl:if>
    
    
                        <xsl:if test="count(child::Entity)&gt;0 and (EntityID = $CategoryID or descendant::Entity/EntityID = $CategoryID)">
                            <ul class="tame">
                                <xsl:apply-templates select="Entity">
                                    <xsl:with-param name="prefix" select="concat($prefix, '**')"/>
                                </xsl:apply-templates>
                            </ul>
                        </xsl:if>
                    </li>
                </xsl:template>
    
            </xsl:stylesheet>
        </PackageTransform>
    </package>

  4. #4
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Is this a v9 site?

    If it is, the 'QueryString/categoryid' field is no longer populated (not sure why) but it's relatively easy to solve but needs some code creating.

    All, please note, this code can be used by anyone but if you do use it, please credit Webopius somewhere on your site with a genuine link to http://www.webopius.com.

    Many thanks
    Adam

    1. In the App_Code folder, create a new file called something like 'CustomExtension.cs' containing:

    Code:
    // ------------------------------------------------------------------------------------------
    // Copyright Webopius.com 2010
    // Custom XSLT Extensions for the ASPDotNetStorefront forum
    // ------------------------------------------------------------------------------------------
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Text;
    using System.Xml;
    using System.Xml.Xsl;
    using System.Xml.XPath;
    using System.Web;
    using System.Globalization;
    using System.Text.RegularExpressions;
    using System.Runtime.CompilerServices;
    using AspDotNetStorefrontCore;
    
    /// <summary>
    /// Custom Xslt Extension Class
    /// </summary>
    public class CustomXsltExtension : XSLTExtensionBase
    {
        #region Variable Declaration
        #endregion
    
        #region Constructor
        public CustomXsltExtension()
            : this(null, 1, null)
        {
        }
    
        public CustomXsltExtension(Customer cust, int SkinID, Dictionary<string, EntityHelper> EntityHelpers)
            : base(cust, SkinID)
        {
        }
        #endregion
        #region Methods
    
    		// ---===---===---===---===---===---===---===---===---===---===---===---===---===---===
        // getEntityName, v9 no longer gives you the entity name and id in general XML functions
        // this method returns the entity name of the page (e.g. 'Category')
    
        public string getEntityName(string pagename)
        {
            String entityname = "";
            Match m = Regex.Match(pagename, "^([c|p|g|m|d|v|s])-([0-9]*)-([\\w-]*)\\.aspx(?:\\?(.*))?", RegexOptions.IgnoreCase);
            if (m.Success)
            {
                Group g = m.Groups[1];
                String entity = g.ToString().ToLower();
                switch (entity)
                {
                    case "c": entityname = "category"; break;
                    case "p": entityname = "product"; break;
                    case "g": entityname = "genre"; break;
                    case "m": entityname = "manufacturer"; break;
                    case "d": entityname = "distributor"; break;
                    case "v": entityname = "vector"; break;
                    case "s": entityname = "section"; break;
                }
            }
    
            return entityname;
        }
    
        // ---===---===---===---===---===---===---===---===---===---===---===---===---===---===
        // getEntityID, v9 no longer gives you the entity name and id in general XML functions
        // this method returns the entity ID of the page (e.g. '2234')
    
        public string getEntityID(string pagename)
        {
            string id = "0";
            string entity = "";
            Match m = Regex.Match(pagename,"^([c|p|g|m|d|v|s])-([0-9]*)-([\\w-]*)\\.aspx(?:\\?(.*))?",RegexOptions.IgnoreCase);
            if (m.Success)
            {
                entity = m.Groups[1].ToString().ToLower();
                id = m.Groups[2].ToString();
    
                switch (entity)
                {
                    case "c": AppLogic.SetCookie("lastviewedcategoryid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "p": AppLogic.SetCookie("lastviewedproductid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "g": AppLogic.SetCookie("lastviewedgenreid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "m": AppLogic.SetCookie("lastviewedmanufacturerid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "d": AppLogic.SetCookie("lastvieweddistributorid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "v": AppLogic.SetCookie("lastviewedvectorid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                    case "s": AppLogic.SetCookie("lastviewedsectionid", id, new TimeSpan(30, 0, 0, 0, 0)); break;
                }
            }
            return id;
        }
       #endregion	
    }
    2. Edit your web.config to register this new XsltExtension so that the 'Extensions' section looks like this:

    Code:
          <extensions>
            <clear />
            <add name="receipt" namespace="urn:receipt" type="ReceiptXsltExtension, app_code"></add>
            <add name="custom" namespace="urn:custom" type="CustomXsltExtension, app_code"></add>
          </extensions>
    3. Now, in your rev.categories (or any other XMLPackage that needs to get the Current or last viewed category ID):

    Edit the <xsl:stylesheet> section to look something like this:

    Code:
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="urn:custom" xmlns:aspdnsf="urn:aspdnsf" exclude-result-prefixes="aspdnsf custom">
    And change the category parameter code block to something like this (extend it for other page types):

    Code:
    <xsl:param name="CategoryID">
    		<xsl:choose>
    		<xsl:when test="custom:getEntityName(/root/System/PageName) = 'category' and custom:getEntityID(/root/System/PageName) != 0">
    			<xsl:value-of select="custom:getEntityID(/root/System/PageName)"/>
    		</xsl:when>
    		<xsl:when test="custom:getEntityName(/root/System/PageName) = 'product' and boolean(/root/Cookies/lastviewedcategoryid)">
    			<xsl:value-of select="/root/Cookies/lastviewedcategoryid"/>
    		</xsl:when>
    	<xsl:otherwise>0</xsl:otherwise>
    	   </xsl:choose>
          </xsl:param>
    It's difficult 'talking code' on the forum but hopefully this all works - let me know if not.

    Adam

  5. #5
    hunter0781 is offline Member
    Join Date
    Apr 2010
    Posts
    34

    Thumbs up

    Thank you! I followed your directions and now I receive the error below in the system log.

    Code:
    Page URL:/c-15-scents.aspx
    Source:System.Data.SqlXml
    Message:Cannot find the script or external object that implements prefix 'urn:custom'.
    Stack Trace:
    at System.Xml.Xsl.Runtime.XmlQueryContext.InvokeXsltLateBoundFunction(String name, String namespaceUri, IList`1[] args)
    at System.Xml.Xsl.CompiledQuery.Query.CategoryID(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime) in C:\9013\Web\images\rev.categories.xml.config_store.runtime.xsl:line 6
    at System.Xml.Xsl.CompiledQuery.Query.Execute(XmlQueryRuntime {urn:schemas-microsoft-com:xslt-debug}runtime)
    at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
    at System.Xml.Xsl.XmlILCommand.Execute(IXPathNavigable contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
    at System.Xml.Xsl.XslCompiledTransform.Transform(IXPathNavigable input, XsltArgumentList arguments, Stream results)
    at AspDotNetStorefrontCore.XmlPackage2.TransformString() in C:\9013\ASPDNSFCore\XmlPackage2.cs:line 635

  6. #6
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Hi

    This is usually a problem with the web.config. Double check the <extensions> section matches the code block I posted above - particularly the closing </add> of receipt.

    Adam

  7. #7
    hunter0781 is offline Member
    Join Date
    Apr 2010
    Posts
    34

    Thumbs up

    Yea i feel stupid, you're exactly right.

    This works like a charm, thanks a ton Adam.

    I'll add a link to your site as soon as possible.

  8. #8
    hunter0781 is offline Member
    Join Date
    Apr 2010
    Posts
    34

    Thumbs up

    Adam,

    I found a slight issue with your code. The menu system works perfectly when drilling down through the categories to the product. It always bolds the menu option for the current category the product is within. However when you skip directly to a product from a completely different category it still bolds the previous category even though the product isn't in that category. Is there any way to correct this so we're always showing the current category as bold in the menu?

    Thanks for your time!

  9. #9
    webopius is offline Senior Member
    Join Date
    Nov 2008
    Location
    London, UK
    Posts
    440

    Default

    Hi

    The problem with landing directly on individual product pages is that in many stores, products can map to more than one category so it's difficult to make an accurate assessment as to which category should be selected.

    That's why it uses the 'lastviewedcategoryid' cookie if nothing else matches.

    If your store only ever has one category for each product, then you could create a new method within the custom XSLTextension to retrieve the product's category id and to use this within the XMLPackage. In this case, if you landed on a product page directly, the correct category would be selected.

  10. #10
    ashish.patel is offline Junior Member
    Join Date
    Jan 2011
    Posts
    22

    Default

    @webopius u r great!!!!!!!!! u save my couple days........
    Thanks
    Last edited by ashish.patel; 10-15-2011 at 07:03 PM.