How to Build an RSS Reader with jQuery Mobile

How to Build an RSS Reader with jQuery Mobile

Tutorial Details
  • Topics: jQuery Mobile, PHP
  • Difficulty: Intermediate
  • Estimated Completion Time: 40 Minutes

Final Product What You'll Be Creating

Twice a month, we revisit some of our readers’ favorite posts from through out the history of Nettuts+. This tutorial was first published in October 2010.

Today, we’ll dive into jQuery Mobile, which, at the time of this writing, is in a RC1 state. We’ll build a simple Tuts+ RSS reader, using PHP and jQuery Mobile. When we’re finished, you’ll have the ability to add this simple project to your iPhone or Android phone with the click of a button, as well as the skills to build your own custom mobile web apps!


Step 1: Outline the Project

It’s always helpful to first outline what you want your project to do/achieve.

  • Display a list of every Tuts+ site, along with its square logo
  • Display the feed for each site, when clicked on
  • Create a basic *article* stylesheet for rendering each posting
  • Create an Apple-touch icon for the users who add the “app” to their phone
  • Use YQL to retrieve the desired RSS feed
  • Implement a basic form of “text file” caching every three hours

Step 2: Begin

The next step is to begin creating our project. Go ahead and make a new folder — name it how you wish — and add a new header.php file. *Note that this project uses PHP. If you’re not familiar with this language, feel free to skip the PHP parts! Within this file, we’ll reference jQuery mobile, its stylesheet, and any other assets that we require. If only to stay organized, I’ve placed my header.php file within an includes/ folder.

<!DOCTYPE html>
<html>
   <head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

   <title> Tuts+ </title> 

   <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
   <link rel="apple-touch-icon" href="img/tutsTouchIcon.png" />

   <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
   <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
</head>

There are a handful of things worth noting here.

  1. An HTML5 doctype is required. But you should be using that anyways!
  2. The X-UA-Compatible tag forces IE to use it most current rendering engine
  3. We need to reference jQuery Mobile’s stylesheet. You can use their CDN, and save on bandwidth!
  4. If you want to designate an icon for when users add your webpage to their iPhone (or Android) home screen, add a link tag, with a rel attribute of apple-touch-icon.
  5. We’re referencing the most recent version of jQuery: 1.4.3
  6. Finally, we’re loading the jQuery mobile script file (currently in Alpha 1)

The Basic Structure

The jQuery Mobile framework can be activated by applying unique data-* attributes to your code. The basic structure for most sites will look similar to:

<!-- Let's include the header file that we created above -->
<?php include('includes/header.php'); ?>
<body>
 <div data-role="page">

   <header data-role="header">

   </header>

   <div data-role="content">

   </div>

   <footer data-role="footer">

   </footer>

 </div>

</body>
</html>

Add the code above to a new index.php file, within the root of your project.

We have to tell jQuery about our project. For example, try not to think of each file as a page. Technically, you can create multiple pages at a time, by adding additional wrapping data-role="page" attributes. These are referred to as inner pages.

Further, the framework has specific settings and stylings in place for the header, main content area, and footer. To inform jQuery Mobile about the locations of these elements, we add the following attributes.

  • data-role="header"
  • data-role="content"
  • data-role="footer"
No Data Attributes Applied

No data-role attributes have been applied.

Data Applied

Data-role attributes applied.

Step 3: Listing the Tutorial Sites

Now that the structure of our index.php page is complete, we can populate each section with our Tuts+ specific mark-up.

<body>
 	<div>
	    <header data-role="header">
	    	<h1> <img src="img/TLogo.png" alt="Tuts+"/> </h1>
	    </header>

	    <div data-role="content">
			<ul>
				<li>
					<img src="img/ntLogo.jpg" alt="Nettuts" class="ui-li-icon"/>
					<a href="site.php?siteName=nettuts"> Nettuts+ </a>
				</li>
				<li>
					<img src="img/psdLogo.jpg" alt="Psdtuts" class="ui-li-icon"/>
					<a href="site.php?siteName=psdtuts"> Psdtuts+ </a>
				</li>
				<li>
					<img src="img/vectorLogo.jpg" alt="Vectortuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=vectortuts"> Vectortuts+ </a>
				</li>
				<li>
					<img src="img/mobileLogo.png" alt="Mobiletuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=mobiletuts"> Mobiletuts+ </a>
				</li>
				<li>
					<img src="img/aeLogo.jpg" alt="Aetuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=aetuts"> Aetuts+ </a>
				</li>
				<li>
					<img src="img/photoLogo.jpg" alt="Phototuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=phototuts"> Phototuts+ </a>
				</li>
				<li>
					<img src="img/cgLogo.jpg" alt="Cgtuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=cgtuts"> Cgtuts+ </a>
				</li>
				<li>
					<img src="img/audioLogo.jpg" alt="Audiotuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=audiotuts"> Audiotuts+ </a>
				</li>
				<li>
					<img src="img/wdLogo.jpg" alt="Webdesigntuts+" class="ui-li-icon"/>
					<a href="site.php?siteName=webdesigntutsplus"> Webdesigntuts+ </a>
				</li>
			</ul>
	    </div>

	    <footer data-role="footer">
			<h4> www.tutsplus.com </h4>
	    </footer>

	</div>

</body>
</html>
  • Header: In this section, we’re simply inserting the Tuts+ graphic, and providing alternate text if images are turned off.
  • Content: In the content area, we need to list all of the tutorial sites, and apply a unique icon next to each heading. We also link to a new page, site.php that will handle the process of retrieving the RSS feed. For convenience, when we link to site.php, we also pass through the name of the selected site, via the querystring: siteName=nettuts.
  • Footer: At the bottom, for now, we’ll simply add a link to Tuts+.

jQuery Mobile offers a plethora of helpful CSS classes, including ui-li-icon. When applied to an image, it’ll float it to the left, and apply 10px worth of margin-right.

Our project so far

At this point, our site should look like the above image.

Page Transitions

As jQuery will load local pages asynchronously with AJAX, we can specify any number of cool page transitions. The default is the basic slide-left or slide-right effect that most touch-phone users are aware of. To override the default, use the data-transition attribute on the anchor tag.

<a href="site.php?siteName=nettuts" data-transition="pop"> Nettuts+ </a>

Available Transitions

  • slide
  • slideup
  • slidedown
  • pop
  • flip
  • fade

Step 4: ListViews

Ehh – the image, shown above, still looks like a website. We need to make things a bit more phone-like. The answer is to use the data-role="listview" attribute. Watch what happens when we do nothing more than apply this attribute to the wrapping unordered list.

Using the listview data-role attribute

Wow – what an improvement! Even better, we have access to theme-roller, which allows us, with the change of a single letter, to switch color themes.

<ul data-role="listview" data-theme="a">
Theme A
<ul data-role="listview" data-theme="b">
Theme B
<ul data-role="listview" data-theme="e">
Theme E

List Dividers

Now, what if we wanted to divide this list of tutorial sites? In these situations, we can take advantage of data-role="list-divider", which can be applied to the <li> element.

List Divider

These, too, can receive lettered theme roller stylings. They can be set within the parent <ul>.

<ul data-role="listview" data-dividertheme="d">
Divider Theme
Learn more about list dividers.

Note that we won’t be using dividers for this particular application.


Step 5: CSS

jQuery Mobile takes care of a great deal of the formatting, however, we still, of course, need our own stylesheet for tweaking. For example, looking at the images above, we can see that the tutorial icons need to be pushed up a bit. Additionally, I’d like to use the Tuts+ red for the background color of the heading and footer, rather than the default black.

Create a new folder, CSS, and add a new stylesheet — I’ll call mine: mobile.css. Within this file, we’ll first fix the icon positioning:

 .ui-li-icon {
   top:  9px;
}

Next, we’ll create a handful of classes, named after their respective tutorial sites. These classes will contain any specific formatting/colors for the site. For example, Nettuts+ has a darker green color, while MobileTuts+ is yellow.

.tuts { background: #c24e00; }
.nettuts { background: #2d6b61; }
.psdtuts { background: #af1c00; }
.vectortuts { background: #1e468e; }
.aetuts { background: #4a3c59; }
.phototuts { background: #3798aa; }
.cgtuts { background: #723b4a; }
.audiotuts { background: #4b7e00; }
.webdesigntutsplus { background: #0d533f; }
.mobiletuts { background: #dba600; }

That should be fine for now. The last step for index.php is to apply the .tuts class to the header and footer elements. That way, the header and footer will render the correct background color.

<header data-role="header" class="tuts">
...
<footer data-role="footer" class="tuts">
Added the Tuts Color

Step 6: YQL, PHP, and Caching

Now, it’s time to step away from the layout, and work on the functionality. Each of the links we created directed to site.php?siteName="siteName". Let’s go ahead and create that file now.

Even though this is a relatively tiny app, we should still strive to follow best practices. In this case, it means that we should keep as little PHP in our document as possible. Instead, we’ll use site.php as a controller of sorts. This file will handle the initial logic, and will then, at the bottom, load in our HTML template.

Assigning the Site Name

In order to retrieve the desired RSS feed, we first need to capture the name of the site that the user clicked on initially. If you’ll refer to a previous step, when we linked to site.php, we also passed the name of the site through the querystring. With PHP, this can easily be retrieved, with $_GET['siteName']. However, what if, for some odd reason, this value doesn’t exist? Maybe site.php was accessed directly?? We should set a default site to compensate for these situations.

$siteName = empty($_GET['siteName']) ? 'nettuts' : $_GET['siteName'];

If $_GET['siteName'] is empty, we’ll set “nettuts” to the variable, $siteName. Otherwise, it’ll be equal to the name of the respective site.

Security

Even though this is a small project, let’s also try to set some security in place. To prevent the user from automatically assigning a potentially dangerous value to the siteName key, let’s ensure that the value is in fact the name of one of our tutorial sites.

// Prepare array of tutorial sites
$siteList = array(
   'nettuts',
   'flashtuts',
   'webdesigntutsplus',
   'psdtuts',
   'vectortuts',
   'phototuts',
   'mobiletuts',
   'cgtuts',
   'audiotuts',
   'aetuts'
);

// If the string isn't a site name, just change to nettuts instead.
if ( !in_array($siteName, $siteList) ) {
   $siteName = 'nettuts';
}

The in_array() function allows us to determine if a value — in our case, the value of $siteName — is equal to one of the items in the $siteList array.

Caching

Ultimately, we’ll be using the excellent YQL to perform our queries. Think of YQL as an API for APIs. Rather than having to learn twenty different APIs, YQL’s SQL-like syntax allows you to only learn one. However, though YQL does perform a bit of caching on its own, let’s also save the RSS feeds to a text file on our server. That way, we can improve performance a fair bit.

We begin by creating a new variable, $cache, and making it equal to the location of where the cached file will be stored.

$cache = dirname(__FILE__) . "/cache/$siteName";

The code above points to the current directory of the file, and then into a cache folder, and, finally, the name of the selected site.

I’ve decided that this cached file should be updated every three hours. As such, we can run a quick if statement, and determine the last time that the file was updated. If the file does not exist, or the update was longer than three hours ago, we query YQL.

$cache = dirname(__FILE__) . "/cache/$siteName";
// Re-cache every three hours
if( filemtime($cache) < (time() - 10800) ) {
 // grab the site's RSS feed, via YQL
}

YQL is ridiculously easy to work with. In our case, we'll use it for a very simple purpose: grab the RSS feed, in JSON form, of the site that was passed through the querystring, via siteName. You can experiment with the various commands by using the YQL console.

To query an RSS feed, we using the command: SELECT * FROM feed WHERE url="path/to/rss/feed".

  • Nettuts+ Feed: http://feeds.feedburner.com/nettuts
  • Psdtuts+ Feed: http://feeds.feedburner.com/psdtuts
  • Vectortuts+ Feed: http://feeds.feedburner.com/vectortuts
  • etc.

Building the Path

For the sake of readability, we'll build up our YQL query in sections.

 // YQL query (SELECT * from feed ... ) // Split for readability
 $path = "http://query.yahooapis.com/v1/public/yql?q=";
 $path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.feedburner.com/$siteName'");
 $path .= "&format=json";

The key is the second part above; when the page loaded, we grabbed the name of the site from the querystring. Now, we only need to insert it into the SELECT query. Luckily, all of the tutorial sites use Feedburner! Make sure that you urlencode the query to replace any special characters.

Okay, the path is ready; let's use file_get_contents() to grab the feed!

$feed = file_get_contents($path, true);

Assuming that $feed is now equal to the returned JSON, we can store the results in a text file. However, let's first ensure that data was returned. As long as something is returned from the query, $feed->query->count will be equal to a value greater than zero. If it is, we'll open the cached file, write the data to the file, and finally close it.

// If something was returned, cache
if ( is_object($feed) && $feed->query->count ) {
   $cachefile = fopen($cache, 'w');
   fwrite($cachefile, $feed);
   fclose($cachefile);
}

It seems confusing, but it's really not. The function fopen() accepts two parameters:

  • The file to open: We stored this path in the $cache variable at the top of the page. Note that, if this file doesn't exist, it will create the file for you.
  • Access privileges: Here, we can specify which privileges are available. w stands for "write."

Next, we open that file, and write the contents of $feed (the returned RSS JSON data) to the file, and close it.

Using the Cached File

Above, we first checked whether the cached file was greater than three hours old.

if( filemtime($cache) < (time() - 10800) ) {
 // grab the site's RSS feed, via YQL
}

But what if it wasn't? In that case, we run an else statement, and grab the contents of the text file, rather than using YQL.

if( filemtime($cache) < (time() - 10800) ) {
 // grab the site's RSS feed, via YQL
 ....
}
else {
// We already have local cache. Use that instead.
$feed = file_get_contents($cache);
}

Lastly, we can't do much with the JSON RSS feed until we decode it with PHP.

// Decode that shizzle
$feed = json_decode($feed);

And that should do it for our controller! With the logic out of the way, let's include our HTML template.

// Include the view
include('views/site.tmpl.php');

Here's our final site.php. Click on the expand icon to view it.

<?php
// If "siteName" isn't in the querystring, set the default site name to 'nettuts'
$siteName = empty($_GET['siteName']) ? 'nettuts' : $_GET['siteName'];

$siteList = array(
   'nettuts',
   'flashtuts',
   'webdesigntutsplus',
   'psdtuts',
   'vectortuts',
   'phototuts',
   'mobiletuts',
   'cgtuts',
   'audiotuts',
   'aetuts'
);

// For security reasons. If the string isn't a site name, just change to
// nettuts instead.
if ( !in_array($siteName, $siteList) ) {
   $siteName = 'nettuts';
}

$cache = dirname(__FILE__) . "/cache/$siteName";
// Re-cache every three hours
if(filemtime($cache) < (time() - 10800))
{
   // Get from server
   if ( !file_exists(dirname(__FILE__) . '/cache') ) {
      mkdir(dirname(__FILE__) . '/cache', 0777);
   }
   // YQL query (SELECT * from feed ... ) // Split for readability
   $path = "http://query.yahooapis.com/v1/public/yql?q=";
   $path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.feedburner.com/$siteName'");
   $path .= "&format=json";

   // Call YQL, and if the query didn't fail, cache the returned data
   $feed = file_get_contents($path, true);

   // If something was returned, cache
   if ( is_object($feed) && $feed->query->count ) {
      $cachefile = fopen($cache, 'wb');
      fwrite($cachefile, $feed);
      fclose($cachefile);
   }
}
else
{
   // We already have local cache. Use that instead.
   $feed = file_get_contents($cache);
}

// Decode that shizzle
$feed = json_decode($feed);

// Include the view
include('views/site.tmpl.php');

Step 7: The Site Template

At the end of the previous step, we loaded in our template (or view). Go ahead and create that views folder, and site.tmpl.php file. Feel free to name it how you wish. Next, we'll insert our HTML.

<?php include('includes/header.php'); ?>
<body> 

<div data-role="page">

   <header data-role="header" class="<?php echo $siteName; ?>">
      <h1><?php echo ucwords($siteName).'+'; ?></h1>
   </header>

   <div data-role="content">
      <ul data-role="listview" data-theme="c" data-dividertheme="d" data-counttheme="e">

      </ul>
   </div>

   <footer data-role="footer" class="<?php echo $siteName; ?>">
      <h4> www.tutsplus.com</h4>
   </footer>
</div>

</body>
</html>

Points of Interest Above

  • Notice how we follow the same basic layout: header, content area, footer.
  • As this template will be used for every Tuts+ tutorial site, we need to set the title dynamically. Luckily, if you remember, the site name was passed through the querystring, and stored in the $siteName variable (like, "nettuts"). To capitalize the first letter, and apply the signature + after the name, we'll run the variable through ucwords() (uppercases the first letter of each word in the string), and append a "+": <h1><?php echo ucwords($siteName).'+'; ?></h1>
  • We'll soon be displaying the number of comments for each posting next to the title. We can, again, use ThemeRoller to style it, via the data-counttheme="e" attribute.
Site Template Thus Far

Filtering Through the Feed

At this point, we have access to the $feed object that contains our RSS feed. To dissect this object, you can either print_r($feed), or use the YQL console for a prettier view. We'll use the latter in this case. Check it out.

To grab the data for each posting, we need to filter through: $feed->query->results->item. PHP makes this a cinch with foreach().

Within the foreach() statement, we can now access the desired values with $item->title, or $item->comments, which will display the title, and the comment number, respectively. Add the following within the <ul> tags.

<ul data-role="listview" data-theme="c" data-dividertheme="d" data-counttheme="e">
<?php
    foreach($feed->query->results->item as $item) { ?>

    <li>
      <h2>
         <a href="article.php?siteName=<?php echo $siteName;?>&origLink=<?php echo urlencode($item->guid->content); ?>">
               <?php echo $item->title; ?>
         </a>
      </h2>
      <span class="ui-li-count"><?php echo $item->comments; ?> </span>
   </li>

<?php  } ?>
</ul>

In the code above, we build up a list item, containing the title of the posting, the number of comments, and a link to article.php that also contains the site name and the permanent link (to the original article on the Tuts+ site) in the query-string.

When we view the updated page in the browser, tada!

Recent article list

Notice how the comment count is in a yellow bubble, and is floated to the right? That's because we applied the data-counttheme="e" attribute to the wrapping unordered list. How convenient.

Hmm...I think the text is too large for these long titles. A quick visit to Firebug shows that I can target the h2 tags with a class of .ui-li-heading. Let's return to our stylesheet (mobile.css), and add a new rule:

.ui-li-heading { font-size: 12px; }

That's better.

Applying a smaller heading size

Step 8: Displaying the Full Posting

The final step is to build article.php, which will display the entire posting. As with site.php, article.php will serve as our controller, and will query the selected article with YQL, and load the appropriate view.

<?php

$siteName = $_GET['siteName'];
$origLink = $_GET['origLink'];

// YQL query (SELECT * from feed ... ) // Split for readability
$path = "http://query.yahooapis.com/v1/public/yql?q=";
$path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.feedburner.com/$siteName' AND guid='$origLink'");
$path .= "&format=json";

$feed = json_decode(file_get_contents($path));
$feed = $feed->query->results->item;

include('views/article.tmpl.php');

If you've been following along, the code above should look a bit more familiar to you. When we loaded this page, from site.php, we passed through two items, via the query string:

  • Site Name: Contains the name of the currently selected tutorial site
  • Orig Link: A link to the original posting on the tutorial site

The difference with the YQL query, this time, is that we match the guid (orig link) with the posting that the user clicked on (or pressed). This way, exactly one posting will be returned. Check out this sample YQL query to gain a better idea of what I mean.

New YQL query

Article Template

At the bottom of the code above, we loaded the template file for the article page: views/article.tmpl.php. We'll create that file now.

<?php include('includes/header.php'); ?>
<body> 

<div data-role="page">

   <header data-role="header" class="<?php echo $siteName; ?>">
      <h1> <?php echo ucWords($siteName).'+'; ?> </h1>
   </header>

   <div data-role="content">
        <h1> <?php echo $feed->title; ?> </h1>
        <div> <?php echo $feed->description; ?> </div>
   </div>

   <footer data-role="footer" class="<?php echo $siteName; ?>">
      <h4> <a href="<?php echo $feed->guid->content;?>"> Read on <?php echo ucWords($siteName); ?>+</a></h4>
   </footer>
</div>

</body>
</html>

Ah - so familiar. We've already gone over this template. The only difference is that, this time, because there's only one posting from the YQL query to display, we don't need to bother with a foreach() statement.

Unstyled Article Page
Unstyled article page

At this point, on your own, the next step would be to begin applying your desired styling to the article. I don't see a need to go over it in this tutorial, as it all comes down to personal taste. Here's my super-minimal version.

Minimally styled article page
Applying a font-size, line-height, padding, and image formatting.

Locked Footers

One last thing: in the footer section of the article, we link to the original posting on Nettuts+. In its current state, the reader will only see that when they reach the bottom of the article. Let's lock the footer to the bottom of the current view-point at all times. We can use the data-position attribute to achieve this.

   <footer data-role="footer" data-position="fixed">
      <h4> <a href="<?php echo $feed->guid->content;?>"> Read on <?php echo ucWords($siteName); ?>+</a></h4>
   </footer>

That's better!


We're Done!

And, with relatively little work, we've successfully built a mobile RSS reader for the Tuts+ sites. It can certainly be expanded to provide additional features, error checking, and performance improvements, but this will hopefully get you started! If you'd like to fork the project and make it better, by all means...do! Thanks for reading, and be sure to refer to the jQuery Mobile documentation for more details. I've no doubt that you'll come across more jQuery mobile tutorials on our sister site, Mobiletuts+.

Add the Reader to your iPhone Home Screen

Add Comment

Discussion 147 Comments

Comment Page 2 of 3 1 2 3
  1. Damien says:

    It look like the link to article.php gets treated as an external link, just as if you used rel=”external”. That’s why there’s no Back button on the article view page. It’s because there’s an “http” inside the URL; seems like a bug.

    • Jeffrey Way says:
      Author

      Hey Damien – You’re right. That url should be encoded first. I’ll fix that.

      But, the framework should also compensate for these sorts of user errors, I think. Just submitted a pull request: http://github.com/jquery/jquery-mobile/pull/276

    • Ricky says:

      KarthikeyanTHanks for the arictle, i think that JQUery Mobile lacks in better documentation from a beginner perspective,Is any sites having a better explanations with code samples?Also how to hyperlink a page when clicking on a LIstView.?even i tried of using target attr but it doesnt go to the page?plz help if me if u know?Thank u…

  2. redwall_hp says:

    To the TutsMobile, Batman!

    Envato should set this up as the mobile version of Tutsplus.com.

    • Dale Hurley says:

      I think it is clear that this one sits in between both. It is clearly all web technology for mobile. I personally think it is okay theses sort of articles in either. In this case I think it is more web dev cos of the YQL and PHP. jQuery Mobile is really just a display tool.

      Dale

  3. B says:

    Great stuff. Very clear and well done. And timely ! I have big hopes for jquerymobile. Thank you !

  4. Lucian Pacurar says:

    Is there a way to add extra JS code to run after the default jQuerymobile anchor href page load comes to an end?

  5. Derek says:

    I’m having problems with the is_object part of the code…while the feed is successfully obtained, the part in the if loop is never executed. I commented the if check out and everything seems to be working…do you have any idea why I might be running into this?

  6. Sharbel says:

    Thank-you, very nice tutorial.

  7. Very good Tutorial! This will be a great help once my RSS feeds are implemented on my new site!

  8. Jnik says:

    That’s a great introduction to jQuery mobile.

    I would be definitely looking into YQL the next days. It seems to make things very simple, although it adds the delay of an extra connection.

  9. Excellent tutorial. I have been testing the demo in various mobile browsers. Android Dolphin Browser (one of the popular) has several issues. It seems many of the jQuery mobile functions do not work well in that browser. Also the footer keeps jumping up every time you scroll the content (slideup). And the text size really huge in the content as compared to the headlines.

  10. Mikah says:

    I’m confused as to why I always get a # in front of my path for my link. The files are in the same directory but when clicking on them I always get a hash tag. I’m not using PHP or any server side.

    i.e.

    Overview
    URL1

    Outputs: http://www.url.com/#search.html

    Any help is appreciated. Thanks!

    • Mikah again says:

      I didnt enter code in pre tags earlier sorry

      Overview
      URL1

      Outputs: http://www.url.com/#search.html

      Any help is appreciated. Thanks!

      • Mikah OMG says:

        So sorry to spam !!

        I’m confused as to why I always get a # in front of my path for my link. The files are in the same directory but when clicking on them I always get a hash tag. I’m not using PHP or any server side.

        i.e.

        Overview
        URL1

        Outputs: http://www.url.com/#search.html

        Any help is appreciated. Thanks!

    • Cliff says:

      I had the same problem when I used 1.0 Alpha 2, I downgraded to 1.0 Alpha 1 and the problem disappeared.
      Perhaps it’s the same issue with your situation?

    • kevcha says:

      I have the same problem !
      As Mika said i tried to downgrade to alpha1, but i still have this problem !
      And i’m using a php framework so I can’t do anything before have solved this problem…
      Do someone have an idea why this hash tag come automatically when clinking on a link ?
      Thanks in advance !!

  11. Ward says:

    Finally got around to coding this up on my server – nice tutorial and a great looking finished product! I’m confused why no one is talking about the error being thrown with

    if ( is_object($feed) && $feed->query->count ) {

    I have seen several people mention it but no one answers – $feed is not an object and nothing is being cached here.

    W

    ——————-
    OK, took a look, the problem is that feed needs to go through json_decode before it is an object so that line needs to be moved up above so that it sits right after

    $feed = file_get_contents($path, true);

    Now I am having permissions problems writing the cache file :/ sigh….

  12. Ward says:

    So here is my final edits

    ### Add the decode line after the file_get_contents line as show below
    <pre name="code" class="php"
    $feed = file_get_contents($path, true);

    $feed = json_decode($feed);

    This will return an array which will pass the is_object test loop.

    ### Change the fwrite line as follows
    <pre name="code" class="php"
    fwrite($cachefile, json_encode($feed));

    Here we re-encode to a string for the purposes of overwriting the cache file.

    ### Change the else branch as follows

    else {
    // We already have local cache. Use that instead.
    $feed = json_decode(file_get_contents($cache));
    }

    When reading back out of the cache file we will need to turn that string of json data back into an array.

    ——

    I think thats it.

  13. Ward says:

    Shite, sorry, ignore those malformed <pre tags up above :/

  14. Markus says:

    Hi, i have Problems with loading my Images from RSS. Take a Look.. http://Media-owl.de/jqmobile THW posts are not Complete ! In WordPress is everething Set to FullText. what can i do?

  15. Martin says:

    Hi,

    thanks for this nice tutorial. I get an error message:

    Warning: Invalid argument supplied for foreach() in /site.tmpl.php on line 13

    Can someone help me please?

  16. Kamil says:

    its a really great idea and even better execution.

  17. Kamil says:

    @Martin

    because we have:

    foreach ($some_array as …) {
    }

    instead give

    if (isset($some_array)) {
    foreach ($some_array as …) {
    }
    }

  18. mobilize says:

    I’m unable to get the file to write. any reason why this is occuring?

    if ( is_object($feed) && $feed->query->count ) {
    $cachefile = fopen($cache, ‘wb’);
    fwrite($cachefile, $feed);
    fclose($cachefile);

  19. jonathanistrying says:

    This is exactly what i need. Does anyone know if this could work in phonegap? also, I am having trouble dealing with the php..

    what does it mean if im not familiar I can just skip it? it seems to be integral. I link to the “index.php” file and everything seems fine, but i am getting no luck when clicking other links in the browser… is it not enough just to download the source code and plug and play?

    thanks in advance.

    -jonathanistrying

  20. Hi Jeff, thank you so much for your amazing work on this one. Sure learned a lot.

    But I’m having some trouble getting the Web app to work that I think it’s beyond my knowledge.
    Both my project and yours run just fine on a local server, running Apache.
    The cache is being written, the feed is fetched and displayed, all good, it made me very happy.

    The problem is when I test it on my PHP server. Absolutely nothing happens when the feed is being fetched! Zero results are displayed, and not a single error or warning is displayed. I had a warning at first telling me that the array was empty, but I got around it by wrapping the condition on a isset.

    But nothing is returned, I don’t think the feed (any feed) is being fetched by the server. I have disabled the cache-related coding and nothing happens. No error, no warnings, so I’m stuck on a blind debugging. And since everything works on a local server, I can’t really put my finger on what’s wrong.

    Any ideas?

    Thank you,
    Ricardo

  21. jonathanistrying says:

    Does anyone know you could circumvent the php and use xmlhttprequests instead to implement on phonegap…

    Anyone have any ideas?

  22. meltz says:

    For those having problem displaying no of comments .. use $item->comments[1], comments is now an array

  23. Darmie says:

    Thank you very much! you just saved my Job ;)

  24. Darmie says:

    i want to ask, what if you decide not to use php at all and use Javascript? like i learnt from this article of yours –> http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
    and do everything in Javascript, because i want to deploy a similar application with Phonegap.

  25. Alex Hedley says:

    Hi, Great Tutorial,

    I’ve amended it so it just uses Javascript as I was trying to see if I could.
    One problem I’ve come across, as I think others have reading the comments, the # tagging in the URL is causing the page not to load the data.

    Say it was
    ../index.html#site.html?rss=blog
    this won’t load but
    ../site.html?rss=blog
    does.

    This happens again for loading the single articles.

    I can’t seem to find a way to fix this.

    Anybody got any ideas?

    Kind Regards
    Alex

    • Alex Hedley says:

      Ok so I thought I’d managed to fix the problem,

      The page content is added to the DOM of the current page, using ajax, so this is causing problems as the page is made dynamically once it has loaded, only the body of the page is added so all the scripts used to make up the page aren’t ran

      Just add rel=external to the link and the page loads as is should.
      This works but then the back button isn’t added.
      I added data-rel=”back” to the link but this breaks the link.

      I’d added all the meta data from the tutorial [http://mobile.tutsplus.com/tutorials/iphone/iphone-web-app-meta-tags/] but since these links are now external if you use the app from a link saved on the home screen a new instance of safari is opened, defeating the purpose of native app style.
      But if you add then you lose the back buttons which I now need.

      [I could use to just hide the url instead]

      Half way there I guess

  26. David says:

    I am sort of off topic, but I don’t know where else to find help.

    I have a list view on my own script similar to this.

    My page is page.html, and I am trying to insert php code inside the index html, but it treats it as normal text…I want to generate the list of sites dynamically.

    jQuery Mobile Docs – Lists with Form Controls

    Inset list samples
    Home

    Sites

    <?php
    $david = "www.david.com";
    echo "” . $david . “”;
    ?>


    • Valari says:

      Thank you for sarhing this info with us. I could not figure out how to do this replacement. After seeing how you did it I went out and quickly removed mine. You Rock.

  27. Mittchel says:

    Why am I keep getting this error:

    Warning: Invalid argument supplied for foreach() in /home/kwzXDGoJvK/domains/isbaas.nl/public_html/reader/views/site.tmpl.php on line 14

  28. Mittchel says:

    When using this code:

    query->results->item)) {
    foreach($feed->query->results->item as $item) {
    if ( $siteName === ‘psdtuts’ ) $comments = $item->comments->content;
    else $comments = $item->comments[1];
    ?>

    <a href="article.php?siteName=&origLink=guid->content);?>”>
    title; ?>

    It doesn’t give any result just blank page, why does this happen?

  29. Craig says:

    Can you tell me why it is not pulling the full description and image of my feed-burner feed?

  30. Dansk says:

    Nice tutorial, ta!

    A couple of other people have left comments here about phonegap and php. Since many of us will be trying to develop apps that can be deployed through phonegap is there any chance of some tips or hints about this?

  31. Hanami says:

    I’m new to YQL but below query return null:

    SELECT * FROM feed WHERE url=”http://feeds.feedburner.com/nettuts” AND guid=”http://net.tutsplus.com/?p=15284″

    could anyone show me why?

  32. cognostek says:

    Hi, You have an amazing tutorial, its really helpful. Thanks again. My quick question would be I was unable to get the RSS content of any website to mobile jquery.I have tried it but couldn’t find the answer. Have you tried it or can check if it works for you?

  33. Tuan Bui says:

    Great article. If you want to see jquery mobile in action, check out http://www.mobosurvey.com we are using jquery mobile for our survey generator for mobile devices and it looks great.

  34. Did anyone tried this? please help.

  35. Vag says:

    Hello, I modified my code to make it work with my site. The problem is though that the
    origLink doesn’t return anything

    $origLink = $_GET['origLink'];

    I think that this is because my origLink is in Greek. Everything else is double checked and seems to be ok. Can any1 help?

    Thank you

  36. Romy says:

    you are OG. thanks for putting this up!

  37. Pamela says:

    Great ;-) but do you know a simple way to add a website which has a news feed which is not available at feedreader.com ?

    I’m trying to repace your n+ feed adresses by 2, 3 from my friend’s blog but I’m a newbie in php

    Thanks in advance

  38. Mohamed Atef says:

    It’s an amazing tutorial.. but is there some way I can to use this get all wordpress all posts?
    sorry, I can’t search in WPTuts because there’s some bug in all tuts+ network search

  39. Aslam Doctor says:

    Very nice tutorial on jQuery mobile usage. I would give it a try to expand this with some more features like add/delete rss feeds :)

  40. Thanks for sharing this tutorials, that was really a difficult job, but you have make it easy!

  41. Great Article! Someone above noted that it would be ideal to be able to do this for WordPress. I think making it into a plugin would fit a wide audience and making it tuts + exclusive could benefit you! This might just be me pulling for an easy way out ;)

  42. Ali Baba says:

    Mobiletuts gives you an error: http://demo.jeffrey-way.com/tutsMobile/#site.php?siteName=mobiletuts

    Warning: Invalid argument supplied for foreach() in /nfs/c04/h03/mnt/59914/domains/demo.jeffrey-way.com/html/tutsMobile/views/site.tmpl.php on line 13
    Check array before do foreach

    Otherwise good Tutorial. Well done.

  43. Darko says:

    Great work,

    I was trying to adapt this for my own needs, and i’m having the weirdest problem. Absolutely everything works fine, except the article.php and article.tmpl.php, but only in Firefox. This is the weird part. I have tested it in Chrome, Opera, Safari even IE and it displays everything correctly. When i open a specific article in Firefox i get a notice: Trying to get property of non-object in C:\xampp\htdocs\veleriRSS\views\article.tmpl.php on line 18.

    There is something wrong with the $feed in article.php. When i try to print_r it’s empty in Firefox, but not in any other browser. I can’t figure out why is that happening, there must be something wrong with the YQL query, but i don’t understand why just in Firefox. Jeffrey’s example works normally in Firefox, and after a while i decided to just copy his code and try it, but still no luck.

    Any help would be appreciated.

  44. Julien says:

    I dunno if anyone had this problem but file_gets_contents() needs allow_url_fopen. I don’t have my own server and it wasn’t activated so i replaced this part by a simple cURL request.

    I’m commenting because the usual error message didn’t show up and I spent too much time testing to understand. Maybe it could help someone.

    Anyway, Thanks for this great introduction. YQL is absolutely brilliant!

  45. Thank you for sharing nice script. But In this you used “file_get_contents” but most of the servers are not supporting now. We can use CURL using php. I too develop a mobile app using this code : http://www.anil2u.info/2011/10/how-to-build-php-application-in-google-app-engine/

  46. I was looking for a solution to read RSS using javascript/jquery/jqueryui/yahooui.
    And this is exactly what I need.
    Thank you so much!

  47. Anyone help?
    Nothing wrote to cache file :(

  48. Jenn says:

    Thanks for posting this, it’s been a GREAT help with a project I was handed. I looked everywhere and this is the one I kept coming across as far as help with this.
    One issue I am having, …..
    I am attempting to pull in an rss feed. I have it so that it pulls the Post titles, but when you click on the post titles, there isn’t any content. It’s a blank page. Her is an URL: http:/www.anchordigital.net/fertility
    It seems as though the code is not getting the origLink from feeds.feedburner.com. Any help would be greatly appreciated.

    Thanks

  49. Romy says:

    I love you! i Love you! you are so beautiful! thank you

  50. Clayton says:

    Hi, I’m not sure if I’m the only one but has anyone noticed the weird gradient when viewing it through IE. I can’t figure out how to override this. Anyone have any suggestions?

Comment Page 2 of 3 1 2 3

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.