Sitecore : Getting image field in code behind

This is just a quick post to show how to get image URL via code behind.

This is mostly useful when you are binding children items to a repeater or returning image URL in a JSON webservice

public static string GetImageURL(Item currentItem)
{
          string imageURL = string.Empty;
          Sitecore.Data.Fields.ImageField imageField = currentItem.Fields["Image"];
          if (imageField != null && imageField.MediaItem != null)
          {
            Sitecore.Data.Items.MediaItem image = new Sitecore.Data.Items.MediaItem(imageField.MediaItem);
            imageURL = Sitecore.StringUtil.EnsurePrefix('/', Sitecore.Resources.Media.MediaManager.GetMediaUrl(image));
          }
return imageURL;
}

Cheers

, , ,

Leave a Comment

Sitecore vs Umbraco – A developer’s view

One Friday afternoon, I was sitting at my desk and fixing bugs (as usual), a member of sales team came up to me and said

“Hey Naveed, we have this interesting new client and they are not sure about which CMS to go for, they have finalised Sitecore and Umbraco as the last two, can you help”

I replied: “Sure, why not, what are their business requirements ?”

Sales person: “They are medium to large size organisation and have usual requirements like news, events, forums, blogs, video content etc, they want a simple to use CMS with multiple authors and security levels”
I replied: “Ok, Sitecore and Umbraco are both equally powerful in content generation and management, they both are based on .NET stack (.NET,C#,SQL) and both are highly customisable, so far they both can be their potential CMS, do you have more specific requirements ?”

Sales person: “Yes, in future, they would like to integrate with Sharepoint and their back-end CRM system”

I replied :”Sitecore comes with a sharepoint connector out-of-box whereas for Umbraco we have to custom build one. As long as their back end CRM exposes API, we can integrate any of the CMS system with their back end, this will be custom build in both cases, do you have any other requirements ?”

Sales person: “It is not a requirement but in their wish list to have personalised content for different regions or profile history”

I replied: “Sitecore comes with Customer Engagement Platform (CEP) and Online Marketing Suite (OMS) which can make their life easy in future, however, Umbraco lacks these customised modules. So it looks like Sitecore can be their potential candidate for CMS, also do you have any idea about their budget for the website?”

Sales person: “Yes, it’s a five figure sum, not sure what exactly their budget is”

I replied: “If they are tight on budget and can compromise on add-ons then Umbraco would be good to start off with but will have high maintenance cost if they go down the route implementing customised modules. However, paying for Sitecore licenses up front will give them added benefit to use some of the modules out of the box and will have low maintenance cost, I guess best would be to give them a demo of both CMS systems to the client and let them make informed decision”

Sales person: “Sounds like a plan, ok I will let them know, cheers”

Conclusion:

No CMS is right or wrong for your business out of the box, you have evaluate them against your own business requirements for the website. Open source may be cheaper to start off with but will have maintenance costs down the line.

Disclaimer: I have worked with both CMS systems and hold them up in same respect for what they do, I am not a sales person or work for either of the CMS systems, this is just my opinion as a third party developer

, , ,

Leave a Comment

EPiServer : Dynamic Data Store

If you are reading this post, then I can assume you are curios about EPiServer dynamic data store and want to know how to use it. In this post, I am going to do exactly the same. I will create, update and delete from DDS using EPiServer API.

1- Create a new dynamic data store

Imagine you have to dynamically store landing page ids for certain products or sections and then read them back from dynamic data store

private void CreateLandingPageDDS(PageData myPage)
{
//create a propertybag
PropertyBag landingProperties = new PropertyBag();

//add your custom properties
landingProperties.Add("LandingPageKey", myPage.PageLink.ID.ToString());
landingProperties.Add("LandingPageProductName", myPage.PageName);
//add more properties if you like, but there is a limit that you can add upto, or
//create a custom object and add that object

//create a new store for DDS
DynamicDataStore store = DynamicDataStoreFactory.Instance.CreateStore("DDS",   landingProperties.GenerateTypeBag());

//store DDS in database
Identity id = store.Save(landingProperties);

}

pretty simple :)

2- Get dynamic data store

Now let say you want to query the same DDS and would like to get pageName if you pass in the pageID

public static string GetLandingPageName(string currentPageID)
{
//get the store from database
DynamicDataStore store = (DynamicDataStore)DynamicDataStoreFactory.Instance.GetStore("DDS");

if (store != null)
{
//find all the properties for that key/value pair
IEnumerable<PropertyBag> landingProperties = store.FindAsPropertyBag("LandingPageKey", currentPageID);

//iterate through each property and return only where key matches
if (landingProperties != null)
{
foreach (PropertyBag item in landingProperties)
{
string pageName = item["LandingPageProductName"] as string ?? string.Empty;
return pageName;
}

}

}
return string.Empty;
}

Although pageName is a trivial property, this is just an example how to go about using DDS.

3- Update dynamic data store

Now let say you want to update pageName using pageID

private void UpdateLandingPage(string currentPageID)
{
DynamicDataStore store = (DynamicDataStore)DynamicDataStoreFactory.Instance.GetStore("DDS");

if (store != null)
{
IEnumerable<PropertyBag> landingProperties = store.FindAsPropertyBag("LandingPageKey", currentPageID);

if (landingProperties != null)
{
foreach (PropertyBag item in landingProperties)
{
item["LandingPageProductName"] = "New name";
store.Save(item);
}


}

}
}

4- Delete dynamic data store

That is very strait forward, just use

DynamicDataStoreFactory.Instance.DeleteStore("DDS",true);

5-Important note

If during development, you have to change your dynamic data store by adding more properties to property bag object, it will result in exception.

There are two ways to get round this

1.If you are in development, delete your previous DDS entries and start fresh
2.If you are in production, then you have to re-map/re-link the property bag.

Have fun coding DDS

, ,

Leave a Comment

EPiServer : CustomProperty for Radio Button List

EPiServer has lots of in-built properties, but one major property that it is missing is ‘radio button list’ , sometimes user wants to select just one option from give 4 or 5 options.

In this post, I will guide you through making a very basic custom property for EPiServer for ‘Radio Button List’

Step1: In your VS project, right-click and new EPiServer custom property control as show below, i will rename this control is ‘PropertyMyPicker’

Add custom property

Add custom property

Step2: Inherit it from ‘PropertyString’ as shown below

Inherit from property string

Inherit from property string

Step3: This will create two code files in your project as following

PropertyMyPicker.cs

PropertyMyPickerControl.cs

You do not need to do anything in ‘PropertyMyPicker.cs’ class, and all your logic will be implemented in  ‘PropertyMyPickerControl.cs’.

Step4: In this code snippet,  we create 3 radio buttons, if their value is selected, that text is stored in the database and when the page is re-visited/re-loaded the value is read back from the database. Change the code of the ‘PropertyMyPickerControl.cs’ as shown below and make necessary namespace and variable changes. You have overwrite some of the methods and implement your own if necessary.

/// <summary>
/// PropertyControl implementation used for rendering PropertyMyPicker data.
/// </summary>
public class PropertyMyPickerControl : EPiServer.Web.PropertyControls.PropertyStringControl
{
RadioButton radioButton1 = null;
RadioButton radioButton2 = null;
RadioButton radioButton3 = null;
// Value that will be stored in db,
string desc = string.Empty;
// group name for all radio buttons to make them behave as radiobuttonlist
readonly string groupName = "MyPicker";
/// <summary>
/// Gets the PropertyMyPicker instance for this IPropertyControl.
/// </summary>
/// <value>The property that is to be displayed or edited.</value>
public PropertyMyPicker PropertyMyPicker
{
get
{
return PropertyData as PropertyMyPicker;
}
}
/// <summary>
///creates radio button list and pre-select if the value
///has been saved in database
/// </summary>
public override void CreateEditControls()
{
//add radioButton1 radio button
radioButton1 = new RadioButton();
radioButton1.Text = "Radio 1 Text";
radioButton1.GroupName = groupName;
radioButton1.Checked = IsRadioChecked(radioButton1.Text);
//add radioButton2 radio button
radioButton2 = new RadioButton();
radioButton2.Text = "Radio 2 Text"
radioButton2.GroupName = groupName;
radioButton2.Checked = IsRadioChecked(radioButton2.Text);
//add radioButton3 radio button
radioButton3 = new RadioButton();
radioButton3.Text = "Radio 3 Text";
radioButton3.GroupName = groupName;
radioButton3.Checked = IsRadioChecked(radioButton3.Text);

this.Controls.Add(radioButton1);
this.Controls.Add(radioButton2);
this.Controls.Add(radioButton3);

}
/// <summary>
/// Saves it to the database
/// </summary>
public override void ApplyEditChanges()
{
desc = GetMyDescription();
base.SetValue(desc);
}
/// <summary>
/// Get selected radio button text
/// </summary>
/// <returns></returns>
private string GetMyDescription()
{
string selectedMyPicker = string.Empty;

if (radioButton1.Checked)
selectedMyPicker = "Radio 1 Text";
else if (radioButton2.Checked)
selectedMyPicker = "Radio 2 Text";
else if (radioButton3.Checked)
selectedMyPicker ="Radio 3 Text";

return selectedMy;

}
/// <summary>
/// Check if the controls contain value for any of the radio button in database
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private bool IsRadioChecked(string name)
{
if (this.PropertyData.Value != null)
{
string selectedMy = this.PropertyData.Value.ToString();
if (selectedMy.ToLower() == name.ToLower())
return true;
}
return false;
}

}

Step 5: Next you need to create the property for the page template, you will see your new property in the dropdown list

Step 6: You can use this property as a page string property and output your custom logic

//assuming MyPicker is the page property name
var myPicker = CurrentPage["MyPicker"] as string;

if (!String.IsNullOrEmpty(myPicker))
{
  //add your custom logic here
}

Thats it, job done!

, ,

Leave a Comment

Sitecore : Extending OnItemSave Handler

In a recent project, I have to update certain fields of sitecore item when the item is saved in sitecore.

The solution I went for involved extending item:saved event and adding my own handler to do certain actions based upon template type

If you are in a similar situation, here are the steps to do

1. Create you custom class with a public method to perform your logic
2. In web.config under <events> find , <event name=”item:saved”> and append your handler at the end.

Here is basic class code

public class ItemSaveEventHandler
{
//master database name
public static readonly string Master = "master";
//sample template id
public static readonly string TemplateIdItem = "{67B44133-70CD-405C-BDAF-B93E5AEA2682}";

public void OnItemSaved(object sender, EventArgs args)
{

Item temp = Event.ExtractParameter(args, 0) as Item;
//make sure you are in edit mode and not in publish mode
if (temp != null && temp.Database.Name.ToLower() == Master)
{
//check if the template is what you are looking for
if (temp.TemplateID.ToString() == TemplateIdItem )
{
//do your stuff with the item, this is just a sample
temp.Editing.BeginEdit();
temp.Fields["Title"] = "new item saved title";
temp.Editing.EndEdit();
temp.Editing.AcceptChanges();

}

}

}

Complie and debug code, when you are ready change the web.config

<event name="item:saved">
<handler type="Sitecore.Links.ItemEventHandler, Sitecore.Kernel" method="OnItemSaved"/>
<handler type="Sitecore.Globalization.ItemEventHandler, Sitecore.Kernel" method="OnItemSaved"/>
<handler type="Sitecore.Rules.ItemEventHandler, Sitecore.Kernel" method="OnItemSaved"/>
<!-- add the namespace name and assembly dll name as per your site -->
<handler type="<MyWebsite.Handlers.ItemSaveEventHandler>, <MyWebsite.Hanlders>" method="OnItemSaved"/>
</event>

Thats it, if everything is correct the event handler will be called when someone saves an item in sitecore

Cheers

, ,

1 Comment

Sitecore : Adding schedule jobs via agents

This is a really short and sweet post. Sometimes you have to add scheduled jobs to query sitecore items at regular intervals and perform some custom logic.

The easiest way to do it is by adding your code as an agent to the web.config and setting up the interval

First, create your custom class, this could either be within the main website or a separate class library project something like

namespace  Website.AgentsNamespace
{
public class MyAgentClass
{
   public static void Run()
   {
     //add your custom logic here
     //call sitecore, services, database whatever
     //its up to you

   }
}
}

Compile and make sure there are no bugs.

Navigate to web.config and find

<scheduling>

node. Add your class as an agent and set the time interval like

<agent type="[name.of.your.class.including.namespace], [name.of.dll.where.the.class.is.compiled]" method="Run" interval="00:05:00" />

Thats it, job done.

Check the logs, and see when sitecor adds the job to scheduler.

, , ,

Leave a Comment

SQL Tips – Back up and restore

Here are some SQL bits that I user over and over again

If you try to manually restore the MS SQL server database via console app, it might say, ‘exclusive access could not be obtained’

This is probably there are some connections which have been left hanging or they are actually trying to do some stuff with the database.

I use this script to kill all un-wanted connections

use master

declare @vcdbname varchar(50)

Set @vcdbname = 'DatabaseName'

set nocount on

declare Users cursor for

 select spid

 from master..sysprocesses

 where db_name(dbid) = @vcdbname

declare @spid int, @str varchar(255)

open users

fetch next from users into @spid

while @@fetch_status <> -1

begin

   if @@fetch_status = 0

   begin

      set @str = 'kill ' + convert(varchar, @spid)

      exec (@str)

   end

   fetch next from users into @spid

end

deallocate users

Just change the name to your own database name and run the script

Imagine you have to backup and restore 5-10 database on adhoc bases, going through console app is very pain full and takes lot of time

I normally use scripts and run them in a go which back them up and restore them in a flash

For backups

DECLARE @BackupLocation AS NVARCHAR(250);
DECLARE @BackupDate AS NVARCHAR(8);
DECLARE @BackUpName AS NVARCHAR(350);

SET @BackupLocation = 'E:\SQLBackup\';
SET @BackUpDate = CONVERT(NVARCHAR(8), GETDATE(), 112)

-- replace MyDatabase with your database name
SET @BackUpName = @BackupLocation + 'MyDatabase_' + @BackUpDate + '.Bak';
USE master;
BACKUP DATABASE MyDatabase TO DISK = @BackUpName;

To resotre simply use the following script

USE [master];
ALTER DATABASE MyDatabaseNew SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE MyDatabaseNew SET SINGLE_USER;
RESTORE DATABASE MyDatabaseNew FROM DISK = 'E:\SQLBackup\<you-file-name>.Bak'
WITH REPLACE;
ALTER DATABASE MyDatabaseNew SET MULTI_USER;
GO

I would normally create these scripts for each of the databases and when required just run them in SQL

4 Comments