This is the third and the final part in the tutorial series, ‘Setting up an Amzon Product Store on Google App Engine’. Please go through the first 2 parts before you continue further. Here are the links:

Okay guys, thank you for your patience and your enthusiasm to learn, and sorry for my ‘very draggy sometimes’ style of writing! This is the last part in this series and we’ll see how to loop through the ‘books’ list for displaying the books properly in a tabular format on the results page.

Create a new file ‘results.html’ in our app’s folder and put the following code in it:

[html]
<html>
<head>
<title>Amazing Amazon Store</title>
<link type=’text/css’ rel=’stylesheet’ href=’/stylesheets/style.css’ />
</head>
<body>
<div id=’wrapper’>
<div id=’head’>
<p>You bought it here!</p>
<span>Buy anything you want from Amazon. Best quality, best price!</span>
</div>
<div id=’nav’>
<ul>
<li><a href =’/’>Home</a></li>
<li><a href =’http://www.blog.rutwick.com’>Learn to make it!</a></li>
</ul>
</div>
<div id=’content’>
<table valign=’top’>
{% for book in books %}
<tr>
<td >
<a href='{{book.details}}’><img src='{{book.image}}’ alt=’Click to see details’ /></a>
</td>
<td><span class=’title’>{{ book.title }}</span>
<br />
<span class=’author’>{{book.author|check}}</span>
<br />
<span class=’asin’>{{book.asin}}</span>
<br />
<a class=’details’ href='{{book.details}}’>More…</a>
</td>
</tr>
{% endfor %}
</table>
</div>
<div id=’footer’>
<p>2011. All rights reserved.</p>
</div>
</div>
</body>
</html>
[/html]

We’re looping through the books list in the ‘content’ div. This is how you write a template for a GAE app. ‘index.html’ was plain html/css, so there weren’t any template specific tags. But the ‘results.html’ file has a lot of template specific code. We’re looping through the ‘books’ list object, which has a dictionary object per book. Then we access the properties for every book using the ‘dot’ syntax. Take a look at the line where we’re accessing the book’s author. It’s written as ‘book.author | check’. A single book can have multiple authors, which will be returned in the form of a list object. We have to join these names as a single string. So if a book has 2 authors say a and b, which will be returned as a list object by the ‘xml2obj’ module, [‘a’, ‘b’], then the resultant string should be ‘a, b’. We can’t do the checking here within the template. This is where the custom template tag ‘check’ comes in picture. We pass the ‘book.author’ to the ‘check’ function (this is how you pass an argument to a custom template function) which checks if it’s a list object with multiple authors, and joins them in a single string. Let’s see how to register our custom template tag ‘check’.

Create a new folder in our app’s folder. Name it as ‘customtags’ (you can name it anything you want, but make sure to name it something small and easy, we’re going to use the folder name in our code). Create an empty Python file in it, name it as ‘__init__.py’. Now create another Python file and put the following code in it:

[python]
from google.appengine.ext.webapp import template
register = template.create_template_register()

def check(key):
if type(key)==type(list()):
item = ‘, ‘.join(key)
return item
else:
return key

register.filter(‘check’, check)
[/python]

Save this as ‘check.py’ in the ‘customtags’ folder. The check function takes one argument, checks if the argument is a ‘list’ object, and if it is, the joins them as a single string with commas inserted in between the values. If not a ‘list’ object, then returns the ‘key’ as it is. The ‘register.filter’ function means, whenever the term ‘check’ is used in the template, call the ‘check’ function.
To include this custom template tag in our app, we have to make little change in the ‘amazon.py’ file. Add the following code at the top after all the import statements in the ‘amazon.py’ file:

[python]
template.register_template_library(‘customtags.check’)
[/python]

This registers the ‘check.py’ file from the ‘customtags’ folder ( ‘check’ without the ‘.py’ extension). If you named the folder as ‘abc’ and the custom template tag file as ‘xyz.py’, then you’d register it here as ‘template.register_template_library(‘abc.xyz’). That’s it! Our template tag ‘check’ can now be used in the templates.

Run the app using the command ‘dev_appserver.py and visit the url, http://localhost:8080/.

Enter a keyword in the form and click submit (Make sure your internet connection is on when you test the app). You should see a books list in a tabular format on the results page. (See the demo please, its exactly the same as we’ve build along)

What’s left is uploading the app on the actual GAE server. Head on to http://appengine.google.com, use your google account to login and register an ID for our app. Copy this ID and replace ‘blogapp’ with this ID in the ‘app.yaml’ config file. Now use the ‘appcfg.py update ‘ command to upload the app to the GAE server. It will take some time to upload. Once done, visit the url http://www..appspot.com, to see the app in action.

Congrats guys… You have your Amazon book store set up on Google App Engine. Everytime someone purchases a book via your website, you get paid for it!

Please help me make this post better. I don’t have the best writing style you ever came across, but that doesn’t stop me from spreading the knowledge! Any suggestions, comments, criticism are welcome! Contact me at mail@rutwick.com, Twitter: @tweetrut.

By rutwick

6 thoughts on “Set up an Amazon Book Store on Google App Engine – 3 – Display the books list on the results page”
    1. Thanks a lot Sidhant… your feedback is valuable!
      I’m experimenting with a couple of other frameworks with GAE… readers can expect more on it!

  1. Hi Rutwick, Nice piece of work. I’m a total newbie on GAE, but the tutorial was very easy to understand. Please keep writing. Thanks

    1. Hi Waruna,
      Very sorry for replying late, been a little busy!
      Thanks a lot, I’m glad it helped you! I will definitely write more on GAE, I’m a big GAE fan!
      -Rutwick

Leave a Reply to Waruna Cancel reply

Your email address will not be published. Required fields are marked *