Warning: Cannot modify header information - headers already sent by (output started at /home/seomov22/public_html/blog/wp-content/themes/int-seomoves/functions.php:2) in /home/seomov22/public_html/blog/wp-includes/feed-rss2.php on line 8
Search Engine Optimization, SEO, & Other Online Marketing Strategies http://www.seomoves.org/blog SEO Moves News and Information Tue, 22 May 2012 17:25:47 +0000 en hourly 1 http://wordpress.org/?v=3.3.2 Facebook Launches New iOS Pages Manager Application http://www.seomoves.org/blog/social-media-marketing/facebook-launches-new-ios-pages-manager-application-2744/ http://www.seomoves.org/blog/social-media-marketing/facebook-launches-new-ios-pages-manager-application-2744/#comments Tue, 22 May 2012 17:21:11 +0000 Matt http://www.seomoves.org/blog/?p=2744 Install Facebook Pages Manager Notification in News FeedLast night while browsing Facebook’s iPhone app,  a little message popped in at the top of my News Feed informing me of a new Facebook iPhone app devoted to managing the pages you are an admin on all from one place. While the number of smartphone users continue to grow daily and as social media [...]]]> Last night while browsing Facebook’s iPhone app,  a little message popped in at the top of my News Feed informing me of a new Facebook iPhone app devoted to managing the pages you are an admin on all from one place.

Install Facebook Pages Manager Notification in News Feed

While the number of smartphone users continue to grow daily and as social media interaction is developing into a major factor in the credibility of “great content” in Google’s eyes; I decided to head over to App Store and give it a try.

Facebook Pages Manager - App Store      SEO Moves Facebook Pages Manager View

The Application looks virtually the same as the regular Facebook iPhone Application but instead of any type of personal information, it is devoted only to the pages that you are an admin on.  By clicking on the menu navigation in the top left corner, you can quickly switch between the different pages you have and see different aspects of those pages.

SEO Moves Facebook Pages Manager Insights View

 

 

Features:

  • Post new updates and photos as your Page
  • Get notifications about new activity on your page when it happens, no matter where you are
  • Respond, post and comment as your page while you are “on-the-go”
  • Manage all Facebook Pages from one interface
  • View all of your latest Page Insights

 

 

 

After using the App I do think that it is a good idea and with some added functionality in the future I could see myself adopting it for use with our business pages.  For now it is still a good resource for quickly checking the statistics or making some quick slight edits to your Facebook Pages from your phone.

Issues I have / Functionality I would Like to  see Added:

  • Messages are not currently supported in the App
  • Can Not currently look through photo albums in the App
  • Event Management has not been incorporated (Can’t Create or Manage Events)
  • App has not been updated to include the Timeline View (This is the default view for pages now and I would like the content to be displayed in the app the same way it is displayed for our customers and fans)

With The use of mobile phones and the importance of social media, I can only assume that these issues will be quickly updated by Facebook in the coming versions of the Application.

App Store Download Page: Facebook Pages Manager

]]>
http://www.seomoves.org/blog/social-media-marketing/facebook-launches-new-ios-pages-manager-application-2744/feed/ 0
HTML5 Microdata, Schema.org and Rich Snippets – Explained and a Free Tool http://www.seomoves.org/blog/build/html5-microdata-2711/ http://www.seomoves.org/blog/build/html5-microdata-2711/#comments Mon, 21 May 2012 16:28:34 +0000 Bob http://www.seomoves.org/blog/?p=2711 Rich Snippet Microdata Google ExampleRich snippets are all the rage these days. Ever since Google started enhancing their search results with these extra tidbits of information, everyone is rushing to update their web sites with the metadata to enable them. So what is the benefit of having a “rich” search result for your site? Good question. Other than giving [...]]]>



Rich Snippet Microdata Google Example


Rich snippets are all the rage these days. Ever since Google started
enhancing their search results with these extra tidbits of information,
everyone is rushing to update their web sites with the metadata to
enable them. So what is the benefit of having a “rich” search result for
your site? Good question. Other than giving the search engine user a
little bit of extra bit of detail, I suppose there’s also a subtle
psychological factor that kicks in. Someone might be more inclined to
click on a search engine result that has a 5 star rating and a friendly
face than one that doesn’t. Plus, they’re just plain cool. Who doesn’t
want to add bling to their search results? But this only scratches the
surface. There’s much much more to them than that.

Instant information aggregation: It’s only a matter of semantics

Rich Snippets, as Google calls them, are actually semantic markup. The
idea of marking up some sort of document with meta information for the
benefit of machines is not a new idea. Semantic markup is as old as
information technology its self. For example, a Word document contains
metadata about its author, and a digital photo contains meta data about
the camera it was taken with. You might, for instance, store your
digital snapshots in a photo archiving program which uses this semantic
data to filter your photos by date taken, lens type, flash used, etc.
So, in essence, metadata is data about data.

It’s should be clear, then, how this “data about data” can be extremely
useful to search engines. It can provide a search engine the ability to
derive a semantic meaning from a document’s meta
information rather than having to rely purely on the abstract, human
understandable, concepts within the text of the document. Searches can
become less about keywords in text documents and more about
relationships between semantical data types.

To illustrate this point further, consider the following search: Find
all restaurants with a 3.5 star or better rating on the Las Vegas strip
that specialize in Italian OR Mexican cuisine AND are open after 11 PM
on Sunday nights AND do NOT require reservations.
On the
semantic web, rather than a list of links to restaurant web sites that
may or may not match your given criteria, you might get a list of
“restaurant result objects” that DO match exactly
that criteria and never even have to visit the restaurant’s web site.
This is where the real power of semantic data lies. Instant information
aggregation.

A Microdata Example

This “semantic web”, also, is not a new idea. In fact, Tim Berners-Lee
himself envisioned the world wide web as a kind of “Semantic Network
Model” and even the earliest HTML specifications included the concept of
meta tags, which you are undoubtedly familiar with. Later iterations,
such as XHTML, took this idea a step further. Most notably is the RDFa
specification
, which has been around for quite some time.

These later meta data specifications brought with them the concept of a hierarchical
type system
. Within these type systems each data type
(i.e an abstract representation of a real world object) might have any
number of subtypes. So, you might have a base level
abstraction such as “Thing” which has a derived type such as a
“Business” and then a further derived type such as a “Store”, and
further still a more specific type of store such as “Book Store.”

The latest and greatest HTML5 introduces yet another form of semantic
web data called Microdata. You can view the documentation on http://schema.org.
Whether or not Microdata will supplant the earlier semantic markups
seems unclear at this point. However, the really interesting thing about
Microdata is that all the major search engines have helped develop it
and are beginning to standardize on it. E.g Google currently recommends
its use for its rich snippets.

Adding microdata to your html does require a little leg work, but its
advantages are likely worth the effort in the long term as it appears
search engines are starting to make use of it for some really
interesting stuff such as Rich Snippets. I have a feeling we’ll be
seeing other uses for it as well as HTML5 starts to really take hold.

Marking up your pages with Microdata

Adding Microdata to your html is a relatively painless process, but you
do need to consider the semantical relationships between the data on
your page. Essentially, each element you want to specify as an “item”
has an itemscope (i.e, where the item begins and ends)
and a number of descriptive properties which may either
be primitive types such as strings, dates, or numbers, or which may be
other “items” which in turn have their own item scope and properties.
Consider the following example of a “Book.” A Book has an author
property, which is a Person item. In addition the Book has a publisher
Property which is an Organization item. Thus, we have a single item that
has a relationship between two other data types.

                
<div class="listItem" itemprop="itemListElement" itemscope itemtype="http://schema.org/Book">
    <img itemprop="image" src="footfall.jpg" />
    <div class="details">
        <h3 itemprop="name">Footfall</h3>
        <div class="arating" itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
            <span itemprop="ratingValue">3.9</span> stars based on
            <span itemprop="reviewCount">25</span> reviews
        </div>
        <p itemprop="description">
            They first appear as a series of dots on astronomical plates, heading from Saturn directly toward Earth...
        </p>

        <div class="authInfo">
            <span itemprop="author" itemscope itemtype="http://schema.org/Person">
                By <span itemprop="name">Larry Niven</span>
            </span>
            and
            <span itemprop="author" itemscope itemtype="http://schema.org/Person">
                <span itemprop="name">Jerry Pournell</span>
            </span>
        </div>
        <div class="pubInfo" itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
            <strong>Published by:</strong> <span itemprop="name">DelRey Books</span>
        </div>
        <div class="clr"></div>
    </div>
    <div class="clr"></div>
</div>
                
            

What type you actually ascribe to your items is, of course, dependent on
your content. The type hierarchy on schema.org is fairly extensive, but
it also allows you to define your own types, if you need finer grained
data types than what the current spec provides.

As for the rest of the nitty gritty details, well the documentation at schema.org
is pretty clear so I won’t rehash it here.

A Microdata Parser

To help with marking up your web pages with HTML5 microdata, and for
discovering microdata embedded on other websites, I have developed a schema
tool
which can parse a page and give you a graphical overview of the
data types embedded within the html. You can see the relationships
between the semantic types on your page, as well as all their
properties. Clicking on an object in the diagram will display the full
list of properties and the html it parsed.

This simple web page is marked up with
Microdata: http://tools.seomoves.org/microdata/example/

View it with the microdata parser here:

http://tools.seomoves.org/microdata?url=tools.seomoves.org%2Fmicrodata%2Fexample%2F

You can see each Microdata item embeded within the html.

Meta Utopia or Meta Baloney?

It seems unclear at this point whether the idea of a truly “semantic
web” will ever be fully realized. The idea of being able to search not
just for keywords in text documents, but for many different related
types of data matching a vast array of criteria holds great potential.
However, the skeptic inside me sees a few problems.

  • Not all abstract concepts can easily be described within a simple
    schema.
    E.g what is “art”
  • The data has to be abundant. Creating meta data and
    classifications is extra work with no real immediate benefit. There’s
    currently no real “killer application” that rewards people for adding
    semantic markup to their pages, so the vast majority won’t see any
    need to do it.
  • The data has to be reliable. Spammers will inevitably exploit
    it thereby making the data useless. I already see pages ascribing
    types to data that doesn’t fit the schema. For the semantic web to
    function the data must be reliable.

Ultimately, only time will tell if the semantic web evolves like its
proponents envision. In the mean time, it is definitely worth
experimenting with microdata, if only for the rich snippet goodness.


]]>
http://www.seomoves.org/blog/build/html5-microdata-2711/feed/ 0
Rand Fishkin’s True Feelings on XML Video Sitemaps http://www.seomoves.org/blog/news/rand-fishkins-true-feelings-on-xml-video-sitemaps-2671/ http://www.seomoves.org/blog/news/rand-fishkins-true-feelings-on-xml-video-sitemaps-2671/#comments Wed, 16 May 2012 14:23:31 +0000 john http://www.seomoves.org/blog/?p=2671 Rand Fishkin    While watching the recent free video release from Distilled I got to see Rand Fishkin of SEOmoz’s true feelings about XML Video Sitemaps.  I decided that it required a true visual representation.     Share with social media]]>

 

 

While watching the recent free video release from Distilled I got to see Rand Fishkin of SEOmoz’s true feelings about XML Video Sitemaps.  I decided that it required a true visual representation.

 

 

Rand Fishkin's Crack Cocaine Rainbow Care Bear Transformer

]]>
http://www.seomoves.org/blog/news/rand-fishkins-true-feelings-on-xml-video-sitemaps-2671/feed/ 0
dynoTable – A JQuery Plugin by Bob Tantlinger http://www.seomoves.org/blog/web-design-development/dynotable-a-jquery-plugin-by-bob-tantlinger-2683/ http://www.seomoves.org/blog/web-design-development/dynotable-a-jquery-plugin-by-bob-tantlinger-2683/#comments Tue, 15 May 2012 23:55:50 +0000 Bob http://www.seomoves.org/blog/?p=2683 jQuery Logo - Write Less Do MoredynoTable: A JQuery plugin for creating editable tables A while back I was working on a project that required the GUI to allow the user to dynamically add, remove and rearrange various form fields contained in table rows. The tricky part was that the UI needed to have this functionality for several different types of [...]]]>



jQuery Logo - Write Less Do More

dynoTable: A JQuery plugin for creating editable tables

A while back I was working on a project that required the GUI
to allow the user to dynamically add, remove and rearrange various form
fields contained in table rows. The tricky part was that the UI needed
to have this functionality for several different types of elements
across several different forms. For instance, one set of fields was for
adding and removing specifications to a product while another set of
fields was for adding images to a product. Thus, I needed a solution
that would be flexible enough to work across virtually any type of form
elements.

Naturally, I turned to JQuery. I first took a look around within
JQuery’s plugin ecosystem to see if perhaps there was already a plugin
that might do the job. While I did find a few different plugins for
adding removing form elements, none of them did exactly what I
needed, specifically re-arranging items… So, I was left with either
trying to hack the functionality into an existing plugin, or roll up my
sleeves and write my own. I choose the later option, since JQuery’s
excellent extension mechanism makes writing plugins a fairly
straightforward process. The result is the plugin below, which I call
dynoTable.

What the plugin does

DynoTable makes an html table editable. With it you can:

  • Add rows
  • Remove rows
  • Clone rows
  • Click and Drag to Re-arrange rows (If you have Jquery UI included on
    your page)

Getting started with dynoTable is a snap. First make sure you have
JQuery, and the dynoTable plugin, included in your page like so:

            
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
<script type="text/javascript" src="jquery.dynotable.js"></script>
            
        

Next, once the dom has loaded, simply instantiate dynoTable like so:

        
$(document).ready(function(){
    $('#t1').dynoTable();
});
        
        

Given an html table similar to the one below, you will have the ability to add rows, clone rows, remove rows, and rearrange rows (rearranging works only if you have included JQuery UI)

        
<table id="t1" class="example">
    <tr id="add-template">
        <td>
            <img class="drag-handle" src="drag.png" alt="click and drag to rearrange" />
        </td>
        <td>
            <input id="tf1" type="text" value="I am in a table row!" />
        </td>
        <td>
            <select>
                <option>Yes</option>
                <option>No</option>
                <option>Unsure</option>
            </select>
        </td>
        <td>
            <img class="row-cloner" src="clone.png" alt="Clone Row" />
        </td>
        <td>
            <img class="row-remover" src="remove.png" alt="Remove Row" />
        </td>
    </tr>
</table>
        
        

Looking at the table above, you’ll notice a few classes:

  • row-cloner – clones the row when clicked
  • row-remover – removed the row when clicked
  • drag-handle – click and drag to rearrange row

And ids:

  • add-row – when clicked adds a row to the table
  • add-template – the table row template used when add-row is clicked.
    This row is NOT visible, it is only used as a template for rows that are added.

These specify what the user can click on to interact with the table. The
result of which is below:

Note: You can change these class-names to anything you want by
passing in them as properties to dynoTable. See available properties.

Example (Click Add Row to add a table row)

Configuring dynoTable

The dynoTable defaults will probably handle most use cases. If you do
not require any of the functionality it provides, you can simply omit
the classes from your table. However, dynoTable also provides a number
of properties and callback functions to configure it further if needed.

To pass configuration options and callback functions to dynoTable, you
simply pass them in as an object, when instantiating the plugin. For
example:

            
/*
 * dynoTable configuration options
 * These are the options that are available with their default values
 */
$('#myTable').dynoTable({
    removeClass: '.row-remover',        //class for the clickable row remover
    cloneClass: '.row-cloner',          //class for the clickable row cloner
    addRowTemplateId: '#add-template',  //id for the "add row template"
    addRowButtonId: '#add-row',         //id for the clickable add row button, link, etc
    lastRowRemovable: true,             //If true, ALL rows in the table can be removed, otherwise there will always be at least one row
    orderable: true,                    //If true, table rows can be rearranged
    dragHandleClass: ".drag-handle",    //class for the click and draggable drag handle
    insertFadeSpeed: "slow",            //Fade in speed when row is added
    removeFadeSpeed: "fast",            //Fade in speed when row is removed
    hideTableOnEmpty: true,             //If true, table is completely hidden when empty
    onRowRemove: function(){
        //Do something when a row is removed
    },
    onRowClone: function(){
        //Do something when a row is cloned
    },
    onRowAdd: function(){
        //Do something when a row is added
    },
    onTableEmpty: function(){
        //Do something when ALL rows have been removed
    },
    onRowReorder: function(){
        //Do something when table rows have been rearranged
    }
});
            
        

Callbacks: Extending dynoTable

In addition to the configuration options, you can pass in your own
behaviors as call back functions, as shown above. The available
callbacks are:

  • onRowRemove – Called when a row is removed
  • onRowClone – Called when a row is cloned
  • onRowAdd – Called when a new row is added
  • onTableEmpty – Called when ALL rows have been removed
  • onRowReorder – Called when rows have been rearranged by the user

The example below shows an example of how dynoTable might be used in
conjuntion with callback functions. When you add, clone, or rearrange the beers in the table, their numbers update automagically

Example Code

            
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js"></script>
        <script type="text/javascript" src="jquery.dynotable.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {
                /*
                 * Table of beers, created with some custom config options and callbacks.
                 */
                $('#beers').dynoTable({
                    removeClass: '.remove-beer',            //Custom remover class name in beers table
                    cloneClass: '.clone-beer',              //Custom cloner class name in beers table
                    addRowTemplateId: '#add-beer-template', //Custom id for beer row template
                    addRowButtonId: '#add-beer',            //Click this to add a beer!
                    lastRowRemovable: false,                //Don't let the table be empty. Never run out of beer!
                    orderable: true,                        //beers can be rearranged
                    dragHandleClass: ".drag-beer",          //class for the click and draggable drag handle
                    onRowRemove: function(){
                        updateBeerCount();
                        $('#msg').html("<span style='color:crimson'>Take one down, pass it around!</span>");
                    },
                    onRowClone: function(){
                        updateBeerCount();
                        $('#msg').html("<span style='color:orange'>You cloned a beer, nice job.</span>");
                    },
                    onRowAdd: function(){
                        var numBeers = updateBeerCount();
                        $('#msg').html("<span style='color:forestgreen'>" + numBeers +  " bottles of beer on the wall, woohoo!</span>");
                    },
                    onRowReorder: function(){
                        updateBeerCount();
                        $('#msg').html("<span style='color:blue'>Beers got rearranged and renumbered</span>");
                    }
                }); 

                updateBeerCount(); //initial bottles of beer
            });

            /**
             * Updates the current beer count
             */
            function updateBeerCount() {
                var count = 0;
                $('.beer').each(function(){
                    count++;
                    var msg = (count == 1) ? "1 bottle" : count + " bottles";
                    $(this).html(msg + " of beer on the wall!");
                });
                return count;
            }
        </script>
    </head>
    <body>
        <table id="beers">
            <tr>
                <td>
                    <img class="drag-beer" src="drag.png" alt="click and drag to rearrange" />
                </td>
                <td class="beer">

                </td>
                <td>
                    <img class="clone-beer" src="clone.png" alt="Clone Row" />
                </td>
                <td>
                    <img class="remove-beer" src="remove.png" alt="Remove Row" />
                </td>
            </tr>
            <tr>
                <td>
                    <img class="drag-beer" src="drag.png" alt="click and drag to rearrange" />
                </td>
                <td class="beer">

                </td>
                <td>
                    <img class="clone-beer" src="clone.png" alt="Clone Row" />
                </td>
                <td>
                    <img class="remove-beer" src="remove.png" alt="Remove Row" />
                </td>
            </tr>
            <tr id="add-beer-template">
                <td>
                    <img class="drag-beer" src="drag.png" alt="click and drag to rearrange" />
                </td>
                <td class="beer">
                    <!-- Beer text will go here  -->
                </td>
                <td>
                    <img class="clone-beer" src="clone.png" alt="Clone Row" />
                </td>
                <td>
                    <img class="remove-beer" src="remove.png" alt="Remove Row" />
                </td>
            </tr>
        </table>
        <div id="msg">
            &nbsp;
        </div>
        <button id="add-beer">Add a Beer!</button>
    </body>
</html>
            
        

Example of Custom Configuration of dynoTable

Source Code

Below is the full source code of the dynoTable plugin for those who might find it useful. I am placing this code in the public domain and
you may do with it as you wish. You can also download the javascript file here.

            
/*
 *  jquery.dynotable.js
 *  Created on Aug 1, 2011 3:36:39 PM by bob
 */
(function($){
    $.fn.extend({
        dynoTable: function(options) {

            var defaults = {
                removeClass: '.row-remover',
                cloneClass: '.row-cloner',
                addRowTemplateId: '#add-template',
                addRowButtonId: '#add-row',
                lastRowRemovable: true,
                orderable: true,
                dragHandleClass: ".drag-handle",
                insertFadeSpeed: "slow",
                removeFadeSpeed: "fast",
                hideTableOnEmpty: true,
                onRowRemove: function(){},
                onRowClone: function(){},
                onRowAdd: function(){},
                onTableEmpty: function(){},
                onRowReorder: function(){}
            };     

            options = $.extend(defaults, options);

            var cloneRow = function(btn) {
                var clonedRow = $(btn).closest('tr').clone();
                var tbod = $(btn).closest('tbody');
                insertRow(clonedRow, tbod);
                options.onRowClone();
            }

            var insertRow = function(clonedRow, tbod) {
                var numRows = $(tbod).children("tr").length;
                if(options.hideTableOnEmpty && numRows == 0) {
                    $(tbod).parents("table").first().show();
                }

                $(clonedRow).find('*').andSelf().filter('[id]').each( function() {
                    //change to something else so we don't have ids with the same name
                    this.id += '__c';
                });

                //finally append new row to end of table
                $(tbod).append( clonedRow );
                bindActions(clonedRow);
                $(tbod).children("tr:last").hide().fadeIn(options.insertFadeSpeed);
            }

            var removeRow = function(btn) {
                var tbod = $(btn).parents("tbody:first");
                var numRows = $(tbod).children("tr").length;

                if(numRows > 1 || options.lastRowRemovable === true) {
                    var trToRemove = $(btn).parents("tr:first");
                    $(trToRemove).fadeOut(options.removeFadeSpeed, function() {
                        $(trToRemove).remove();
                        options.onRowRemove();
                        if(numRows == 1) {
                            if(options.hideTableOnEmpty) {
                                $(tbod).parents('table').first().hide();
                            }
                            options.onTableEmpty();
                        }
                    });
                }
            }

            var bindClick = function(elem, fn) {
                $(elem).click(fn);
            }                  

            var bindCloneLink = function(lnk) {
                bindClick(lnk, function(){
                    var btn = $(this);
                    cloneRow(btn);
                    return false;
                });
            }

            var bindRemoveLink = function(lnk) {
                bindClick(lnk, function(){
                    var btn = $(this);
                    removeRow(btn);
                    return false;
                });
            }

            var bindActions = function(obj) {
                obj.find(options.removeClass).each(function() {
                    bindRemoveLink($(this));
                });

                obj.find(options.cloneClass).each(function() {
                    bindCloneLink($(this));
                });
            }

            return this.each(function() {
                //Sanity check to make sure we are dealing with a single case
                if(this.nodeName.toLowerCase() == 'table') {
                    var table = $(this);
                    var tbody = $(table).children("tbody").first();

                    if(options.orderable && jQuery().sortable) {
                        $(tbody).sortable({
                            handle : options.dragHandleClass,
                            helper:  function(e, ui) {
                                ui.children().each(function() {
                                    $(this).width($(this).width());
                                });
                                return ui;
                            },
                            items: "tr",
                            update : function (event, ui) {
                                options.onRowReorder();
                            }
                        });
                    }                                 

                    $(table).find(options.addRowTemplateId).each(function(){
                        $(this).removeAttr("id");
                        var tmpl = $(this);
                        tmpl.remove();
                        bindClick($(options.addRowButtonId), function(){
                            var newTr = tmpl.clone();
                            insertRow(newTr, tbody);
                            options.onRowAdd();
                            return false;
                        });
                    });
                    bindActions(table);

                    var numRows = $(tbody).children("tr").length;
                    if(options.hideTableOnEmpty && numRows == 0) {
                        $(table).hide();
                    }
                }
            });
        }
    });
})(jQuery);
            
        


]]>
http://www.seomoves.org/blog/web-design-development/dynotable-a-jquery-plugin-by-bob-tantlinger-2683/feed/ 0
Track Any Client Side Event With Google Analytics http://www.seomoves.org/blog/social-media-marketing/track-any-client-side-event-with-google-analytics-2635/ http://www.seomoves.org/blog/social-media-marketing/track-any-client-side-event-with-google-analytics-2635/#comments Tue, 15 May 2012 13:00:03 +0000 Bob http://www.seomoves.org/blog/?p=2635 The Google Analytics LogoTrack any client side event with google analytics By: Bob Tantlinger I’ve recently been doing some work integrating social media events, such as facebook likes, with google anayltics and was pleased to find that Google gives you a deep level of control over what you can track. It occurred to me that since a social [...]]]>





The Google Analytics Logo

Track any client side event with google analytics

By: Bob Tantlinger

I’ve recently been doing some work integrating social media events, such
as facebook likes, with google anayltics and was pleased to find that
Google gives you a deep level of control over what you can track. It
occurred to me that since a social media “event” is not really much
different than any other client side event, why not use google analytics
to keep tabs on any event the visitor might trigger.

With just a few lines of code, you can take your analytics a step
further and get some fine grained details about not only your visitors,
but their interaction with your web site. Using the techniques I show
below you can answer questions such as:

  • Did the user scroll a section of your page into view?
  • Did the user start filling out a form?
  • Did the user encounter an error while interacting with your site?
  • Did the visitor move their mouse over a particular page element?

These are just few examples off the top of my head for how this could be
useful, but you get the point. The sky is virtually the limit on what
you can track.

Get Tracking with _trackEvent

So, let’s dig in with a quick and dirty example that shows how to detect
if a user mouses over a a specific image on your page. To get started,
you’ll need:

  • A google anyltics account (Obviously)
  • The google tracking code installed in your sites head
  • JQuery included in your page

When you include google’s tracking code in your html, it brings in a
global variable named _gat
(Google analytics tracker) . Using this variable, we have a handle by
which we can get all trackers that have been included on the page. Using
the tracker objects, we can push arbitrary events onto the _gaq
(google anyltics queue) to be tracked. They can be anything. Their
meaning is entirely up to you.

After an event has been pushed onto the queue as an event, you can
monitor them under the “Events” section in your google analytics
account. (If you’re the pointy hair type, it’s probably neat idea to set
up goals for your events!)

So, the steps thus far are:

  • Decide what arbitrary events you want to track
  • Get a handle on all trackers included on the current page with _gat
  • Use the tracker to send an event to GA.

In our example, we will present the user with some images of food and
ask which is their favorite. We want to know when a user mouses over an
image, what type of image it was, and which food they select. With this
in mind we might write with some code such as this (Take note of
comments)

            
<!DOCTYPE html>
<html>
    <head>
        <title>Track a mouse over image event</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <style type="text/css">
            h1{text-align: center;}
            p{text-align: center;}
            img{border: 1px solid #333;}
        </style>

        <!-- include jQuery -->
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

        <script type="text/javascript">
            var _ga = _ga || {}; //ensure that _ga has been initialized
            var _gaq = _gaq || [];
            /*
             * Define a function on the _ga object that will automatically push events to all the registered trackers
             * It is possible that there is more than one tracker, hence this function
             */
            _ga.getEventTrackers_ = function(category, action, opt_label) {
                //we can return this anonnymous function and pass it to the _gaq
                return function() {
                    var trackers = _gat._getTrackers(); //Gets an array of allt he trackers from the _gat object
                    for (var i = 0, tracker; tracker = trackers[i]; i++) {

                        //Now we have a handle to a tracker, we can send the event to GA
                        //The tracker returns a boolean true if the event was successfully tracked, false otherwise
                        var result = tracker._trackEvent(category, action, opt_label, 1);

                        //for debugging the event tracking we can check the return value
                        if(result) {
                            console.log("Tracked " + category + " event " + action + " " + opt_label + " successfully"); //log the event to the console.
                        } else {
                            console.log("Tracking " + category + " event " + action + " " + opt_label +  " FAILED"); //log the event to the console.
                        }
                    }
                };
            };            

            /*
             * Wait for the document to be fully loaded, then bind events that we are interested to GA
             * In this example, we'll simply track what kind of image the user has moused over
             *
             */
            $(document).ready(function() {
                /*
                 * Bind mouseenter events to the images on the page
                 */
                $('img').mouseenter(function(){
                    //get the image id
                    var imgType = $(this).attr("id");
                    var label = $(this).attr("alt");

                    //push the mouse over event to GA
                    _gaq.push(_ga.getEventTrackers_("food", "mouseover", label, imgType));
                });

                /*
                 * Bind selection events to the radio buttons on the page
                 */
                $('input[name=food]').change(function(){
                    var imgType = $(this).attr("class");
                    var label = $(this).val();

                    //push the selection event to GA
                    _gaq.push(_ga.getEventTrackers_("food", "selection", label, imgType));

                });
            });
        </script>

        <!-- include your GA code snippet -->
        <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-1234567-1']); //IMPORTANT - this is a dummy id, replace with YOUR ga id!!!
            _gaq.push(['_trackPageview']);
            (function() {
                var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
                ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
                var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
            })();
        </script>
    </head>
    <body>
            <h1>Which is Most Tasty?</h1>
            <p>
                <input type="radio" name="food" class="hamburger" value="Hamburger" />Hamburger<br />
                <img id="hamburger" src="hamburger.jpg" alt="Hamburger" />
            </p>
            <p>
                <input type="radio" name="food" class="hotdog" value="Hot Dog" />Hot Dog<br />
                <img id="hotdog" src="hot-dog.jpg" alt="Hot Dog" />
            </p>
            <p>
                <input type="radio" name="food" class="pizza" value="Pizza" />Pizza<br />
                <img id="pizza" src="pizza.jpg" alt="Pizza" />
            </p>
    </body>
</html>

            
        

Rolling your mouse over the images or selecting a radio button fires
events, which will then be pushed to Google Analytics, where you can
keep track of them as show below.

Google Analytics Event Tracking Screen Shot

Click To Enlarge!

You can see a working demo here.

This was just a simple example of the flexibility that Google’s analytic
platform offers. Many more events can be tracked. You’re really only
limited by your imagination.

]]>
http://www.seomoves.org/blog/social-media-marketing/track-any-client-side-event-with-google-analytics-2635/feed/ 0
Tracking Pins With The Pinterest Button http://www.seomoves.org/blog/tools/tracking-pins-with-the-pinterest-button-2595/ http://www.seomoves.org/blog/tools/tracking-pins-with-the-pinterest-button-2595/#comments Mon, 14 May 2012 06:38:23 +0000 Bob http://www.seomoves.org/blog/?p=2595 Pinterest LogoTracking Pins With the Pinterest Button By: Bob Tantlinger Recently I was tasked with logging social media interaction on a site utilizing the “buttons” (what do you call those anyway) of Twitter, Facebook, Google+, LinkedIn, and Pinterest. We wanted to be able to record not only when a social media button was clicked, but when [...]]]>



Pinterest Logo

Tracking Pins With the Pinterest Button

By: Bob Tantlinger

Recently I was tasked with logging social media interaction on a site
utilizing the “buttons” (what do you call those anyway) of Twitter,
Facebook, Google+, LinkedIn, and Pinterest.

We wanted to be able to record not only when a social media button was
clicked, but when an actual share, like, or whatever took place. In
other words, we needed to know that the user actually did the share.
Nothing very difficult. Most of the big players in social media have
handy APIs that let you subscribe to events they fire off when a share
takes place, which makes this fairly straight forward. In a perfect
world it WOULD be easy, but there’s -always- a monkey wrench lurking
around the corner ready to ruin your day. In this case the monkey wrench
was a royal “Pin in the Ass.” I am referring to, of course, Pinterest.

Pinterest is the newest social media fad, so their button is popping up
all over the place at an alarming rate. Everyone is rushing to get their
images pinned to the worlds biggest pin board. But there’s a problem.
While Pinterest’s “Pin it” button works fine, they offer no offical API,
so unlike the other social media services, there’s not much you can do
with the Pin It button. You can stick it on your site, and that’s it.
You cannot track events, such as when a “pin” occurs, or even when
someone simply clicks on the darn thing.

The good news is that Pinterest is working on an API, which should
hopefully be ready soon. Parts of it are apparently in “Read Only” mode http://tijn.bo.lt/pinterest-api

http://articles.businessinsider.com/2012-03-26/tech/31238519_1_mobile-apps-twitterrific-hootsuite

Sadly, until then, the best you can hope for is a hack like the one I
will document below.

Bending Pinterest to your will (Almost)

When you include the Pinterest button on your page like they want you
to, you include their javascript file:

http://assets.pinterest.com/js/pinit.js

and a simple link where you want the button to show up:

        
<a href="http://pinterest.com/pin/create/button/" class="pin-it-button"
count-layout="horizontal"><img border="0"
src="//assets.pinterest.com/images/PinExt.png" title="Pin It" /></a>
        
        

All well and good… BUT when the pinterest javascript executes, it
takes the simple link, removes it from your DOM, and replaces it with an
IFRAME. (an embedded html document right in your page where the button
goes) So the pin it button is not actually a button. Rather, it’s a
small html file loaded from Pinterest’s CDN embedded in your page. The
transformed code looks like this:

        
<iframe scrolling="no" frameborder="0"
src="http://pinit-cdn.pinterest.com/pinit.html?url=http%3A%2F%2Fmysite.com&amp;media=http%3A%2F%2Fmysite.com%2Fpic.jpg&amp;description=Neat+Pic&amp;layout=vertical"
style="border: medium none; width: 43px; height: 58px;"></iframe>
        
        

Because they put it in an IFRAME, it’s like putting a brick wall around
the button. The IFRAME is pointing to
http://pinit-cdn.pinterest.com/pinit.html, which is obviously different
than your domain… Thus, you run up against the browser’s same origin
policy
(A security measure browsers implement which ensures scripts from
two different domains can not interact with each other.). So, I was
stuck. I could not get through the IFRAME brick wall, so I decided to go
around it completely.

Looking at the code contained in the IFRAME, you’ll see it’s just a tiny
html document, which only contains the button. If you examine this code
with Firebug, you can get the css styling, images, etc that give it its
look:

Firebug Pinterest Button Analysis

Click to Enlarge!

As you can see from the code, the pinterest button is basically just a
couple images and some css styling. Thus with a little bit of jquery
magic, I created my own function to embed the button on my own domain.

The Pinterest Button Hack

First, I stripped out all references to the pinterest button. It’s
important to NOT include the pinterest javascript file.

Next, I created a small javascript file with two functions:
loadPinterest and updatePinterestCount. I chose to create this as an
individual file, so that I could simply include it on any page I wanted
a “pin it” button on.

            
var updatePinterestCount = function() {
    $.ajax({
        url: 'http://api.pinterest.com/v1/urls/count.json?callback=?',
        data: {
            url: document.URL
        },
        success: function(data) {
            $('.PinCountBubble').html(data.count);
        },
        dataType: 'jsonp'
    });
};        

var loadPinterest = function(buttonSelector, imageUrl, description, onPinItClickCallback) {
    var pinUrl = "http://pinterest.com/pin/create/button/?url=";
    pinUrl += encodeURIComponent(document.URL);
    pinUrl += "&media=" + encodeURIComponent(imageUrl);
    pinUrl += "&description=" + encodeURIComponent(description);
    var css = "position: absolute; background: url('http://assets.pinterest.com/images/pinit6.png');";
    css += "left:0px;top:40px;font: 11px Arial, sans-serif; text-indent: -9999em; font-size: .01em;";
    css += "color: #CD1F1F; height: 20px; width: 43px; background-position: 0 -7px;";
    var html = "<div style='position:relative;margin:0;padding:0;width:43px;height:45px;display:block;'>";
    html += '<a class="pinner" href="' + pinUrl + '" style="' + css + '" count-layout="vertical">Pin It</a>';
    html += '<div style="display:block;">';
    css = "background-position: 0 0; height: 7px;top: 31px; width: 41px;";
    css += "background: url('http://assets.pinterest.com/images/pinit6.png') repeat scroll 0 0 transparent;";
    css += 'color: #FFFFFF;font-size: 0.01em;position: absolute;text-indent: -9999em;z-index: 1;';
    html += '<div class="PinCountPointer" style="' + css +  '"></div>';
    css = "font: 12px/12px Arial,Helvetica,sans-serif; height: 21px;left: 1px;padding: 9px 0 0;text-align: center;width: 39px;";
    css += "background-color: #FCF9F9;border: 1px solid #C9C5C5;border-radius: 1px 1px 1px 1px;color: #777777;position: absolute;";
    html += '<div class="PinCountBubble" style="' + css + '">0</div>';
    html += "</div>";
    html += "</div>";
    $(buttonSelector).html(html);
    $('.pinner').click(function() {
        window.open($(this).attr("href"), 'signin', 'height=300,width=665');
        if (typeof(onPinItClickCallback) == "function") {
            onPinItClickCallback();
        }
        return false;
    });
    $('.pinner').mouseenter(function() {
        updatePinterestCount(opts);
    });
    $('.pinner').mouseleave(function() {
        updatePinterestCount(opts);
    });
    updatePinterestCount();
};

            
        

The loadPinterest function uses jQuery to insert the button wherever you
specify via a css selector. E.g <div id=”pinit”></div>

You can pass this function:

  • CSS selector of the page elements you want to become pinterest buttons
  • The url of your image
  • A description of the image
  • a callback function, so that when someone clicks on the pin it button,
    you can take some action.

When the pin it button is clicked the following things happen:

  • A popup window opens http://pinterest.com/pin/create/button/ just as
    it does with the offical pinit button.
  • The window displays the options to “pin it” based on the parameters
    you passed the loadPinterest function.
  • The callback is called. What action you decide to take is up to you.
    The best you can do is detected when the pint button is clicked.
    Unfortunately, there’s no way to know that the user actually pinned
    anything or closed the window.
  • The updatePinterestCount function accesses pinterest to get the
    current pin count with an ajax jsonp request. So at the very least we
    can keep track of the pin count on the button.

The button’s count is updated when:

  • The page first loads
  • The user mouses over the pinit button

So, then, to include the button you simply need to call the pinterest
like so:

            
<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
        <script type="text/javascript" src="pin-me.js"></script>
        <script type="text/javascript">
            $(document).ready(function(){
                loadPinterest('#pinit', $('#pinImg').attr("src"), $('#desc').html(), doSomethingOnPinClick);
            });

            function doSomethingOnPinClick() {
                //do whatever you want here
                alert("You clicked the Pin It button!");
            }
        </script>
    </head>
    <body>
        <h3 id="desc">My Cool Picture</h3>
        <img id="pinImg" src="http://bobtantlinger.com/social/pic.jpg" />
        <div id="pinit"></div>
    </body>
</html>
            
        

And here is the working demo of the above code. The pinterest button is not being loaded from pinterest at all, and you can detect when the user clicks on it.

Limitations

This is ultimately a kludge until Pinterest releases its API. As
mentioned above, there is still no way to detect if the user actually
completed a pin. Only that he or she clicked on the pin it button.
Until there is an official API from Pinterest, that is probably the best
one can hope for.

In addition, the html + css for the button only does the vertical (count
bubble on top) version of button because that’s what I needed. It
should be straight forward to change if you need other button styles.


]]>
http://www.seomoves.org/blog/tools/tracking-pins-with-the-pinterest-button-2595/feed/ 0
SEO by the Sea and Me http://www.seomoves.org/blog/grow/seo-by-the-sea-and-me-2580/ http://www.seomoves.org/blog/grow/seo-by-the-sea-and-me-2580/#comments Wed, 09 May 2012 02:57:22 +0000 john http://www.seomoves.org/blog/?p=2580 SEO ExpertI wanted to publicly thank Bill Slawski from SEO by the Sea I recently hooked up with Bill in a Google Hang out which was hosted by and old mate of mine Dejan from DejanSEO. After listening to him talk about various SEO related topics, I knew I wanted to hear more. I fired off [...]]]> SEO ExpertI wanted to publicly thank Bill Slawski from SEO by the Sea I recently hooked up with Bill in a Google Hang out which was hosted by and old mate of mine Dejan from DejanSEO. After listening to him talk about various SEO related topics, I knew I wanted to hear more. I fired off an email offering to take him out to lunch and he responded promptly (maybe he was just hungry?), we sorted out a day and time for me to come down to meet with him.

It was a pleasure to chat with an industry veteran and share some war stories. I am looking forward to learning from and working with Bill in the future. If you have the opportunity to listen to Bill speak, listen very carefully and take notes :-) .

 

 

 

]]>
http://www.seomoves.org/blog/grow/seo-by-the-sea-and-me-2580/feed/ 1
Negative SEO – A post from 2008 http://www.seomoves.org/blog/google/negative-seo-a-post-from-2008-2573/ http://www.seomoves.org/blog/google/negative-seo-a-post-from-2008-2573/#comments Thu, 03 May 2012 22:19:53 +0000 john http://www.seomoves.org/blog/?p=2573 All this discussion about “Negaitve SEO” reminded me about a blog post that I wrote in 2008 on the same topic: “Jun 28, 2008 Negative Search Engine Optimization (SEO) the future of SEO I have been reading and studying the term negative search engine optimization (SEO). I find it quite funny how people at Google [...]]]> All this discussion about “Negaitve SEO” reminded me about a blog post that I wrote in 2008 on the same topic:

“Jun 28, 2008

I have been reading and studying the term negative search engine optimization (SEO). I find it quite funny how people at Google in particular (Matt Cutts) says Google Bombing or negative SEO is difficult or nearly impossible without high jacking someone’s website. This is totally wrong, but then again he is the same guy saying you need links to get your site to rank, but don’t buy them… (If I hear that loaded answer one more time!).

Google is very smart. What they do is rely on a human being’s general perception that if something is deemed wrong or is generally unacceptable, that most will avoid it. They have been pounding down everyone’s throat that paid links are bad, if you buy links your a bad person or evil webmaster. They talk about penalties and banning websites. In the past penalties were very rare, but recently I have seen several link buyers penalized.

As soon as I see a client penalized, I see the clear path to negative SEO. Each and every time I see or hear about a website penalized for off site SEO work, I create a log of what transpired and what the effects were. Does Google think SEO’s or people involved in search engine optimization are dumb? Well we are not. I have a list of places where links are penalized, I have a list of the types and quantities of links that have been penalized, I know how long it takes and how to avoid it or how to cause it.

I am not talking about buying links for Viagra for a number one ranked website for the search term homes. But you know if the site that ranked #1for homes, ranked between 4-6 for home sales, sell homes, buy homes etc., and that these are the keywords that a top quality website can be penalized for, then you simply build just a few too many really good links. Do not be obvious, do 100% legit SEO (buying links is OK in my book) work for the target site, just do a little too much, a little to quick, and guess what they will be given a -30 or a -45, for several of the over optimized keywords. They will not be penalized for their primary keyword which would require a 100% hand removal from Google or a Hand Penalty from Google, but it is not difficult to get them hammered for their 2nd tier search words.

Needless to say, I can present Google with multiple instances of proof that this is a fact, and I can certainly repeat the results if required.

Google is crossing its fingers that the general SEO community will frown on the part of negative SEO, because of the bad Karma, but in reality what is the difference between getting your site to rank higher (therefore lowering your competitors site) or simply lowering your competitors site so your site ranks higher?

Google is really beginning to upset me with these link threats, and link penalties. If they continue this barrage on SEO companies, everyone will just do very low profile SEO for their client’s sites, and over optimize 3-4 of their competitor’s websites. When multiple SEO companies adopt this theory, Google is really screwed. They will lose nearly all control, and be left unable to properly address which sites should be rewarded and which should be penalized.

For now Google is OK, because of the bad Karma factors and the “it’s wrong to do this”, but it will only take Google penalizing 2-3 top clients before SEO companies will all decided it is so much easier, and more profitable to negative SEO their competitors.

I will say that it is NOT hard, it is NOT difficult. If a group of top SEO and link builders got together, they could probably get nearly any site penalized.”

]]>
http://www.seomoves.org/blog/google/negative-seo-a-post-from-2008-2573/feed/ 0
Google Correcting Exact Match Domains Strength in SERPS http://www.seomoves.org/blog/google/google-correcting-exact-match-domains-strength-in-serps-2567/ http://www.seomoves.org/blog/google/google-correcting-exact-match-domains-strength-in-serps-2567/#comments Wed, 25 Apr 2012 04:19:39 +0000 julie http://www.seomoves.org/blog/?p=2567 Just heading to bed and noticed that out of the blue, many exact match domains have slipped in search. I noticed a number of exact match domains names have slipped somewhere from 5-40 positions in search. It was really long over due that Google fixed this issue. Exact match had gotten so far out of [...]]]> Just heading to bed and noticed that out of the blue, many exact match domains have slipped in search. I noticed a number of exact match domains names have slipped somewhere from 5-40 positions in search. It was really long over due that Google fixed this issue. Exact match had gotten so far out of hand that domain names like www.health-insurance-quotes.us were ranking well.

Glad to see Google has discovered a way to tweak this, although I am not a fan of some of the recent changes Google has made, they really did need to make some serious changes.

Google has been releasing changes to it’s algorithm rapid fire, I think they updated it about 3-4 times in the past 60 days. I think they may take a breather soon, and possibly even turn back some of their changes. I think they have moved with a VERY heavy hand on some of their link updates, and have really scared everyone online.

Everyone now is worried about “over optimization” I have had nearly every client of ours contacting us about this, so needless to say it is on everyone’s mind (including mine).

]]>
http://www.seomoves.org/blog/google/google-correcting-exact-match-domains-strength-in-serps-2567/feed/ 0
How to Get TWO Rows of Review Stars in Search Results http://www.seomoves.org/blog/news/how-to-get-two-rows-of-review-stars-in-search-results-2554/ http://www.seomoves.org/blog/news/how-to-get-two-rows-of-review-stars-in-search-results-2554/#comments Fri, 13 Apr 2012 21:10:06 +0000 john http://www.seomoves.org/blog/?p=2554 Two Rows of Reviews ExampleIf it’s your first time hearing about rich snippets you may want to read up at microformats.org first. In general though, rich snippets allow webmasters to influence the display of their website’s listings in search engines. Like this: Rich snippets have been around since 2009, but up until recently only a few websites could actually [...]]]> If it’s your first time hearing about rich snippets you may want to read up at microformats.org first. In general though, rich snippets allow webmasters to influence the display of their website’s listings in search engines.

Like this:

Two Rows of Reviews ExampleRich snippets have been around since 2009, but up until recently only a few websites could actually benefit from them. Previously, Google required webmasters to submit rich snippet request forms through its webmaster tools before anything would display differently in search results. Recently though Google has removed the manual approval process for hReview and other rich snippet code. This opens up many new exciting opportunities for both webmasters and SEO professionals.

hReview is arguably the most important rich snippet because it can pull reviews from your website and display them as stars under your search listings. Richard Baxter from SEO Gadget noticed a 5% CTR increase to his website after implementing hReview and obtaining stars in search results. 5% is an attractive number considering it takes all of five minutes to install the code.

To get the code for your website you can try the hReview Creator tool at microformats.org or simply use a template (I didn’t have much luck with the hReview Creator tool personally). Here is an example code template I drew up for my company, Evolve Creative Group.

<div class=”hreview”>

<span>

<span>Evolve Creative Group </span>

</span>

Reviewed by <span class=”reviewer”>Susie Smith </span> on

<span>

Jan 31<span class=”value-title” title=”2012-01-31″></span>

</span>.

<span>Thank you for being a great partner and delivering a world-class website.</span>

<span>After an extensive web agency search, we selected Evolve Creative Group and couldn’t have been happier with our choice. Todd Bertsch and his team demonstrated a passion and commitment to our project from the very first phone call.</span>

Rating:

<span class=”rating”>5.0</span>

</div>

This code can be placed anywhere within the body section of your source code. Make sure to use Google’s rich snippet testing tool to ensure that everything is set-up correctly.

Review stars will undoubtedly make your website more prominent in search results, but you need to be careful with how you use them or you risk getting your website penalized (unlikely) or having the snippet disappear altogether. Google’s guidelines for the hReview rich snippet state:

  • The main topic of the page needs to be about a specific product or service. For example, using review markup on a page containing multiple products is not supported.
  • Review of adult-related products or services are not supported.
  • If the markup contains a single review, the reviewer’s name needs to be a valid name (person or Organization). For example, “50% off until Saturday” is not a valid name for a reviewer.

Google also has a rich snippet spam report form that states, “a rich snippet promoting a travel package as an event or displaying fabricated reviews would be considered spam.”

Google’s first guideline is the most confusing for many because it’s open to so much interpretation. My company could argue that our homepage is about a specific service (web design), but would Google see it the same way? Denmonlaw.com from the example above has simply moved a review from their testimonial page onto their homepage and incorporated hReview.

Denmon Review

Assuming the review is legitimate I don’t see any issues with this practice. Only time will tell the future of this new open-ended system, but for now, we should all be taking advantage of this incredible opportunity while it’s still available. What do you think about moving a few testimonials to the homepage to benefit from hReview?

]]>
http://www.seomoves.org/blog/news/how-to-get-two-rows-of-review-stars-in-search-results-2554/feed/ 0