New Multiple Blog Feature - Site Aggregation

April 15, 2012 at 12:10 AMBen

A new feature named Site Aggregation is available in the BlogEngine.NET developer builds, and will of course be available in the next public release.  Site Aggregation is a feature related to Multiple Blog instances and this has been asked about by several people.

What is Site Aggregation?

You can designate up to 1 blog instance as being the Site Aggregation instance.  Typically it would be the primary blog instance.  When a blog instance becomes a Site Aggregation instance, the data displayed on the homepage, RSS feed and widgets contain blog posts from all the blog instances (see below for a complete list).  So the data is an aggregate of the blog posts across all instances.

This is useful for site visitors who will be able to visit the main blog, and see blog posts across all instances.  And if the RSS feed is subscribed to, that too aggregates blog posts across all instances.

What's Included

The main homepage, Posts by Tag page, and Posts by Date Range pages display the site aggregate data.  All the main widgets including the Tag Cloud, Recent Comments, Month List, Recent Posts, Calendar also take into account the site aggregate posts.  The Search results page, and RSS feed too.

For each post listed, clicking on the post title will take you to that post within that post's blog instance.  Each post usually also lists Tags and Categories tied to that post.  Clicking on a tag or category link will take you to the tag/category listing page for that post's blog instance (i.e. you will leave the site aggregate blog).

What's Not Included

Category based pages/widgets do not currently aggregate posts across all sites.  In particular, this includes the Category List widget and the Archive page.  These items still can be used on the site aggregate blog instance, but they will only display Posts for the site aggregate blog instance -- not for any of the non-site aggregate blogs.  The code needed to make these Category pages work with the site aggregated data is partially implemented in the Category core class (in particular, Category.AllBlogCategories and Category.ApplicableCategories), but some more work is needed for this.  It may not be until the following release where these category widgets/pages are site-aggregate capable.

The other item which is not included are Pages.  I think in most cases, it is preferable that Pages are not aggregated across all sites.

Configuring the Site Aggregate Blog Instance

It's very easy to designate a blog instance as being the site aggregate blog instance.  On the Blogs management page, there is a new "Is For Site Aggregation" property/checkbox you can check -- as shown below.

 

A Look at the Site Aggregate Blog Instance

In my test system, I have a primary blog instance, which is also the site aggregate blog instance, and 2 sub-blogs.  One sub-blog uses a virtual path, and the other sub-blog uses a different hostname.  Each blog instance has a post in it.  Here's what the homepage of the site aggregate blog instance looks like:

 

Similarly, here's a view of the RSS feed:

 

Site Aggregation Site - Includes "Local" Posts

The Site Aggregation site includes posts from other blog instances, as well as posts from its own instance (local posts).  This means you can create posts in the site aggregation instance as well, which is probably a handy feature for some.

Relative & Absolute Links

One issue that is accounted for is if you are using different hostnames for your blog instances.  For example, if your site aggregation instance is running at www.example.com and you have a sub-blog running at sub1.example.com, a lot of the links in BlogEngine.NET use relative paths, via RelativeLink and RelativeWebRoot.  A typical example is a hyperlink that you would find in PostView.ascx.

<a href="<%=Post.RelativeLink %>" class="taggedlink"><%=Server.HtmlEncode(Post.Title) %></a>

This URL in the HREF would end up being an invalid URL when the site aggregation site is displaying a post for sub1.example.com.  It would need to be an absolute link to "escape" out of the current hostname and get over to the other hostname (sub1.example.com).  The simple solution is to convert all these RelativeLink to AbsoluteLink.  A new property has been created off of IPublishable named RelativeOrAbsoluteLink.  This will return a relative link if it works, and if not, it will return an absolute link.  While an absolute link in theory always works, there are some advantages to using relative paths whenever possible.  So when using this new RelativeOrAbsoluteLink property, if the sub-blog's hostname matches the hostname of the site aggregation blog instance, you'll get a relative link, otherwise an absolute link.  Because the minority of BlogEngine.NET users won't be this situation where they are (a) using multiple blogs, (b) using the Site Aggregation feature, and (c) using different hostnames, RelativeOrAbsoluteLink will basically preserve backwards compatibility for everyone else not in this situation.

On this note, if you are using a custom theme, you may need to change RelativeLink in the PostView.ascx page to RelativeOrAbsoluteLink -- if you are in this situation.

A similar new property has been created in the Utils class, named RelativeOrAbsoluteWebRoot.  Just like RelativeOrAbsoluteLink, RelativeOrAbsoluteWebRoot will return the RelativeWebRoot if it works, otherwise it will return AbsoluteWebRoot.

AllBlogPosts and ApplicableBlogPosts

These are 2 new properties in the Post class, which are used to support this site aggregation feature.  AllBlogPosts is a list of posts across all blog instances.  It's very similar to Post.Posts.  Post.Posts is just for the current blog instance, where Post.AllBlogPosts is posts across all instances.  The only real challenge here is the blog posts for a particular blog instance are not loaded into memory until the first time that blog instance is hit.  If the site aggregation blog is hit before some of the sub-blogs have been hit, the data (Posts) for those sub-blogs will not yet be loaded in memory.  The AllBlogPosts property takes care of this by loading the posts of these sub-blogs into memory that have not yet had their first hit.

ApplicableBlogPosts is a shortcut property that either returns AllBlogPosts or Posts depending on which one is needed.

The Category class has similar properties that have been added to it -- AllBlogCategories and ApplicableBlogCategories.  These properties will be useful when the Archive page and Category based widgets such as the Category widget become site aggregate data capable (as mentioned above, these items are not yet site aggregate capable).

Blog and BlogId added to BusinessBase

The last notable change for this feature is the BusinessBase class now has Blog and BlogId properties.  This means objects such as Post, Category, BlogRollItem  (and anything else inheriting from BusinessBase) are now aware of which blog instance they belong to.  This has a lot of potential uses.  The main purpose for this at this point is properties such as RelativeLink (as in Post.RelativeLink) now take into account its blog instance's virtual path and hostname.  So when working with Post.AllBlogPosts which contains blog posts across all the blog instances, calling Post.RelativeLink or Post.AbsoluteLink on any of the posts in this AllBlogPosts collection will return the correct path.  As noted above, it's not safe to use Post.RelativeLink especially when working with Post.AllBlogPosts data.  Instead, Post.RelativeOrAbsoluteLink or just Post.AbsoluteLink are the safer choices.

Give it a Try

If you think this new Site Aggregation feature may be of use to you, I encourage you to try it out, either now or once the beta for the next version of BlogEngine.NET comes out.  The best place to bring up any issues or suggestions regarding this feature is in the CodePlex discussions group.

Comments (7) -

This should be ideal for my family blog Smile

Andy McKay
Andy McKay says:

Don't currently use multiple blogs myself, but having a viewport to all blogs is such an obviously good feature to have, shame the categories aren't going to be ready for this release, but well done on getting this implemented.

As a matter of interest, how will this affect the aggregate blog in presenting a collection of blogs where each has a high volume of posts i.e. is scalability going to become more of a priority?  

Hi Andy.  Scalability has always been an issue, but the new aggregation feature does not make it worse, it's the same.

If anything the multiple blogs feature from v2.5 will tend to cause more data (posts) to be written and stored in memory.  Before this site aggregation feature, the blog posts across all blog instances were being stored in memory.  The site aggregation feature is taking all that blog post data (already in memory) and combining it into a single List that is sent to the normal PostList user control, with the normal paging.  The PostList user control typically displays 10 posts or so at a time, so the performance here will not be affected.  And so memory wise, the master List of posts used for the site aggregation is the only real impact which I believe is minimal since it's essentially a collection (or list) of pointers to Posts already in memory.

We still need to address the core scalibility issue.  Maybe via IQueryable.  I think the XML storage makes it a lot more difficult to make it work, and DB only would be easier.  XML is of course a super convenient way to run a blog though.

Andy McKay
Andy McKay says:

Hi Ben,

Thanks for clarifying, that makes sense.

I guess I was also thinking about things like related posts for example. In the aggregated instance that could be a rather large list to process if you are considering posts across all instances, but I suppose it comes back to the core issue of scalability and XML is indeed very appealing, especially for new BE users.

Just thought I'd mention in case the glitch is not my end, got the comment notification email twice.

Cheers

When replying before, I wrote a new comment rather than a Reply to you.  I realized it after saving it, so deleted my original comment and posted the comment again as a Reply.  What can I say, I'm a newbie Smile

Yeah, scalability will be a big topic to address.  It'll be nice to come up with a solution for it some day.

Andy McKay
Andy McKay says:

Hi Ben,

Really impressed with how the blog aggregation works. The first thing I did after downloading BE 2.6 release candidate was to have a look at a couple of the standard controls to see if there had been any changes to support aggregation and didn't see anything, so started poking around elsewhere based on the pointers in your post, still digesting the changes but credit where it's due - this is very nicely done.

Glad you had a chance to take a look.  Yeah, the code changes are subtly here and there, nothing too groundbreaking.  Thanks for the feedback :>

Pingbacks and trackbacks (4)+

Comments are closed