Tag Archives: Web Development

Using WordPress For Web Application Development: Available Features, Part 7: Caching

When it comes to building web applications, one of the most important things that we have to constantly be mindful of is performance.

As they say, performance is a feature.

And regardless of if you’re a designer, developer, or a user, you know this intuitively to be true: When it comes to applications, we hate waiting. We get frustrated when things don’t perform fast enough, or we have to wait longer than we believe that we should.

To that end, most modern web development frameworks make it possible to implement some type of caching through the use of certain APIs, and WordPress—though a foundation—is no different.

So as we continue our discussion on why WordPress is a viable option for serving as a foundation in web application development, we’ll take a look at the APIs that are provided by the core application, how they work, how we can leverage them to our advantage, and how performance can be enhanced even more by additional caching plugins.

Why Is Caching Important?

In short, caching is important because it allows us to store data that is frequently retrieved in a place in memory so that it can be quickly retrieved.

When you look at this at a larger scale, this becomes increasingly evident when multiple users are viewing a site. By that, I mean that if a single person—or a very small number of people—hit a website, and the site has its data stored in a database, then each time a page is loaded, then that information must be retrieved from the database, inserted into the page, and then returned to the user.

If a level of caching is instituted, then calls to the database won’t have to be made as frequently. Instead, the information can be pulled from an area in memory that results in faster retrieval, and thus faster page load times.

We’ll get into the technical details of this a bit more later in the article.

What About Plugins?

If you’ve been using WordPress for a significant amount of time, then you’re likely familiar with a number of caching plugins that are available.

These are no doubt great solutions to speeding up your web site and/or web application, but it does raise the question: If plugins are available to do this, then why should we worry about it?

It’s a valid question, to be sure, but the plugins can only do so much work on their own.

Developers can structure their applications in such a way that they not only perform well without caching mechanisms, but will also be greatly enhanced by said caching plugins.

By that, I mean that these caching plugins look for data to be stored in a certain location by themes and applications, and if we can programmatically do that within the context of our own work, then the plugins will result in even greater performance.

After we take a look at the APIs that we have available, we’ll revisit this topic to see howthey enhance performance of caching plugins later in the article.

The Transients API

In order to introduce a our first level of caching into the application, we need to take advantage of WordPress’ Transients API. First, note that the official definition of the a transient is “something that exists only for a short amount of time.”

Just as defined in the Codex:

[The Transient API] offers a simple and standardized way of storing cached data in the database temporarily by giving it a custom name and a timeframe after which it will expire and be deleted.

But what does this mean exactly? After all, the data is still being stored in the database, so why is this any better than keeping data stored in any other database table (such as the wp_options table?)?

Once we revisit the discussion on caching and plugins, we’ll talk more about this in more detail.

Setting Transients

Setting a transient value is actually really easy, and it’s much like storing data in the options table.

Specifically, you need a key value that will uniquely identify the data, and then you need a value to be associated with that key. You also need an expiration time (in seconds) to keep the data in the table before refreshing it.

So let’s say that we want to store the current user’s name as the last—or most recent—user active on the site. We can do this by taking advantage of thewp_get_current_user() function.

First, we’ll set the value like this:

set_transient( 'most_recent_user', wp_get_current_user()->user_login, 12 * HOUR_IN_SECONDS )

Here, notice a couple of things:

  • I’m identifying the most recent user in the system as the current user who was logged in, and we’re storing it for 12 hours.
  • Note that the HOUR_IN_SECONDS constants is something that was introduced in WordPress 3.5. A full list of the constants are available here.

Though this is how we go about setting a transient, this still doesn’t account for how we can manage transients if they don’t exist, or if they already exist.

We’ll cover that more a bit later in the article.

Retrieving Transients

When it comes to retrieving transients, it’s very similar to retrieving things such as meta data or options. By that, I mean that we simply need to know the key by which to retrieve the information.

So in keeping consistent with the example above, we can retrieve the most recent user of the application with the following call:

get_transient( 'most_recent_user' );

This will obviously return whatever type of information that you stored, or if the transient has expired—that is, over 12 hours have passed—then the function will return the boolean value of FALSE.

This is key to remember especially when you’re attempting to read cache values, and then needing to grab them from another data source should they not be available in the transient store.

We’ll take a look at a complete example of doing this before the end of the article.

Deleting Transients

Finally, should you need to delete a transient either to remove it completely it, or to remove it before its defined expiration in order to replace it with another value, then you’d simply use the following function:

delete_transient( 'most_recent_user' );

Additionally, this function will return FALSE if the deletion of the transient value is not successful; otherwise, it will return FALSE.

Expiring Transients

When it comes to setting times for cache values to expire, there are a number of ways that make it easier to set values rather than music basic integer manipulation.

For example, MINUTE_IN_SECONDS is much easier to use than 60 especially when multiplying it by, say, minutes, hours, or days.

And as of WordPress 3.5, several constants have been added to the core application that make these calculations much easier to read.

Namely:

  • MINUTE_IN_SECONDS
  • HOUR_IN_SECONDS
  • DAY_IN_SECONDS
  • WEEK_IN_SECONDS
  • YEAR_IN_SECONDS

Much easier to use, to read, and to write, isn’t it?

A Complete Example of Using Transients

At this point, I think it’s important to look at how we can go about setting up transients start with storing a value in the options table.

Here’s the order in which we’ll go about doing this:

  1. We’ll save an option in the wp_options table.
  2. Next, we’ll check to see if the value exists in the cache.
  3. If the value does exist in the cache, we will delete it; otherwise, we will add it.

Then, in the second half of the code, we’ll do the following:

  1. We’ll try to retrieve a value function the cache.
  2. If the value exists in the cache, we’ll fall back to the options table; however, if the value does exist, then we’ll use it.

With that said, let’s take a look:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$username = wp_get_current_user()->user_name;
add_option( 'most_recent_user', $username );
// Check to see if the value exists in the cache
if ( FALSE !== get_transient( 'most_recent_user' ) ) {
    // If it does, we'll delete it...
    if( delete_transient( 'most_recent_user' ) ) {
        // ...and store the most recent user for a maximum of one minute
        set_transient( 'most_recent_user', MINUTE_IN_SECONDS );
    } else {
        // The deletion was unsuccessful, so log the error
    }
}
// Now try to read the value from the cache.
if ( FALSE !== ( $username = get_transient( 'most_recent_user' ) ) {
    // Since it doesn't exist, then we'll read it from the option's table
    $username = get_option( 'most_recent_user' );
    // And then we'll update the cache
    set_transient( 'most_recent_user', $username, MINUTE_IN_SECONDS );
}

Note that this example is not complete—it could be refactored to be a bit cleaner, and the code should be abstracted into functions that are more relevant to the application, but the purpose of this code is to show how to handle conditional logic, options, and transients.

How Does This Fit With Plugins?

Now, with all of that said, we can revisit the question as to how using transients can improve performance within plugins.

As we previously mentioned:

After we take a look at the APIs that we have available, we’ll revisit this topic to see how they enhance performance of caching plugins later in the article.

With that said, caching and the WordPress database has to do with the location of the data in the database.

Since transients are stored in a separate location than the rest of the data, plugins—such as a memcached-based plugin, for example—will look for data where transients are stored, then load the data into memory from that location.

Thus, when the data is requested, it will be retrieved from memory. If the data doesn’t exist, then it will be retrieved from the database.

On top of that, if the programming is done correctly, when data fails to be read from the cache and is retrieved from the database, it will be inserted back into the cache so that the next time it is retrieved it will be available in memory.

Finally, the key thing to note about transient information is that it has a period of expiration. This means that data will only be stored in this area of the database for a specific amount of time.

To that end, we need to account for that. This means that whenever we’re looking to retrieve transients, we need to make sure they exist. If they don’t, then we’ll pull them from where they are located, and then store them in the proper location.

Custom Queries

At this point, we’ve covered a lot of ground of the features that WordPress offers as it relates to a foundation for web application development.

But we’ve got one last major component to cover and that’s how to deal with custom queries.

Sure, there are some great APIs as it relates to running queries designed for WordPress specific purposes—like WP_Query and WP_User_Query, but we’ll also take a look at some of the native facilities that allow us to write custom queries against the database using defined WordPress objects as well as methods that allow for proper data sanitization.

But we’ll cover all of that and more of that material in the next article.

JavaScript Animation That Works (Part 2 of 4)

In the last post, we introduced the idea of spriting, an easy way to animate in JavaScript that works in all browsers. We also walked through how to set up the sprite as a background image for a div and then use a line of JavaScript to change the background position to make it appear as if the image has moved.

In this post, we will use this technique to animate both running and jumping motions. In order to create the animation, we will need to quickly change the background position at a regular interval. Take a look again at the sprite we are using.

javascript-spriting-j

Meet J, the mascot for my company, Joust Multimedia.

In our example, we have ten total images: one of J standing facing right, three of J running to the right and one of J jumping while facing right (with the same number of each frame facing left). Let’s start with making him run to the right. In order to make our image look like it is running, we will need to do two things: change the sprite to a different image and move the div towards the right.

Running to the Right Animation

We certainly won’t want to be stuck clicking different buttons to cycle through the sprites, so we will need to create some functions that do this automatically.

For our running function, we want to:

  1. Move the div towards the right slightly
  2. Move to the next frame of animation
  3. Pause for a fraction of a second (to preserve the “persistence of vision” illusion)
  4. Loop the function again

Fortunately, there is an easy way to loop with functions. A native command in JavaScript called setTimeout will allow us to create a timed delay, after which we will call the function again (from inside the function).

1
2
3
4
5
6
7
function run_right(){
  // Move slightly to the right ...
  // Change to the next frame of animation ...
  // this will call 'run_right' again after 200 milliseconds
  setTimeout(function(){run_right();}, 200);
}

So now we have a function that will call itself again five times a second (which will be fast enough to create animation for our purposes). Remember here that browsers are not terribly accurate with their timers. You can specify timing to the millisecond, but that doesn’t mean your script will run at that timing exactly!

Our next problem to tackle is how is our function going to know which sprite to change to? In our example, we will need to cycle back and forth through our three images (to have four total frames of animation). To do this, we are going to pass our function a bit of information to tell it which slide to switch to. Once in the function, we will do a test that will check which slide we should be on, then switch the background position to the correct sprite. When we call the function again, we will pass the next slide as the argument.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
function run_right(slide){
  // Move slightly to the right ...
  switch (slide){ // this switch statement checks for different possibilities for 'slide'
    case 1: // if 'slide' equals '1' ...
      document.getElementById('j').style.backgroundPosition = "-40px 0px";
      setTimeout(function(){run_right(2);}, 200);
      break;
    case 2: // if 'slide' equals '2' ...
      document.getElementById('j').style.backgroundPosition = "-80px 0px";
      setTimeout(function(){run_right(3);}, 200);
      break;
    case 3: // if 'slide' equals '3' ...
      document.getElementById('j').style.backgroundPosition = "-120px 0px";
      setTimeout(function(){run_right(4);}, 200);
      break;
    case 4: // if 'slide' equals '4' ...
      document.getElementById('j').style.backgroundPosition = "-80px 0px";
      setTimeout(function(){run_right(1);}, 200);
      break;
  }
}

And now when we call the function for the first time, we will need to make sure we pass the starting slide.

1
<input type="button" value="Run Right" onclick="run_right(1);" />

Similarly, to move our div to the right slightly, we can pass the initial left attribute of thediv, then move the div slightly each time the function is called.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function run_right(slide, left){
  
  left = left + 15; // Increase his left attribute by 15px
  document.getElementById('j').style.left = left+"px";
  
  switch (slide){ // this switch statement checks for different possibilities for 'slide'
    case 1: // if 'slide' equals '1' ...
      document.getElementById('j').style.backgroundPosition = "-40px 0px";
      setTimeout(function(){run_right(2, left);}, 200);
      break;
    case 2: // if 'slide' equals '2' ...
      document.getElementById('j').style.backgroundPosition = "-80px 0px";
      setTimeout(function(){run_right(3, left);}, 200);
      break;
    case 3: // if 'slide' equals '3' ...
      document.getElementById('j').style.backgroundPosition = "-120px 0px";
      setTimeout(function(){run_right(4, left);}, 200);
      break;
    case 4: // if 'slide' equals '4' ...
      document.getElementById('j').style.backgroundPosition = "-80px 0px";
      setTimeout(function(){run_right(1, left);}, 200);
      break;
  }
}

And when we initially call the function, we need to make sure we pass the current left position of our div.

1
<input type="button" value="Run Right" onclick="run_right(1, document.getElementById('j').offsetLeft);" />

Stopping the Animation

So, now we have a function that, when called, will animate J to run to the right. Unfortunately, we have no way to stop it. First of all, we will need to make the function stop calling itself if J runs to the edge of our stage. To do that, every time the function runs, we will check an if statement to see if J has room to keep running. If so, we will run the function like normal. If not, we will stop calling the function and return him to the standing sprite.

1
2
3
4
5
6
7
8
function run_right(slide, left){
  // If we can add 15 pixels to the left and have J's right edge not be at the stage's right edge ...
  if ((left + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)){
    // We have room! Continue like normal here
  } else { // if we are on the right edge, we need to stop calling the function and return to standing
    document.getElementById('j').style.backgroundPosition = "0px 0px";
  }
}

Finally, we will want to have a way to stop the function, when needed. We can set thesetTimeout() command to a variable, then stop it with the clearTimeout()command. In order to do this, we will need to declare that variable outside of the function, so that we will be able to refer to it later. For now, we will declare it as a global variable. This is terrible coding practice, but we will correct this in the next post. This is what our function looks like.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var timer;
function run_right(slide, left){
  if ((left + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)){
    left = left + 15; // Increase his left attribute by 15px
    document.getElementById('j').style.left = left+"px";
  
    switch (slide){ // this switch statement checks for different possibilities for 'slide'
      case 1: // if 'slide' equals '1' ...
        document.getElementById('j').style.backgroundPosition = "-40px 0px";
        setTimeout(function(){run_right(2, left);}, 200);
        break;
      case 2: // if 'slide' equals '2' ...
        document.getElementById('j').style.backgroundPosition = "-80px 0px";
        setTimeout(function(){run_right(3, left);}, 200);
        break;
      case 3: // if 'slide' equals '3' ...
        document.getElementById('j').style.backgroundPosition = "-120px 0px";
        setTimeout(function(){run_right(4, left);}, 200);
        break;
      case 4: // if 'slide' equals '4' ...
        document.getElementById('j').style.backgroundPosition = "-80px 0px";
        setTimeout(function(){run_right(1, left);}, 200);
        break;
    }
  } else {
    document.getElementById('j').style.backgroundPosition = "0px 0px";
  }
}

And we can create another function to stop the running timer and return the sprite to the standing image.

1
2
3
4
function stop_running(){
  document.getElementById('j').style.backgroundPosition = "0px 0px";
  clearTimeout(timer);
}

Running to the Left Animation

Now by borrowing the code from our run_right function, we can create another function to make a run_left function, with just a few modifications.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function run_left(stage, left){
  if ((left - 15) > 0){
    left = left - 15;
    document.getElementById('j').style.left = left+"px";
    switch (stage){
      case 1:
        document.getElementById('j').style.backgroundPosition = "-40px -50px";
        timer = setTimeout(function(){run_left(2, left);}, 200);
        break;
      case 2:
        document.getElementById('j').style.backgroundPosition = "-80px -50px";
        timer = setTimeout(function(){run_left(3, left);}, 200);
        break;
      case 3:
        document.getElementById('j').style.backgroundPosition = "-120px -50px";
        timer = setTimeout(function(){run_left(4, left);}, 200);
        break;
      case 4:
        document.getElementById('j').style.backgroundPosition = "-80px -50px";
        timer = setTimeout(function(){run_left(1, left);}, 200);
        break;
    }
  } else {
    document.getElementById('j').style.backgroundPosition = "0px -50px";
  }
}

Jumping Animation

Finally, we need to create a jump function. We will pass two arguments to this function, one that will track whether the div is currently moving up or down and another that will track the current top attribute of the div. Between the two, we will determine which direction the div needs to move next, and how far (we will move the div less distance near the arc of the jump to simulate acceleration with gravity).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function jump(up, top){
  /*
   * We change J to his jumping sprite ...
   */
  document.getElementById('j').style.backgroundPosition = "-160px 0px";
  /*
   * Here, we need to decide whether he should be traveling up or down...
   */
  if (up && (document.getElementById('j').offsetTop > 20)){
    // if he is currently moving up, and he is more than 20 pixels from the top of the stage ...
    top = top - (top * .1); // This gives us a slight arc in the jump, rather than a constant movement like running
    document.getElementById('j').style.top = top+"px"; // Change his position
    timer = setTimeout(function(){jump(up, top);}, 60); // Then call the function again
  } else if (up) {
    // if he is currently moving up, but he is almost at the top of the stage and needs to come back down...
    up = false; // we switch the 'up' variable so he will be falling in the next loop
    timer = setTimeout(function(){jump(up, top);}, 60);
  } else if (!up && (document.getElementById('j').offsetTop < 115)){
    // if he is moving down, but is more than 5px from the ground, he will continue to fall...
    top = top + (top * .1); // His fall will slightly accelerate
    document.getElementById('j').style.top = top+"px";
    timer = setTimeout(function(){jump(up, top);}, 60);
  } else {
    // If he is moving down, and he is within 5px of the ground...
    document.getElementById('j').style.top = "120px"; // Place him on the ground
    document.getElementById('j').style.backgroundPosition = "0px 0px"; // return to standing sprite
    // We do not call the loop anymore since he is standing still at this point
  }
}

Now we can put all four of our functions into buttons and have a working prototype of a running and jumping animation! Please check out the source code for this page with comments and download the sprite sheet that I used, if you’d like.

Conclusion

Now, although we have a working prototype here, you may notice it is a little buggy. When you click on more than one button at a time, the script will try to run both at once. Or, if you click the jump button again on the way down, J will continue to fall forever. Also, as I mentioned earlier, we have global variables in our script, which means it might be difficult to add this code into an existing page without crashing other JavaScript (which is also why I didn’t try to run this code within this blog page). In our next post, we will clean up all of these bugs and talk about the concept of encapsulation and why it is important to write good code in the real world.

Create a Collect-the-Pieces Game with Corona

In this tutorial, I will show you how to create a collect-the-pieces game using the Corona SDK and the Lua programming language. We will explore how to use touch controls and events, create shapes using the graphics API, and we will also make use of physics collisions and timers. Let’s get started.

1. Application Overview

In this game, the player will be able to control a puck on the screen to collect other pieces with the same color. The player has only a limited time to collect as many pieces as possible. If the player touches a piece from another color, the game is over.

App Overview
This application uses the Graphics 2.0 Library. If you’re using an older version of the Corona SDK, you may run into problems. Consult the migration guide for more information.

In this project you will learn the following skills:

  • physics collisions
  • create text fields
  • user timers and images
  • how to use touch controls and events
  • create shapes using the new Graphics API

2. Target Device

Target Device

The first thing we have to do is select the platform we want to run our application on. This enables us to choose the correct sizes for the artwork that we’ll use.

The iOS platform has the following requirements:

  • iPad 1/2/Mini: 1024px x 768px, 132 PPI
  • iPad Retina: 2048px x 1536px, 264 PPI
  • iPhone/iPod Touch: 320px x 480px, 163 PPI
  • iPhone/iPod Retina: 960px x 640px, 326 PPI
  • iPhone 5/iPod Touch: 1136px x 640px, 326 PPI

Since Android is a more open platform, there are many devices and possible resolutions. A few of the more common ones are listed below:

  • Asus Nexus 7 Tablet: 800px x 1280px, 216 PPI
  • Motorola Droid X: 854px x 480px, 228 PPI
  • Samsung Galaxy SIII: 720px x 1280px, 306 PPI

In this tutorial, we’ll be focusing on the iOS platform and the iPhone and iPod Touch in particular. However, the code used in this tutorial can also be used for the Android platform.

3. Interface

Interface

We’ll use a simple and friendly interface with multiple shapes, buttons, bitmaps and more. The artwork for the interface can be found in the source files of this tutorial.

4. Export Graphics

Export Graphics

Depending on the device you’ve selected, you may need to convert the graphics to the recommended resolution (PPI), which you can do in your favorite image editor. I used the Adjust Size… option in the Tools menu of the Preview application on OS X. Remember to give the images a descriptive name and save them in your project folder.

5. Application Configuration

We’ll use a configuration file, config.lua, to make the application go full screen across devices. The configuration file shows the original screen size and the method used to scale the content in case the application is run on a different resolution.

1
2
3
4
5
6
7
8
9
application =
{
    content =
    {
        width = 320,
        height = 480,
        scale = 'letterbox'
    },
}

6. main.lua

Let’s write the actual application. Open your preferred Lua editor. Any plain text editor will work, but it is recommended to use a text editor that has syntax highlighting. Create a new file and save it as main.lua in your project folder.

7. Code Structure

We’ll structure our code as if it were a class. If you’re familiar with ActionScript or Java, you should find the project structure familiar.

01
02
03
04
05
06
07
08
09
10
11
Necessary Classes
Variables and Constants
Declare Functions
    constructor (Main function)
    class methods (other functions)
call Main function

8. Hide Status Bar

1
display.setStatusBar(display.HiddenStatusBar)

This code snippet hides the status bar. The status bar is the bar at the top of the device’s screen that shows the time, signal, and other indicators.

9. Default Anchors

Setting the display’s default anchors is useful if you’re porting an application from the previous Graphics library, that is, the projects you’ve created with previous version of the Corona SDK. Since the release of the Graphics 2.0 library, the reference point of every image has changed from its top-left to its center. To change this in every image that you use in your project, we can invoke the setDefault method and pass a value from 0.0 to 1.0, with 0.0 being the left if you change the x anchor and the top if you change the y anchor.

1
2
display.setDefault('anchorX', 0)
display.setDefault('anchorY', 0)

10. Import Physics

We’ll be using the physics library to handle collisions. Import and start the library using the code snippet shown below.

1
2
3
4
-- Physics
local physics = require('physics')
physics.start()

11. Background

Background

A simple background for the application’s user interface. The code snippet below draws the background to the screen.

1
2
3
-- Graphics
-- [Background]
local gameBg = display.newImage('gameBg.png')

12. Title View

Title View

This is the title view. It’s the first interactive screen to appear in our game. These variables store its components.

1
2
3
4
5
6
-- [Title View]
local title
local playBtn
local creditsBtn
local titleView

13. Credits View

Credits View

The credits view shows the credits and copyright of the application. The creditsViewvariable is used to store it.

1
2
3
-- [CreditsView]
local creditsView

14. Score Text Field

Score

We’ll create a text field for showing the player’s score a bit later in this tutorial. We store a reference to this text field in the scoreTF variable.

1
2
3
-- Score TextField
local scoreTF

15. Pucks

Pucks

The pucks in the game are created and distributed randomly on the stage. The pucksgroup will be used to group them so that we can manipulate them easily.

1
2
3
-- Pucks
local pucks

16. Alert

Alert

The alertView variable keeps a reference to the alert view that is displayed when a puck of the wrong color is touched by the player. The alert view will show the player the game is over.

1
2
3
-- Alert
local alertView

17. Sounds

Sounds

We’ll use sound effects to give the game extra character. The sounds that I’ve used in this project were obtained from as3sfxr. You can find the background music on Play On Loop.

1
2
3
4
5
-- Sounds
local bgMusic = audio.loadStream('POL-sky-sanctuary-short.mp3')
local blip = audio.loadSound('blip.wav')
local wrong = audio.loadSound('lose.wav')

18. Variables

The next code snippet lists the variables that we’ll use in the game. The totalPucksvariable stores the number of pucks that are placed on the stage, timerSrc keeps a reference to the game’s timer, and time references the rectangle that shows the remaining time.

1
2
3
4
5
-- Variables
local totalPucks = 20
local timerSrc
local time

19. Declare Functions

We declare the functions as local at the very beginning. In Lua, you can forward declare a function by declaring its name before implementing the function’s body. This makes it easier to keep track of the various functions that we’ll use in this project.

01
02
03
04
05
06
07
08
09
10
11
12
-- Functions
local Main = {}
local startButtonListeners = {}
local showCredits = {}
local hideCredits = {}
local showGameView = {}
local gameListeners = {}
local createPuck = {}
local movePuck = {}
local reduceTime = {}
local alert = {}

20. Constructor

Let’s start by creating a stub implementation for the function that will initialize the game logic, the Main function.

1
2
function Main()
end

21. Add Title View

Next, we draw the title view to the screen and add a tap listener to each button. ThenewImage method is used to load the images and display them on the screen using the positions passed to the function. We also create a group named titleView that serves as a container for the newly created elements.

1
2
3
4
5
6
7
8
function Main()
  titleBg = display.newImage('titleBg.png')
  playBtn = display.newImage('playBtn.png', 220, 168)
  creditsBtn = display.newImage('creditsBtn.png', 204, 230)
  titleView = display.newGroup(titleBg, playBtn, creditsBtn)
  startButtonListeners('add')
end

22. Start Button Listeners

In startButtonListeners, we add the event listeners to the title view’s buttons. When the play button is tapped, we show and start the game. When the credits button is tapped, we show the game’s credits.

1
2
3
4
5
6
7
8
9
function startButtonListeners(action)
  if(action == 'add') then
    playBtn:addEventListener('tap', showGameView)
    creditsBtn:addEventListener('tap', showCredits)
  else
    playBtn:removeEventListener('tap', showGameView)
    creditsBtn:removeEventListener('tap', showCredits)
  end
end

23. Show Credits

In showCredits, we hide the buttons, display the credits, and add a tap listener to hide the credits when the player taps the credits.

1
2
3
4
5
6
function showCredits:tap(e)
  playBtn.isVisible = false
  creditsBtn.isVisible = false
  creditsView = display.newImage('credits.png', -110, display.contentHeight-80)
  transition.to(creditsView, {time = 300, x = 0, onComplete = function() creditsView:addEventListener('tap', hideCredits) end})
end

24. Hide Credits

When the player taps the credits, the view is tweened from the stage and removed.

1
2
3
4
5
function hideCredits:tap(e)
  playBtn.isVisible = true
  creditsBtn.isVisible = true
  transition.to(creditsView, {time = 300, y = display.contentHeight+creditsView.height, onComplete = function() creditsView:removeEventListener('tap', hideCredits) display.remove(creditsView) creditsView = nil end})
end

25. Show Game View

When the player taps the play button to start a new game, the title view is tweened from the stage and hidden. This shows the game view. The game view is the heart of the game. Let’s break the rest of the showGameView step by step.

1
2
3
function showGameView:tap(e)
  transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})
end

26. Score Text Field

We start by creating the score text field as shown below.

1
2
3
4
5
6
7
8
function showGameView:tap(e)
  transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})
  -- TextFields
  scoreTF = display.newText('0', 25, 18, 'Courier', 15)
  scoreTF:setFillColor(15, 223, 245)
end

The newText method accept a number of arguments.

  • The initial text of the text field.
  • The text field’s x coordinate.
  • The text field’s y coordinate.
  • The text field’s font and font size.

On iOS, you have access to a wide range of fonts. On Android there are only three fonts available; Droid Sans, Droid Serif, and Droid Sans Mono.

27. Timer

In the next step, we create the timer’s rectangle shape using Corona built-in vector graphics library. The newRect function creates a rectangle that is 20pt wide, 6pt tall, and it places it in the top-right of the stage. The default color of new shapes is white so we need to change the rectangle’s color by invoking setFillColor and passing in an RGB value. The Graphics 2.0 library doesn’t use values ranging from 0 to 255 for RGB values. Instead an RGB value is expected to range from 0.0 to 1.0.

01
02
03
04
05
06
07
08
09
10
11
12
13
function showGameView:tap(e)
  transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})
  -- TextFields
  scoreTF = display.newText('0', 25, 18, 'Courier', 15)
  scoreTF:setFillColor(15, 223, 245)
  -- Timer
  time = display.newRect(450, 20, 20, 6)
  time:setFillColor(0.05, 0.87, 0.96)
end

A quick and easy approach for converting old RGB value to new values is by dividing the old value by 255. For example, 123 becomes 123/255, which translates to0.48.

28. Pucks

The pucks group stores all the pucks so that we can manipulate them all at once.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
function showGameView:tap(e)
  transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})
  -- TextFields
  scoreTF = display.newText('0', 25, 18, 'Courier', 15)
  scoreTF:setFillColor(15, 223, 245)
  -- Timer
  time = display.newRect(450, 20, 20, 6)
  time:setFillColor(0.05, 0.87, 0.96)
  -- Pucks
  pucks = display.newGroup()
end

29. Start Game

To finish the showGameViewMethod, we install the game listeners and start the background music. By setting the loops parameter to -1, the background music will loop until we tell it to stop.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
function showGameView:tap(e)
  transition.to(titleView, {time = 300, x = -titleView.height, onComplete = function() startButtonListeners('rmv') display.remove(titleView) titleView = nil end})
  -- TextFields
  scoreTF = display.newText('0', 25, 18, 'Courier', 15)
  scoreTF:setFillColor(15, 223, 245)
  -- Timer
  time = display.newRect(450, 20, 20, 6)
  time:setFillColor(0.05, 0.87, 0.96)
  -- Pucks
  pucks = display.newGroup()
  gameListeners('add')
  audio.play(bgMusic, {loops = -1, channel = 1})
end

30. Game Listeners

In showGameView, we call the gameListeners function in which the pucks are created by invoking the createPucks function. We also create a rectangle for displaying the game’s time.

01
02
03
04
05
06
07
08
09
10
11
12
function gameListeners(action)
  if(action == 'add') then
    createPucks()
    timerSrc = timer.performWithDelay(1000, reduceTime, 20)
  else
    for i = 1, pucks.numChildren do
      pucks[i]:removeEventListener('touch', movePuck)
    end
    timer.cancel(timerSrc)
    timerSrc = nil
  end
end

31. Create Pucks

In createPucks, we use a for loop to instantiate the pucks. The number of pucks is stored in totalPucks, which we set to 20 a bit earlier in this tutorial.

A random position is calculated for each puck using math.random. We also usemath.random to help us load a different color from the project’s images. How does this work? We generate a random integer between 1 and 4, and add the result to the name of the image that we want to load. For example, if the random number is equal to3, the game loads an image named puck3.png.

01
02
03
04
05
06
07
08
09
10
11
12
13
function createPucks()
  for i = 1, totalPucks do
    local p
    local rnd = math.floor(math.random() * 4) + 1
    p = display.newImage('puck' .. tostring(rnd) .. '.png', math.floor(math.random() * display.contentWidth), math.floor(math.random() * display.contentHeight))
    p.name = 'p' .. tostring(rnd)
    p:addEventListener('touch', movePuck)
    -- Physics
    physics.addBody(p, 'dynamic', {radius = 12})
    p.isSensor = true
    pucks:insert(p)
  end
end

32. Move Function

We use touch events to let the player move the pucks. When the player touches a puck, it is aligned with the position of the touch, the player’s finger, and is then moved by updating its position. We also add a collision listener to the active puck to detect when the puck collides with another puck. This event listener is removed when the player releases the puck by lifting their finger from the screen.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function movePuck(e)
  if(e.phase == 'began') then
    -- Collision
    e.target.x = e.x - e.target.width/2
    e.target.y = e.y - e.target.height/2
    e.target:addEventListener('collision', onCollision)
  end
  if(e.phase == 'moved') then
    e.target.x = e.x - e.target.width/2
    e.target.y = e.y- e.target.height/2
  end
  if(e.phase == 'ended') then
    e.target:addEventListener('collision', onCollision)
  end
end

33. Timer

The reduceTimer function is in charge of the timer rectangle we created earlier. Every second, the width of the shape is reduced by setting its xScale property and it is removed from the stage when it’s no longer visible. An alert view is shown to the player when the time’s up.

1
2
3
4
5
6
7
8
function reduceTime(e)
  time.xScale = time.xScale - 0.05
  time.x = 450
  if(time.xScale <= 0.2) then
    display.remove(time)
    alert()
  end
end

34. Handling Collisions

The onCollision function is in charge of handling collisions between pucks.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function onCollision(e)
  if(e.other ~= nil) then
    if(e.other.name == e.target.name) then
      audio.play(blip)
      -- Local Score
      local score = display.newText('50', e.other.x, e.other.y, 'Courier New Bold', 14)
      transition.to(score, {time = 500, xScale = 1.5, yScale = 1.5, y = score.y - 20, onComplete = function() display.remove(score) score = nil end })
      -- Remove
      display.remove(e.other)
      e.other = nil
      -- Total Score
      scoreTF.text = tostring(tonumber(scoreTF.text) + 50)
      scoreTF.x = 15
    else
      audio.play(wrong)
      alert('lose')
    end
  end
end

This is what happens when a collision occurs:

  • We first check whether the names of the pucks are the same to see if their color matches.
  • If they have the same color, we play a sound effect.
  • The player’s score is increased by 50 points and the score text field is updated.
  • If the color of the pucks don’t match, a different sound effect is played and the game over alert view is shown to the player.

35. Alert

The alert function is a simple helper function to show an alert view and animate it. We stop the audio after 700 milliseconds to make sure that we can play a sound effect. The game listeners are removed to end the game and we show an appropriate image to the player.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function alert(action)
  timer.performWithDelay(700, function() audio.stop(1) audio.dispose(bgMusic) bgMusic = nil end, 1)
  gameListeners('rmv')
  if(action == 'lose') then
    alertView = display.newImage('gameOver.png', 155, 125)
  else
    alertView = display.newImage('timeUp.png', 155, 125)
    local score = display.newText(scoreTF.text, 225, 160, 'Courier New Bold', 20)
    score:setFillColor(255, 255, 255)
  end
  transition.from(alertView, {time = 300, xScale = 0.5, yScale = 0.5})
  -- Wait 100 ms to stop physics
  timer.performWithDelay(10, function() physics.stop() end, 1)
end

36. Call Main

To start the game, we invoke the Main function as shown below.

1
Main()

37. Loading Screen

Loading Screen

On the iOS platform, the file named Default.png is displayed while the application is launching. Add this image to your project’s source folder, and it will be automatically added by the Corona compiler.

38. Icon

Icon

Using the graphics you created earlier, you can now create a nice icon. The dimensions of the icon size for a non-retina iPhone are 57px x 57px, while the retina version needs to be 114px x 114px. The artwork for iTunes is required to be 1024px x 1024px. I suggest creating the iTunes artwork first and then creating the smaller sized images by scaling the iTunes artwork down to the correct dimensions. There is no need to make the application icon glossy or add rounded corners as this is taken care of by the operating system.

39. Testing in the Simulator

Testing

It’s time to test our application in the simulator. Open the Corona Simulator, browse to your project folder, and click Open. If everything works as expected, you’re ready for the final step.

40. Build

Build

In the Corona Simulator, go to File > Build and select the target device. Fill out the required fields and click Build. Wait a few seconds and your application is ready to test on a device and/or to be submitted for distribution.

Conclusion

In this tutorial we’ve learned about touch listeners, collision detection, and physics, as well as a few other skills that can be useful in a wide number of games. Experiment with the final result and try to modify the game to create your own version. I hope you liked this tutorial and found it helpful. Thank you for reading.

Creating a WordPress Theme From Static HTML: The Footer File

In this series, you’ve been learning how to create a WordPress theme form static HTML.

Up to this point, you have:

  • prepared your markup for WordPress
  • converted your HTML to PHP and split your file into template files
  • edited the stylesheet and uploaded your theme to WordPress
  • added a loop to your index file
  • added meta tags, the wp_head hook and the site title and description to your header file
  • added a navigation menu
  • added widget areas to the header and sidebar.

 

In this tutorial, you’ll finish off the footer.php file by adding the following areas to it:

  • widget areas
  • a colophon
  • the wp_footer hook.

When you’ve done this. you will have a fully functioning theme. Then, in the remaining parts of the series, I’ll show you how to make your theme even better by adding extra template files and featured images functionality.

What You’ll Need

  • your code editor of choice
  • a browser for testing your work
  • a WordPress installation, either local or remote
  • If you’re working locally, you’ll need MAMP, WAMP or LAMP to enable WordPress to run.
  • If you’re working remotely, you’ll need FTP access to your site plus an administrator account in your WordPress installation.

1. Registering Widget Areas for the Footer

Registering widget areas for your footer is very similar to registering them for the header and sidebar which we did in the previous article in this series.

The different is that, in this article, we’re going to register four widget area rather than just one. This means that the theme can have four widgetized areas displayed side-by-side in what’s traditionally called a “fat footer.”

Start by opening your functions.php file. Find the wptutsplus_widgets_init()function and add the following code inside it, below the code for the three sidebars you’ve already registered:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// First footer widget area, located in the footer. Empty by default.
register_sidebar(
    array(
        'name' => __( 'First Footer Widget Area', 'compass' ),
        'id' => 'first-footer-widget-area',
        'description' => __( 'The first footer widget area', 'compass' ),
        'before_widget' => '<div id="%1$s">',
                'after_widget' => '</div>',
        'before_title' => '<h3>',
                'after_title' => '</h3>'
    )
);
// Second Footer Widget Area, located in the footer. Empty by default.
register_sidebar(
    array(
        'name' => 'Second Footer Widget Area',
        'id' => 'second-footer-widget-area',
        'description' => 'The second footer widget area',
        'before_widget' => '<div id="%1$s">',
                'after_widget' => '</div>',
        'before_title' => '<h3>',
                'after_title' => '</h3>',
    )
);
// Third Footer Widget Area, located in the footer. Empty by default.
register_sidebar(
    array(
        'name' => 'Third Footer Widget Area',
        'id' => 'third-footer-widget-area',
        'description' => 'The third footer widget area',
        'before_widget' => '<div id="%1$s">',
                'after_widget' => '</div>',
        'before_title' => '<h3>',
                'after_title' => '</h3>',
    )
);
// Fourth Footer Widget Area, located in the footer. Empty by default.
register_sidebar(
    array(
        'name' => 'Fourth Footer Widget Area',
        'id' => 'fourth-footer-widget-area',
        'description' => 'The fourth footer widget area',
        'before_widget' => '<div id="%1$s">',
                'after_widget' => '</div>',
        'before_title' => '<h3>',
                'after_title' => '</h3>',
    )
);

This registers four new widget areas, each of which has a unique ID and description.

If you open the “Widgets” admin screen now, you’ll see the four empty widget areas ready for you to populate:

creating-wordpress-theme-from-static-html-widgets-screen-before-footer-widgets-added

But you still need to add the widget areas to your footer.php file to make them work properly.

2. Adding Widget Areas to the Footer File

Open your theme’s footer.php file and find this code:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<aside class="fatfooter" role="complementary">
  <div class="first quarter left widget-area">
    <div class="widget-container">
      <h3 class="widget-title">First footer widget area</h3>
      A widget area in the footer - use plugins and widgets to populate this.
    </div><!-- .widget-container -->
  </div><!-- .first .widget-area -->
  <div class="second quarter widget-area">
    <div class="widget-container">
      <h3 class="widget-title">Second footer widget area</h3>
      A widget area in the footer - use plugins and widgets to populate this.
      </div><!-- .widget-container -->
    </div><!-- .second .widget-area -->
  <div class="third quarter widget-area">
    <div class="widget-container">
      <h3 class="widget-title">Third footer widget area</h3>
      A widget area in the footer - use plugins and widgets to populate this.
    </div><!-- .widget-container -->
  </div><!-- .third .widget-area -->
  <div class="fourth quarter right widget-area">
    <div class="widget-container">
      <h3 class="widget-title">Fourth footer widget area</h3>
        A widget area in the footer - use plugins and widgets to populate this.
    </div><!-- .widget-container -->
  </div><!-- .fourth .widget-area -->
</aside><!-- #fatfooter -->

Replace it with the code below:

1
2
3
4
5
6
7
<aside class="fatfooter" role="complementary">
  <div class="first quarter left widget-area"></div><!-- .first .widget-area -->
  <div class="second quarter widget-area"></div><!-- .second .widget-area -->
  <div class="third quarter widget-area"></div><!-- .third .widget-area -->
  <div class="fourth quarter right widget-area"></div><!-- .fourth .widget-area -->
</aside>
<!-- #fatfooter -->

Now save your footer template.

You can now add widgets to your widget areas via the “Widgets” admin screen. I won’t cover this here as we’ve already reviewed you how to do that in the previous tutorial.

3. Adding a Colophon to Your Footer

A colophon is a note at the bottom of the page with small print. It may include copyright information, or company details if your site is for a company, or other similar information. For many WordPress-based sites, many of them include a link that reads “Proudly Powered by WordPress.”

In my colophon, I’m going to add a copyright notice with the date – I’ll use thebloginfo() function to retrieve information about the site.

In your footer.php file, immediately after the closing </footer> tag, add the following code:

1
2
3
4
5
6
7
8
9
</pre>
<section class="colophon" role="contentinfo">
  <small class="copyright half left">
    © 2013
  </small><!-- .copyright -->
  <small class="credits half right">
     Proudly powered by <a href="http://wordpress.org/">WordPress</a>.
  </small><!-- .credits -->
</section><!--.colophon-->

Now if you save your footer file and visit your site, you will see the colophon displayed (as well as the footer widgets):

creating-wordpress-theme-from-static-html-colophon

4. Adding the wp_footer Hook

The final step is to add the wp_footer hook. You may remember that in Part 5 of this series you added the wp_head hook to the header.php file. Both of these hooks are used by plugins and both are essential for any site using your theme to work.

In your footer.php template, before the closing </body> tag, add the following line:

1
<?php wp_footer(); ?>

Finally, save your file.

Summary

The footer template, as well as all of the other template files you’ve created, is now complete. You have a fully functioning theme which you can use to power your sites.

In the next tutorial, I’ll show you how to make your theme even better by adding a template file just for static pages, so that you can display content differently on those to the way it’s displayed on posts or archive pages.

Resources

  • The Widgets API
  • The wp_get_theme() function
  • The wp_footer hookIn this series, you’ve been learning how to create a WordPress theme form static HTML.

    Up to this point, you have:

    • prepared your markup for WordPress
    • converted your HTML to PHP and split your file into template files
    • edited the stylesheet and uploaded your theme to WordPress
    • added a loop to your index file
    • added meta tags, the wp_head hook and the site title and description to your header file
    • added a navigation menu
    • added widget areas to the header and sidebar.

     

    In this tutorial, you’ll finish off the footer.php file by adding the following areas to it:

    • widget areas
    • a colophon
    • the wp_footer hook.

    When you’ve done this. you will have a fully functioning theme. Then, in the remaining parts of the series, I’ll show you how to make your theme even better by adding extra template files and featured images functionality.

    What You’ll Need

    • your code editor of choice
    • a browser for testing your work
    • a WordPress installation, either local or remote
    • If you’re working locally, you’ll need MAMP, WAMP or LAMP to enable WordPress to run.
    • If you’re working remotely, you’ll need FTP access to your site plus an administrator account in your WordPress installation.

    1. Registering Widget Areas for the Footer

    Registering widget areas for your footer is very similar to registering them for the header and sidebar which we did in the previous article in this series.

    The different is that, in this article, we’re going to register four widget area rather than just one. This means that the theme can have four widgetized areas displayed side-by-side in what’s traditionally called a “fat footer.”

    Start by opening your functions.php file. Find the wptutsplus_widgets_init()function and add the following code inside it, below the code for the three sidebars you’ve already registered:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    // First footer widget area, located in the footer. Empty by default.
    register_sidebar(
        array(
            'name' => __( 'First Footer Widget Area', 'compass' ),
            'id' => 'first-footer-widget-area',
            'description' => __( 'The first footer widget area', 'compass' ),
            'before_widget' => '<div id="%1$s">',
                    'after_widget' => '</div>',
            'before_title' => '<h3>',
                    'after_title' => '</h3>'
        )
    );
    // Second Footer Widget Area, located in the footer. Empty by default.
    register_sidebar(
        array(
            'name' => 'Second Footer Widget Area',
            'id' => 'second-footer-widget-area',
            'description' => 'The second footer widget area',
            'before_widget' => '<div id="%1$s">',
                    'after_widget' => '</div>',
            'before_title' => '<h3>',
                    'after_title' => '</h3>',
        )
    );
    // Third Footer Widget Area, located in the footer. Empty by default.
    register_sidebar(
        array(
            'name' => 'Third Footer Widget Area',
            'id' => 'third-footer-widget-area',
            'description' => 'The third footer widget area',
            'before_widget' => '<div id="%1$s">',
                    'after_widget' => '</div>',
            'before_title' => '<h3>',
                    'after_title' => '</h3>',
        )
    );
    // Fourth Footer Widget Area, located in the footer. Empty by default.
    register_sidebar(
        array(
            'name' => 'Fourth Footer Widget Area',
            'id' => 'fourth-footer-widget-area',
            'description' => 'The fourth footer widget area',
            'before_widget' => '<div id="%1$s">',
                    'after_widget' => '</div>',
            'before_title' => '<h3>',
                    'after_title' => '</h3>',
        )
    );

    This registers four new widget areas, each of which has a unique ID and description.

    If you open the “Widgets” admin screen now, you’ll see the four empty widget areas ready for you to populate:

    creating-wordpress-theme-from-static-html-widgets-screen-before-footer-widgets-added

    But you still need to add the widget areas to your footer.php file to make them work properly.

    2. Adding Widget Areas to the Footer File

    Open your theme’s footer.php file and find this code:

    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <aside class="fatfooter" role="complementary">
      <div class="first quarter left widget-area">
        <div class="widget-container">
          <h3 class="widget-title">First footer widget area</h3>
          A widget area in the footer - use plugins and widgets to populate this.
        </div><!-- .widget-container -->
      </div><!-- .first .widget-area -->
      <div class="second quarter widget-area">
        <div class="widget-container">
          <h3 class="widget-title">Second footer widget area</h3>
          A widget area in the footer - use plugins and widgets to populate this.
          </div><!-- .widget-container -->
        </div><!-- .second .widget-area -->
      <div class="third quarter widget-area">
        <div class="widget-container">
          <h3 class="widget-title">Third footer widget area</h3>
          A widget area in the footer - use plugins and widgets to populate this.
        </div><!-- .widget-container -->
      </div><!-- .third .widget-area -->
      <div class="fourth quarter right widget-area">
        <div class="widget-container">
          <h3 class="widget-title">Fourth footer widget area</h3>
            A widget area in the footer - use plugins and widgets to populate this.
        </div><!-- .widget-container -->
      </div><!-- .fourth .widget-area -->
    </aside><!-- #fatfooter -->

    Replace it with the code below:

    1
    2
    3
    4
    5
    6
    7
    <aside class="fatfooter" role="complementary">
      <div class="first quarter left widget-area"></div><!-- .first .widget-area -->
      <div class="second quarter widget-area"></div><!-- .second .widget-area -->
      <div class="third quarter widget-area"></div><!-- .third .widget-area -->
      <div class="fourth quarter right widget-area"></div><!-- .fourth .widget-area -->
    </aside>
    <!-- #fatfooter -->

    Now save your footer template.

    You can now add widgets to your widget areas via the “Widgets” admin screen. I won’t cover this here as we’ve already reviewed you how to do that in the previous tutorial.

    3. Adding a Colophon to Your Footer

    A colophon is a note at the bottom of the page with small print. It may include copyright information, or company details if your site is for a company, or other similar information. For many WordPress-based sites, many of them include a link that reads “Proudly Powered by WordPress.”

    In my colophon, I’m going to add a copyright notice with the date – I’ll use thebloginfo() function to retrieve information about the site.

    In your footer.php file, immediately after the closing </footer> tag, add the following code:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    </pre>
    <section class="colophon" role="contentinfo">
      <small class="copyright half left">
        © 2013
      </small><!-- .copyright -->
      <small class="credits half right">
         Proudly powered by <a href="http://wordpress.org/">WordPress</a>.
      </small><!-- .credits -->
    </section><!--.colophon-->

    Now if you save your footer file and visit your site, you will see the colophon displayed (as well as the footer widgets):

    creating-wordpress-theme-from-static-html-colophon

    4. Adding the wp_footer Hook

    The final step is to add the wp_footer hook. You may remember that in Part 5 of this series you added the wp_head hook to the header.php file. Both of these hooks are used by plugins and both are essential for any site using your theme to work.

    In your footer.php template, before the closing </body> tag, add the following line:

    1
    <?php wp_footer(); ?>

    Finally, save your file.

    Summary

    The footer template, as well as all of the other template files you’ve created, is now complete. You have a fully functioning theme which you can use to power your sites.

    In the next tutorial, I’ll show you how to make your theme even better by adding a template file just for static pages, so that you can display content differently on those to the way it’s displayed on posts or archive pages.

    Resources

Working with NSURLSession: AFNetworking 2.0

In the previous installments of this series, we’ve taken a close look at theNSURLSession API introduced in iOS 7 and OS X Mavericks. Networking on iOS and OS X has become much simpler and more flexible thanks to the NSURLSession API. Does this mean that you should stop using AFNetworking for your networking needs? And what about AFNetworking 2.0, which was introduced a few months ago? In this final installment, I will tell you about AFNetworking 2.0 and how it compares to theNSURLSession API.

Introduction

As Mattt Thompson points out on NSHipsterAFNetworking has become the de facto networking library for Cocoa applications. At the time of writing, the library has surpassed 10,000 stars on GitHub and was forked close to 3,000 times.

If you’re new to AFNetworking and would like to read more about its history and features, then I suggest to read Mattt’s post about AFNetworking 2.0 on NSHipster. In this article, I’d like to focus on two aspects, what is new in AFNetworking 2.0 and how does it compare to the NSURLSession API . The question you should be asking yourself is “Should I still be using AFNetworking with NSURLSession in my toolbox?” That’s the question I plan to answer in this article.

Requirements

Before we take a closer look at what AFNetworking 2.0 has to offer, it’s important to know about the library’s new requirements. It shouldn’t be a surprise that the requirements of AFNetworking 2.0 are stricter than those of AFNetworking 1.x. As its version number indicates, AFNetworking includes breaking changes, which are the result of its new architecture. This also means that migrating a project from AFNetworking 1.x to 2.0 should be done with caution. The migration guide is the ideal place to start if you plan on migrating a project to AFNetworking 2.0.

AFNetworking no longer supports iOS 4.3 and 5. The minimum deployment targets for iOS and OS X are iOS 6 and OS X 10.8 respectively. AFNetworking 2.0 also requires Xcode 5. If you’re still using Xcode 4, this may be a good time to make the transition to Xcode 5.

Solid Foundation

AFURLConnectionOperation

As many of you probably know, AFNetworking is built on top of NSURLConnection andNSOperation, which has proven to be a powerful and elegant combination. The result of this combination is AFURLConnectionOperation, an NSOperation subclass that manages an NSURLConnection instance and implements theNSURLConnectionDelegate protocol. Even though this robust foundation remains unchanged in AFNetworking 2.0, it is supplemented by the NSURLSession API, which I’ll cover in more detail later.

Separation of Responsibilities

In AFNetworking 1.x, the AFHTTPRequestOperation class was in charge of request and response serialization and validation. This is no longer true in AFNetworking 2.0. TheAFHTTPRequestOperation class and its subclasses are no longer directly responsible for serializing and validating requests and responses. This responsibility has been moved to the AFURLRequestSerialization and AFURLResponseSerializationprotocols. Each protocol declares a single delegate method to handle request and response serialization and validation respectively.

To make your life easier, however, AFNetworking 2.0 ships withAFHTTPRequestSerializer and AFHTTPResponseSerializer as well as a number of subclasses for common content types, such as JSON and XML. To see how this works in practice, let’s take a look at an example in which I query the Forecast API. This doesn’t look all that different from how you made a request with AFNetworking 1.x. The main difference is that you’ll be using the AFHTTPRequestOperation class more often. The AFJSONRequestOperation and AFXMLRequestOperation classes are no longer present in AFNetworking 2.0.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/37.8267,-122.423", key]];
// Initialize Request Operation
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:[NSURLRequest requestWithURL:URL]];
// Configure Request Operation
[requestOperation setResponseSerializer:[AFJSONResponseSerializer serializer]];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Process Response Object
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // Handle Error
}];
// Start Request Operation
[requestOperation start];

The AFJSONResponseSerializer class inherits from AFHTTPResponseSerializer and should be used for JSON responses. If you need to process XML responses, thenAFXMLNResponseSerializer will help you out. For other content types, you need to subclass AFHTTPResponseSerializer.

AFHTTPRequestOperationManager

Another major change in AFNetworking 2.0 is the removal of the AFHTTPClient class, which was in charge of talking to web services. The responsibilities of AFHTTPClienthave been split up into a number of classes and protocols. To talk to a web service, you now use AFHTTPRequestOperationManager and AFHTTPSessionManager. Just likeAFHTTPRequestOperationAFHTTPRequestOperationManager andAFHTTPSessionManager delegate serialization of requests and responses to separate objects. Both AFHTTPRequestOperationManager and AFHTTPSessionManager have arequestSerializer and responseSerializer property for this purpose. Let’s revisit the above example to see how this works in practice.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *baseURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/", key]];
// Initialize Request Operation Manager
AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL];
// Configure Request Operation Manager
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
// Send Request
[manager GET:@"37.8267,-122.423" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    // Process Response Object
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // Handle Error
}];

What About NSURLSession?

AFURLSessionManager

The key question when discussing AFNetworking 2.0 in the light of the NSURLSessionAPI is whether we still need AFNetworking. AFNetworking adds a number of convenience classes and methods to the NSURLSession API and this is only possible thanks to the separation of responsibilities I discussed earlier. The most significant improvement that AFNetworking provides on top of the NSURLSession API are theAFURLSessionManager and AFHTTPSessionManager classes.

The AFURLSessionManager helps you manage an NSURLSession object. Even though I love the NSURLSession API, I have to agree with Mattt that its API is incomplete. TheAFURLSessionManager class adds a number of convenience methods that make theNSURLSession API even better. Serialization and validation, for example, are much easier and intuitive with AFNetworking. Just like theAFHTTPRequestOperationManager, instances of AFURLSessionManager have arequestSerializer and responseSerializer property that makes serialization of requests and responses seamless and intuitive.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
NSString *key = @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"https://api.forecast.io/forecast/%@/37.8267,-122.423", key]];
// Initialize Session Configuration
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
// Initialize Session Manager
AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:sessionConfiguration];
// Configure Manager
[manager setResponseSerializer:[AFJSONResponseSerializer serializer]];
// Send Request
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[[manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
    // Process Response Object
}] resume];

I hope you can see the benefit of using AFNetworking in combination with theNSURLSession API. It makes working with the NSURLSession API much more intuitive especially if you’re already used to the way AFNetworking 2.0 separates serialization and validation from the actual task or request operation.

AFHTTPSessionManager

AFNetworking 2.0 also incudes a subclass of AFURLSessionManager,AFHTTPSessionManager, which makes interacting with web services a breeze. TheAFHTTPSessionManager class includes a number of conveniences methods, such asGET:parameters:success:failure: andPOST:parameters:constructingBodyWithBlock:success:failure: that make the migration process from AFHTTPClient to AFHTTPSessionManager easy. Similar methods are also available in the AFHTTPRequestOperationManager class, which I discussed earlier.

Reachability

Reachability is managed by the AFURLRequestOperationManager andAFURLSessionManager classes. When instances of these classes have a validbaseURL, then a reachability manager is automatically instantiated and set up. Of course, it is also possible to explicitly create an instance of theAFNetworkReachabilityManager class.

Icing On The Cake

AFNetworking 2.0 has a number of other features, such as built-in support for SSL pinning and various categories on UIKit classes. Take a look at this example in which I leverage AFNetworking’s category on UIProgressView to update a progress view while downloading a remote image.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// Initialize Request
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cdn.tutsplus.com/mobile/uploads/2014/01/5a3f1-sample.jpg"]];
// Initialize Session Manager
self.sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
// Initialize Download Task
NSURLSessionDownloadTask *downloadTask = [self.sessionManager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
    // Handle Success
} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
    // Handle Failure
}];
[self.progressView setProgressWithDownloadProgressOfTask:downloadTask animated:YES];
[downloadTask resume];

Verdict

If your project doesn’t rely on networking, then you won’t need all the power and convenience that AFNetworking has to offer. As a matter of fact, I think it’s important that every iOS or OS X developer is familiar with NSURLSession and NSURLConnection, because they are key components of the platform.

Even though the NSURLSession API is great and easy to use, the networking APIs provided by the Foundation framework aren’t perfect. As Mattt points out, even theNSURLSession API has a few notable gaps. AFNetworking tries to elegantly fill these gaps. The combination of the NSURLSession API and AFNetworking is a marriage made in heaven. It truly is a joy to use.

I really like the NSURLSession API and I hope I’ve convinced you of its power in this series. However, this doesn’t mean that AFNetworking has become obsolete. In my opinion, AFNetworking is the perfect companion of the NSURLSession API. AFNetworking has matured and it is indeed the best and most robust networking library available. Its modular architecture means that you don’t need to include every class or category it has to offer. You are free to pick and choose from the components that it includes. AFNetworking supports CocoaPods subspecs, which make this process trivial.

Conclusion

I couldn’t be more happy with the second major release of AFNetworking. The library’s modularity and separation of responsibilities is what makes it shine in my opinion. It complements the NSURLSession API so well that you won’t even notice that you’re using AFNetworking. Mattt Thompson and the more than 130 contributors of AFNetworking have done a formidable job. It’s good to be a Cocoa developer.