DataObjects and GoogleSitemaps

Googlesitemaps is a great module for SilverStripe. It is so important to SilverStripe's team that they deliver it with the standard download package. The sitemap is an important cornerstone in SEO, and SEO is vital for an ecommerce website.

What's the big deal?

The module creates an (virtual) XML-file in the installation root. The file delivers all viewable pages created in the backend as XML elements.

The thing is: SilverCart's products are DataObjects and do not have a backend page. There is a detail page that shows product details depending on an ID segment in the url. It took me one hour to modify the googlesitemaps module to show our product detail pages to each viewable product.

When I contacted SilverStripe's core developer Will Rossiter to add me changes to the modules code, he asked mo to find a solution that would be applicable to any DataObject. That way eg. forum threads could be added to the sitemap. With the help of Sebastian I found that solution in short time (the truth is: He did it on his own while I was sitting next to him).

The code

I submitted my changes to the file GoogleSitemap.php to the github repository as a pull request. I hope they find their way into the standard code soon. Meanwhile you may get them from my repo:

https://github.com/rlehmann/silverstripe-googlesitemaps

But thats not enough. The google sitemap needs a link to each item. This is called in the template /googlesitemaps/templates/GoogleSitemap.ss as AbsoluteLink. Your DataObject needs an additional method. For our SilvercartProduct it looks like this:

    /**
     * Returns the link to this product with protocol and domain
     * 
     * @return string the absolute link to this product
     * @author Roland Lehmann , Sebastian Diel 
     * @since 6.6.2011 
     */
    public function AbsoluteLink() {
        return Director::absoluteURL($this->Link());
    }

Furthermore define a method canView(). Ours uses the SilvercartProduct::get() wrapper to determin if the product is viewable:

    /**
     * Is this product viewable in the frontend?
     * 
     * @param Member $member the current member
     * 
     * @author Roland Lehmann 
     * @copyright 2011 pixeltricks GmbH
     * @since 6.6.2011
     * @return bool 
     */
    public function canView($member = null) {
        parent::canView($member);
        $publishedProduct = SilvercartProduct::get("`ID` = $this->ID");
        if ($publishedProduct) {
            return true;
        } else {
            return false;
        }
    }

Now you still need to tell the system which DataObject to add to the sitemap. We have a static method that should be called inside your project's config.php:

if (method_exists('GoogleSitemap', 'registerDataObject')) {
    GoogleSitemap::registerDataObject('SilvercartProduct');
}

The call to method_exists() makes sure that your googlesitemap module has our changes. You may pass the change frequency (daily, weeky, monthly, ...) as a second parameter. It's default value is "monthly".