<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Fernando Correia's Weblog &#187; pinax</title>
	<atom:link href="http://fernandoacorreia.wordpress.com/tag/pinax/feed/" rel="self" type="application/rss+xml" />
	<link>http://fernandoacorreia.wordpress.com</link>
	<description>A glimpse on my journey through software development</description>
	<lastBuildDate>Tue, 11 Nov 2008 00:57:20 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='fernandoacorreia.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/c020be056d4be6b57d45172e715d6fed?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Fernando Correia's Weblog &#187; pinax</title>
		<link>http://fernandoacorreia.wordpress.com</link>
	</image>
			<item>
		<title>Exploring Pinax Series</title>
		<link>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-series/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-series/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 11:26:36 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=314</guid>
		<description><![CDATA[Pinax is an integrated collection of selected Django reusable applications. It can be used as a head start for website projects and also to experiment patterns of Django applications.
As I learn how to leverage Pinax to build Web applications, I&#8217;m writing about my experiences. I plan to update this article and to use it as [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=314&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><a href="http://pinaxproject.com/">Pinax</a> is an integrated collection of selected <a href="http://www.djangoproject.com/">Django</a> reusable applications. It can be used as a head start for website projects and also to experiment patterns of Django applications.</p>
<p>As I learn how to leverage Pinax to build Web applications, I&#8217;m writing about my experiences. I plan to update this article and to use it as an index:</p>
<ul>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/">Part 1</a>:</strong> Installing Pinax.</li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/23/exploring-pinax-part-2/">Part 2</a>: </strong>Creating a new tab<strong>.<br />
</strong></li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/24/exploring-pinax-part-3/">Part 3</a>: </strong>Creating a new application inside a Pinax website.</li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/26/exploring-pinax-part-4/">Part 4</a>: </strong>The main domain object of the sample application.</li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/28/exploring-pinax-part-5/">Part 5</a>: </strong>A form for submitting new items.</li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/10/30/exploring-pinax-part-6/">Part 6</a>:</strong> Comments on approaches to revision control.</li>
<li><strong><a href="http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-part-7/">Part 7</a>: </strong>Notifications.</li>
</ul>
<p>The source code for the sample application is hosted on <a href="http://github.com/fernandoacorreia/oxybeles/tree/master">GitHub</a>.</p>
<p>I also have a <a href="http://fernandoacorreia.wordpress.com/tag/pinax/feed/"><strong>feed</strong></a> for my Pinax-related articles.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/314/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=314&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-series/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 7</title>
		<link>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-part-7/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-part-7/#comments</comments>
		<pubDate>Sat, 08 Nov 2008 11:22:14 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=300</guid>
		<description><![CDATA[I&#8217;m proceeding in my quest to learn how to create a Django application using Pinax as a base. I&#8217;m writing a sample paste bin application called Oxybeles. It&#8217;s main feature will be the ability to send pasted items to another user and to receive new pasted items as responses.
I want a user to be notified [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=300&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I&#8217;m proceeding in <a href="http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-series/">my quest</a> to learn how to create a <a href="http://www.djangoproject.com/">Django</a> application using <a href="http://pinaxproject.com/">Pinax</a> as a base. I&#8217;m writing a sample paste bin application called <a href="http://images.google.com/images?q=Oxybeles">Oxybeles</a>. It&#8217;s main feature will be the ability to send pasted items to another user and to receive new pasted items as responses.</p>
<p>I want a user to be <strong>notified</strong> when another user sends an item or responds to one. So I went looking how the applications integrated into Pinax do that. For instance, the Inbox feature in Pinax can be used to send a message to another website user:</p>
<p><img class="alignnone size-full wp-image-301" title="Compose Message" src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-1.png?w=340&#038;h=100" alt="" width="340" height="100" /></p>
<p>The Propose Swap feature of the Swaps application will also notify another user:</p>
<p><img class="alignnone size-full wp-image-302" title="Propose Swap" src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-2.png?w=337&#038;h=205" alt="" width="337" height="205" /></p>
<p>Those notifications can be seen in the Notices feature of the Inbox:</p>
<p><img class="alignnone size-full wp-image-303" title="Notices" src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-3.png?w=545&#038;h=177" alt="" width="545" height="177" /></p>
<p>By inspecting the source code for these features, I found out that they use the <a href="http://code.google.com/p/django-notification/"><strong>django-notification</strong></a> app. There is some <a href="http://pinaxproject.com/docs/trunk/external/notification/index.html">documentation</a> about it on the Pinax project website. So, I started following it.</p>
<h1>Creating notice types</h1>
<p>Following samples and <a href="http://pinaxproject.com/docs/trunk/external/notification/usage.html#creating-notice-types">documentation</a>, I created the file <strong>apps/oxybeles/management.py</strong> that creates notice types at syncdb time:</p>
<pre class="brush: python;">
from django.db.models import signals, get_app
from django.utils.translation import ugettext_noop as _
from django.core.exceptions import ImproperlyConfigured

try:
    notification = get_app('notification')

    def create_notice_types(app, created_models, verbosity, **kwargs):
        notification.create_notice_type(
            &quot;pasteditem_received&quot;,
            _(&quot;Pasted Item Received&quot;),
            _(&quot;you have received a pasted item&quot;))
        notification.create_notice_type(
            &quot;pasteditem_sent&quot;,
            _(&quot;Pasted Item Sent&quot;),
            _(&quot;you sent a pasted item&quot;))

    signals.post_syncdb.connect(create_notice_types, sender=notification)
except ImproperlyConfigured:
    print &quot;Skipping creation of NoticeTypes as notification app not found.&quot;
</pre>
<p>Then I ran syncdb:</p>
<pre>$ python manage.py syncdb
Created pasteditem_received NoticeType
Created pasteditem_sent NoticeType</pre>
<h1>Notification templates</h1>
<p>Then I created the templates that will be used to format the notifications. Each set is composed by three files: short.txt, full.txt and notice.html. For each notification type I created a directory under apps/oxybeles/templates/notification. For instance:</p>
<p><strong>apps/oxybeles/templates/notification/pasteditem_received/full.txt:</strong></p>
<pre class="brush: xml;">
{% load i18n %}{% blocktrans with pasted_item.get_absolute_url as pasted_item_url %}
{{ sender }} sent you a pasted item:

http://{{ current_site }}{{ pasted_item_url }}{% endblocktrans %}
</pre>
<p><strong>apps/oxybeles/templates/notification/pasteditem_sent/notice.html:</strong></p>
<pre class="brush: xml;">
{% load i18n %}
{% blocktrans with pasted_item.get_absolute_url as pasted_item_url %}
You sent a &lt;a href=&quot;{{ pasted_item_url }}&quot;&gt;pasted item&lt;/a&gt; to {{ recipient }}.
{% endblocktrans %}
</pre>
<h1>Sending notification</h1>
<p>After that I should be able to notify a user when someone sends a pasted item. The first step is to add an appropriate field to the pasted item detail template:</p>
<p><strong>templates/oxybeles/pasteditem_detail.html:</strong></p>
<pre class="brush: xml;">
...
&lt;h1&gt;Pasted Item&lt;/h1&gt;
&lt;pre&gt;
&lt;p&gt;{{ object.text }}&lt;/p&gt;
&lt;/pre&gt;
&lt;div id=&quot;basic-form&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;{% trans &quot;Send Item&quot; %}&lt;/legend&gt;
&lt;form id=&quot;pastebin_send_form&quot; method=&quot;POST&quot; action=&quot;&quot;&gt;
&lt;div&gt;{{ form.non_field_errors }}&lt;/div&gt;
&lt;div&gt;{{ form.recipient.errors }}&lt;/div&gt;
&lt;div&gt;Send to another user: {{ form.recipient }}&lt;/div&gt;
&lt;div&gt;&lt;input type=&quot;submit&quot; value=&quot;send&quot; class=&quot;button&quot; /&gt;&lt;/div&gt;
&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;send&quot; /&gt;
&lt;input type=&quot;hidden&quot; name=&quot;uuid&quot; value=&quot;{{ object.uuid }}&quot; /&gt;
&lt;/form&gt;
&lt;/fieldset&gt;
&lt;/div&gt;
...
</pre>
<p>And a form to deal with the submitted data:</p>
<p>In <strong>apps/oxybeles/forms.py</strong>:</p>
<pre class="brush: python;">
...
class SendItemForm(forms.Form):
    uuid = forms.CharField(max_length=36)
    recipient = forms.CharField(max_length=30)
...
</pre>
<p>The view that shows a pasted item now will also act on this form&#8217;s data:</p>
<p>In <strong>apps/oxybeles/views.py</strong>:</p>
<pre class="brush: python;">
...
def detail(request, uuid, form_class=SendItemForm, template_name='oxybeles/pasteditem_detail.html'):
    form = form_class()
    if request.method == 'POST':
        if request.POST[&quot;action&quot;] == &quot;send&quot;:
            form = form_class(sender=request.user, data=request.POST)
            if form.is_valid():
                form.save()
                request.user.message_set.create(
                    message=ugettext(&quot;The pasted item was sent.&quot;))
                url = form.pasted_item.get_absolute_url()
                return HttpResponseRedirect(url)
    pasted_item = get_object_or_404(PastedItem, uuid=uuid)
    return render_to_response(template_name,
                              { 'object': pasted_item, 'form': form },
                              context_instance=RequestContext(request))
detail = login_required(detail)
...
</pre>
<p>The <strong>form.save()</strong> function will notify the recipient and also the sender.</p>
<p>In <strong>apps/oxybeles/forms.py</strong>:</p>
<pre class="brush: python;">
...
def save(self):
    self.pasted_item = self.cleaned_data['uuid']
    self.recipient_user = self.cleaned_data['recipient']
    if notification:
        notification.send([self.sender], &quot;pasteditem_sent&quot;,
                            {'pasted_item': self.pasted_item,
                            'recipient': self.recipient_user,})
        notification.send([self.recipient_user], &quot;pasteditem_received&quot;,
                            {'pasted_item': self.pasted_item,
                            'sender': self.sender,})
...
</pre>
<p><a href="http://code.google.com/p/django-notification/"><strong>django-notification</strong></a> does all the work. It creates the notifications and will also mail the user if the preference is enabled. The email will only be sent when we run <strong>manage.py send_mail</strong>, though.</p>
<p>Now I can send a pasted item I&#8217;m seeing:</p>
<p><img src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-4.png?w=213&#038;h=322" alt="Sending a pasted item" title="Sending a pasted item" width="213" height="322" class="alignnone size-full wp-image-320" /></p>
<p>Those sendings are recorded as notifications:</p>
<p><img src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-5.png?w=403&#038;h=35" alt="Item sent notification" title="Item sent notification" width="403" height="35" class="alignnone size-full wp-image-321" /></p>
<p>And the recipient is notified when someone sends an item:</p>
<p><img src="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-6.png?w=450&#038;h=37" alt="Item received notification" title="Item received notification" width="450" height="37" class="alignnone size-full wp-image-322" /></p>
<p>Pinax is an integrated collection of selected reusable Django apps, and I&#8217;m starting to learn how to leverage it. Seems pretty nice so far.</p>
<p>The code for this article is hosted at <a href="http://github.com/fernandoacorreia/oxybeles/tree/225476e42b28d91fecbd664746afabb91a5fc538">GitHub</a>. Feedback is welcome.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/300/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/300/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/300/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=300&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/11/08/exploring-pinax-part-7/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-1.png" medium="image">
			<media:title type="html">Compose Message</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-2.png" medium="image">
			<media:title type="html">Propose Swap</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-3.png" medium="image">
			<media:title type="html">Notices</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-4.png" medium="image">
			<media:title type="html">Sending a pasted item</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-5.png" medium="image">
			<media:title type="html">Item sent notification</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/11/pinax-part7-6.png" medium="image">
			<media:title type="html">Item received notification</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 6</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/30/exploring-pinax-part-6/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/30/exploring-pinax-part-6/#comments</comments>
		<pubDate>Thu, 30 Oct 2008 22:53:26 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=293</guid>
		<description><![CDATA[I think this series of articles is starting to pay off&#8230; A few people are using my first article to learn how to set up a new Pinax website. And also, I am getting feedback on how to do things better.
On the pinax-users list, Bob Haugen pointed out that I was not following the recommended [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=293&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>I think this <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">series</a> of articles is starting to pay off&#8230; A few people are using my first article to learn how to set up a new Pinax website. And also, I am getting feedback on how to do things better.</p>
<p>On the pinax-users list, Bob Haugen <a href="http://groups.google.com/group/pinax-users/browse_thread/thread/699a6cd60cc89e22/7d9a3ef4c446b18a?hl=en#7d9a3ef4c446b18a">pointed out</a> that I was not following the recommended setup, because I was creating my new website inside Pinax&#8217;s project directory. There was no real harm, but he was right. I updated <a href="http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/">my instructions</a> so Pinax and the custom website are in separate directories.</p>
<p>As I wrote on the user list:</p>
<blockquote><p>Let me explain my motives. I use Subversion daily and I&#8217;m comfortable<br />
with it. I knew that just copying the directory would give me lots of<br />
trouble when I decided to update Pinax. So the &#8220;export&#8221; idea was<br />
natural.</p>
<p>I just exported it alongside the sample project because I was just<br />
starting to learn Pinax and didn&#8217;t want to mess too much with the<br />
structure because I didn&#8217;t know about its dependencies. I had read the<br />
customization doc, but it was not so clear to me at first sight.</p>
<p>But the official doc is right. I think we should consider Pinax more<br />
like a library, like Django itself, that should be installed and<br />
updated on its own, and the website we build should be a separate<br />
project, with its own version control. So it should be natural to put<br />
Pinax where we store random software (I used ~/opt) and our website<br />
where we put things we&#8217;re working on or software we deploy (I used<br />
~/Projects).</p></blockquote>
<p>I&#8217;m very grateful for the feedback and I hope this humble series may be helpful.</p>
<p>Cheers!</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/293/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/293/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/293/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=293&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/30/exploring-pinax-part-6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 5</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/28/exploring-pinax-part-5/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/28/exploring-pinax-part-5/#comments</comments>
		<pubDate>Tue, 28 Oct 2008 22:50:37 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=278</guid>
		<description><![CDATA[Proceeding with my project to learn how to develop a Django web application over Pinax, I build two simple forms: one for submitting a new item, and another to show an item.
As one reader commented, up to this point I&#8217;m not really using any Pinax feature other than the website structure itself, like authentication, templates [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=278&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Proceeding with <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">my project</a> to learn how to develop a Django web application over Pinax, I build two simple forms: one for submitting a new item, and another to show an item.</p>
<p>As one reader commented, up to this point I&#8217;m not really using any Pinax feature other than the website structure itself, like authentication, templates and menus. I&#8217;m starting with a basic Django application. I hope to add soon features like notification, messaging, tagging, gravatar.</p>
<p>So, in this sprint I started by defining two URLs:</p>
<ul>
<li><strong>/pastebin/</strong> to submit a new item</li>
<li><strong>/pastebin/&lt;uuid&gt;/</strong> to view a submitted item</li>
</ul>
<p>This is what my <strong>apps/oxybeles/urls.py</strong> file looks like:</p>
<pre class="brush: python;">
from django.conf.urls.defaults import *
from oxybeles.models import PastedItem

info_dict = {
    'queryset': PastedItem.objects.all(),
    'slug_field': 'uuid',
}

urlpatterns = patterns('',
    url(r'^$', 'oxybeles.views.new', name='oxybeles_new'),
    url(r'^(?P&lt;slug&gt;[-0-9a-f]{36})/$',
        'django.views.generic.list_detail.object_detail',
        info_dict,
        'oxybeles_detail'),
)
</pre>
<p>I also updated <strong>apps/oxybeles/models.py</strong> so it knows how to build a URL for a pasted item:</p>
<pre class="brush: python;">
def get_absolute_url(self):
    return ('oxybeles_detail', (), { 'slug': self.uuid })
get_absolute_url = models.permalink(get_absolute_url)
</pre>
<p>I wrote a simple form class in <strong>apps/oxybeles/forms.py</strong>:</p>
<pre class="brush: python;">
from django import forms
from django.utils.translation import ugettext_lazy as _ 

from oxybeles.models import PastedItem 

class PastedItemForm(forms.ModelForm):
    class Meta():
        model = PastedItem
        fields = ('text',)

    def __init__(self, user = None, *args, **kwargs):
        self.user = user
        super(PastedItemForm, self).__init__(*args, **kwargs)
</pre>
<p>And finally I wrote in <strong>apps/oxybeles/views.py </strong>the view function that is in charge of the form for submitting new items:</p>
<pre class="brush: python;">
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, get_host
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext, ugettext_lazy as _
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required

from oxybeles.models import PastedItem
from oxybeles.forms import PastedItemForm

def new(request, form_class=PastedItemForm, template_name=&quot;oxybeles/new.html&quot;):
    &quot;&quot;&quot;
    Form for pasting new items.
    &quot;&quot;&quot;
    form = form_class()
    if request.method == 'POST':
        if request.POST[&quot;action&quot;] == &quot;paste&quot;:
            form = form_class(request.user, request.POST)
            if form.is_valid():
                item = form.save(commit=False)
                item.user = request.user
                item.save()
                request.user.message_set.create(
                    message=ugettext(&quot;The new pasted item was saved.&quot;))
                    # some problem with ugettext_lazy here
                return HttpResponseRedirect(reverse('oxybeles_detail',
                                            args=(item.uuid,)))
    return render_to_response(template_name,
                              { &quot;form&quot;: form, },
                              context_instance=RequestContext(request))
new = login_required(new)
</pre>
<p>Finally, I wrote the two templates.</p>
<p><strong>templates/oxybeles/new.html:</strong></p>
<pre class="brush: xml;">
{% extends &quot;site_base.html&quot; %}

{% load i18n %}

{% block head_title %}{% trans &quot;Paste Bin&quot; %}{% endblock %}

{% block body %}
&lt;div id=&quot;basic-form&quot;&gt;
&lt;fieldset&gt;
&lt;legend&gt;{% trans &quot;New Item&quot; %}&lt;/legend&gt;
&lt;form id=&quot;pastebin_new_form&quot; method=&quot;POST&quot; action=&quot;&quot;&gt;
&lt;div&gt;{{ form.non_field_errors }}&lt;/div&gt;
&lt;div&gt;{{ form.text.errors }}&lt;/div&gt;
&lt;div&gt;{{ form.text }}&lt;/div&gt;
&lt;div&gt;&lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;paste&quot; /&gt;
&lt;input type=&quot;submit&quot; value=&quot;paste&quot; class=&quot;button&quot; /&gt;&lt;/div&gt;
&lt;/form&gt;
&lt;/fieldset&gt;
&lt;/div&gt;
{% endblock %}
</pre>
<p><strong>templates/oxybeles/pasteditem_detail.html:</strong></p>
<pre class="brush: xml;">
{% extends &quot;site_base.html&quot; %}

{% load i18n %}

{% block head_title %}{% trans &quot;Paste Bin&quot; %}{% endblock %}

{% block body %}
&lt;h1&gt;Pasted Item&lt;/h1&gt;
&lt;pre&gt;
&lt;p&gt;{{ object.text }}&lt;/p&gt;
&lt;/pre&gt;
{% endblock %}
</pre>
<p>And this is the final result:</p>
<p><strong>http://127.0.0.1:8000/pastebin/</strong></p>
<p><img class="alignnone size-full wp-image-280" title="New Pasted Item" src="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part5-01.png?w=355&#038;h=284" alt="" width="355" height="284" /></p>
<p><strong>http://127.0.0.1:8000/pastebin/47d33482-a936-453a-8d4a-88aada4ebc44/</strong></p>
<p><img class="alignnone size-full wp-image-282" title="View Pasted Item" src="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part5-021.png?w=345&#038;h=164" alt="" width="345" height="164" /></p>
<p>So, the basic app is in place. The source is in <a href="http://github.com/fernandoacorreia/oxybeles/tree/1af5676234f4ea1a29da3662e57fde92c052b2eb">GitHub</a>. In the next article I plan to implement a command to send a pasted item to a user, using Pinax&#8217;s features.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/278/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=278&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/28/exploring-pinax-part-5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part5-01.png" medium="image">
			<media:title type="html">New Pasted Item</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part5-021.png" medium="image">
			<media:title type="html">View Pasted Item</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 4</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/26/exploring-pinax-part-4/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/26/exploring-pinax-part-4/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 23:49:04 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=264</guid>
		<description><![CDATA[This is the fourth of a series of articles about my experience learning Pinax. In the previous articles I created a new option in the menu for a paste bin application and linked it to a very basic view.
My next step is to create a form for pasting text. I plan to do that using [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=264&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is the fourth of a <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">series of articles</a> about my experience learning <a href="http://pinaxproject.com/">Pinax</a>. In the previous articles I created a new option in the menu for a paste bin application and linked it to a very basic view.</p>
<p>My next step is to create a form for pasting text. I plan to do that using a form based on a model object. So the first thing I did was to write that model.</p>
<pre>$ gedit apps/oxybeles/models.py</pre>
<pre class="brush: python;">
from django.contrib.auth.models import User
from django.db import models
from django.utils.translation import ugettext_lazy as _
from uuid import uuid4

class PastedItem(models.Model):
    &quot;&quot;&quot;
    An item that was pasted.
    &quot;&quot;&quot;

    uuid = models.CharField(_('identifier'), max_length=36, unique=True)
    text = models.TextField(_('text'))
    in_response_to = models.ForeignKey('self', related_name='responses',
        blank=True, null=True, verbose_name=_('in response to'))
    user = models.ForeignKey(User, related_name=&quot;pasted_items&quot;,
        verbose_name=_('user'))
    pasted_at = models.DateTimeField(_('pasted at'), auto_now_add=True)

    def __unicode__(self):
        return self.uuid

    def save(self):
        if not self.uuid:
            self.uuid = str(uuid4())  # random so it can't be easily guessed
        super(PastedItem, self).save()
</pre>
<p>The <strong>uuid</strong> will be used later to refer to an object in a URL. It will be a random unique identifier. The <strong>text</strong> field is what the user pasted, and is the main content of this object.</p>
<p>I plan to allow responses to pasted items, so that two users can share different versions of the same text. The <strong>in_response_to</strong> field will be used for that.</p>
<p>Since now the application has a model object, I must tell Django about it:</p>
<pre>$ gedit settings.py</pre>
<p>Insert the application name inside the INSTALLED_APPS list:</p>
<pre class="brush: python;">
INSTALLED_APPS = (
...
    'oxybeles',
...
)
</pre>
<p>Then I was ready to review if the table would be created correctly:</p>
<pre>$ python manage.py sqlall oxybeles</pre>
<pre class="brush: sql;">
BEGIN;
CREATE TABLE &quot;oxybeles_pasteditem&quot; (
    &quot;id&quot; integer NOT NULL PRIMARY KEY,
    &quot;uuid&quot; varchar(36) NOT NULL UNIQUE,
    &quot;text&quot; text NOT NULL,
    &quot;in_response_to_id&quot; integer NULL,
    &quot;user_id&quot; integer NOT NULL REFERENCES &quot;auth_user&quot; (&quot;id&quot;),
    &quot;pasted_at&quot; datetime NOT NULL
)
;
CREATE INDEX &quot;oxybeles_pasteditem_in_response_to_id&quot;
ON &quot;oxybeles_pasteditem&quot; (&quot;in_response_to_id&quot;);
CREATE INDEX &quot;oxybeles_pasteditem_user_id&quot;
ON &quot;oxybeles_pasteditem&quot; (&quot;user_id&quot;);
COMMIT;
</pre>
<p>Finally, I updated the database structure:</p>
<pre>$ python manage.py syncdb</pre>
<p>To test this model, I defined an administrative interface:</p>
<pre>$ gedit apps/oxybeles/admin.py</pre>
<pre class="brush: python;">
from django.contrib import admin
from oxybeles.models import PastedItem

class PastedItemAdmin(admin.ModelAdmin):
    list_display = ('uuid', 'user', 'pasted_at',)
    fields = ('text', 'in_response_to', 'user',)

admin.site.register(PastedItem, PastedItemAdmin)
</pre>
<p>Starting the server again and browsing to <a href="http://127.0.0.1:8000/admin/oxybeles/pasteditem/">http://127.0.0.1:8000/admin/oxybeles/pasteditem/</a>, I was able to create a few pasted items to verify that all is working:</p>
<p><img class="alignnone size-full wp-image-271" title="Pasted Items Administrative Interface" src="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part4-01.png?w=744&#038;h=242" alt="" width="744" height="242" /></p>
<p>In the next step I will create the user interface to paste new items and to view stored items.</p>
<p>The source code is hosted on <a href="http://github.com/fernandoacorreia/oxybeles/tree/9f854acb9c9118a6717ff191d1bc9c41c352a08d">GitHub</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/264/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/264/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/264/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=264&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/26/exploring-pinax-part-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part4-01.png" medium="image">
			<media:title type="html">Pasted Items Administrative Interface</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 3</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/24/exploring-pinax-part-3/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/24/exploring-pinax-part-3/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 23:51:47 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=251</guid>
		<description><![CDATA[This is the third of a series of articles about my experience with the Pinax project. I am building a sample paste bin application named Oxybeles, of all things.
On the previous articles I installed Pinax and created a tab in the main menu for my new app. Now I want to create a basic view, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=251&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is the third of a <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">series of articles</a> about my experience with the <a href="http://pinaxproject.com/">Pinax</a> project. I am building a sample paste bin application named <a href="http://images.google.com/images?q=Oxybeles">Oxybeles</a>, of all things.</p>
<p>On the previous articles I installed Pinax and created a tab in the main menu for my new app. Now I want to create a basic view, but first I need to start a new Django app.</p>
<pre>$ python manage.py startapp oxybeles</pre>
<p>It seems that it would be appropriate to move it into the apps directory, so I did that:</p>
<pre>$ mv oxybeles/ apps/</pre>
<p>Here, I took a detour to create a <a href="http://github.com/fernandoacorreia/oxybeles/tree">GitHub repository</a> to host this application, but I won&#8217;t record my git sessions on this series, because the focus is on Pinax and Django.</p>
<p>After exploring a bit how other Pinax application URLs are set up, I decided to start by copying the pattern used in the &#8220;about&#8221; application.</p>
<p>I started by creating a basic template:</p>
<pre>$ mkdir templates/oxybeles
$ gedit templates/oxybeles/new.html</pre>
<p>I created the new file <strong>templates/oxybeles/new.html</strong> with this content:</p>
<pre>{% extends "site_base.html" %}

{% load i18n %}

{% block head_title %}{% trans "Paste Bin" %}{% endblock %}

{% block body %}
    {% blocktrans %}
        &lt;p&gt;This will be a form to post some text.&lt;/p&gt;
    {% endblocktrans %}
{% endblock %}</pre>
<p>Next, I created a new urls.py file inside the new app:</p>
<pre>$ gedit apps/oxybeles/urls.py</pre>
<pre class="brush: python;">
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template

urlpatterns = patterns('',
    url(r'^$',
        direct_to_template,
        {&quot;template&quot;: &quot;oxybeles/new.html&quot;},
        name=&quot;oxybeles_new&quot;),
)
</pre>
<p>Then I added the new application to the main <strong>urls.py</strong> file:</p>
<pre>$ gedit urls.py</pre>
<p>Around line 56, inside the urlpatterns list declaration, I inserted:</p>
<pre>(r'^pastebin/', include('oxybeles.urls')),</pre>
<p>And finally, I changed the menu option to link to the new URL:</p>
<p>$ gedit templates/site_base.html</p>
<p>Changing:</p>
<pre>&lt;td class="tab rtab_pastebin"&gt;&lt;div&gt;&lt;a href="#"&gt;{% trans "Paste Bin" %}&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;</pre>
<p>To:</p>
<pre>&lt;td class="tab rtab_pastebin"&gt;&lt;div&gt;&lt;a href="{% url oxybeles_new %}"&gt;{% trans "Paste Bin" %}&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;</pre>
<p>Now the <strong>Paste Bin</strong> menu item links to <a href="http://127.0.0.1:8000/pastebin/">http://127.0.0.1:8000/pastebin/</a> and that renders the <strong>oxybeles/new.html</strong> template that shows just:</p>
<pre>This will be a form to post some text.</pre>
<p>Good, the new app is linked to Pinax and the basic view is working. In the next article I&#8217;ll try to get a basic form working.</p>
<p>The application source code at this stage can be found in <a href="http://github.com/fernandoacorreia/oxybeles/tree/bc8a5567478a483b7e8182a0b5cee838806b5ff2">GitHub</a>.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/251/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/251/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/251/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/251/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/251/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/251/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/251/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/251/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/251/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/251/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=251&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/24/exploring-pinax-part-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 2</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/23/exploring-pinax-part-2/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/23/exploring-pinax-part-2/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 22:59:36 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=245</guid>
		<description><![CDATA[This is the second of a series of articles where I register what I learn about developing Web applications with Pinax.
In the first part I got the sample website running. Now I&#8217;m going to add a section for a new application.
I will develop a simple paste bin where people will be able to store small [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=245&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>This is the second of a <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">series of articles</a> where I register what I learn about developing Web applications with <a href="http://pinaxproject.com/">Pinax</a>.</p>
<p>In the <a href="http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/">first part</a> I got the sample website running. Now I&#8217;m going to add a section for a new application.</p>
<p>I will develop a simple <a href="http://en.wikipedia.org/wiki/Pastebin">paste bin</a> where people will be able to store small ammounts of text and send it to other people. I will try to write it as a reusable Django application and leverage Pinax&#8217;s features.</p>
<p>I will call this application <a href="http://images.google.com/images?q=Oxybeles"><strong>Oxybeles</strong></a>: an implement for throwing things, because when you paste something online you usually want to &#8220;throw&#8221; it to someone. Besides, a Greek name fits a Pinax app.</p>
<h1>Creating a new tab</h1>
<p>The first thing I wanted to do was to create a new tab in the site interface for the paste bin app. After searching a little I found out that the website tabs are defined in <strong>templates/site_base.html</strong> and that the actual text is stored in localizable resource files such as <strong>locale/en/LC_MESSAGES/django.po</strong>.</p>
<p>So I edited <strong>templates/site_base.html</strong> and inside the {% block right_tab %} section I inserted this line, among the others:</p>
<pre>&lt;td class="tab rtab_pastebin"&gt;&lt;div&gt;&lt;a href="#"&gt;{% trans "Paste Bin" %}&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;</pre>
<p>After that I thought I should edit <strong>locale/en/LC_MESSAGES/django.po</strong>. But it seemed autogenerated, so I went to learn how that works. <a href="http://docs.djangoproject.com/en/dev/topics/i18n/">Django&#8217;s documentation</a> is great. I quickly found out that internationalization is very easy and automatic in Django. While I&#8217;m developing I can just use the English text. If I want to update the translation files I can use this command at the project&#8217;s root dir:</p>
<pre>$ python manage.py makemessages -l en</pre>
<p>The first time, I got a message complaining that xgettext was not found. I corrected that by installing gettext:</p>
<pre>$ sudo aptitude install gettext</pre>
<p>After that, I generated the makemessages command again and I could see that <strong>locale/en/LC_MESSAGES/django.po</strong> was updated. I learned that I should also compile those files. But I reckon I&#8217;d only need to do that before a release, not during development.</p>
<p>So, with only a single new line in a template, I got the <strong>Paste Bin</strong> tab:</p>
<p><img class="alignnone size-full wp-image-247" title="Paste Bin tab" src="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part2-011.png?w=397&#038;h=47" alt="" width="397" height="47" /></p>
<p>In the next step I will develop a basic view for this tab and maybe start the model object.</p>
<p>Your feedback is welcome.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/245/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=245&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/23/exploring-pinax-part-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part2-011.png" medium="image">
			<media:title type="html">Paste Bin tab</media:title>
		</media:content>
	</item>
		<item>
		<title>Exploring Pinax &#8211; Part 1</title>
		<link>http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/</link>
		<comments>http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 23:13:27 +0000</pubDate>
		<dc:creator>fernandoacorreia</dc:creator>
				<category><![CDATA[Software Development]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[pinax]]></category>

		<guid isPermaLink="false">http://fernandoacorreia.wordpress.com/?p=228</guid>
		<description><![CDATA[What this is about
After learning how to build a Flex client and a Python server running on Google App Engine, I decided to try a pure-Web, pure-Python alternative. I chose Django, a first-class Web framework. I went through the tutorial and read the excellent book Practical Django Projects. The next step is building a website [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=228&subd=fernandoacorreia&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h1>What this is about</h1>
<p>After learning how to build a Flex client and a Python server running on Google App Engine, I decided to try a pure-Web, pure-Python alternative. I chose <strong><a href="http://www.djangoproject.com/">Django</a></strong>, a first-class Web framework. I went through the <a href="http://docs.djangoproject.com/en/dev/intro/tutorial01/">tutorial</a> and read the excellent book <a href="http://www.amazon.com/Practical-Django-Projects-Pratical/dp/1590599969">Practical Django Projects</a>. The next step is building a website with some applications.</p>
<p>Fortunately, I found out about the <a href="http://pinaxproject.com/"><strong>Pinax</strong></a> project. It builds a website framework over Django and provides patterns for interoperable applications. I decided to learn how to leverage it so I can learn best practices and use some of its nice features like notifications.</p>
<p>I will do my learning in the open, as I did <a href="http://fernandoacorreia.wordpress.com/2008/08/23/example-of-ria-in-the-cloud/">before</a>, sharing my path and my discoveries. This is a journey from the eyes of a n00b that knows very little about Python, Django and Pinax.</p>
<p>I found out that this process helps me focus and structure my self-learning. I hope it may be useful to someone that follows the same path. And maybe someone more knowledgeable will correct one or two of the bloopers I make.</p>
<h1>Installing Pinax</h1>
<p>I started in a development environment that was already configured to run Django applications and had its fair share of tools, like a <strong>Subversion</strong> client and <strong>sendmail</strong>. You will have to refer to basic Django and Python material if you need to learn how to get to this point. Also, all my work is being done on <strong>Ubuntu 8.10</strong>, so you may need to adjust some commands if you use other environment.</p>
<p><strong>Making a directory for Pinax:</strong></p>
<pre>$ mkdir ~/opt/django -p
$ cd ~/opt/django</pre>
<p>Downloading Pinax and associated applications and libraries:</p>
<pre>$ svn checkout http://svn.pinaxproject.com/pinax/trunk/ pinax</pre>
<p>I am using version 0.5.0rc1. Things might be different if you use a newer version.</p>
<h1>Creating a sample project</h1>
<p><em><strong>Edit:</strong> I changed these instructions twice, first to reflect <a href="http://pinaxproject.com/docs/0.5.0/customization.html">best practices</a>, thanks to <a href="http://groups.google.com/group/pinax-users/browse_thread/thread/699a6cd60cc89e22/7d9a3ef4c446b18a?hl=en#7d9a3ef4c446b18a">a tip</a> by Bob Haugen and later when Pinax was updated to require only changes in settings.py and not in manage.py.<br />
</em></p>
<p>Pinax comes with a sample project that can be used directly, but I will create an independent clone that I can change at will without getting in trouble with repository updates later.</p>
<pre>$ cd pinax/projects/
$ svn export complete_project/ ~/Projects/exploring_pinax</pre>
<p>Now we must edit settings.py to reflect the directory where we installed Pinax:</p>
<pre>$ cd ~/Projects/exploring_pinax
$ vi settings.py</pre>
<p>Change PINAX_ROOT to the main Pinax directory. For instance:</p>
<pre>...
PINAX_ROOT = '/home/fernando/opt/django/pinax'
...</pre>
<p>Also set ROOT_URLCONF using the name of the directory you exported the website project to:</p>
<pre>...
ROOT_URLCONF = 'exploring_pinax.urls'
...</pre>
<p>After that, save settings.py.</p>
<p>If we want, we can also create a file for future local settings like database passwords. I won&#8217;t use it now, but it may be handy to have it already created:</p>
<pre>$ touch local_settings.py</pre>
<p>Now create the local sqlite3 database:</p>
<pre>$ python manage.py syncdb</pre>
<p>When asked, create a superuser (admin).</p>
<h1>Starting the website</h1>
<pre>$ python manage.py runserver</pre>
<p>Open <a href="http://127.0.0.1:8000/">http://127.0.0.1:8000/</a> in your browser. You should have a Pinax website running. Congratulations! Login with your superuser and explore at leisure.</p>
<p><img class="alignnone size-full wp-image-236" title="Sample Pinax website" src="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part1-01.png?w=583&#038;h=453" alt="" width="583" height="453" /></p>
<p>If you want to follow this series, browse <a href="http://fernandoacorreia.wordpress.com/tag/pinax/">http://fernandoacorreia.wordpress.com/tag/pinax/</a> for more articles or subscribe to my <a href="http://fernandoacorreia.wordpress.com/feed/">feed</a>.</p>
<p>Your feedback is most welcome.</p>
  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/fernandoacorreia.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/fernandoacorreia.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/fernandoacorreia.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/fernandoacorreia.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/fernandoacorreia.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/fernandoacorreia.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/fernandoacorreia.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/fernandoacorreia.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/fernandoacorreia.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/fernandoacorreia.wordpress.com/228/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=fernandoacorreia.wordpress.com&blog=4230505&post=228&subd=fernandoacorreia&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://fernandoacorreia.wordpress.com/2008/10/22/exploring-pinax-part-1/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1ab5a45161c183997bce5249d3c46473?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">fernandoacorreia</media:title>
		</media:content>

		<media:content url="http://fernandoacorreia.files.wordpress.com/2008/10/pinax-part1-01.png" medium="image">
			<media:title type="html">Sample Pinax website</media:title>
		</media:content>
	</item>
	</channel>
</rss>