SEO for WordPress: Rank VS Tank

Definitely a not so discussed topic in my blogs. The ever evolving monster known as Search Engine Optimization is a huge consideration when driving traffic to your site… at no cost. Free. How much better does it get?

Recently, I started using some cool new tools from Google and the results are still standing by. Other than using Google Analytics to check visits to your site, using Google Webmaster Tools in combination with Google Page Speed developer tool, should help you not only achieve a cleaner and clutter less site, but rather a site that doesn’t get negative ratings from Google.

As we know, Google is still the most popular engine out there, and we want to make them happy. Recently, I like Google’s push towards more related content. Long gone are the days where losangeleslawyers.com was a good domain for SEO because the domain name had the three most searched terms when someone looked for Los Angeles Lawyers in google. Nowadays, it’s about branding. LoAnLa.com would rank much higher if the description of the site had to deal with LA Lawyers, and the content of the homepage was kept to a less than 200 words page all about the lawyers in Los Angeles.

Because I’ve mentioned them several times in this post, I might actually get dinged by Google since I’m not really talking about them in particular, but I’m only using them as an example. It’s good to keep relevant text on your site, and chose ONE subject to talk about. Don’t put all three of your businesses on one website hoping that you can do cross promotion or something crazy like that.

I hope this can help some of you out there to better rank your pages, rather than tank your pages.

Oh, and for goodness’ sake, clean up your HTML folks. If it doesn’t look good in IE8, it’s probably your fault. I had to spend an entire day tracking down an extra double quote in one of the ads I used. Valid HTML is definitely a plus when Google checks your site. Not only it makes your website faster to load (milliseconds), but visually, more attractive to IE visitors, and there’s about 13% of those around the web as stated by w3schools.com.

One last note. Stop saying SEO Optimization. You sound like a damn fool!

“Search Engine Optimization Optimization”, yes, that’s what you’re saying.

Happy Optimizing.

Site Migration Plugin for WordPress

I’m in the process of finishing up the first version of the plugin that will make site migration really easy for anyone who wants to migrate their sites entirely from one environment to another. This is a great tool for someone setting up their environments initially. Messing around with the database is not a great idea, so this plugin will handle all of the table copying, etc. The requirements are to have a repository in SVN. A future version will have other repository features, such as GIT.

And here’s the first version for your amusement. Modify to your heart’s content, and send me some notes. I know a lot can be fixed and re-factored to make it better.

okm-sitemover

How to Migrate a WordPress Project

When working on WordPress projects, and you need to migrate, let’s say from LOCAL to DEV, or DEV to STAGING, or STAGING to LIVE, whatever the case may be, you need to keep a lot of things in consideration.

Here’s my setup:

  • SVN holds any custom themes or plugins, not the core files, or config files.
  • Multi-tier environment with dropbox backing up local files. (LOCAL, DEV, STAGING, LIVE)
  • LAMP dev environment.

Before you migrate, setup WordPress:

  • Create an entry in the hostfile if necessary
  • Setup the vhosts file
  • Unzip WordPress in the new folder in all environments
    • public_html/newsite.com/dev
    • public_html/newsite.com/stg
    • public_html/newsite.com/www

Let’s go through the basic list:

  • Make sure core is not in SVN. Only keep changes, and new development in SVN.
  • Make a list of plugins used.
  • Extract WordPress in the folder you want to install the website.
  • Copy database to new database.
    • Change DB URL
    • 1
      UPDATE wp_options SET option_value = REPLACE (option_value,'old.domain.com','new.domain.com');
    • Typically from dev.website.com to stg.website.com for staging
    • And dev.website.com to website.com for live.
  • Copy wp-config file to new folder if settings are the same.
    • Change db login credentials.
  • Do a checkout of SVN project in doc root.
  • Re-install all plugins.
    • Configure plugins.

This should be it. I wouldn’t mind working on a custom plugin to handle all this. Maybe add some custom code to do svn updates on the other tier levels as well, so all I would have to do is click a button, and BAM, svn updates to next level.

I might even dedicate a page for this. Standby for this feature.

Clear floats with overflow: hidden

Lately, I’ve seen a trend of programmers adding on new elements to pages in order to add a class to them to clear all of the floated elements in a container. Why? Simply use overflow hidden on the parent, and like a miracle, bam! The container becomes aware of all of the children elements.

The old way:

1
2
3
4
5
6
7
<ul>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
    <li class="clearfix"></li>
</ul>
1
2
3
4
5
6
li {
    float: left;
}
.clearfix {
    clear: both;
}

The old way is not as effective, since we have to add additional elements that do not show anything. Their only purpose is to fix a css style. Why not do it in css? This method also adds what seems like an additional line that makes it seem like you have bottom margin, or padding. Too much to maintain and fix. Additionally, I believe at the time of this writing, google looks for empty elements and dings you if you don’t put anything in them. Validate your HTML. Be a good programmer.

The new way:

1
2
3
4
5
6
<ul>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
    <li><a href="/">Text</a></li>
</ul>
1
2
3
4
5
6
ul {
    overflow: hidden;
}
li {
    float: left;
}

Who’s JSON?

J. S. O. N. Actually

Not sure where I’m going with this, but here we go. I like JSON (JavaScript Object Notation). What’s that, you say? You mean, who’s that? Oh, wait. No, it’s ‘what’s that’.

What I’d like to start with is something experimental. Let’s focus on the idea that there is a back-end, and a front-end to any development, especially web development, and especially web application development. What if both sides could simply just communicate with itself via JSON. Why JSON? Because JSON is super light weight for transferring data. What kind of data, you ask? Any kinds. Sure, we could render out code via an AJAX call as HTML, but all those little extra tags are overhead. JSON keeps it simple with only one or two additional characters per variable or value. Let me show you what I mean.

1
var myObject = { "person" : { "fname" : "John ", "lname" : "Donson"} };

Notice what happens in the block of code above. I’ve specified an object with enough information to arrive at the conclusion that this data is related to a person, and their name is John Donson.

jQuery can easily do this JSON encoding from arrays, strings, etc. You just need to pass it the variable:

1
var myObject = $.parseJSON( '{ "person" : { "fname" : "John ", "lname" : "Donson"} }' );

Please note that I’m using double quotes inside the object itself. This is proper JSON format. Escape any single quotes with backslashes. This gives us an object that we can easily inspect in the console log of Firefox.

All right, now that we understand who JSON is, let’s have fun with him.

HTML5 Kicks in

Wouldn’t it be great if we could use HTML5 to send some data to JavaScript who can in turn send the data to the backend (PHP), who can then get some data from a database and return back some JSON code that we can use back in JS to manipulate elements in HTML5?

Wow, I mean, why even go down this road? Simple. Large amounts of data to be processed. PHP may be fast at 300 requests per second, but HTML is even faster, with 1000 requests per second. The idea is to develop for online applications. Such as, a game, or management systems.

Let’s start from the top. Here come’s < a >.

1
<a href="javascript:void(0);" class="jsonCall" data-get='{"url":"/ajax/main.php","data":{"var1":1,"var2":2}}'>Click me!</a>

Whoa, why all this? Let me break it down.

- The void call in the JS call is to make sure older browsers don’t show a white page when clicked.
- We’ve added a class because we want to identify any element with an action. Doesn’t have to be an < a > element.
- data-get is our HTML5 way of introducing data that we will need. This is our JSON data that we will send from JS through our AJAX call.

Let’s see where this takes us.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(document).ready(function(){
    $('.jsonCall').on('click',function() {
        var queryVars = $(this).attr('data-get');
        var qJSON = $.parseJSON(queryVars);
        var qString = "internal=true";
        for (data in qJSON.data) {
            qString += "&"+data+"="+qJSON.data[data];
        }
        $.ajax({
            url: qJSON.url,
            type: 'post',
            data: qString,
            dataType: 'JSON'
        });
    });
});

This is the entire code we need to parse out our data-get attribute value and send it out for processing. Let’s put what we did into practice.

Practice Makes Improvement, Because No One is Perfect

Let’s say we want to load a list o thumbnails with descriptions and links to another page. So, let’s set up the scenario.

What we need:
- link
- thumb
- text

There’s the classic way and try to render everything out on the backend, and spew out some static html that can be placed inside our “container” whatever that container will be.

Why not make it smarter, and just send a request for the items you need. Let’s say you need 16 thumbs because that’s how many thumbs will be on the page at once. Yes, you can always change this number, but 16 is perfect for a 4×4 display of thumbs.

First, we need to understand what our content might look like. It will probably look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<ul>
    <li>
        <a href="">
            <img src="" />
            <span></span>
        </a>
    </li>
    <li>
        <a href="">
            <img src="" />
            <span></span>
        </a>
    </li>
    ...
</ul>

Ok, it will be a little more intricate than that, but here’s the reason to load your content with JSON. All of this above is simply overhead. None of our data has been loaded yet. There IS no data! So, with all this effort of rendering out, we got back a big fat nothing.

Why not templat-ize the results? It would make much more sense. Why not load the template HTML content inside our current document so we can just use it? Since it will be used anyway on the page, load it up, but keep it hidden.

1
2
3
4
5
6
7
8
<script id="content-list-item" type="text/x-jquery-tmpl">
    <li>
        <a href="[[url]]">
            <img src="[[thumb]]" />
            <span>[[text]]</span>
        </a>
    </li>
</script>

This would allow us to get the content via the jQuery.html() function, replace the values inside the double brackets, and append this element to the container.

Doesn’t make sense yet? Let’s compare the old way we used to do things. If we had a loop of items on a page, we would render everything at the php level right after we got the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$qty = $_POST['qty'];
$retVal = array();

for ($itemCount = 0; $itemCount < $qty; $itemCount++) {
    ?>
    <li>
        <a href="http://www.motortrend.com/roadtests/oneyear/coupe/1302_2013_scion_fr_s_arrival/">
            <img src="http://i2.squidoocdn.com/resize/squidoo_images/-1/lens10584771_1271704447MARIO_thumbnail.jpg" />
            <span>2013 Scion FR-S Arrival</span>
        </a>
    </li>
    <?php
}
?>

This would be fine, if the data would remain minimal, but where are your alt tags, title tags, what if you use itemprops for SEO results. All that is additional overhead.

Our template contains almost the same amount data returned as JSON. The reason being is that we’re not returning

1
<a href="

as data, but we’re most likely returning

1
{"

instead. Less code already.

But, you say, the difference is not that great. We went from 236 bytes to 258 bytes. It’s not a huge difference. It’s about 9%. I’m not impressed.

Ok, what if you do add those additional items, like title, alt, propitem, etc… And what if you have additional wrappers and other overhead HTML that repeats? Your template only includes this once. The rendered version of your code returns this 16 fold. Let’s see the difference between.

235 to 305!!! How’s 30% increase in your data for a significant enough number?

In Conclusion

So, when comparing the two methods, you notice that our template has been increased by a few bytes.

1
2
3
4
5
6
7
8
<script id="content-list-item" type="text/x-jquery-tmpl">
    <li itemprop="stuff">
        <a href="[[url]]" itemprop="url" title="[[text]]">
            <img src="[[thumb]]" itemprop="image" title="[[text]]" alt="[[text]]" />
            <span>[[text]]</span>
        </a>
    </li>
</script>

Our JS has not increased since we’re just reusing the same references for the alt, title, etc tags.

While the oldmain.php rendering file has increased a bit more than the template file, this repeats several times, significantly increasing the size of data transferred back to the client.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
$qty = $_POST['qty'];
$retVal = array();

for ($itemCount = 0; $itemCount < $qty; $itemCount++) {
    ?>
    <li itemprop="stuff">
        <a href="http://www.motortrend.com/roadtests/oneyear/coupe/1302_2013_scion_fr_s_arrival/" itemprop="url" title="2013 Scion FR-S Arrival">
            <img src="http://i2.squidoocdn.com/resize/squidoo_images/-1/lens10584771_1271704447MARIO_thumbnail.jpg" itemprop="image" title="2013 Scion FR-S Arrival" alt="2013 Scion FR-S Arrival" />
            <span>2013 Scion FR-S Arrival</span>
        </a>
    </li>
    <?php
}
?>

Another benefit is that the template can be changed as an individual file. So, if designs change, you never have to bother the back-end developers, unless new data is necessary for the items retrieved, but that’s a data issue, not a design issue.

Updates to the other files:

The call is being made from here

1
2
3
<a href="javascript:void(0);" class="jsonCall" data-template='#content-list-item' data-container='#my-container' data-qty='16' data-action='getmario'>Click Me!</a>

<div id="my-container"></div>

The JavaScript updated file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    $('.jsonCall').on('click',function() {
        var template = $(this).attr('data-template');
        var container = $(this).attr('data-container');
        var action = $(this).attr('data-action');
        var qty = $(this).attr('data-qty');
       
        $.ajax({
            url: '/ajax/main.php',
            type: 'post',
            data: 'qty='+qty+'&action='+action,
            dataType: 'JSON',
            success: function(data) {
                $(container).html('');
                var templateCode = $(template).html();
                for (var itemCount = 0; itemCount < qty; itemCount++) {
                    templateCode = templateCode.replace(/\[\[url\]\]/gi, data[itemCount].url);
                    templateCode = templateCode.replace(/\[\[thumb\]\]/gi, data[itemCount].thumb);
                    templateCode = templateCode.replace(/\[\[text\]\]/gi, data[itemCount].text);
                    $(container).append(templateCode);
                }
            }
        });
    });

The ajax called JSON returning php file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
// a sort of a controller to get the right function to run
if (isset($_REQUEST['action'])) {
    switch ($_REQUEST['action']) {
        case 'getmario':
            getMario();
            break;
    }
}

function getMario() {
    // normally would make a database connection to populate the data,
    // but that's not what we're testing here.
    // We only made one connection per call anyway.
    $qty = $_POST['qty'];
    $retVal = array();

    for ($itemCount = 0; $itemCount < $qty; $itemCount++) {
        array_push ($retVal, array(
            'url' => 'http://www.motortrend.com/roadtests/oneyear/coupe/1302_2013_scion_fr_s_arrival/',
            'thumb' => 'http://i2.squidoocdn.com/resize/squidoo_images/-1/lens10584771_1271704447MARIO_thumbnail.jpg',
            'text' => '2013 Scion FR-S Arrival'
        ));
    }
    $retValJSON = json_encode($retVal);
    echo $retValJSON;
}

?>

Just to show once again that the more complex your html will be, the more data you are returning the old way, whereas the new way, you are barely adding anything at all to the data coming back. In the long run, you will benefit significantly from the template way of doing things.

Changed the oldway file:

1
2
3
4
5
6
7
8
// from
...
<li itemprop="stuff">
...
// to
...
<li itemprop="stuff" id="item_<?php echo $itemCount; ?>">
...

Changed the template file:

1
2
3
4
5
6
7
8
9
10
11
12
// from
...
<li itemprop="stuff">
...
// to
...
<li itemprop="stuff" id="item_[[id]]">
...
// and added this line to our array of data
...
'id' => $itemCount,
...

Minor changes, HUGE difference. The new results are in, and the new way has gone up to 268 bytes, while the old ways have gone up to 353 bytes. Now we’re at 31.7% increase which goes to show you that we went from just under 30% difference to 31.7% (almost a 2% increase in bandwidth, just from a single change). This might be nothing when considering the small size of data, but for multi million user websites this number can be real significant. And it separates your code better.

Yes, you will use up more space initially when loading the templates. About 115 bytes more, but in the long run, there are greater benefits.

OK Maya adding web design services…

I’ve been asked a lot lately to do websites for several of my friends. So, I figure, I already know how to make websites, why no help them out? I will keep everyone posted on the website I will be building. Meanwhile, visit the Portfolio page to see all, well, most of my current projects.

Want pricing? Consider the following. No two websites are ever the same. So, no pricing is ever the same. But, I did come up with a complex plan of showing you a simple table of prices that can keep it affordable for you and keep food on my table. Check out the pricing table here.

It’s-a me, Mario!

Since I absolutely love the Super Mario Brothers, I couldn’t bare the thought of not upgrading an old classic to the power of HTML5. Am I saying that I’ll re-create the entire game here? No… probably not. But, it’s nice to know that with today’s technology, you can come pretty darn close, and sometimes, even surprise yourself.

Taken from the basic Mario where I had a jumping block on a white background, I think you’ll find it refreshing to see Mario re-evolve in the web world, and have this game be playable on any device eventually. That’s my goal.

Successfully completed the “framework”

The reason I put it in quotes is because it’s not really a framework. It’s an open ended solution for anyone that wants a working website out of the box, ready with an admin section, credentials for admin and users, search based on parameters and zip code geo locations, and pagination.

So, basically, what inspired me to scrap what I had and redo everything from scratch, and go back to the basics was the idea of too much complexity. I was digging myself deeper and deeper into my own code, limiting myself to certain rules, when I know that PHP should never be limited to anyone’s design.

So, I came up with Clean PHP, read about it here:

http://okmaya.com/clean-php/clean-php-step-1/

This is the first time in my life that I feel reassured that I can really program, and anyone that claims that OOP belongs to web development and it’s crucial, is fooling themselves.

I have nothing against OOP in its place, like console games and desktop applications, but web dev is completely different. Apples and oranges.

Read up on the clean php pages and tell me I’m wrong. But make sure you read it first. Let’s look at it this way:

OOP for console games:

  1. Game Loads (takes some games 5 minutes to create objects in memory)
  2. Those objects are in the game for the entire life of the program, or level, that’s why you see loading bars at the start of every level.

OOP For websites:

  1. Now imagine coming to a website where you have to wait even 30 seconds for every page to load because it has to build objects. Just doesn’t make any sense.
  2. Why build objects on every page load, when all the objects are going to be gone once the page is loaded anyway?
  3. It’s like building a stock car at the start of every race only to completely take it apart at the finish line. Pointless.

Anyway, enough of my ramblings. I’m proud of the work I’ve put into this little package. I say little because at less than 80K, it kicks the crap out of any MVC OOP Framework out there.

  • Note to OOP Web Devs. Stop being lazy and learn to actually program. ;)

New look and feel

I thought I would go back to the basics. I don’t like messing around with too many templates, styles, etc. Although, if I put my mind so it, I could do some layout and design. Just checkout my video site at http://twomartinis.com. Also, http://actingshowcase.com.

Anyway, new look and feel, and I’m going to also rework the pages to give a clearer understanding of what I’m doing with this site. I’m all about keeping things simple. I believe in the KISS rule. (Keep It Simple, Stupid).

Enjoy browsing.

Framework maturing

The current framework is being used in an application inspired by my son. It seems to hold up well. One of the reasons this MVC framework is better is because it uses controllers at the model and view level.

Pre-thoughts…

Just remember, we’re building a website. Which means that each webpage is its own island. Web pages are supposed to be script, not objects. We’re not developing a desktop application. So, with that said, remember, we’re building this procedurally.

First, the .htaccess file. This is the very first entry point in every page. We need to specify some routing. Basically, if the file exists, we do not reroute. We use the existing page. If the file doesn’t exist, we try to route. Our first step in the controller part of the website.

1
2
3
4
# Page redirect - if page doesn't exist, output URL as querystring
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php?route=$1 [L]

Second, the index.php file explained. This is our second hit as we’re attempting to render our page, whatever the page may be.

1
2
3
4
// Basic session start
session_start();
// load in your database connections and other common functions
require_once( $_SERVER['DOCUMENT_ROOT'].'/helpers/functions.php' );

The configurations in the index.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Currently our configurations are set in an array. We can easily move this to another file.
$_config = array();

$_config['site_domain'] = 'http://'.$_SERVER['SERVER_NAME'];
$_config['section'] = '';
$_config['showadminheadercontent'] = true;
// we use the page config variable to determine the page we're requesting.
// If it's blank, we're obviously grabbing the index page.
$_config['page'] = 'index';
// Same concept as above, a pagelet is a sort of a modular page.
// If the pagelet is not requested in the URL, we set it as "main" for every page.
// We use this in order to grab different pages or views, or to determine what
//   files we need to request.
$_config['pagelet'] = 'main';
...

The router in the index.php file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// This is where we get the router as passed in by our .htaccess file.
if (isset($_GET['route'])) {
    // a simple explode to get all of our values from the URL.
    // The format of the incoming URL will always be /part1/part2/part3/etc...
    $route = explode("/",$_GET['route']);

    // we check to see if our route contains anything in the first part.
    if (isset($route[0])) {
        // if we have an admin section, this is where we would check for that.
        if ($route[0] == 'admin') {
            // This means that we're in the admin section. So, we can set this in our configuration.
            $_config['section'] = '/admin';
        } else {
            $_config['section'] = '/';
        }
    }
}

You can continue with the rest of the routing the same way. $route[1] can be your page call, $route[2] can be an action call, and $route[3] and beyond can be variable values passed along.

You can also set your $_config['page'] as $route[0] or $route[1] depending on if you’re in the admin section or not. We do this in order to store the value in ONE variable instead of the $route[0] or $route[1] variable, and constantly use a conditional to determine the page we’re on.

Next step in the index.php file is the models. We want to load the models after we’ve gathered all information required. If you want to add a “language” setting to the site, do it before the models.

1
2
3
4
5
6
7
8
9
10
// define your model name here.
// the folder structure for models is: /models/&lt;section&gt;/&lt;page&gt;_model.php
$model_name = "/models".$_config['section'].'/'.$_config['page']."_model.php";
if (is_file($_SERVER['DOCUMENT_ROOT'].$model_name)) {
    $_SESSION['error'] = '';
    require_once($_SERVER['DOCUMENT_ROOT'].$model_name);
} else {
    $_SESSION['error'] = "Model $model_name not found.&lt;br&gt;";
    echo '&lt;div style="border:1px solid #f00;"&gt;'.$_SESSION['error'].'&lt;/div&gt;';
}

Our models are based on a folder structured mentioned in the code:

1
/models/
/ _model.php so if your URL looks something like this:

http://website.com/info

There will be an attempt to load the model: /model/info_model.php

If that model does not exist, an error will display.

Following the next step, it’s time to write some HTML out to the page. This is where the Doctype, html, head, body tags are send to the page for rendering.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en-US">;
    <head>
        <!--[if IE]><link rel="stylesheet" href="/css/main-ie.css" type="text/css" /><![endif]-->
        <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
        <link rel="stylesheet" type="text/css" href="/css/site_<?php require_once($_SERVER['DOCUMENT_ROOT'].'/helpers/combine_css.php'); ?>.css">
        <link rel="stylesheet" type="text/css" href="/css<?php echo $_config['section']; ?>/main.css">
        <?php
       if ( function_exists ("loadMoreCss") ) {
           loadMoreCss();
       }
       ?>
    </head>
    <body>

Notice several things above. We’ve added an ie css link for those of you that need to tweak css for IE. This section is where you load your CSS ONLY, do not attempt to load any javascript. Javascript will be taken care of in the footer.

Another thing to notice was that I used a CSS combiner to combine all of my common CSS, like jQuery UI CSS, Fancybox CSS, and other standard CSS that I use on all my projects.

Also notice that loadMoreCss() function. This is in case your page will require additional CSS to be rendered, we don’t want to include it EVERY page on our site.

All of the above should be placed in the loadHeader() function. Don’t forget to global your $_config array.

The body will be explained in a different post. I will also make this tutorial available in the pages section.