Uncategorized

Get users by taxonomy category

Ektron’s taxonomy feature allows you to categorise not only content but also users and user groups too. Putting a user into a category has all kinds of uses such as identifying users who have performed a certain task on your site like signing up to a feature or adding something to their profile.

There is a little bit of a grey area in terms of whether you would use a user group or custom user properties for some of the use cases. Taxonomy is always going to be the more powerful option as it provides a hierarchical structure whereas groups and properties are flat.  Taxonomies themselves can also be extended through the use of custom properties on the category.

So consider what you will use it for before you go ahead and choose the right approach.

Here is a simple code sample:

// Use the Framework API from versions 8.5 onwards
Ektron.Cms.Framework.User.UserManager uMgr = new Ektron.Cms.Framework.User.UserManager();
Ektron.Cms.User.UserTaxonomyCriteria criteria = new Ektron.Cms.User.UserTaxonomyCriteria();

// Get users based on taxonomy ID
//criteria.AddFilter(Ektron.Cms.User.UserTaxonomyProperty.Id, Ektron.Cms.Common.CriteriaFilterOperator.EqualTo, 98);

// Or get users based on Taxonomy Path
criteria.AddFilter(Ektron.Cms.User.UserTaxonomyProperty.Path, Ektron.Cms.Common.CriteriaFilterOperator.EqualTo,
"\\UserTax");

List userList = uMgr.GetList(criteria);

Response.Write(userList.Count().ToString());

The above code uses the Ektron Framework API to get the information so you will need to be using Ektron version 8.5 or greater.

Geo IP lookup API in Ektron

A useful feature of Ektron CMS is the ability to target content at specific people based on their geographic location. This is commonly done within the Targeted Content widget.

However there are often times when you need the ability to do this in code outside of a Pagebuilder widget. Fortunately the Ektron API provides you with a simple way of determining where the user is coming from:

Ektron.Cms.UserLocationData userLocationInfo = Ektron.Cms.UserContext.GetLocationInfo("192.168.1.1");

if (userLocationInfo.CountryCode == "GB")
{
// User is from Great Britain
}

The simple example given above determines if a user resides in Great Britain or not by checking the CountryCode property of the UserLocationData object.  The GetLocationInfo() method takes a string parameter that holds the IP address that you want to look up.  Typically you would get this address by calling something like Request.UserHostAddress.

There are many other properties available from the UserLocationData object such as:

  • CountryName
  • City
  • Latitude
  • Longitude
  • Postalcode

The CMS makes use of three data files that are stored in your App_Data folder to get this information.  Those files are:

  • GeoIPDomain.dat
  • GeoIPOrg.dat
  • GeoLiteCity.dat

These data files are from an organisation called MaxMind so it is possible to update the data files from there and also to purchase a more complete file that contains advanced information (like what company a user works for).

Slow login to Ektron

I recently discovered a problem on a client’s site whereby it was taking a long time to login to the CMS. They had Active Directory integration enabled but we were able to rule that out as being the cause of the slowness by temporarily disabling it.

We also investigated the possibility that there may have been some plug-ins / extensions running that could be performing some kind of background task and slowing it down.  However this was not the case either. The problem did turn out to be related to plug-ins though…

Remember that from v8.0 Ektron introduced Extensions to replace the older plug-in technology. Plug-ins and Extensions allow you to write code modules that execute code following on from events that occur within the CMS. Such an event might be related to creating a user or deleting a content item.

There is a setting in the Ektron web.config file that turns the old plug-ins on or off:

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

If you are on version 8.0 or greater then this setting should always be “false”.  Unbeknownst to me at the time, adding new content items was also running slowly. This was also due to this setting being set at “true”. Basically, the Ektron was looking for the old plug-ins and waiting for a set amount of time before giving up – hence the delay.

Setting this to “false” suddenly made adding content and logging in users much faster!

Get content taxonomy using Ektron API

Ever wondered how to get the taxonomies that a content item is assigned to whilst using the Framework API?

In the older APIs there was a method called Ektron.Cms.API.Content.Taxonomy.ReadAllAssignedCategory().  This worked fine, but what if we want to use the fabby new Framework API?  Well here is how:

/// <summary>
/// Return the Taxonomy ID for a given content item. Only picks
/// the first taxonomy if there are more than one.
/// </summary>
/// <param name="contentId">Content Id</param>
/// <returns>Taxonomy ID</returns>
public long GetContentItemTaxonomyId(long contentId)
{
    long taxonomyId = default(long);
    var taxItemMgr = new TaxonomyItemManager();
    var itemCriteria = new TaxonomyItemCriteria();
    itemCriteria.AddFilter(TaxonomyItemProperty.ItemId, CriteriaFilterOperator.EqualTo, contentId);

    List<TaxonomyItemData> taxonomyItemsList = taxItemMgr.GetList(itemCriteria);

    if (taxonomyItemsList.Any())
    {
        taxonomyId = taxonomyItemsList.First().TaxonomyId;
    }

    return taxonomyId;
}

This method returns the Taxonomy Id but could easily be adapted to return the TaxonomyItemData object instead.

CSS Aggregation targeting specific browser version in Ektron

I have mentioned the benefits of CSS aggregation previously when using Ektron: reduce HTTP requests, reduce overall page download size and boost performance.

One thing I discovered recently was the ability to use Ektron’s CSS aggregation feature but to be able to specify a target web browser.

You have probably seen conditional comments in CSS before:

<!--[if IE 6]>
Special instructions for IE 6 here
<![endif]-->

If you want to use this feature in tandem with CSS aggregation then you need these two lines of code:

Ektron.Cms.Framework.Content.ContentManager contentMgr = new Ektron.Cms.Framework.Content.ContentManager();
Ektron.Cms.API.Css.RegisterCss(this, contentMgr.SitePath + "/css/file.css", "css_file", Ektron.Cms.API.Css.BrowserTarget.IE7);

As you can see from the final parameter in the RegisterCSS() method, you can specify a target browser. In the example above I have specified IE7.

Get content item in preview mode using Ektron API

When content has been checked-in and has a status of “I” it will appear on the site if the site is in preview mode. Using preview mode allows you to see what content will look like on your site before you click the publish button.

The code below simulates the site being in preview mode and uses the Framework API:

Ektron.Cms.Framework.Core.Content.Content contentApi = new Ektron.Cms.Framework.Core.Content.Content(ApiAccessMode.Admin);
contentApi.InPreviewMode = true;
CB.Text = contentApi.GetItem(ContentBlockId).Html;

Aliased custom 404 error page

This article describes how to create a custom 404 error page in Ektron CMS that will return a HTTP status code 404, use a friendly aliased URL and give content authors the ability to change the content within the page.

Create the template

Create a new ASPX Web Form template called Error404.aspx (or something similar).  Add a ContentBlock to the HTML source view and set the DynamicParameter property to “id”.

Add the template to the CMS in the Settings > Configuration > Template Configuration section in the Ektron workarea.

Now create a new content item in the CMS and assign it to the Error404.aspx template that you created earlier.  Assign an alias to the content item, something like “/page-not-found/”.

Test the page loads of by browsing directly to /page-not-found/.

HTTP status code 404

Now you need to tell the template to return the correct HTTP status code.  At present it is returning a status code of 200 which means “success”.  This will cause search engines to incorrectly believe that your 404 page is actually valid content – in other words, it will be indexed and returned in Google’s results!

To prevent this, go to the code-behind file (this is in C# of course):

    protected void Page_PreRender(object sender, EventArgs e)
    {
        Response.TrySkipIisCustomErrors = true;
        Response.Status = "404 Not Found";
        Response.StatusCode = 404; 
    }

What this does is set the HTTP status code to be 404.  This will indicate to search engines that they have found a missing page so they will not index it.

You can test your page by browsing to an invalid page and seeing if the custom error page is returned.

Enable custom error handling

The next step is to tell .Net that we want to use a custom error page.  This is done within the web.config file like so :

    <system.web>      
      <customErrors mode="On">
          <error statusCode="404" redirect="/page-not-found/" />
      </customErrors>
    <system.web>

This tells .Net to send any “404 page not found” errors to an alias called “/page-not-found/”.

Problems with invalid aliases

You may find that your custom 404 error page isn’t being activated if you try to browse to an invalid alias.  What I have found is that you instead get a nasty server 500 error instead:

Server Error in Application “###”

Internet Information Services 7.5

Error Summary

HTTP Error 500.0 – Internal Server Error

Internal Server Error

Detailed Error Information

Module ManagedPipelineHandler
Notification ExecuteRequestHandler
Handler ExtensionlessUrlHandler-Integrated-4.0
Error Code 0x800703e9
Requested URL http://###:80/wibble/
Physical Path C:\inetpub\wwwroot\###\wibble\
Logon Method Forms
Logon User ###

Eeek!  Where is my custom error page?!?!

I discovered that the problem was due to an incorrect setting in my web.config file.  I needed to remove a handler called “ExtensionlessUrlHandler-Integrated-4.0”, like so :

<system.webServer>
    <handlers>
        <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    </handers> 
</system.webServer>

(Please note I am using IIS 7)

By removing this HTTP handler it allows the request to be passed through to your custom 404 error page instead.

URL Redirects with Ektron 8.6

One of the new features of Ektron version 8.6 is to allow CMS administrators to define URL redirects from within the CMS itself.  Prior to 8.6 this could only be done by setting up redirects in IIS – this made it more of an IT/Server administrator role instead.

To access the new feature follow these steps :

  1. Open the workarea and browse to the Settings > Configuration > URL Aliasing section.
  2. Click Settings.
  3. Click Edit.
  4. Tick the checkbox labelled “Enable URL Redirects”.
  5. A new option will now appear in the URL Aliasing folder called “Redirects”.
  6. Click Redirects.
  7. Click  the “Add Redirect” button.
  8. You have the following options:
  • Choose which website the redirect is applied to.
  • Choose the redirect code.  This is an important SEO (Search Engine Optimisation) factor.  The “301 Permanent Redirect” is often used when moving content to a new website; it is used to tell search engines that a page which used to live in one place has now moved permanently to another.  The idea is that search engines won’t visit the old URL again and will instead visit the new one.
  • You may also set the new and original URLs.

Setting up redirects is a useful tool in preventing users and search engines from hitting dead links on your site.  Typically these dead links are introduced when you move to a new website or to a new CMS.

 

How to configure a multi-lingual site in Ektron

Ektron CMS is a fully multi-lingual product that allows multiple different language versions of a content item to be created.  As of version 8.5 you can also create regions and add custom languages.  Even without the features of v8.5 you can still create multi-lingual sites easily.

When beginning an Ektron project that requires multi-lingual content, first decide whether you are running one domain or multiple domains.  Some organisations like to have one domain such as http://www.theglobalfund.org and within this domain the user can select the language that they wish to view the site in.  Other organisations such as http://www.selecta.co.uk/ provide region/country specific websites which may or may not then provide the option to choose a language.

Single domain multi-lingual sites

Having just one domain is certainly the easiest to implement but is not sufficient for organisations that wish to have a regional presence.  If you have just one domain you would typically provide a language switching control on the page which can use either the CMS LanguageAPI control or some custom API code.

With one domain, many websites will use a language identifier as part of the url; for example http://www.mywebsite.com/en-gb.  This can be achieved using Taxonomy automatic aliasing; the top category in your taxonomy would be “en-gb” and within that would be your information architecture.  Taxonomies themselves are multi-lingual so can be translated.  The “en-gb” taxonomy would be translated into “fr-fr” for French (France) and “fr-ch” for French (Switzerland).  If you also setup your taxonomy folder relationships then content can be auto-added into the taxonomy meaning your multi-lingual aliases are completely automatic!

A language identifier in your alias is useful as it helps to prevent different language versions of content items having the same alias.

Multi-domain multi-lingual sites

Ektron CMS provides a means to manage many websites from a single CMS installation called Multi-site.  Essentially you have more than one IIS website, each with its own web root but only one database.  The reason behind doing this is so that each website can have its own default language.  If you had http://www.mywebsite.de, chances are you want the default language to be German.  The CMS sets the default language of a site within its web.config file.  As you can only have one web.config file per .Net website this means you need separate sites in IIS.

So you would first install the “parent” site – this is the base to which all of your multi-sites are added.  The parent site would hold common content that is shared amongst the other “child” websites.  Each of the child multi-sites are then added using the dedicated Ektron Multi-site installer.  The child multi-sites also have to be configured within the Workarea by right-clicking on the root folder and choosing “Add Site”.

Remember that any content you add within the child site folder in the Workarea will have the domain of the site added to the start of the QuickLink.  This only happens within multi-site folders.  If you do not want this to happen then add the content to a non-multi-site folder, i.e. a folder belonging to the “parent”.

It is your choice whether these sites have their own ASPX templates, controls and PageBuilder wireframes.  Usually the physical files are the same so that organisations have a consistent look and feel across websites even if the domains are slightly different.

For more information on Ektron multi-site see here.

Disable Language Awareness

It is worth mentioning that your Url Aliasing settings.  In the workarea, go to Settings > Configuration > Url Aliasing > Settings and check the “Disable Language Awareness” button.  I find the wording of this setting to be confusing.  When “Disable Language Awareness” is checked you can browse to an alias from a non-default language piece of content.  If it is not checked then the CMS will attempt to load the alias using the default language – so if the alias does not exist in the default language you will get a 404 page not found error.

Time to add content

So you should now have an idea for how to approach setting up Ektron CMS for multi-lingual websites.  You may want to review Ektron’s documentation on multi-lingual content to make sure you have all bases covered; there are other items such as menus, images, taxonomies, etc to consider.

Order search results by metadata field

Ektron’s Framework API gives a great deal of flexibility when it comes to searching, filtering and ordering.  An often needed requirement is to perform a search using the API and the order the results by a metadata value.  Prior to v8.5 and the Framework API this would be difficult and you would often need to do a search, then iterate through the results to get the metadata and then finally do the ordering.

Thankfully as of v8.5 it is much easier!

Firstly you will need the following “using” statements to include the right namespaces:

using Ektron.Cms;
using Ektron.Cms.Search;
using Ektron.Cms.Search.Expressions;
using Ektron.Cms.Search.Compatibility;

I now assume that you have an ASPX page with a search form that includes a submit button. Upon clicking the button a method is executed that will carry out the search.

Next we define the rows that should be returned in the search results:

KeywordSearchCriteria criteria = new KeywordSearchCriteria();

criteria.ReturnProperties = new HashSet(PropertyMappings.ContentSearchProperties);
criteria.ReturnProperties.Add(
SearchMetadataProperty.GetStringProperty(“metaStr”));;

A return column is added here : “metaStr”. This corresponds to a metadata definition called “metaStr” which in my example is of type String. You can also include types Integer, Boolean, Date and Decimal.

Then we say how the results should be ordered:

criteria.OrderBy = new List()
{
new OrderData(
Ektron.Cms.Search.SearchMetadataProperty.GetStringProperty("metaSr"),
OrderDirection.Ascending)
};

This code simply says “order by metaStr, ascending”. Now we add the actual search query:

criteria.QueryText = "ektron";

In reality your search query might be more complicated here, but I want to stick to the script. Finally we perform the search itself:

ISearchManager manager = ObjectFactory.GetSearchManager();
Ektron.Cms.Search.SearchResponseData responseData = manager.Search(criteria);

So there we saw how we can perform a simple search, include metadata in the results and then order by that metadata.