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.
- An HTML5 doctype is required. But you should be using that anyways!
- The
X-UA-Compatibletag forces IE to use it most current rendering engine - We need to reference jQuery Mobile’s stylesheet. You can use their CDN, and save on bandwidth!
- If you want to designate an icon for when users add your webpage to their iPhone (or Android) home screen, add a
linktag, with arelattribute ofapple-touch-icon. - We’re referencing the most recent version of jQuery: 1.4.3
- 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-role attributes have been 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.phpthat will handle the process of retrieving the RSS feed. For convenience, when we link tosite.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.
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.
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">
<ul data-role="listview" data-theme="b">
<ul data-role="listview" data-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.
These, too, can receive lettered theme roller stylings. They can be set within the parent <ul>.
<ul data-role="listview" data-dividertheme="d">
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">
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
$cachevariable 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.
wstands 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
$siteNamevariable (like, "nettuts"). To capitalize the first letter, and apply the signature + after the name, we'll run the variable throughucwords()(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.
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!
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.
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.
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
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.

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





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.
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
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…
To the TutsMobile, Batman!
Envato should set this up as the mobile version of Tutsplus.com.
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
Great stuff. Very clear and well done. And timely ! I have big hopes for jquerymobile. Thank you !
Is there a way to add extra JS code to run after the default jQuerymobile anchor href page load comes to an end?
You could create a new script element using JS document.createElement
or
document.write(‘<script ><\/script>’);
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?
Thank-you, very nice tutorial.
Very good Tutorial! This will be a great help once my RSS feeds are implemented on my new site!
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.
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.
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!
I didnt enter code in pre tags earlier sorry
Overview
URL1
Outputs: http://www.url.com/#search.html
Any help is appreciated. Thanks!
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!
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?
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 !!
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….
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.
Shite, sorry, ignore those malformed <pre tags up above :/
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?
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?
its a really great idea and even better execution.
@Martin
because we have:
foreach ($some_array as …) {
}
instead give
if (isset($some_array)) {
foreach ($some_array as …) {
}
}
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);
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
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
Does anyone know you could circumvent the php and use xmlhttprequests instead to implement on phonegap…
Anyone have any ideas?
For those having problem displaying no of comments .. use $item->comments[1], comments is now an array
Thank you very much! you just saved my Job ;)
Glad it helped!
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.
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
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
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 . “”;
?>
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.
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
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?
Can you tell me why it is not pulling the full description and image of my feed-burner feed?
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?
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?
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?
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.
Did anyone tried this? please help.
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
you are OG. thanks for putting this up!
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
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
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 :)
Thanks for sharing this tutorials, that was really a difficult job, but you have make it easy!
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 ;)
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.
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.
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!
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/
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!
Anyone help?
Nothing wrote to cache file :(
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
I love you! i Love you! you are so beautiful! thank you
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?