Friday, September 9, 2011

How To: SharePoint 2010 Weather Web Part

Over the years working with SharePoint I have had many requests for a weather web part to be placed on the home page of a company’s intranet or web site. The problem has always been that the RSS feeds you find online are never that reliable, and even if you do find one the data that it returns is never structured in an easy-to-use way.

I have recently found out that Google has its own weather feed. The data is structured perfectly for what I want to do, and the following will show how I went about creating a custom weather web part. I will be adding properties for the user to select if they want the Current Conditions or Tomorrow’s Forecast and the City they live in. (For now these will only be South African cities.)

1. Create the Project in Visual Studio
Open up visual studio and select to create a new Visual Web Part project under the SharePoint > 2010 templates, enter a name and click OK. On the next window enter your site URL and click Finish.
For purposes of keeping my projects tidy I have renamed my Web Part, the user control and the class files to more appropriate names.




2. Set up the user control display

I have added the following to my WeatherWebPartUserControl.ascx file that will render the data:

<style type="text/css">
    .wwp-container { width: 200px; text-align: center; font-family:Arial; font-size:12px; }
    .wwp-city { font-size:14px; font-weight:bold; }
    .wwp-error { color:Red; }
</style>
<div class="wwp-container">
    <asp:Label runat="server" ID="lblCity" CssClass="wwp-city"></asp:Label><br />
    <asp:Label runat="server" ID="lblDate" CssClass="wwp-date"></asp:Label><br />
    <asp:Image runat="server" ID="lblImage" CssClass="wwp-image"></asp:Image><br />
    <asp:Label runat="server" ID="lblTemp" CssClass="wwp-temperature"></asp:Label>&nbsp;-&nbsp;
    <asp:Label runat="server" ID="lblCondition" CssClass="wwp-condition"></asp:Label>
    <asp:Label runat="server" ID="lblError" CssClass="wwp-error"></asp:Label>
</div>

3. Update the Web Part class

In your web part class file you are going to add properties for the web part that will display when you edit the web part in your page. These settings make it easy for users to control how the web part works:



Here's the code:

// enums for the values of the drop downs
public enum CityEnum { None, Johannesburg, Cape_Town, Durban, Pretoria, Bloemfontein };

public enum ForeCastDayEnum { Today, Tomorrow };
// public properties
public static CityEnum City;
public static ForeCastDayEnum ForeCastDay;

// these settings tell the web part how to display the controls
[Category("Settings"), Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("City"),
DefaultValue("None"), WebDescription("Select a city")]
public CityEnum _City
{
 get { return City; }
 set { City = value; }
}
// these settings tell the web part how to display the controls
[Category("Settings"),
Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Forecast Day"),
DefaultValue("Today"), WebDescription("Select a city")]
public ForeCastDayEnum _ForeCastDay
{
 get { return ForeCastDay; }
 set { ForeCastDay = value; }
}

4. Update the User Control class

The class of the user control is where most of the processes happen. Here the methods are contained for accessing the RSS data and transforming it into displayable data. Below are the methods that I used. Comments are in line.

public const string _xmlUrl = "http://www.google.com/ig/api?weather={0},ZA&hl=en";
public const string _webUrl = "http://www.google.com/";
protected void Page_Load(object sender, EventArgs e)
{
 lblError.Text = string.Empty;
 try
 {
  WeatherWebPart.CityEnum selectedCity = WeatherWebPart.City;
  // check if a city has been selected
  if (selectedCity == WeatherWebPart.CityEnum.None)
  {
   throw new Exception("No city has been selected from the web part settings.");
  }
  else
  {
   GetWeatherData(selectedCity);
  }
 }
 catch (Exception ex)
 {
  lblError.Text = ex.Message;
 }
}

private void GetWeatherData(WeatherWebPart.CityEnum city)
{
 // format the url
 string url = String.Format(_xmlUrl, city.ToString().Replace("_", " "));
 // create the xmlreader
 XmlTextReader reader = new XmlTextReader(url);
 // load the reader into an xmldocument
 XmlDocument doc = new XmlDocument();
 doc.Load(reader);
 // get the root node
 XmlNode rootNode = doc.SelectSingleNode("/xml_api_reply/weather");
 // get the forecast data
 string cityName = rootNode.SelectSingleNode("forecast_information/city").Attributes["data"].Value;
 DateTime forecastDate = Convert.ToDateTime(rootNode.SelectSingleNode("forecast_information/forecast_date").Attributes["data"].Value);
 // check if the web part displays today or tomorrows weather
 if (WeatherWebPart.ForeCastDay == WeatherWebPart.ForeCastDayEnum.Today)
 {
  ShowToday(rootNode, cityName, forecastDate);
 }
 else
 {
  ShowTomorrow(rootNode, cityName, forecastDate);
 }
}

private void ShowTomorrow(XmlNode rootNode, string cityName, DateTime forecastDate)
{
 // get tomorrows conditions
 string tomorrowCondition = rootNode.SelectSingleNode("forecast_conditions[2]/condition").Attributes["data"].Value;
 string tomorrowHigh = rootNode.SelectSingleNode("forecast_conditions[2]/high").Attributes["data"].Value;
 string tomorrowLow = rootNode.SelectSingleNode("forecast_conditions[2]/low").Attributes["data"].Value;
 string tomorrowIcon = _webUrl + rootNode.SelectSingleNode("forecast_conditions[2]/icon").Attributes["data"].Value;
 string temperature = String.Format("{0}&deg;C - {1}&deg;C", tomorrowLow, tomorrowHigh);
 UpdateWebPartDisplay(cityName, tomorrowCondition, forecastDate.AddDays(1), temperature, tomorrowIcon);
}

private void ShowToday(XmlNode rootNode, string cityName, DateTime forecastDate)
{
 // get the current conditions
 string currentCondition = rootNode.SelectSingleNode("current_conditions/condition").Attributes["data"].Value;
 string currentTemperature = rootNode.SelectSingleNode("current_conditions/temp_c").Attributes["data"].Value + "&deg;C";
 string currentIcon = _webUrl + rootNode.SelectSingleNode("current_conditions/icon").Attributes["data"].Value;
 UpdateWebPartDisplay(cityName, currentCondition, forecastDate, currentTemperature, currentIcon);
}

private void UpdateWebPartDisplay(string city, string condition, DateTime date, string temperature, string iconUrl)
{
 lblCity.Text = city;
 lblCondition.Text = condition;
 lblDate.Text = date.ToLongDateString();
 lblTemp.Text = temperature;
 lblImage.ImageUrl = iconUrl;
}

5. Deploy the web part and install it on the page.

You can deploy the web part by simply right-clicking your project file and clicking Deploy. The solution will deploy to the URL that you specified in the setup stages of the project.

Here is the final look of the web part:


Thursday, September 1, 2011

10 ways to optimize your website for better Search Engine rankings – Part 3

Google Adwords

Adwords is a product from Google that helps to advertise your website. Basically how it works is, you get Google to advertise your website as one of their sponsored links based on keywords that are searched for and for every click that goes through on these links you will pay them a certain amount.
This means that even though searching for the phrase “peanut butter” only brings your site on the 27th page of the search results, it will still display on the first page of the results because of the ad campaign and this in turn generates more traffic for you website.
You might think that this can be quite costly if all of a sudden there is a shortage on peanut butter in some country and you get 10000 visitors, but Google allows you to set a maximum limit on what you are willing to pay.
Regular Content Updates
Updating the content on your website is very important to keep the crawlers coming back to your site. The more you update the content, the more relevant it will be to search results.

 Updating content does not mean rewriting your entire About Us page every month, but at least update some sites images, galleries or articles about your company.
Blogs
Ok so I’m not sure if blogs can fall under Social Media as well, but in any case it plays a big role on its own. Think about it this way:
You create a blog on a popular blogging site like blogger, wordpress, drupal, squarespace etc. This blog can be read by anybody on the web. Every blog post has something very relevant to your business and your website and contains a link to your site, images or gallery items. Boom! You have a semi-not-so-famous-yet website.
Google Page Speed
Google Labs has recently launched a new tool called Page Speed Online that will help you detect issues in your website that might cause it load slowly.
All you need to do is browse to http://pagespeed.googlelabs.com/, enter your website address and click Analyse Performance. The page will return with a description of what High Priority, Medium Priority and Low Priority respectively means. On the left hand side you will see a list of things you can look at to help speed up your website.