<?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/"
	>

<channel>
	<title>Random Musings of an Insane Mind &#187; Framework</title>
	<atom:link href="http://cd34.com/blog/category/framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://cd34.com/blog</link>
	<description>This is my blog, there are many others like it but this one is mine.</description>
	<lastBuildDate>Tue, 29 Jun 2010 04:22:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Using Pylons for a Facebook Application</title>
		<link>http://cd34.com/blog/framework/using-pylons-for-a-facebook-application/</link>
		<comments>http://cd34.com/blog/framework/using-pylons-for-a-facebook-application/#comments</comments>
		<pubDate>Thu, 27 May 2010 20:48:28 +0000</pubDate>
		<dc:creator>cd34</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[graph api]]></category>
		<category><![CDATA[pylons]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=947</guid>
		<description><![CDATA[Cue Inspiration I had an idea the other day for a simple Facebook application. With Pylons, I figured it would take no more than an hour or two to get the mechanics of the application working at which point a designer could come in to handle the rest. What followed was quite a struggle. I&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[<h2>Cue Inspiration</h2>
<p>I had an idea the other day for a simple Facebook application.  With Pylons, I figured it would take no more than an hour or two to get the mechanics of the application working at which point a designer could come in to handle the rest.  What followed was quite a struggle.</p>
<p>I&#8217;ve written Facebook applications using the old PHP SDK.  While this method is rather well documented, moving to Python should have been easy.  <a href="http://github.com/sciyoshi/pyfacebook/">PyFacebook</a>, a project hosted at GitHub, is woefully out of date.  Even after applying three of the suggested patches, and modifying one of the imports in the library, I was left with numerous issues regarding the access_token, odd redirects and a few other minor issues.  Add to this the fact that Facebook really suggests that applications use the Graph API and IFrames rather than the FBML canvas and we&#8217;re setting ourselves up for a problem down the road.  Facebook has maintained that they will always support FBML and the REST API, but, new features won&#8217;t be accessible to the older API.</p>
<p>With that in mind, I looked at <a href="http://github.com/facebook/python-sdk/">Python SDK</a>, the officially recommended library for Python and Facebook.  While Pylons is supported fairly well, going through the documentation on Facebook&#8217;s site resulted in looking through the PHP-SDK, the supplied oauth access in the Python-SDK and a bit of trial and error along the way.  OAuth with the Graph API is a bit more complex to understand, but, if your application is using AJAX or JSON, avoiding the FBML proxy is much quicker.  Flash was used quite a bit with FBML applications so that applications could communicate directly with a game server which made things much quicker.  HTML apps using FBML often exhibited pageload performance problems.  With the IFrame method, your application still runs within Facebook&#8217;s canvas, but, the surfer is communicating directly with your application.</p>
<h2>What happened?</h2>
<p>First, I tried to replicate what I had done in PHP using PyFacebook and Pylons.  While there are hooks for WSGI (which includes Paster/Pylons implemented servers), there were a number of issues.  I briefly tried Django with PyFacebook and met different issues.  Once you stray from PHP, you&#8217;re in uncharted territory.  A statistic I read somewhere claimed that only a few hundred apps were developed in something other than PHP with Java/JSP being the most common alternate.  Django, the Google App Engine and web.py appear to be the favorites among Python frameworks.  While I know there are a handful of applications running Pylons, and at least one running TurboGears, I don&#8217;t believe there are many using the Graph API.</p>
<p>At this point, the Graph API and OAuth seemed to be the sane choice.  An IFrame canvas, using the Javascript SDK to complement Python SDK appeared to be the answer.</p>
<p>The first stumbling block when following the OAuth guide on Facebook is the frame in a frame shaded authentication box.  Clicking on the grey box opens the inner frame to the full page where you can authorize the application, but, that is a rather ugly situation.  The following Javascript fixes that which isn&#8217;t great solution, but does work.  </p>
<pre>
&lt;script language="javascript">
top.location.href='https://graph.facebook.com/oauth/authorize?client_id=${config['facebook.appid']}&#038;redirect_uri=${config['facebook.callbackurl']}&#038;display=page&#038;scope=publish_stream';
&lt;/script>
</pre>
<h3>Error validating verification code</h3>
<p>After working with a few other issues, another issue with the auth_token resulted in the following error (after loading the url that was being fetched):</p>
<pre>
{
   "error": {
      "type": "OAuthException",
      "message": "Error validating verification code."
   }
}
</pre>
<p>Adding <strong>&#038;type=client_cred</strong> to your access_token url fixes that situation.</p>
<h2>Here&#8217;s the guide</h2>
<p>We&#8217;re going to put our project in the facebook directory and use Pylons 1.0:</p>
<pre>
git clone http://github.com/facebook/python-sdk.git
wget http://www.pylonshq.com/download/1.0/go-pylons.py
python go-pylons.py facebook
cd facebook
source bin/activate
paster create -t pylons fbapp
cd fbapp
vi development.ini
rm fbapp/public/index.html
cp ../python-sdk/src/facebook.py fbapp/fbapp/lib
</pre>
<p>We need to make a few changes to our development.ini in the [app:main] section:</p>
<pre>
facebook.callbackurl = http://apps.facebook.com/ourfbapp/
facebook.apikey = 6b5aca8bd71c1234590e697f79xxxxxx
facebook.secret = df5d928b87c0df312c8be101e5xxxxxx
facebook.appid = 124322020xxxxxx
</pre>
<p>modify config/routing.py:</p>
<pre>
    map.connect('/{action}', controller='root')
    map.connect('/', controller='root', action='index')
</pre>
<p>templates/oauth_redirect.mako:</p>
<pre>
&lt;script language="javascript">
top.location.href='https://graph.facebook.com/oauth/authorize?client_id=${config['facebook.appid']}&#038;redirect_uri=${config['facebook.callbackurl']}&#038;display=page&#038;scope=publish_stream';
&lt;/script>
&lt;noscript>
&lt;a href="https://graph.facebook.com/oauth/authorize?client_id=${config['facebook.appid']}&#038;redirect_uri=${config['facebook.callbackurl']}&#038;display=page&#038;scope=publish_stream" target="_top">Click here to authorize this application&lt;/a>
&lt;/noscript>
</pre>
<p>templates/index.mako:</p>
<pre>
${tmpl_context.user}
</pre>
<p>controllers/root.py:</p>
<pre>
# using python 2.5
import simplejson
import cgi
import urllib

from pylons import request, response, session, tmpl_context, config
from pylons.controllers.util import abort, redirect

from fbapp.lib.base import BaseController, render
import fbapp.lib.facebook as facebook

class RootController(BaseController):

    def __before__(self):
        tmpl_context.user = None
        if request.params.has_key('session'):
            access_token = simplejson.loads(request.params['session'])['access_token']
            graph = facebook.GraphAPI(access_token)
            tmpl_context.user = graph.get_object("me")

    def index(self):
        if not tmpl_context.user:
            return render('/oauth_redirect.mako')
        return render('/index.mako')
</pre>
<p>In Facebook, you want to make the following changes:</p>
<p>Canvas Callback URL: http://yourdomain.com/<br />
Connect URL: http://yourdomain.com/<br />
Canvas URL: http://apps.facebook.com/yourappname/<br />
FBML/Iframe: iframe<br />
Application Type: website</p>
<p>Under the Migrations Tab, Verify that New Data Permissions and New SDKs are both set to enabled.  When you write your application, you can refer to the <a href="http://developers.facebook.com/docs/authentication/permissions">extended permissions</a> which are set in the &#038;scope= section of oauth_redirect.mako.</p>
<h2>What&#8217;s next?</h2>
<p>Once you&#8217;ve retrieved the access_token and the user_id, you probably want to save that into your local database so that you don&#8217;t need to fetch the data from the Graph API on every pageload.  While the Graph method is indeed faster than FBML, Facebook has lifted some of the restrictions regarding the data you can keep which allows for faster pageloads.  With the IFrame method, pages using AJAX/JSON are indeed much quicker.</p>
<p>While I originally estimated this project to take &#8216;a few hours&#8217;, working through all of the possible scenarios with the Python Facebook SDK ended up taking quite a bit more time than expected.  The Graph API is very well thought out and is much faster than the REST API and appears to be almost as fast as FQL.</p>
<p>Good Luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/using-pylons-for-a-facebook-application/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Django CMS to support Varnish and Akamai ESI</title>
		<link>http://cd34.com/blog/framework/django-cms-to-support-varnish-and-akamai-esi/</link>
		<comments>http://cd34.com/blog/framework/django-cms-to-support-varnish-and-akamai-esi/#comments</comments>
		<pubDate>Fri, 18 Dec 2009 22:50:00 +0000</pubDate>
		<dc:creator>cd34</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[akamai]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[esi]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[Varnish]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=870</guid>
		<description><![CDATA[Many years ago I ran into a situation with a client where the amount of traffic they were receiving was crushing their dynamically created site. Computation is always the enemy of a quick pageload, so, it is very important to do as little computation as possible when delivering a page. While there are many ways [...]]]></description>
			<content:encoded><![CDATA[<p>Many years ago I ran into a situation with a client where the amount of traffic they were receiving was crushing their dynamically created site.  Computation is always the enemy of a quick pageload, so, it is very important to do as little computation as possible when delivering a page.</p>
<p>While there are many ways to put together a CMS, high traffic CMS sites usually involve caching or lots of hardware.  Some write static files which are much less strenuous, but, you lose some of the dynamic capabilities.  Fragment caching becomes a method to make things a bit more dynamic as <a href="http://masonhq.com/">MasonHQ</a> does with their page and block structure.  <a href="http://code.google.com/p/django-blocks/">Django-blocks</a> was surely influenced by this or reinvented this method.</p>
<p>In order to get the highest performance out of a CMS with a page and block method, I had considered writing a filesystem or inode linklist that would allow the webserver to assemble the page by following the inodes on the disk to build the page.  Obviously there are some issues here, but, if a block was updated by a process, it would automatically be reassembled.  This emulates a write-through cache and would have provisions for dynamic content to be mixed in with the static content on disk.  Assembly of the page still takes more compute cycles than a static file but is significantly less than dynamically creating the page from multiple queries.</p>
<p>That design seriously limits the ability to deploy the system widely.  While I can control the hosting environment for personal projects, the CMS couldn&#8217;t gain wide acceptance.  While Varnish is a rather simple piece of software to install, it does limit deploy-ability, but, provides a significant piece of the puzzle due to Edge Side Includes (ESI).  If the CMS gets used beyond personal and small deployments, Akamai supports Edge Side Includes as well.</p>
<p>Rather than explain ESI, <a href="http://www.trygve-lie.com/blog/entry/esi_explained_simple">ESI Explained Simply</a> contains about the best writeup I&#8217;ve seen to date to explain how ESI can be used.</p>
<p>The distinction here is using fragment caching controlled by ESI to represent different zones on the page.  As a simple example, lets consider our page template contains an article and a block with the top five articles on the site.  When a new post is added, we can expire the block that contains the top five articles so that it is requested on the next page fetch.  Since the existing article didn&#8217;t change, the interior ESI included block doesn&#8217;t need to be purged.  This allows the page to be constructed on the Edge rather than on the Origin server.</p>
<p>As I have worked with a number of PHP frameworks, none really met my needs so I started using Python frameworks roughly two years ago.  For this CMS, I debated using Pylons or Django and ended up choosing <a href="http://www.djangoproject.com/">Django</a>.  Since both can be run behind WSGI compliant servers, we&#8217;ve opened ourselves up to a number of potential solutions.  Since we are running Varnish in front of our Origin server, we can run Apache2 with mod_wsgi, but, we&#8217;re not limited to that configuration.  At this point, we have a relatively generic configuration the CMS can run on, but, there are many other places we can adapt the configuration for our preferences.</p>
<p>Some of the potential caveats:<br />
* With <a href="http://varnish.projects.linpro.no/">Varnish</a> or <a href="http://www.akamai.com/">Akamai</a> as a frontend, we need to pay closer attention to X-Forwarded-For:<br />
* Web logs won&#8217;t exist because Varnish is serving and assembling the pages (There is a trick using ESI that could be employed if logging was critical)<br />
* ESI processed pages with Varnish are not compressed.  This is on their <a href="http://varnish.projects.linpro.no/wiki/PostTwoShoppingList">wishlist</a>.</p>
<p>Features:<br />
* Content can exist in multiple categories or tags<br />
* Flexible URL mapping<br />
* Plugin architecture for Blocks and Elements<br />
* Content will maintain revisions and by default allow comments and threaded comments</p>
<p>Terms:<br />
* Template &#8211; the graphical layout of the page with minimal CMS markup<br />
* Element &#8211; the graphical template that is used to render a Block<br />
* Block &#8211; a module that generates the data rendered by an Element<br />
* Page &#8211; a Page determined by a Title, Slug and elements<br />
* Content &#8211; The actual data that rendered by a block</p>
<p>Goals:<br />
* Flexible enough to handle something as simple as a personal blog, but, also capable of powering a highly trafficed site.<br />
* Data storage of common elements to handle publishing of content and comments with the ability to store information to allow threaded comments.  This would allow the CMS to handle a blog application, a CMS, or, a forum.<br />
* A method to store ancillary data in a model so that upgrades to the existing database model will not affect developed plugins.<br />
* Block system to allow prepackaged css/templating while allowing local replacement without affecting the default package.<br />
* Upgrades through pypy or easy_install.<br />
* Ability to add CDN/ESI without needing to modify templates.  The system will run without needing to be behind Varnish, but, its full power won&#8217;t be realized without Varnish or Akamai in front of the origin server.<br />
* Seamless integration of affiliate referral tracking and conversion statistics</p>
<p>At this point, the question in my mind was whether or not to start with an existing project and adapt it or start from scratch.  At this point, the closest Django CMS I could find was Django-Blocks and I do intend to look it over fairly closely, but, a cursory look showed the authors were taking it in a slightly different direction than I anticipated.  I&#8217;ll certainly look through the code again, but, the way I&#8217;ve envisioned this, I think there are some fundamental points that clash.</p>
<p>As I already have much of the database model written for an older PHP CMS that I wrote, I&#8217;m addressing some of the shortcomings I ran across with that design and modifying the models to be a little more generic.  While I am sure there are proprietary products that currently utilize ESI, I believe my approach is unique and flexible enough to power everything from a blog to a site or forums or even a classified ads site.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/django-cms-to-support-varnish-and-akamai-esi/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>AttributeError: &#8216;function&#8217; object has no attribute &#8216;replace&#8217;</title>
		<link>http://cd34.com/blog/framework/attributeerror-function-object-has-no-attribute-replace/</link>
		<comments>http://cd34.com/blog/framework/attributeerror-function-object-has-no-attribute-replace/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 18:54:10 +0000</pubDate>
		<dc:creator>cd34</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[pylons]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[toscawidgets]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=778</guid>
		<description><![CDATA[While doing some coding to move a Turbogears2 application over to Pylons, I ran into an issue with Validation and ToscaWidgets. AttributeError: &#8216;function&#8217; object has no attribute &#8216;replace&#8217; Validation in Pylons listed: @validate(form=movie_form, error_handler=index) for the decorator syntax, but, error_handler should be a name, not a function. The correct decorator should be: @validate(form=movie_form, error_handler=&#8217;index&#8217;)]]></description>
			<content:encoded><![CDATA[<p>While doing some coding to move a Turbogears2 application over to Pylons, I ran into an issue with Validation and ToscaWidgets.</p>
<h3>AttributeError: &#8216;function&#8217; object has no attribute &#8216;replace&#8217;</h3>
<p><a href="http://toscawidgets.org/documentation/tw.forms/tutorials/validate_pylons.html" target="_new">Validation in Pylons</a> listed:</p>
<p>@validate(form=movie_form, error_handler=index)</p>
<p>for the decorator syntax, but, error_handler should be a name, not a function.  The correct decorator should be:</p>
<p>@validate(form=movie_form, error_handler=&#8217;index&#8217;)</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/attributeerror-function-object-has-no-attribute-replace/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rapid Application Development using Turbogears and Django</title>
		<link>http://cd34.com/blog/framework/rapid-application-development-using-turbogears-and-django/</link>
		<comments>http://cd34.com/blog/framework/rapid-application-development-using-turbogears-and-django/#comments</comments>
		<pubDate>Sat, 08 Aug 2009 06:07:44 +0000</pubDate>
		<dc:creator>cd34</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[RAD]]></category>
		<category><![CDATA[rapid application development]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=737</guid>
		<description><![CDATA[For the last 14 months we&#8217;ve been developing an application to replace 90000 lines of PHP code. Rewriting the application from scratch to support I18N and many of the enhancements it needed was deemed to be a better long term solution. When that project was first started, I spent a month with Django and a [...]]]></description>
			<content:encoded><![CDATA[<p>For the last 14 months we&#8217;ve been developing an application to replace 90000 lines of PHP code.  Rewriting the application from scratch to support I18N and many of the enhancements it needed was deemed to be a better long term solution.</p>
<p>When that project was first started, I spent a month with Django and a month with Turbogears writing the same test application so that I could compare the development cycle.  Both have matured and I needed to do a rapid turnaround on another project.  I decided to give Django another look since it had hit version 1.0 and had added quite a few features that were missing in my preliminary evaluation.  What follows is a discussion of the major points from both of the frameworks.</p>
<p>Turbogears has excellent form handling.  Except for the Forms Wizard in Django, working with forms is much easier in Turbogears.  Validation of the form and the resulting database update methods are much cleaner in Turbogears.  Django, while slightly more complex in handling form input, does handle things with a single function which might enhance readability in a large project.</p>
<p>Database handling through SQL Alchemy in Turbogears is much better than the database methods in Django.  Yes, you can use SQL Alchemy in Django now, but, their default ORM has plenty of room for improvement.</p>
<p>Turbogears is true MVC.  Their terminology and methods are true to the paradigm set forth by Smalltalk.  Django is MVC, but they call it MTV, Model, Template, View.  The differences are slight and the developers of both have made good decisions.  Adapting to either project&#8217;s methods is quick and not a hindrance.</p>
<p>Django&#8217;s definitely wins with Authentication/Authorization.  Methods to handle registration, user creation, login and forgotten passwords are built in and wrapped with very nice templates that can be overridden.  For Turbogears, repoze.who and repoze.what have been pulled from Plone and put into place.  While Turbogears works with repoze, the decisions made and the lack of full support behind it make it difficult to implement.</p>
<p>Django feels faster.  Comparing 14 months of development in Turbogears on an application to an application written in Django this week, the template engine, database access and pageload time seemed faster.  Django is a lighter weight framework and you are closer to the data.  Turbogears puts a little more insulation in which makes some coding easier at the expense of performance.</p>
<p>Maintainability of code would have to go to Turbogears.  IBM once stated that the maximum number of bugfree lines of code that could be written was 23.  With Turbogears, much of the heavy lifting is handled by widgets and decorators and your model resulting in a smaller codebase.  Django requires more code to do the same task unless you utilize some of the snippets.  Turbogears makes certain assumptions and has wrapped many of the libraries that make development easy in the default installation.  Django&#8217;s default installation lacks those decisions, but, you are not prevented from establishing your own middleware.  If you were developing a number of Django projects, you would pick and choose snippets that would replicate the decisions that Turbogears has already made.</p>
<p>URL Mapping is much easier to implement with Django.  While routes support in Turbogears is present, Django&#8217;s regexp mapping is much easier to manipulate.</p>
<p>Community, hands down, Django wins.  With a much larger installed base, bugs are found and fixed much more quickly.  While Turbogears was founded on loftier principles, execution and follow through are lacking.  Development is done when it is needed by a client project in the core group of developers.  There is a definite air of condescension when the project developers handle questions from potential developers.  With Django, there are people of all experience levels willing to help on groups.google, IRC, and thorough documentation that far exceeds most of the open source documentation out there.</p>
<p>Documentation, again, Django.  Well organized, well thought out and well documented examples on Django&#8217;s part show dedication to having a framework that is well understood and well used.  Turbogears recently moved to Sphinx, but, documentation generated from poorly documented code still means poor documentation.  The tutorials and examples have been improving, but, they have a long way to go.</p>
<p>Genshi and Mako are supported fairly well with Turbogears and are both very good engines.  Jinja is also supported which is a bit faster than Genshi and is powerful and very easy to work with.  Django&#8217;s template language is also very flexible, powerful and easy to work with.  Django had some definite advantages with a simpler language, but, neither Django or Turbogears stood out as a clear winner. </p>
<p>If you were looking to write an extremely heavy database or form involved site, I think Turbogears would be a good solution.  If you choose Turbogears, be prepared to delve into the code when you are faced with problems.  Bugs are not dealt with very promptly even though upgrades are pushed out.  Be prepared to patch upgraded packages or hold certain packages once you move into production.</p>
<p>On the other hand, if you are writing a less complicated application, Django would be a good choice.</p>
<p>All told, the application developed this week in Django took about 12 hours and had I been working with Django for the last 14 months, I would estimate the project to have taken roughly 8 hours.  Developed in Turbogears, I probably could have written it in 6 hours.  PHP, to mimic all of the functionality would have taken 14-16 hours even using one of the numerous frameworks.</p>
<p>There is a definite advantage to using a framework and Python frameworks do appear to offer Rapid Application Development even over most of the PHP frameworks.  For me, new development will probably be done in Django unless there is a strong case to use Turbogears.</p>
<p>* <a href="http://turbogears.org/2.0/">Turbogears 2.0</a><br />
* <a href="http://www.djangoproject.com/">Django</a><br />
* <a href="http://www.djangosnippets.org/">Django Snippets</a></p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/rapid-application-development-using-turbogears-and-django/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>User Interface Design</title>
		<link>http://cd34.com/blog/infrastructure/user-interface-design/</link>
		<comments>http://cd34.com/blog/infrastructure/user-interface-design/#comments</comments>
		<pubDate>Wed, 24 Jun 2009 05:46:26 +0000</pubDate>
		<dc:creator>cd34</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Infrastructure]]></category>
		<category><![CDATA[formencode]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[smarty]]></category>
		<category><![CDATA[sqlalchemy]]></category>
		<category><![CDATA[toscawidgets]]></category>
		<category><![CDATA[turbogears]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=676</guid>
		<description><![CDATA[Programmers are not designers. Technical people should not design User Interfaces. * 810 source files * 90658 lines of code * 10213 lines of html For an internal project tasked to a series of programmers throughout the years without enough oversight, it is a mass of undocumented code with multiple programming styles. PHP allowed lazy [...]]]></description>
			<content:encoded><![CDATA[<p>Programmers are not designers.  Technical people should not design User Interfaces.</p>
<p>* 810 source files<br />
* 90658 lines of code<br />
* 10213 lines of html </p>
<p>For an internal project tasked to a series of programmers throughout the years without enough oversight, it is a mass of undocumented code with multiple programming styles.  PHP allowed lazy programming, Smarty didn&#8217;t have some of the finesse required, so, the User Interface suffered.  Functional but confusing to anyone that hadn&#8217;t worked intimately with the interface or been walked through it.</p>
<p>The truest statement is that it is easier for me to do things through the MySQL command line than through the application.  While this does have a tendency to introduce possible typos, it has altered SQL practices here.</p>
<p><code>update table set value=123 where othervalue=246;</code></p>
<p>could have an accidental typo of </p>
<p><code>update table set value=123 where othervalue-=246;</code></p>
<p>which would have completely unintended consequences.  One typo altered the DNS entries for 48000 records.  Shortly after that typo, ingrained in company policy was that I never wanted to ever see a query like that executed in the command line regardless of how simple the command.</p>
<p>Even within code, the above command would be entered as:</p>
<p><code>update table set value=123 where othervalue in (246);</code></p>
<p>This prevented a number of potential typos.  Even limit clauses with deletions were enforced to make sure things didn&#8217;t go too haywire in an update.</p>
<p>With Python, indenting is mandatory which results in multiple programmer&#8217;s code looking similar and easier to troubleshoot.  Utilizing SQLAlchemy which enforces bind variables when talking with the database engine, we&#8217;ve eliminated the potential for a typo updating too many records.  Even cascade deletes are enforced in SQLAlchemy even when running on top of MyISAM.  With MVC, our data model is much better defined and we&#8217;re not tied down to remembering the relationship between two tables and possible dependencies.  Conversion from the existing MySQL database to a DeclarativeBase model hasn&#8217;t been without issues, but, a simple python program allowed the generation of a simple model that took care of most of the issues.  Hand tweaking the database model while developing the application has allowed for quite a bit of insight into issues that had been worked around rather than making adjustments to the database.</p>
<p>Fundamental design issues in the database structure were worked around with code rather than fixed.  Data that should have been retained was not, relationships between tables was defined in code rather than in the database leading to a painful conversion.</p>
<p>When it was decided to rewrite the application in Python using TurboGears, I wasn&#8217;t that familiar with the codebase nor the user interface.  Initially it was envisioned that the templates would be copied and the backend engine would be written to power those templates.  After a few hours running through the application, and attempting the conversion on a number of templates, I realized the application was functional but it was extremely difficult to use in its current state.  So much for having a programmer design an interface.</p>
<p>Some functionality from the existing system was needed so I peered into the codebase and was unprepared for that surprise.  At this point it became evident that a non-programmer had designed the interface.  While Smarty was a decent template language, it was not a formtool, so, methods were designed to give a consistent user experience when dealing with error handling.  A single php file was responsible for display, form submission and validation and writing to the database for each &#8216;page&#8217; in the application.  The code inside should have been straightforward.</p>
<p>* Set up default CSS classes for each form field for an &#8216;ok&#8217; result<br />
* Validate any passed values and set the CSS class as &#8216;error&#8217; for any value that fails validation<br />
* Insert/Update the record if the validation passes<br />
* Display the page</p>
<p>Some validation takes place numerous times throughout the application, and, for some reason one of the &#8216;coders&#8217; decided that copy and paste of another function that used that same validation code was better than writing a function to do the validation.  Of course when that validation method needed to be changed, it needed to be changed in eight places.</p>
<p>So, what should have been somewhat simple has changed considerably:</p>
<p>* Evaluate each page<br />
* Redesign each page to make the process understandable<br />
* Adjust terminology to make it understandable to the application&#8217;s users<br />
* modify the database model<br />
* rewrite the form and validation</p>
<p>A process that should have been simple has turned into quite a bit more work than anticipated.  Basically, development boils down to looking at the page, figuring out what it should be, pushing the buttons to see what they do and rewriting from scratch.</p>
<p>TurboGears has added a considerable amount of efficiency to the process.  One page that dealt with editing a page of information was reduced from 117 lines of code to 12 lines of code.  Since TurboGears uses ToscaWidgets and Formencode, validation and form presentation is removed from the code resulting in a controller that contains the code that modifies the tables in the database with validated input.  Since Formencode already has 95% of the validators that are needed for this project, we can rest assured that someone else has done the work to make sure that field will be properly validated.  Other validation methods can be maintained and self-tested locally, but, defined in such a manner that they are reused throughout the application rather than being cut and pasted into each model that is validating data.  In addition, bugs should be much less frequent as a result of a much-reduced codebase.</p>
<p>Due to the MVC framework and the libraries selected by the developers at TurboGears, I wouldn&#8217;t be surprised if the new codebase is 10%-15% the size of the existing application with greater functionality.  The code should be more maintainable as python enforces some structure which will increase readability.</p>
<p>While I am not a designer, even using ToscaWidgets and makeform, the interface is much more consistent.  Picking the right words, adding the appropriate help text to the fields and making sure things work as expected has resulted in a much cleaner, understandable interface.</p>
<p>While there are some aspects of ToscaWidgets that are a little too structured for some pages, our current strategy is to develop the pages using ToscaWidgets or makeform to make things as clear as possible making notes to overload the Widget class for our special forms at a later date.</p>
<p>While it hasn&#8217;t been a seamless transition, it did provide a good opportunity to rework the site and see a number of the problems that the application has had for a long time.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/infrastructure/user-interface-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Legacy Code Fix versus Code Rewrite</title>
		<link>http://cd34.com/blog/framework/legacy-code-fix-versus-code-rewrite/</link>
		<comments>http://cd34.com/blog/framework/legacy-code-fix-versus-code-rewrite/#comments</comments>
		<pubDate>Sat, 28 Feb 2009 07:13:23 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=573</guid>
		<description><![CDATA[Python Frameworks use the DRY Method &#8212; Don&#8217;t Repeat Yourself.  That is a powerful mantra to follow when developing applications. I am faced with a quandry.  I have an application that consists of roughly 40000 lines.  That code was written in php many years ago, with a handbuilt web framework implemented with smarty.  There are [...]]]></description>
			<content:encoded><![CDATA[<p>Python Frameworks use the DRY Method &#8212; Don&#8217;t Repeat Yourself.  That is a powerful mantra to follow when developing applications.</p>
<p>I am faced with a quandry.  I have an application that consists of roughly 40000 lines.  That code was written in php many years ago, with a handbuilt web framework implemented with smarty.  There are a number of issues with the existing code, including inline functions duplicated through multiple files, poorly validated input and bad structure.  Outsourcing some code development appeared to be cost effective.  In the end, the code quality churned out by that vendor was sub-par.  Maintenance of that codebase easily costs twice as much as it should.</p>
<p>This week, a few requirements cropped up which brought up an interesting question.  Knowing that the code consists of 40000 lines of poorly written, difficult to maintain code, I debated whether fixing the existing code would be quicker than rewriting the relevent portion and coding the addendum.  TurboGears, a python webapp framework would shrink the code considerably since it is thin middleware on top of a wsgi compliant server.</p>
<p>Where it took 45 lines of code to do a halfway decent job of validating a few input fields in php with smarty, the equivalent code in TurboGears consists of a model definition containing the validator segment and a few lines of code to define the page.  Updating the database becomes one line of code, replacing 8-12 lines of code.</p>
<p>I had planned to convert the application over to TurboGears eventually, but, the scope of this current project gives me an opportunity to convert a piece of the application over while adding the new features, and leaving the legacy code running as is.</p>
<p>The features I need to add will take roughly 150 lines of Python/TurboGears code, or perhaps 1500-2000 lines of php to achieve the same functionality.  I have debated using another PHP framework as a stopgap, but, I have yet to find a decent form library for it that works well.</p>
<p>If I had to pick a favorite, ad_form from openacs would top the list.  TurboGears and Genshi with formencode come in as a close second.</p>
<p>I believe rewriting the portions of the app I need to write will probably take roughly the same amount of time as it would take to patch the existing code.  The investment in time will put me closer to finishing the complete rewrite of the existing system.</p>
<p>An added advantage is that I can fix architectural issues with the existing package that couldn&#8217;t easily be reworked without considerable effort.  If the code you are maintaining is over five years old, you owe it to yourself to check out some of the other frameworks out there.  Prior to settling on TurboGears, I looked at Django, Catalyst, Mason and a number of other frameworks.  I even searched the PHP frameworks but didn&#8217;t find anything with the strengths I saw with TurboGears.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/legacy-code-fix-versus-code-rewrite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>If you could have it all&#8230;.</title>
		<link>http://cd34.com/blog/framework/if-you-could-have-it-all/</link>
		<comments>http://cd34.com/blog/framework/if-you-could-have-it-all/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 19:24:11 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=6</guid>
		<description><![CDATA[I&#8217;m a bit of a web performance nut.  I like technology when it is used to solve real challenges and won&#8217;t use technology for technology&#8217;s sake.  When you look at today&#8217;s scalability problems of all of the web 2.0 shops, one only needs to make one real generalization. What is the failing point of today&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a bit of a web performance nut.  I like technology when it is used to solve real challenges and won&#8217;t use technology for technology&#8217;s sake.  When you look at today&#8217;s scalability problems of all of the web 2.0 shops, one only needs to make one real generalization.</p>
<p>What is the failing point of today&#8217;s sites?  How many stories have you read in the media about some rising star that gets mentioned on yahoo or digg or slashdot?  Generally, their site crashes under the crushing load (I&#8217;ve had sites slashdotted, its not as big a deal as they would have you believe).  But, the problem we face is multifaceted.</p>
<p>Developer learns php.  Developer discovers MySQL.  Developer stumbles across concept.  Developer cobbles together code, buys hosting &#8212; sometimes on a virtual/shared hosting environment, sometimes on a VPS, sometimes a dedicated server.  But, the software that performs well for a few friends hitting the site and acting as beta testers is never really pushed.  While the pages look nice, the engine behind them is usually poorly conceived, or worse, designed thinking that the single server or dual server web/mysql combination is going to keep them alive.</p>
<p>95% of the software designed and distributed under Open Source Licenses doesn&#8217;t understand the unique challenges behind a site that needs to handle 20 visitors versus 20000 visitors per hour.  Tuning apache to handle high traffic, tuning mysql indexes and mysql&#8217;s configuration and writing applications designed for high traffic is not easy.  Debugging and repairing those applications after they&#8217;ve been deployed is even harder.  Repairing while maintaining backwards compatibility adds a whole new level of complexity.</p>
<p>Design with scalability in mind.  I saw a blog the other day where someone was replacing a 3 server setup behind a load balancer with a single machine because the complexity of 100% uptime made their job harder.  Oh really?</p>
<p>What happens when your traffic needs outgrow that one server?  Whoops, I&#8217;m back to that load balanced solution that I just left.</p>
<p>What are the phases that you need to look for?</p>
<p>Is your platform ready for 100,000 users a day?  If not, what do you need to do to make sure it is ready?  Where are your bottlenecks? Where does your software break down?  What is your expansion plan?  When do you split your mysql writers and readers?  Where does your appliction boundary start and end?  What do you think breaks next?  Where is our next bottleneck?</p>
<p>What happens with a digg or slashdot that crushes a site?  Usually, its a site that has all sorts of dynamic content with ill conceived mysql queries generated in realtime every pageload.  I can remember a CMS framework that did 54 sql queries to display the front page.   That is just rediculous and I dumped that framework 5 minutes after seeing that.  Pity, they did have a good concept.</p>
<p>So, with scalability in mind, how does one engineer a solution?  LAMP isn&#8217;t the answer.</p>
<p>You pick a framework that doesn&#8217;t use the usual paradigms of an application.  Why should you worry about a protocol, you should design the application divorced from the protocol.  You develop an application that faces the web rather than talking direct to the web because other applications might talk to your application.  When it comes time to scale, you add machines without having to worry about task distribution.  Google does it, you should too.</p>
<p><a title="Mantissa" href="http://divmod.org/trac/wiki/DivmodMantissa" target="_blank">Mantissa</a> solves that problem by being a framework that encompasses all of that.  If some of these Web 2.0 sites thought about their deployment like google did &#8212; expansion wouldn&#8217;t create much turmoil.  To grow, you just add more machines to the network.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/if-you-could-have-it-all/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails&#8230; ugh.</title>
		<link>http://cd34.com/blog/framework/rails-ugh/</link>
		<comments>http://cd34.com/blog/framework/rails-ugh/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 15:41:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Apache]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=5</guid>
		<description><![CDATA[While I am not a fan of Ruby, and much less rails, there is a new project that does seem to at least raise the bar.  While I am always concerned about application performance, rails usually falls pretty flat when hit with the thundering herd.  Passenger does appear to remedy that partially.]]></description>
			<content:encoded><![CDATA[<p>While I am not a fan of Ruby, and much less rails, there is a new project that does seem to at least raise the bar.  While I am always concerned about application performance, rails usually falls pretty flat when hit with the thundering herd.  <a href="http://www.modrails.com/" target="_blank">Passenger</a> does appear to remedy that partially.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/rails-ugh/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turbogears 1.x</title>
		<link>http://cd34.com/blog/framework/turbogears-1x/</link>
		<comments>http://cd34.com/blog/framework/turbogears-1x/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 15:39:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=4</guid>
		<description><![CDATA[TurboGears looks to be one of the next great frameworks.  While django has a little more maturity, TurboGears understands MVC quite well and is quick, easy to work with.]]></description>
			<content:encoded><![CDATA[<p><a href="http://turbogears.org/" target="_blank">TurboGears</a> looks to be one of the next great frameworks.  While django has a little more maturity, TurboGears understands MVC quite well and is quick, easy to work with.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/turbogears-1x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django</title>
		<link>http://cd34.com/blog/framework/django/</link>
		<comments>http://cd34.com/blog/framework/django/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 15:36:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Framework]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://cd34.com/blog/?p=3</guid>
		<description><![CDATA[One of the many things I have really disliked about the internet coders is that none really understand MVC.   PHP, my arch nemesis surely has cobbled a bunch of frameworks together, yet, very few of them actually do what they should. Django is one of them that I have toyed around with and so far, [...]]]></description>
			<content:encoded><![CDATA[<p>One of the many things I have really disliked about the internet coders is that none really understand MVC.   PHP, my arch nemesis surely has cobbled a bunch of frameworks together, yet, very few of them actually do what they should.</p>
<p><a href="http://www.djangoproject.com/" target="_blank">Django</a> is one of them that I have toyed around with and so far, its got some promise.  1.0 should be quite nice.</p>
<p>RedHatMagazine has a really good <a href="http://www.redhatmagazine.com/2008/06/05/installingconfiguringcaching-django-on-your-linux-server/" target="_blank">article</a> on installing django.</p>
]]></content:encoded>
			<wfw:commentRss>http://cd34.com/blog/framework/django/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
