Google reader is the most popular web-based feed-reader. A lot of ajax techniques and well-defined layout — that's all Google Reader offers. This tutorial is aimed at creating a Google reader mock-up with some of its awesome features.


Download Source Try Demo

Building The Layout

Google Reader has a fluid table based layout having header, a left pane containing the feeds and a right view-area. Our simple-reader would have a header area, a left pane and a view-area.

We create the index.php file and add the following code:

<html>
<head>
<title>Simple Reader</title>
<style type='text/css'>
body {
 margin:0px;
 padding:0px;
 font-family:Arial, serif;
 font-size:14px;
}
a {outline:none;}
#header {
 background:url("images/logo.png") no-repeat center left;
 height:10%;
 overflow:hidden;
}

#loader {
 background:#f9dd7d;
 width:75px;
 margin:auto;
 display:block;
 padding:6px;
 font-weight:bold;
 display:none;
}

#wrapper {
 height:90%;
 margin:0px;
 padding:0px;
}
</style>
<script type='text/javascript' src='jquery.pack.js'></script>
<script type='text/javascript' src='jquery.layout.js'></script>
</head>
<body>
 <div id='header'>
  <div id='loader'>Loading...</div>
 </div>
 <div id='wrapper'> </div>
</body>
</html>
Notice that we have added a div with id 'loader'. We have hidden it by setting display:none but we would show it while making ajax calls.

Within #wrapper we'd have two sections: #sidebar and #view-area. For the purpose of building this, we are going to use jQuery layout plugin which makes things easier by adding panes and resizers that come handy in creating rich ajax based web-application interface.

jQuery Layout has a very simple structure. If we just add five divs with class names ui-layout-north, ui-layout-west, ui-layout-center, ui-layout-east and ui-layout-south, it automatically aligns the divs the following way and also adds resizers to collapse the panes.
But for the purpose of our layout we just need the west and the center sections. So within the #wrapper div we add:
<div class='ui-layout-west' id='sidebar'></div>

<div class='ui-layout-center' id='view-area'></div>
We also include the javascript files within the head tag.
<script type='text/javascript' src='jquery.pack.js'></script>
<script type='text/javascript' src='jquery.layout.js'></script>
But nothing happens to our layout. That's because we have not initiated the layout with jquery. To do so we add the following code in the head tag.
<script type='text/javascript'>
$(document).ready(function () {
 var my_layout = $('#wrapper').layout({applyDefaultStyles:true});
 });
</script>
Now we have something like this:
Notice that the layout plugin has added a resizer to our sidebar section. If you inspect this element in Firebug, you'd find that the resizer is a span section with class name ui-layout-resizer-west-open and within the span, there's a div section having a class name ui-layout-toggler-west-open. If you close the panel clicking the grey area, the class name of the span turns to ui-layout-resizer-west-closed and that of the div turns to ui-layout-toggler-west-closed.
So now we add some css to make it look better.
.ui-layout-resizer-west {
 background:#ebeff9;
}

.ui-layout-toggler-west-open {
 background:url("images/toggle-lt.gif") no-repeat center;
}
.ui-layout-toggler-west-closed {
 background:url("images/toggle-rt.gif") no-repeat center;
}
.ui-layout-center {
 border-top:2px solid #ebeff9;
}

.ui-layout-west {
 background:#ffffff;
 border-top:2px solid #ebeff9;
}
We also remove the default styling of the layout by removing {applyDefaultStyles:true} So now, our javascript looks like:
var my_layout = $('#wrapper').layout();
Our layout now looks much nicer with the toggler images.


Creating And Connecting To The Database

Now that we have the layout prepared, we create a database that would contain URL and feed names.
Here we have table called feeds with four fields.

Next, we create file called config.php.
<?php
$hostname = "YOUR_HOSTNAME";
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";
$database = "YOUR_DATABASE_NAME";

$link = mysql_connect($hostname, $username, $password) or die("Cannot connect to the database!");
mysql_select_db($database) or die("Cannot select database!");
?>
We also include the config.php file at the top of index.php to gain access to database credentials.
<?php
include("config.php");
?>

Adding Feeds To The Reader

So we have the table and we have connected to the database. We now add feeds — that too with Ajax!

Within the sidebar section we create a link to add feeds.

<a class='add-feed' href='javascript:;'>Add Feed</a>
And some css to make it look good.
a.add-feed {
 background:url("images/add_feed.gif") no-repeat center left;
 padding:6px 6px 6px 35px;
 font-size:1.5em;
 display:block;
 color:#000000;
 text-decoration:none;
}

a.add-feed:hover {
 text-decoration:underline;
}
What we want is when the add-feed link is clicked an ajax call would be made to the server and a form would be sent. We do this with jquery.
$("a.add-feed").click(function(){
  $("#loader").fadeIn();
  $.ajax({
   type: "POST",
   data: "action=show_form",
   url: "add.php",
   success: function(msg)
    {
     $("#view-area").html(msg);
     $("#loader").fadeOut();
    }
  });
 });
In the above code, we show the loader when the ajax call is in process and when response has reached the browser, we hide the loader and show the reponse in view-area. Remember the above javascript will go inside the curly braces of $(function(){ }); because the javascript will be available for execution after the page is loaded.

But we don't have the add.php page. Let's create it.
<?php
include("config.php");
if(!$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
 {
 die("No direct access to files is allowed");
 }
$action = trim($_POST["action"]);

if($action == "show_form")
 {
?>
<form action='' id='add_form'>
<label for='feed_name'>Name:</label>
<input type='text' id='feed_name' name='feed_name'/>
<label for='feed_url'>Feed URL:</label>
<input type='text' id='feed_url' name='feed_url'/>
<input type='submit' value='add' class='submit-button'/>
</form>
<?php
 }
?>
First, we stop access to the page except through ajax call. Then, we show the form.

Now if you click the Add Feed link, the form will be displayed. But it looks horrible without css. Let's give it some style.
form#add_form {
 width:300px;
 margin:auto;
}

form#add_form {
 width:300px;
 margin:25px auto;
}

#add_form label {
 float:left;
 text-align:right;
 margin-right:15px;
 width:75px;
 padding-top:5px;
 cursor:pointer;
}

#add_form input {
 margin:0px 0px 10px;
 padding:3px;
 font-size:1.2em;
}

#add_form .submit-button {
 border:1px solid #e8e8ff;
 float:right;
}
Remember that since we are showing everything on the index.php page, all css definitions will go within the <style> tag of index.php

Now, we want to add feed — with Ajax. For that purpose we use the following javascript code.
$("form#add_form").live("submit", function()
  {
  $("#loader").fadeIn();
  $.ajax({
   type: "POST",
   data: "action=submit&"+$(this).serialize(),
   url: "add.php",
   success: function(msg)
    {
    alert(msg);
    $("#loader").fadeOut();
    }
  });
  
  return false;
  });
First we show the loader and then make ajax call. We then show the response as an alert. We added return false because we don't want the page to be reloaded when the form is submitted. Also notice that instead of using the usual click() method we have made use of the new live() method (available in jQuery 1.3). That's because the view-area is dynamically loaded and we have to rebind all the events after every ajax call. That would be complex. The new live() method does the job with ease.

Notice that when the form is submitted, we send action=submit through ajax. But we have not defined any action for the same in add.php. Let's do that.

We append the following code to add.php
<?php
elseif($action == "submit")
 {
 $feed_name = filter_var($_POST["feed_name"], FILTER_SANITIZE_STRING);
 $feed_url = filter_var($_POST["feed_url"], FILTER_SANITIZE_STRING);
 if(empty($feed_name) || empty($feed_url))
  {
  echo "You have not filled up all the fields!";
  }
 else
  {
  $q = "INSERT INTO feeds (name, url) VALUES ('$feed_name', '$feed_url')";
  $r = mysql_query($q);
  if(mysql_affected_rows($link)==1)
   {
   echo "Feed is added. Please reload the page.";
   }
  else
   {
   echo mysql_error();
   }
  }
 }
?>
First we sanitize the data. Then check whether they are non-empty. If not, we add the data to the table. Pretty simple.

Now that you have created the add functionality, add a few feeds. Don't you forget to add AbhiTech feed!

Show The Data

Now, we list all the feeds in the sidebar and when we click on a link, the view-area will show the latest updates. To list the feeds in the sidebar we add the following code within the #sidebar in index.php

<ul id="feed-list">
<?php
$q = "SELECT * FROM feeds ORDER BY name";
$r = mysql_query($q);

if(mysql_num_rows($r)>0)
 {
 while($row = mysql_fetch_assoc($r))
  {
  echo "<li><a href=".$row["url"]." class='item_link'>".$row["name"]."</a></li>";
  }
 
 }

?>
</ul>
Here we just select all the added feeds in the table and then loop through the rows to show them as list elements. But without css, it's looking ugly.
ul#feed-list {
 margin:0px;
 padding:0px;
 overflow:auto;
 height:85%;
}

ul#feed-list li {
 list-style:none;
 margin-top:6px;
 padding:4px;
}

ul#feed-list li:hover  {
 background-color: #fdf9e8;
}

ul#feed-list li a {
 background: url("images/rss.png") no-repeat center left;
 display:block;
 padding:3px 3px 3px 18px;
 color:#000000;
 font-size:100%;
 text-decoration:none;
 font-weight:bold;
}
Now, we want to make ajax calls to display the feed. Notice that each link of the feeds has a class name item_link. Thus our javascript will deal with clicking on item_link class. We add the following javascript code.
$("a.item_link").click(function()
  {
   $("#loader").fadeIn();
   
   feed_url = $(this).attr("href");
   $.ajax({
    type: "POST",
    data: "url="+feed_url,
    url: "view.php",
    success: function(msg)
     {
     $("#view-area").html(msg);
     
     $("#loader").fadeOut();
     
     }
   });
   return false;
  });
First, we show the loader. Then, we get the feed url and with that, make ajax call to view.php (which we have not created yet). When the response has reached, we show it in the view-area. Finally, we hide the loader. Notice that we have added return false because we want to stop the browser to go to the feed URL when clicked. Instead, we want to execute the javascript.

We now create view.php. To parse feeds with PHP, we are going to use SimplePie. Download SimplePie and put simplepie.inc in the same directory. We create a file view.php and put the following code in it.
<?php
if(!$_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest')
 {
 die("No direct access to files is allowed");
 }
include("simplepie.inc");
include("config.php");

$url = filter_var($_POST["url"], FILTER_SANITIZE_STRING);
$q = "SELECT * FROM feeds WHERE url = '$url'";
$r = mysql_query($q);

if(mysql_num_rows($r)==1)
 {
 $row = mysql_fetch_assoc($r);
 $feed = new SimplePie($url);
 $feed->handle_content_type();
echo "<a href='".$row['url']."' class='feed-title' target='_blank'>".$row['name']." &raquo;</a>
  <ul class='entries'>";
 foreach ($feed->get_items() as $item)
  {
  echo "<li>
   <a href='javascript:;' class='title'>".$item->get_title()."</a>  
   <div class='content'>
    <a class='entry-title' href='".$item->get_link()."' target='_blank'>".$item->get_title()." &raquo;</a>"
    .$item->get_content()."
   </div>
   </li>";
  }
 echo "</ul>";
 }
else
 {
 echo "Feed not found!";
 }

?>
A lot of code! Let me explain.

First we stop access to the script except through ajax call. We then add simplepie.inc and config.php. We filter the requested url and then select the row in the table where the url matches. If url is found in the table, we get the row with mysql_fetch_assoc and then create a simplepie object. Then for each item, we create a list element and put the title of the feed and the content inside it.

We also add css to make it look better.
ul.entries {
 list-style:none;
 margin:0px;
 padding:0px;
}

.entries li {
 border-bottom:1px solid #e8e8ff;
}

.entries .title {
 background:url("images/item-icon.png") no-repeat center left;
 font-size:100%;
 font-weight:bold;
 color:#000000;
 text-decoration:none;
 display:block;
 padding:2px 2px 2px 18px;
}

.entries .content {
 text-align:justify;
 padding:18px;
 display:none;
 border-bottom: 1px solid #e8e8ff;
}

.content a.entry-title {
 font-size:150%;
 text-decoration:none;
 display:block;
}

.content a img {
 border:none;
}
Notice that we have set display:none; to the main content of the feed. That is because we are going to give it some nice jQuery effect. We add the following javascript code.
$("a.title").live("click", function(){
 $(this).next("div.content").slideToggle();

});
When we click on the title of an item, this simple snippet will slide down the hidden content next to the link.

You should have something like this.


Speed it up

Notice that after you click on a feed link, it takes a long time before you get the content. That's because we have not create a 'cache' directory in the same directory. Do that and see the difference for yourself!


Conclusion

This is a very simple example of how to create a simple RSS reader. It leaves out a lot of space to improve. Play with it and try to extend its features with your own. Your comments and thoughts are always welcome! :)

Icons courtesy Dryicons.com. The logo belongs to SimplePie Community.

Labels: , ,

Read More
Well, this is a very old and dirty trick to change 'localhost' (i.e. http://127.0.0.1/) to some other name. Many of you are aware of this trick. In Windows, go to "C:\Windows\system32\drivers\etc". You'd find a file named "hosts" (without quotes, of course). Open it with your favourite text editor. Find the lines:
127.0.0.1       localhost
Just after that line, add the following line:
127.0.0.1  the_name_you_like
Of course, replace "the_name_you_like" with the name of your choice. That's it! Next time you type "the_name_you_like" in the address bar and hit enter enter, you'd be redirected to http://127.0.0.1/ How cool is that! Also if you want to run multiple domains under one machine head to this article.

Labels:

Read More
The single most important power every web-developer should give to the users is the ability to search for data. With millions of blogs and sites coming up everyday, users simply find themselves lost in the ocean of data. Then comes the power of the tiny search-box. And how about an animated ajax search that further stops the user from waiting to load another page? Interesting? Then, read on!
Download Source Try Demo

Build the Layout

First things first: we build the layout. Since this is just an example of how things work, we are not going to make it very attractive; rather it would have a basic structure.
Create an index.php file and put the following code inside it.
<html>
<head>
<title>Ajax Search With jQuery</title>
<link rel='stylesheet' href='style.css'></link>
<script type='text/javascript' src='jquery.pack.js'></script>
</head>
<body>

<div id='container'>
<div id='search-box'>
 <span id='search-text'>Search</span>
 <form id='search-form'>
  <input type='text' id='input-text' name='s' value='Type and hit enter'/>
 </form>
</div>

<div id='results'>

</div>

</div>

</body>
</html>
Pretty simple to follow. We added jQuery and style.css. We made a container within which the search-box and results are placed. The results will be shown as list items (i.e. <li> elements).

Now, we create a style.css file and put the following css there.
html, body, div, h1, h2, h3, h4, h5, h6, ul, ol, dl, li, dt, dd, p, blockquote,
pre, form, fieldset, table, th, td { margin: 0; padding: 0; }
body {
 font-size:14px;
}
a, a:visited {
 color:blue;
}
#container {
 width:480px;
 margin:auto;
}
#search-box {
 width:233px;
 height:42px;
 background: url("images/search-form.png") no-repeat center;
 margin:15px auto;
}
#search-text {
 float:left;
 background:#000000;
 width:58px;
 margin:2px;
 color:#ffffff;
 padding:11px 0px;
 text-align:center;
}
#search-text a {
 color:#ffffff;
}
#search-form {
 margin:0px;
 padding:8px 0px;
 display:block;
}
#search-form #input-text{
 background:transparent;
 border:0px;
 margin:3px;
 font-size:1.1em;
}
#search-status {
 border:1px solid #ebeef5;
 padding:6px;
}
#results ul {
 list-style:none;
 margin:15px 0px;
 padding:0px;
}
#results ul li {
 padding:5px 5px 5px 18px;
 margin-bottom:15px;
 border-top:1px solid #ebeef5;
 border-bottom:1px solid #ebeef5;
}
#results ul li a {
 text-decoration:none;
}
The first part of the code is stolen from NetTUTS! You can find the image: search-form.png along with the source code given with this tutorial. The css is pretty simple and easy to understand. Only one thing I'd like to mention: notice that we have set the background of #input-text to transparent even though it comes above the search-box (whose background is already set). This is because if we have not done so, the default background in <input&t; elements (which is white) will be visible.

If you have done it right, you should have this:


Prepare the database

Now that we have prepared our layout, it's time we move in the back-end and set up the database and work with PHP.


We create a simple table in the database. The table needs not be the same as it is shown here. It can have other fields. For this simple tutorial, I created this simple table.

Here, we have only 3 fields: id, title & url. (We are going to search the title field only.)

Then we add some dummy data to the table.


Connect To The Database

We create a config.php file and put the following codes in it.

<?php
$hostname = "YOUR_HOSTNAME";
$username = "YOUR_USERNAME";
$password = "YOUR_PASSWORD";
$database_name = "YOUR_DATABASE_NAME";

$link = mysql_connect($hostname, $username, $password) or die("Cannot connect to the database!");
mysql_select_db($database_name) or die("Cannot select the database!");
?>
Here we just made a connection with MySQL database. Change the default values with your own credentials.

Show the Data

Now, we have the database prepared and we are able to connect to the database. Now, we show the data in index.php page. We include the config.php file in index.php by adding these lines of code at the top of index.php


<?php
include("config.php");
?>
Now, we have access to the database connection. Thus, we add the following lines inside the results div of index.php
<ul>
<?php
$q = "SELECT * FROM posts";
$r = mysql_query($q);
while($row = mysql_fetch_assoc($r))
 {
?>
<li><a href='<?php echo $row['url']; ?>'><?php echo $row['title']; ?></a></li>
<?php
 }
?>
</ul>
Here we create an ul element and then query the table to get a resultset of all the rows. Once we have the resultset, we loop through all the rows and create a li element for each row. Note that we wrapped the title with the corresponding url of the row.

Add Some Effects

Now, we make an ajax call to search.php (which we will create in the next step) and make an animated effect while the request is being sent.

<script type='text/javascript'>
$(function(){
/* This is the jQuery section
 * All javascript codes in this tut go here
 */
 $("form#search-form").submit(function(){
  $("#search-form").hide();
  $("#search-text").animate({"width":"229px"});
  $("#results").fadeOut();
  $.ajax({
   type:"GET",
   data: $(this).serialize(),
   url: "search.php",
   success: function(msg)
    {
    $("#results").html(msg);
    $("#results").fadeIn();
    $("#search-text").html("<a href='#' id='search-again'>Search Again</a>");
    }
  });
 return false;
 });
</script>
The above bit of codes goes within the index.php file after we added jquery. Follow the code closely. Here, we add a function that works only when the search form is submitted. When the form is submitted, we simply hide the form and set the width of #search-text to 229px (which is the total width of search-box div) with a cool animation, thanks to jQuery. Then, we make an ajax call to search.php (which we will create in the next step) and put the response from search.php in results div and fade in the results div. To stop the page from reloading we add return false. But since we have already set the width of search-text div to 229px and have hidden the form, the form is no longer available. But the user may again need to search. So, we add a link (with title "Search Again") to let the user access the form again. Thus we again add the following bit of javascript just after the above lines of codes.
$("#search-again").live("click", function()
  {
   $("#search-text").html("Search");
   $("#search-text").width("58px");
   $("#search-form").fadeIn();
  });
Two things to notice: first, we make use of the live() function of jQuery (new in jQuery 1.3.1). That's because this function repeatedly binds elements to future events; you don't have to bind it again and again. Secondly, we set the width of #search-text to 58px. This is exactly the width of the #search-text as set by css. To make the long story short, we bring back the earlier form when "Search Again" is clicked.

Search it, baby!

Finally, we create the main search.php file. We add the following lines of code in search.php

<?php
include("config.php");
$search_term = filter_var($_GET["s"], FILTER_SANITIZE_STRING);
$q = "SELECT * FROM posts WHERE title LIKE '%".$search_term."%'";
$r = mysql_query($q);
if(mysql_num_rows($r)==0)//no result found
 {
 echo "<div id='search-status'>No result found!</div>";
 }
else //result found
 {
 echo "<ul>";
 while($row = mysql_fetch_assoc($r))
  {
  $title = str_ireplace($search_term, "<b>".$search_term."</b>", $row['title']);
?>
 <li><a href='<?php echo $row['url']; ?>'><?php echo $title ?></a></li>

<?php
  }
 echo "</ul>";
 }
?>
Here, we include config.php file to get access to the database connection. Then, we 'sanitize' the search term with filter_var (available in PHP 5.2+). Next, we search all the titles in the table that matches the required search term. If result(s) is (are) found, we loop through the resultset, and wrap the search term with <b> tag. We, then, create a list element for each result.

Conclusion

This is simple search tutorial. It mainly focuses on jQuery's ajax techniques and effects you can create with it. You can implement this technique in your Wordpress blog and create something like the legendary K2.

Labels: , ,

Read More