Showing posts with label Sitecore. Show all posts
Showing posts with label Sitecore. Show all posts

Tuesday, 9 July 2013

Missing Context Menu on Item in Team Development for Sitecore (TDS)

I recently had a problem in which I tried to "get" items from Sitecore using TDS. The item I was trying to get had several immediate children; however, the get only fetched the top item. When I right-clicked it to try to delete, no context menu appeared. I checked the file system and found that the .item file did not physically exist, so I reloaded the Visual Studio solution. This removed the item from the Solution Explorer, but did not explain what had gone wrong.

I eventually discovered the issue was due to having an alias item of the same name at the same level in Sitecore. Once I'd renamed the alias, I could correctly get the item and all of its children.

Wednesday, 13 July 2011

Lucene: Compression support not configured

I got this error when trying to extract Hits.Doc from Lucene:

Compression support not configured

at SupportClass.CompressionSupport.CheckCompressionSupport()
at SupportClass.CompressionSupport.Uncompress(Byte[] input)
at Lucene.Net.Index.FieldsReader.Uncompress(Byte[] input)
at Lucene.Net.Index.FieldsReader.AddField(Document doc, FieldInfo fi, Boolean binary, Boolean compressed, Boolean tokenize)
at Lucene.Net.Index.FieldsReader.Doc(Int32 n, FieldSelector fieldSelector)
at Lucene.Net.Index.SegmentReader.Document(Int32 n, FieldSelector fieldSelector)
at Lucene.Net.Index.IndexReader.Document(Int32 n)
at Lucene.Net.Search.IndexSearcher.Doc(Int32 i)
at Lucene.Net.Search.Hits.Doc(Int32 n)


The solution was to add the following missing keys into Sitecore AppSettings.config:

<add key="Lucene.Net.FSDirectory.class" value="Sitecore.Data.Indexing.FSDirectory, Sitecore.Kernel" />
<add key="Lucene.Net.CompressionLib.class" value="Sitecore.IO.Compression, Sitecore.Kernel" />

Wednesday, 18 August 2010

Using Sitecore with Firefox, Chrome and other browsers

Sitecore recommends the use of IE for its client. When trying to log in with Firefox or Chrome (and presumably others), you don't get the option of viewing the desktop. There is a way you can override this behaviour. Open Sitecore in IE and go to the User Manager. Select your account and click Edit to bring up the "Edit User" dialogue. Click on the Profile tab and set the start URL to "Desktop". Save your changes and then try logging in with Firefox, etc. You should now see the full desktop.

Tuesday, 15 June 2010

Sitecore link fields put /home in the target URL's href

When using sc:fld('fieldname', ., 'url') in an XSLT rendering to get a link field's target URL, you will find that the href includes '/home'. This is rarely desirable. Thankfully, it's easy to solve. Simply use sc:fld('fieldname', ., 'id') instead to get the target ID. You can then pass the ID to sc:path().

Tuesday, 23 March 2010

How to remove an apostrophe from a string in Sitecore XSLT

Given a variable named "string", you can remove apostrophes by declaring a variable to hold the apostrophe and then passing that to the sc:Replace method:

<xsl:variable name="apos">'</xsl:variable>
<xsl:variable name="string"
select="sc:Replace( $input, $apos, '' )" />

Wednesday, 28 October 2009

Get a list of all Sitecore Items tagged with specific multilist items

If you wish to return all items in the content tree that have been tagged with a specific multilist item, you might be tempted to use Sitecore.Context.Database.SelectSingleItem(), passing it an XPath query. The problem with this is that performance degrades as the content tree grows. A far more efficient way is to use the GetReferrers method of the LinkDatabase class as shown below:

Database db = Sitecore.Context.ContentDatabase;

LinkDatabase linkDb = Globals.LinkDatabase;

// lookupItem is the multilist item
ItemLink[] links = linkDb.GetReferrers( lookupItem );

foreach( ItemLink link in links )
{
Item linkedItem = db.Items[link.SourceItemID];
// Process item...
}

Friday, 14 August 2009

Write to Sitecore log file from XSLT

It is simple to write to the Sitecore log file from within an XSLT file without having to write any custom code. We can just hook up to the Sitecore.Diagnostics.Log class and call one of its methods.

In the web.config, define the extension under <xslextensions>:

<extension mode="on"
type="Sitecore.Diagnostics.Log, Sitecore.Kernel"
namespace="http://www.sitecore.net/log"
singleInstance="true" />

Within the XSLT file, add a prefix that matches the namespace you used in the above step:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sc="http://www.sitecore.net/scReal"
xmlns:dot="http://www.sitecore.net/dot"
xmlns:log="http://www.sitecore.net/log"
exclude-result-prefixes="dot sc log">

The Log class contains a number of overloads for Info, Warn, Error and so on. Some of these expect an exception as a parameter, so we cannot call these direct from XSLT. We can, however match the overloads that expect a string and an object (eg. Warn( String, Object )):

<xsl:value-of select="log:Warn('Warning message', 'Another string... perhaps the name of your rendering file')" />

That's it! Now you can log whatever you like from within your renderings.

Tuesday, 28 July 2009

The type initializer for 'Sitecore.Search.SearchManager' threw an exception

If you get this (or similar) error, check that the version of the Sitecore.Kernel.dll referenced by class libraries is the same as used by the web site. It fixed a problem I had anyway!

Tuesday, 14 July 2009

Using a Clean Sitecore Client for Authoring

I had a situation this week where I could not get the Sitecore client to work on my local machine. Although I could browse the end web site, I got the dreaded vague null reference exception when trying to browse to /sitecore. As the web site was fairly complex, I was finding it very painful to try to re-contruct from new. In the end, it dawned on me that all I needed to do was install a clean Sitecore client that was completely separate from the web site. This gave me the ability to change content, while the end web site enabled me to view the effect of code changes. This set-up has other benefits too; the Sitecore client runs unimpeded by any custom code (unless you are using pipelines, etc.). This makes it easier to identify/eliminate custom code as a possible cause for any slowness. Similarly, you can readily identify if any errors in the log are due to your code.

Thursday, 9 July 2009

Value cannot be null

When trying to open the Sitecore client (ie. by putting /sitecore in the URL), I got the following exception:

Exception: System.ArgumentNullException
Message: Value cannot be null.
Parameter name: item
Source: Sitecore.Kernel
at Sitecore.Diagnostics.Assert.ArgumentNotNull(Object argument, String argumentName)
at Sitecore.Web.UI.HtmlControls.Menu.AddFromDataSource(Item item, String target)
at Sitecore.Web.UI.HtmlControls.DataContextMenu.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

I noticed that the URL had changed to /sitecore/shell

With so few clues as to the cause, I simply entered the full path to the log-in screen (/sitecore/login). The log-in screen loaded and I was able to log in successfully.

Out of curiosity, I logged out again and then re-tried /sitecore on its own. The log-in screen opened OK that time. I've no idea as to the cause and I don't fancy investigating. If you're having the same problem, why not try what I did? Good luck.

Friday, 16 January 2009

Screen reader friendly phone numbers

When you display a telephone number on screen, screen readers read it out as a single number. The Fangs screen reader emulator (see http://sourceforge.net/projects/fangs) reads the number (01234) 567890 as “left paren six hundred sixty-eight right paren five hundred sixty-seven thousand eight hundred ninety”. The “six hundred sixty-eight” bit is particularly curious: the 01234 is being interpreted as an octal number.

By encasing each digit within a <span /> tag, the digits are read out individually. So, (01234) 567890 becomes “left paren zero one two three four right paren five six seven eight nine zero”.

I have written an XSLT template that takes a phone number and applies a <span /> to each digit:

<xsl:template name="DisplayPhoneNumber">
<xsl:param name="position" />
<xsl:param name="phonenumber" />
<xsl:variable name="digit"
select="substring($phonenumber, $position, 1)" />

<xsl:choose>
<xsl:when test="contains('012345678', $digit)">
<span>
<xsl:value-of select="$digit" />
</span>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$digit" />
</xsl:otherwise>
</xsl:choose>

<xsl:if test="$position &lt;
string-length($phonenumber)">
<xsl:call-template name="DisplayPhoneNumber">
<xsl:with-param name="position">
<xsl:value-of select="$position+1" />
</xsl:with-param>
<xsl:with-param name="phonenumber"
select="$phonenumber" />
</xsl:call-template>
</xsl:if>
</xsl:template>

To call the template, pass in the telephone number and prime the starting position using a value of 1:

<xsl:call-template name="DisplayPhoneNumber">
<xsl:with-param name="position" select="'1'" />
<xsl:with-param name="phonenumber"
select="'(01234) 567890'" />
</xsl:call-template>


If you’re using this within Sitecore, you can simply pass in a field value in the usual way:

<xsl:call-template name="DisplayPhoneNumber">
<xsl:with-param name="position" select="'1'" />
<xsl:with-param name="phonenumber"
select="sc:fld('phone', .)" />
</xsl:call-template>

Friday, 18 July 2008

Could not find property 'Name' on object of type: Sitecore.Data.SqlServer.SqlServerDataProvider

This week, I branched a solution in TFS and checked out the branch. It built successfully. I then added virtual directories in IIS to point at the locations of the app_config, sitecore, sitecore modules and data folders (I move these outside of the web site root for easier swappability and source control). On browsing to the site, I got the message:

Could not find property 'Name' on object of type: Sitecore.Data.SqlServer.SqlServerDataProvider

It took a while to figure out that this was due to the assemblies in source control being out of date. Once I'd copied the contents of the bin folder on the live web server to my local machine, I was able to browse the site.

Thursday, 24 April 2008

Postback opens layout rather than the Sitecore item

This was a weird one. I created a Sitecore item with layout and a sublayout. Then I placed a Button control on the sublayout and adding a click event handler that did something simple like display "Hello World" in a label on the sublayout. However, clicking the button navigated to the layout, rather than posting back to the Sitecore item. A colleague searched the Sitecore forum and eventually sorted the problem. It was due to the following line being commented out in the Form.browser file:
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="Sitecore.Web.FormAdapter, Sitecore.Kernel" />

I had commented this out due to runtime exceptions I was getting that referred to this line in the file. However, it now seems perfectly happy with it left in!

The file exists in the App_Browsers folder in the web site root. If it isn’t there, copy it from a clean 5.3.1 installation.

[Edited 30/7/2008]

And thanks to my colleague Jason Linham for noting further that the folder should not be hidden.

[Updated 16/9/2008]

Wednesday, 16 April 2008

Sitecore item content not showing

As I’ve spent too many times trying to work out why item content (or a change to an item) is not reflected in the browser, here’s a quick note-to-self check-list:

  • If the item is in a workflow, check it has been submitted and approved

  • If you’re referencing an item using @key (eg. item[@key='fieldname']), make sure the field name is all lower case

  • Check the item has been published (do a full publish if changes have been made to templates too)

  • Do a full publish (or re-save the web.config file) if you suspect Sitecore caching is having an effect

  • Check the content of the item is in the web database by using the dbbrowser utility (in the same broswer session as your Sitecore instance, browse to /sitecore/admin/dbbrowser.aspx)

  • If you’re using local IIS, do an IIS reset to refresh the cache

  • Use the Access Viewer to check the permissions of the item for the extranet anonymous user

  • Check the item’s rendering is assigned to a valid placeholder key (be particularly careful if you are attaching renderings dynamically)

  • If applicable, view the HTML source and paste into the W3 validator to check for errors. Something like a self-closing script tag can throw the output.


Have I forgotten anything?

[Updated 7 Jan 2009; added bullet]

Friday, 4 April 2008

Using ASP.NET Log-in Controls with Sitecore Extranet

It is simple to use the log-in controls to sign in to a Sitecore extranet. Having dragged a Login control to the design surface of a layout or sub-layout (ie. web form or user control), go to the control’s properties and click the lightning symbol. Double-click the field to the right of the Authenticate item to attach an event handler to the Authenticate event. In the event handler, set the Authenticated property of the AuthenticateEventArgs parameter equal to the success flag of the Sitecore Login() method.

Your Login control definition will be similar to:

<asp:Login ID="Login1" runat="server"
OnAuthenticate="Login1_Authenticate"></asp:Login>

Your event handler will be similar to:

protected void Login1_Authenticate( object sender,
AuthenticateEventArgs e )
{
e.Authenticated = Sitecore.Context.Domain.Login(
Login1.UserName, Login1.Password).Success;
}

Tuesday, 11 March 2008

Root element is missing

This exception arises if you store the Sitecore and Sitecore Modules folders outside of the web root and have forgotten to create virtual directories under the web root that point to them.

Thursday, 21 February 2008

Extract the Month from a DateTime Field in Sitecore

Using sc:formatdate(), it is a fairly trivial matter to format a date in a Sitecore Xslt rendering. Eg:
sc:formatdate(sc:fld('MyDateField', .),
'd MMM yyyy @ h:mm')

However, extracting just the month as a number without padding is less obvious. Using the format string 'MMM' gives three-letter month names, 'MM' gives months padded with zeros (eg. 02 for Feb), while 'M' curiously gives full month name and date padded with zeros.

A workaround is to use substring-after in conjunction with the format '/M'. Example:
substring-after(sc:formatdate(
sc:fld('MyDateField', .), '/M'), '/')

Friday, 15 February 2008

Get the Path of a Sitecore File Field Given a Media Path

A file field in Sitecore uses a media path. If you want to get the actual URL to the uploaded file, you need to append the file’s media path to the media library path and use this to reference the item in the media library. You can then extract the value of the path field. Example:

<a href="{sc:fld('Path', sc:item(concat('/sitecore/media library', sc:fld('filefieldname', .)), .))}">Download file</a>

How to Determine Sitecore System Field Names

If you want to find out the name of system fields in Sitecore, you need to open the Standard Template in the Template Manager.

Here are some of the available fields (obtained from version 5.2):

Workflow:
__Workflow
__Workflow state
__Lock
__Default workflow

Help:
__Short description
__Long description
__Help link

Publishing:
__Publish
__Unpublish
__Publishing groups
__Never publish

Tasks:
__Archive date
__Reminder date
__Reminder recipients
__Reminder text

Lifetime:
__Valid from
__Valid to

Statistics:
__Created
__Created by
__Revision
__Updated
__Updated by

Might be obvious, but I couldn’t find a list on SDN.

Monday, 11 February 2008

Setting Query String Parameters in Xslt

In Xslt, adding a new parameter to a query string presents a problem as, without writing your own extension function, you cannot determine whether you should prefix your parameter with ‘?’ or ‘&’. In Sitecore, the Xslt function sc:qs('parametername') can be used to obtain the value of a named parameter parametername. Unfortunately, there is no function provided that obtains the entire query string.

Here’s a workaround. Let’s say you want to add a parameter called ‘page’.

First, build up the rest of the query string. The following template checks the existence in the query string of parameter names passed to it. You need to know the names of the possible parameters. If they exist, they are written out.

<xsl:template name="SetQueryParameter">
<xsl:param name="name" />
<xsl:if test="sc:qs($name)">
<xsl:text>&amp;</xsl:text>
<xsl:value-of select="$name" />
<xsl:text>=</xsl:text>
<xsl:value-of select="sc:qs($name)" />
</xsl:if>
</xsl:template>

This template would typically be called from within a variable definition, therefore saving the created query string. In the following example, we are checking parameters type and orderby and saving them if they exist so we can add them back in later:

<xsl:variable name="RestOfQueryString">
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">type</xsl:with-param>
</xsl:call-template>
<xsl:call-template name="SetQueryParameter">
<xsl:with-param name="name">orderby</xsl:with-param>
</xsl:call-template>
</xsl:variable>

You are then able to append this query string to your newly-added parameter, which you add using a ‘?’:

<a>
<xsl:attribute name="href">
<xsl:text>?page=10</xsl:text>
<xsl:value-of select="$RestOfQueryString" />
</xsl:attribute>
<xsl:text>Page 10</xsl:text>
</a>