I want to make SEO friendly tag URL in magento.
Currently it is abc.com/tag/product/list/tagId/17/
but i want to make it abc.com/tag/xyz
I tried this by using "URL rewrite management" but it is not working.
Please help.
First I want to say that this is a nice question. Got me all fired up.
It works with the url management but it's kind of a drag. To much work.
For example I added this in the url management.
Type : Custom
Store: Select any store here - if you have more you have to do this process for each one
ID Path: TAG_23
Request Path: tag/camera
Target Path: tag/product/list/tagId/23
Redirect: No
Saved. now when calling ROOT/tag/camera
I see the prodcts tagged with 'camera'.
But for sure this is not the way to go. if you have more than 10 tags you get bored.
So the idea is to make a module that will make magento recognize tags like tag/something
and will change the links for tags to the same format above, so you won't have to edit a lot of templates.
I named the module Easylife_Tag
. You need for it the following files.
app/etc/modules/Easylife_Tag.xml
- the declaration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Tag>
<codePool>local</codePool>
<active>true</active>
<depends>
<Mage_Tag />
</depends>
</Easylife_Tag>
</modules>
</config>
app/code/local/Easylife/Tag/etc/config.xml
- the configuration file
<?xml version="1.0"?>
<config>
<modules>
<Easylife_Tag>
<version>1.0.0</version>
</Easylife_Tag>
</modules>
<global>
<events>
<controller_front_init_routers><!-- add a custom router to recognize urls like tag/something -->
<observers>
<easylife_tag>
<class>Easylife_Tag_Controller_Router</class>
<method>initControllerRouters</method>
</easylife_tag>
</observers>
</controller_front_init_routers>
</events>
<models>
<tag>
<rewrite>
<tag>Easylife_Tag_Model_Tag</tag><!-- rewrite the tag model to change the url of the tags to tag/something -->
</rewrite>
</tag>
<tag_resource>
<rewrite>
<tag>Easylife_Tag_Model_Resource_Tag</tag> <!-- rewrite the tag resource model - see below why is needed -->
</rewrite>
</tag_resource>
</models>
</global>
</config>
app/code/local/Easylife/Tag/Model/Tag.php
- the rewritten tag model
<?php
class Easylife_Tag_Model_Tag extends Mage_Tag_Model_Tag {
//change the url from `tag/product/list/tagId/23` to `tag/camera`
public function getTaggedProductsUrl() {
return Mage::getUrl('', array('_direct' => 'tag/'.$this->getName()));
}
}
app/code/local/Easylife/Tag/Model/Resource/Tag.php
- rewritten tag resource model
<?php
class Easylife_Tag_Model_Resource_Tag extends Mage_Tag_Model_Resource_Tag {
//by default, when loading a tag by name magento does not load the store ids it is allowed in
//this method loads also the store ids
public function loadByName($model, $name){
parent::loadByName($model, $name);
if ($model->getId()) {
$this->_afterLoad($model);
}
else {
return false;
}
}
}
app/code/local/Easylife/Tag/Controller/Router.php
- the custom router - see comments inline
<?php
class Easylife_Tag_Controller_Router extends Mage_Core_Controller_Varien_Router_Abstract{
public function initControllerRouters($observer){
$front = $observer->getEvent()->getFront();
$front->addRouter('easylife_tag', $this);
return $this;
}
public function match(Zend_Controller_Request_Http $request){
//if magento is not installed redirect to install
if (!Mage::isInstalled()) {
Mage::app()->getFrontController()->getResponse()
->setRedirect(Mage::getUrl('install'))
->sendResponse();
exit;
}
//get the url key
$urlKey = trim($request->getPathInfo(), '/');
//explode by slash
$parts = explode('/', $urlKey);
//if there are not 2 parts (tag/something) in the url we don't care about it.
//return false and let the rest of the application take care of the url.
if (count($parts) != 2) {
return false;
}
//if the first part of the url key is not 'tag' we don't care about it
//return false and let the rest of the application take care of the url
if ($parts[0] != 'tag') {
return false;
}
$tagName = $parts[1]; //tag name
//load the tag model
$tag = Mage::getModel('tag/tag')->loadByName($tagName);
//if there is no tag with this name available in the current store just do nothing
if(!$tag->getId() || !$tag->isAvailableInStore()) {
return false;
}
//but if the tag is valid
//say to magento that the request should be mapped to `tag/product/list/tagId/ID_HERE` - the original url
$request->setModuleName('tag')
->setControllerName('product')
->setActionName('list')
->setParam('tagId', $tag->getId());
$request->setAlias(
Mage_Core_Model_Url_Rewrite::REWRITE_REQUEST_PATH_ALIAS,
$urlKey
);
return true;
}
}
That's it. Clear the cache and give it a go.
[EDIT].
You can find the full extension here. The only difference is that it uses the community
code pool instead of local as described above.
Im using Magento 1.8.1 and tried the Marius's solution but I had one problem: 2+ keyword tags (with a space between words) was going to 404 page and the spaces in url were changed to %20. One keyword tag is working like a charm!
So, I modified his module to show a spaced word on Tag Module and 'hyphenized' in the URL.
File: Easylife/Tag/Model/Tag.php
return Mage::getUrl('', array('_direct' => 'tag/'.str_replace(" ", "-", $this->getName())));
File: Easylife/Tag/Controller/Router.php
$tagName = str_replace("-", " ", $parts[1]); //tag name
Its working for me now.
Best regards and thanks for the module Marius!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With