This is the documentation for concrete5 version 5.6 and earlier. View Current Documentation
defined('C5_EXECUTE') or die(_("Access Denied.")); 
class SiteNavigationHelper extends NavigationHelper { 

     * Returns a link to a page 
     * @param Page $cObj 
     * @return string $link 
    public function getLinkToCollection(&$cObj, $appendBaseURL = false, $ignoreUrlRewriting = false) {
        // basically returns a link to a collection, based on whether or we have  
        // mod_rewrite enabled, and the collection has a path 
        $dispatcher = ''; 
        if (!defined('URL_REWRITING_ALL') || URL_REWRITING_ALL == false) { 
            if ((!URL_REWRITING) || $ignoreUrlRewriting) { 
                $dispatcher = '/' . DISPATCHER_FILENAME; 
        if ($cObj->getCollectionPath() != null) { 
            $link = DIR_REL . $dispatcher . $cObj->getCollectionPath() ; 
        } else { 
            $_cID = ($cObj->getCollectionPointerID() > 0) ? $cObj->getCollectionPointerOriginalID() : $cObj->getCollectionID(); 
            $link = DIR_REL . '/' . DISPATCHER_FILENAME . '?cID=' . $_cID; 

        if ($appendBaseURL) { 
            $link = BASE_URL . $link; 
        return $link; 


Originally posted by DavidMIRV in the Forums

Edited with some updates by andrew


This Google Webmaster blog post
 basically explains that having two urls point to the same content is not ideal for users or googlebot. I have often found that you can also get SEO dillution through content duplication over the same two similar urls ( and concrete5 will render the same page at and There is however a simple fix you can implement in concrete5 to stop this behavior and improve your site's SEO friendliness.

Enable a Custom Redirect

First, create config/site_post.php in your local config/ directory.  This is a custom file that lets your site do some work every time it is accessed. Perfect for what we need. 

I added the following code to detect 301 redirect the 'bad' URL's

    if ($_SERVER['REQUEST_URI'] != '/' && preg_match('#/$#',$_SERVER['REQUEST_URI'])) 
        $newuri = preg_replace('#/$#','',$_SERVER['REQUEST_URI']); 
        Header( "HTTP/1.1 301 Moved Permanently" );  
        Header( "Location: ". BASE_URL. $newuri);      

This will force only one instance of the URL to be the truly canonical one. 

Additionally, if you'd like to change the navigation helper which builds these links to use the ones without ending slashes, you can employ this code. (Editor's Note: It'd probably be simpler to change the above code to treat the pages with trailing slashes as the canonical URLs, and leave this code unchanged, but this will work as well, and is useful for those who prefer links without trailing slashes.)

Override and Extend the Navigation Helper

First, create navigation.php in your local empty helpers/ directory. Then, paste the following content into it:

This should fix any calls to the core API for getting the URL and the sitemap.xml generation of the page link

Simple eh? Thats my motto - keep it simple. I was originally concerned about this code effecting single page controller arguments but thus far in my testing in the last month I haven't discovered anything. Let me know if you do!

Loading Conversation