Portal Engine Questions on portal engine and web parts.
Version 5.x > Portal Engine > Category name in the url. View modes: 
User avatar
Member
Member
Leandro Brito - 9/14/2011 10:25:32 PM
   
Category name in the url.
Hello,

I searched some help about how to put the category name in the url and found something related with "wildcards".

The document type is "News" and it's has one category related.

e.g.
Categories: Mobile, CMS

www.domain.com/KenticoCMS/News/Mobile/mobile-phone-free
www.domain.com/KenticoCMS/News/CMS/kentico

*News in URL is a page item.

I try put this in document path of news "/{categoryname}/", but I got no sucess.

It's possible to do?

Thanks!

User avatar
Member
Member
kentico_michal - 9/16/2011 1:57:19 AM
   
RE:Category name in the url.
Hello,

Yes, it should be possible to accomplish. You can define a Wildcard URL in the following way: /News/{categoryname}

Now if you access a page /News/Development, the wildcard part of the URL (Development) gets translated into a query string parameter (categoryname= Development).

Then, you can use standard repeater with a special Where condition which would filter only documents with appropriate categoryname:

WHERE condition: '{%CategoryName%}' = '' OR (DocumentID IN ( SELECT DocumentID FROM CMS_DocumentCategory WHERE CategoryID = (SELECT CategoryID FROM CMS_Category WHERE CategoryName like '{%CategoryName%}') ))


For more information about Wildcard URLs, I would like to point you to the following article: Wildcard URLs

Information related to categories can be found here: Categories module overview

Best regards,
Michal Legen

User avatar
Member
Member
Leandro Brito - 9/16/2011 8:07:41 AM
   
RE:Category name in the url.
I see. But I think this will work for parent page (pageitem).

I don't understand how I will configure the url of document.

e.g.:

The user has created one news (document type) called "The best mobile SO" (the-best- mobile-so.aspx).
He chose for it the category "Mobile", so the url of this document (detail page) needs to be:

www.domain.com/News/Mobile/the-best-mobile-so.aspx

If he changed the category for SO in document form, the url needs to be:

www.domain.com/News/SO/the-best-mobile-so.aspx

Thank you.

User avatar
Member
Member
Leandro Brito - 9/18/2011 5:49:23 PM
   
RE:Category name in the url.
Hi,

Someone knows a way to do this on the news documento (no page item)?

Thx!

User avatar
Member
Member
kentico_michal - 9/19/2011 2:17:13 AM
   
RE:Category name in the url.
Hello,

In that case, you will need to manually define a new document alias through which the document should be accessible. If you want to create it automatically, you can take advantage of CustomDataHandler class which allows you to execute custom actions when any data item is created, updated or deleted. You will need to handle updates of cms.documentcategory class, which defines a relation between a document and a category, and create a document alias using the following API (How to create a new document alias using API)

So, please take a look at following code snippet which shows the OnBeforeInsert method of CustomDataHandler and how you to you can get the CategoryInfo object and TreeNode object from cms.documentcategory data class:


public override void OnBeforeInsert(object dataObj, object conn)
{
// INSERT YOUR CUSTOM BEFORE-INSERT CODE
SimpleDataClass dataItem = dataObj as SimpleDataClass;
if (dataItem != null)
{
if (dataItem.ClassName.ToLower() == "cms.documentcategory")
{
int documentId = CMS.GlobalHelper.ValidationHelper.GetInteger((dataObj as SimpleDataClass).GetValue("DocumentID"), 0);
int categoryId = CMS.GlobalHelper.ValidationHelper.GetInteger((dataObj as SimpleDataClass).GetValue("CategoryID"), 0);

CMS.SiteProvider.CategoryInfo category = CMS.SiteProvider.CategoryInfoProvider.GetCategoryInfo(categoryId);

CMS.SiteProvider.UserInfo ui = CMS.SiteProvider.UserInfoProvider.GetUserInfo("administrator");
CMS.TreeEngine.TreeProvider tree = new CMS.TreeEngine.TreeProvider(ui);
CMS.TreeEngine.TreeNode node = tree.SelectSingleDocument(documentId);
if (node != null && category != null)
{
// you can create a new document alias
// the current category name can be accessed using category.CategoryName property
}
}
}
}


For more information about CustomDataHandler, I would like to point you to following sections of Developer's guide: Event handling overview, Custom data handler


Best regards,
Michal Legen

User avatar
Member
Member
Leandro Brito - 9/22/2011 3:52:34 PM
   
RE:Category name in the url.
Hi,

I'm trying configure it but without sucess.
I followed the Event handling overview document, did all the configurations and put the code above, but the event never is called on debug.

User avatar
Member
Member
kentico_michal - 9/23/2011 1:12:25 AM
   
RE:Category name in the url.
Hello,

Could you please make sure that the <appSettings> node of your web project's web.config file contains the following key:

<add key="CMSUseCustomHandlers" value="true" />

as it is described here: Event handling overview.

Best regards,
Michal Legen

User avatar
Member
Member
Leandro Brito - 9/23/2011 8:10:18 AM
   
RE:Category name in the url.
Hi,

Thanks Michal, now the breakpoint is called when I insert a new document type (news), seems it's almost running.

I create the new aliaspath using category name (categoryname/documentname) and it appeared on the list of alias (property>url).

The last one problem is change the link on repeater for the new alias created, because
the GetDocumentUrl() continues getting the alias of tree, "pageitem/documentname". I will try change node aliaspath, but it is readyonly, so I'm searching about other ways to choose which document url I want use.

Can You help me on this final step?

Thank very much.

User avatar
Member
Member
Leandro Brito - 9/23/2011 8:14:05 AM
   
RE:Category name in the url.
My code snippet



public override void OnBeforeInsert(object dataObj, object conn)
{

[...]
string newAliasPath = "/News/" + category.CategoryName + "/" + node.NodeAlias;

CMS.TreeEngine.DocumentAliasInfo aliasinfo = new CMS.TreeEngine.DocumentAliasInfo();
aliasinfo.AliasURLPath = newAliasPath;
aliasinfo.AliasCulture = "pt-BR";
aliasinfo.AliasSiteID = CMS.CMSHelper.CMSContext.CurrentSiteID;
aliasinfo.AliasNodeID = node.NodeID;
aliasinfo.AliasExtensions = ".aspx";
aliasinfo.SetObject();
}


User avatar
Member
Member
kentico_michal - 9/26/2011 5:57:25 AM
   
RE:Category name in the url.
Hello,

You will need to use some custom method instead of GetDocumentUrl method and create links to documents using custom code.

You can access all document aliases of the currently displayed documents and choose one of them:


GeneralConnection con = ConnectionHelper.GetConnection();
DataSet ds = GetDocumentAliases("AliasNodeID = " + nodeId, null, conn);

if (!DataHelper.DataSourceIsEmpty(ds))
{
// For each alias
foreach (DataRow row in ds.Tables[0].Rows)
{
DocumentAliasInfo infoObj = new DocumentAliasInfo(row);
if (infoObj != null)
{
// choose one document alias
}
}
}


For more information about custom transformation methods, I would like to point you to the following article:
Custom functions to transformations


Best regards,
Michal Legen

User avatar
Member
Member
Leandro Brito - 9/26/2011 8:01:06 AM
   
RE:Category name in the url.
Thanks for the clarification Michal.

One last question to finish my problem.

How can I find the categoryid or categoryname of the document?

I want access the categoryname for compare the alias and choose one path.

By example:

I have the news with category "Mobile" and the paths "News/Mobile/docname" and "News/PC/docname". So I need compare "if (aliaspath.Contais(categoryname)) use it".

What document has informations about this kind of code, using C# to get more informations about documents?
I've searched in dev manual about the Class CategoryInfoProvider but didn't find it

Thanks again.
Best regards.

User avatar
Member
Member
kentico_michal - 9/26/2011 1:59:19 PM
   
RE:Category name in the url.
Hello,

You can use the GetDocumentCategories from CMS.TreeEngine.DocumentCategoryInfoProvider class.

Please take a look at following code snippet:


GeneralConnection conn = ConnectionHelper.GetConnection();
DataSet ds = DocumentCategoryInfoProvider.GetDocumentCategories("DocumentID = " + documentId, null, conn);
if (!DataHelper.DataSourceIsEmpty(ds))
{
foreach (DataRow row in ds.Tables[0].Rows)
{
DocumentCategoryInfo documentCategoryInfo = new DocumentCategoryInfo(row);
if (documentCategoryInfo != null)
{
CategoryInfo categoryInfo = CategoryInfoProvider.GetCategoryInfo(documentCategoryInfo.CategoryID);
if (categoryInfo != null)
{
// here you can access the categoryInfo.CategoryName
}
}
}
}


Best regards,
Michal Legen

User avatar
Member
Member
Leandro Brito - 9/26/2011 2:06:18 PM
   
RE:Category name in the url.
Thank you very much!

User avatar
Member
Member
Leandro Brito - 10/3/2011 8:17:25 AM
   
RE:Category name in the url.
Hi,

I have one problem. I'm trying publish my site with the project CustomEventHandler, but I don't know how to do.
The publish of visual studio returns a error and put the folder in the same structure of dev enviroment but it doesn't work.

User avatar
Member
Member
kentico_michal - 10/4/2011 6:01:18 AM
   
RE:Category name in the url.
Hello,

Could you please make sure that you have done everything required as it is described in the documentation: Pre-compilation publishing

Best regads,
Michal Legen

User avatar
Member
Member
Leandro Brito - 10/4/2011 10:46:15 AM
   
RE:Category name in the url.
I'll need deploy my site for a instance of kentico where already exist other site.
Is possible use the DataCustomHandler without pre-compile the site?

User avatar
Member
Member
tiago.guirado-gmail - 10/4/2011 2:34:04 PM
   
RE:Category name in the url.
Hi,
I have the same problem. I need to publish my site without pre-compilation.
Can anyone help us please?

User avatar
Member
Member
kentico_michal - 10/5/2011 8:12:53 AM
   
RE:Category name in the url.
Hello,

You can copy files from CustomEventHandler project (CustomDataHandler.cs, CustomTreeNodeHandler.cs, CustomWorkflowHandler.cs, etc) to the AppCode folder and modify them according to your requirements.

Then, you will need to modify the GetCustomClass method (~\App_Code\Global\CMS\CMSCustom.cs):


// Provide your custom classes
switch (className.ToLower())
{
// Define the class MyTask implementing ITask and you can provide your scheduled tasks out of App_Code
case "custom.mytask":
return new MyTask();
case "app_code.customworkflowhandler":
return new CustomWorkflowHandler();
case "app_code.customtreenodehandler":
return new CustomTreeNodeHandler();
case "app_code.customsecurityhandler":
return new CustomSecurityHandler();
case "app_code.customexceptionhandler":
return new CustomExceptionHandler();
case "app_code.customdatahandler":
return new CustomDataHandler();
}



Then, you need to also add the following key to the web.config file [appSettings]

<add key="CMSCustomHandlersAssembly" value="App_Code" />

For more information I would like to point you to the following blog and its comments: Provide your classes from AppCode

Best regards,
Michal Legen