Programming and general geekiness.

Posts tagged ‘blog’

Building a simple blogging system in PHP – Part 2

In yesterday’s section of the tutorial we considered the basic layout, CSS and database structure. Today we are going to build the initial code that will fetch posts and other information. The previous tutorial ended looking like this:

Clearly there wasn’t any information so we need to begin adding things. The first thing we should do before doing anything else is to add some sample data to the database so that we can begin creating code that works. I added the following:

  • A blog post with the title ‘My first blog post!’ and the link My_first_blog_post along with some basic content
  • I added the category ‘life’ to the category table by adding a row with Id 1, Category life and Post 1 (links with the post table)
  • I added some tags the same way I added categories

The next simple bit of code to be run is to fetch a category list to display on the sidebar. I wrote the following code in code.php:

$pdo = new PDO("mysql:host=localhost;dbname=myblog", "root", "");
$pageTitle = "My Blog";
$pageContent = "";
$categoryList = "<ul class=\"category-list\">";
foreach ($pdo->query("SELECT DISTINCT Category FROM categories ORDER BY Category ASC")->fetchAll() as $cat)
{
 $categoryList .= "<li><a href=\"http://localhost/myblog/category/" . $cat[0] . "\">" . $cat[0] . "</a></li>";
}
$categoryList .= "</ul>";

Here’s a quick walkthrough of the code:

  • First we create a new PHP Data Object which is connected to the database we created. If you haven’t used PDO before it maybe worth looking it up in the PHP Manual
  • We then set default values for the variables and start an HTML list element in the $categoryList variable
  • We then loop through all the unique values in alphabetical order in the categories table and add them as a list item and link
  • We finish the list off

The end result of my sidebar is the following (I added some additional styling and layout stuff):

In the database I had all the category names as lowercase however CSS can style these as an uppercase letter at the beginning of each word. Now we need to look back at how the URLs work.

We have already established that the server will direct everything that doesn’t exist already into index.php to give us clean URLs. We therefore need to write some code that will interpret the requested URL. We also need to consider that we are including an RSS feed feature which will mean that people can subscribe to the site. I have therefore including the code that will generate the feed:

$url = explode("/", substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], "myblog/")+7));
if ($url[0] == "feed" || $url[0] == "rss")
{
 header("Content-type:application/rss+xml; charset=ISO-8859-1");
 echo "<?xml version=\"1.0\"?>\n";
 echo "<rss version=\"2.0\">\n";
 echo "<channel>\n";
 echo "<title>My Blog</title>\n";
 echo "<link>http://localhost/myblog/</link>\n";
 echo "<description>The source of information about my life!</description>\n";
 echo "<language>en-us</language>\n";
 foreach ($pdo->query("SELECT * FROM posts ORDER BY Posted DESC LIMIT 0, 20")->fetchAll() as $row)
 {
 echo "<item>\n";
 echo "<title>" . $row['Title'] . "</title>\n";
 echo "<link>http://localhost/myblog/post/" . $row['Link'] . "</link>\n";
 echo "<description><![CDATA[" . $row['Content'] . "]]></description>\n";
 echo "<pubDate>" . date('D, d M Y H:i:s O', strtotime($row['Posted'])) . "</pubDate>\n";
 echo "</item>\n";
 }
 echo "</channel>\n</rss>";
 exit;
}
else
{
}

I won’t explain what all the code that generates individual items of XML does, but here is roughly what happens:

  • We get everything in the URL after the myblog/ part and split it where there is a forward slash character
  • We check if the first part of the URL is feed or rss and if it is send an XML header
  • Echo the initial required data about the feed
  • Loop through the twenty most recent items and print the required details – note that the date has to be first passed into a PHP date and then into a valid RSS date
  • If the feed wasn’t requested, continue running code.

The next stage of code is rather massive but gives us the core stuff for the blog and goes inside that last else statement. I won’t chunk it out into sections so here is the block:

if (isset($_GET['p'])) $page = ((int)$_GET['p'])-1;
 else $page = 0;
 if ($page < 0) $page = 0;
 if ($url[0] == "post")
 {
 if (isset($url[1]))
 {
 $post = $pdo->prepare("SELECT * FROM posts WHERE Link = :link");
 $post->execute(array(":link" => $url[1]));
 }
 else header("location:http://localhost/myblog/");
 }
 else if ($url[0] == "category")
 {
 if (isset($url[1]))
 {
 $post = $pdo->prepare("SELECT * FROM posts WHERE Id = ANY (SELECT Post FROM categories WHERE Category = :cat) ORDER BY Posted DESC LIMIT " . $page*10 . ", 10");
 $post->execute(array(":cat" => $url[1]));
 }
 else header("location:http://localhost/myblog/");
 }
 else if ($url[0] == "tag")
 {
 if (isset($url[1]))
 {
 $post = $pdo->prepare("SELECT * FROM posts WHERE Id = ANY (SELECT Post FROM tags WHERE Tag = :tag) ORDER BY Posted DESC LIMIT " . $page*10 . ", 10");
 $post->execute(array(":tag" => $url[1]));
 }
 else header("location:http://localhost/myblog/");
 }
 else $post = $pdo->query("SELECT * FROM posts ORDER BY Posted DESC LIMIT " . $page*10 . ", 10");
 if ($post->rowCount() > 0)
 {
 foreach ($post->fetchAll() as $row)
 {
 if ($url[0] == "post") $pageTitle = $row['Title'];
 $pageContent .= "<article>";
 $pageContent .= "<header><h2><a href=\"http://localhost/myblog/post/" . $row['Link'] . "\">" . $row['Title'] . "</a></h2><p>" . date('j F Y', strtotime($row['Posted'])) . "</p></header>\n";
 $pageContent .= $row['Content'];
 $cats = $pdo->prepare("SELECT Category FROM categories WHERE Post = :post");
 $cats->execute(array(":post" => $row['Id']));
 if ($cats->rowCount() > 0)
 {
 $pageContent .= "\n<p>Posted in: ";
 foreach ($cats->fetchAll() as $cat)
 {
 $pageContent .= "<a href=\"http://localhost/myblog/category/" . $cat[0] . "\" class=\"category-link\">" . $cat[0] . "</a> ";
 }
 $pageContent .= "</p>";
 }
 $tags = $pdo->prepare("SELECT Tag FROM tags WHERE Post = :post");
 $tags->execute(array(":post" => $row['Id']));
 if ($tags->rowCount() > 0)
 {
 $pageContent .= "\n<p>Tagged with: ";
 foreach ($tags->fetchAll() as $tag)
 {
 $pageContent .= "<a href=\"http://localhost/myblog/tag/" . $tag[0] . "\" class=\"category-link\">" . $tag[0] . "</a> ";
 }
 $pageContent .= "</p>";
 }
 $pageContent .= "</article>";
 }
 }
  • The first thing that happens is checking if the p variable is set – this tells the user what page they are on
  • If we are looking at an individual post, prepare a query for that post
  • If we are looking at a category, prepare a query for that category
  • If we are looking at a tag, prepare a query for that tag
  • Loop through all the posts and produce the appropriate HTML for them

In reality it is actually relatively simple, it just takes quite a bit of code to work correctly. Here is what the finished result looks like, although you may want to add extra styling:

In the next tutorial we’ll add commenting and a basic admin panel.

Building a simple blogging system in PHP – Part 1

Today there are many blogging systems available to create a blog such as WordPress, Blogger and Tumblr however it can be more rewarding to build your own blogging system that you can use directly in your website. This set of tutorials will go through the procedure of building a blogging system with tags, categories and RSS using PHP and MySQL because they are both easily accessible environments. If you do not have either of these available on your system I recommend that you download WampServer and go through some PHP tutorials because that is what I will be using along with NetBeans 7.1 RC2 for coding.

Initial considerations

A blogging system has a few basic requirements. Here is what I think they are:

  • Simplistic two column layout – the left is for posts and the right is for a sidebar including category links, recent posts, RSS and search
  • Ability to fetch many posts or individual posts
  • Ability to tag a post with as many tags as required and as many categories as required
  • RSS feed automatically generated
  • Commenting on posts
  • Admin panel for editing
  • Well structured database for storing data

Clearly a blogging system is quite a large project and it is important to carefully consider how you will build it. In part 1 of this tutorial I shall develop the appropriate tables in a database, setup the server and basic layout of the pages.

Making the database

For simplicity I created a database called myblog in PHPMyAdmin on WampServer. I created the following tables:

  • posts
    • Id INTEGER PRIMARY_KEY AUTO_INCREMENT
    • Title TEXT
    • Link TEXT
    • Content TEXT
    • Posted DATETIME
  • categories
    • Id INTEGER PRIMARY_KEY AUTO_INCREMENT
    • Category TEXT
    • Post INTEGER
  • tags
    • Id INTEGER PRIMARY_KEY AUTO_INCREMENT
    • Tag TEXT
    • Post INTEGER

Incredibly this is all that we need in our database because we will be taking advantage of other web services to manage things like commenting. The next stage involves configuring Apache.

Configuring Apache

Apache is the web server of the web because its free and it does the job. Before we move on it is worth considering how we wish URLs on the blog to appear. One option is to have something like blog/post.php?id=3 to direct to the third blog post in the database however this is a cumbersome old school approach that is not used on many websites. Instead we will have something like blog/post/My_blog_post. Before we do this we first need to do a few things. The first is to ensure that the rewrite_module is enabled in Apache. In WampServer this can be done by clicking the WampServer icon in the taskbar, clicking Apache, clicking Apache Modules and then ensuring there is a tick against the rewrite_module. You then need to navigate to where you intend to put your blog (I’ve created a folder called myblog in C:\wamp\www) and create a new file called .htaccess and put in the following:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+) - [PT,L]
RewriteRule ^(.*) index.php

These five lines of code basically (I won’t go into detail) cause everything that doesn’t exist on the server (such as image files) in the directory to go through index.php which is where our basic code will be stored.

Creating index.php

For simplicity purposes this is where we are directing the server to for requesting posts. I’ve created the following in the file:

<?php include("code.php"); ?>
<!DOCTYPE html>
<html>
 <head>
 <link rel="stylesheet" type="text/css" href="http://localhost/myblog/css.css" />
 <title><?php echo $pageTitle ?></title>
 </head>
 <body>
 <div id="page">
 <div id="header">
 <h1>My blog</h1>
 <h3>The source of information about my life</h3>
 <div id="header-image">&nbsp;</div> 
 </div>
 <div id="page-content">
 <div id="left">
 <?php echo $pageContent ?>
 </div>
 <div id="right">
 <a href="http://localhost/myblog/rss" id="feed-link">Feed</a>
 <?php echo $categoryList ?>
 </div>
 </div>
 <div id="footer">My blog was created by Programming Thomas</div>
 </div>
 </body>
</html>

There is very little to observed from this other than it defines our basic layout. It is worth noting that the links have to be full lengths because they will not have the same relativity in localhost/myblog/post/My_post_name and localhost/myblog. I also created code.php and gave the variables some default variables so that I could view the page without errors. Here is what it looked like after styling:

I decided to use Google Web Fonts to get the Open Sans font which I thought looked quite nice. The image is from Flickr however I’ve cropped it. Here is the full CSS (I’ve tried to make it as small as possible):

@import url(http://fonts.googleapis.com/css?family=Open+Sans);
body
{
 font-family:"Open Sans", sans-serif;
}
#page
{
 width:750px;
 padding:5px;
 margin:10px auto;
}
#header h1, #header h3
{
 margin:0;
 font-weight:normal;
}
#header-image
{
 background:url(http://farm8.staticflickr.com/7159/6576537579_fcc8f6efd8_b_d.jpg) center center;
 height:175px;
 margin:5px 0;
}
#left
{
 width:490px;
 padding:5px;
 float:left;
}
#right
{
 width:240px;
 padding:5px;
 float:right;
}
#footer
{
 clear:both;
 text-align:center;
}
#feed-link
{
 background:url("http://localhost/myblog/feed-icon-28x28.png") no-repeat;
 padding:0 0 0 33px;
 color:black;
 text-decoration:none;
 width:100%;
 font-size:21px;
}

I think that is all that we will do today, check back tomorrow for Part 2 of the tutorial.

Stats

I’ve just realized October has been my awesomest month by 25% so far on this blog.

WordPress stats

A lot of viewers of my blog will probably not realize how much information it collects about them. Everyday I am able to find out what searches got people to my blog, which websites people got to it from (generally Google+, some spam one and YouTube) and which websites they go onto afterwards. I can also see daily views and other fascinating breakdowns – it can be especially useful to see which posts are successful (as a result of this there is definitely going to be another Cleverbot talking to Cleverbot, or maybe another bot, post), but from all the statistics the search terms are the most hilarious. Here are my favorites:

  • Push Amy but only when she tells you to
  • Apple store down
  • ajcuivd289
  • Jedi Jim Apprentive
  • Put Hitler in the Cupboard
  • Chuck Norris
Or at least those are my favorites from the rather dull list of a few hundred…

UI Design Experiment

I’m doing a project for a friend that is essentially a web application that allows members of a group to connect and contribute together. We had discussed using a forum or a private blog/wiki, however eventually decided that it would be more interesting to do something that was a cross between the three. I haven’t done much yet, but so far it looks like this:

I haven’t done much and it isn’t yet interactive, but there are some nice fades between pages.

Post 100

Incredibly, since I started blogging here in early January I have posted 100 posts. This is the 100th. In that time I have learnt Python, PHP and Java, written countless programs and built a website here. It has been great fun and I have every intention of keeping up Programming Thomas and all the other cool things I have done on the internet. To celebrate my 100th post I would like to look back at all the things I have done on this blog, and to start it off here’s a tag cloud:

These, incredibly, are just my most used tags. The reality is that I have used over 800 since then. Probably a tad to many. After this post I have decided that I am now going to tag posts with every last variation of a tag (like macosx, mac osx and mac os x).

I suppose that the main subject of my blog is programming, however I have noticed that I do seem to blog quite a lot about politics (remember the Alternative Vote?), Doctor Who (coming back soon!) and Windows 8 rumors. I’ve also demoed a game that I produced – an HTML5 version of FallDown and showed off some appalling animation.

Of course the blogging has been great and to help towards even better future blog posts feel free to subscribe to this blog and sign-up to my website!

HTML5 Book

I have just added a new experiment to my site where you can view the site’s blog as a book. It has been produced using HTML5, CSS3 and a bit of jQuery. Click here to view it.

New Programming Blog

http://programmingthomas.wordpress.com/

New Programming Blog

I have made a new blog specifically about programming and my projects over at Blogspot: programmingthomas.blogspot.com

Coming this week: DumbCMS

This week (not sure when) I will upload the code to a new CMS that I have coded called DumbCMS on Google Code. The idea behind the project is to use a really simple system that allows people to quickly create websites. It will be fully modifiable through an Admin system where administrators will be able to edit pages, post blog updates and upload files.

http://code.google.com/p/dumbcms/

Follow

Get every new post delivered to your Inbox.