Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canonical URL #998

Closed
egorpromo opened this issue Oct 17, 2013 · 75 comments
Closed

Canonical URL #998

egorpromo opened this issue Oct 17, 2013 · 75 comments
Assignees

Comments

@egorpromo
Copy link
Contributor

Is it possible to create method for getting the Canonical URL of the current page? Canonical URL is very important for SEO. It is needed for any webmaster to get Canonical URL an put it in the <link rel="canonical"> tag.
I propose something like:

$canonicalUrl=Yii::$app->getUrlManager()->getCanonicalUrl();

So it will be easy to get Canonical URL and put it in the <link> tag.

On other hand. If it is not possible It will be handy to have the route and the parmeters of the current page. If the route and the parameters of the current page will be in the use then any webmaster can create correct Canonical URL for the current page via helpers.

@samdark
Copy link
Member

samdark commented Oct 17, 2013

\Yii::$app->request->getAbsoluteUrl().

@samdark samdark closed this as completed Oct 17, 2013
@egorpromo
Copy link
Contributor Author

Ha ha ha! You are wrong! :) It is not Canonical URL. It is URL that user write in the adress bar of his browser.
Suppose Canonical URL is 'http://example.com/?id=10'. If user request something like 'http://example.com/?id=10&foo=bar' you method will return not 'http://example.com/?id=10' but 'http://example.com/?id=10&foo=bar' (notice additional malicious 'foo=bar').

@egorpromo
Copy link
Contributor Author

@samdark For more datailed explaination you can read this (in russian)

@samdark
Copy link
Member

samdark commented Oct 17, 2013

How would Yii know that id is part of canonical URL while foo isn't? Why http://example.com/?foo=bar can't be canonical in this case?

I don't think it can be automated in the scale of framework so it's up to you to choose which URLs are canonical.

@egorpromo
Copy link
Contributor Author

We have explicit route and parameters. Route and parameters are for one URL only. We can use them to create one explicit URL that is Canonical.

@samdark
Copy link
Member

samdark commented Oct 17, 2013

Sure we can but which parameters should be used and which should not?

http://example.com/foo-bar/filterby/price/desc?id=10 what URL is canonical in this case?

@egorpromo
Copy link
Contributor Author

Do we have route and parameters for this URL? If parameter 'id' is used in the action of the controller then it is needed and we must have it. If we know route and parameters then can we create URL? I think can.

@SonicGD
Copy link
Contributor

SonicGD commented Oct 17, 2013

You can have more than one route for one action. For example action

public function actionShow($id, $foo=false)
{
if($foo) {...}
}

and two routes:

'/controller/show/<id:\d+>/' => 'controller/show',
'/controller/show/<id:\d+>/<foo:\w+>/' => 'controller/show',

And if user open page by url '/controller/3/bar' - how can url manager decide which route is canonical?

@egorpromo
Copy link
Contributor Author

@SonicGD Ask @qiangxue not me. It is job for framework.

@rawtaz
Copy link
Contributor

rawtaz commented Oct 17, 2013

Yeah, it's just as easy as snapping your fingers.

@egorpromo Are you aware of any framework that currently does this? If yes, how do they do it? If you want this discussion to be practical, please provide pointers to actual solutions/implementations that does what you are suggesting - in part to show that it is doable and in part to clarify/give an example of how you want this to work in various situations (as you can see it's not straight forward).

@SonicGD
Copy link
Contributor

SonicGD commented Oct 17, 2013

It's not a job for framework, because only you know logic of url building on your site. So you can extend UrlManager and, for example, add canonical=true|false option to rule to define which rule is canonical.

@egorpromo
Copy link
Contributor Author

@rawtaz I don't know any framework that currently does this. Maybe Wordpress (CMS) a little. But this is not a reason do not use Canonical URL.

@rawtaz
Copy link
Contributor

rawtaz commented Oct 17, 2013

@egorpromo I think there might be a reason that you haven't seen this in other frameworks yet. It's not as easy as you think.

Either case, you should be able to discuss how to solve the practical issus that were already raised. It's not like people here don't want to evolve the framework, but practical issues has to be solved to meet real use cases. If you have an idea, you need to help elaborate on it.

@egorpromo
Copy link
Contributor Author

I think that yii developers don't investigate serach engine optimization deeply like I did or any seo professional did. Canonicalization URL and <link rel="canonical"> are very important for every site in the Web. You can see it if you google seo canonical url. It is very important for modern frameworks to take participation in seo trends. There is a need that everyone holds on the good site design. I can explain everyone that canonicalization of URL and <link rel="canonical"> tag are one of the most important part of modern sites. You can ask me. So i can help yii developers and i can try to create this feature for Yii2 on my own because this feature will help me and other yii users to create robust sites. Hey, @qiangxue! Do you want this feature in Yii? I can try to realize it ;)

@samdark
Copy link
Member

samdark commented Oct 24, 2013

@egorpromo I never said it's not important. I said that there's no single correct approach to the problem and it's application developer to decide what is canonical URL and what isn't.

@qiangxue
Copy link
Member

I agree with @samdark that it is application developer's responsibility to design what a canonical URL is.

@rawtaz
Copy link
Contributor

rawtaz commented Oct 24, 2013

@egorpromo

Canonicalization URL and are very important for every site in the Web. You can see it if you google seo canonical url. It is very important for modern frameworks to take participation in seo trends. There is a need that everyone holds on the good site design.

Noone argued or argues any of that.

I can explain everyone that canonicalization of URL and tag are one of the most important part of modern sites. You can ask me. So i can help yii developers and i can try to create this feature for Yii2 on my own because this feature will help me and other yii users to create robust sites.

This is precisely what you should do. If you have identified the problem and know how it should work, then elaborate on it so that a good algorithm/implementation to solve it can be worked out. Or point to an existing implementation in some other framework. As has been said earlier, it's not as simple as you might think, and this is a reason to think it through and try to address any issues.

Again, understand that people are not just dismissing what you say, but you are asking for something which is not straight forward to do/solve, and you are doing so without providing any actual discussion about how it can be done.

When people ask how a certain detail of this should work, you can't just answer "you figure it out" (as with @SonicGD) - if you cannot even explain how it should work yourself, then what makes you think it can work in the first place and what makes you expect others to magically come up with a solution? Try to be constructive.

@egorpromo
Copy link
Contributor Author

I am amazed, guys.
In Yii you have CApplication::createUrl(). Yes, it is Canonical URL. There are some little problem when using routes but I think it could be solved.
How finding of Canonical URL must be worked in Yii? I think that framework can find all get-parameters and its values that user type in the address bar of his browser. Later framework must find which parameters are passed to the action. Only parameters that passed to the action are used for construction of Canonical.

$CanonicalURL = Yii::app()->createUrl($route,$params);

Only one little thing you should do it is give application's developer a $route and $params which are used for generating current page. Another GET-params must be rejected.

@samdark
Copy link
Member

samdark commented Oct 24, 2013

If parameter is passed to the action it doesn't mean anything:

public function actionIndex($filterBy = 'price', $filterValue = null, $orderBy = 'desc') {

Parameters are passed to action but none of these could be considered as a part of canonical URL.

@egorpromo
Copy link
Contributor Author

@samdark I am grateful to you for your contributing about Yii but it is obvious for me that you don't understand search engine optimization. Can you ask some seo professionals about Canonical URL? Take account on any seo forum and ask anybody. At least you can ask me because I investigate seo many years. My site is http://indysite.ru. SEO is not programming. You are programmer. Today it is important to have robust informational architecture in the site. I think that the using of Canonical URL is good for any site and I try to explain to yii developers about importantance of SEO, seems it is not possible now.

@samdark
Copy link
Member

samdark commented Oct 25, 2013

No need to explain about importance of SEO, we all know that.

The question was about how a framework can determine which part of URL is canonical and which isn't. I'm trying to explain that it can't be done automatically for all applications and all cases.

Also I do not understand why it's not possible to add canonical URLs currently if we're assuming you know how these should be built for your application. Here's an example how it can be done in a view:

$this->registerLinkTag(['rel' => 'canonical', 'href' => $yourUrlHere]);

Or in Controller:

$this->view->registerLinkTag(['rel' => 'canonical', 'href' => $yourUrlHere]);

@egorpromo
Copy link
Contributor Author

How you can define $yourUrlHere? It must be Canonical URL but it must be defined also. How do you do it?

@samdark
Copy link
Member

samdark commented Oct 25, 2013

That's the question I'd like to ask you from the very start.

I personally think that it can't be done automatically for all applications and all cases so it's up to developer to decide how canonical URL should be built.

In application scope it may be something like:

function getCanonicalUrl()
{
  $params = $_GET;
  // do your magic, filter out what isn't part of canonical or take only what is part of it
  return \Yii::$app->urlManager->ceateAbsoluteUrl(\Yii::$app->controller->getRoute(), $params)
}

@lucianobaraglia
Copy link
Contributor

@egorpromo , as far as I understand, a canonical url is an url that is prefered between several that has the same content. Am I right or is it more complicated?

For example, having:

http://example.com/products/category/goodies/order/price_asc

and

http://example.com/products/category/goodies/order/price_desc/limit/10

the canonical url could be

http://example.com/products/category/goodies

If so, how could the framework determine it automatically?
Is more a developer task...

@rawtaz
Copy link
Contributor

rawtaz commented Oct 25, 2013

@egorpromo You are very keen on reiterating your assumption that people don't understand. Yet you completely fail, over and over again, to answer our simple questions. Funny guy. Thanks for the links though.

@egorpromo
Copy link
Contributor Author

@samdark
Algorithm to define Canonical URL.

  1. Find route to needed action. Find GET-parameters that user write in the address bar of his browser.
    http://example.com/?r=site/index&id=10&cat=all&foo=value
    We can find route and parameters here.
    Route: site/index
    Parameters: id=10, cat=all, foo=value

  2. Find parameters that are used in the action

public function action index($id, $cat)
{

}

We can see that used the 'id' and 'cat' only. Now we can define canonical route and canonical parameters.
Canonical Route: site/index
Canonical Parameters: id=10, cat=all

  1. Find Canonical URL
$CanonicalURL =  \Yii::$app->urlManager->ceateAbsoluteUrl($CanonicalRoute, $canonicalParams);

That's all I think

@egorpromo
Copy link
Contributor Author

@rawtaz lol

@samdark
Copy link
Member

samdark commented Oct 25, 2013

@egorpromo that, again, doesn't work for all cases.

For example, a product may belong to categories "mobile" and "gadgets" so it will be accessible via following URLs:

http://example.com/?r=product/view&id=1&cat=mobile
http://example.com/?r=product/view&id=1&cat=gadgets

Canonical URL should be one of these but not both since page content is nearly identical (except maybe breadcrumb).

@samdark samdark reopened this Oct 25, 2013
@ghost ghost assigned samdark Oct 25, 2013
@samdark
Copy link
Member

samdark commented Oct 25, 2013

@jjnavsofs0
Copy link

@egorpromo bro, don't take me offending but I have been watching your all posts by now and you sounds to be insulting other developers. I hope this platform gives us opportunities to collaborate and build some great solutions for all of us. I wish that rather than letting us know the issues of @samdark or the bad of programmer who made actions in controller you should better contribute your extraordinary and smart code with your supreme knowledge and excellent coding abilities.

@egorpromo
Copy link
Contributor Author

@jjnavsofs0 Thanks :)

@egorpromo
Copy link
Contributor Author

@samdark What about default parameters? ...Ah, maybe another way exists...

@samdark
Copy link
Member

samdark commented Oct 25, 2013

I'm still unsure about default parameters. I see no reliable way determine these. Any ideas?

@egorpromo
Copy link
Contributor Author

If developer sets parameters which are not in $_GET? It can be mistake that developer have done by accident.

@samdark
Copy link
Member

samdark commented Oct 25, 2013

Or he's not aware how these should be formatted or doesn't care about SEO unil it's too late. I'd better stick with setting canonical URL parameters explicitly.

@egorpromo
Copy link
Contributor Author

Another thing. For Google it is important the permanency of GET-parameters' row.
For example http://example.com?r=site/index&cat=10&subcat=20 and http://example.com?r=site/index&subcat=20&cat=10 are different pages ('cat' and 'subcat' are on different places). I am not assured but it may be real. Is it possible to make the row of GET-parameters constant?

@egorpromo
Copy link
Contributor Author

We must foresee some exeptional situations.

  1. $parameterNames is consists of parameters that are in the $ _GET.
    It is normal situation.

  2. $parameterNames is consists of some parameters. Some of them are in the $ _GET, another do not exist in $ _GET. It is the mistake made by developer.
    It is exception. setCanonicalParameters() function must use the parameters of $parameterNames that are in the $ _GET only. Another parameters that developer has stated must be rejected.

  3. $parameterNames is consists of parameters that are not in $_ GET.
    It is exception. What to do in this case?
    First situation is that application doesn't need any $ _GET parameters. http://example.com?r=site/index.
    Second situation is that application needs one or several $ _GET parameters. http://example.com?r=site/index&id=10.
    I think in these two last exceptional sutuations it is not possible to find Canonical URL. Developer has made a mistake in these two last exceptional situations. So it is needed do not create Canonical URL at all. If we create Canonical URL in these situations this is a mistake because created URL may point to wrong URL.

@samdark
Copy link
Member

samdark commented Oct 26, 2013

There's support for default values in UrlManager so the situation should not result in exception, I think.

@egorpromo
Copy link
Contributor Author

I have some thoughts.
I propose If parameters are used in the action of controller then they are default for Canonical URL. For example:

class siteController extends Controller
{
    public function actionIndex($id, $color)
    {
        //Now Canonical Parameters are 'id' and 'color'. Developer can set additional Canonical Parameters if he wants via setCanonicalParameters() function like that: setCanonicalParameters(['category'])

        Yii::$app->request->get('category', false); //If developer wants use 'category' parameter he must make it as Canonical Parameter via setCanonicalParameters(['category'])
    }
}

If developer doesn't use setCanonicalParameters() function then in example above Canonical URL will be http://example.com?r=site/index&id={$id}&color={$color}. If he uses setCanonicalParameters(['category']) then Canonical URL will be http://example.com?r=site/index&id={$id}&color={$color}&category={$category}

@samdark
Copy link
Member

samdark commented Oct 27, 2013

As I said before, that doesn't work. In your own example you're using $id and $color. From programming point of view it's OK but SEO guides do recomment not including color variations as canonical URL parameters.

@egorpromo
Copy link
Contributor Author

It is just abstract example... Instead color may be another parameter.
To include 'color' or don't include 'color' must decide the developer on his own. Often it is not needed to include 'color'. But in some cases 'color' is not just a color of the T-shirt. And in these cases it is needed to include 'color' in Canonical URL.

@egorpromo
Copy link
Contributor Author

We can use another function to erase Canonical Parameter. For example: eraseCanonicalParameters(['color']).

@lucianobaraglia
Copy link
Contributor

Now you are given examples that requieres the developers input, so, one
could do that from the very begining and there would no need of the
framework doing it.

Luciano Baraglia

Desde el celular.
El oct 27, 2013 3:56 a.m., "egorpromo" [email protected] escribió:

We can use another function to erase Canonical Parameter. For example:
eraseCanonicalParameters(['color']).


Reply to this email directly or view it on GitHubhttps://github.com//issues/998#issuecomment-27164064
.

@egorpromo
Copy link
Contributor Author

@lucianobaraglia Now I can see there is no any possible way to create Canonical URL of the curent page in YII2. :( Later on we can not only create Canonical URL but we can create robust Informational Architecture for modern sites.
For example my vision of Canonical System in the action:

class siteController extends Controller
{
    public function actionIndex($t_shirt_id, $color=NULL)
    {

/*
    Yii2: Now you have Canonical URL like http://example.com?r=site/index&t_shirt_id={$t_shirt_id}&color={$color}
    Programmer: I don't want `color` in Canonical URL. `color` are used for showing color of t-shirt only. I want that page http://example.com?r=site/index&t_shirt_id={$t_shirt_id} is in the Google.
    Yii2: You have to use eraseCanonicalParameters() function.
    Programmer: Ok
*/
        eraseCanonicalParameters(['color']);

        Yii::$app->request->get('sortby', false);

/*
    Yii2: You use `sortby` parameter. You have to use setCanonicalParameters() function.
    Programmer: No. `sortby` is just for sorting colors of t-shirt. I don't want page http://example.com?r=site/index&t_shirt_id={$t_shirt_id}&sortby={$sortby} is in the Google. I want that web-users find page http://example.com?r=site/index&t_shirt_id={$t_shirt_id} when searching in Google.
    Yii2: Ok. Do nothing.
*/

        Yii::$app->request->get('category', false);

/*
    Yii2: You use `category` parameter. You have to use setCanonicalParameters() function.
    Programmer: Ok. Page http://example.com?r=site/index&t_shirt_id={$t_shirt_id}&category={$category} is the Canonical. I want this page is in the Google.
    Yii2: Do setCanonicalParameters(['category'])
*/

        setCanonicalParameters(['category']);

    }
}

@samdark
Copy link
Member

samdark commented Oct 28, 2013

This implicitness sounds like a very bad idea.

@egorpromo
Copy link
Contributor Author

@samdark Maybe if programmer doesn't know what is Canonical URL :) This feature is very convinent for SEO professionals. If programmer don't know what is Canonical URL he may not use it. Or this feature can be disabled by default.

@samdark
Copy link
Member

samdark commented Oct 28, 2013

Yes but SEO professionals are not majority so implicitness will hurt ones what aren't aware of canonical URLs.

@lucianobaraglia
Copy link
Contributor

@egorpromo as @samdark said in #998 (comment) :

Here's an example how it can be done in a view:

$this->registerLinkTag(['rel' => 'canonical', 'href' => $yourUrlHere]);

Or in Controller:

$this->view->registerLinkTag(['rel' => 'canonical', 'href' => $yourUrlHere]);

@samdark
Copy link
Member

samdark commented Oct 28, 2013

@lucianobaraglia solution in #998 (comment) is a bit better.

@rawtaz
Copy link
Contributor

rawtaz commented Oct 28, 2013

On the topic of what @samdark write I agree. Whitelisting over blacklisting please.

@egorpromo
Copy link
Contributor Author

Maybe the simplest way is just getting parameters that are passed to the action.
If we will have \Yii::$app->UrlManager->getRoute() and \Yii::$app->UrlManager->getParameters() then we will can create Canonical URL as we want.

$current_route=\Yii::$app->UrlManager->getRoute();
$current_params=\Yii::$app->UrlManager->getParameters();

//Now we can create any needed URL of the current page
$canonicalParams=array_intersect_key(['id', 'color', 'category'], $current_params);
$CanonicalURL = \Yii::$app->urlManager->ceateAbsoluteUrl($current_route, $canonicalParams);

@samdark
Copy link
Member

samdark commented Oct 31, 2013

@qiangxue any idea where to put such functionality? It's something in the middle between request and URL manager.

@qiangxue
Copy link
Member

qiangxue commented Nov 1, 2013

You may manipulate Controller::actionParams to adjust the parameters for creating the canonical URL.

@kartik-v
Copy link
Contributor

Nice one @qiangxue and yii-developers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants