Pages

12 November, 2012

Personalize button is missing in Sitecore > Presentation > Details tab in Sitecore


Personalization and Analytics in Sitecore are interrelated. If we disable the analytics, all the personalization related stuff also gets hidden from the content tree.

If we disable analytics, we will not get the personalize button in the pop up.



If we enable analytics, we will get the option of adding rules using personalize button.  


Enable the Analytics in Sitecore.Analytics.config in Includes/App_Config folder.
      <setting name="Analytics.Enabled" value="true" />

03 November, 2012

Find the list of Sitecore Admin Users (through database)

If you want to list down the users who have Sitecore admin access, you have to go through each user (to check IsAdministrator checkbox is checked or not) in User Manager in Security tools. We can also find the list by querying Sitecore ASP.Net membership tables. Mostly these table will be located in Sitecore Core database.

Query:

/**  Getting the list of Users who have Sitecore admin access **/
SELECT [ApplicationId]
      ,[UserId]
      ,[UserName]
      ,[LoweredUserName]
      ,[MobileAlias]
      ,[IsAnonymous]
      ,[LastActivityDate]
  FROM [NewInstance1Sitecore_Core].[dbo].[aspnet_Users]
  WHERE UserId IN
  /** Getting the list of user-ids **/
  (SELECT [UserId]
  FROM [NewInstance1Sitecore_Core].[dbo].[aspnet_Profile]
  WHERE
  /** IsAdministrator Property Name Check **/
  [PropertyNames] LIKE '%IsAdministrator%'
  AND
  /** Property Value : True or False Check **/
  /** !Important: This check should be avoided when you have other boolean type
            custom profile property. And in that case, just get the User name
without this check and manually check in User Manager **/
  (PropertyValuesString LIKE '%True%' AND PropertyValuesString NOT LIKE '%False%'))

This query will return the user details who have admin access.

Note: If you have any custom Boolean type profile property, you may need to avoid using the PropertyValuesString values check in the query. 

22 July, 2012

Sitecore: Disable Sitecore cache and browser cache while developing to save time


It is always to have cache in any web application. But while in development stage, it is better to disable Sitecore cache and also browser cache to avoid wasting time in recycling application pool or clearing cache from cache admin. To disable it,

      <!--  CACHING ENABLED
            Determines if caching should be enabled at all
            Specify 'true' to enable caching and 'false' to disable all caching
      -->
      <setting name="Caching.Enabled" value="true" />
      <!--  DISABLE BROWSER CACHING
            If true, all pages will have:
              Cache-Control: no-cache, no-store
              Pragma: no-cache
            in the http header
      -->
      <setting name="DisableBrowserCaching" value="true" />

Both the setting should be true; former to avoid Sitecore cache and latter to BrowserCache.

Avoid locking of items by a user in Sitecore


In Sitecore, many users will work parallelly and locking of item will not allow another user to work on the same item. To avoid locking and loss of changes, we have settings in the web.config.

      <!--  AUTOMATIC LOCK ON SAVE
            If true, the a lock is automatically taken on an item
            when a user saves the item.
      -->
      <setting name="AutomaticLockOnSave" value="false" />
      <!--  AUTOMATIC UNLOCK ON SAVED
            If true, the a saved item is automatically unlocked after
            saving.
      -->
      <setting name="AutomaticUnlockOnSaved" value="false" />

Both the setting should be true; former to avoid data loss and latter to avoid locking of items.

Access issue with language security settings

Sometimes we used to get errors like “The Security settings for the current language prevent you from seeing this item.”









This is due to that Language Item under system is not having read and write access (atleast read). Please give Language Read and Write access and you will be allowed to edit whichever items you have access.


Problem with downloading Media files from Sitecore if Windows Authentication enabled

UAT environment used to be locked with Windows/Basic Authentication. There is an issue with Sitecore media items (mainly XSLT) when site is locked with Windows Authentication. 401 unauthorized issue. We need to give anonymous access only to media items like XSLT. Thanks to Ankit Agarwal who gave the solution.

In applicationHost.config, add these lines,
<location path="<Sitecore>/~/media">
        <system.webServer>
            <security>
                <authentication>
                    <anonymousAuthentication enabled="true" />
                    <basicAuthentication enabled="false" />
                </authentication>
            </security>
        </system.webServer>
    </location>

This solved the issue with Media items. 

09 July, 2012

How to use custom font in Sitecore

Different browsers will use different font types for using custom font in HTML. From the blog, we can understand the compatibility of different font types in various browsers.

Font Type
IE
Mozilla
Safari
Chrome
Opera
.ttf
No
3.5+
3.1+
2.0+
10+
.otf
No
3.5+
3.1+
No
10+
.eot
4+
No
No
No
No
.svg
No
No
3.1+
0.3+
9.0+
.woff
No
Yes
???
???
???
                     .ttf – All browsers which are compatible to CSS3.

All the font types may be having same name. 
@font-face
{
    font-family: 'Brandon';
    src:      url('/~/media/css/fonts/Brandon.eot') format('embedded-opentype'),
              url('/~/media/css/fonts/Brandon.woff') format('woff'),
url('/~/media/css/fonts/Brandon.ttf') format('truetype'),;
}

For example: Brandon.ttf, Brandon.otf, Brandon.eot. If we upload all the types in 
same folder as like the below screenshot and when we request for ‘eot’ extension, 
it may download any of the font-type or same. Mostly it will download the first 
item in the folder. This is not consistent.  
 
 When I tested with the below url, http://sample/~/media/css/fonts/brandon.eot, 
it downloaded woff font type. 
 

So ideally the above CSS should be able to download the font depending upon the extension 
and the browsers.  
Few hacks and ideas: 
1.       Rename the font file name for each type, upload it in Media library and use it 
in CSS src attribute. Then the requested url should be able to download the font as 
we will be having one font in each type.
                  
 Also add the following mime type for the font. 
Font Type
Mime
.ttf
font/truetype
.otf
font/opentype
.eot
application/vnd.ms-fontobject
.woff
application/x-font-woff
2.       In IE9, you may get error “@font-face failed OpenType embedding permission check. 
Permission must be Installable.” Fix: “Obtain the correct permission or licenses for 
embedding the font.” 
– Source: http://blog.beacontechnologies.com/custom-fonts-i-internet-explorer/ 

If anyone has solution to request multiple font types with same file name in Sitecore, please comment and provide me the solution. 

16 May, 2012

Sitecore Multilingual URLs/Dynamic URLs with Wildcard (Sitecore v6.5)

Dynamic URLs using WildCard Module:
In Sitecore, we have the option of creating Dynamic URLs. A Sitecore module called Wildcard Module is being used to pass variables instead of using Query String.

Multilingual URLs with LinkManager:
Multilingual URLs can be achieved in Sitecore using DisplayName for an item. To use display name in URLs, we need to configure LinkManager to accept DisplayName.

Problem: Multilingual URL is working perfectly in Sitecore. ItemResolver Pre-processor is able to resolve the Sitecore item using Display Name. The real problem comes into picture when we use wild card in multilingual URL (Display Name). Using Display Name and wild card in Sitecore URL will returns “Item Not Found” page. This is due to ItemResolver Processor in Sitecore doesn’t able to resolve the wild card Sitecore item when using Display Name.

Resolution: To resolve this issue, we need to modify ItemResolver processor. In processor, modify “GetChild” method to get the WildCard Item.

        private Item GetChild(Item item, string itemName)
        {
            ChildList children = item.Children;
            foreach (Item item2 in children)
            {
                //Resolve WildCard Item in Multilingual URL.
                //To Get WildCard Item (*)
                if (item2.DisplayName == @"*" || item2.Name == @"*")
                {
                    Item result = item2;
                    return result;
                }
                //Resolve WildCard Item in Multilingual URL.

                if (item2.DisplayName.Equals(itemName, StringComparison.OrdinalIgnoreCase))
                {
                    Item result = item2;
                    return result;
                }
                if (item2.Name.Equals(itemName, StringComparison.OrdinalIgnoreCase))
                {
                    Item result = item2;
                    return result;
                }             
            }
            return null;
        }


Please comment if I am doing anything wrong.

29 April, 2012

Moving Sitecore item from one instance (Active Directory 1) to another (Active Directory 2)

We have Sitecore out of box package designer to package items and to move it to another instance. Let’s say we have two instance of Sitecore. First one is integrated with Active directory 1 (for example: ad1) and second with active directory 2(ad2). But it is really important to unlock all the items before packaging and installing it in another instance.


Scenario: In Instance 1 (ad1), a user (ad1\user1) locks an item. Sitecore item will be locked with ad1\user1 id. User packages the item and moves it to another instance. User installs the package in second instance. Those items will be still locked with ad1\user1 in second instance too. Importantly even if you login with admin user and try to unlock the item, admin will not be able to unlock it.

Resolution: Go to first instance, unlock the item, package it and install it in second instance. 

23 April, 2012

How to deploy a Site in Sitecore in Production (Multi-domain) - 11


In web.config file, we have <sites> node to configure roothpath, startitem, host name etc. For production deployment, we have to use www.example.com and example.com. So we added to <sites> node in web.config file. We came to know that it created two cache folders, one for each website node. To avoid this, we have to create a single node for the site with hostname as “*example.com” (Please don’t use dot in the host name.).
<site name=”example” hostname=“*example.com” … />


10 April, 2012

Kick Logged/Unused session in Sitecore Client in the admin – 10

While the number of sites in Sitecore increases, the number of users using Sitecore client will be huge and there will be slowness in Sitecore. And sometimes, the user session will not be available for another user to login and also there will be few issues with media library too. In such scenario, we need to close the user session explicitly by logging into admin to kick such unused sessions. The url to see all the user session (both using and used session) is
http://domain/sitecore/shell/Applications/Login/Users/Kick.aspx

Log into to Sitecore using Admin user and kick such unused session to resolve this issue.

19 March, 2012

Wildcard Module is not working for newly created page in Sitecore – 9

Wildcard Module allows us to work with Dynamic URL and Sitecore wildcard items.

Problem: In Sitecore instance, Wildcard module was working for a page when we initially configured for the first time. When we deleted that page and recreated that page again, wildcard module was not working. And it was not working for the newly created page in Sitecore. In Code-behind, it was not able to match the tokens in the particular URL.


Solution: In Sitecore \System\Modules\Wildcards\Routes\<BlogRoute>, we need to add items to create the rule for wildcard replacement. In that, we will be adding the pages to which wildcard to apply.
When we add pages to Data Items, wildcard module will replace with tokens only to pages which match this Items Collection (GUIDs). So in order to use this wildcard route in other page or newly created page, we need to add the page explicitly in this data items as shown in below diagram.
By doing this, Sitecore Wildcard module started to work for newly created page.


For every newly created page, we cannot add the page to this Item collection automatically. If someone finds the solution to resolve this issue, it would be a great help. !!!

16 March, 2012

How to use extension in the Sitecore Media Request URL – 8

Go to Web.config file and find a setting named “Media.RequestExtension” and remove the extension value.
<!--  MEDIA - REQUEST EXTENSION                
The extension to use in media request URLs. If the value is not set, the Extension field of the individual media items will be used (ie. JPG, GIF, etc.)
Default value: "ashx"-->
      <setting name="Media.RequestExtension" value="ashx" />

Remove ashx from the value.
      <setting name="Media.RequestExtension" value="" />


Sample:
Before change      : /~/media/Images/logo.ashx
After change         : /~/media/Images/logo.png (ashx also will work.)



How to allow dots(.) in Sitecore Item names – 7

Go to Web.config file and find a setting named “ItemNameValidation” and change the validation to allow dots. 
      <!--  ITEM NAME VALIDATION
            Regular expression for validating item names   -->
      <setting name="ItemNameValidation" value="^[\w\*\$][\w\s\-\$]*(\(\d{1,}\)){0,1}$" />
Modified Regular Expression.
      <setting name="ItemNameValidation" value="^[\w\*\$][\w\.\s\-\$]*(\(\d{1,}\)){0,1}$" /> 


15 March, 2012

How to use SecurityDisabler and UserSwitcher in Sitecore

In Sitecore, if the current context user doesn’t have permission to access this item, Sitecore will return null or throw exception.

SecurityDisabler:
SecurityDisabler will elevate the context user to have administrative privilege and so context user will be able to do anything on the system.

new Sitecore.SecurityModel.SecurityDisabler();

UserSwitcher:
UserSwitcher allows a segment of code to run under a specific user instead of current context user. 

new Sitecore.Security.Accounts.UserSwitcher(Sitecore.Security.Accounts.User.FromName("username",false));

Note: It is recommended to provide context user with appropriate rights than using SecurityDisabler or UserSwitcher.

Sample Code:


        /// <summary>
        /// Code snippets explaining SecurityDisabler and UserSwitcher
        /// </summary>
        private void SecuritySample()
        {
            //Getting Master Database
            Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");
            //Getting a Sitecore Item
            Sitecore.Data.Items.Item home = masterDB.GetItem("/sitecore/content/Home"); 
            //Using Begin, End, Cancel Edit and Security Disabler
            BeginEditAndSecurityDisabler(home); 
            //Using EditContext and Security User Switcher
            EditContextAndSecurityUserSwitcher(home);
        }
 
        /// <summary>
        /// Using Begin, End, Cancel Edit and Security Disabler
        /// </summary>
        /// <param name="home"></param>
        private void BeginEditAndSecurityDisabler(Sitecore.Data.Items.Item home)
        {
            using (new Sitecore.SecurityModel.SecurityDisabler())
            {
                home.Editing.BeginEdit();
                try
                {
                    home["Title"] = "Title from Code"; 
                    //Commit the changes
                    home.Editing.EndEdit();
                }
                catch (Exception)
                {
                    //Revert the Changes
                    home.Editing.CancelEdit();
                }
            }
        }
 
        /// <summary>
        /// Using EditContext and Security User Switcher
        /// </summary>
        /// <param name="home"></param>
        private void EditContextAndSecurityUserSwitcher(Sitecore.Data.Items.Item home)
        {
            //User which is already created in Sitecore User Manager
            string testUser = @"sitecore\testuser"; 
            //User existing or not
            if (Sitecore.Security.Accounts.User.Exists(testUser))
            {
                //Getting Sitecore User Object with UserName
                Sitecore.Security.Accounts.User scUser = Sitecore.Security.Accounts.User.FromName(testUser, false); 
                //Switching Context User
                using (new Sitecore.Security.Accounts.UserSwitcher(scUser))
                {
                    //Using EditContext to edit an Item
                    using (new Sitecore.Data.Items.EditContext(home))
                    {
                        home["Text"] = "Modified Text from Code";
                    }
                }
            }
        }
Before UserSwitcher:
After UserSwitcher:


blockquote { margin: 0; } blockquote p { padding: 15px; background: #eee; border-radius: 5px; } blockquote p::before { content: '\201C'; } blockquote p::after { content: '\201D'; }