This is the next generation Google sitemap generator for osCommerce MS2.2 based stores. I have previously released a sitemap generator in the osC contribution area but that is obsolete and difficult to deal with. This is a one script solution and eliminates the need for CRON jobs, file permissions, and other problems that plague other scripts. All data is generated on the fly...truly a set and forget solution for osC stores. The attached file is for the product sitemap. I have another for the categories but you should be able to use the very simple product one as a template...simply change the SQL a bit and you off and running. This version is previously unreleased but I will let it out in the wild here under GPL. You can view the script below and also download it so as to avoid copy-and-paste errors. Have fun! Bobby <?php /** * Google Sitemap Generator * * Script to generate a Google sitemap for osCommerce based stores * * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version 1.2 * @link http://www.oscommerce-freelancers.com/ osCommerce-Freelancers * @copyright Copyright 2006, Bobby Easland * @author Bobby Easland * @filesource */ /* * Include the application_top.php script */ include_once('includes/application_top.php'); /* * Send the XML content header */ header('Content-Type: text/xml'); /* * Echo the XML out tag */ echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n"; ?> <urlset xmlns="http://www.google.com/schemas/sitemap/0.84"> <?php /* * Define the uniform node function */ function GenerateNode($data){ $content = ''; $content .= "\t" . '<url>' . "\n"; $content .= "\t\t" . '<loc>'.trim($data['loc']).'</loc>' . "\n"; $content .= "\t\t" . '<lastmod>'.trim($data['lastmod']).'</lastmod>' . "\n"; $content .= "\t\t" . '<changefreq>'.trim($data['changefreq']).'</changefreq>' . "\n"; $content .= "\t\t" . '<priority>'.trim($data['priority']).'</priority>' . "\n"; $content .= "\t" . '</url>' . "\n"; return $content; } # end function /* * Define the SQL for the products query */ $sql = "SELECT products_id as pID, products_date_added as date_added, products_last_modified as last_mod, products_ordered FROM " . TABLE_PRODUCTS . " WHERE products_status = '1' ORDER BY products_last_modified DESC, products_date_added DESC, products_ordered DESC"; /* * Execute the query */ $query = tep_db_query($sql); /* * If there are returned rows... * Basic sanity check */ if ( tep_db_num_rows($query) > 0 ){ /* * Initialize the variable containers */ $container = array(); $number = 0; $top = 0; /* * Loop the query result set */ while( $result = tep_db_fetch_array($query) ){ $top = max($top, $result['products_ordered']); $location = tep_href_link(FILENAME_PRODUCT_INFO, 'products_id=' . $result['pID'], 'NONSSL', false); if ( tep_not_null($result['last_mod']) ){ $lastmod = $result['last_mod']; } else { $lastmod = $result['date_added']; } $changefreq = 'weekly'; $ratio = ($top > 0) ? ($result['products_ordered']/$top) : 0; $priority = $ratio < .1 ? .1 : number_format($ratio, 1, '.', ''); /* * Initialize the content container array */ $container = array('loc' => htmlspecialchars(utf8_encode($location)), 'lastmod' => date ("Y-m-d", strtotime($lastmod)), 'changefreq' => $changefreq, 'priority' => $priority ); /* * Echo the generated node */ echo generateNode($container); } # end while } # end if /* * Close the urlset */ echo '</urlset>'; /* * Include the application_bottom.php script */ include_once('includes/application_bottom.php'); ?> PHP:
Thank you for your kind remarks! If you're familiar with osC based stores you may also know of a few other contributions I've created...specifically Ultimate SEO URLs. This version handles stores that have SEO URLs enabled and those with stock URL generation (both parameter driven as well as SEF). Over time I plan on releasing the Project X framework on these forums as well as all the osC-MS2.2 scripts I've created. Might as well give them to the people! Bobby
Only one top level element is allowed in an XML document. Error processing resource 'http://www.fitness4home.nl/googleSitem...
Misa, that is because there is output in your includes/application_bottom.php script. I recommend moving whatever output you have in application_bottom.php to footer.php Bobby
Hello Bobby, thank you for this contribution. Should I submit googleSitemapProducts.php as Google Sitemap? How to do if the shop is in the subdirectory "catalog"? mro
Upload the script to your /catalog/ directory and it will generate the XML on the fly. When submitting to Google enter the full URL (i.e. - domain.com/catalog/googleSitemapProducts.php) and it will be indexed correctly. Google will want you to create a blank file with a long filename (which they will provide) and place it at the domain root. This is to verify that you are the site owner and will allow you to see various statistics about your domain. If you have any issues just post back and we'll get them sorted out. Bobby
Hello Bobby, thank you for your reply. I had to submit first the site "domain.com/catalog" and Google accepted "domain.com/catalog/googleSitemapProducts.php" as the sitemap URL. The sitemap URL should be in the lowest directory of the submited site. Thank you for your scripts (I also use Ultimate SEO) and your help! mro
That is the wrong file Misa, its application_bottom.php that has the problem and that file is application_top.php At a wild guess I think you might be using some tracking software thats in there, maybe google`s stats programme (forget what its called right now, the one that uses urchin) that might be causing the problem? HTH
<?php /* $Id: application_bottom.php,v 1.14 2003/02/10 22:30:41 hpdl Exp $ osCommerce, Open Source E-Commerce Solutions http://www.oscommerce.com Copyright (c) 2003 osCommerce Released under the GNU General Public License */ // close session (store variables) tep_session_close(); if (STORE_PAGE_PARSE_TIME == 'true') { $time_start = explode(' ', PAGE_PARSE_START_TIME); $time_end = explode(' ', microtime()); $parse_time = number_format(($time_end[1] + $time_end[0] - ($time_start[1] + $time_start[0])), 3); error_log(strftime(STORE_PARSE_DATE_TIME_FORMAT) . ' - ' . getenv('REQUEST_URI') . ' (' . $parse_time . 's)' . "\n", 3, STORE_PAGE_PARSE_TIME_LOG); if (DISPLAY_PAGE_PARSE_TIME == 'true') { echo '<span class="smallText">Parse Time: ' . $parse_time . 's</span>'; } } // DO NOT REMOVE echo '<!-- 3.15.16.25.18.9.7.8.20.3.12.5.13.5.14.20.14.9.3.15.12.1.5.19.3.21 -->'; if ( (GZIP_COMPRESSION == 'true') && ($ext_zlib_loaded == true) && ($ini_zlib_output_compression < 1) ) { if ( (PHP_VERSION < '4.0.4') && (PHP_VERSION >= '4') ) { tep_gzip_output(GZIP_LEVEL); } } ?>
It does NOT have to be in the domain root...just in the directory that the catalog is located. However, notice that they want you to create a file in the root to verify that you own the domain. @misa <?php // close session (store variables) tep_session_close(); if (STORE_PAGE_PARSE_TIME == 'true') { $time_start = explode(' ', PAGE_PARSE_START_TIME); $time_end = explode(' ', microtime()); $parse_time = number_format(($time_end[1] + $time_end[0] - ($time_start[1] + $time_start[0])), 3); error_log(strftime(STORE_PARSE_DATE_TIME_FORMAT) . ' - ' . getenv('REQUEST_URI') . ' (' . $parse_time . 's)' . "\n", 3, STORE_PAGE_PARSE_TIME_LOG); if (DISPLAY_PAGE_PARSE_TIME == 'true') { echo '<span class="smallText">Parse Time: ' . $parse_time . 's</span>'; } } // DO NOT REMOVE #echo '<!-- 3.15.16.25.18.9.7.8.20.3.12.5.13.5.14.20.14.9.3.15.12.1.5.19.3.21 -->'; if ( (GZIP_COMPRESSION == 'true') && ($ext_zlib_loaded == true) && ($ini_zlib_output_compression < 1) ) { if ( (PHP_VERSION < '4.0.4') && (PHP_VERSION >= '4') ) { tep_gzip_output(GZIP_LEVEL); } } ?> PHP: Bobby
The XML page cannot be displayed Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later. -------------------------------------------------------------------------------- Only one top level element is allowed in an XML document. Error processing resource 'http://www.fitness4home.nl/googleSitem... </urlset><br> ----------^ s="m"></url>
Misa, You have output that is located in application_bottom.php and you must remove that before the XML will be valid. Bobby
OK...restore the application_bottom.php to original code as you posted above. Then in the googleSitemapProducts.php script comment out the last line of code that includes the application_bottom.php application_bottom.php has some shut down functions that are nice but not essential (unless you're on an older server version and have gzip enabled). Give it a shot. If that doesn't work turn off the gzip and try it again. If that doesn't work you'll need someone to FTP in and check the code. Bobby
Sorry I couldn't solve your issue. How about from someone else that installed this script? How is it working for everyone else? Bobby
Hi Chemo...nice to see you back. I didn't like the way you were treated by those oscommerce guys. Anyway I have two questions. I have your old sitemap generator and it is working fine so should I change to this one? Also, I was wondering if there was a way I could manually add a page to the sitemap index that isn't generated from the database? Thanks!
I upgrade all clients to the latest version of scripts...othewise there would be no need to release enhanced versions However, the decision to upgrade is based entirely on your situation. Since the data is created on the fly if your catalog is very large in size it might be best to continue with the CRON method. You can manually add a page without much difficulty. Most of my clients want their sitemap listed first. Just define the array and use the uniform node function. Let me know if you need an example. Bobby