The ScenarioWhat we need for one of our projects is to automatically publish content from external blogging frameworks into our Sitefinity project. This is easily accomplish with taking RSS feeds from the external platforms and setting them as inbound pipe and publishing them as blog posts. This works greatly out of the box. The problem comes when the search engines index our automatically published content - since this content will be exact duplicate, we have to decorate it the proper way so our SEO rank doesn't suffer. We have to set the following markup in our page, to designate the original source of this content:
<link rel="canonical" href="[original url]" />
Extending the Blogs module
First, we need a new field to keep the source of a blog post. Every post that is automatically published will have this field filled with the url of the original blog post. The rest will have just an empty field. This is easy to be done through the administration: Go to Blogs module -> Click on a random blog -> "Custom fields for posts" -> Click on "Add a field". Choose appropriate name (let's say CanonicalLink) for the field and set it to a short text type. Done.
After that we need to write some logic that adds the suitable markup when this field is not empty. To achieve this, the easiest way I found is to derive from "Telerik.Sitefinity.Modules.Blogs.Web.UI.Public.DetailPostView" class, override the InitializeControls method and implement the logic I need there.
Finally, we need to set this modified class as a detail view for blog posts - this is done again through the administration: Administration -> Settings -> Advanced -> Blogs -> Controls -> BlogPostsFrontend -> Views -> DetailBlogPostsFrontend. There is a field "ViewType" here and you should set the fully qualified typename of the modified class. Hitting save will modify some config files, so they should be checked outand the app pool user should have permission to modify them.
So far so good, if we have the field filled in - the proper markup will be rendered. We need to fill the field now.
Extending the Alternative publishing system
As I mentioned the backbone of this system are inbound pipes and outbound pipes. These are basically the input and the output of the system. For this task, we need to extend the default outbound pipes for Sitefinity content and make it to fill the custom field we already created. So, we derive from the Telerik.Sitefinity.Publishing.Pipes.ContentOutboundPipe :As you can see, I've override the SetPropertiesThroughPropertyDescriptor method to set the custom field I need. Using reflection (no other way unfortunately), I look for a property called "Link" in the wrapperObj - this is the object Sitefinity provides to the outbound pipe, so the pipe can produce the Sitefinity content.
There is another static method used to register the pipe. Here comes the bad news - I couldn't find a way to replace the default outbound pipe with the modified one, so I had to add a new one. This might be incovenient for the end user and leads to misunderstanding sometimes (probably hiding the default one from the UI with css is an option). Everything I tried with removing the default one or replacing it - leads to runtime errors. So, here is how to add a new outbound pipe - subscribe for the initialized event that Sitefinity exposes and call the static method that is already provided in the outbound pipe:
Well, that's all - after you build and restart you will get your new outbound pipe as an option in the dialog:
Boyan Barnev for helping me with this one, I wouldn't do it without his help :)