I would like to avoid a canonical tag being created in the manufacturer view that links to the main page. I can understand that for example a photocamera can be placed in the category "reflexcamera" and "professional camera" at the same time... creating duplicate content that must be solved with canonicals. But... a Nikon camera will never be found in the Canon category. In theory every manufacturer page should be unique. So the canonical in the manufacturer category view should only point to the first page of that manufacturer (limitstart=0)
The problem in search engines is this below
option=com_virtuemart&view=category&virtuemart_category_id=&virtuemart_manufacturer_id=2&lang=nl
--> this view with images does not get indexed by Google because a canonical points to the virtuemart main page
option=com_virtuemart&view=manufacturer&virtuemart_category_id=&virtuemart_manufacturer_id=2&lang=nl
--> this view without productimages gets indexed by google
the first page is visually more attractive and should be indexed instead of the manufacturer info
purpose of this code change
1. Creates a canonical for the manufacturer page that points to the first page with products of that manufacturer INSTEAD of pointing to the virtuemart main page
2. In categories where a manufacturer filter is applied, the canonical will still point to the category canonical (same as before)
3. On the manufacturer info page without the products, the canonical points to the manufacturer page where the products are visible (canonical points to view=category INSTEAD of view=manufacturers)
In short ... every category has one canonical to the first page, every manufacturer has one canonical to its own page with view= category so that products are visible. And when applying a manufacturer filter in a category, the canonical remains the same.
file: components\com_virtuemart\views\category\view.html.php
approx @ line 125
<?php
$categoryId = JRequest::getInt('virtuemart_category_id', ShopFunctionsF::getLastVisitedCategoryId());
$virtuemart_manufacturer_id = JRequest::getInt('virtuemart_manufacturer_id',0 );
$this->setCanonicalLink($tpl,$document,$categoryId);
?>
CHANGED TO
<?php
$categoryId = JRequest::getInt('virtuemart_category_id', ShopFunctionsF::getLastVisitedCategoryId());
$catType = 'category';
$virtuemart_manufacturer_id = JRequest::getInt('virtuemart_manufacturer_id',0 );
if ($categoryId == NULL and isset($virtuemart_manufacturer_id)){
$categoryId = $virtuemart_manufacturer_id;
$catType = 'manufacturer';
}
$this->setCanonicalLink($tpl,$document,$categoryId,$catType);
?>
approx @ line 550 function setCanonicalLink is changed to this
<?php
public function setCanonicalLink($tpl,$document,$categoryId,$catType){
// Set Canonic link
if (!empty($tpl)) {
$format = $tpl;
} else {
$format = JRequest::getWord('format', 'html');
}
if ($format == 'html') {
$document->addHeadLink( JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_'.$catType.'_id='.$categoryId, FALSE) , 'canonical', 'rel', '' );
}
}
?>
file: components\com_virtuemart\views\manufacturer\view.html.php
line added under the $document->setTitle
<?php
$document->setTitle(JText::_('COM_VIRTUEMART_MANUFACTURER_DETAILS').' '.strip_tags($manufacturer->mf_name));
//added so that the canonical points to page with visible products
$document->addHeadLink( JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_manufacturer_id='.$virtuemart_manufacturer_id, FALSE) , 'canonical', 'rel', '' );
?>
Very interesting detail, thank you. I just implemented it. I just wonder that $categoryId == NULL works, I think it must be $categoryId === NULL, and when I look in getLastVisitedCategoryId
getLastVisitedCategoryId () {
$session = JFactory::getSession();
return $session->get( 'vmlastvisitedcategoryid', 0, 'vm' );
That should return at least always a 0. Be aware that 0 means here not false, it means "root category" => all categories with parentid=0, same imho with manufacturers 0 shows all. So the idea was to give categorId= 0 and a manufacturerId, which sets the filter for the product listing and gives directly all products of a manufacturer regardless the category.
Next problem is that your "fix" sets later the manufacturerId as categoryId in $products = $productModel->getProductsInCategory($categoryId); around line 75
public function getProductsInCategory ($categoryId) {
$ids = $this->sortSearchListQuery (TRUE, $categoryId);
$this->products = $this->getProducts ($ids);
return $this->products;
}
so we must just use directly the sortSearchListQuery, the rest is done in the initialiseRequests
You are right... I just discovered some problems with my code and the fact I'm changing the categoryid to the manufacturer id. I will have a look for a better coding. When NULL or 0 is returned, the manufacturer view is ... well ... broken :-[
Didn't know that 0 always pointed to the root category. Learning every day.
One solution
static public function getLastVisitedCategoryId ($default = 0) {
$session = JFactory::getSession();
return $session->get( 'vmlastvisitedcategoryid', $default, 'vm' );
}
Another solution that seems more stable is this
file: components\com_virtuemart\views\category\view.html.php
search for function setCanonicalLink and switch with function here below
<?php
public function setCanonicalLink($tpl,$document,$categoryId){
// Set Canonic link
if (!empty($tpl)) {
$format = $tpl;
} else {
$format = JRequest::getWord('format', 'html');
}
if ($format == 'html') {
// Adapt canonical to manufacturer or category
$vm_canon_cat_id = JRequest::getVar('virtuemart_category_id');
$vm_canon_mf_id = JRequest::getVar('virtuemart_manufacturer_id');
if ($vm_canon_cat_id==0 and $vm_canon_mf_id>0){
$canonType='manufacturer';
$canonId=$vm_canon_mf_id;
}else{
$canonType='category';
$canonId=$categoryId;
}
$document->addHeadLink( JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_'.$canonType.'_id='.$canonId, FALSE) , 'canonical', 'rel', '' );
}
}
?>
Now there is no need to adapt the code at the top. Only the function setCanonicalLink is changed now. In that way the code is not influenced by other settings or code. Looks like its working. Can you verify this?
But the code is wrong at top. Please try the svn, or load the files manually here http://dev.virtuemart.net/projects/virtuemart/repository/show/branches/com_virtuemart2.0.14mp
Max,
I don't have a login for the dev or svn. I'll have a look to how it works. But the code at the top does no longer have to be changed. Only the function setCanonicalLink is changed... the rest is the same.
The changes are these
file: components\com_virtuemart\views\manufacturer\view.html.php
--> addHeadlink added to point the canonical of that view towards the view WITH products (see above)
file: components\com_virtuemart\views\category\view.html.php
--> function setCanonicalLink rewritten to detect if we have a category or a manufacturer (see code in last post above)
no the rest contains a bit more, so that you get the right products. and I wonder why you just not use the link? You do not need developer rights to use the svn.
I don't have a clue how the svn works. Tried different things, but I always get a login screen. I can see the file structure, browse trough it and read the code. I don't see any way to upload a revision or modify the pieces of code. In the process I already got a redmine account and SmartGit installed but to no avail.
I downloaded the latest revision and changed the code. File is in attachment (as txt file ... php was not allowed)
Unless there is a noob-level-manual about the svn? :)
[attachment cleanup by admin]
The latest revision IS containing your ideas, already. You gave e 80% of it and I noticed it need a bit more. So I must know if my idea works for you.
I added this at line 245 and this work very well for me? Is it any help?
// Set Canonic link
if (!empty($tpl)) {
$format = $tpl;
} else {
$format = JRequest::getWord('format', 'html');
}
if ($format == 'html') {
// mod for manufacturer canonic link
if ($virtuemart_manufacturer_id = JRequest::getInt('virtuemart_manufacturer_id',0 ))
$document->addHeadLink( 'index.php?option=com_virtuemart&view=category&virtuemart_manufacturer_id='.$virtuemart_manufacturer_id , 'canonical', 'rel', '' );
else
$document->addHeadLink( JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$categoryId) , 'canonical', 'rel', '' );
//end of mod
}