[Coldbox: 3.6] HTMLHelper / Canonical URL's

Hi folks,

I’ve been working on some updates to the HTMLHelper for an upcoming ColdBox release which adds improvements to the link() and meta() functions. In particular I’ve added logic to link() to support the canoncial url’s as well as force to the buffer / htmlhead by default.

Reference: http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394

In the BaseHandler of my site I want to use this function to generate a default canoncial URL using event.getCurrentRoutedURL(). In each handler method there may be a case to override the default canonical URL.

Here is the new code for the link() function in HTMLHelper: https://gist.github.com/af9aaf2f50d903537361

By default the link element will be forced to the html head using $htmlhead(buffer.toString());

So in BaseHandler.cfc I’ll call:

//Inject html helper
property name=“html” inject=‘coldbox:myPlugin:HTMLHelper’;

html.link(type=“canonical” rel=event.getCurrentRoutedURL());

In my handler I might then override to:
html.link(type=“canonical” rel=event.buildlink(‘foobars’));

Calling the link() function twice will result in two canonical link elements being generated however I only want one.

So my question is how can I look into the buffer to see if a canonical link element is already there, and remove it? Make sense?



Try this instead


Hi Andrew,

First off, great post. I have seen those helpers in ContentBox and always
wondered how they worked.

That being said, i'm not entirely sure how I would make this work for my
If I used your approach I still don't understand how or what
object/variable I would be evaluating to determine if something was already
in the buffer.

I took a read through your first post on HTMLHelpers -

Is the only difference between this approach and injecting a custom
plugin/using wirebox is that your approach "attaches" the custom plugin
during the interception registration chain? If so, that's cool as it saves
a step, but in reality it provides the same capabilities if you were to do
it through DI.

Also, in your example you refer to "custom_beforeHeadEnd" in the helper
call, however the interception point name is "cbui_preRequest". should
these not be the same? If not, I don't understand how they reference one

In my app I'm using a RequestContextDecorator as well, which I use for
adding JS/CSS programatically.

So in a handler I can say...Event.addAsset('css','myfile.css") and that
will get appended into the buffer. This allows me to programatically add
assets on a handler/method basis whereas if I were to use your approach (
all of the logic to display the CSS/JS, etc would be encapsulated within
the interception point which seems a bit restrictive. I can definately see
though how it could be used for stuff like displaying menus, etc, and
certainly some cases to drop in a bunch of assets, but personally I like to
have finer control on a case by case basis.

I'm interested in your approach and could see how it can be applied to what
i'm trying to do, I'm stuck on the buffer part where I need to determine if
a canonical link element should use the default, or if it was overwritten.
Would you be so willing to take your blog post another step further to
apply my scenario?

Thanks for your time. PS, I like the new blog styling.


You don’t need to understand what is in the buffer, the idea is that the interceptor that you create listens for that event or more to the point is run when it is announced.

So that means one interceptor could be for adding what you want, another could be for adding skins and another could be for adding JS to the header. All interceptors will do what they need to do, all they just have to be registered and the custom interception points registered. For example I wrote two modules for ContentBox, that uses this one sole purpose is for displaying the Open Graph tags for my blog as it is run only once it gets displayed only once, the second module has another interceptor and its sole purpose is to display Google Analytics, and I can switch them on or off without changing core code.

You could get to the buffer if you need, but in this case there will be no need. As the interceptor is only run once and will add what you tell it too add, as the example shows. To show case that create two interceptors to listen for the same announcement, but display different things.

As for the difference, the approach I have gone down is to apply that html helper only when the renderer is loaded and configured, that means it will be available in any view or viewlet only. Where DI will only make it available to the handler, so if you wanted to write your own or extended or changed version then you have the ability to do so.

As for being restrictive, it is the exact opposite.

Lets take modules into consideration here for a minute, each would not know what the other is doing. Which means you have to write code to do all sorts of checks, for example like you discovered you need a way to only include it once. You could use the addAsset method and it will do the same job, but you would need to have two parts one that adds the asset and one that actually displays the asset. The adding part will be the area where you check to see if it has already been added.

Now modules come into play, because you can drop a module in that can be notified of this interception point, and just append to the buffer nothing more nothing less, and you can just pull the module or place/drop it in and it will just work. With less code to do so.

The scalability is that bit, there is nothing more to write and you’re allowing for future modules to hook into this or not.

Well canonical links, now this is something I have read up, but only briefly over the years. But these links are for search engines, what that means is that if you have a path or in the case of ColdBox a handler that might display a table of contacts, but you could sort these depending on what criteria you pass through the event handler. Search engines don’t care about this, and they are more inclined to just use the default option or whatever the feel is best.

In other words if the data or content is going to be the same, with different options to display the content differently then search engines would like to know so they display what you want them to display when the link is clicked in the search engine.

So in your case, you can build the canonical link the same way inside the htmlHelper or the interceptor it doesn’t matter where.

And yes that was a mistake on my part with the interceptor method, I have now fixed this, as there is an issue with some posts when editing the code gets jumbled, so I had to re-paste it again and forgot to change the method name.

And thanks for the positive feedback on my blogging. As for taking it a step further, sure I can do that with another post, might be a few days though.