RangerChris
RangerChris

Reputation: 139

Get item based on displayname in sitecore

I need to get a specific item based on it's displayname, how do I do that?

For example I want to get this item /sitecore/content/mysite/about But on the site is translated to multiple languages and could be something like www.site.com/om (in Sitecore it would be /sitecore/content/mysite/om)

Upvotes: 1

Views: 5462

Answers (2)

Derek Dysart
Derek Dysart

Reputation: 1396

There are a couple approaches you can take. The most efficent is to leverage the Content Search API, but the challenge is that Display Name is excluded from the index by default. A simple patch file can fix this:

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <contentSearch>
      <indexConfigurations>
        <defaultLuceneIndexConfiguration>
          <exclude>
            <__display_name>
              <patch:delete />
            </__display_name>
          </exclude>
        </defaultLuceneIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>

Then your code would be something like:

public Item GetItemByDisplayName(string displayName)
{
    var searchIndex = ContentSearchManager.GetIndex("sitecore_master_index"); // sub your index name
    using (var context = searchIndex.CreateSearchContext())
    {
        var searchResultItems =
            context.GetQueryable<SearchResultItem>().Where(i => i["Display Name"].Equals(displayName)).FirstOrDefault();


        return searchResultItems == null ? null : searchResultItems.GetItem();
    }
}

This all is assuming you are on Sitecore 7. If you're on Sitecore 6, your option are limited and are probably not going to perform well if you content tree is large. Nonetheless, your function might look like:

public Item GetItemByDisplayName(string displayName)
{
    var query = string.Format("fast:/sitecore/content//*[@__Display Name='{0}']", displayName);

    var item = Sitecore.Context.Database.SelectSingleItem(query);

    return item;
}

Please note that this will be horribly inefficent since under the covers this is basically walking the content tree.

Upvotes: 5

Mark Cassidy
Mark Cassidy

Reputation: 5860

Often, you wouldn't need to. LinkManager (responsible for generating all your item URLs) has an option to base the URLs on Display Name instead of Item.Name.

        var d = LinkManager.GetDefaultUrlOptions();
        d.UseDisplayName = true;

This can also be configured in configuration. Find and amend this section in your Web.config (or patch it via include files):

<linkManager defaultProvider="sitecore">
  <providers>
    <clear />
    <add name="sitecore" type="Sitecore.Links.LinkProvider, Sitecore.Kernel"
        addAspxExtension="false" alwaysIncludeServerUrl="false" encodeNames="true"
        languageEmbedding="never" languageLocation="filePath" lowercaseUrls="true" 
        shortenUrls="true" useDisplayName="false" />
  </providers>
</linkManager>

To truly do exactly what you ask is a quite involved process. If you point DotPeek to Sitecore.Pipelines.HttpRequest.ItemResolver, you can step through the ResolveUsingDisplayName() method. It essentially loops through child items, comparing the URL Part to the "__Display Name" field. You would have to cook up something similar.

Upvotes: 1

Related Questions