Building RSS Reader With Sencha Touch and PHP

December 18th, 2010 by aditia rahman / 10 Comments  

     

Sencha Touch is one of the mobile web appication framework available that we can download for free, it targeted for iPhone, Android or Tablet devices, if you have some experience with ExtJS, I believe you have one advantage in learning Sencha Touch, most of the component, code structure built similar with ExtJS. This is my first bite, tasting sencha touch I have created RSS reader that read from FeedBurner .

Ok lets get our finger dirty, first I created the main html file, this will include the sencha touch files (javascript and css) and my custom script for creating this application, this main html file I called rss-list.html

<!DOCTYPE html>
<html>
<head>
	<title>RSS List</title>
	<link rel="stylesheet" href="sencha-touch/resources/css/sencha-touch.css"/>
	<script type="text/javascript" src="sencha-touch/sencha-touch-debug.js"></script>
	<script type="text/javascript" src="apps.js"></script>
</head>
<body>
</body>
</html>

As you can see on the code above I separate sencha touch files on the sencha-touch folder and the apps.js is located in the same folder as rss-list.html, this file contain all the implementation of sencha touch component, and here what it look like (filename: apps.js)

Ext.setup({
    onReady: function() {
        Ext.regModel('ListItem', {
            fields: [
                { name: 'text', type: 'string' },
                { name: 'url', type: 'string' }
            ]
        });

        var store = new Ext.data.TreeStore({
            model: 'ListItem',
            proxy: {
                type: 'ajax',
                url: 'blogname.json',
                reader: {
                    type: 'tree',
                    root: 'items'
                }
            }
        });

        var topToolbar = new Ext.Toolbar({
            dock : 'top',
            ui: 'dark',
            title: 'Top Blog Feed'
        });

        var nestedList = new Ext.NestedList({
            fullscreen: true,
            style: 'font-weight:bold',
            dockedItems: [topToolbar],
            modal: true,
            toolbar: {
                dock: 'bottom',
                id: 'tb1',
                layout: {
                    pack : 'center'
                },
                items: [{
                    text: 'Home',
                    handler: function() {
                        store.setProxy({
                            type: 'ajax',
                            url: 'blogname.json',
                            reader: {
                                type: 'tree',
                                root: 'items'
                            }
                        });
                        store.load();
                        topToolbar.setTitle("Top Blog Feed");
                    }
                }]
            },
            displayField: 'text',
            store: store
        });

        nestedList.on('leafitemtap', function(subList, subIdx, el, e,
            detailCard) {
            var ds = subList.getStore(),
                r  = ds.getAt(subIdx);

            store.setProxy({
                type: 'ajax',
                url: 'getFeed.php?blogid=' + subIdx,
                reader: {
                    type: 'tree',
                    root: 'items'
                }
            });
            store.load();
            topToolbar.setTitle(r.get('text'));

            nestedList.on('leafitemtap', function(subList, subIdx, el, e,
                detailCard) {
                var ds = subList.getStore(),
                    r  = ds.getAt(subIdx);

                window.location = r.get('url');
            });

        });

    }
});

This example using NestedList for the main component, it will need data that can be retrieve by TreeStore component, I’m thinking it like ExtJS dataStore, we can change the data by reconfiguring the proxy component as much as we like, therefore this example not using the tree child to opening each title of the rss article, but just reloading the NestedList.

Data that store will read is json format and this is the basic blog name that we will fetch, I’m using my favorite blog name to show this example, you can change with other if you want to, filename blogname.json

{
	"items": [{
		"text": "Hongkiat",
		"leaf": true
	}, {
		"text": "1stWebDesigner",
		"leaf": true
	}, {
		"text": "Speckyboy",
		"leaf": true
	}]
}

The last file is to getting the latest article from every blog that choosed, I modify this php script from this source (filename: getFeed.php)

<?php

if ($_GET['blogid'] == '0') {
	$blogname = 'hongkiat';
} elseif ($_GET['blogid'] == '1') {
	$blogname = '1stwebdesigner';
} elseif ($_GET['blogid'] == '2') {
	$blogname = 'speckboy-design-magazine';
}

// URL location of your feed
$feedUrl = "http://feeds.feedburner.com/".$blogname;
$feedContent = "";

// Fetch feed from URL
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $feedUrl);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);

// FeedBurner requires a proper USER-AGENT...
curl_setopt($curl, CURL_HTTP_VERSION_1_1, true);
curl_setopt($curl, CURLOPT_ENCODING, "gzip, deflate");
curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

$feedContent = curl_exec($curl);
curl_close($curl);

if($feedContent && !empty($feedContent)) {
	$feedXml = simplexml_load_string($feedContent);

	$data = array();

	if($feedXml) {
		foreach($feedXml->channel->item as $item) {
			$data[] = array(
				'text' => "".$item->title,
				'leaf' => true,
				'url' => "".$item->link
			);
		}
	}

}

echo json_encode(array('items' => $data));
?>

Yep that’s all, but I know this is not enough yet, some feature that I haven’t found are adding an icon in each list, create this example using TreeStore that have children, loading message or masking the list while loading and displaying the article content in a mobile web format (this example just redirecting to original url), if you know better way to do this, you can let know, and by the way here are the screenshot that I have tested on Android Emulator, and the download link.

Download Source

        submit to reddit Delicious

10 Comments Leave a Comment Subscribe RSS

Leave a Comment