<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>Web Development, SEO and Project Management</title>
	<atom:link href="http://www.webopius.com/content/feed" rel="self" type="application/rss+xml" />
	<link>http://www.webopius.com/content</link>
	<description>Web Design &#38; Development, SEO and Project Management</description>
	<pubDate>Sun, 07 Mar 2010 15:24:20 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating a new ASPDotNetStorefront paging control</title>
		<link>http://www.webopius.com/content/376/creating-a-new-aspdotnetstorefront-paging-control</link>
		<comments>http://www.webopius.com/content/376/creating-a-new-aspdotnetstorefront-paging-control#comments</comments>
		<pubDate>Sun, 07 Mar 2010 15:24:20 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Web Content Pages]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[modules]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=376</guid>
		<description><![CDATA[The standard ASPDotNetStorefront paging control looks something like this:

Nothing particularly wrong with the idea but it is generated as a series of &#60;a&#62; tags without css id or class names. As a result, it offers limited capability for styling to match your store and more importantly, if you have many pages, the standard ASPDotNetStorefront control [...]]]></description>
			<content:encoded><![CDATA[<p>The standard ASPDotNetStorefront paging control looks something like this:</p>
<p><img class="alignnone size-full wp-image-430" title="paging-old" src="http://www.webopius.com/content/wp-content/uploads/2009/12/paging-old.png" alt="paging-old" width="313" height="35" /></p>
<p>Nothing particularly wrong with the idea but it is generated as a series of <code>&lt;a&gt;<!--formatted--></code> tags without css id or class names. As a result, it offers limited capability for styling to match your store and more importantly, if you have many pages, the standard ASPDotNetStorefront control can get quite wide because all pages available are shown.</p>
<h2>An improved, styled ASPDotNetStorefront paging control</h2>
<p>Webopius have developed a new paging control that will be familiar to users of sites such as FlickR, it looks like this:<br />
<img src="http://www.webopius.com/content/wp-content/uploads/2010/03/paging-new1.png" alt="New ASPDotNetStorefront paging control" title="New ASPDotNetStorefront paging control" width="481" height="50" class="size-full wp-image-432" /></p>
<p>I hope you agree, it looks better? More importantly, it only shows the first page, the last page and a maximum of two available pages either side of the current page. If your store&#8217;s category has a lot of product results, the control never gets too large. Also, the control is rendered as an unordered list <code>&lt;ul&gt;<!--formatted--></code> with the class name &#8216;paginator&#8217;. The current page is identified with the class name &#8216;thispage&#8217;. </p>
<p>The result is a much more elegant paging control that can easily be styled with CSS to suit your store. </p>
<h2>A direct replacement for the existing ASPDotNetStorefront paging control</h2>
<p>Our new paging control can be inserted as a direct replacement for the existing ASPDotNetStorefront page control by replacing the existing line in your XSL templates:</p>
<pre><code>
&lt;xsl:value-of select=&quot;aspdnsf:PagingControl($BaseURL, $CurrentPage, /root/Products2/Product/pages)&quot; disable-output-escaping=&quot;yes&quot; /&gt;
<!--formatted--></code></pre>
<p>With this:</p>
<pre><code>
&lt;xsl:value-of select=&quot;Webopius:CustPagingControl($BaseURL, $CurrentPage, /root/Products2/Product/pages, 12, $TotalProducts)&quot; disable-output-escaping=&quot;yes&quot; /&gt;
<!--formatted--></code></pre>
<h2>No source code required</h2>
<p>This new control has been implemented as a stand-alone library and just needs copying into your store with a one line change to the web.config file. You do not need the ASPDotNetStorefront source code to implement this control on your site.</p>
<p>If you would like a copy of this paging control installed into your store to improve your <a href="/enquiry.php" title="ASPDotNetStorefront development services">ASPDotNetStorefront site&#8217;s visitor experience, please contact us</a>. We can usually have it installed and tested within an hour.</p>
<h2>Other ASPDotNetStorefront Enhancements available</h2>
<p>You might also be interested in other enhancements we have available for your ASPDotNetStorefront store, including:</p>
<ul>
<li>iPhone and mobile versions of ASPDotNetStorefront templates for your store</li>
<li>Sort ASPDotNetStorefront product results by price and name</li>
<li>For multi-language sites, sort product results based on the language the user is viewing the site in</li>
<li>Overlay product images with icons such as &#8216;Sale&#8217;, &#8216;Top seller&#8217;, &#8216;Rare!&#8217; - you choose the icon, you set a flag on the product and the icons are automatically generated</li>
<li>Featured product, random product or latest product shown at the top of your category results</li>
<li>Featured product carousel on your ASPDotNetStorefront site home page</li>
<li>Custom styling of the shopping cart without requiring the source code</li>
<li>Multi-language product import module</li>
<li>Bulk image resizing system for ASPDotNetStorefront - scans all your large images and automatically creates icon and medium images</li>
<li>Custom product fields and custom product to product relationships</li>
</ul>
<p>&#8230;and the list goes on. We have worked with ASPDotNetStorefront for many years and believe we provide one of the <a href="/enquiry.php">best ASPDotNetStorefront development and support services for your business</a>. Why not try Webopius?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/376/creating-a-new-aspdotnetstorefront-paging-control/feed</wfw:commentRss>
		</item>
		<item>
		<title>Consorzio Triveneto payment gateway for ASPDotNetStorefront (ASPDNSF)</title>
		<link>http://www.webopius.com/content/422/consorzio-triveneto-payment-gateway-for-aspdotnetstorefront-aspdnsf</link>
		<comments>http://www.webopius.com/content/422/consorzio-triveneto-payment-gateway-for-aspdotnetstorefront-aspdnsf#comments</comments>
		<pubDate>Fri, 05 Mar 2010 11:19:50 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[modules]]></category>

		<category><![CDATA[triveneto]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=422</guid>
		<description><![CDATA[We&#8217;ve recently written a new payment gateway for ASPDotNetStorefront allowing stores to make payments using the Consorzio Triveneto payment system. Consorzio Triveneto is a &#8216;boomerang&#8217; gateway that takes the customer off the store to a hosted payment page to enter their card details before returning them back. It operates in a similar way to other [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve recently written a new payment gateway for ASPDotNetStorefront allowing stores to make payments using the Consorzio Triveneto payment system. Consorzio Triveneto is a &#8216;boomerang&#8217; gateway that takes the customer off the store to a hosted payment page to enter their card details before returning them back. It operates in a similar way to other ASPDotNetStorefront boomerang gateways such as PayPal express and Worldpay.</p>
<h2>Writing a new ASPDotNetStorefront payment gateway</h2>
<p>In developing this new gateway, we spent a lot of time working in the payment processing system used in ASPDNSF and took advantage of the excellent, modular way in which you can easily extend the available number of payment methods. We thought it would be useful to share the method used.</p>
<p>If you are developing a new gateway, you will need to have purchased the ASPDotNetStorefront source code because it involves modifying the ASPDNSFGateways.dll library and making changes to the Checkout Payment pages.</p>
<h2>The payment gateway process in ASPDotNetStorefront</h2>
<p>An overview of the Consorzio Triveneto gateway process within ASPDNSF is shown to the right.</p>
<blockquote class="citeright"><p>
<img src="http://www.webopius.com/content/wp-content/uploads/2010/03/flow.png" alt="ASPDNSF Triveneto Payment gateway flow" title="ASPDotNetStorefront Triveneto Payment gateway flow" width="350" height="739"  />
</p></blockquote>
<p>It works in a slightly different way to a gateway like Worldpay, in that before you are taken to the Triveneto Payment screen, you need to send the gateway the payment details and you receive back the URL for making payment. The final step is also different in that you have to pass back a URL to Triveneto informing it which page to send the customer to (Error or Order Confirmation).</p>
<p>In addition to making changes to the gateway library and checkout payment pages, we created three new aspx pages specific to the Triveneto Gateway: trivenetoprocess, trivenetoerror and trivenetosuccess.</p>
<p>The basic approach in writing the gateway was:</p>
<h2>Step 1 - Tell the ASPDotNetStorefront configuration wizard about your new gateway</h2>
<p>The first step in creating a new gateway is to give it a unique identifier and update the ASPDotNetStorefront admin system&#8217;s configuration wizard so that it offers the new gateway as a configuration choice. </p>
<p>In our example, we used the identifier &#8216;TRIVENETO&#8217; for our new gateway and edited the admin directory file wizard.aspx with a new line:</p>
<pre><code>
&lt;asp:ListItem Value=&quot;TRIVENETO&quot;&gt;Consorzio Triveneto&lt;/asp:ListItem&gt;
<!--formatted--></code></pre>
<h2>Step 2 - Update the ASPDotNetStorefront Gateway library</h2>
<p>Next, we modified the ASPSNDSF Gateway library to recognize &#8216;TRIVENETO&#8217; as a valid gateway and added code in to receive information during a Make Payment request. If the order is successful, the gateway simply returns and the customer is sent to the order confirmation page. If unsuccessful, the gateway creates a record in the failed transactions table with the technical details of the failure and the customer is taken to the error page before returning to the shopping cart.</p>
<h2>Step 3 - Update the Checkout payment page</h2>
<p>The next stage is to update the checkout payment page so that it can send a payment request to the hosted payment page. This is a case of creating a form containing the payment elements (currency, language, amount, tracking id etc).</p>
<p>You will need to edit the source of checkoutpayment.aspx.cs and create a new if statement for your gateway. In our case, we created an &#8216;if {GW== Gateway.ro_GWTRIVENTO} &#8230;&#8217; section.</p>
<p>Triveneto requires URLs to be passed for both error and standard response conditions. We created new AppConfig values for these and also added support for both Test and Live payment processing.</p>
<p>In our model, the checkout payment form sends the payment information to the new page called &#8216;trivenetoprocess.aspx&#8217;. </p>
<h2>Step 4 - Capture the payment</h2>
<p>trivenetoprocess.aspx takes the payment information received from checkoutpayment.aspx and creates a URL format specific to the Consorzio Triveneto gateway specification. This URL is then sent to the Live/Test payment URL which returns a unique Payment ID and Payment URL, or an Error message.</p>
<p>The Customer is then sent to the Payment URL to enter their credit card details.</p>
<h2>Step 5 - Handle errors</h2>
<p>If the Customer enters incorrect card details, Triveneto returns them to the error URL on your site, in our case, this is trivenetoerror.aspx. Trivenetoerror.aspx parses the error information and presents a description of the error to the Customer. The Customer then clicks on a link to be taken back to the shopping cart.</p>
<h2>Step 6 - Handle payment processing</h2>
<p>With correct card details, Triveneto will process the payment and return the Customer to the trivenetosuccess.aspx page. Despite the filename, the transaction may still have been rejected (such as due to an authorisation issue). This page checks the state of the payment and if successful, creates a new order record within ASPDotNetStorefront.</p>
<h2>New payment gateways for ASPDotNetStorefront</h2>
<p>If you would like to discuss development and installation of <a href="/enquiry.php">new or existing payment gateways for ASPDotNetStorefront, please contact us</a>. Webopius have extensive experience in developing for ASPDotNetStorefront and always spend time understanding your business and requirements.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/422/consorzio-triveneto-payment-gateway-for-aspdotnetstorefront-aspdnsf/feed</wfw:commentRss>
		</item>
		<item>
		<title>Showing a random product on your homepage in OpenCart</title>
		<link>http://www.webopius.com/content/416/showing-a-random-product-on-your-homepage-in-opencart</link>
		<comments>http://www.webopius.com/content/416/showing-a-random-product-on-your-homepage-in-opencart#comments</comments>
		<pubDate>Sun, 28 Feb 2010 16:46:45 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[modules]]></category>

		<category><![CDATA[opencart]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=416</guid>
		<description><![CDATA[Another OpenCart article today (see link to the right). After this, we&#8217;ll be writing some new ASPDotNetStorefront tutorials.

Related Links&#8230;
OpenCart Open Source shopping


This tutorial will show you how to extend OpenCart and retrieve a random product from your product catalogue to display on the homepage. Each time a user refreshes the page, or a new visitor [...]]]></description>
			<content:encoded><![CDATA[<p>Another OpenCart article today (see link to the right). After this, we&#8217;ll be writing some new <a href="/content/tag/aspdotnetstorefront">ASPDotNetStorefront tutorials</a>.</p>
<blockquote class="citeright"><p>
<b>Related Links&#8230;</b><br />
<a href="http://www.opencart.com/" rel="nofollow">OpenCart Open Source shopping</a>
</p>
</blockquote>
<p>This tutorial will show you how to extend OpenCart and retrieve a random product from your product catalogue to display on the homepage. Each time a user refreshes the page, or a new visitor goes to your site, a different product will be shown.</p>
<p>First, a big thank you to the author of article on <a rel="nofollow" href="http://www.greggdev.com/web/articles.php?id=6">Gregg Website Development</a> who showed a method for quickly retrieving random rows from MySQL on large datasets with minimal performance impact.</p>
<h2>Step 1. Extend your product model with a getRandomProduct() function</h2>
<p>The OpenCart MVC model shows it&#8217;s power here as we add a new function to the product model. Edit the &#8216;product.php&#8217; file located in your site&#8217;s /catalog/model/catalog/product directory and add a new function called getRandomProduct() to the class as follows:</p>
<pre><code>
// Retrieve a random product from the database
public function getRandomProduct() {
   $maxminid = $this-&gt;db-&gt;query(&quot;SELECT MAX(product_id) as max_id, MIN(product_id) as min_id from &quot;. DB_PREFIX . &quot;product p&quot;);
   $maxrow = -1;
   $minrow = -1;
   if ($maxminid-&gt;num_rows) {
        $maxrow = $maxminid-&gt;row[&#039;max_id&#039;];
        $minrow = $maxminid-&gt;row[&#039;min_id&#039;];
    }
   $randomrow = mt_rand($minrow, $maxrow);

   $query = $this-&gt;db-&gt;query(&quot;SELECT DISTINCT *, pd.name AS name, pd.short_description as short_description, p.image, m.name AS manufacturer, ss.name AS stock FROM &quot; . DB_PREFIX . &quot;product p LEFT JOIN &quot; . DB_PREFIX . &quot;product_description pd ON (p.product_id = pd.product_id) LEFT JOIN &quot; . DB_PREFIX . &quot;manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN &quot; . DB_PREFIX . &quot;stock_status ss ON (p.stock_status_id = ss.stock_status_id) WHERE p.product_id &gt;= &#039;&quot; . (int)$randomrow . &quot;&#039; AND pd.language_id = &#039;&quot; . (int)$this-&gt;language-&gt;getId() . &quot;&#039; AND ss.language_id = &#039;&quot; . (int)$this-&gt;language-&gt;getId() . &quot;&#039; AND p.date_available &lt;= NOW() AND p.status = &#039;1&#039; order by p.product_id ASC limit 1&quot;);

    if (!$query-&gt;row) {
        $query = $this-&gt;db-&gt;query(&quot;SELECT DISTINCT *, pd.name AS name, pd.short_description as short_description, p.image, m.name AS manufacturer, ss.name AS stock FROM &quot; . DB_PREFIX . &quot;product p LEFT JOIN &quot; . DB_PREFIX . &quot;product_description pd ON (p.product_id = pd.product_id) LEFT JOIN &quot; . DB_PREFIX . &quot;manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN &quot; . DB_PREFIX . &quot;stock_status ss ON (p.stock_status_id = ss.stock_status_id) WHERE p.product_id &lt; &#039;&quot; . (int)$randomrow . &quot;&#039; AND pd.language_id = &#039;&quot; . (int)$this-&gt;language-&gt;getId() . &quot;&#039; AND ss.language_id = &#039;&quot; . (int)$this-&gt;language-&gt;getId() . &quot;&#039; AND p.date_available &lt;= NOW() AND p.status = &#039;1&#039; order by p.product_id DESC limit 1&quot;);
    }
    return $query-&gt;row;
}
<!--formatted--></code></pre>
<p>What this function does is find the maximum and minimum product ids in your database and generates a random value in this range.</p>
<p>It then looks for a product row with an ID >= the random ID. If none is found, it selects an ID less than the random ID. The product row is returned.</p>
<h2>Step 2. Change your homepage controller to ask for a random product</h2>
<p>Now, you can change any of your OpenCart controller pages to retrieve a random product. In this example, we will use the homepage controller. Find the file &#8216;home.php&#8217; in your site&#8217;s /catalog/controller/common directory.</p>
<p>Insert the following lines into the code:</p>
<pre><code>
$featured = $this-&gt;model_catalog_product-&gt;getRandomProduct();
$this-&gt;data[&#039;featuredproduct&#039;] = array(
    &#039;name&#039; =&gt; $featured[&#039;name&#039;],
    &#039;thumb&#039;   =&gt; image_resize($featured[&#039;image&#039;], 165, 165),
    &#039;href&#039; =&gt; $this-&gt;model_tool_seo_url-&gt;rewrite($this-&gt;url-&gt;http(&#039;product/product&amp;product_id=&#039; . $featured[&#039;product_id&#039;]))
);
<!--formatted--></code></pre>
<p>This example just uses the product&#8217;s name, image thumb and URL but you can use any other available product fields returned by the SQL you created earlier. This code will create an array called $featuredproduct[] containing a single random product that can be used on your home page.</p>
<h2>Step 3. Add the featured product to your home page</h2>
<p>The last step involves rendering the featured product on your home page. How and where you place the product will depend very much on your site&#8217;s template and styles. The example below just shows how to display the results - you will probably want to wrap the code with css for styling.</p>
<p>Edit the home.tpl file with your site&#8217;s /catalog/view/theme/[your theme]/template/common directory and insert the following lines at the point you want the featured product displayed:</p>
<pre><code>
&lt;b&gt;Featured Product...&lt;/b&gt;
&lt;?php echo &#039;&lt;a class=&quot;image&quot; href=&quot;&#039; . $featuredproduct[&#039;href&#039;] .&#039;&quot; title=&quot;&#039; . $featuredproduct[&#039;name&#039;] . &#039;&quot;&gt;&lt;img src=&quot;&#039;.$featuredproduct[&#039;thumb&#039;].&#039;&quot; alt=&quot;&#039; . $featuredproduct[&#039;name&#039;].&#039;&quot;/&gt;&lt;/a&gt;&#039;; ?&gt;
&lt;?php echo &#039;&lt;b&gt;&lt;a href=&quot;&#039; . $featuredproduct[&#039;href&#039;] .&#039;&quot; title=&quot;&#039; . $featuredproduct[&#039;name&#039;] . &#039;&quot;&gt;&#039;. $featuredproduct[&#039;name&#039;].&#039;&lt;/a&gt;&lt;/b&gt;&#039;; ?&gt;
<!--formatted--></code></pre>
<p>This code uses the $featuredproduct[] variable that you just created in the controller code and places a featured product thumbnail image, link and description on the home page.</p>
<h2>More OpenCart features</h2>
<p>This is just one example of how OpenCart can easily be extended. We have also implemented full SEO friendly URLs, news pages, <a href="/content/406/creating-image-watermarks-in-opencart">product image watermarks</a> and an updated product export/import system.</p>
<p>If you would like to discuss implementing an <a href="/enquiry.php">e-commerce solution based on OpenCart</a>, please get in touch.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/416/showing-a-random-product-on-your-homepage-in-opencart/feed</wfw:commentRss>
		</item>
		<item>
		<title>Creating image watermarks in OpenCart</title>
		<link>http://www.webopius.com/content/406/creating-image-watermarks-in-opencart</link>
		<comments>http://www.webopius.com/content/406/creating-image-watermarks-in-opencart#comments</comments>
		<pubDate>Sat, 27 Feb 2010 19:42:56 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[opencart]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=406</guid>
		<description><![CDATA[We&#8217;ve been using the fantastic OpenCart e-commerce system (see link to the right) for some time now on a number of sites.

Related Links&#8230;
OpenCart Open Source shopping

OpenCart has almost every feature that you need to build an e-commerce solution quickly. More importantly, it can be extended easily and has a strong online community. We&#8217;ve recently made [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been using the fantastic OpenCart e-commerce system (see link to the right) for some time now on a number of sites.</p>
<blockquote class="citeright"><p>
<b>Related Links&#8230;</b><br />
<a href="http://www.opencart.com/" rel="nofollow">OpenCart Open Source shopping</a>
</p></blockquote>
<p>OpenCart has almost every feature that you need to build an e-commerce solution quickly. More importantly, it can be extended easily and has a strong online community. We&#8217;ve recently made a simple enhancement to one of the stores we developed (the <a href="http://www.orchidstore.co.uk">Orchid Store</a>) to overlay product images with a watermark like this:</p>
<p><img src="http://www.webopius.com/content/wp-content/uploads/2010/02/orchid.jpg" alt="orchid" title="orchid" width="300" height="300" class="alignnone size-full wp-image-407" /></p>
<p>It&#8217;s a really simple change and I thought it would be useful to others if I posted how to do it. Please note, this solution is a &#8216;quick implementation&#8217; and can be enhanced further.</p>
<h2>Step 1. Create your watermark overlay image</h2>
<p>The first step is to create a small image that will become the watermark overlaying your product images. I would recommend using a transparent PNG format. In the example above, the background of the watermark is transparent and the text is set to 50% opacity.  </p>
<p>Save this image as &#8216;watermark.png&#8217;  in your site&#8217;s /images/userfiles directory.</p>
<h2>Step 2. Create some new OpenCart image functions</h2>
<p>The next step is to create a couple of new watermark functions within the OpenCart system area. Open the /system/library/image.php file.  You will see that there is already a watermark() function available. </p>
<p>In this example, we are going to create a new watermark function as it makes handling any upgrades of OpenCart slightly easier and you are adding to rather than changing any existing functionality. You may prefer to edit the existing watermark() function directly.</p>
<p>The new function looks like this:</p>
<pre>
<code>
public function addwatermark($position = &#039;bottomright&#039;) {
        $watermark = imagecreatefrompng(DIR_IMAGE . &#039;userfiles/watermark.png&#039;);
        $watermark_width = imagesx($watermark);
        $watermark_height = imagesy($watermark);

        switch($position) {
            case &#039;topleft&#039;:
                $watermark_pos_x = 0;
                $watermark_pos_y = 0;
                break;
            case &#039;topright&#039;:
                $watermark_pos_x = $this-&gt;info[&#039;width&#039;] - $watermark_width;
                $watermark_pos_y = 0;
                break;
            case &#039;bottomleft&#039;:
                $watermark_pos_x = 0;
                $watermark_pos_y = $this-&gt;info[&#039;height&#039;] - $watermark_height;
                break;
            case &#039;bottomright&#039;:
                $watermark_pos_x = $this-&gt;info[&#039;width&#039;] - $watermark_width;
                $watermark_pos_y = $this-&gt;info[&#039;height&#039;] - $watermark_height;
                break;
           case &#039;middle&#039;:
                $watermark_pos_x = ($this-&gt;info[&#039;width&#039;] - $watermark_width)/2;
                $watermark_pos_y = ($this-&gt;info[&#039;height&#039;] - $watermark_height)/2;
                break;
        }

        imagecopy($this-&gt;image, $watermark, $watermark_pos_x, $watermark_pos_y, 0, 0, $watermark_width, $watermark_height);
        imagedestroy($watermark);
     }
<!--formatted--></code></pre>
<p>What the function above is doing is creating an image object from your watermark (use imagecreatefromgif() if you have chosen a gif format) and then placing this watermark over the image (supplied in $this) in a position you specify (topleft, topright, bottomleft, bottomright or middle).</p>
<p>Now, edit /system/helper/image.php and add the following code as an additional function:</p>
<pre><code>
function image_watermark($filename) {
	if ( (!file_exists(DIR_IMAGE . $filename)) &amp;&amp; (!file_exists(DIR_IMAGE . &#039;cache/&#039; . $filename)) ) {
		return;
	} 

	if (file_exists(DIR_IMAGE . &#039;cache/&#039; . $filename)) {
		$old_image = DIR_IMAGE . &#039;cache/&#039; . $filename;
	} else {
		$old_image = DIR_IMAGE . $filename;
	}

	$new_image = &#039;cache/&#039; . substr($filename, 0, strrpos($filename, &#039;.&#039;)) . &#039;-w.jpg&#039;;

	if (!file_exists(DIR_IMAGE . $new_image) || (filemtime($old_image) &gt; filemtime(DIR_IMAGE . $new_image))) {
		$image = new Image($old_image);
		$image-&gt;addwatermark(&#039;middle&#039;);
		$image-&gt;save(DIR_IMAGE . $new_image);
	}

	if (isset($_SERVER[&#039;HTTPS&#039;]) &amp;&amp; (($_SERVER[&#039;HTTPS&#039;] == &#039;on&#039;) || ($_SERVER[&#039;HTTPS&#039;] == &#039;1&#039;))) {
		return HTTPS_IMAGE . $new_image;
	} else {
		return HTTP_IMAGE . $new_image;
	}
}
<!--formatted--></code></pre>
<p>What the above code is doing is being given a product image filename ($filename). It then checks in both the standard image directory and the cache directory for that product image. This is slightly non standard from the usual OpenCart which only looks in the main image directory. We added the second cache check because we will call this watermark function after the product image has been re-sized and placed in the cache directory.</p>
<p>What the code then does is create a new &#8216;watermarked&#8217; filename for the image by appending a &#8216;-w.jpg&#8217; to the existing filename. It then checks the cache to see if a watermark has already been created. If not, it calls the addwatermark() function we just created. The resulting watermarked image filename is then returned.</p>
<h3>Step 3. Modify your OpenCart product template to show the watermark</h3>
<p>The watermark function can of course be used in any templates and image fields you choose. In this example, we are using the &#8216;popup&#8217; product image field. Locate the product.php file in your sites /catalog/controller/product directory. Look for a line similar to this in the code:</p>
<pre><code>$this-&gt;data[&#039;popup&#039;]  = image_resize($image, $this-&gt;config-&gt;get(&#039;config_image_popup_width&#039;), $this-&gt;config-&gt;get(&#039;config_image_popup_height&#039;));	<!--formatted--></code></pre>
<p>&#8230;and change it to this:</p>
<pre><code>$productimage = image_resize($image, $this-&gt;config-&gt;get(&#039;config_image_popup_width&#039;),$this-&gt;config-&gt;get(&#039;config_image_popup_height&#039;));
$wmimage = image_watermark(basename($productimage));
$this-&gt;data[&#039;popup&#039;] = $wmimage;<!--formatted--></code></pre>
<p>This adds an additional step to the process. After resizing the image, the $productimage file will be placed in the cache. Image_watermark() is then called to overlay the product image with your watermark. </p>
<p>Hopefully, if you&#8217;ve followed these steps your site will now be showing product images with watermarks added. As I mentioned at the start, this solution can be extended and improved further and it would be good to hear feedback from others. </p>
<p>The OpenCart image library also contains a number of other hidden features including rotation and cropping. We have also extended the OpenCart image helpers further with dynamic image scaling. If anyone is interested in this, <a href="/enquiry.php">please get in touch</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/406/creating-image-watermarks-in-opencart/feed</wfw:commentRss>
		</item>
		<item>
		<title>Interprise Suite installation with ecommerce module</title>
		<link>http://www.webopius.com/content/390/interprise-suite-installation-with-ecommerce-module</link>
		<comments>http://www.webopius.com/content/390/interprise-suite-installation-with-ecommerce-module#comments</comments>
		<pubDate>Sun, 24 Jan 2010 18:50:56 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[General news]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[interprise]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=390</guid>
		<description><![CDATA[Last week, we did an Interprise Suite CRM installation on Windows Server 2008 using IIS7. In addition to the Interprise Suite database and files, we also installed the Interprise ecommerce module (based on ASPDotNetStorefront IS).
Because Interprise and the ecommerce module are 32-bit applications and this was an install on the 64-bit Windows platform, things didn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>Last week, we did an Interprise Suite CRM installation on Windows Server 2008 using IIS7. In addition to the Interprise Suite database and files, we also installed the Interprise ecommerce module (based on ASPDotNetStorefront IS).</p>
<p>Because Interprise and the ecommerce module are 32-bit applications and this was an install on the 64-bit Windows platform, things didn&#8217;t always go smoothly and I thought some tips might help others who are trying to do the same&#8230;</p>
<h2>Install IIS7 with ASP.NET role services</h2>
<p>Step 1 of the install is to use the Windows Server Manager and add a role of &#8216;Web Server&#8217;. This will install IIS7 and during the install you should be asked which Role Services you want to install with IIS7. </p>
<p>Make sure you choose &#8216;ASP.NET&#8217; at this stage because we found that installing it later can cause problems or conflicts with Windows Process Activation (WPA). If you do get into difficulties, we found that an un-install of the WPA before trying to re-install IIS7 makes life a lot easier.</p>
<p>Along with ASP.NET roles, we also chose:</p>
<p>- Static Content<br />
- Default Document<br />
- HTTP errors<br />
- HTTP redirection<br />
- ISAPI extensions<br />
- ISAPI filters<br />
- HTTP logging<br />
- Request monitor<br />
- Tracing<br />
- Basic authentication<br />
- Windows authentication<br />
- Request filtering<br />
- Static content compression<br />
- IIS Management console</p>
<h2>Create a 32-bit application pool</h2>
<p>Before you add your ecommerce module website to IIS7, create a new application pool capable of running 32-bit applications.</p>
<p><strong>Basic settings:</strong>  .NET Framework v2.x.xxxxx<br />
<strong>Advanced settings:</strong><br />
Enable 32-bit applications: TRUE<br />
Managed pipeline mode: Classic</p>
<p>Leave all other settings at their defaults</p>
<h2>Make sure your Interprise Suite ecommerce site using the new Application Pool</h2>
<p>Once you create your website configuration from within the IIS manager, make sure it is using the application pool you created. In your site&#8217;s &#8216;Basic Settings&#8217;, set the Application Pool to the correct pool.</p>
<h2>Resolve web.config conflicts</h2>
<p>IIS7 uses a new method of managing the web.config application settings based on a hierarchy. You may find once you&#8217;ve installed Interprise and ASPDotNetStorefront IS that some of your new web.config settings conflict with the default IIS7 settings.</p>
<p>To check this, from within your web site&#8217;s configuration in IIS manager, double click on the various configuration icons - for example &#8216;.NET compilation&#8217;. IIS will inform you of any errors as you click through the icons.</p>
<p>Unfortunately, to resolve this, it&#8217;s a case of editing your web.config (or the default web.config) and removing conflicts.</p>
<h2>Stuck?</h2>
<p>If all this sound too much, why not get in touch with Webopius. We can help you get your site installed and running. <a href="/enquiry.php">We also provide ongoing operational support such as hosting, remote backups, site enhancements and other Interprise/ASPDotNetStorefront development services</a>&#8230;. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/390/interprise-suite-installation-with-ecommerce-module/feed</wfw:commentRss>
		</item>
		<item>
		<title>ASPDotNetStorefront automated bulk image resizing</title>
		<link>http://www.webopius.com/content/386/aspdotnetstorefront-automated-bulk-image-resizing</link>
		<comments>http://www.webopius.com/content/386/aspdotnetstorefront-automated-bulk-image-resizing#comments</comments>
		<pubDate>Sun, 24 Jan 2010 17:18:06 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[General news]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=386</guid>
		<description><![CDATA[Recently, we were doing some ASPDotNetStorefront (ASPDNSF) work for a client where they had many thousands of product images to import. 
They were using a customised version of the product import system to load products into the store database - the import customisation allowed them to import product descriptions in multiple languages which is not [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, we were doing some ASPDotNetStorefront (ASPDNSF) work for a client where they had many thousands of product images to import. </p>
<p>They were using a customised version of the product import system to load products into the store database - the import customisation allowed them to import product descriptions in multiple languages which is not part of the standard ASPDotNetStorefront import routine.</p>
<p>They were also using the ImageFileNameOverride feature to allow the image names to match a specific attribute of the product (the ISBN number in this case).</p>
<p>This was all fine - they name the images to match the products, place the images in the /images/products/large folder and then perform the product import with the correct value in the ImageFileNameOverride column.</p>
<p><strong>No automatic creation of Icon and Medium sizes</strong></p>
<p>One challenge with the product import routine is that it doesn&#8217;t automatically create all image sizes for you - normally you need a thumbnail image (icon) for products on the category page, a medium sized image when viewing the product page and a large image when you want the user to see more detail.</p>
<p>Automatic image re-sizing is only performed in ASPDotNetStorefront when you manually create/edit a product and upload an image. Of course, when you have thousands of images to load, this is not something you want to do.</p>
<h2>An automatic image resizing solution</h2>
<p>So, to solve this, we wrote a module that can be called from within the ASPDotNetStorefront admin system that scans through all large images and looks for a matching icon and medium image. </p>
<p>If no image match is found, it automatically creates and icon and/or medium image for you based on the ASPDotNetStorefront application config settings for image resizing.</p>
<p>This saves a huge amount of time for the user and also allows them to re-run the re-sizing routine whenever they upload new images.</p>
<h2>ASPDotNetStorefront Development Services</h2>
<p>If you would like a this image resizing routine installed on your <a href="/enquiry.php">ASPDotNetStorefront site, or would like to discuss other ASPDotNetStorefront requirements, then please contact us</a>.</p>
<p>For more information on <a href="/content/aspdotnetstorefront-aspdnsf-development-services">ASPDotNetStorefront development services offered by Webopius, please click here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/386/aspdotnetstorefront-automated-bulk-image-resizing/feed</wfw:commentRss>
		</item>
		<item>
		<title>ASPDotNetStorefront - Improved card failure reporting using SagePay/Protx</title>
		<link>http://www.webopius.com/content/383/aspdotnetstorefront-improved-card-failure-reporting-using-sagepayprotx</link>
		<comments>http://www.webopius.com/content/383/aspdotnetstorefront-improved-card-failure-reporting-using-sagepayprotx#comments</comments>
		<pubDate>Sun, 20 Dec 2009 19:40:27 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[General news]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<category><![CDATA[protx]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=383</guid>
		<description><![CDATA[For many UK stores using ASPDotNetStorefront, the Sage Pay (formerly Protx) gateway is a popular payment processing solution.
The card was not accepted. Please try again
Picture the scenario, your store is receiving thousands of visits and a percentage a these are reaching the goal of adding items to their shopping cart and are moving through the [...]]]></description>
			<content:encoded><![CDATA[<p>For many UK stores using ASPDotNetStorefront, the Sage Pay (formerly Protx) gateway is a popular payment processing solution.</p>
<h2>The card was not accepted. Please try again</h2>
<p>Picture the scenario, your store is receiving thousands of visits and a percentage a these are reaching the goal of adding items to their shopping cart and are moving through the ASPDotNetStorefront checkout process. The Customer enters the correct billing address and credit card number but incorrectly enters their card&#8217;s &#8216;valid until&#8217; date into the start date field.</p>
<p>They confirm the order and because of the problem, ASPDotNetStorefront rejects the order and takes them straight back to the credit card payment form with the message:</p>
<p><strong>The card was not accepted. Please try again</strong></p>
<p>At this point, without any explanation, your Customer may think your store is faulty or that their bank declined the payment. This is the point they may choose to give up and leave your ASPDotNetStorefront site without proceeding with payment.</p>
<h2>An improved status message for failed Sage Pay/Protx transactions</h2>
<p>There is a good explanation as to why the &#8216;real&#8217; status message isn&#8217;t shown. Often these messages also contain additional technical information that you wouldn&#8217;t want your customer to see and some of the messages can be a bit harsh.</p>
<p>However, wouldn&#8217;t it be nice if the Customer was at least told that the reason their details were not accepted was because &#8220;the start date of the card is in the future. The card is not yet valid&#8221;. At least that prompts them that they may have mis-typed the details and prompt them to retry.</p>
<p>Webopius have developed a Web Control that can be embedded within the ASPDotNetStorefront &#8216;Checkoutpayment.aspx&#8217; page. It sits within the .aspx page and doesn&#8217;t make or require any changes to be made to the ASPDotNetStorefront source code.</p>
<p>At the point that a failed transaction error is shown to your Customer, this web control looks in the Failed Transaction table for this Customer and retrieves that Sage Pay/Protx status code. It then performs a lookup to turn this code into a meaningful and readable description of the reason the Customer&#8217;s credit card had problems.</p>
<p>If you would like a this control installed into your ASPDotNetStorefront site, we can install for you usually in less than an hour (including testing). Although not tried with other gateways, it should also be possible to modify the control to work with other ASPDotNetStorefront credit card payment gateways - we can look at each on a case by case basis.</p>
<h2>ASPDotNetStorefront development and support services</h2>
<p>Webopius provide a comprehensive range of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">ASPDotNetStorefront development and support services</a>. From small fixes, to site deployments and custom ASPDotNetStorefront theming - all at very competitive prices with no charge until the work has been completed.</p>
<p>Please <a href="/enquiry.php">Contact us for more information</a>. For a description of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">the range of ASPDotNetStorefront services offered, please click here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/383/aspdotnetstorefront-improved-card-failure-reporting-using-sagepayprotx/feed</wfw:commentRss>
		</item>
		<item>
		<title>ASPDotNetStorefront integrated with Affiliate Window</title>
		<link>http://www.webopius.com/content/381/aspdotnetstorefront-integrated-with-affiliate-window</link>
		<comments>http://www.webopius.com/content/381/aspdotnetstorefront-integrated-with-affiliate-window#comments</comments>
		<pubDate>Sun, 20 Dec 2009 18:07:57 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[ecommerce]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=381</guid>
		<description><![CDATA[Earlier this year, we wrote an article about how to integrate the excellent ASPDotNetStorefront ecommerce system with the Webgains affiliate platform.
ASPDotNetStorefront provides a basic method of affiliate tracking and reporting but does not provide commission calculations or affiliate payments. For this reason, many retail sites choose a third party affiliate network and integrate it with [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this year, we wrote an article about how to integrate the excellent <a href="/content/249/integrating-webgains-affiliate-network-with-aspdotnetstorefront">ASPDotNetStorefront ecommerce system with the Webgains affiliate platform</a>.</p>
<p>ASPDotNetStorefront provides a basic method of affiliate tracking and reporting but does not provide commission calculations or affiliate payments. For this reason, many retail sites choose a third party affiliate network and integrate it with ASPDNSF.</p>
<blockquote class="citeright"><p>
<a href="http://www.affiliatewindow.com/" rel="nofollow">Affiliate Window</a>
</p></blockquote>
<p>More recently, a client asked if we could integrate the Affiliate Window affiliate network (see link on right) with ASPDotNetStorefront. Given the previous work with Webgains, this proved to be a straightforward process split into three tasks:</p>
<p>1. Add tracking code to all main site pages<br />
2. Add order confirmation tracking code to the order confirmation page<br />
3. Develop a product feed to send Affiliate Window </p>
<h2>Add tracking code to main site pages</h2>
<p>To enable Affiliate Window to track clicked links to your site, you need to insert tracking code into your page source code just before the closing <code>&lt;/body&gt;</code>. </p>
<p>We developed a simple ASPDotNetStorefront XMLPackage and then from within our skin templates, added a call with one line like this:<br />
(!XmlPackage Name=&#8221;affiliatewindow.xml.config&#8221;!)</p>
<h2>Add order confirmation tracking</h2>
<p>If you read our Webgains article, this describes in outline how to develop tracking within the order confirmation page. Affiliate Window order confirmation tracking is done in almost the same way by modifying page.orderconfirmation.xml.</p>
<p>The tracking code enables Affiliate Window to track sales made within your ASPDotNetStorefront site and for the appropriate sales commission to be calculated.</p>
<h2>Develop a product feed</h2>
<p>Finally, you will need a method to tell the Affiliate Window network partners which products are available on your ASPDNSF store. The best way to do this is to copy one of the existing product feeds such as the ASPDotNetStorefront Google Base feed and to modify it to the format required by Affiliate Window.</p>
<h2>Do you require Affiliate Window integration into ASPDotNetStorefront?</h2>
<p>If you would like Affiliate Window integrated into your ASPDNSF site, then please <a href="/enquiry.php">contact us</a>.</p>
<p>Are you using ASPDotNetStorefront, or are you thinking of using it for your website? Webopius provide a comprehensive range of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">ASPDotNetStorefront development services</a>. From small fixes, to site deployments and custom ASPDotNetStorefront theming - all at very competitive prices with no charge until the work has been completed.</p>
<p>Please <a href="/enquiry.php">Contact us for more information</a>. For a description of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">the range of ASPDotNetStorefront services offered, please click here</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/381/aspdotnetstorefront-integrated-with-affiliate-window/feed</wfw:commentRss>
		</item>
		<item>
		<title>Updating ASPDotNetStorefront to work with latest Google Base specification</title>
		<link>http://www.webopius.com/content/369/updating-aspdotnetstorefront-to-work-with-latest-google-base-specification</link>
		<comments>http://www.webopius.com/content/369/updating-aspdotnetstorefront-to-work-with-latest-google-base-specification#comments</comments>
		<pubDate>Thu, 03 Dec 2009 10:00:12 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[Tips]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[google]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=369</guid>
		<description><![CDATA[ASPDotNetStorefront includes some really powerful but often under-utilised feed generators. These can take a feed of your products (or any other store data using the powerful ASPDotNetStorefront XML packages), generate a feed file (usually in XML but other formats are possible) and then FTP this file to a remote location.
The most popular uses are feeds [...]]]></description>
			<content:encoded><![CDATA[<p>ASPDotNetStorefront includes some really powerful but often under-utilised feed generators. These can take a feed of your products (or any other store data using the powerful ASPDotNetStorefront XML packages), generate a feed file (usually in XML but other formats are possible) and then FTP this file to a remote location.</p>
<p>The most popular uses are feeds for Amazon, Affiliate Programmes and Google Base. Google Base allows you to upload your products and pricing into Google to make them available within the Google product search system. It&#8217;s Google Base that we are covering today as Google have changed their product feed specification and users of ASPDotNetStorefront may find that when they send their feed, Google is reporting that none of their products are loading.</p>
<h2>Note for ASPDotNetStorefront version 8 users</h2>
<p>If you have ASPDNSF version 8.x, the recommended route to solving the Google Base issue is to contact the ASPDotNetStorefront support team. They have a patch available for v8 versions and the latest release of ASPDotNetStorefront should come shipped with the updated Google Base feed included.</p>
<p>v7 users should also contact the ASPDotNetStorefront support team but if they are unable to provide a Google Base patch, you can follow the simple instructions below to fix your Google Base feed</p>
<h2>Updating the ASPDotNetStorefront Google Base feed</h2>
<p>Making your existing ASPDotNetStorefront Google Base feed compliant with the latest Google feed specification is actually really simple as long as you are only selling only new or only used products throughout your store and a one line change is required as follows:</p>
<p>1. Edit the file &#8216;feed.googlebase.xml.config&#8217; in your Admin/XmlPackages directory (Note: for security, you may have previously changed the directory &#8216;Admin&#8217; to another name)<br />
2. Before the line &#8216;<code>&lt;/item&gt;<!--formatted--></code>&#8216;, add this:<br />
<code><br />
&lt;g:condition&gt;new&lt;/g:condition&gt;<br />
<!--formatted--></code><br />
If you only sell used products, replace &#8216;new&#8217; with &#8216;used&#8217;.<br />
3. Save the file</p>
<p><strong>Set your file encoding<br />
</strong></p>
<p>Sometimes after importing, Google Base may complain about character encoding within the feed. If this happens in your case, it might be worth forcing Google Base to use UTF-8 encoding rather than trying to detect automatically.</p>
<p>To do this, log into your Google Merchant account and click on &#8216;data feeds&#8217; in the left menu. Find your feed and click on the word &#8216;edit&#8217; next to the feed name. Change encoding from auto detect to UTF-8.</p>
<h2>More Google Base and ASPDotNetStorefront tips</h2>
<p>After writing this article, we discovered some more useful information and resources that you might find useful&#8230;</p>
<p><strong>Validating your Google Base feed</strong></p>
<p>If you want to do more detailed diagnostics on your Google Base feed without the trouble of submitting to Google directly. There is an excellent online validator here:</p>
<p><a href="http://celebird.googlepages.com/ckbase.htm" rel="nofollow">http://celebird.googlepages.com/ckbase.htm</a></p>
<p>Simply generate your feed with auto-ftp set to &#8216;no&#8217;. This will create the feed file in the images directory of your site. Now submit the full feel URL (http://youriste.com/images/yourfeedname.xml) to the above validation site and within about 5 minutes you&#8217;ll receive an email back with a very detailed set of diagnostics.</p>
<p><strong>Error &#8220;Invalid attribute name: description&#8221;</strong></p>
<p>After you&#8217;ve submitted your feed to Google Base, you may see Google reporting that some of your products are rejected because of Invalid attribute name: description. Unfortunately, Google doesn&#8217;t tell you a great deal more than this and unlike other error types doesn&#8217;t show you the products affected.</p>
<p>When we had this error, it was due to a couple of issues. The first was html being included within the product/variant descriptions. The second was related but was caused by a single <code>&lt;br&gt;<!--formatted--></code> existing within variant descriptions - even though the ASPDNSF Admin pages showed a blank variant description. Because the Google Base feed looks for a variant description before a product description, this <code>&lt;br&gt;<!--formatted--></code> was being used instead of the product description and Google was rejecting it.</p>
<p><strong>A Fix</strong></p>
<p>In our case, we fixed this issue by changing these lines within the feed.googlebase.xml.config:</p>
<p><code><br />
 &lt;xsl:param name=&quot;ProductDescr&quot; select=&quot;aspdnsf:GetMLValue(description)&quot;&gt;&lt;/xsl:param&gt;<br />
 &lt;xsl:param name=&quot;VariantDescr&quot; select=&quot;aspdnsf:GetMLValue(VariantDescr)&quot;&gt;&lt;/xsl:param&gt;<br />
<!--formatted--></code></p>
<p>To this:</p>
<p><code><br />
&lt;xsl:param name=&quot;ProductDescr&quot; select=&quot;aspdnsf:StripHtml(aspdnsf:GetMLValue(description,$WebConfigLocaleSetting,&#039;FALSE&#039;))&quot;&gt;&lt;/xsl:param&gt;<br />
&lt;xsl:param name=&quot;VariantDescr&quot; select=&quot;aspdnsf:StripHtml(aspdnsf:GetMLValue(VariantDescr,$WebConfigLocaleSetting,&#039;FALSE&#039;))&quot;&gt;&lt;/xsl:param&gt;<br />
<!--formatted--></code></p>
<p>This uses the full version of the ASPDotNetStorefront function &#8216;GetMLValue&#8217; to return the descriptions without HTML Encoding, then the StripHtml() function removes all html tags.</p>
<h2>ASPDotNetStorefront Development Services</h2>
<p>Are you using ASPDotNetStorefront, or are you thinking of using it for your website? Webopius provide a comprehensive range of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">ASPDotNetStorefront development services</a>. From small fixes, to site deployments and custom ASPDotNetStorefront theming - all at very competitive prices.</p>
<p>Please <a href="/enquiry.php">Contact us for more information</a>. For a description of <a href="/content/aspdotnetstorefront-aspdnsf-development-services">ASPDotNetStorefront services offered, please click here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/369/updating-aspdotnetstorefront-to-work-with-latest-google-base-specification/feed</wfw:commentRss>
		</item>
		<item>
		<title>Now evaluating ExpressionEngine CMS</title>
		<link>http://www.webopius.com/content/353/now-evaluating-expressionengine-cms</link>
		<comments>http://www.webopius.com/content/353/now-evaluating-expressionengine-cms#comments</comments>
		<pubDate>Wed, 28 Oct 2009 21:39:51 +0000</pubDate>
		<dc:creator>Webopius</dc:creator>
		
		<category><![CDATA[General news]]></category>

		<category><![CDATA[aspdotnetstorefront]]></category>

		<category><![CDATA[content management]]></category>

		<category><![CDATA[drupal]]></category>

		<category><![CDATA[expression engine]]></category>

		<guid isPermaLink="false">http://www.webopius.com/content/?p=353</guid>
		<description><![CDATA[When Webopius builds new websites for clients, we work with them to select the right Content Management System. In the past, much of the time this has resulted in using Drupal for robust, scaleable sites with multiple content types and the need for the client to easily maintain the content. For e-commerce systems, ASPDotNetStorefront is [...]]]></description>
			<content:encoded><![CDATA[<p>When Webopius builds new websites for clients, we work with them to select the right Content Management System. In the past, much of the time this has resulted in using Drupal for robust, scaleable sites with multiple content types and the need for the client to easily maintain the content. For e-commerce systems, ASPDotNetStorefront is often chosen as it&#8217;s one of the best commercial ecommerce platforms out there.</p>
<p>More recently, we&#8217;ve been very impressed with <a title="ExpressionEngine" rel="nofollow" href="http://expressionengine.com/">ExpressionEngine</a> as an alternative Content Management System. A friend introduced us to ExpressionEngine and a couple of months ago we downloaded a copy to evaluate.</p>
<p>Like other CMS systems, Expression Engine cleanly separates the templates and content (weblogs) which is dynamically loaded from the database. Unlike many CMS systems, the template design and tagging system is very easy to understand. You can also intermingle php and the tags to create very powerful content relationships within web pages.</p>
<p>One of the other aspects that appealed to us were the minimal updates once sites are deployed. With other CMS platforms, the system is always nagging us about a security patch or module update that is required. This requires downloading new modules, testing them on development boxes, fixing bugs (and looking up issues with clashes between different modules) before the changes can be deployed to a live site. For a company like us, this takes up valuable time and increases the risk of downtime on client sites. With Expression Engine there seem to be far less frequent security and general updates applied - overall it seems a pretty solid system.</p>
<p>The only initial criticism is that there doesn&#8217;t appear to be a central repository or directory of plugins, modules and extensions available which usually means spending yet more time in Google looking for a solution or writing your own. While I&#8217;m thinking, why have plugin, extension and modules. Just extensions would be fine and less confusing as I can&#8217;t see a great deal of difference, certainly between &#8220;module&#8221; and &#8220;extension&#8221;!</p>
<p>Currently, we will be using Expression Engine on the new Luzmon.com (<a href="http://www.luzmon.com" rel="nofollow">www.luzmon.com</a>) owned by Louise Mohn (<a href="http://www.louisemohn.com" title="Louise Mohn">www.louisemohn.com</a>). As soon as it&#8217;s deployed, I&#8217;ll write here with our experiences.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.webopius.com/content/353/now-evaluating-expressionengine-cms/feed</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.879 seconds -->
