Hello again - Here is the latest installment of Sitefinity 4 tips. If you have any questions or issues implementing these tips, leave us a comment and we'll be sure to help out!
Using the Archive Widget
If you drag and drop the archive widget onto a Sitefinity page, it is extremely unclear of how to get it working. After some back and forth with the Sitefinity team, we found that there is a property called "ContentType" in the property list that you need to populate with a value. For use with a Blog, set ContentType to "Telerik.Sitefinity.Blogs.Model.BlogPost". Below is a list of various content types:
Telerik.Sitefinity.News.Model.NewsItem
Telerik.Sitefinity.Blogs.Model.BlogPost
Telerik.Sitefinity.Events.Model.Event
Telerik.Sitefinity.GenericContent.Model.ContentItem
Telerik.Sitefinity.Libraries.Model.Document
Telerik.Sitefinity.Libraries.Model.Image
Telerik.Sitefinity.Libraries.Model.Video
GetUsersInRole Error
Sitefinity has a function called GetUsersInRole that allows the developer to get a list of users that belong to a specific role. If you are logged into Sitefinity, this function works fine. But for the normal guest - it will throw this error: "Object reference not set to an instance of an object". To make this work, implement the following code in your code-behind instead:
UserManager.GetManager().Provider.SuppressSecurityChecks = true;
var roleMngr = RoleManager.GetManager(RoleManager.GetDefaultProviderName());
roleMngr.Provider.SuppressSecurityChecks = true;
Role MyRole = roleMngr.GetRoles().Where(r => r.Name == "myrole").Single();
var users = roleMngr.GetUsersInRole(MyRole);
The Suppress Security Checks are what allows you to run these functions without being logged into Sitefinity.
Search Index for Multiple Blogs
One frustrating thing about Sitefinity 4 is that (by default) each Blog has to share the same search index. Sitefinity's team provided us with a solution for creating a "custom" search index for a specific blog. Add the code below to your Global.asax code-behind file (if you don't have a Global.asax in the root - create it).
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Telerik.Sitefinity.Abstractions.Bootstrapper.Initialized += new EventHandler<Telerik.Sitefinity.Data.ExecutedEventArgs>(Bootstrapper_Initialized);
}
void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs e)
{
if (e.CommandName == "Bootstrapped")
{
var blog = App.WorkWith().Blogs().Where(b => b.Title.ToString() == "My Blog Name").Get().SingleOrDefault();
if (blog != null)
{
var pipeSettings = (SitefinityContentPipeSettings)PublishingSystemFactory.GetPipeSettings(ContentInboundPipe.PipeName);
pipeSettings.ContentTypeName = typeof(Telerik.Sitefinity.Blogs.Model.BlogPost).FullName;
pipeSettings.ContentLinks = new Guid[] { blog.Id };
pipeSettings.MaxItems = 0;
PublishingSystemFactory.RegisterTemplatePipe("SearchItemTemplate", pipeSettings);
}
}
}
} Save it and refresh your application pool in IIS. If you go to your search indexes in Sitefinity, you should have a new one specifically for "My Blog Name". Voila!
Issues with having the same widget on a page
If you are using the Blog Posts control more than one time on a page, then you may run into this issue (this tip works for all content based modules - news, events, blog posts, etc). In our case, we needed one of the controls to always list blog posts. The other control needed to show the detailed content for a blog post when it was clicked on. There are two settings that need to be set - and these need to be set for the control that always *lists* blog posts.
- Click [edit] on the control that should always list
- Click on [advanced] in the bottom right
- Near the bottom is the property ContentViewDisplayMode. By default, it is "Automatic". Set this to "Master".
- Scroll up and click the [ControlDefinition] button
- Scroll down and click the [Views] button
- Click the [Master***Frontend] button. "***" might be "BlogPosts" or "EventsList". Depends on which control you are using.
- By default "AllowUrlQueries" is set to "true". Change this to "false".
- Save
After saving and publishing the page, you should be all good to go. That control you just configured should always list content even when on a detail page.
Accessing Content Properties from Search Results
When Sitefinity returns search results, it does not return them as their native type. If you know that you are always searching for specific content type (Blog Posts, News Items, etc) - then you can use this trick. On your search results widget template, set its OnItemDataBound function to "RepeaterDataBound". In the code behind of your widget template, add the code below:
protected void RepeaterDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
BlogsManager bmanager = new BlogsManager();
var pData = e.Item.DataItem as Telerik.Sitefinity.Services.Search.Data.IDocument;
var pTitle = pData.GetValue("Title").ToString();
var pubDate = DateTime.Parse(pData.GetValue("PublicationDate").ToString());
BlogPost post = bmanager.GetBlogPosts().Where(b => b.Title == pTitle && b.Status == ContentLifecycleStatus.Live && b.Parent.Id == new Guid("0996B088-473C-4972-82D3-0252D40981F6")).SingleOrDefault();
}
} In the code above, we are finding the blog post for each search result. We can do this because "Title" and "PublicationDate" are properties of every search result. USing these properties, we can search for each unique blog post in the Repeater. Now, you can access all of the properties of that post. For instance:
var summary = post.GetValue("Summary").ToString(); Keep in mind that anytime you use the GetValue function, you need to include Telerik.Sitefinity.Model at the top of your code behind.