Hi everyone,
We use the VM file to manage the headers of our pages via the page top macro. I am trying to add the Canonical link for each page once it is assembled via that VM header macro and I can get the root URL into the page but am having difficulty getting the complete absolute path to the specific page. I have tried several code combinations with now luck. Is anyone doing this and/or any suggestions on a statement that will work?
Thanks,
MJW
We need to generate a full url when outputting an RSS feed… so we do something like:
#set($pageSiteID = $rx.asmhelper.getSingleParamValue($sys.params,'sys_siteid'))##
#if($pageSiteID)##
#set($pageSiteBase = $rx.location.siteBase($pageSiteID,"no"))##
#else##
#set($pageSiteBase = '')##
#end##
#set($fullRSSPageURL= $rx.location.generate($sys.assemblyItem, "myPgTemplateNameRSS2"))##
##prepend site url if it does not exist
#if($fullRSSPageURL.indexOf("http")!=0)##
#set($fullRSSPageURL= "${pageSiteBase}${fullRSSPageURL}")
#end##
Thanks, that is actually the code I started with, I use the same thing for our RSS pages and if in fact it was in inserted into the template for the page itself it works well, where I am stumped is in the velocity macro file how to use that code for ANY template that is being assembled? I may not be explaining it correctly, but for example, if I set this call in the macro:
<link rel="canonical" href=$sys.site.path>
It inserts the root path into any template in the header. There must be something I am missing. For instance if I insert
$rx.location.generate($sys.assemblyItem, "myPgTemplateNameRSS2"))
it will add the full path to a specific template but not the others?
Thanks for your input and help.
MJW
[QUOTE=jitendra;20655]We need to generate a full url when outputting an RSS feed… so we do something like:
#set($pageSiteID = $rx.asmhelper.getSingleParamValue($sys.params,'sys_siteid'))##
#if($pageSiteID)##
#set($pageSiteBase = $rx.location.siteBase($pageSiteID,"no"))##
#else##
#set($pageSiteBase = '')##
#end##
#set($fullRSSPageURL= $rx.location.generate($sys.assemblyItem, "myPgTemplateNameRSS2"))##
##prepend site url if it does not exist
#if($fullRSSPageURL.indexOf("http")!=0)##
#set($fullRSSPageURL= "${pageSiteBase}${fullRSSPageURL}")
#end##
[/QUOTE]
So really, you just want the vm to dynamically figure out what template it is assembling (part of) right?
Exactly. That would be correct.
Bumping this up, still need some feedback/assistance on this issue? Anyone?
Maybe take a step back, I am not sure I fully understand the problem.
I just refreshed myself on Google’s handling of the canonical links. As I understand the <link rel=“canonical” tag, you want to point similar content to a single authoritative url for the content, ideally with an absolute URL. So the link you are inserting into the head would be a link to the canonical item for the content in the non-canonical pages only. The actual canonical item would have no <link rel=“canonical” tag.
How is the canonical item identified by the item being assembled in your implementation? Is there like a canonical slot or a something like a taxonomy tag that is flagging content as related and another field/tag that identifies the canonical item as the source item for a given tag?
-n
Thanks for the response Nate, I appreciate it and yes, in fact I may be taking the wrong approach to the solution, not sure. To answer your question, the canonical item is NOT being identified assembled or set up as a slot, taxonomy tag etc. currently. Hence the reason for this post. My first inclination was to utilize the pagetop macro and to insert the link tag on the appropriate pages to alleviate the manual entry of the link tag in the pages via a slot and/or field. To your point yes, only certain pages/items require this link tag designating them as the preferred Google search page item. After reviewing this again over the weekend I believe probably the best option is to utilize a slot and/or field approach due to the complexity of developing the logic in the VM file to insert this tag where required. Of course if someone has a better idea, approach, solution or implementation I am all ears.
Thanks again,
MJW
[QUOTE=natechadwick;20679]Maybe take a step back, I am not sure I fully understand the problem.
I just refreshed myself on Google’s handling of the canonical links. As I understand the <link rel=“canonical” tag, you want to point similar content to a single authoritative url for the content, ideally with an absolute URL. So the link you are inserting into the head would be a link to the canonical item for the content in the non-canonical pages only. The actual canonical item would have no <link rel=“canonical” tag.
How is the canonical item identified by the item being assembled in your implementation? Is there like a canonical slot or a something like a taxonomy tag that is flagging content as related and another field/tag that identifies the canonical item as the source item for a given tag?
-n[/QUOTE]
Are you using version 7.2? I really like the idea of using taxonomy tags for this and wouldn’t mind working up an example if you are interested.
-n
[QUOTE=mjweise;20681]Thanks for the response Nate, I appreciate it and yes, in fact I may be taking the wrong approach to the solution, not sure. To answer your question, the canonical item is NOT being identified assembled or set up as a slot, taxonomy tag etc. currently. Hence the reason for this post. My first inclination was to utilize the pagetop macro and to insert the link tag on the appropriate pages to alleviate the manual entry of the link tag in the pages via a slot and/or field. To your point yes, only certain pages/items require this link tag designating them as the preferred Google search page item. After reviewing this again over the weekend I believe probably the best option is to utilize a slot and/or field approach due to the complexity of developing the logic in the VM file to insert this tag where required. Of course if someone has a better idea, approach, solution or implementation I am all ears.
Thanks again,
MJW[/QUOTE]
Hi Nate,
Actually we are in the process of upgrading to 7.2 as we speak. I should have it up and implemented in the next couple of weeks. Any examples you have regarding the taxonomy option would be a huge help to me. I am still a bit vague on what additional functionality is available in 7.2 so any and all input on that version would help.
Thanks!
Mike
[QUOTE=natechadwick;20683]Are you using version 7.2? I really like the idea of using taxonomy tags for this and wouldn’t mind working up an example if you are interested.
-n[/QUOTE]
So what i’m not getting is why can’t you just use $rx.location.generate($sys.assemblyItem) in your .vm (in conjunction with the site root if needed)? Am i missing something here?
When adding that statement to the VM file ($rx.location.generate($sys.assemblyItem) it works but requires a template association (I believe) so I can use that statement with ONE template e.g. erauGeneric and it works fine but I need to dynamically assemble every template. Does that make sense?
Mike
You should be able to use it without adding a template… at least I was able to… This may require that if your content has multiple page templates associated with it, one needs to be a “default template” but I’m not positive.
In my example I specified the template (the rss2) because otherwise the link would have defaulted to the html page template.
By golly, I think you are correct, with one exception. In order to get the full path of the page into the link tag it looks something like this:
<link rel="canonical" href=$sys.site.url$rx.location.generate($sys.assemblyItem)>
Of course this offers up a separate unique problem for content items that are copied a a link or utilized across sites.
Thanks,
Mike
Here is a Taxonomy example.
This example assumes a setup where you have 2 shared fields that are using the taxonomy control, both pointed at the same taxonomy. These should be text data type fields, but not set to MAX. Use something like 2000. The fields are added to each applicable type and content is tagged. When tagging, the Canonical tag field is only populated for the authoritative URL for the given tag, the Tags field is populated for any tag that you might want. I tested it with FastForward so rffGeneric in the query could be changed to whatever types make sense. It is also using a method from the PSO Toolkit.
This would probably need tweaked for correctness (not sure if you really would want more than one authoritative link for a given item for example, this macro loops through each tag), but is an example of the approach.
#macro(getCanonicalLinks)
#if("$!{canonicalTagId}" == "")##
#if($sys.item.hasProperty("rx:canonical_tag"))##
#set($canonicalTagId = $sys.item.getProperty('rx:canonical_tag').string.trim())##
#end##
#end##
##
## We don't really want to do anything if this is the canonical link
#if("$!{canonicalTagId}" == "")##
## We want to get the canonical link for each Tag applied to this item.
#set($list = $rx.percTaxonomyJexl.getNodesFromIds($sys.item.getProperty('rx:tags').string))##
#if($list.size() > 0)##
#foreach($tag in $list)##
#set($tagId = $tag.getId())##
#set($keys=[])##
#set($vals=[])##
#set($pa = $user.psoMapTools.create($keys,$vals))##
#set($relresults = $user.psoQueryTools.executeQueryNodes("SELECT rx:sys_contentid FROM rx:rffGeneric WHERE rx:canonical_tag LIKE '%$!{tagId}%'",1,$pa,""))##
#if($relresults.size >0)##
#set($node = $relresults.nextNode())##
#set($clone = $sys.assemblyItem.getCloneParentItem())##
$clone.removeParameter("sys_folderid")##
$clone.setNode($node)##
#if("$!{clone}"!="")##
#set($relLink = $rx.location.generate($clone))##
<link rel="canonical" href="$relLink" />
#else##
<!-- No Canonical Item Found for Tag: $!{tagId} -->
#end##
#else##
<!-- No Canonical Item Found for Tag: $!{tagId} -->
#end##
#end##
#end##
#end##
#end
Macro would then be called from the head section of the Global template:
#getCanonicalLinks()
[QUOTE=mjweise;20686]Hi Nate,
Actually we are in the process of upgrading to 7.2 as we speak. I should have it up and implemented in the next couple of weeks. Any examples you have regarding the taxonomy option would be a huge help to me. I am still a bit vague on what additional functionality is available in 7.2 so any and all input on that version would help.
Thanks!
Mike[/QUOTE]
$rx.location.generate($sys.assemblyItem) will generate the link using the Default template for the item. If you want to generate a link using a different template, you would pass that in as a second parameter, $rx.location.generate($sys.assemblyItem,“myOtherTemplate”). The location is generated using the location schemes defined in publishing design, so you’d need one for each template being published for that type if it has more than one. That is so that the urls are different.
There should be only one default template for a given type. Are you using a dispatch template maybe, if you have more than one page template on the type? Or are there more than one page template and they are set to “Always” publish?
-n
[QUOTE=mjweise;20688]When adding that statement to the VM file ($rx.location.generate($sys.assemblyItem) it works but requires a template association (I believe) so I can use that statement with ONE template e.g. erauGeneric and it works fine but I need to dynamically assemble every template. Does that make sense?
Mike[/QUOTE]
Binding Variables:
$pagelink
$rx.location.generate($sys.assemblyItem)
$canonicalLink
if ($context==0){$pagelink;}else{$sys.site.url+$pagelink;}
Use inside template:
link rel=canonical href=$canonicalLink
That definitely solves the use case where the canonical link is always the absolute URL of the current page.
-n
[QUOTE=hpp8140;20702]Binding Variables:
$pagelink
$rx.location.generate($sys.assemblyItem)
$canonicalLink
if ($context==0){$pagelink;}else{$sys.site.url+$pagelink;}
Use inside template:
link rel=canonical href=$canonicalLink[/QUOTE]
Thank you, great example. I appreciate it.
MJW
[QUOTE=natechadwick;20699]Here is a Taxonomy example.
This example assumes a setup where you have 2 shared fields that are using the taxonomy control, both pointed at the same taxonomy. These should be text data type fields, but not set to MAX. Use something like 2000. The fields are added to each applicable type and content is tagged. When tagging, the Canonical tag field is only populated for the authoritative URL for the given tag, the Tags field is populated for any tag that you might want. I tested it with FastForward so rffGeneric in the query could be changed to whatever types make sense. It is also using a method from the PSO Toolkit.
This would probably need tweaked for correctness (not sure if you really would want more than one authoritative link for a given item for example, this macro loops through each tag), but is an example of the approach.
#macro(getCanonicalLinks)
#if("$!{canonicalTagId}" == "")##
#if($sys.item.hasProperty("rx:canonical_tag"))##
#set($canonicalTagId = $sys.item.getProperty('rx:canonical_tag').string.trim())##
#end##
#end##
##
## We don't really want to do anything if this is the canonical link
#if("$!{canonicalTagId}" == "")##
## We want to get the canonical link for each Tag applied to this item.
#set($list = $rx.percTaxonomyJexl.getNodesFromIds($sys.item.getProperty('rx:tags').string))##
#if($list.size() > 0)##
#foreach($tag in $list)##
#set($tagId = $tag.getId())##
#set($keys=[])##
#set($vals=[])##
#set($pa = $user.psoMapTools.create($keys,$vals))##
#set($relresults = $user.psoQueryTools.executeQueryNodes("SELECT rx:sys_contentid FROM rx:rffGeneric WHERE rx:canonical_tag LIKE '%$!{tagId}%'",1,$pa,""))##
#if($relresults.size >0)##
#set($node = $relresults.nextNode())##
#set($clone = $sys.assemblyItem.getCloneParentItem())##
$clone.removeParameter("sys_folderid")##
$clone.setNode($node)##
#if("$!{clone}"!="")##
#set($relLink = $rx.location.generate($clone))##
<link rel="canonical" href="$relLink" />
#else##
<!-- No Canonical Item Found for Tag: $!{tagId} -->
#end##
#else##
<!-- No Canonical Item Found for Tag: $!{tagId} -->
#end##
#end##
#end##
#end##
#end
Macro would then be called from the head section of the Global template:
#getCanonicalLinks()
[/QUOTE]
Thank you, I appreciate it. I will take a look at it. I was wanting to utilize the VM to alleviate adding the code to each template separately. I am finding that that may not be an option. I did determine via a different post the code to add the absolute URL to each page. The problem is utilizing the canonical tag code via the VM file adds it the link to ALL pages and causes a separate problem in the use case of items that have been copied as a link etc. Anyways, thanks again.
MJW
[QUOTE=hpp8140;20702]Binding Variables:
$pagelink
$rx.location.generate($sys.assemblyItem)
$canonicalLink
if ($context==0){$pagelink;}else{$sys.site.url+$pagelink;}
Use inside template:
link rel=canonical href=$canonicalLink[/QUOTE]