Tuesday, June 28, 2011

PEPBrowser: The First Evently Widget

Introduction

In this blog post, I will be walking you through on how I wrote the first Evently widget for the PEPBrowser App. The widget simply displays a listing of the main categories of the PEP documents. For those who would like to get the documents used for this project, simply replicate it from this CouchDB database, http://nieldomingo.iriscouch.com/pepbrowser/_design/pepbrowser/.

The PEP Document Represented in CouchDB

First and foremost, we have to understand the structure of the PEP doument stored in Couchdb. Below is an example of the PEP document as stored in Couchdb.


{
   "_id": "00808d5fefdabc7c068ed3089d08aac3",
   "_rev": "1-f4e2d53f17d1b8ff0842baf921f773b2",
   "category": "Process",
   "status": "Active",
   "num": "1",
   "version": "b5ab214ac135",
   "created": "13-Jun-2000",
   "url": "http://www.python.org/dev/peps/pep-0001",
   "lastmodified": "2011-03-04 05:03:26 +0000 (Fri, 04 Mar 2011)",
   "author": "Barry Warsaw, Jeremy Hylton, David Goodger",
   "html": "<div class=\"contents ...",
   "title": "PEP Purpose and Guidelines",
   "type": "pep"
}

The definition of the fields that we would be using follows.
  • type - the document type. I used the value, 'pep', to identify the PEP document.
  • category - the category of the PEP document.
  • status - the status of the PEP document. It determines whether the PEP is accepted, rejected, active, etc.
  • num - the number of the PEP document. PEP documents are numbered; they are usually referred as PEP 1, PEP 3000, etc.
  • title - the title of the PEP.
  • html - the html of the PEP document body.
The categories View

Before proceeding to writing the first Evently widget, we first need to make a CouchDB view that will generate a query of the information to be displayed by the widget. The widget would show a listing of all the PEP document categories and the number of documents for each category.

To start making this view, let us first generate some boiler-plate code using the couchapp utilty by running the following command.

couchapp generate view categories

The above command would generate a folder, named 'categories', inside the 'views' folder. Inside the 'categories' folder are two files, map.js and reduce.js. The map.js would contain the code for mapping part of the view and reduce.js would contain the code for the reduction part of the view.

The code for map.js follows.


function(doc) {
  if (doc.type == 'pep') {
    emit(doc.category, 1);
  }
}

The code for reduce.js follows.

function(keys, values, rereduce) {
  return sum(values);
}

The above view when run with a group_level=1 parameter, http://localhost:5984/pepbrowser/_design/pepbrowser/_view/categories?group_level=1, produces the following output.

{"rows":[
{"key":"Informational","value":38},
{"key":"Process","value":22},
{"key":"Standards Track","value":218}
]}


Categories List Evently Widget

Now that we have a CouchDB view, let us proceed with creating the evently widget. In the 'evently' folder of our Couchapp, create the folder, 'peplist'. 'peplist' would be the name of our widget. Inside the 'peplist' folder, create the folder '_init'. '_init' is the event that is triggered when the widget is loaded. This widget is intended to be part of the start page of the app so most of the work is done during initialization. Thus all our following activities in creating this widget is done inside the '_init' folder.

Inside the '_init' folder, create the query.json file. It should contain the following JSON.

{
  "view": "categories",
  "group_level": 1
}

The query.json file indicates the query to be done by the '_init' event. The 'view' field indicates the CouchDB view to be used and 'group_level' is a parameter to be used in making the query. The result of this query is passed to the function inside the 'data.js' function for processing.

Also under the '_init' folder, create the 'data.js' file with the following content.


function (data) {
return {'categories': data.rows};
};

The 'data' argument in the above function contains the result of the 'categories' view as defined by query.json. The above function is a simple function that returns a mapping to be used by the mustache template.

Create the mustache template inside the _init' folder. The filename of the mustache template should be 'mustache.html'. And for this case, it should contain the following markup.

<ul id="peplist" data-role="listview" data-theme="c" data-dividertheme="b">
  {{#categories}}
  <li><a href="#categorystatuslist" title="{{ key }}">{{key}} ({{value}})</a></li>
  {{/categories}}
</ul>

Notice in the above template that it lists down each and every row of the 'categories' field passed by the mapping of 'data.js'. Each row is represented by a list item tag, 'li', and a link tag, 'a'. The text contained in the link is the category name and the number of documents, i.e. "Informational (38)". The values of the 'href' and 'title' attributes contains values that will be explained later when we linked this widget to other widgets.

Lastly, we need to create the 'after.js' file with the following contents.

function () {
$('#peplist').listview();
};

The 'after.js' contains code that would be run  by the widget after all the other functions have been run, which explains its name. The function is necessary in order to initialize the list into a Jquerymobile list.

After all our changes, the peplist widget folder should look as follows.


Using the Evently Widget

To use the widget inside the main page of the app, we need to modify the 'main.html' file in the '_attachments' folder as follows.

<!doctype html>
<head>
  <title>PEP Browser</title>
  <link rel="stylesheet" href="style/jquery.mobile-1.0a4.1.min.css" type="text/css">
  <script src="js/myloader.js"></script>
  <script src="js/jquery.mobile-1.0a4.1.min.js"></script>
  <script type="text/javascript" charset="utf-8">
    $.couch.app(function(app) {
      $("#maincategorylist").evently("peplist", app);    
    });
  </script>
</head>
<body>
  <div data-role="page" id="categorylist">
    <div  data-role="header" data-theme="b">
      <h1>PEP Browser</h1>
    </div> 
<div  data-role="content">
 <div id="maincategorylist">
 </div>
</div> 
  </div>
</body>
</html>

The highlighted Javascript above connects the Evently widget we just created to the 'maincategorylist' div.

$("#maincategorylist").evently("peplist", app);

This means that the 'maincategorylist' div would contain the widget. It would display the markup generated by the widget.


After all of these changes, the app would look as follows.




Sunday, June 26, 2011

Update on PEPBrowser:

This weekend I spent most of my time working on the project rather than blogging about it. I was able to accomplish much, I finished the basic functionality and proceeded to packaging the Couchapp as a Android App. Unfortunately, packaging it as an Android App has its issues. I've been trying for 2 days now and still can't make it work. But I still have some ideas left to try. Hopefully, all this effort would amount to something if I get to make it work (very hopeful, but keeping fingers crossed). Looking forward to writing a very informative blog post regarding this experience.

For the meantime, I would like to share the basic PEPBrowser. Thanks to iriscouch for their free basic Couchdb hosting, I am able to make it available online, http://nieldomingo.iriscouch.com/pepbrowser/_design/pepbrowser/main.html.

I'll resume recounting how I built the basic app this week.

Wednesday, June 22, 2011

PEPBrowser: Building the Base of the PEP Browser App

Introduction


In this blog post, I'll try to walk-through the process of making the base of the PEP Browser app. I'll be writing this from memory so I might miss some steps. So if you're trying to follow this and got lost, don't hesitate to leave me a comment.


Boilerplate Couchapp


To start, I made the initial boilerplate application using the Couchapp utility. You could install it using the following command in the command-line. (Note: my instructions assumes that you are using a unix based system)

$ sudo easy_install couchapp

After installing the Couchapp utility, I created the boilerplate application by running the following command.

$ couchapp generate pepbrowser

The above command would generate  a directory named, 'pepbrowser', which is a simple Couchapp which we will use as the starting for our project. Before starting to customize it, let us first push the initial Couchapp to a local Couchdb server to see that it works.

To push it to a Couchdb server, we need to modify or create the '.couchapprc' file inside the 'pepbrowser' folder. The file should look like as follows.

{
  "env": {
    "default": {
      "db": "http://username:password@localhost:5984/pepbrowser"
    }
  }
}

Remember that you should change the 'username' and  'password' in the above example. You should also change 'localhost' and '5984', in case your Couchdb server is not installed locally and does not use the default port.

After modifying the '.couchapprc' file, we push the initial Couchapp using the following command.

$ couchapp push

The above command should be run inside the 'pepbrowser' folder. Running the command would produce an output similar to the output below.

$ couchapp push
2011-06-22 21:53:45 [INFO] Visit your CouchApp here:
http://localhost:5984/pepbrowser/_design/pepbrowser/index.html

As indicated above, you could already visit the installed Couchapp using the link provided above. Visiting the above link in your browser wold display a page similar to the screen capture below.




By now, we have a working Couchapp. We will proceed with customizing the Couchapp.


Setup Initial View


As an initial page for this app, I want to setup a static html page with Jquerymobile working. I want to make sure that I could make Jquerymobile work inside a Couchapp. To start, I copied the 'index.html' file inside the '_attachments' directory to a new file 'main.html'. The 'main.html' is also located inside the '_attachments' folder. The 'main.html' page would be accessible through this url, http://localhost:5984/pepbrowser/_design/pepbrowser/main.html. But for this page to be accessible, you would have to run 'couchapp push' in order to push your changes to the server.


Before modifying the 'main.html' file, we would have to download and set-up the Jquerymobile files so that it could be loaded. I used Jquerymobile version 1.0a4.1 as I encountered some issues with the latest version. I'll try to update this later to the latest version if possible. Jquerymobile is composed of one javascript file, one CSS file and a folder of images. I copied the CSS file, 'jquery.mobile-1.0a4.1.min.css', to the 'style' directory inside the '_attachments' directory. I also copied to the 'style' directory the 'image' directory.






Inside the '_attachments' directory, I created a 'js' directory, which will contain javascript files. I placed inside that new directory the 'jquery.mobile-1.0a4.1.min.js' file. Now we have setup Jquerymobile inside our Couchapp.






One more thing. We need to add a newer version of Jquery to the 'js' directory. The reason for this is that the Couchapp comes with verion 1.4.2 which does not work with Jquerymobile 1.0a4.1. I tried upgrading to the latest version of Jquery, but it breaks Evently. After trying so many versions, the latest version of Jquery that works with both Evently and Jquerymobile 1.0a4.1 is version 1.4.4. So we get a minimized copy of that version and also place it inside the 'js' folder.




So now lets modify the 'main.html' file. It should now be similar to the following code.




<!doctype html>
<head>
  <title>PEP Browser</title>
  <link rel="stylesheet" href="style/jquery.mobile-1.0a4.1.min.css" type="text/css">
  <script src="js/myloader.js"></script>
</head>
<body>
  <div data-role="page">
    <div  data-role="header" data-theme="b">
      <h1>PEP Browser</h1>
    </div> 
<div  data-role="content">
 <div id="maincontent">
    <ul id="peplist" data-role="listview" data-theme="c" data-dividertheme="b">
 <li>
   <a href="#">Entry</a>
 </li>
 <li>
   <a href="#">Entry</a>
 </li>
 <li>
   <a href="#">Entry</a>
 </li>
 <li>
   <a href="#">Entry</a>
 </li>
 <li>
   <a href="#">Entry</a>
 </li>
</ul>
 </div>
</div> 
<div  data-role="footer" data-theme="b">
 <h1>Footer</h1>
</div>
  </div>
</body>
</html>





Notice some special tag attributes (data-role, data-theme) in the markup. This attributes are used by Jquerymobile. To better understand the above mark-up, check-out the Jquerymobile documentation. Its very easy to understand.


Another thing to notice in the code above is the link and script tag inside the header tag. The link tag is simply a reference to the Jquerymobile CSS located in the 'style' directory. The script tag refers to a custom javascript, myloader.js.


In the 'index.html' file in the '_attachments' directory, notice that it loads a javascript, 'loader.js'.



<!DOCTYPE html>
<html>
  <head>
    <title>My New CouchApp</title>
    <link rel="stylesheet" href="style/main.css" type="text/css">
  </head>
  <body>
    <div id="account"></div>


    <h1>Generated CouchApp</h1>


    <div id="profile"></div>
    <div id="items"></div>


    <div id="sidebar">
      <p>Edit welcome message.</p>
      <p>Ideas: You could easily turn this into a photo sharing app, or a grocery list, or a chat room.</p>
    </div>
  </body>
  <script src="vendor/couchapp/loader.js"></script>
  <script type="text/javascript" charset="utf-8">
    $.couch.app(function(app) {
      $("#account").evently("account", app);
      $("#profile").evently("profile", app);
      $.evently.connect("#account","#profile", ["loggedIn","loggedOut"]);
      $("#items").evently("items", app);
    });
  </script>
</html>



This script simply loads all the necessary Javascript files for the page to operate. Below is the code inside loader.js.


function couchapp_load(scripts) {
  for (var i=0; i < scripts.length; i++) {
    document.write('<script src="'+scripts[i]+'"><\/script>')
  };
};

couchapp_load([
  "/_utils/script/sha1.js",
  "/_utils/script/json2.js",
  "/_utils/script/jquery.js",
  "/_utils/script/jquery.couch.js",
  "vendor/couchapp/jquery.couch.app.js",
  "vendor/couchapp/jquery.couch.app.util.js",
  "vendor/couchapp/jquery.mustache.js",
  "vendor/couchapp/jquery.evently.js"
]);



Since we are loading some additional Javascript files and we would like to override the default Jquery version, I copied the contents of this loader.js into myloader.js and made some modifications. Its code resulting code of myloader.js follows.




function couchapp_load(scripts) {
  for (var i=0; i < scripts.length; i++) {
    document.write('<script src="'+scripts[i]+'"><\/script>')
  };
};

couchapp_load([
  "/_utils/script/sha1.js",
  "/_utils/script/json2.js",
  "js/jquery-1.4.4.min.js",
  "/_utils/script/jquery.couch.js",
  "vendor/couchapp/jquery.couch.app.js",
  "vendor/couchapp/jquery.couch.app.util.js",
  "vendor/couchapp/jquery.mustache.js",
  "vendor/couchapp/jquery.evently.js",
  "js/jquery.mobile-1.0a4.1.min.js"
]);



Note: I don't know if this is right, but I decided to put all script tags inside the <head> tag as i don't expect any loading delays as I plan to run this Couchapp in a local database, no network congestion. I might be wrong so feel free to leave a comment.


So now after all these changes to the boilerplate Couchap, we could push our changes to the Couchdb server using 'couchapp push' and view the 'main.html' page, http://localhost:5984/pepbrowser/_design/pepbrowser/main.html. The result when viewed in a regular browser would appear as follows.






Notice that the page looks to be more appropriate for a mobile browser.


Next Post


Next post, we will create an Evently widget for the listing of PEPs.





Tuesday, June 21, 2011

PEPBrowser: Introducing the Python PEP Browser

Introduction

Weeks ago I got interested in couchdb and also weeks ago a friend asks some advice regarding possible approaches in building a simple Android application, because of this I researched two topics, Couchdb and mobile application development. In my research, I discovered that this two topics intersect at some point, because Couchdb is being promoted in the mobile application domain through mobile Couchapps. This gave me an idea to combine my current research interests and develop a simple mobile Couchapp to further learn more about my current topics of interest.

As a simple project, I plan to develop a simple mobile app which lists down all Python Enhancement Proposals (PEPs), http://www.python.org/dev/peps/,  and allow the user to read each PEP. I chose this project as I found it useful from time to time to read PEPs to further understand Python language features. I doubt if this application would really be useful to anyone aside from me, but my intention is not to build a killer mobile app, but simply learn new software technologies.

Selected Software Technologies, Libraries, etc.

To implement this small project, I have chosen Couchdb to be the central technology. I plan to implement this project as a mobile Couchapp. In my research, I discovered that there are two ways of implementing Couchapps. One approach utilizes server-side scripts; this approach is discussed in chapters 10-14 of the book, "Couchdb: The Definitive Guide" (full text available at http://guide.couchdb.org/draft/index.html). Another approach utilizes client-side scripts; this approach uses the Evently Jquery plugin and is discussed in this page, http://couchapp.org/page/evently. I decided to use the client-side approach because I think its simpler than the server-side approach. Plus, I think that the main application of the server-side approach is for building web pages that should be friendly to search engines. Since this project is just a simple application which I intend to be served by a local mobile Couchdb server, it does not have to be friendly to search engine crawlers.

To easily create mobile application interfaces, I decided to use a mobile Javascript framework such as Jquerymobile, Sencha Touch, JQ Touch, etc. In the selection of which mobile Javascript  framework to use for this project,  I just went with my gut. I don't know why, but I felt most comfortable with using Jquerymobile. So for this project, I will use Jquerymobile for no clear reason.

Initial Research, Good Materials to Checkout to Understand the Technologies to be Used

Honestly, I got confused in my research on how to build Couchapps. This is because the book, "Couchdb: The Definitive Guide", discussed the use of server-side scripts in building Couchapps. Initially, I have decided to used the book, "Couchdb: The Definitive Guide", as my main reference. However, when I reached the chapters discussing how to create Couchapps I noticed that the book discussed a different approach than the one implemented in the latest version of the example application it used, https://github.com/jchris/sofa. I thought that the book was already outdated and the newer approach should be researched elsewhere. This lead me to the couchapp.org website, where I was able to learn about Evently and the Couchapps that primarily utilized client-side scripting.

It really took me sometime before I understood how to make Couchapps using Evently. I think this is because of the arrangement of the documentation in couchapp.org. Thus to help you get started with Couchapps and Evently faster, I have some suggestions.


  1. First, read chapters 1-9 of "Couchdb: The Definitive Guide". This chapters discusses the basics of Couchdb. There are also chapters dealing with Couchapps, but if you decide to use Evently, I think those chapters won't be as much help.
  2. Next, attentively watch and follow the Evently Guided Hackalong Screencast available through this url, http://www.youtube.com/watch?v=Xk5gaUURdJI. This would give you a jump start in learning how to use Evently and making Couchapps.
  3. To further reinforce what you learned in the screencast, read and follow this tutorial, http://couchapp.org/page/evently-do-it-yourself, and its succeeding tutorial, http://couchapp.org/page/evently-do-it-yourself-ii-state.
Following the above steps would enable you to learn Couchdb and Couchapps faster and prepare you to follow my posts regarding this project.

What to Expect in My Next Post

I have been writing for about an hour now (it's quite tiring), I'll end my blog post now but I'll give you some appetizers on what to expect in my next blog post.

Below are some screenshots on what I have implemented so far. Its not much since I haven't given much time, but I think its already quite substantial as a skeleton for the application.



I have also made available the code through github, https://github.com/nieldomingo/pepbrowser.

Monday, June 20, 2011

Initial Post

Years ago I started writing a blog which I eventually closed down. This is my second attempt in maintaining a blog. My old blog dealt with topics on energy and programming; this time, this blog would simply document my adventures in implementing small software projects. The initial project is an attempt to create a simple mobile couchapp.