Showing posts with label SEO. Show all posts
Showing posts with label SEO. Show all posts

Sunday, December 9, 2012

SEO Basics: Friendly URLs

Implementing SEO-friendly URLs turned out to be much easier than I expected - MVC routing already takes care of the "heavy lifting". The developer only needs to provide a function that returnes the "friendly urls" from strings (product names, blog titles etc.) and to update action links.

1. Routing. A new route needs to be added. It has to be added above the default route so that MVC framework attempted to match it first. The seofriendly parameter can be pretty much anything that will satisfy valid url requirements.

routes.MapRoute(
 name: \"SEOFriendly\",
 url: \"{controller}/{action}/{id}/{seofriendly}\",
 defaults: new { controller = \"Home\", action = \"Index\", id = UrlParameter.Optional, seofriendly = \"\" }
);

2. Creating friendly urls. Here is an example I found on the web and added it "as is".

public static string ToSeoUrl(this string url)
{
 // make the url lowercase
 string encodedUrl = (url ?? \"\").ToLower();

 // replace & with and
 encodedUrl = Regex.Replace(encodedUrl, @\"\&+\", \"and\");

 // remove characters
 encodedUrl = encodedUrl.Replace(\"'\", \"\");

 // remove invalid characters
 encodedUrl = Regex.Replace(encodedUrl, @\"[^a-z0-9]\", \"-\");

 // remove duplicates
 encodedUrl = Regex.Replace(encodedUrl, @\"-+\", \"-\");

 // trim leading & trailing characters
 encodedUrl = encodedUrl.Trim('-');

 return encodedUrl;
}  

3. Making use of the friendly url. Just adding an extra parameter to the object.

Before:

<div class=\"display-button\">@Html.ActionLink(\"Edit\", \"Edit\", new { id=item.PostID }) </div>
<div class=\"display-button\">@Html.ActionLink(\"Details\", \"Details\", new { id = item.PostID }) </div>
<div class=\"display-button\">@Html.ActionLink(\"Delete\", \"Delete\", new { id = item.PostID }) </div>

After:

<div class=\"display-button\">@Html.ActionLink(\"Edit\", \"Edit\", new { id=item.PostID, seofriendly = item.Title.ToSeoUrl() }) </div>
<div class=\"display-button\">@Html.ActionLink(\"Details\", \"Details\", new { id = item.PostID, seofriendly = item.Title.ToSeoUrl() }) </div>
<div class=\"display-button\">@Html.ActionLink(\"Delete\", \"Delete\", new { id = item.PostID, seofriendly = item.Title.ToSeoUrl() }) </div>

References:

SEO-Friendly URLs in ASP.Net MVC 3
How can I create a friendly URL in ASP.NET MVC?
by . Also posted on my website

Sunday, December 2, 2012

SEO Basics: Linking My Content to Google+ Using rel='author'

I've learned the first step of using rich snippets to make links to my content look better in search results. The process is not extremely complicated, but it also is not intuitive to me, so I'd better write it down. I linked the content on my Blogger blog and also on my website which I'm using as training grounds. There are several steps involved - I need to modify my Google+ account, and I need to modify the content where I publish it.

1. Google+ account.

Assuming I already have a Google+ profile with photo on it, I go to my Profile, About and select Edit Profile.

Edit Profile

I scroll down to where Contributor to section is. In there I add the places I'm going to post my content. I edit this section to specify where my content is posted. Now Google+ knows where I'm posting, but that's not enough - I have to provide a way to verify that it's actually me.

Edit Contributor

2. My Website.

Here I have full control! I can experiment without fear to break things beyond repair. I did a few simple things so far: In the _Layout.cshtml, the partial view that is rendered on every page, I added the link to my Google+ account

<head>
    <link rel="author" href="https://plus.google.com/112677661119561622427/posts"/>
 ...
</head>

Additionally (optional) I modified the view that will display my posts to update the MetaKeywords and MetaDescription (see my previous post) dynamically.

@{
    ViewBag.MetaDescription = "Description of this post";
    ViewBag.MetaKeywords = "Keywords of this post";
    ViewBag.Title = Model.Title;
}

I'll add appropriate properties to the Model later, but that's beyond the scope of this post. I think that's all.

3. Blogger.

For reason I'll try to explain below, I had to add the following to the template of my blog in Blogger:

<a class='updated' expr:href='data:post.url' rel='bookmark' title='permanent link'><abbr class='updated' expr:title='data:post.timestampISO8601'><data:post.timestamp/></abbr></a>

Edit Blogger Template

I also added the same link as I did for my website - I'm not sure it's absolutely necessary though.

I'll also be adding the following to the end of my posts:

by <a title="Evgeny" rel="author" href="https://plus.google.com/112677661119561622427?rel=author" alt="Google+" title="Google+">Evgeny</a>.

With all that done I can publish this very post on my website and Blogger and then test the results.

4. Testing

Now I can test the results by entering the link to my post in the Structured Data Testing Tool. I enter the url and the tool tests the link for me.

This is the Blogger post.

Blogger - Positive Test Result

And this is my website.

Website - Positive Test Result

Finally, what would have happened if I hadn't added that bit to the Blogger template? I did not save the exact screenshot, but the error returned was "Missing required field 'Updated'" and looked similar to the image below.

Missing Required Field "Updated"

References

Warning: Missing required field "updated" in Blogger Rich Snippet Webmaster Tool [Solved]
Embrace Authorship - The importance of rel=me and rel=author on your content's SEO and Google
Rich snippets for idiots. And, er, you.
by . Also posted on my website

Wednesday, November 28, 2012

MVC and SEO basics: inject title, keywords and description into views

Almost by accident, I came across Google's starter guide for SEO optimisation and decided that it is a good idea to make some improvements I've been neglecting. Here's what I did so far and how I applied it to the MVC framework.

1. Create unique, accurate page titles

One way to do it with the MVC framework is to create a placeholder on the master page and then override it on the view page.

Master:


    
    
        <%=this.Page.Title%>
    

View:


       Home Page

For now, I chose the easier approach to set the title in the _Layout.cshtml

@ViewBag.Title

And assign it in each view separately

@{
    ViewBag.Title = "Main Page - The Stepping Stone Markov Chain Algorithm - MVC Stepping Stone Example";
}

2. Make use of the "description" and "keywords" meta tags

This takes a little more work. Here's my chosen approach: First, make sure each controller inherits from the BaseController. Then create two new classes, MetaDescriptionAttribute and MetaKeywordsAttribute, and inherit them from System.Attribute

public class MetaDescriptionAttribute : Attribute
{
 private readonly string _parameter;

 public MetaDescriptionAttribute(string parameter)
 {
  _parameter = parameter;
 }

 public string Parameter { get { return _parameter; } }
}

public class MetaKeywordsAttribute : Attribute
{
 private readonly string _parameter;

 public MetaKeywordsAttribute(string parameter)
 {
  _parameter = parameter;
 }

 public string Parameter { get { return _parameter; } }
}

In BaseController, override OnActionExecuting

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
 var keywords = filterContext.ActionDescriptor.GetCustomAttributes(typeof(MetaKeywordsAttribute), false);
 if (keywords.Length == 1)
  ViewData["MetaKeywords"] = ((MetaKeywordsAttribute)(keywords[0])).Parameter;

 var description = filterContext.ActionDescriptor.GetCustomAttributes(typeof(MetaDescriptionAttribute), false);
 if (description.Length == 1)
  ViewData["MetaDescription"] = ((MetaDescriptionAttribute)(description[0])).Parameter;

 base.OnActionExecuting(filterContext);
}

Decorate the appropriate controller method with newly created attributes

[MetaKeywords("C#, MVC, Markov Chain, Stepping Stone, Programming")]
[MetaDescription("Stepping Stone Markov Chain model is an example that has been used in the study of genetics. In this model we have an n-by-n array of squares, and each square is initially any one of k different colors. For each step, a square is chosen at random. This square then chooses one of its eight neighbors at random and assumes the color of that neighbor")]
public ActionResult Index()
{
 SteppingStoneHelpers.CreateNewTable();
 HtmlString table = new HtmlString(SteppingStoneHelpers.table.ToString());
 return View(table);
}

Finally, in the _Layout.cshtml, add the following


All done! There we go, the resulting html:




    
    
    Main Page - The Stepping Stone Markov Chain Algorithm - MVC Stepping Stone Example
    
    

References:

Google Starter Guide
ASP.NET MVC - View with master page, how to set title?
asp.net mvc - strategy for including SEO information such as meta keywords and descriptions
by . Also posted on my website