News:

Support the VirtueMart project and become a member

Main Menu

Canonicals for manufacturers in VM

Started by Peter Pillen, August 01, 2013, 13:04:10 PM

Previous topic - Next topic

Peter Pillen

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->addHeadLinkJRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_'.$catType.'_id='.$categoryIdFALSE) , '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->addHeadLinkJRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_manufacturer_id='.$virtuemart_manufacturer_idFALSE) , 'canonical''rel''' );
?>

Milbo

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
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Peter Pillen

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.

Milbo

One solution

static public function getLastVisitedCategoryId ($default = 0) {

$session = JFactory::getSession();
return $session->get( 'vmlastvisitedcategoryid', $default, 'vm' );

}
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Peter Pillen

#4
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==and $vm_canon_mf_id>0){
$canonType='manufacturer';
$canonId=$vm_canon_mf_id;
}else{
$canonType='category';
$canonId=$categoryId;
}
$document->addHeadLinkJRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_'.$canonType.'_id='.$canonIdFALSE) , '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?

Milbo

Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Peter Pillen

#6
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)

Milbo

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.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

Peter Pillen

#8
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]

Milbo

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.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

sandstorm

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

}
J3.6.4 / PHP7.0.12
VM3.0.16