ThemeEngine.Net: A Theming Engine For BlogEngine.Net

A major item on my BlogEngine.Net wishlist has been the ability to customize the sidebar elements on a page-by-page basis. For example, I'd like to show the latest posts in the side bar, but not on the home page where the body of the page displays the posts anyway. Or  I'd like to show the search box in the sidebar on all pages, but not on the search page which has it anyway in the body.

Extending the trend of thought, why not customize the sidebar on category pages? Wouldn't it be nice to fill the sidebar with information or links related to the category? And going a step even further, why not have the ability to customize the sidebar on any page or post as you can do with Drupal and Wordpress?

But that's not possible with BlogEngine.Net because it routes almost all page display through default.aspx. Therefore, you can customize the sidebar(s) to your hearts content in your theme, but you get the same sidebar on all your pages.

ThemeEngine.Net is a theming engine that allows you to customize the sidebar content on any page on your web site. It's not really an engine or anything; it's simply a master page, a bit of URL rewriting code which I cut and pasted from BlogEngine.Core, and a set of conventions. But calling it ThemeEngine.Net sounds a bit more grand.

ThemeEngine is not a theme; it is a way of building BlogEngine.Net themes. You can easily convert any BlogEngine theme to use ThemeEngine. ThemeEngine doesn't modify any of BlogEngine's source code.

Actually, you do have to make a small change to the blog.js file. In the addComment: function(preview) method, the CommentView1 control's id is hard-coded as ctl00cphBody$CommentView1. When you add ThemeEngine's master page to the mix, ASP.Net changes the id of the control to ctl00$ctl00$cphThemeEngine$cphBody$CommentView1. So you must change it in the addComment: function(preview) method for the comment posting to work. But I hear this problem is being fixed in the next version of ASP.Net. So I still maintain that ThemeEngine doesn't really change any of BlogEngine.Net's source.

ThemeEngine's code resides entirely in the theme folder. It uses a Wordpress-like logic to load sidebar content dynamically.  In a nutshell, this is how it works:

  • ThemeEngine has a master page called ThemeEngine.master. It consists of the html head and body sections of your theme's template. It has a single ContentPlaceHolder control, cphThemeEngine. ThemeEngine.master's code-behind class contains the URLrewriting code that I mostly copied and pasted from BlogEngine.Core.
  • A ThemeEngine enabled theme's site.master inherits from ThemeEngine.master. Site.master has a single content control that fills cphThemeEngine from ThemeEngine.master. All your html markup resides inside the content control that ends up in cphThemEngine.
  • You can have as many sidebars as you want, but to keep this explanation simple, assume that you have a single sidebar. You place it within a placeholder control inside cphThemEngine. For this example, let's say the placeholder's id is phSideBar.
  • The content that will go in the sidebar resides in a subfolder of a folder named ThemeEngine within your theme's folder. The subfolder has the same name as the id of the placeholder on your page. So in this example, the folder would have to be named phSideBar. Inside the phSideBar folder, place a user control that has the default content of the sidebar and name it default.ascx.
  • Now to customizing the content. ThemeEngine uses a Wordpress-like template hierarchy. Let's say you want to customize the sidebar on contact.aspx. Simply put a user control in the phSideBar folder with the desired content and name it contact.ascx. Customizing search.aspx? Place another control with the desired content in phSideBar folder and name it search.aspx. This scheme takes care of the home page, default.aspx, and other "built-in" pages - contact.aspx, search.aspx, archive.aspx, and error404.aspx (yes, you can customize the sidebar on the error page as well). Remember, you don't have to have a user control for each of the pages. If you have an appropriately named control, ThemeEngine will load it. If you don't, ThemeEngine will load the content from default.ascx. And if you don't have default.ascx either, ThemeEngine will leave the control blank. (Actually it loads a control called ThemeEngineFallback.ascx, which has no content.)
  • The scheme works for categories as well, except that the user controls reside in a subfolder (of phSideBar) named category. If the name of the category is, say, my-books, you'll have a user control called my-books.ascx at the location /themes/yourtheme/ThemEngine/category/my-books.ascx. If you want the same sidebar content on all caltegory pages, create a control called  category.ascx. At run time, ThemeEngine tries to locate a control with the same name as the category. If it's found, ThemeEngine loads the control. If not, ThemeEngine looks for a control called category.ascx, and if found loads it. If not, it attempts to load default.ascx from the ThemeEngine folder. And if you don't have that one either, ThemeEngine leaves the placeholder blank.
  • Now you've got the hang of the thing. It works the same way for posts. The folder path for posts is /themes/yourtheme/ThemEngine/post/.
    The default control for posts is post.ascx located at /themes/yourtheme/ThemEngine/post/post.aspx. To customize a post called my-first-published-book.aspx, place a control named my-first-published-book.ascx in the post folder. At run time, ThemeEngine tries to locate a control with the same name as the post. If it's found, ThemeEngine loads the control. If not, ThemeEngine looks for a control called post.aspx, and if found loads it. If not, it attempts to load default.ascx from the ThemeEngine folder. And if you don't have that one either, ThemeEngine leaves the placeholder blank.
  • What if you have two sidebars, say, phRightSidebar and phLeftSidebar? You'll simply have a folder for each inside the ThemeEngine folder. You can have 100 sidebars for all ThemEngine cares.

FAQ

How many sidebars can I have?
As many as you want.

Why have another masterpage? Why not add the code to site.master?
1. The new masterpage keeps all the code separate from whatever code you might have in site.master
2. Updates to the code can be seamless.

What if I have other placeholders which I don't want to load dynamic content into?
ThemeEngine ignores any placeholders for which it doesn't find a folder inside the ThemeEngine folder.

Can I widgetize my themes?
Sure. Just put the widget code inside your user controls. But remember: because of BlogEngine.Net's architecture, that widgetized content is not customizable on a page-by-page basis. But you could always add static content to your controls along with widgetized content.

Do you have a working example?
This web site. Visit the search or contact pages, or some of the category pages and you'll see that they have different content in the right sidebar.

Where can I download it?
The attached zip file, TEStandard.zip (10.52 kb) contains the ThemeEngine version of BlogEngine's Standard theme. It's called TEStandard. Just create the necessary subfolders for your site's structure.

How can I BlogEngine-enable a theme?
1. Copy ThemeEngine.master and ThemeEngine.master.cs to the theme folder.
2. Create a folder named ThemeEngine in the theme folder.
3. Copy ThemeEngineFallback.ascx to the theme folder.
4. Change site.master to inherit from ThemeEngine.master and to use its cphThemeEngine ContentPlaceholder.
5. Change BlogEngine.Net's blog.js to change the name of the control as mentioned above.
    (If you don't do this, the Saving Comment... spinner will keep showing after you try to add a comment.)
6.Create the necessary folders and ascx controls

 


Comments

May 23. 2009 01:56 PM

BlogEngine Themes

This is awesome!  And I made my "ThemeEngine" the name of my project because it can persist any selected theme across postbacks, lol.  I think yours is better suited to be called that.

Great job, I'll have to play around with this a bit.

Would you be interested in posting this up on BlogEngineTheme.com?

BlogEngine Themes

August 26. 2009 01:07 AM

Narashiman

Hi,

I am trying to integrate the Blogengine Blog and also the jitbit free forum together.
And i have tried all the permutations and combinations of integrate of integrating them and am getting the error
Object refrence not set to and instance of the object.

As both the Blog and Forum have DLL, both needs Default.aspx
but i can include only one. Can i change the name of the Default.aspx to blog.aspx for blog and make the blog working without the default.aspx, coz i cannot change the name of the default.aspx of the forum page.
Its compulsary to use the default.aspx page for jitbit forum.

Please can u help me what to do .!!
Waiting for your reply.

My email id is shiman123@rediffmail.com

Regards
Narashiman

Narashiman

Add comment




  Country flag

[b][i][u][quote]
Loading