HTML From Scratch

I am often asked where to find quality tutorials on beginning learning HTML and all that jazz, so I thought I'd make a video! This is the first in a series I call "From Scratch" that aims to teach total newbies how to make web-pages, I hope the video explains it all well enough and you get something from it. As always comment below if you need any help.

You can view the demo of what we create, and also download the finished product below.

View demo
Download files
Next: CSS From Scratch

WordPress: Load more posts on page scroll

Note: This article has been marked for a quality review and will soon be updated.

Although I don't visit archive pages very often, when I do I like it when I don't have to trawl through pages and pages of 10 posts using tiny navigation buttons at the bottom of the page. A great way to prevent this annoyance for your users is to use AJAX to dynamically append posts to the end of your archive list. To do this in WordPress we need to abstract the process of getting the list of posts and then use some Javascript (in out case jQuery aided) magic to load in our content. So lets get started.

First off we need to create a function that we can call to spit out a list of posts. Usually on an archive page we would use the normal WordPress loop to accomplish this, but in our case we need to abstract the loop into a separate function so that we can access it from any file - more specifically our Javascript file. We also need to be able to pass an offset value to this function to make sure we don't load the same posts every time it is called. This function is going to differ slightly depending on your markup for your archive page, but this is how it would look for Tom's Big Box:

function getArchives($count,$offset){
	query_posts('posts_per_page='.$count.'&offset='.$offset);
	
	$posts = array();

	if(have_posts()) : while(have_posts()) : the_post(); 	
		$img = post_image($post->ID);
		$commentsNo = get_comments_number();
		if($commentsNo==0){
			$comments = 'No Responses';
		}else if($commentsNo==1){
			$comments = '1 Response';
		}else {
			$comments = $commentsNo . ' Responses';
		}
		
		$item = '<li id="'. get_the_ID() .'">
			<figure class="vignette left">
				<img src="'. get_bloginfo('template_url') .'/scripts/timthumb.php?src='. $img->src .'&w=180&h=120" alt="'. $img->alt .'" />
			</figure>
			<h3><a href="'. get_permalink() .'">'. get_the_title() .'
			<p class="article-meta left">'. get_the_time('jS M Y',$post->ID) .' ~ '. $comments .'

<p class="extract"> '. get_the_excerpt() .' </p> </li>'; array_push($posts,$item); endwhile; endif; return $posts; }*/

Stick this in your functions.php file, and we can walk through what this code is doing. Firstly the two parameters that we it accepts are $count - which tells our functions how many posts we want, and $offset - to ensure that we don't load the same posts every time our function is called. We then send these parameters to WordPress's query_posts() function which will give us a list of posts. We then set up the $posts array to sold our data and begin iterating through the posts. I created a separate image variable to hold information about each post's image because I don't use WordPress's inbuilt image resizing, this is something which may not apply to you. After that an if statement creates a nice string based on the number of comments per post - this is because the inbuilt functions return only the number of comments or directly outputs to the document - something we don;t want. Then we load our content into the $item variable using whatever markup we need, and finally use array_push() to add our $item variable to the $posts variable, before returning the final $posts variable in its entirety.

Phew! Well that's most of the server-side stuff done, but before we can say goodbye to PHP, we need to do one more thing. We need to create a file to which we will pass our parameters, and that will execute the function we just created, and return the code we need. Don't worry, this is far simpler than the function above, let's take a look at the code:

require( '../../../../wp-load.php' );
$posts = getArchives(20,$_GET['offset'],false); 
foreach($posts as $p){
	echo str_replace("'","'",$p);
}

So, ignoring the first line for a moment, this file simply passes the $_GET['offset'] variable to our newly created function, and then iterates over the output, making sure to replace any single quotation marks to stop it from breaking. "But hang on Tom, what does that first line do?!" I hear you cry, well the first line makes sure we can access the function we just created, and for that matter all the inbuilt WordPress functions, so it is vital that you keep it. You will also need to change the path in the require() statement to ensure it matches the root directory of your WordPress install. Pop the above code in a file called get-posts.php and stick it in your theme's directory. And with that, we can say hasta la vista to PHP, and buongiorno to jQuery (that's right, I'm cultured).

Now, having made sure jQuery is included on your page, paste in the following code:

var halfWay = ($(document).height()/2);
var offset = 20;
var inAction = false;
var reachedEnd = false;

$(document).scroll(function(){
   if($(document).scrollTop() > halfWay && inAction == false){
       inAction = true;
		
       $('.article-list').append($('
').load('http://example.com/wp-content/themes/myTheme/get-posts.php?offset='+offset, function(){ offset = offset + 20; halfWay = halfWay + 1775; inAction = false; })); } });

Lets go through what this does. We have a function that fires whenever the page scrolls, and within that we compare the current scroll amount to half the overall document height, if it is greater (meaning that the user has scrolled more than half way down the page), and the variable inAction (I'll get to that in a moment) is true, it executes the following code. If the conditions are satisfied we then use AJAX to load in some more posts. Now it may appear a rather convoluted way to be doing so, but in my experience this way of handling an AJAX request of this type is the best. So for this method we send a request to our file that we just created in our theme's directory, and pass it the variable offset, when the content is loaded we run the embedded function which increments our offset variable by 20, adds a suitable amount to our halfWay variable. We then reset the inAction variable. This variable is used to prevent a massive build up of requests because of page scrolling, we use it because every time the page scrolls even a pixel, the function is called, so we don't want it to be called 3 times before we have a chance to offset the next post, otherwise we will end up with a huge amount of duplicate posts being loaded in. The conditions in the if statement will stop being satisfied after the last posts are loaded in because our inAction will stay in it's true state forever after one request for no posts means the success() function isn't executed.

And that's it! It might be a good idea to have a loading graphic at the bottom of you page when doing this to give some user feedback, and I would suggest also adding pagination just incase your server stops responding and leaves your users hanging. But aside from that, I think I covered the basics of how to implement the AJAx loading in of content. Oh and by the way, you will now also be able to generate archives anywhere on your site using the function getArchives(), meaning you will write less code in the long run - two birds with one stone!

Elegant URL Rewriting

To me .htaccess files are black magic - one letter wrong and you get internal server errors bouncing around everywhere, so when it came to URL re-writing (more specifically removal of file extensions) I was a little tired of getting "Error 500" messages. But I finally managed to manipulate the dark magic that lyes deep within the realms of the kingdom of .htaccess file, and created a system whereby I made my server pass all URL arguments to a single file to play with. Here's what I did.

Firstly you're going to need to edit your .htaccess file, for my purposes I send all the info to my index.php file like so:

RewriteEngine On

<IfModule mod_rewrite.c>
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

The code above simply ignores the path that was requested, and loads your index.php file. From there we can do implement some logic to decide what it is our users are after. To be able to understand the request we need to find out what the URL is, and to do that we will use some PHP to grab the URL, and then put the contents into an array like so:

$request = explode('/', $_SERVER['REQUEST_URI']); 
$args = array();
	
//Remove empty indexes
foreach($request as $r){
	if(!empty($r)){
		array_push($args, $r);
        }
}		

The above code simply creates an array where each index contains parts of the URL separated by a slash ('/'). We then look for any empty parts of the array to make sure we don't run in to difficulty later on. Now we need to think about when users visit the root directory of our site, when they do our array will be empty, so we need to cater for that by assigning our default page to our array with the following code:

//Allow no parameters
if(empty($args) || $args[0] == 'index.php'){ $args[0] = 'home'; }

Now for the next part we also need to consider page titles to use in out <title> sections, to do that we will look at making the slug more human-readable. We will implement that alongside the code that will deal with actually getting the physical files, and what we will do if a certain file doesn't exist.

if(file_exists($args[0] . '.php')){
	$page = str_replace("-"," ",ucfirst($args[count($args)-1]));
	include($args[0] . '.php');
}else {
	$page = '404';
	include('404.php'); //Keeps URL intact
}

So above we check to see if the file exists, and if it does we set the $page variable to a proper title - this isn't entirely necessary, but I found it useful later on. After that we simply include the file that was requested. But if the file doesn't exists, we include our 404 page to make sure our site doesn't simply throw an error.

Now in my case the included files would then query a database for content, but if you'd like you can do that directly in this file - instead of the include() statement, you could set up a database query there to ask for the page "with title" and go from there.

And with that you should have some fine looking URLs!

Build an uploader for S3

S3 is Amazon's "Simple Storage Service" for hosting content on the web. It allows developers to offload static content to their powerful content delivery network at low cost, to improve site performance. I've used S3 on a number of projects to host content, but one thing that only recently cropped up wad the notion of allowing users to upload their own content to the service from within any given site. To accomplish this I had to use a little bit of everything, including PHP and jQuery. But don't worry, if you don't want to use jQuery, this technique should still apply to other implementations.

As I said we will be using jQuery for this, and more specifically, the fantastic plugin Uplodify - a set of files that will enable simple uploading, and that will handle all the heavy lifting of file manipulation. So go ahead and download/unzip Uplodify, and then stick it on your server. I then used the following standard HTML to display the upload button.

<div id="upload_box">
	<div id="file_upload" name="theFile"></div>
</div>

Having done that, make sure to include jQuery, swifobject.js, and jquery.uplodify.[VERSION].js, and then add the following JS.

<script type="text/javascript">
    $(document).ready(function() {
      $('#file_upload').uploadify({
        'uploader'  : 'uploadify.swf',
        'script'    : 'uploadify.php',
        'folder'    : 'uploads',
        'multi'	: true,
        'fileExt'   : '*.jpg;*.gif;*.png',
        'auto'      : true,
        'buttonImg' : 'button.jpg',
        'width'	: '86',
        'height'	: '28',
        'onSWFReady': function(){ $("#file_upload").show(); },
      });
      
    });
</script>

And that's the basic configuration needed to get Uploadify working. Now we need to enlist the help of a PHP class to enable us to interface with S3. That class allows you to do some pretty advanced stuff, and is a great solution all round for working with S3. In our case you just need to download that that and pop it in the same directory as the file uplodify.php.

And now we are finally ready to add the functionality that we've all been waiting for. Open uplodify.php and change:

move_uploaded_file($tempFile,$targetFile);
echo str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);

to:

$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile =  str_replace('//','/',$targetPath) . $_FILES['Filedata']['name'];

 $fileTypes  = str_replace('*.','',$_REQUEST['fileext']);
 $fileTypes  = str_replace(';','|',$fileTypes);
 $typesArray = split('\|',$fileTypes);
 $fileParts  = pathinfo($_FILES['Filedata']['name']);

 if (in_array($fileParts['extension'],$typesArray)) {
	
	if (!class_exists('S3'))require_once('S3.php');
	
	//AWS access info
	if (!defined('awsAccessKey')) define('awsAccessKey', '[ACCESS KEY]');
	if (!defined('awsSecretKey')) define('awsSecretKey', '[SECRET KEY]');
	
	//instantiate the class
	$s3 = new S3(awsAccessKey, awsSecretKey);

	//move the file
	$s3->putObject($_FILES['Filedata']['tmp_name'], "[BUCKET NAME]", $_FILES['Filedata']['name'], S3::ACL_PUBLIC_READ);


	echo "http://s3.amazonaws.com/[BUCKET NAME]/".$fileName;
 } else {
 	echo 'Invalid file type.';
 }

So what we've done there is replaced the part of the code that previously moved the uploaded file (with the imaginatively named move_uploaded_file() function), with some code to invoke a move to your S3 bucket. As you can see in the code above, the functions require some information that you will need to provide yourself such as your secret key - this can be found by logging in here.

And that's that! As I said above the class can be used for more advanced manipulation of your S3 buckets and account, so do go and explore some of the things you can do with that, and have fun uploading!

Adding subtle user feedback

We all hate waiting for websites to load right? It's annoying to watch images download and wait for Twitter streams to render isn't it? Well it's a fact that 99% of websites have this issue - that is, that load time is about 1 or 2 seconds. Now for companies like Google it isn't an issue, they have enough money to ensure they have sites that load instantly; but for us average folk what can we do? Investing in new and expensive serves often isn't an option, so one method I propose is creating subtle user feedback.

One way to accomplish this is to go all AJAX, instead of letting the browser jump between pages, simply load they pages using Javascript and fade in a loading animation while you do just that. Great, problem solved. Or is it? What about large sites that are already up and running? Is it a good idea to re-write a lot of code? Well while AJAX will provide you with the most control over UX, I propose a slightly different method, details of which follow.

I recently finished work on a site which has a load time of about 1 second - pretty average stuff. But I wasn't happy with just providing the normal experience. I thought about fading/sliding in individual elements when the page had fully loaded (much like Apple now does on it's product pages. But the problem with that is, if done incorrectly, you end up extending the load time of a site, and no matter how nice an effect might look, if it harms the end user-experience, it's best to leave it out (at this point I should say that if you load a page and then send multiple requests for more data, and then fade them in, that makes sense). So I came up with a simple solution - add a loading header graphic. Allow me to elaborate.

Instead of simply loading a page with the normal logo of the site in the header, I load a GIF that looks exactly like the header graphic (minus the text), and once the page has finished loading (courtesy of jQuery), I swap the images out. So what does it look like? Head over to Cooking Pete (shameless plug I know) to see the effect in action.

I used the:

$(document).ready(function(){  });

Function to allow me to detect the fully loaded DOM, and then simply change the src attribute of my header graphic.

And that's it! Adding simple user feedback like that let's your users know that the site is doing something, and doesn't leave them in the dark.

Adding Vignettes to Images with CSS

Vignettes are something we've been able to add to images in Photoshop for many years - it describes the technique of reducing clarity towards the edges of images by reducing things like saturation and brightness, and can often give an image a different quality. It was for that reason that I decided I wanted to use them in my designs, but I certainly didn't want to use images that were pre-composed with the effect, and so decided it would be simple to add them using CSS. What I didn't know, was that there were many things conspiring to prevent me achieving the effect properly. So without further adieu, allow me to share my experience with you.

I first read Trent Walton's article on vignetting and implemented that on the site, but soon realised its shortcomings. Firstly the use of negative z-indexing played havoc with my backgrounds - this is because its fine if you have an all-white background, but if you have an image, it simply throws the picture behind it. And secondly I found myself frustrated with the fact that you couldn't right click and save the image with ease. I also took a look at Chris Coyier's article on the subject, but once again hit a brick wall.

So after a lot of playing around and many alterations I came up with a solution that is the combination of many techniques that I have come across, and the one use on the site today.

My HTML is as follows.

<figure>	
    <img src="path/to/image" alt="Test image" />
</figure>

The class of left simply floats the element to the left, while I use the following CSS to style the rest.

figure {
	position: relative;
	display: block; 
}

	figure.vignette img {
		z-index: 1;
		position: relative;
		display: block;
	}

	figure::before {
		content: "";
		position: absolute;
		top: -1em;
		bottom: -1em;
		left: -1em;
		right: -1em;
	}

	figure.vignette::after {
		position: absolute;
		top: 0;
		bottom: 0;
		left: 0;
		right: 0;
		content: "";
		z-index: 2;
		pointer-events: none;
		width:100%;
		height:100%;
		box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		-webkit-box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		-moz-box-shadow:inset 0px 0px 85px rgba(0,0,0,.5);
		border-radius: 3px;
		-moz-border-radius: 3px;
		-webkit-border-radius: 3px;
	}

So the main styling of the figure element simply makes sure it is visible and sets it's position to relative, as does the styling of the image within it; but it is the code that follows that does all the magic. We use the pseudo ::before and ::after to apply the vignette effect. If you are unfamiliar with those selectors, visit W3's article on the subject. You can increase the intensity of the vignette by altering the box-shadow property to have a less transparent shadow, or bigger radius. You could even have different colours by altering the same property.

And that's it! I haven't found any inherent problems with this technique just yet, and although this method isn't really apply a vignette in the traditional sense, I feel it does a pretty good imitation of it.

Trimming the Fat

In light of the recent redesign of Tom's Big Box I thought I write a post about some of the design choices I made with regard to 'trimming the fat'. I want to look at the attitudes towards certain aspects of websites, and more specifically blogs. In re-designing the site I was constantly asking myself "is this element entirely necessary". Tom's Big Box isn't about showing off my skills as a web designer; it's about sharing (hopefully valuable) content with the community, therefore my re-design was primarily concerned with the creation of a design that best promotes the content of the site.

To use a cliché "content is king" - we all know this and all abide by it - it doesn't matter how good your site looks, without content it's worth nothing. I'm certainly not going to dispute that, but what I will say is that I believe a certain culture has grown up around blogging, which has let to accepted standards. I rarely visit a blog without a sidebar listing monthly archives these days. Most of the time blogs have a great number of features that I believe are entirely superfluous. Why do we need monthly archives, seriously? Think about it. Never have I thought, "I know, I could do with seeing all the posts from March 2010". The only circumstance that would lead to that for me would be the searching of content related to an event occurring in that month. But despite the fact that few people ever use them (if statistics show I'm wrong please prove me wrong), blogs often whack them in the sidebar. I think this type of design by convention is bad. Bloggers feels that they should include a blogroll, and archives because everyone else is doing it, when really it's just more visual noise.

And it's this visual noise that I hate so much. The guys over at 37Signals, alongside many others often quote Antoine de Saint-Exuper in saying:

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away ~ Antoine de Saint-Exuper

This is something I think holds true in every medium of design. If we evaluate the elements on a blog page, what is the most important thing? The post itself obviously. We can then go about assessing the importance of other elements and delete as appropriate. This approach forces us to justify the use of an element on the page - "why do I need a link to the category in which this was posted?" might be answered with "because people may want to see related posts" - the link stays. "Why do I have a share button for Twitter at the bottom of the article?" might garner a response of "to allow people to easily share with friends" - is that a good enough reason? In my opinion, no. Why? Because the integration of social buttons like this makes it easy to regurgitate content in robotic forms like '[article name] by [article author], [link]' - how very boring. If a user likes your content enough, if your post justifies a Tweet or share, then let the reader think of a way to share it, and let them decide if the extra 10 seconds is worth spending time on to promote your article.

In conclusion I want you to take away one thing from this article - elements should have to justify themselves. Design for yourself, if you never click blogroll links, don't put them on your site, but at the same time remember this is limited to certain things, just because you don't use an RSS reader, doesn't mean others share your opinion. I for one have become frustrated by all this visual noise around today. I get that many sites need ads to support them and won't ever complain about them, but don't add to the crap by sticking a link to half the internet on your page as well as 'what your are currently listening to on last.fm', because do you know what? I don't care, maybe if the article is good, I'll check out your profile, but not before.

Site Redesign 2011

Well I finally got around to it! For months I've been procrastinating and finding other thing to do, but today I am proud to announce that I have successfully redesigned the blog and built a new theme. What you see before you is the result of many hours working on design and coding (as most websites are), during the process which spanned several months, I had about 4 different designs for the blog. But after about a week I found myself disliking every one. But I managed to finally design what I think is a rather clean and simple theme to house the blog. Unlike the theme which preceded this new one (I'm calling it 'Focus' by the way), I set the primary goal being that of reducing visual noise. Each time I came to design an element I asked myself "is this really essential?", because I wanted to design an experience that foregrounded the content above all else.

So what have I done to ensure your reading isn't distracted? Well you won't find a sidebar anywhere on the site. You won't find a list of months in which posts were published, and you won't find my latest tweet anywhere on the site. Why not? Well the way I see it is this. Most people come to Tom's Big Box to see the articles I written - in fact in most cases I visit blogs for that purpose, and that purpose alone. So why should I add all this visual noise when nobody cares about it? If you want to see my latest tweet, follow me on Twitter. As for the archives, you can view all posts by date on the archives page, but if you want to see them any other way you will have to guess that URL; why? Because I asked myself the question "have I ever wanted to see what posts were posted in a given month?" - nope. And I doubt any of my visitors have either - I can see only 1 unique on a month's archive.

Above: I even recorded the bulk of the coding side of things in a timelapse!

But beyond removing certain elements, I've also added certain things like better code highlighting (expect a tutorial soon), and better semantic markup. The site is now coded in HTML5 meaning I can call myself one of the cool kids. I've also removed a number of plugins and just generally cleaned up the code, so the site should be working a lot faster. I've also written some very specific code just for mobile to ensure you get the best viewing experience - even though the changes are subtle, they make a big difference. I've also added caching to speed things up!

And that's it! I hope you like the new theme and I hope it helps you get a clearer view of what you are trying to see, and if you have any questions, or notice any errors, please send me a pigeon.

Updates are coming!

I've not blogged in months, I know, I'm lazy. But things are going to change. I am in the process of redesigning the site and have a number of articles that I'm working on, so this is just a post to check in and let you know I'm not gone and am going to return to blogging in the near future.

So where have I been? Well I've been busy working on sites such as Cooking Pete and updating things like my about.me profile (the background of which lends itself to this post). I've also been working on a couple of iPhone Apps that'll hopefully be finished very soon as well. Alongside that I've got a few side projects that I am constantly adding to but that won't be ready for some time. But luckily I've encountered a number of interesting problems along the way, so I've got a number of articles in the works (I do have some nearly done, but I don't want to post half-arsed articles).

So that's it really. This post is really simply about re-assuring you that despite my last post being published in September last year, I am going to make an effort come early June to push the new design, and post a bunch more quality posts - stay tuned!

Use PayPal for pay-per-post on WordPress.

Note: This article has been marked for a quality review and will soon be updated.

As you may know I like WordPress - it's a great platform for building websites on. As you may not know is, I like PayPal - it's an easy to way to safely make quick payments online. Now you may be asking what the hell I'm on about, have I been paid by WP and PayPal to go on about their services? Nope. Today I want to share with you an easy way to integrate these two fantastic services, to allow users of your site to pay each time they want to post on your site. For this we will be using the PayPal API, and a rather special page indeed which will allow your users to post from outside of the admin panel. If you didn't know, there is already a tutorial on doing so entitled - Publishing to WordPress from outside the admin panel, so go ahead and check that out, and then come back over here.

So first let's think about the theory behind this. We want users to go to our post-page, and then be asked to buy a token to post 1 article; we then want to send the user to PayPal, for them to pay us, and then be sent back to our site, where the same post-page now shows them everything they need to post an article. Sound good? Almost there, we need to make sure we prepare for something - say for instance the user has user paid, and there is a power-cut at their house, in that case they will have just lost the money they paid us, and will be rather angry that there is no way to get it back; so essentially we are covering for the user closing their browser without posting, having paid us. And for that we are going to enlist the help of the cookie monster! Nah, just kidding, we'll stick to just one cookie for now - which will be placed on the user's machine to tell our site that they have paid, and when they have posted we can alter the cookie to reflect that. So let's go ahead and start with our posting page, place this code above your form.

<?php
if($_POST['payment_status']=="Completed"){
  $paid = true;
}else if($_COOKIE['activeToken']=="true") {
  $paid = true;
}else {
  $paid = false;
}

if(!$paid){ ?>

// User hasn't paid

<?php }else {  ?>

So what do we have here? Well at the top we can see we are checking to see if a posted variable is equal to "Completed" - this is something that PayPal gives us when the user has completed their transaction. We then set the $paid variable equal to true. Next we check a cookie to see if it's value is "true", and once again if this is true, we set $paid equal to true. And finally if neither of the above conditions validates we simply set the variable equal to false. Next we have an if statement which runs if $paid is equal to false - using the handy ! just before the variable. Now, after the else { statement is where you will want to put your form for posting an article, but not before you enter our crazy AJAX/Cookie-goodness code which follows.

<script type="text/javascript">
  $(document).ready(function(){
    var dataString = "cval=true";
    $.ajax({
      type: "POST",
      url: "<?php bloginfo('template_url') ?>/scripts/cookie.php",
      data: dataString,
    });
  });
</script>

// Your HTML goes here

<?php } ?>

Woah what the frick is that?! I hear you shouting. Right well let's go from the top. First off we can see that we are using JavaScript, and also jQuery - so make sure it's included, and we are also waiting for the DOM to have fully loaded everything before beginning our code. Then inside of this code we are setting up a variable named dataString and setting it's value to "cval=true" - more on this soon. Then we create an AJAX call using jQuery which will POST to a URL which is in our theme folder in the scripts sub-folder, to a file named "cookie.php" the data in the variable dataString. Make sense? Hopefully it does. Now you might be thinking, but wait a moment, I don't have a file called cookie.php, and even more annoying is that I don't even have a folder called scripts in my theme directory. Well don't worry - go ahead and create a new file called cookie.php in your theme directory, and if you tend to store scripts in another directory like me, go ahead and move it into that directory - just be sure to update the URL there - and if you didn't know that handy bit of code that reads <?php bloginfo('template_url') ?> just spits out the URL of your theme's directory. Now, copy and paste the following code into your new file.

<?php
$expire = 60 * 60 * 24 * 60 + time();
setcookie('activeToken', $_POST['cval'], $expire,'/');
?>

So what does that code do? Well the first line sets up a variable named $expire which holds the value of the date two months from today using some basic maths. Then we use the PHP function setcookie() to create a cookie in the format setcookie(name,value>,expiry date,directory) - now you might be wondering what that final "directory" bit is about - put simply that is the location where your cookie can be read from - if you leave out this parameter you won't be able to access your cookie, except from the cookie.php page you created it on - not ideal.

Now we have a good thing going now, but we need to think about when the user has submitted the form, and posted an article - we need to alter the cookie to tell our site that the user has used up the token he bought - simply by using the same JavaScript code that we used above, but changing "cval=true" to "cval=false". Now if you submit your main form using AJAX you can simply add this function in the success: parameter, otherwise you might want to do any number of other things - using jQuery's submit() function like so.

$("#myform").submit(function(){
  var dataString = "cval=false";
  $.ajax({
    type: "POST",
    url: "<?php bloginfo('template_url') ?>/scripts/cookie.php",
    data: dataString,
  });
});

Or you could stick the code on the page to which new post data is posted (new-post.php). Either way, you just have to ensure, that when the submit button is clicked - the cookie is set to false.

Now we've done nearly everything without having touched PayPal - the subject of the next section of the article; but before we begin I want to eradicate any preconceptions you may have about working with PayPal. Many people think it will be rather difficult to use PayPal in the way I am going to describe - that because you are dealing with people's money there is a greater margin for error. But this isn't the case - because at the end of the day, PayPal is the one going all the ground-work, and if it doesn't like what you are doing - it's going to tell you, so don't worry - and just go crazy! So go ahead and replace that comment we created earlier "//User hasn't paid" with the following code - kindly provided by PayPal.

<form action="https://www.paypal.com/cgi-bin/webscr?return=<?php the_permalink(); ?>&cpp_header_image=http://example.com/myHeaderImage.jpg&cbt=Return and post an article&rm=2" method="post">
<!-- Identify your business so that you can collect the payments. -->
<input type="hidden" name="business" value="name@example.com">
<!-- Specify a Buy Now button. -->
<input type="hidden" name="cmd" value="_xclick">
<!-- Specify details about the item that buyers will purchase. -->
<input type="hidden" name="item_name" value="Job Post Token">
<input type="hidden" name="amount" value="1000"> <input type="hidden" name="currency_code" value="USD">
<!-- Display the payment button. -->
<button value="Buy Posting Token"><span>Buy Posting Token</span></button>
<img alt="" border="0" width="1" height="1" src="https://www.paypal.com/en_US/i/scr/pixel.gif" >
</form>

So above, we have a form with a heck of a lot of information in it, but if we break it down, it's actually rather simple. Firstly we set up the form and tell it to post to PayPal's website - we also specify a number of variables to post along with it - the values of which are highlighted in bold. Firstly we have return - where the user will be returned to, once payment has been completed, for this we use the page's URL, helpfully provided to us by WordPress. Then we send it something called cpp_header_image - a 90x750px image which will be used in the header - using an image of your own will make the user feel more comfortable, and looks more professional. Then a variable called - cbt - which is the text used on the button which will send users back to the return URL specified above. The last variable is to do with PayPal posting values back to our page - including that of the handy payment_status - so don't change that.

The next value highlighted in bold is an email address - this is where you should enter the email address of the PayPal account holder to which all transactions will be credited. Next is the value "1000" - which is the amount you wish to charge your users to post - in this case $1000 - may be a little pricy - you decide. The currency is also set below and is currently set to US Dollars. PayPal provides a full list of variables for you to use, which is worth checking out for further customisation.

And that, ladies and gentlemen, is that! So now hopefully you can see just how easy it is to integrate PayPal with WordPress. As always if you have any questions/problems with the tutorial, leave a comment and let me know what you think.

Edit
For those of you who wish to make visitors to your site pay per viewing of each post you would need the following code structure alongside the code above.

<?php
if($_POST['payment_status']=="Completed"){
  $paid = true;
}else if($_COOKIE['activeToken']=="true") {
  $paid = true;
}else {
  $paid = false;
}

if($paid){ ?>

// User had paid, therefore enter the WordPress loop for the post

if(have_posts()) : while(have_posts()) : the_post();

//etc

<?php }else { ?>

//User hasn't paid, so display the payment options

<?php } ?>

Check out the codex for more information on the loop.