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 4 of 4

Thread: Google Product Feed

  1. #1
    maltschul is offline Junior Member
    Join Date
    May 2010
    Posts
    13

    Default Google Product Feed

    I spent a fair amount of time crafting a google shopping feed that lists all products/variants/colors with images for each specific product/variant/color combination and grouped the colors together in a single variant per Google's specs (as of 6/30/12). Also includes additional images for each color if exists. I've hacked the inventory table to make this all happen. Using warehouselocation, extendeddata, and vendorfullsku to populate the gtin and to be able to query on each color. I couldn't find a way to make this happen in a query any other way since the colors are kept in a single, comma-delimited field of the variant and also I couldn't find another way to access the product/variant/color-specific images except with the hacked field and manually typing in the color name that ASPDNSF uses based on the pretty color name.

    This is highly customized for just my site and only works with a fair amount of manual data entry in the hi-jacked fields, but worked for me since I only have 20 products on my site (www.cm4.com). Hopefully this will help someone as they're trying to accomplish a similar task.

    Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- ###################################################################################################### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2009.  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 displayname="Google Base RSS 2.0 Feed" version="2.1" debug="false" includeentityhelper="false">
      <query name="Products" rowElementName="Product">
        <sql>
    
          <![CDATA[
    select
    	p.productid,
    	pv.variantid,
    	p.sku,
    	i.vendorfullsku as id, 
    	p.name + ' (' + i.vendorid + ')' as title, 
    	isnull(p.FroogleDescription, '') as description, 
    	p.extensiondata as google_product_category,
    	p.extensiondata as product_type,
    	i.warehouselocation as imagecolor,
    	i.extensiondata as gtin,
    	pv.name as item_group_id,
    	i.vendorid as color,
    	p.misctext as material,
    	convert(VARCHAR(10), pv.weight) + 'lb' as shipping_weight,
    	pv.price, 
    	p.sename, 
    	p.SEKeywords,
    	m.Name as brand
    from 
    
    	dbo.product p with (nolock) 
    	join dbo.productvariant pv with (nolock) on p.productid = pv.productid
    	join (Select ProductID, MIN(CategoryID) as CategoryID from productcategory group by ProductID) pc on p.ProductID = pc.ProductID 
    	join category c with (nolock) on pc.CategoryID = c.CategoryID
    	left join ProductManufacturer pm with (nolock) on p.ProductID = pm.ProductID
    	left join Manufacturer m with (nolock) on pm.ManufacturerID = m.ManufacturerID
    	join Inventory i with (nolock) on pv.variantid = i.variantid
    where 
    	p.IsSystem=0 
    	and p.deleted = 0 
    	and p.published = 1 
    	and p.ExcludeFromPriceFeeds = 0 
    	and c.ParentCategoryID = 0
    	and i.vendorfullsku <> ''
    order by p.productid
    
    			]]>
        </sql>
      </query>
      <PackageTransform>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aspdnsf="urn:aspdnsf"   xmlns:g="http://base.google.com/ns/1.0" exclude-result-prefixes="aspdnsf">
          <xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="no" />
    
          <xsl:param name="EntityName">
            <xsl:value-of select="/root/QueryString/entity" />
          </xsl:param>
    
          <xsl:param name="ShowInGrid">true</xsl:param>
          <xsl:param name="GridCols">4</xsl:param>
          <xsl:param name="UseDescr" select="aspdnsf:AppConfig('Froogle_UseDescriptionsIfFroogleDescEmpty')" />
    
          <xsl:param name="LocaleSetting" select="/root/Runtime/LocaleSetting" />
          <xsl:param name="WebConfigLocaleSetting" select="/root/Runtime/WebConfigLocaleSetting" />
    
          <xsl:template match="/">
            <rss version="2.0">
              <channel>
                <title>
                  <xsl:value-of select="aspdnsf:AppConfig('StoreName')" />
                </title>
                <link>
                  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" />
                </link>
                <description>
                  <xsl:value-of select="aspdnsf:AppConfig('RSSChannelDescr')" />
                </description>
                <language>
                  <xsl:value-of select="$WebConfigLocaleSetting" />
                </language>
                <pubDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </pubDate>
                <lastBuildDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </lastBuildDate>
                <xsl:apply-templates select="/root/Products/Product" />
              </channel>
            </rss>
          </xsl:template>
    
    	<xsl:template name="AdditionalImages">
    		<xsl:param name="imageNum" select="1"></xsl:param>
            <xsl:param name="productid" select="aspdnsf:GetMLValue(productid)"></xsl:param>
            <xsl:param name="imagecolor" select="aspdnsf:GetMLValue(imagecolor)"></xsl:param>
            <xsl:param name="image"><xsl:text>../../shop/images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_</xsl:text><xsl:value-of select="$imageNum" /><xsl:text>_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text></xsl:param>
            <xsl:param name="imageURL"><xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" /><xsl:text>images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_</xsl:text><xsl:value-of select="$imageNum" /><xsl:text>_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text></xsl:param>
    		
    		<xsl:if test="$imageNum &lt; 11">
    
    		<xsl:if test="aspdnsf:FileExists($image)">
    				<g:additional_image_link>
    				  <xsl:value-of select="$imageURL" />
    				</g:additional_image_link>
    			</xsl:if>
    
    			<xsl:call-template name="AdditionalImages">
    				<xsl:with-param name="imageNum" select="$imageNum + 1"/>
    				<xsl:with-param name="productid" select="$productid"/>
    				<xsl:with-param name="imagecolor" select="$imagecolor"/>
    			</xsl:call-template>
    		</xsl:if>		
    	  </xsl:template>
    	  
          <xsl:template match="Product">
            <xsl:param name="productid" select="aspdnsf:GetMLValue(productid)"></xsl:param>
            <xsl:param name="VariantID" select="aspdnsf:GetMLValue(variantid)"></xsl:param>
            <xsl:param name="SKU" select="aspdnsf:GetMLValue(SKU)"></xsl:param>
            <xsl:param name="id" select="aspdnsf:GetMLValue(id)"></xsl:param>
            <xsl:param name="title" select="aspdnsf:GetMLValue(title)"></xsl:param>
            <xsl:param name="description" select="aspdnsf:GetMLValue(description)"></xsl:param>
            <xsl:param name="google_product_category" select="aspdnsf:GetMLValue(google_product_category)"></xsl:param>
            <xsl:param name="product_type" select="aspdnsf:GetMLValue(product_type)"></xsl:param>
            <xsl:param name="imagecolor" select="aspdnsf:GetMLValue(imagecolor)"></xsl:param>
            <xsl:param name="gtin" select="aspdnsf:GetMLValue(gtin)"></xsl:param>
            <xsl:param name="item_group_id" select="aspdnsf:GetMLValue(item_group_id)"></xsl:param>
            <xsl:param name="color" select="aspdnsf:GetMLValue(color)"></xsl:param>
            <xsl:param name="material" select="aspdnsf:GetMLValue(material)"></xsl:param>
            <xsl:param name="shipping_weight" select="aspdnsf:GetMLValue(shipping_weight)"></xsl:param>
            <xsl:param name="price" select="aspdnsf:GetMLValue(price)"></xsl:param>
            <xsl:param name="sename" select="aspdnsf:GetMLValue(sename)"></xsl:param>
            <xsl:param name="Keywords" select="aspdnsf:GetMLValue(SEKeywords)"></xsl:param>
            <xsl:param name="brand" select="aspdnsf:GetMLValue(brand)"></xsl:param>
            
    
              <item>
                <g:id>
                  <xsl:value-of select="$id" />
                </g:id>
                <g:title>
                  <xsl:value-of select="$title" />
                </g:title>
                <g:description>
                  <xsl:value-of select="$description" />
                </g:description>
                <g:google_product_category>
                  <xsl:value-of select="$google_product_category" />
                </g:google_product_category>
                <g:product_type>
                  <xsl:value-of select="$product_type" />
                </g:product_type>
                <link>
                  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" />
                  <xsl:value-of select="aspdnsf:ProductLink(productid, sename, 0, '')" />
                </link>
    			<g:image_link>
    			  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" /><xsl:text>images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_1_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text>
                </g:image_link>
    			<xsl:call-template name="AdditionalImages">
    				<xsl:with-param name="imageNum" select="2"/>
    				<xsl:with-param name="productid" select="$productid"/>
    				<xsl:with-param name="imagecolor" select="$imagecolor"/>
    			</xsl:call-template>
                <g:condition>New</g:condition>
                <g:availability>in stock</g:availability>
                <g:price>
    			  <xsl:value-of select="format-number((price), '###0.00')" />
                </g:price>
                <g:brand>
                  <xsl:value-of select="$brand" />
                </g:brand>
                <g:gtin>
                  <xsl:value-of select="$gtin" />
                </g:gtin>
                <g:mpn>
                  <xsl:value-of select="$id" />
                </g:mpn>
                <g:item_group_id>
                  <xsl:value-of select="$item_group_id" />
                </g:item_group_id>
                <g:color>
                  <xsl:value-of select="$color" />
                </g:color>
                <g:material>
                  <xsl:value-of select="$material" />
                </g:material>
              </item>
    
          </xsl:template>
    	  
        </xsl:stylesheet>
      </PackageTransform>
    </package>

  2. #2
    ACENUMBER5 is offline Junior Member
    Join Date
    Feb 2012
    Location
    Dallas, TX
    Posts
    10

    Default Nice!

    Nice work on the inventory table!
    How come you did it this way instead of using dotfeed?

    I'm trying to do something similar to extract the data for the shopsavvy product feed. I haven't submitted it yet, but I don't think it's as picky as google's feed.

    Best of luck,
    Andrew

  3. #3
    maltschul is offline Junior Member
    Join Date
    May 2010
    Posts
    13

    Default

    I hacked the inventory table instead of using Dotfeed because 1.) I'm cheap and 2.) I didn't know if Dotfeed would support listing multiple color variations as separate products bound as a single item-group per Google's standards. From what I read, Dotfeed would just list items and variants, but not color or size variations.

    Again, it's a major hack and will only work on a small scale, but worked for my company our 18 products.

  4. #4
    PowerProducts is offline Member
    Join Date
    Oct 2010
    Location
    Spokane, WA
    Posts
    40

    Default

    Quote Originally Posted by maltschul View Post
    I spent a fair amount of time crafting a google shopping feed that lists all products/variants/colors with images for each specific product/variant/color combination and grouped the colors together in a single variant per Google's specs (as of 6/30/12). Also includes additional images for each color if exists. I've hacked the inventory table to make this all happen. Using warehouselocation, extendeddata, and vendorfullsku to populate the gtin and to be able to query on each color. I couldn't find a way to make this happen in a query any other way since the colors are kept in a single, comma-delimited field of the variant and also I couldn't find another way to access the product/variant/color-specific images except with the hacked field and manually typing in the color name that ASPDNSF uses based on the pretty color name.

    This is highly customized for just my site and only works with a fair amount of manual data entry in the hi-jacked fields, but worked for me since I only have 20 products on my site (www.cm4.com). Hopefully this will help someone as they're trying to accomplish a similar task.

    Code:
    <?xml version="1.0" encoding="utf-8" ?>
    <!-- ###################################################################################################### -->
    <!-- Copyright AspDotNetStorefront.com, 1995-2009.  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 displayname="Google Base RSS 2.0 Feed" version="2.1" debug="false" includeentityhelper="false">
      <query name="Products" rowElementName="Product">
        <sql>
    
          <![CDATA[
    select
    	p.productid,
    	pv.variantid,
    	p.sku,
    	i.vendorfullsku as id, 
    	p.name + ' (' + i.vendorid + ')' as title, 
    	isnull(p.FroogleDescription, '') as description, 
    	p.extensiondata as google_product_category,
    	p.extensiondata as product_type,
    	i.warehouselocation as imagecolor,
    	i.extensiondata as gtin,
    	pv.name as item_group_id,
    	i.vendorid as color,
    	p.misctext as material,
    	convert(VARCHAR(10), pv.weight) + 'lb' as shipping_weight,
    	pv.price, 
    	p.sename, 
    	p.SEKeywords,
    	m.Name as brand
    from 
    
    	dbo.product p with (nolock) 
    	join dbo.productvariant pv with (nolock) on p.productid = pv.productid
    	join (Select ProductID, MIN(CategoryID) as CategoryID from productcategory group by ProductID) pc on p.ProductID = pc.ProductID 
    	join category c with (nolock) on pc.CategoryID = c.CategoryID
    	left join ProductManufacturer pm with (nolock) on p.ProductID = pm.ProductID
    	left join Manufacturer m with (nolock) on pm.ManufacturerID = m.ManufacturerID
    	join Inventory i with (nolock) on pv.variantid = i.variantid
    where 
    	p.IsSystem=0 
    	and p.deleted = 0 
    	and p.published = 1 
    	and p.ExcludeFromPriceFeeds = 0 
    	and c.ParentCategoryID = 0
    	and i.vendorfullsku <> ''
    order by p.productid
    
    			]]>
        </sql>
      </query>
      <PackageTransform>
        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aspdnsf="urn:aspdnsf"   xmlns:g="http://base.google.com/ns/1.0" exclude-result-prefixes="aspdnsf">
          <xsl:output method="xml" omit-xml-declaration="no" encoding="utf-8" indent="no" />
    
          <xsl:param name="EntityName">
            <xsl:value-of select="/root/QueryString/entity" />
          </xsl:param>
    
          <xsl:param name="ShowInGrid">true</xsl:param>
          <xsl:param name="GridCols">4</xsl:param>
          <xsl:param name="UseDescr" select="aspdnsf:AppConfig('Froogle_UseDescriptionsIfFroogleDescEmpty')" />
    
          <xsl:param name="LocaleSetting" select="/root/Runtime/LocaleSetting" />
          <xsl:param name="WebConfigLocaleSetting" select="/root/Runtime/WebConfigLocaleSetting" />
    
          <xsl:template match="/">
            <rss version="2.0">
              <channel>
                <title>
                  <xsl:value-of select="aspdnsf:AppConfig('StoreName')" />
                </title>
                <link>
                  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" />
                </link>
                <description>
                  <xsl:value-of select="aspdnsf:AppConfig('RSSChannelDescr')" />
                </description>
                <language>
                  <xsl:value-of select="$WebConfigLocaleSetting" />
                </language>
                <pubDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </pubDate>
                <lastBuildDate>
                  <xsl:value-of select="/root/System/CurrentDateTime" />
                </lastBuildDate>
                <xsl:apply-templates select="/root/Products/Product" />
              </channel>
            </rss>
          </xsl:template>
    
    	<xsl:template name="AdditionalImages">
    		<xsl:param name="imageNum" select="1"></xsl:param>
            <xsl:param name="productid" select="aspdnsf:GetMLValue(productid)"></xsl:param>
            <xsl:param name="imagecolor" select="aspdnsf:GetMLValue(imagecolor)"></xsl:param>
            <xsl:param name="image"><xsl:text>../../shop/images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_</xsl:text><xsl:value-of select="$imageNum" /><xsl:text>_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text></xsl:param>
            <xsl:param name="imageURL"><xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" /><xsl:text>images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_</xsl:text><xsl:value-of select="$imageNum" /><xsl:text>_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text></xsl:param>
    		
    		<xsl:if test="$imageNum &lt; 11">
    
    		<xsl:if test="aspdnsf:FileExists($image)">
    				<g:additional_image_link>
    				  <xsl:value-of select="$imageURL" />
    				</g:additional_image_link>
    			</xsl:if>
    
    			<xsl:call-template name="AdditionalImages">
    				<xsl:with-param name="imageNum" select="$imageNum + 1"/>
    				<xsl:with-param name="productid" select="$productid"/>
    				<xsl:with-param name="imagecolor" select="$imagecolor"/>
    			</xsl:call-template>
    		</xsl:if>		
    	  </xsl:template>
    	  
          <xsl:template match="Product">
            <xsl:param name="productid" select="aspdnsf:GetMLValue(productid)"></xsl:param>
            <xsl:param name="VariantID" select="aspdnsf:GetMLValue(variantid)"></xsl:param>
            <xsl:param name="SKU" select="aspdnsf:GetMLValue(SKU)"></xsl:param>
            <xsl:param name="id" select="aspdnsf:GetMLValue(id)"></xsl:param>
            <xsl:param name="title" select="aspdnsf:GetMLValue(title)"></xsl:param>
            <xsl:param name="description" select="aspdnsf:GetMLValue(description)"></xsl:param>
            <xsl:param name="google_product_category" select="aspdnsf:GetMLValue(google_product_category)"></xsl:param>
            <xsl:param name="product_type" select="aspdnsf:GetMLValue(product_type)"></xsl:param>
            <xsl:param name="imagecolor" select="aspdnsf:GetMLValue(imagecolor)"></xsl:param>
            <xsl:param name="gtin" select="aspdnsf:GetMLValue(gtin)"></xsl:param>
            <xsl:param name="item_group_id" select="aspdnsf:GetMLValue(item_group_id)"></xsl:param>
            <xsl:param name="color" select="aspdnsf:GetMLValue(color)"></xsl:param>
            <xsl:param name="material" select="aspdnsf:GetMLValue(material)"></xsl:param>
            <xsl:param name="shipping_weight" select="aspdnsf:GetMLValue(shipping_weight)"></xsl:param>
            <xsl:param name="price" select="aspdnsf:GetMLValue(price)"></xsl:param>
            <xsl:param name="sename" select="aspdnsf:GetMLValue(sename)"></xsl:param>
            <xsl:param name="Keywords" select="aspdnsf:GetMLValue(SEKeywords)"></xsl:param>
            <xsl:param name="brand" select="aspdnsf:GetMLValue(brand)"></xsl:param>
            
    
              <item>
                <g:id>
                  <xsl:value-of select="$id" />
                </g:id>
                <g:title>
                  <xsl:value-of select="$title" />
                </g:title>
                <g:description>
                  <xsl:value-of select="$description" />
                </g:description>
                <g:google_product_category>
                  <xsl:value-of select="$google_product_category" />
                </g:google_product_category>
                <g:product_type>
                  <xsl:value-of select="$product_type" />
                </g:product_type>
                <link>
                  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" />
                  <xsl:value-of select="aspdnsf:ProductLink(productid, sename, 0, '')" />
                </link>
    			<g:image_link>
    			  <xsl:value-of select="concat('http',substring-after(/root/System/StoreUrl,'https'))" /><xsl:text>images/Product/large/</xsl:text><xsl:value-of select="$productid" /><xsl:text>_1_</xsl:text><xsl:value-of select="$imagecolor" /><xsl:text>.jpg</xsl:text>
                </g:image_link>
    			<xsl:call-template name="AdditionalImages">
    				<xsl:with-param name="imageNum" select="2"/>
    				<xsl:with-param name="productid" select="$productid"/>
    				<xsl:with-param name="imagecolor" select="$imagecolor"/>
    			</xsl:call-template>
                <g:condition>New</g:condition>
                <g:availability>in stock</g:availability>
                <g:price>
    			  <xsl:value-of select="format-number((price), '###0.00')" />
                </g:price>
                <g:brand>
                  <xsl:value-of select="$brand" />
                </g:brand>
                <g:gtin>
                  <xsl:value-of select="$gtin" />
                </g:gtin>
                <g:mpn>
                  <xsl:value-of select="$id" />
                </g:mpn>
                <g:item_group_id>
                  <xsl:value-of select="$item_group_id" />
                </g:item_group_id>
                <g:color>
                  <xsl:value-of select="$color" />
                </g:color>
                <g:material>
                  <xsl:value-of select="$material" />
                </g:material>
              </item>
    
          </xsl:template>
    	  
        </xsl:stylesheet>
      </PackageTransform>
    </package>
    Thank you so much for posting this! I did not need the whole code, but one piece of your code saved me a lot of time. I really appreciate it!
    Currently running 9.3 Multistore on 5 sites.