Portal Engine Questions on portal engine and web parts.
Version 7.x > Portal Engine > Categories and Blog Posts View modes: 
User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 2/26/2013 8:14:01 PM
   
Categories and Blog Posts
Im using the built in categories with a blog post and I'm attempting to display all the categories for a post in a transformation and nothing seems to work. I have 20 posts and a nested category list in the transformation and it displays the same category on all blog posts even though they do not have a category assigned to the post. What am I doing with this seemingly simple item that's wrong?

User avatar
Member
Member
sobrohewolt-gmail - 3/5/2013 1:35:04 AM
   
RE:Categories and Blog Posts
I have this problem too. I am running a blogspot account but I could not use categories for my articles. Has there been any simple way to assign my articles to categories?

User avatar
Kentico Support
Kentico Support
kentico_janh - 3/5/2013 4:35:01 AM
   
RE:Categories and Blog Posts
Hello,

May I ask what exact code are you using in your transformation for displaying those categories? However, could you please take a look at this article which describes how to get categories for a current transformation item?

How do you render document categories for each document in a transformation?

Best regards,
Jan Hermann

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 3/6/2013 7:02:17 AM
   
RE:Categories and Blog Posts
Jan, I attempted that approach and received SQL errors. One was stating there was not a "selectversion" query so it crashed. The other was invalid sql, which when I ran the same exact query in SSMS, it worked just fine.

User avatar
Member
Member
davids-kentico - 3/6/2013 5:11:32 AM
   
RE:Categories and Blog Posts
Hey, I recently had the same problem, so I ended up writing a custom transformation function.

Here's the code:
public static string GetDocumentCategories(int documentId, string documentListAliasPath)
{
if (documentId < 1)
{
throw new Exception("Invalid document ID");
}

// Set to current document if the path was not given.
if (documentListAliasPath == null)
{
documentListAliasPath = CMSContext.CurrentDocument.NodeAliasPath;
}

// The resulting HTML code
string result = "";

// Get the categories.
DataSet ds = CategoryInfoProvider.GetDocumentCategories(documentId, null, null, 0, "CategoryID, CategoryDisplayName");
if (!DataHelper.DataSourceIsEmpty(ds))
{
foreach (DataRow row in ds.Tables[0].Rows)
{
// Construct links to the list of documents with the category ID in the query string.
int categoryId = ValidationHelper.GetInteger(row["CategoryID"], 0);
string categoryName = ValidationHelper.GetString(row["CategoryDisplayName"], null);

result += "<a href=\"" + UrlHelper.ResolveUrl(CMSContext.GetUrl(documentListAliasPath));
result += "?category=" + categoryId;
result += "\">" + categoryName + "</a> ";
}
}
return result;
}

Paste it into a new class in App_Code, then use it like this:
<%# CustomFunctions.GetDocumentCategories(Eval<int>("DocumentID"), "/Articles") %>

The first parameter takes the ID of the document you're rendering. The second parameter is optional. You can create a document which lists documents in a particular category and then pass the document's alias path to the second parameter.

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 3/6/2013 7:05:28 AM
   
RE:Categories and Blog Posts
Thanks David. I ended up creating my own ascx control with a repeater on it I was able to specify transformations, etc within the blog post transformation. I attempted to use the CategoryList webparts controls but was unsuccessful with them as well but after a quick look through the code, I found the code you mentioned
CategoryInfoProvider.GetDocumentCategories(int DocID, string Where, string OrderBy)
And it worked like a charm. I was able to get exactly what I needed in less than 30 lines of code.

User avatar
Member
Member
davids-kentico - 3/6/2013 9:55:32 AM
   
RE:Categories and Blog Posts
Glad to see your solution works.

Would you care to share it? I would be very interested what your control and transformations look like, and I'm sure I'm not the only one, as Kentico doesn't provide this useful functionality out of the box, unfortunately.

Thanks

User avatar
Kentico Legend
Kentico Legend
Brenden Kehren - 3/6/2013 10:48:01 AM
   
RE:Categories and Blog Posts
I like the option of just using a method to extract this data although it doesn't leave much room for formatting and/or creating links which is why I opted for this way.
ASCX control:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CategoryListing.ascx.cs" Inherits="Custom_Controls_CategoryListing" %>

<cms:CMSRepeater ID="rptCategories" runat="server" HideControlForZeroRows="true" />
Code behind:
using CMS.SiteProvider;
using CMS.UIControls;
using System;
using System.Data;

public partial class Custom_Controls_CategoryListing : CMSUserControl
{
public string TransformationName
{
get
{
return rptCategories.TransformationName;
}
set
{
rptCategories.TransformationName = value;
}
}
public int DocumentID { get; set; }
public string OrderBy { get; set; }
public string Where { get; set; }
public string TopN { get; set; }
public string ItemSeparator
{
get
{
return rptCategories.ItemSeparator;
}
set
{
rptCategories.ItemSeparator = value;
}
}

protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
SetupControl();
}
private void SetupControl()
{
DataSet ds = new DataSet();

// checking here to see if we need to limit it to a specific number or not
if (string.IsNullOrEmpty(TopN))
{
ds = CategoryInfoProvider.GetDocumentCategories(DocumentID, Where, OrderBy);
}
else
{
ds = CategoryInfoProvider.GetDocumentCategories(DocumentID, Where, OrderBy, Convert.ToInt32(TopN), "");
}

rptCategories.DataSource = ds;
rptCategories.DataBind();
}

public void ReloadData()
{
SetupControl();
}
}
Usage in a transformation:
<%@ Register Src="~/Custom/Controls/CategoryListing.ascx" TagName="CategoryListing" TagPrefix="uc1" %>
<uc1:CategoryListing runat="server" ID="CategoryListing" ItemSeparator="," TransformationName="cms.blogpost.BlogCategories" DocumentID='<%# ValidationHelper.GetInteger(Eval("DocumentID"), 0) %>' />
The transformation for the CategoryListing control (cms.blogpost.blogcategories)
<%# (DataItemIndex == 0 ? " in " : "") %>
<a href="<%# "~/Blog/Category/" + Convert.ToString(Eval("CategoryDisplayName")).Replace(" ", "-") %>"><%# Eval("CategoryDisplayName") %></a>
I use dynamic URLs for the Blog page that have the Category name in place so they are friendly URLs vs. catID=2 or something usless like that. I also modified the TagCloud webpart to do the same thing and use friendly URLs.

Its a bit dissapointing to me to be able to set "friendly URLs" in the Site Manager but it doesn't apply across all modules (i.e.: blogs, forums, etc.)