<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Random thoughts and musings.  Or something.</description><title>Blog</title><generator>Tumblr (3.0; @gulielmus)</generator><link>http://blog.willbarton.com/</link><item><title>ZopeEditManager 0.9.7 Universal</title><description>&lt;p&gt;If you do a lot with Zope and don’t like to have to use Zope’s ZMI editor, external editing is a godsend. Unfortunately the &lt;a href="http://www.urbanape.com/downloads/"&gt;ZopeEditManager&lt;/a&gt; application for Mac OS X hasn’t been updated in quite a while. This is fine because it still functions well, but the problem is the most recent binaries are not universal. I don’t have anything else using Rosetta, so I’d prefer not to have to install it.&lt;/p&gt;
&lt;p&gt;Thankfully because it’s open source you can &lt;a href="http://www.urbanape.com/downloads/"&gt;download the source&lt;/a&gt;. I’ve done just that and built a quick universal binary. I’ve made no other changes, and it seems to work quite nicely.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;a href="http://willbarton.com/files/ZopeEditManager-0.9.7-universal.zip"&gt;ZopeEditManager 0.9.7 Universal&lt;/a&gt;&lt;/dt&gt; &lt;dd&gt;
&lt;strong&gt;MD5:&lt;/strong&gt; 5bd3e6497ec0d65d21c60e138c8d6fa5&lt;/dd&gt; &lt;dd&gt;
&lt;strong&gt;SHA1:&lt;/strong&gt; da5f5e216d518727d6f95fe2af32c0db2c6039f9&lt;/dd&gt; &lt;/dl&gt;</description><link>http://blog.willbarton.com/post/595239898</link><guid>http://blog.willbarton.com/post/595239898</guid><pubDate>Thu, 13 May 2010 09:35:00 -0400</pubDate><category>zope</category><category>open source</category><category>plone</category></item><item><title>Emulating iPhone Mail Compose View</title><description>&lt;p&gt;There have been a couple of situations where I’ve had several small data fields along side one large body of data. The iPhone’s mail view/compose UI fits this model fairly well, and it’s something users are used to. The problem is that it can be difficult to emulate.&lt;/p&gt;
&lt;p&gt;Taking a look at a MFMailComposeViewController’s view hierarchy can demonstrate why. One might think it’s a simple UITableView with a UITextView (or something similar) as its footer view, or as the last table cell. In fact, the hierarchy looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MailComposeView                   
&lt;ul&gt;
&lt;li&gt;UIView                     
&lt;ul&gt;
&lt;li&gt;UIScrollView                       
&lt;ul&gt;
&lt;li&gt;UIView                         
&lt;ul&gt;
&lt;li&gt;ComposeRecipientView&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;MFComposeSubjectView&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;UITextContentView&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ve left out a couple of views here, it illustrates the structure. This is different from the expectation that a table is being used. Having established that Apple is not using a UITableView for this structure, let’s try to do it anyway.&lt;/p&gt;
&lt;p&gt;The structure I’d like to use is this (I’ve included a project downloadable below):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;UIScrollView                     
&lt;ul&gt;
&lt;li&gt;UITableView&lt;/li&gt;
&lt;li&gt;UITextView&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;!-- more --&gt;This presents two primary problems. First, Both UITableView and UITextView are themselves subclasses of UIScrollView. We can turn scrolling off on both of these views, but we need to resize them such that their contentSize is equal to their frame size. In doing so we’ll also need to adjust the scroll view’s size as well. The method below should take care of this.&lt;/p&gt;
&lt;pre class="brush: objc"&gt;- (void)resizeViews {
    // We need to resize the text view, the table view, and the scroll 
    // view based on their respective contents.
    
    CGSize tableViewSize = self.tableView.contentSize;
    CGRect tableViewFrame = self.tableView.frame;
    
    CGSize textViewSize = self.textView.contentSize;
    CGRect textViewFrame = self.textView.frame;

    CGSize scrollViewSize = self.scrollView.contentSize;
    
    // First the table view. We need to calculate the height for each 
    // section's rows. Then we'll set that as the contentSize height 
    // and the frame's height.
    // NOTE: This doesn't account for headers and footers. A better way
    // would be to ask the delegate the height for header, footer, and 
    // each individual row.
    NSInteger tableHeight = 0;
    for (NSInteger i = 0; i &lt; [self.tableView numberOfSections]; i++) 
        tableHeight += [self.tableView numberOfRowsInSection:i] * 
                       self.tableView.rowHeight;
    tableViewSize.height = tableHeight;
    tableViewFrame.size.height = tableHeight;
    self.tableView.frame = tableViewFrame;
    
    // For the text view we simply need to set the frame's height to the 
    // content size's height and offset the y to the table view's height.
    textViewFrame.origin.y = tableHeight;
    textViewFrame.size.height = textViewSize.height;
    self.textView.frame = textViewFrame;
    
    // Finally we just need to set the content size on the parent 
    // scroll view. It'll be the table's height plus the text view's 
    // height.
    scrollViewSize.height = tableHeight + textViewSize.height;
    self.scrollView.contentSize = scrollViewSize;
    
}&lt;/pre&gt;
&lt;p&gt;When does this method need to be called? It will need to be called when the view loads (or appears), after the table view and text view have been populated with their initial data. It will also need to be called after any updates to either the table view or the text view.&lt;/p&gt;
&lt;p&gt;The second problem is scrolling within the text view as the text is edited. This is slightly trickier because we have to find the cursor in the text view and adjust the scroll view’s offset appropriately. The following method should work.&lt;/p&gt;
&lt;pre class="brush: objc"&gt;- (void)scrollToCursor {
    // Scroll the parent scroll view to the cursor's location inside 
    // the text view.
    
    CGRect textViewFrame = self.textView.frame;
    CGRect scrollViewFrame = self.scrollView.frame;
    CGPoint scrollViewOffset = self.scrollView.contentOffset;
    CGRect visibleFrame = CGRectMake(scrollViewOffset.x, 
                                     scrollViewOffset.y, 
                                     scrollViewFrame.size.width, 
                                     scrollViewFrame.size.height);
    
    // We have to convert the cursor position into a usable point to 
    // which to scroll. We do this by finding the selected range and 
    // finding the size of the string up to that selected range and 
    // scrolling to that offset.
    NSRange selectedRange = self.textView.selectedRange;
    NSString * stringToSelection = [self.textView.text substringWithRange:NSMakeRange(0, selectedRange.location + selectedRange.length)];
    CGSize selectionSize = [stringToSelection sizeWithFont:self.textView.font 
                                         constrainedToSize:textViewFrame.size 
                                             lineBreakMode:UILineBreakModeWordWrap];
    // We're also going to need the height of the string on a single 
    // line. We'll multiple this height by 2 below in order to make 
    // sure there is at least one full height's worth visible.
    CGSize lineSize = [stringToSelection sizeWithFont:self.textView.font];
    
    // This should be the point where the cursor is currently located 
    // inside the scroll view
    CGPoint selectionOffset = CGPointMake(scrollViewFrame.origin.x, 
                                          textViewFrame.origin.y + 
                                          selectionSize.height);
    
    // If that point is already inside the visible frame we don't need 
    // to do anything.
    if ((selectionOffset.y + (lineSize.height * 2)) &lt; 
            (visibleFrame.origin.y + visibleFrame.size.height))
        return;
    
    // Otherwise all we want to do is scroll to where the cursor is 
    // just visible.
    else
        selectionOffset.y = selectionOffset.y - 
            visibleFrame.size.height + (lineSize.height * 2);
    
    [self.scrollView setContentOffset:selectionOffset animated:YES];
}&lt;/pre&gt;
&lt;p&gt;Again we have to decide when to call this method. There are two UITextViewDelegate methods in which I believe this would be appropriate, textViewDidChangeSelection: and textViewDidChange:. Both involve movement of the cursor; the former is called when the user changes the selection, including moving the cursor and the later when text is changed.&lt;/p&gt;
&lt;p&gt;In rudimentary testing this seems to work satisfactorily. The project linked below includes the above code hooked up to a UI for demonstration purposes. It’s not perfect, indeed it needs to be made more robust for UITableView changes and more testing is certainly needed on UITextView scrolling before it could be ready to be used. But it’s a functional demonstration that I hope can be useful.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://willbarton.com/code/mailclone/MailClone.20100503.tgz"&gt;Download the MailClone Project&lt;/a&gt; – Licensed under the &lt;a href="http://willbarton.com/code/license"&gt;Modified BSD License&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/568281141</link><guid>http://blog.willbarton.com/post/568281141</guid><pubDate>Sun, 02 May 2010 22:25:00 -0400</pubDate><category>iphone</category></item><item><title>Rethinking iPhone Tabular Input</title><description>&lt;p&gt;I’m unhappy with the standard input paradigm for tabular data on the iPhone.&lt;/p&gt;
&lt;p&gt;The most common pattern is a &lt;code&gt;UITableView&lt;/code&gt; inside a &lt;code&gt;UINavigationController&lt;/code&gt;. The user selects a row and a new &lt;code&gt;UIViewController&lt;/code&gt; that allows the user to edit the value is pushed onto the &lt;code&gt;UINavigationController&lt;/code&gt;. When the user is done, that &lt;code&gt;UIViewController&lt;/code&gt; is popped and the user returns to the &lt;code&gt;UITableView&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have a lot of rows to edit this can become tedious for both the developer and the user. As developers, we can create abstractions that make it a lot easier to edit different types of data in different rows. For users, there’s little to alleviate the back and forth of entering data.&lt;/p&gt;
&lt;p&gt;In wanting to find a better way to present a table of editable values to the user, I began thinking about the new-ish &lt;code&gt;UISearchController&lt;/code&gt;’s behavior. It overlays the &lt;code&gt;UITableView&lt;/code&gt; when selected, moves to the top of the screen, and presents the keyboard. What if a row in the table did something similar when selected?&lt;/p&gt;
&lt;p&gt;The video below is of a proof-of-concept I worked up. When a row is selected, a new view is overlaid that contains a label and text field mimicking the position of the row. That view then moves to the top, and the label and text field rearrange to be more friendly to data input. Touching ‘Done’ or touching outside of the input area (on the darkened table view) will dismiss the new view.&lt;/p&gt;
&lt;p&gt;
&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" data="http://www.flickr.com/apps/video/stewart.swf?v=71377" height="400" width="289" type="application/x-shockwave-flash"&gt;
&lt;param value="intl_lang=en-us&amp;photo_secret=1f63563e18&amp;photo_id=4485279121" name="flashvars"&gt;
&lt;param value="http://www.flickr.com/apps/video/stewart.swf?v=71377" name="movie"&gt;
&lt;param value="#000000" name="bgcolor"&gt;
&lt;param value="true" name="allowFullScreen"&gt;
&lt;embed width="289" height="400" flashvars="intl_lang=en-us&amp;photo_secret=1f63563e18&amp;photo_id=4485279121" allowfullscreen="true" src="http://www.flickr.com/apps/video/stewart.swf?v=71377" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;Quick testing shows this to work with &lt;code&gt;UITableViewCellStyleValue1&lt;/code&gt; and &lt;code&gt;UITableViewCellStyleValue2&lt;/code&gt;. It won’t work with &lt;code&gt;UITableViewCellStyleDefault&lt;/code&gt; since it expects both cell labels. It also looks just a bit weird with &lt;code&gt;UITableViewCellStyleSubtitle&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Is this better than the back-and-forth of &lt;code&gt;UINavigationController&lt;/code&gt;? I’m not sure. But this is, to me, more pleasant to use. It still feels like I’m in the same place in the application, instead of being whisked to another view.&lt;/p&gt;
&lt;p&gt;This is fairly straight-forward in implementation, and I’d like to provide for text editing as well as values from a &lt;code&gt;UIPickerView&lt;/code&gt;. In time I’d like to release this as open source through &lt;a href="http://water-powered.com"&gt;Water-Powered Ideas&lt;/a&gt;, but I want to work through the kinks first.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/492417346</link><guid>http://blog.willbarton.com/post/492417346</guid><pubDate>Fri, 02 Apr 2010 23:16:00 -0400</pubDate><category>iphone</category><category>proof of concept</category></item><item><title>Outtake from Gabriel’s Passport Photos</title><description>&lt;img src="http://28.media.tumblr.com/tumblr_kzlfgerPQW1qzhu72o1_r1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Outtake from Gabriel’s Passport Photos&lt;/p&gt;</description><link>http://blog.willbarton.com/post/461422933</link><guid>http://blog.willbarton.com/post/461422933</guid><pubDate>Sat, 20 Mar 2010 14:31:26 -0400</pubDate></item><item><title>Infusion</title><description>&lt;a href="http://ideas.water-powered.com/infusion"&gt;Infusion&lt;/a&gt;: &lt;p&gt;One area I felt iPhone apps lacked was in tea-timers. There exist several, and they’re generally pretty decent, but they lack a bit of configurability I’d like. So I wrote Infusion. The most important feature for me personally is being able to start a pre-defined timer with one touch after Infusion launches, but it’ll also let you customize the startup tab, add teas, edit existing ones, and even just use it as a generic timer. I tried to include a fairly large number of teas. Not many tisanes (herbals) or blends (yet) simply because it’s difficult to keep up the large numbers that are specific to vendors.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;</description><link>http://blog.willbarton.com/post/450907568</link><guid>http://blog.willbarton.com/post/450907568</guid><pubDate>Wed, 24 Feb 2010 23:00:00 -0500</pubDate><category>Infusion</category><category>Tea</category></item><item><title>Railo on FreeBSD with Tomcat and Apache</title><description>&lt;p&gt;This is primarily written for myself for posterity, but maybe others might find it useful.  I find myself wanting to play with &lt;a href="http://www.getrailo.org"&gt;Railo&lt;/a&gt;, an Open Source ColdFusion engine.  Java on FreeBSD can be quite un-fun, but I’m going to assume a working JDK to start off with.&lt;/p&gt;
&lt;p&gt;First thing is to get Apache and Tomcat installed:&lt;/p&gt;
&lt;pre class="brush: shell;"&gt;cd /usr/ports/www/apache22 &amp;&amp; make install
cd /usr/ports/www/mod_jk-apache2 &amp;&amp; make install
cd /usr/ports/www/tomcat6 &amp;&amp; make install&lt;/pre&gt;
&lt;p&gt;Next is to create the &lt;code&gt;/usr/local/etc/apache22/workers.properties&lt;/code&gt; file.  The &lt;code&gt;mod_jk&lt;/code&gt; port gives you a sample to start from.  Mine contains:&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;worker.list=default          # The name of the tomcat server
worker.tomcat.port=8009       # The port of the tomcat server
worker.tomcat.host=127.0.0.1  # The host of the tomcat server
worker.tomcat.type=ajp13      # The type of the connection
worker.tomcat.lbfactor=1      # The weight of the tomcat server&lt;/pre&gt;
&lt;p&gt;Then &lt;code&gt;mod_jk&lt;/code&gt; needs to be added to &lt;code&gt;httpd.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;LoadModule jk_module libexec/apache22/mod_jk.so    # Load the mod_jk module

# mod_jk basic configuration
&lt;IfModule mod_jk.c&gt;
    JkWorkersFile etc/apache22/workers.properties # Set the worker.properties file
     JkLogFile  /var/log/jk.log                   # Set the jk log
     JkShmFile  /var/log/jk-runtime-status        # Set the status file
     JkLogLevel error                             # Set the log level
&lt;/IfModule&gt;&lt;/pre&gt;
&lt;p&gt;That was successful in getting Tomcat up and working.  Now for Railo.  Thankfully, that’s the easy part.  Railo provides a WAR file that can easily be dropped into Tomcat’s &lt;code&gt;webapps&lt;/code&gt; directory.  After that it’s a simple matter of telling Apache what to do about it.  I simply added the following to my &lt;code&gt;mod_jk.c&lt;/code&gt;’s &lt;code&gt;IfModule&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;JkMount /*.cf* default
DirectoryIndex index.html index.cfm index.cfml&lt;/pre&gt;
&lt;p&gt;And hey presto.  I also added a &lt;code&gt;&lt;Host&gt;&lt;/code&gt; entry for a particular domain I wanted to use Railo with:&lt;/p&gt;
&lt;pre class="brush: xml;"&gt; &lt;Host name="domain.com" appBase="/path/to/domain.com"&gt;
    &lt;Context path="" docBase="www"/&gt;
&lt;/Host&gt;
&lt;/pre&gt;
&lt;p&gt;And simply extracted the Railo WAR file there instead of in Tomcat’s webapps directory and used it as the basis for the particular site. The only thing is to make sure the web server has appropriate permissions on the &lt;code&gt;WEB-INF&lt;/code&gt; directory.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/345464430</link><guid>http://blog.willbarton.com/post/345464430</guid><pubDate>Thu, 21 Jan 2010 00:06:00 -0500</pubDate></item><item><title>Observation</title><description>&lt;a href="http://ideas.water-powered.com/observation"&gt;Observation&lt;/a&gt;: &lt;p&gt;This is a little project I’ve been working on. If you’re an amateur astronomer with an iPhone, take a look!&lt;/p&gt;</description><link>http://blog.willbarton.com/post/325947516</link><guid>http://blog.willbarton.com/post/325947516</guid><pubDate>Sat, 02 Jan 2010 20:10:00 -0500</pubDate><category>observation</category><category>iphone</category></item><item><title>We have a Gabriel.</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_kvwq4khhE81qzhu72o1_400.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;We have a Gabriel.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/322546720</link><guid>http://blog.willbarton.com/post/322546720</guid><pubDate>Sun, 06 Dec 2009 00:00:00 -0500</pubDate></item><item><title>Rounding DateTimes in Cocoa</title><description>&lt;p&gt;Let’s see here, what’s the currently supported way to round a datetime to the nearest hour in Cocoa?&lt;/p&gt;
&lt;pre class="brush: objc;"&gt;// Round the current date to the nearest hour
NSDate * currentDateTime = [NSDate date];
NSCalendar * currentCalendar = [NSCalendar currentCalendar];
NSDateComponents * dateComponents = [currentCalendar components:NSEraCalendarUnit | 
                                                                NSYearCalendarUnit | 
                                                                NSMonthCalendarUnit | 
                                                                NSDayCalendarUnit | 
                                                                NSHourCalendarUnit | 
                                                                NSMinuteCalendarUnit 
                                                       fromDate:currentDateTime];
if ([dateComponents minute] &gt;= 30) 
    [dateComponents setHour:[dateComponents hour] + 1];
[dateComponents setMinute:0];
NSDate * roundedDate = [currentCalendar dateFromComponents:dateComponents];
&lt;/pre&gt;
&lt;p&gt;The API seems a little excessive.  I can appreciate what Apple has tried to do in making dates more flexible and easier to internationalize, but should basic manipulation really be that cumbersome?&lt;/p&gt;</description><link>http://blog.willbarton.com/post/162975152</link><guid>http://blog.willbarton.com/post/162975152</guid><pubDate>Fri, 14 Aug 2009 14:55:00 -0400</pubDate></item><item><title>The advantages of working from home.</title><description>&lt;img src="http://28.media.tumblr.com/EbCTbh1oCr33fkc9vYSWlnDfo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The advantages of working from home.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/162046238</link><guid>http://blog.willbarton.com/post/162046238</guid><pubDate>Thu, 13 Aug 2009 09:51:22 -0400</pubDate></item><item><title>The braces being finished.</title><description>&lt;img src="http://28.media.tumblr.com/EbCTbh1oCqg24i68oild0muWo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;The braces being finished.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/150778123</link><guid>http://blog.willbarton.com/post/150778123</guid><pubDate>Tue, 28 Jul 2009 06:55:57 -0400</pubDate></item><item><title>Braces being built to hold shelves in the room downstairs. 37...</title><description>&lt;img src="http://25.media.tumblr.com/EbCTbh1oCqg238d0FEpQSCzfo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Braces being built to hold shelves in the room downstairs. 37 braces for 9 12’ shelves and 5 4’ shelves.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/150777856</link><guid>http://blog.willbarton.com/post/150777856</guid><pubDate>Tue, 28 Jul 2009 06:55:01 -0400</pubDate></item><item><title>So, we had a little bit of a storm the other day.  Nothing spectacular, or so I thought.  There were...</title><description>&lt;p&gt;So, we had a little bit of a storm the other day.  Nothing spectacular, or so I thought.  There were a few limbs down here and there, and then I got home:&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" src="http://willbarton.com/temp/IMG_1240.jpg" width="640" height="427"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" src="http://willbarton.com/temp/IMG_1250.jpg" width="640" height="427"/&gt;&lt;/p&gt;
&lt;p&gt;Lucky.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146015278</link><guid>http://blog.willbarton.com/post/146015278</guid><pubDate>Sun, 19 Jul 2009 07:52:00 -0400</pubDate></item><item><title>It’s a boy.</title><description>&lt;img src="http://29.media.tumblr.com/EbCTbh1oCq647pu3R3p5yS9Bo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;It’s a boy.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146016965</link><guid>http://blog.willbarton.com/post/146016965</guid><pubDate>Thu, 16 Jul 2009 21:56:00 -0400</pubDate></item><item><title>Photo</title><description>&lt;img src="http://25.media.tumblr.com/EbCTbh1oCpf4fah6QFnCHQhOo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;</description><link>http://blog.willbarton.com/post/134169856</link><guid>http://blog.willbarton.com/post/134169856</guid><pubDate>Thu, 02 Jul 2009 10:33:13 -0400</pubDate></item><item><title>Thoughts on Blocks</title><description>&lt;p&gt;Or: &lt;em&gt;How I Learned to Stop Worrying and Love the NIH&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I’ve been interested in a few things lately with respect to web applications. The first is &lt;a href="http://www.seaside.st/"&gt;Seaside&lt;/a&gt; and its approach to stateful control flow through the use of continuations. Since I’d like to work in Python, continuations are not possible, but we do have something equally interesting, microthreads via &lt;a href="http://www.stackless.com/"&gt;Stackless Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The other is the fact that I have a lot of good, useful code already written to perform logic on data that I’d love to reuse in web applications. The problem is that most available frameworks enforce, to varying degrees, their own views on data modeling. Don’t get me wrong, &lt;a href="http://www.zope.org/"&gt;the&lt;/a&gt; &lt;a href="http://turbogears.org/"&gt;available&lt;/a&gt; &lt;a href="http://pylonshq.com/"&gt;web&lt;/a&gt; &lt;a href="http://www.djangoproject.com/"&gt;frameworks&lt;/a&gt; for Python are all very high-quality and useful in their own right. They’re just not always the best solution to the problems I’m trying to solve.&lt;/p&gt;
&lt;p&gt;So, what I’ve set out to do is to create a lightweight framework that uses &lt;a href="http://www.stackless.com/"&gt;Stackless Python&lt;/a&gt; for control flow between discrete objects that function losely as the &lt;em&gt;Controller&lt;/em&gt; in an MVC-like architecture. These objects can form a tree, with parents, children, and siblings, with state being preserved for that object no matter how the user finds their way to it.&lt;/p&gt;
&lt;p&gt;It can be a little mind-bending at first, and it’s taken me a while to get my mind wrapped around it (assuming I actually have at this point), but I think I have the functional basis for a framework based on these ideas. I’m uncreatively calling it &lt;em&gt;Blocks&lt;/em&gt;. Here’s an example I’ve written for the API documentation that may help to illustrate the basic ideas:&lt;/p&gt;
&lt;pre class="brush: python"&gt;&gt;&gt;&gt; import random
&gt;&gt;&gt; from blocks.content import Block
&gt;&gt;&gt; class IntegerInput(Block):
...     def validate(self, request, num):
...         try:
...             number = int(request.parameters.get("num"))
...         except ValueError:
...             return self.render(request)
...         else:
...             return number
...
...     def render(self, request):
...         self.callback('validate')
...         number = self.respond('''Enter a number!
...             &lt;input type='text' name='num'/&gt;''')
...         self.answer(number)
...
&gt;&gt;&gt; class GuessTheNumber(Block):
...     def render(self, request):
...         secret_number = random.randint(1,100)
...         guess = self.call(IntegerInput(), request)
...         if guess == secret_number:
...             return "Yay! That's correct!"
...         return "Sorry, that's wrong."
&lt;/pre&gt;
&lt;p&gt;This is a fairly simplistic number guessing game. The GuessTheNumber block passes control to another block that takes an integer input and returns it to the original block once its been received. The original then decides whether the guess was correct or not, and informs the user accordingly. This could be expanded to have the GuessTheNumber block loop until the user correctly guesses.&lt;/p&gt;
&lt;p&gt;Because the content blocks are fairly generic (all they need is a ‘render’ method that returns something to give to the user), they can be exceptionally flexible in using existing code, data models, etc. Now, we can lay a few layers on top of that to get some nice templating, generic functionality, and more, but none of that is necessarily required.&lt;/p&gt;
&lt;p&gt;I’m working on a couple of applications based on Blocks which will hopefully help me iron out any problems, bugs, design flaws, etc. Once I’m reasonably satisfied it’s possible to write something useful with Blocks, I’ll release it. Until then, I’ll probably get some introductory info up on its web page at &lt;a href="http://blocks.water-powered.com/"&gt;Water-Powered Ideas&lt;/a&gt;, but I wanted to quickly describe what I’ve been working on for the past few months.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146309745</link><guid>http://blog.willbarton.com/post/146309745</guid><pubDate>Wed, 19 Nov 2008 19:34:00 -0500</pubDate><category>Blocks</category><category>Web Applications</category></item><item><title>We have a Rachel.</title><description>&lt;img src="http://26.media.tumblr.com/EbCTbh1oCq6nzznnGL8sMlR1o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;We have a Rachel.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146310989</link><guid>http://blog.willbarton.com/post/146310989</guid><pubDate>Sun, 30 Dec 2007 15:34:00 -0500</pubDate></item><item><title>Loading C Plugins for PureDocs</title><description>&lt;p&gt;I finally had a chance to sit back down with PureDocs, after getting the build process straightened out, and figure out how to load C plugins. Turns out, it’s pretty simple with ctypes. Let’s imagine I have a C library, compiled and linked as libtest, containing the following (a simple modification of my original example):&lt;/p&gt;
&lt;pre class="brush: c"&gt;#include &lt;stdio.h&gt;
#include "puredocs.h"

Resource * test_function() {
    Resource * r = puredocs_createResource("foo");
    Resource * c = puredocs_createResource("bar");

    puredocs_setDocString(r, "omg some docs lol");
    puredocs_setDocString(c, "some bar docs omg lol");

    puredocs_setProperty(r, "feh", "omg");

    if ((puredocs_addChild(r, c)) &lt; 0) {
        printf("OH NOES!\n");
    }

    return r;
}
&lt;/pre&gt;
&lt;p&gt;This function can easily be called when loading the libary with“ctypes“’s PyDLL type (won’t release the Python interpreter’s GIL, which is important if we’re creating Python objects we want to use). The restype of the function needs to be set toctypes.py_object, since we’re returning a Python object. The whole process looks like this:&lt;/p&gt;
&lt;pre class="brush: python"&gt;&gt;&gt;&gt; from ctypes import *
&gt;&gt;&gt; t = pydll.LoadLibrary("libtest.dylib")
&gt;&gt;&gt; t.test_function.restype=py_object
&gt;&gt;&gt; r = t.test_function()
&gt;&gt;&gt; r
&lt;Resource foo [&lt;Resource bar []&gt;]&gt;
&lt;/pre&gt;
&lt;p&gt;The whole point of this exercise is basically to make it possible to write C libraries that serve as plugins for PureDocs that don’t necessarily have any knowledge of Python. They’ll be linked against a PureDocs library that provides the glue-code. So, for PureDocs’s purpose, I now just need to wrap this around some library loading and registration code, and we’ll be ready to go!&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146311277</link><guid>http://blog.willbarton.com/post/146311277</guid><pubDate>Sat, 01 Sep 2007 09:25:00 -0400</pubDate></item><item><title>Peanut thumbing her nose.</title><description>&lt;img src="http://27.media.tumblr.com/EbCTbh1oCq6o1i0c68pz1Zczo1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Peanut thumbing her nose.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146311609</link><guid>http://blog.willbarton.com/post/146311609</guid><pubDate>Tue, 21 Aug 2007 01:54:00 -0400</pubDate></item><item><title>Building PureDocs, Redux</title><description>&lt;p&gt;After much trial and tribulation with Pyhton’s distutils and setuptools, I decided it wasn’t really appropriate to be building a C library with the Python tools. While the capability exists in distutils, it’s pretty obvious that it suffers from some pretty substantial code rot.&lt;/p&gt;
&lt;p&gt;So, I’ve gone the autoconf route. I didn’t really want to, but really there’s no better solution that I can find that doesn’t involve setting PureDocs aside while I start yet another project.&lt;/p&gt;
&lt;p&gt;In any case, the autoconf’ing isn’t complete, and it doesn’t quite work, but I’ve committed what I have so far. Once I get it all working well on multiple platforms, I’ll finish off the C API. Then Kate should be able to add some C-based plugins using the &lt;a href="http://www.tendra.org/projects/sid/index.html" class="reference"&gt;SID parser generator&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.willbarton.com/post/146311943</link><guid>http://blog.willbarton.com/post/146311943</guid><pubDate>Fri, 10 Aug 2007 23:58:00 -0400</pubDate></item></channel></rss>
