Monday, January 10, 2011

SEO Blogging tips

Amanda Fazani posted a three part SEO Blogging Tips article at bloggingtips.com.  It focuses on changes that can be made to Blogger blogs though the prinicples can be portable to any blogging platform

search engine optimization tips for blogger templates part 1
search engine optimization tips for blogger templates part 2
search engine optimization tips for blogger templates part 3

How to change your Blogger Title to help with SEO

I came across an easy article to help change your Blogger blog titles so that they get better rankings in search engines.  By default Blogger titles each of the blogs with the name of your blog instead of the blog title.  Check out this article.

http://www.bloggingtips.com/2008/05/12/how-to-change-your-blogger-title-tags/

Friday, January 7, 2011

Create an external SalesForce Web to Lead form

No matter how good or flexible a CRM tool is, there are times where you will want/need a process of automating the entering of leads from an external source.  In our environment it is cost prohibitive to give all our employees in the contact centers SalesForce licenses.  So we created some web-to-lead web pages that will allow those agents to enter lead info and have it pushed to SalesForce for tracking and lead management.  For organizations where at times there is a need to contract with external sources like West for lead generation who have their own system and you do not want to purchase licenses for then they can also use this process to create lead entries in your SalesForce environment.

SalesForce has a web-to-lead process that works quite nicely.  I will walk you through the process of creating a web to lead document and then making it usable.

Go to the “setup” of you SalesForce instance.  In the “App Setup” open the “Customize” section then open “Leads” then click on “Web-to-lead”.  There are some basic settings that you can configure from this screen.  You can turn on or off the web-to-lead feature, assign the default lead creator and assign default email templates for auto responses.  From this screen click on the “Create Web-to-lead Form” button.

image

The next screen you can select the elements that you want visible for the user to populate.  I am going to leave the defaults for simplicity though you can select any of the standard objects or custom objects you have created in the leads object.  The bottom URL box is used to provide the address that you want the user to see after the lead has been posted.

A note about how this process works.  When the user “submits” the form with the filled in information the page and its data is forwarded to SalesForce where the data is processed and then the page redirects to the provided URL.  There is nothing to denote to the user whether the post to SalesForce was successful or not.  Typically there are not any issues though we have seen times when leads were not always getting through.

image

Once you click “Next” you are taken to the screen where the HTML needed to post the lead is created.  The generated code is very simplistic and there are no formatting applied.  It works but is ugly and not very usable.  Copy the code and paste it into your preferred HTML editor.  My preference is notepad though there are many very good free html editors available.  Click “finished” when you are done copying the html code.

image

I saved the code as webtolead.html.  A sample of what is generated is below.  The hidden web elements are very important and the names of the elements are very important and must not change or data will not transmit properly to SalesForce.

image

This web form is rendered as below.

image

Let’s see if if this page works.  I filled out the page using the values in the image below.

image

Sometimes it can take a bit for the lead to show up in the list.  I logged into my development site and opened my leads and I can see the new lead in the list.  As you can see all the info that I entered in the web-to-lead form populated in the lead record perfectly.  One thing to note is that there are a lot of assignment and workflow rules that you can apply to these to determine how they are assigned.  I will not get into those at this time.

image

This is functional but is not user friendly, there is no branding applied and it opens the possibility of entering bad data since there are no controls associated to it.  I will show some basic techniques to jazz this up though this is not a full tutorial on HTML development since that would take a lot more room and concentration for that effort.

There have been times when there was a need to troubleshoot the code because we would submit a lead but it would not show up in SalesForce.  There are some options that we can turn on to help with that troubleshooting.  Below are the tags that can be added anywhere within the form tags.
<input type="hidden" name="debug" value="1" />
<input type="hidden" name="debugEmail" value=youremail@email.com />
Adding these tags will present the following page when submitting the lead instead of redirecting to the redirect URL.  Also an email will be sent to the address provided in the second debug tag.  This email will have a link to the lead record in SalesForce.

image

For the rest of this tutorial I will be removing the debug tags for ease of use.

The first thing to do is add some of the elements that are needed for a properly designed web page (it will work as is but best practice is to add some additional elements). If you are not familiar with HTML this may be a little hard to follow.  Each web page should contain a tag that tells the web browser what type of document it is and the format that it is organized in.  For more information about this you can browse the internet for additional elements.  Below are the elements that I chose to use.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%22>
<html xmlns="http://www.w3.org/1999/xhtml%22>
Next a closing “</html> tag needs to be added to the very end of the code.

The next element that should be added is the "head” element.  This is the section where you define what titles show, links to scripts, style files, page icons and so forth.  The first “notes” section that is generated can be removed and in its place the <head> tag should be added.  After that tag we want to add a title tag to customize the page a little. 
<title>Web-to-lead eForm</title>
That would leave the entry that starts with “<META” to come next.  After that the next message can be removed and replaced with the closing “</head>” tag.

The next section that normally comes in the body of the page.  We already have a form defined in the generated code.  We need to add the tag <body> just prior to the <form> tag and then add the closing </body> tag just after the closing </form> tag and before the closing </html> tag.

So far all the changes we have made are administrative with the exception of the title and do not do much to pretty up the page though they help the browser to better be able to read the html and set the stage for additional changes.

First thing that I like to do is add a little branding.  Branding is important because it helps to let the user know what company this lead form is for.  I found an image of a tree that I had on my desktop and I am going to use that as my image and I am going to add a header name that corresponds to the image for my fictitious company The Gnarled Tree.  Below the <body> tag that we created previously I added the following code which consists of a table, one row, three cells, and image in the first cell, the header in the second cell and nothing in the third (it is used primarily for spacing purposes).
<table width="100%">
<tr>
<td width="128">
<img src="gnarledtree.png" alt="GnarledTree" />
</td>
<td width="*" align="center"> <h2>The Gnarled Tree</h2>
</td>
<td width="128">
</td>
</tr>
</table>
With the changes the page now looks like the following.

image

Next I would organize the entry fields in to a format that is appealing and user friendly.  I like to organize fields by subject type into sections.  I made two tables one with contact details and the other with company details.  All of the information between the two form tags now looks like the below.

<input type=hidden name="oid" value="00DC0000000PU9Q">
<input type=hidden name="retURL" value="http://salesforce.com%22/>
<b>Contact Information</b>
<table>
<tr>
<td align="center"><label for="first_name">First Name</label></td>
<td align="center"><label for="last_name">Last Name</label></td>
<td align="center"><label for="email">Email</label></td>
</tr>
<tr>
<td><input  id="first_name" maxlength="40" name="first_name" size="20" type="text" /></td>
<td><input  id="last_name" maxlength="80" name="last_name" size="20" type="text" /></td>
<td><input  id="email" maxlength="80" name="email" size="20" type="text" /></td>
</tr>
</table>
<br />
<b>Company Information</b>
<table>
<tr>
<td align="center"><label for="company">Company</label></td>
<td align="center"><label for="city">City</label></td>
<td align="center"><label for="state">State/Province</label></td>
</tr>
<tr>
<td><input  id="company" maxlength="40" name="company" size="20" type="text" /></td>
<td><input  id="city" maxlength="40" name="city" size="20" type="text" /></td>
<td><input  id="state" maxlength="20" name="state" size="20" type="text" /></td>
</tr>
</table>
<br />
<input type="submit" name="submit">
The rendered output looks like the below.

image

Next I want to control what values are displayed in the State Province field.  I will be removing the current input tag with the name “state” (<input  id="state" maxlength="20" name="state" size="20" type="text" />).  In its place I am going to add a drop down list with a few states that I want displayed.  Below is a sample of what will be added in the place of the input tag that was just removed.  It is very important to make sure that the id and name fields have the exact name that the tag that was removed had.  If not the value will not be transferred to SalesForce.
<select id="state" name="state">
  <option value="select">[Select State]</option>
  <option value="AZ">Arizona</option>
  <option value="CA">California</option>
  <option value="FL">Florida</option>
  <option value="TX">Texas</option>
</select>
Below is the new rendered form.

image

The next element that I want to add is some scripting to validate the fields to make sure that required fields have a proper value.  This script will disable the “submit query” button if the requirements have not been met and highlight the fields in yellow that are required and have not been filled out yet.  To start with we need to create a script section with in the “head” tags that we created earlier.  Just prior to the </head> reference add the following lines:
<script language="javascript" type="text/javascript">
</script>
Next we need to modify one of the elements that was generated by SalesForce.  We will need to reference the “submit” button though it does not currently have an id that we can use to access it so that we can enable or disable it depending upon whether the user has entered valid information.

We want to give the “id” attribute the same value as the tag’s name.  It should look something like the following.
<input type="submit" name="submit" id="submit">
We are going to add all of our scripting that we need to create within this section.  The first function that we are going to add is the “load” function.  Within the “script” tags add the following lines:
function Load()
{
}
This function is named “load” and we are going to leave it blank for now.  We will be adding to it in a moment.  We next need to add an ID attribute to this tag to give it an ID that scripting can access. 

Right now adding this function does not do anything because there is nothing that is executing it.  Find the “body” open tag and within it we need to assign the “load” function call to one of the event attributes.  Below is an example of how your “body” open tag should look.
<body onload="Load();">
Next we need to create a function that executes when ever the user does something in the web page.  Under the “load” function we want to create a new function called “pageupdate”  This function will be called whenever any action on the form is performed.  For now we are not going to put anything in the function we will be adding something in a moment.  The function should look similar to the below.
function pageUpdate()
{
}
Similar to the “load” function this function is not doing anything until we assign it to an action.  We are going to assign this function to an action attribute in the “body” tag.  See below for an example of the change.
<body onload="Load();" onkeypress="pageUpdate();" onfocusin="pageUpdate();">
This will execute the function any time the user pushes a button on the page.  Be VERY carful what you put into this function or functions that this function calls.  Since this executes every time an action occurs it happens a lot.  I accidentally added an alert function (pops up a message) when I was testing this and the message would not stop coming up and I had to kill my browser session to stop the messaging.

Also because “select” HTML tags (or drop down lists) react a little different it is good to update that tag by adding the “pageupdate” function to its onchange event.  It should look similar to below.
<select id="state" name="state" onchange="pageUpdate();">
  <option value="select">[Select State]</option>
  <option value="AZ">Arizona</option>
  <option value="CA">California</option>
  <option value="FL">Florida</option>
  <option value="TX">Texas</option>
</select>
Before we make the validation function we need to decide which elements we want to require the user to enter a value into.  I want to require all but company name.  Also, I am a big fan of having a visual indicator that a field is required.  Some people like to put a red asterisk or note by required fields.  I like to change the back ground to yellow.  If you are the type that likes to show the red asterisk or note then you will need to create additional labels with that info and hide them on load and then display them on need in the validation function.  I am fond of the yellow color represented by the internet number of FFFF80.  Below is an example of the my validation function.
function validate()
{
    var reqColor = "#FFFF80"
    var regColor = "#FFFFFF"
    document.getElementById("first_name").style.backgroundColor=regColor;
    document.getElementById("last_name").style.backgroundColor=regColor;
    document.getElementById("email").style.backgroundColor=regColor;
    document.getElementById("city").style.backgroundColor=regColor;
    document.getElementById("state").style.backgroundColor=regColor;
   
    var valid = true;
    if(document.getElementById("first_name").value=="")
    {
        document.getElementById("first_name").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("last_name").value=="")
    {
        document.getElementById("last_name").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("email").value=="")
    {
        document.getElementById("email").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("city").value=="")
    {
        document.getElementById("city").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("state").value=="select")
    {
        document.getElementById("state").style.backgroundColor=reqColor;
        valid = false;
    }
           
    if(valid)
        document.getElementById("submit").disabled=false;
    else
        document.getElementById("submit").disabled=true;
}
Lets walk through this function.  First I create two functions to store the color values for the background, white for valid or yellow for required.  Then I go through each of the elements that are “required” and set their back ground to white in case things have changed since the function was last called.  Next I create a variable to store a true/false value so that I know whether all the validation criteria has passed or if any fail.  The next part is a series of checks that see if the value for each of the fields that are “required” have a value.  If they do not then we set the “valid” variable to false to prevent the submit button from being executed.  A screenshot of our initial screen is below.

image

As you can see all of our required fields are highlighted yellow and our “submit query” button is disabled.  If I fill in all the required values then the colors change and the “submit query” button is now enabled.

image

The final code from this tutorial is below.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd%22>
<html xmlns="http://www.w3.org/1999/xhtml%22>
<head>
<title>Web-to-lead eForm</title>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=UTF-8">
<script language="javascript" type="text/javascript">
function Load()
{
    validate();
}
function pageUpdate()
{
    validate();
}
function validate()
{
    var reqColor = "#FFFF80"
    var regColor = "#FFFFFF"
    document.getElementById("first_name").style.backgroundColor=regColor;
    document.getElementById("last_name").style.backgroundColor=regColor;
    document.getElementById("email").style.backgroundColor=regColor;
    document.getElementById("city").style.backgroundColor=regColor;
    document.getElementById("state").style.backgroundColor=regColor;
   
    var valid = true;
    if(document.getElementById("first_name").value=="")
    {
        document.getElementById("first_name").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("last_name").value=="")
    {
        document.getElementById("last_name").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("email").value=="")
    {
        document.getElementById("email").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("city").value=="")
    {
        document.getElementById("city").style.backgroundColor=reqColor;
        valid = false;
    }
    if(document.getElementById("state").value=="select")
    {
        document.getElementById("state").style.backgroundColor=reqColor;
        valid = false;
    }
           
    if(valid)
        document.getElementById("submit").disabled=false;
    else
        document.getElementById("submit").disabled=true;
}
</script>
</head>
<body onload="Load();" onkeypress="pageUpdate();" onfocusin="pageUpdate();">
<table width="100%">
<tr>
<td width="128">
<img src="gnarledtree.png" alt="GnarledTree" />
</td>
<td width="*" align="center"> <h2>The Gnarled Tree</h2>
</td>
<td width="128">
</td>
</tr>
</table>
<form action="https://www.salesforce.com/servlet/servlet.WebToLead?encoding=UTF-8" method="POST">
<input type=hidden name="oid" value="00DC0000000PU9Q">
<input type=hidden name="retURL" value="http://salesforce.com%22/>
<b>Contact Information</b>
<table>
<tr>
<td align="center"><label for="first_name">First Name</label></td>
<td align="center"><label for="last_name">Last Name</label></td>
<td align="center"><label for="email">Email</label></td>
</tr>
<tr>
<td><input  id="first_name" maxlength="40" name="first_name" size="20" type="text" /></td>
<td><input  id="last_name" maxlength="80" name="last_name" size="20" type="text" /></td>
<td><input  id="email" maxlength="80" name="email" size="20" type="text" /></td>
</tr>
</table>
<br />
<b>Company Information</b>
<table>
<tr>
<td align="center"><label for="company">Company</label></td>
<td align="center"><label for="city">City</label></td>
<td align="center"><label for="state">State/Province</label></td>
</tr>
<tr>
<td><input  id="company" maxlength="40" name="company" size="20" type="text" /></td>
<td><input  id="city" maxlength="40" name="city" size="20" type="text" /></td>
<td>
<select id="state" name="state" onchange="pageUpdate();">
  <option value="select">[Select State]</option>
  <option value="AZ">Arizona</option>
  <option value="CA">California</option>
  <option value="FL">Florida</option>
  <option value="TX">Texas</option>
</select>
</td>
</tr>
</table>
<br />
<input type="submit" name="submit" id="submit">
</form>
</body>
</html>
Thanks for reading this and hopefully it provides helps in your web-to-lead web page development.  Obviously there are a lot more that can be done to help usability.

Saturday, January 1, 2011

DreamForce 2010

This year I had the opportunity to attend the SalesForce.com conference DreamForce 2010.  It was an amazing conference and I enjoyed it quite a bit.  I am not “drinking the SalesForce Kool-Aid” so to speak but I think it is a very good application and a very cool platform that it runs on.  There were a few things that annoyed me about the conference, some things that made me laugh and some things that really piqued my interest.  The best part of the conference had nothing to do with the platform.  I loved the Stevie Wonder concert and after party DJ’d by will.i.am.
I enjoyed the keynote speeches and there were some cool new offerings that they announces though there were a few things that really annoyed me.  One of the cool offerings that I hope to play with soon is the new database.com.  This is an incredible idea.  There has been a hole in the needs of small businesses and individuals when it comes to web site.  That hole has been in that most of these persons have their websites hosted by hosting companies and many of those companies do not have good or cheap database services available.  This platform opens an avenue to be able to have a website and a database hosted that the developer can guarantee that they will work together.  The things that annoyed me…..First off I am glad that Mark Benioff and his company do so much charity work though my impression, others may have had a different impression, is that they were showing those things as a “look how great I am” and you should be like me.  Also when former President Clinton talked he mentioned that there is an issue in the country where only 9% of the US make up 80% of the income and that there is a disparity of classes that needs to be resolved.  The thing that was a little annoying about that is that everyone on that stage is part of that 9%.  Yes they are doing many good things though it is a hard thing to swallow someone that makes millions of dollars in one speaking engagement telling someone who makes less than 100,000 a year that they need to do more.  I agree that we all need to do more though it is still hard to take.
The second thing that annoyed me was their marketing spin and BS that they preach to discourage their customers from working with certain other companies.  It is no secret that there is no happy feelings between SalesForce, Microsoft and Oracle though some of their marketing is a bit silly and misleading in how they discourage people to work with these other vendors.  My first point is their “No Software” mantra.  To me this is a really annoying aspect because there is always software.  I understand the point that they are trying to make in saying that their customers do not have to install their own software, though there is still software involved and many of the “issues” associated to software still exist.  The biggest difference is where the software is installed, who is doing the development and who supports it.  Whether the software is installed in-house or externally it is still there and is still being supported.  So instead of paying internal resources and hosting your own hardware you are now paying someone else to do it for you.  Yes some of those costs are minimized because the costs are somewhat shared between multiple parties though the costs are still there as you can tell by the high licensing costs.  I have not done any analysis of long-term costs between on-premise platforms vs. hosted platforms.  I have seen articles that go both ways and depending upon a companies requirements it is impossible to know which solution is the cheapest solution without knowing the requirements so do not be fooled by generic comparisons.  If you are evaluating multiple platforms make sure you have good requirements and evaluate the platforms based upon these.  In many instances SalesForce would be the best and cheapest solution though in many instances it is not as well.  Do what is right for your organization and do not let the marketing spin delude you into making an uninformed decision.
The next thing that annoyed me was discussions about what is cloud computing and what is now.  One of their marketing niche is that cloud computing is the way of the future and they are the only cloud platform for CRM.  I agree that cloud computing is the way that the world is moving and it is a wonderful way to architect solutions.  What I do not like is their definition of what cloud computing is.  The National Institute of Standards and Technology (NIST) have a good definition of what cloud computing is on their website (http://www.nist.gov/itl/cloud/upload/cloud-def-v15.pdf).  This definition has five main characteristics; on-demand self-service, broad network access, resource pooling, rapid elasticity, and measured service (if you want a description of these terms check out the link previously provided).  The definition also has three service models, Software as a Service (SaaS), Platform as a Service (PaaS) and Infrastructure as a Service (IaaS).  Lastly, the definition has four delivery models; Private cloud, Community Cloud, Public cloud and Hybrid cloud.  SalesForce would have you believe that “Cloud Computing” only includes the public cloud delivery model, or at least when it is trying to explain why their competitors are not true cloud computing providers.  I know that many of their competitors have a SaaS offering similar to SalesForce.  These companies also push on-premise installs because they make more money that way.  An on-premise install can still be cloud computing though it would fall under the “Private cloud” designation.  I am a firm believer that there are good reasons to have software installed and managed in-premise though there are also times where a public cloud application is appropriate.  So saying carte-blanch that a specific delivery model is always bad that makes me nervous.  One of my mantras with technology is that we should not select technology solutions because they come from a specific company or exist in a certain platform and so forth.  We should select technical solutions because they are the best solution to further the business that we support.
The last annoyance was continuously hearing SalesForce telling us how great they are.  I normally follow the thought process that if someone needs to tell you how great they are then that may be something to be concerned about.  The platform should speak for itself.  I am not saying that this solution is deficient in anyway, I am just saying that I tend to lose a little respect for someone or something if they feel the need to tell me how great they are.
When it comes down to it all the major CRM platforms have the same or similar features.  The biggest considerations come into whether the processes for those features match your internal processes, how you want the platform to be managed, integration requirements, and cost.
Now that I am done ranting, there were a couple of things that made me laugh.  I have never been to a conference before where I have seen a competitor trying to hard to interact with the attendees.  I’ll be honest in saying that Microsoft’s actions were a bit hilarious and made them look a little stupid.  This goes back to my previous comment, if they have to tell you how much better they are then someone else then they should take a step back to see what is wrong with their application or sales process that is causing people to not see that they are better.  Personally I think that the biggest issue is not the platform itself but is in the sales process and that the expense to implement the platform is so high that people tend to try to do it on their own and not do it right so they ditch it and then go with someone like SalesForce where the platform is already setup (with the exception of integration elements).  Microsoft typically uses partners for their sales process and I have met with many of them on many different projects and have come away with the same feeling every time.  They come in with the attitude that they have already won the evaluation and are completely inflexible in their presentations to the point that they get lost if someone asks a question that is not planned for.  They are impersonal and are terrible presenters.  SalesForce on the other hand, my experience with them was fabulous.  I will not go into particulars but they were the best presenters for a technical solution I have come across.
There are a lot of things that I really like about the platform.  I think that the Force platform is pretty cool and is really flexible in allowing third party application developers to integrate to SalesForce.  I had already mentioned the database.com platform which is a great idea and there are a lot of other additions to the platform that I am new to that I would like to learn more about.  Needless to say I am doing a lot of learning about this platform that I hope to blog more about here later.