<?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>TurboGears Notes</title>
	<atom:link href="http://tglogs.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://tglogs.wordpress.com</link>
	<description>A blog on TurboGears and Python web development</description>
	<lastBuildDate>Tue, 09 Apr 2013 11:59:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='tglogs.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>TurboGears Notes</title>
		<link>http://tglogs.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://tglogs.wordpress.com/osd.xml" title="TurboGears Notes" />
	<atom:link rel='hub' href='http://tglogs.wordpress.com/?pushpress=hub'/>
		<item>
		<title>TurboGears and AJAX</title>
		<link>http://tglogs.wordpress.com/2012/04/13/turbogears-and-ajax/</link>
		<comments>http://tglogs.wordpress.com/2012/04/13/turbogears-and-ajax/#comments</comments>
		<pubDate>Fri, 13 Apr 2012 20:14:41 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[TurboGears AJAX]]></category>
		<category><![CDATA[TurboGears jQuery]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=98</guid>
		<description><![CDATA[Many beginner web developers ask questions like &#8220;how do i do something without refreshing page?&#8221; or &#8220;how can i load another page in my page?&#8221; etc. The answer is AJAX. AJAX stands for &#8220;Asynchronous JavaScript and XML&#8221;. With AJAX, you &#8230; <a href="http://tglogs.wordpress.com/2012/04/13/turbogears-and-ajax/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=98&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Many beginner web developers ask questions like &#8220;how do i do something without refreshing page?&#8221; or &#8220;how can i load another page in my page?&#8221; etc. The answer is AJAX. AJAX stands for &#8220;Asynchronous JavaScript and XML&#8221;. With AJAX, you can retrieve or send data to the server in the background using an &#8220;XMLHttpRequest.&#8221;</p>
<p><img class="alignleft" src="http://tglogs.files.wordpress.com/2012/04/well_actually_trollcat.jpg?w=237&#038;h=292" alt="Troll Cat" width="237" height="292" align="center" /></p>
<p>Before going further, i would like to take your time and advise you to learn JavaScript. If you are a web developer, no matter if you are back-end or front-end one, at some point in your career you will have to use JavaScript. In order to be ready for those times, go and learn JavasSript. There are awesome resources.</p>
<p>Do not be one of those people who think learning jQuery is enough and how you don&#8217;t need to know JavaScript. jQuery is a JS framework. It&#8217;s a great one and that&#8217;s all. Learn JavaScript.</p>
<p>There are many techniques to use AJAX in a web application. In these examples we are going to use jQuery framework and it&#8217;s powerful &#8220;$.get&#8221; and &#8220;$.post&#8221; methods.</p>
<p>Open up your terminal, cd into your TurboGears environment, activate it, upgrade it to the most recent version which is 2.1.5 with: </p>
<pre><code>easy_install -U -i http://tg.gy/current tg.devtools</code></pre>
<p>Go to your controllers/root.py and change the index action like this:</p>
<pre><code>@expose('ideas.templates.index')
def index(self):
    """Handle the front-page."""
    projects = DBSession.query(Project).all()
    return dict(page='index', projects=projects)
</code></pre>
<p>And this is our new &#8220;templates/index.mak&#8221;:</p>
<pre><code>&lt;%inherit file=&quot;local:templates.master&quot;/&gt;

&lt;%def name=&quot;title()&quot;&gt;
  Welcome to IDEAS.
&lt;/%def&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
$(function(){
    $(&quot;a.project_link&quot;).click(function(){
        var context = this;
        $.get(this.href, function(response){
            $(context).parent().next().html(response);
        });
        return false;
    });
});
&lt;/script&gt;

&lt;div style=&quot;margin-bottom: 50px;&quot;&gt;
    &lt;h1&gt;Projects&lt;/h1&gt;
    % for project in projects:
        &lt;div class=&quot;project&quot;&gt;
            &lt;div style=&quot;margin-bottom: 5px;&quot;&gt;&lt;a class=&quot;project_link&quot; href=&quot;${url('/show_tasks/%s' % project.id)}&quot;&gt;${project.project_name}&lt;/a&gt;&lt;/div&gt;
        &lt;div class=&quot;tasks&quot;&gt;&lt;/div&gt;
    % endfor
&lt;/div&gt;

&lt;%def name=&quot;sidebar_bottom()&quot;&gt;&lt;/%def&gt;
</code></pre>
<p>In our &#8220;show_tasks.mak&#8221; template:</p>
<ul>
<li>We are listing the projects in a for loop.</li>
<li>We create a &#8220;div&#8221; element with the class &#8220;tasks&#8221; to use in our JavaScript.</li>
<li>We include jQuery framework via Google CDN.</li>
</ul>
<p>So whenever we click to a project&#8217;s link, its tasks will be listed under the &#8220;tasks&#8221; div.</p>
<p>Let me walk you through the simple JavaScript codes we wrote. </p>
<p>In the first line, we tell jQuery &#8220;when the DOM is ready&#8221;, use all these child scripts of yours. So it attaches the event listener, changes css classes, anything we want to do.</p>
<p>In the second line, we tell, whenever an &#8220;a&#8221; element with a &#8220;project_link&#8221; class is clicked, create an AJAX request and append the result to the closest div with the class &#8220;tasks&#8221; to the &#8220;a&#8221; element&#8217;s parent.</p>
<p>In JavaScript, whenever a new scope is opened like the second line, the keyword &#8220;this&#8221; changes meaning. In line 3 of our script, it references to the clicked &#8220;a&#8221; element however in the line 5 it references the response object. This is why I have created the &#8220;context&#8221; variable and mapped it to &#8220;this&#8221; which is the clicked &#8220;a&#8221; element. This way, I am able to use the clicked a element.</p>
<p>We are missing two things here. The corresponding TurboGears action and it&#8217;s template. So let&#8217;s create them. In your RootController, add the following action:</p>
<pre><code>@expose('ideas.templates.show_tasks')
def show_tasks(self, project_id):
    tasks = DBSession.query(Task).filter_by(project_id=project_id).all()
    return dict(tasks=tasks)
</code></pre>
<p>And the following goes by &#8220;show_tasks.mak&#8221; under the &#8220;templates&#8221; directory.</p>
<pre><code>% if tasks:
    % for task in tasks:
        &lt;div&gt;${task.task_name}&lt;/div&gt;
    % endfor
% else:
    &lt;div&gt;This project does not have any tasks, yet.&lt;/div&gt;
% endif</code></pre>
<p>That&#8217;s all. Run your server and open it up in your browser. Let&#8217;s see how it goes.</p>
<p>In the next post, I will show you how to use the $.post method and deal with JSON responses from the server when using AJAX. I hope you guys enjoyed all these. Please do not hesitate to ask any question. You are more than welcome.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/98/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=98&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/04/13/turbogears-and-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>

		<media:content url="http://tglogs.files.wordpress.com/2012/04/well_actually_trollcat.jpg" medium="image">
			<media:title type="html">Troll Cat</media:title>
		</media:content>
	</item>
		<item>
		<title>Querying The Models</title>
		<link>http://tglogs.wordpress.com/2012/03/28/querying-the-models/</link>
		<comments>http://tglogs.wordpress.com/2012/03/28/querying-the-models/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 22:02:33 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLAlchemy]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Python ORM]]></category>
		<category><![CDATA[Python web]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=81</guid>
		<description><![CDATA[If you remember the post that we created the models in, you will also remember that TurboGears uses SQLAlchemy for the model part of MVC. Now, we are going to do some practice on querying the models. In the meanwhile, &#8230; <a href="http://tglogs.wordpress.com/2012/03/28/querying-the-models/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=81&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you remember<a href="http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/"> the post that we created the models in</a>, you will also remember that TurboGears uses SQLAlchemy for the model part of MVC. </p>
<p>Now, we are going to do some practice on querying the models. In the meanwhile, you will discover the TurboGears console. Let&#8217;s get into our project&#8217;s home dir and start the console.</p>
<pre><code>cd ~/projects/tg2env/ideas
source ../bin/activate
paster shell development.ini</code></pre>
<p>Let&#8217;s import our models and the DBSession object from ideas/model. At first, we are going to create some projects and tasks. When using queries, you will see which queries are running.</p>
<pre><code>from ideas.model import DBSession, Project, Task
p1 = Project(project_name="TurboGears Shell Project")
p2 = Project(project_name="TurboGears Blog Project")
DBSession.add(p1)
DBSession.add(p2)
DBSession.flush()
t1 = Task(project_id=p1.id, task_name="Extend the shell", status="open")
t2 = Task(project_id=p2.id, task_name="Create the models", status="closed")
t3 = Task(project_id=p2.id, task_name="Use Twitter Bootstrap in the templates", status="open")
DBSession.add(t1)
DBSession.add(t2)
DBSession.add(t3)
DBSession.flush()
</code></pre>
<p>We have created two projects, the first project has 1 open task, second project has 2 tasks; 1 open and 1 closed. We are going to start with the basics.  </p>
<p>As the first step, let&#8217;s query all projects.</p>
<pre><code>DBSession.query(Project).all()
# output:
00:30:09,385 INFO  [sqlalchemy.engine.base.Engine] SELECT projects.id AS projects_id, projects.project_name AS projects_project_name, projects.project_description AS projects_project_description 
FROM projects
00:30:09,385 INFO  [sqlalchemy.engine.base.Engine] ()
[&lt;ideas.model.project.Project object at 0x4161bd0&gt;, &lt;ideas.model.project.Project object at 0x40982d0&gt;, &lt;ideas.model.project.Project object at 0x40a42d0&gt;]
</code></pre>
<p>I had 3 projects in my &#8220;ideas&#8221; app so it returned all 3. </p>
<p>Let&#8217;s order the projects by their name in the ascending order.</p>
<pre><code>projects = DBSession.query(Project).order_by(Project.project_name.asc()).all()

&gt;&gt;&gt; for p in projects: print p.project_name
... 
TurboGears Blog Project
TurboGears Project Management
TurboGears Shell Project</code></pre>
<p>Now we are going to list all open tasks of &#8220;TurboGears Blog Project&#8221;.</p>
<pre><code>DBSession.query(Task).filter(Task.project_id == p2.id).filter(Task.status == "open").all()
&gt;&gt;&gt; for task in tasks: print task.task_name
... 
Use Twitter Bootstrap in the template
</code></pre>
<p>SQLAlchemy has an expression called &#8220;and_&#8221; so we can write the above query like this:</p>
<pre><code>&gt;&gt;&gt; from sqlalchemy.sql.expression import and_
&gt;&gt;&gt; DBSession.query(Task).filter(and_(Task.project_id == p2.id, Task.status == "open")).all()
&gt;&gt;&gt; for task in tasks: print task.task_name
... 
Use Twitter Bootstrap in the templates</code></pre>
<p>And we are going to update the &#8220;Use Twitter Bootstrap in the template&#8221; task and set its status to &#8220;closed&#8221;.</p>
<p><code>
<pre>DBSession.query(Task).filter(Task.id == t3.id).update({"status": "closed"})
00:45:53,126 INFO  [sqlalchemy.engine.base.Engine] UPDATE tasks SET status=? WHERE tasks.id = ?
00:45:53,126 INFO  [sqlalchemy.engine.base.Engine] ('closed', 4)
&gt;&gt;&gt; t3.status
'closed'
</code></pre>
<p>And let's delete all the tasks of "TurboGears Shell Project".</p>
<pre><code>DBSession.query(Task).filter_by(project_id=t1.id).delete()
00:59:01,585 INFO  [sqlalchemy.engine.base.Engine] DELETE FROM tasks WHERE tasks.project_id = ?
00:59:01,585 INFO  [sqlalchemy.engine.base.Engine] (2,)
</code></pre>
<p>For more on SQLAlchemy, please go read on <a href="http://docs.sqlalchemy.org/en/latest/orm/query.html">http://docs.sqlalchemy.org/en/latest/orm/query.html</a> and you can do the <a href="http://docs.sqlalchemy.org/en/latest/orm/tutorial.html">Object Relation Tutorial</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=81&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/28/querying-the-models/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>
	</item>
		<item>
		<title>A Simple Project Management Tool With TurboGears &#8211; Templates</title>
		<link>http://tglogs.wordpress.com/2012/03/28/a-simple-project-management-tool-with-turbogears-templates/</link>
		<comments>http://tglogs.wordpress.com/2012/03/28/a-simple-project-management-tool-with-turbogears-templates/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 18:07:03 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Mako]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Templates]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Mako templates]]></category>
		<category><![CDATA[Python web]]></category>
		<category><![CDATA[Python web framework]]></category>
		<category><![CDATA[Web framework]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=70</guid>
		<description><![CDATA[We have created our models, created our controller actions and forms. Now we are going to set up our templates. Let&#8217;s take a look at the controller action &#8220;new_project&#8221;: @expose('ideas.templates.new_project') def new_project(self): """ Displays the project form. """ return dict(project_form=project_form) &#8230; <a href="http://tglogs.wordpress.com/2012/03/28/a-simple-project-management-tool-with-turbogears-templates/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=70&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>We have created our models, created our controller actions and forms. Now we are going to set up our templates. Let&#8217;s take a look at the controller action &#8220;new_project&#8221;:</p>
<pre><code>
@expose('ideas.templates.new_project')
def new_project(self):
    """ Displays the project form. """
    return dict(project_form=project_form)
</code></pre>
<p>In this action, we tell TurboGears that when new_project action is called, we are going to render it with &#8220;new_project.mak&#8221; file in the &#8220;templates&#8221; folder. We also pass &#8220;project_form&#8221; variable to the template. </p>
<p>Let&#8217;s create our templates. This is the content of new_project.mak:</p>
<pre><code>&lt;!-- ideas/templates/new_project.mak --&gt;
&lt;%inherit file=&quot;local:templates.master&quot;/&gt;

&lt;%def name=&quot;title()&quot;&gt;Project Form&lt;/%def&gt;

${project_form()|n}</code></pre>
<p>This is the content of new_task.mak:</p>
<pre><code>&lt;!-- ideas/templates/new_task.mak --&gt;
&lt;%inherit file=&quot;local:templates.master&quot;/&gt;

&lt;%def name=&quot;title()&quot;&gt;Task Form&lt;/%def&gt;

${task_form()|n}
</code></pre>
<p>And this is the content of show_project.mak:</p>
<pre><code>&lt;!-- ideas/templates/show_project.mak --&gt;
&lt;%inherit file=&quot;local:templates.master&quot;/&gt;

&lt;%def name=&quot;title()&quot;&gt;${project.project_name}&lt;/%def&gt;

&lt;h1&gt;${project.project_name}&lt;/h1&gt;
&lt;div&gt;${project.project_description}&lt;/div&gt;

&lt;h2&gt;Tasks&lt;/h2&gt;
&lt;ul&gt;
    % for task in tasks:
        &lt;li&gt;${task.task_name}&lt;/li&gt;
    % endfor 
&lt;/ul&gt;
</code></pre>
<p>Now start your web server and visit &#8220;<a href="http://127.0.0.1:8080/new_project">http://127.0.0.1:8080/new_project</a>&#8221; and see how the project creation form looks like:</p>
<p><img src="http://tglogs.files.wordpress.com/2012/03/screenshot-1.png?w=640" alt="Project Creation Form" /></p>
<p>And let&#8217;s head to task creation page at &#8220;<a href="http://127.0.0.1:8080/new_task">http://127.0.0.1:8080/new_task</a>&#8220;:</p>
<p><img src="http://tglogs.files.wordpress.com/2012/03/screenshot-2.png?w=640" alt="Task Creation Form" /></p>
<p>Go ahead and play with it. Do something yourself. For more on the templates you can visit <a href="http://docs.makotemplates.org/en/latest/index.html">mako documentation</a>. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/70/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/70/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=70&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/28/a-simple-project-management-tool-with-turbogears-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>

		<media:content url="http://tglogs.files.wordpress.com/2012/03/screenshot-1.png" medium="image">
			<media:title type="html">Project Creation Form</media:title>
		</media:content>

		<media:content url="http://tglogs.files.wordpress.com/2012/03/screenshot-2.png" medium="image">
			<media:title type="html">Task Creation Form</media:title>
		</media:content>
	</item>
		<item>
		<title>A Simple Project Management Tool With TurboGears &#8211; Setting Up the Forms</title>
		<link>http://tglogs.wordpress.com/2012/03/27/a-simple-project-management-tool-with-turbogears-setting-up-the-forms/</link>
		<comments>http://tglogs.wordpress.com/2012/03/27/a-simple-project-management-tool-with-turbogears-setting-up-the-forms/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 16:39:18 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[ToscaWidgets]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Python web]]></category>
		<category><![CDATA[Python web framework]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=43</guid>
		<description><![CDATA[In the previous post, we have created our Project and Task models. Now we have to create our forms. It is very easy to create forms with TurboGears. In this example we are going to use ToscaWidgets 1 however keep &#8230; <a href="http://tglogs.wordpress.com/2012/03/27/a-simple-project-management-tool-with-turbogears-setting-up-the-forms/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=43&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><a href="http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/">In the previous post</a>, we have created our Project and Task models. Now we have to create our forms.</p>
<p>It is very easy to create forms with TurboGears. In this example we are going to use ToscaWidgets 1 however keep in mind that in the next major TurboGears release, TurboGears will switch to ToscaWidgets 2.</p>
<p>HTML forms consist of a form element and its child elements called input. In these examples, we are going to create forms in Pytho thon with the help of ToscaWidgets library and render these forms in our templates.</p>
<p>This is a simple example of creating a form.</p>
<pre>
<code>
# ideas/ideas/forms/project_form.py
# -*- coding: utf-8 -*-
"""Project form module"""

from tw.api import WidgetsList
import tw.forms as forms
from ideas.model.project import Project

class ProjectForm(forms.TableForm):
    class fields(WidgetsList):
        project_name = forms.TextField(validator=forms.validators.NotEmpty)
        project_description = forms.TextArea(validator=forms.validators.NotEmpty)

class TaskForm(forms.TableForm):
    class fields(WidgetsList):
        project_id = forms.SingleSelectField(options=Project.get_projects_for_dropdown())
        task_name = forms.TextField(validator=forms.validators.NotEmpty)
        task_description = forms.TextArea(validator=forms.validators.NotEmpty)
        status = forms.RadioButtonList(options=(('open', 'Open'), ('closed', 'Closed')))

project_form = ProjectForm(action="create_project")
task_form = TaskForm(action="create_task")
</code></pre>
<p>1) We have created two classes called ProjectForm and TaskForm inheriting ToscaWidgets&#8217; TableForm class. When we call the project_form and task_form in our templates, it will render the form elements in a table layout. </p>
<p>2) In the ProjectForm, we have a text field (<code>&lt;input type="text"&gt;</code>) and a textarea (<code>&lt;textarea&gt;</code>) field.</p>
<p>3) In the TaskForm, we have a dropdown box with the options of all our Projects, a text input for the task name and a textarea field for the task description.</p>
<p>Let&#8217;s go to our controllers/root.py file. Let&#8217;s add these 4 actions there.</p>
<pre>
<code>
# these lines go before RootController class definition.
from ideas.model.project import Project, Task
from ideas.forms.project_form import project_form, task_form

# these lines go in the RootController class.
@expose('ideas.templates.new_project')
def new_project(self):
    """ Displays the project form. """
    return dict(project_form=project_form)

@expose('ideas.templates.new_task')
def new_task(self):
    """ Displays the task form. """
    return dict(task_form=task_form)

@expose()
def create_project(self, project_name, project_description):
    """
    Creates a project with the given name and description. 
    Redirects to the project itself.
    """
    project = Project(project_name=project_name, project_description=project_description)
    DBSession.add(project)
    DBSession.flush()
    return redirect("/show_project/%s" % project.id)

@expose()
def create_task(self, project_id, task_name, task_description, status):
    """
    Creates a task for the given project with the given information.
    Redirects back to the project.
    """
    task = Task(project_id=project_id, task_name=task_name, task_description=task_description, status=status)
    DBSession.add(task)
    DBSession.flush()
    return redirect("/show_project/%s" % project_id)

@expose('ideas.templates.show_project')
def show_project(self, project_id):
    """
    Shows the project with the given id and lists its tasks as well.
    Redirects to the new project page if the project does not exist. 
    """
    project = DBSession.query(Project).filter_by(id=project_id).first()
    if not project:
        return redirect("/new_project")
    tasks = DBSession.query(Task).filter_by(project_id=project_id).all()
    return dict(project=project, tasks=tasks)
</code>
</pre>
<p>Now you can create a project at the &#8220;<a href="http://127.0.0.1:8080/new_project">http://127.0.0.1:8080/new_project</a>&#8221; address. Actually, you can&#8217;t create a project yet. Because we haven&#8217;t set up the templates. <a href="http://tglogs.wordpress.com/2012/03/28/a-simple-project-management-tool-with-turbogears-templates/">Let&#8217;s set up the templates</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/43/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/43/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=43&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/27/a-simple-project-management-tool-with-turbogears-setting-up-the-forms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>
	</item>
		<item>
		<title>A Simple Project Management Tool With TurboGears &#8211; Setting Up the Models</title>
		<link>http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/</link>
		<comments>http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 03:25:16 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[SQLAlchemy]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Python web]]></category>
		<category><![CDATA[Python web framework]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[Web framework]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=27</guid>
		<description><![CDATA[I want you to love TurboGears, understand how to use TurboGears and how to become fully productive with it. For example, I can develop a fully fledged application that would take 3 weeks with something else in 1-1.5 weeks with &#8230; <a href="http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=27&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I want you to love TurboGears, understand how to use TurboGears and how to become fully productive with it. For example, I can develop a fully fledged application that would take 3 weeks with something else in 1-1.5 weeks with TurboGears. For that, I think a project management tool fits best here. It requires working with a database, creating forms, authentication and authorization and so on.</p>
<p>Now, go ahead and create a project called &#8220;ideas&#8221;. What we are going to do is a simple, a very simple project management tool. We are going to create a Project model, a Task model.</p>
<pre>
<code>cd tg2env
source bin/activate
paster quickstart -m ideas
# answer yes to authentication/authorization question.</code></pre>
<p>We will &#8220;cd&#8221; into the &#8220;ideas/ideas&#8221; directory and create a forms module and create a project_form.py file while in there.</p>
<pre>
<code>
cd ideas/ideas
mkdir forms
touch forms/__init__.py
touch forms/project_form.py</code></pre>
<p>Next, we are going to create a &#8220;project&#8221; module in ideas/model/ folder.</p>
<pre><code>cd model &amp;&amp; touch project.py
# project.py
# -*- coding: utf-8 -*-
"""Post model module."""

from ideas.model import DBSession, DeclarativeBase
from sqlalchemy import Column, ForeignKey
from sqlalchemy.types import Integer, Unicode, UnicodeText

class Project(DeclarativeBase):
    __tablename__ = 'projects'

    id = Column(Integer, primary_key=True)
    project_name = Column(Unicode(255))
    project_description = Column(UnicodeText)

    @classmethod
    def get_projects_for_dropdown(self):
        projects = DBSession.query(Project).all()
        project_list = [(project.id, project.project_name) for project in projects]
        return project_list

class Task(DeclarativeBase):
    __tablename__ = 'tasks'

    id = Column(Integer, primary_key=True)
    project_id = Column(ForeignKey("projects.id"))
    task_name = Column(Unicode(255))
    task_description = Column(UnicodeText)
    status = Column(Unicode(6))</code></pre>
<p><strong>What have we done?</strong><br />
We have created two models, 1) Project and 2) Task. We have imported the necessary modules from both our project and SQLAlchemy in order to be able to setup our models correctly. The very next step is to create the tables we have declared in the models. Go and open ideas/model/__init__.py file. Go to the end of file. (Here is a &#8220;vim&#8221; trick for you. When you press ESC and then type &#8220;:$&#8221;, you will go to the end of file.) Add the following line there:</p>
<pre><code>from ideas.model.project import Project, Task</code></pre>
<p>Run the following commands:</p>
<pre><code>
# in the top level ideas/ project directory
python setup.py develop
paster setup-app development.ini</code></pre>
<p>&#8220;paster setup-app development.ini&#8221; will create all our tables, including the authentication tables. It will use the database backend defined in the development.ini file, line: 52. By default, it is SQLite.</p>
<p>In the next post, we will create the forms. Until then, take care and check out <a href="http://www.toscawidgets.org/">ToscaWidgets</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/27/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/27/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=27&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/25/a-simple-project-management-tool-with-turbogears-setting-up-the-models/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>
	</item>
		<item>
		<title>First Steps With TurboGears</title>
		<link>http://tglogs.wordpress.com/2012/03/20/first-steps-with-turbogears/</link>
		<comments>http://tglogs.wordpress.com/2012/03/20/first-steps-with-turbogears/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 23:24:42 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[TurboGears]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=20</guid>
		<description><![CDATA[Now that you have learnt what is TurboGears and how to install it, you want to get your hands dirty with it. This is really nice. I&#8217;m glad you&#8217;ve decided to do that. You won&#8217;t regret this decision. TurboGears is &#8230; <a href="http://tglogs.wordpress.com/2012/03/20/first-steps-with-turbogears/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=20&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Now that you have learnt what is TurboGears and how to install it, you want to get your hands dirty with it. This is really nice. I&#8217;m glad you&#8217;ve decided to do that. You won&#8217;t regret this decision. TurboGears is like that guitar you have always wanted to buy. Now that you have it, you can start to rock.</p>
<p>Let&#8217;s go into our virtual environment and quickstart a project.</p>
<pre>
<code>
cd ~/projects/tg2env
source bin/activate
paster quickstart -x -n -m example
cd example
python setup.py develop
paster serve development.ini</code></pre>
<p>What have we done:</p>
<ul>
<li>Went into our virtual environment and activated it.</li>
<li>Created a project called &#8220;example&#8221; with no sqlalchemy, no authentication and authorization and with mako templates.</li>
<li>We have initiated the project and ran the server.</li>
</ul>
<p>Let&#8217;s see how &#8220;<a href="http://127.0.0.1:8080/&#038;#8221" rel="nofollow">http://127.0.0.1:8080/&#038;#8221</a>; looks like.</p>
<p><img alt="" src="http://i.imgur.com/OkZxv.png" title="Quickstarted TurboGears Project Screen" class="aligncenter" width="900" /></p>
<p>Now go ahead and play along with it. Discover TurboGears. You can ask anything via the comments. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/20/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/20/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=20&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/20/first-steps-with-turbogears/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>

		<media:content url="http://i.imgur.com/OkZxv.png" medium="image">
			<media:title type="html">Quickstarted TurboGears Project Screen</media:title>
		</media:content>
	</item>
		<item>
		<title>Let&#8217;s Install TurboGears</title>
		<link>http://tglogs.wordpress.com/2012/03/20/lets-install-turbogears/</link>
		<comments>http://tglogs.wordpress.com/2012/03/20/lets-install-turbogears/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 14:12:23 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Install TurboGears]]></category>
		<category><![CDATA[Python setuptools]]></category>
		<category><![CDATA[Python virtualenv]]></category>
		<category><![CDATA[Python web]]></category>
		<category><![CDATA[Python web framework]]></category>
		<category><![CDATA[Web framework]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=6</guid>
		<description><![CDATA[In order to install TurboGears we need Python setuptools and in order to create an isolated environment we need virtualenv package.  Why an isolated environment? With a virtual environment we don&#8217;t need to think about our packages clashing. Install requirements: &#8230; <a href="http://tglogs.wordpress.com/2012/03/20/lets-install-turbogears/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=6&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In order to install TurboGears we need Python setuptools and in order to create an isolated environment we need virtualenv package.  Why an isolated environment? With a virtual environment we don&#8217;t need to think about our packages clashing.</p>
<p>Install requirements:</p>
<pre><code> sudo apt-get install build-essential python-dev python-setuptools python-virtualenv </code></pre>
<p>Those installation requirements are not specific to TurboGears. If you are working with Python anyway and tried to use any Python package management that means you already have these packages.</p>
<p>The standard installation</p>
<pre><code>$ virtualenv --no-site-packages tg2env </code>
<code>$ cd tg2env/ 
$ source bin/activate 
(tg2env)$ easy_install -i http://tg.gy/current/index/ tg.devtools 
(tg2env)$ deactivate </code></pre>
<p>You may get errors depending on your system and your system&#8217;s requirements. If you have not seen any errors, congratulations, you have installed TurboGears 2.1.4 (the current stable release as of this writing) and its dependencies successfully.</p>
<p>The pip way</p>
<p>You have tried to install TurboGears with the standard way however you are curious. How to install with pip as well? Fear not, young TGer. I will feed your hunger.</p>
<pre>pip install -i http://tg.gy/current tg.devtools</pre>
<p><a href="http://tglogs.wordpress.com/2012/03/20/first-steps-with-turbogears/">Let&#8217;s create an example TurboGears project.</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=6&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/20/lets-install-turbogears/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>
	</item>
		<item>
		<title>Introduction to TurboGears</title>
		<link>http://tglogs.wordpress.com/2012/03/20/introduction-to-turbogears/</link>
		<comments>http://tglogs.wordpress.com/2012/03/20/introduction-to-turbogears/#comments</comments>
		<pubDate>Tue, 20 Mar 2012 13:06:43 +0000</pubDate>
		<dc:creator>mengukagan</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[TurboGears]]></category>
		<category><![CDATA[Python web]]></category>
		<category><![CDATA[Python web framework]]></category>
		<category><![CDATA[Web framework]]></category>

		<guid isPermaLink="false">http://tglogs.wordpress.com/?p=1</guid>
		<description><![CDATA[Welcome to the TurboGears Log blog. The purpose of this blog is to explore TurboGears from a beginner&#8217;s point of view. We will be posting on TurboGears until we feel it&#8217;s enough. TurboGears is a powerful, full stack MVC web &#8230; <a href="http://tglogs.wordpress.com/2012/03/20/introduction-to-turbogears/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=1&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Welcome to the TurboGears Log blog.</p>
<p>The purpose of this blog is to explore TurboGears from a beginner&#8217;s point of view. We will be posting on TurboGears until we feel it&#8217;s enough.</p>
<p>TurboGears is a powerful, full stack MVC web development framework. It comes with its own decisions, yet it is flexible enough to choose your own tools. What TurboGears has for you?</p>
<ul>
<li>SQLAlchemy (PostgreSQL, MySQL, SQLite, etc.)</li>
<li>Ming ORM for MongoDB</li>
<li>Authentication and authorization</li>
<li>Jinja2, Mako or Genshi templating</li>
<li>Administration interface</li>
<li>Easy form generation</li>
<li>Object dispatch</li>
<li>Easy session management</li>
<li>Easy cache management</li>
</ul>
<p>TurboGears is fast enough, if you wonder about the performance. We had deployed a TurboGears application that had ~2K/sec connections. The setup also had nginx and uWSGI but this is another subject in this blog&#8217;s roadmap.</p>
<p>You can get very productive with TurboGears quickly.  Using TurboGears is very easy. TurboGears has a decent documentation that will be better in the near future. When you get stuck you can ask questions in the TurboGears mailing list or the IRC channel on Freenode network.</p>
<p><a href="http://tglogs.wordpress.com/2012/03/20/lets-install-turbogears">Let&#8217;s go ahead and install TurboGears. </a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/tglogs.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/tglogs.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=tglogs.wordpress.com&#038;blog=34057562&#038;post=1&#038;subd=tglogs&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://tglogs.wordpress.com/2012/03/20/introduction-to-turbogears/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/ab8da7ddd57958bfc98473de107b544d?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mengukagan</media:title>
		</media:content>
	</item>
	</channel>
</rss>
