[Pangloss] Re: [openframe] [RFC] OpenFrame AppKit ideas

James A. Duncan jduncan at fotango.com
Tue Apr 8 12:43:21 BST 2003


On Tuesday, April 8, 2003, at 10:39 AM, Steve Purkis wrote:

> Hi James,
>
> Thanks for the comments and suggestions.  I've forwarded your last  
> post on to Pangloss and cross-posted again as I think it still applies  
> - I'm trying to feel out the framework I'll be building Pangloss in  
> and would like the others to see the process.  So please watch replies  
> again .. :)

Fine fine, I'll cross-post this one :-)

> After taking some time to digest your message I've come to the  
> conclusion that I'd misinterpreted the goals of AppKit.  I was  
> assuming it was meant to be a production quality application framework  
> for the web, along with extensibility, bells 'n whistles and such.   
> And so I was holding it up to the light, comparing it to others that I  
> know about and trying to point out ways to improve AppKit.

AppKit may well be production quality in conjunction with other bits  
and pieces from other toolkits on top of OpenFrame.  On its own its not  
particularly fleshed out or complete.

> What a shame: you guys have already solved all these problems, but  
> haven't had time to release them to the world?!  *sniff* !  It would  
> certainly make my job a lot easier! ;-)

The problem is that we've not solved them in a *generic* way.  It  
wouldn't be difficult to extract a framework in retrospect but that  
takes time, and time takes money.

> But seriously, if you do get around to releasing something and need a  
> hand with it let me know.  In the meantime I think I'll follow your  
> suggestion and investigate a separate OpenFrame project.
>
> Next question: is it ok to piggy-back discussions on the OpenFrame  
> list until the idea solidifies, or would it make sense to start up  
> another one from the start?

Use the OpenFrame list if you like.  Its nice to have some traffic  
around here :-)

>>> I'm forced to invent a way of handling errors.  I suppose I could
>>> just stick them in the Session and let the template writer deal
>>> with it.  But then I gotta remove them on each request, and what
>>> if I want to handle them before they get to the template?
>>
>> Thats fine, invent a way to handle errors.  Its pretty hard to come  
>> up with a clever way of abstracting errors and localizing them, and  
>> have it cross cut your presentation and business logic.  This is a  
>> difficult problem, and not one I've managed yet to solve or find a  
>> system that elegantly solves it for me.
>
> It is hard to abstract this, yes.  The way I've handled it in the past  
> has been to throw exceptions my business logic layer, and then convert  
> the exceptions that reach the presentation layer into error flags that  
> the template writer can use.  (Assuming the presentation layer is  
> defined by a template, of course :).
>
> This puts the onus on the Template writer to cover all the error flags  
> that can be set which requires some discipline and, while annoying,  
> works for the situations I've encountered thus far.
>
> I was hoping to use Locale::Maketext for situations where error flags  
> are not enough, though I admit I haven't thought it through yet.

Programmer laziness is good; programmer complacency is bad.  Error  
handling (and everything else for that matter) should enable the former  
whilst discouraging the latter.  Specific solutions will always work,  
because they are specific to the problem (or error) at hand.  I'd like  
to come up with a generic solution for it - but I've not put enough  
hours on it to solve it yet.

> Anyways, one idea is to come up with various error-handling toolkits  
> for OpenFrame.  That way at least users would have something to go on,  
> but can roll their own if need be.

Thats the idea.

>> The loader's will load the appropriate object when they can, and then  
>> the decliners sat at the top of the embedded pipelines return a  
>> Pipeline::Production if there isn't something the rest of the chain  
>> of execution down that particular pipeline can handle.  By using this  
>> method rather than AppKit::App's fairly obscure entry-point  
>> mini-language, we've been able to get expressive classes that cause  
>> the model do one thing and one thing only.  By joining them together  
>> in various ways we can quickly create new applications or by writing  
>> the merest sliver of code bring as-yet unused parts of the model into  
>> play.
>
> So you're essentially classifying your segments and blocking entry to  
> a pipeline when there's nothing in it that it can handle.  Good idea -  
> I can see the utility in that.  For example, you could branch off  
> another pipeline that handled privileged operations that declined  
> requests based on type of user.  You'd also get a good overview of  
> your application without all the clutter.  I will definitely look  
> further into this.

Yup, we do branch our pipeline for administrator operations :-)  We're  
learning how to use pipelines more effectively all the time, and slowly  
its becoming provably useful, rather than just a hunch on my part.   
This sort of internal architecture is one of the things thats proving  
it, as the amount of reuse we've achieved has skyrocketed.

> I agree that there are a lot of similarities between a Segment and the  
> idea of an Action.  The main difference is that an Action would be a  
> bit more specific about what it does: validates and executes actions  
> based on OF::Request's.

Yup, an action can easily be sub-classed from a Segment.

> As for making sure developers write good controllers... well, as in  
> OpenFrame, you can only give them the toolkit.  What they do with it  
> is up to them...

Sure, I realize that, and I'm certainly not into the bondage and  
discipline that certain other programming languages may try and  
enforce.  It is however, nice to strongly suggest...

>>>   URL -> Action mapping
>>> 	Each Action has a url, set in a config file.
>>
>> The other problem with this is a localization issue - if you take a  
>> piece of a URL, for example 'red.html', your french translater is  
>> probably going to want to translate this to 'rouge.html'.   Depending  
>> on how tightly your URL's are bound to your actions you're going to  
>> either have to duplicate the section that calls into your application  
>> _or_ have some sort of pattern matching.  I'm not particularly in  
>> fond of either of those two outcomes.
>
> I got that wrong: each Action has one or more URLs.  Which means  
> pattern matching, yes.  I was thinking along the lines of  
> DispatchOnUri, and frankly I still don't see much wrong with that.

Again, at Fotango we try to let the Pipeline make the decisions for us.  
  Rather than tying specific functionality to a specific URL we let the  
Pipeline decide what functionality to turn execute and not.  This can  
prove hazardous in some situations, but its generally leading to a)  
greater and more effective separation of concerns and b) a more useful  
and robust model.

As an example of this lots of our code in the model used to operate on  
the object id of an image, and involve resolving the id to the original  
object.  By virtue of letting the pipeline Do The Right Thing we don't  
generally bother now, because the model has evolved to accept both  
object id's and objects.  So somewhere near the top of the pipeline we  
turn the object id's seen on the URL into the objects the are supposed  
to represent.  Caveat: for various reasons this isn't _exactly_ what we  
do, but its as close as I can get to explaining.

>> In general I detest config files.  Config files are mini-languages,  
>> and can be far better expressed in a programming language.  I get the  
>> feeling I hold a different opinion on this from most people >  
>> however....
>
> I see your point, but I disagree.  It's true, config files *are*  
> mini-languages, but that's precisely why they're so useful.  They make  
> a world of difference for non-programmers -- imagine how difficult it  
> would be to administrate a machine if you had to know every  
> programming language available to do it?  A well thought out config  
> file can save a lot of hassle...

Config files tend to be filled with the scraps of stuff that don't seem  
to fit neatly anywhere else.  I'd rather see a well thought out way to  
swap pipeline segments in and out of the pipeline (ie,  
Segment::DBH::TestDB vs Segment::DBH::ProdDB) in a front-end userland  
type interface than a well-thought out config file :-)

Something I've been thinking about for a while is a way to get an  
OpenFrame system installed, run it, and be presented with an interface  
that ties to CPAN for downloading new segments, and putting them in  
place.  It would be _really_ nice to have, but probably difficult to  
get one's head around the bootstrapping needs.

> Of course, if you go ahead and program an easy to use administration  
> interface then you could theoretically do away with config files.. :)

Indeed.

>>>   Action Forwards
>>> 	Each Action can have one or more named 'forwarding' url's
>>> 	which can be used to choose which template page to load.
>>> 	    success => "/success.html"
>>> 	    failure => "/failure.html"
>>> 	these are also set in a config file.
>>
>> See above :-)  Again with this I'd rather see the programmer decide  
>> what is going to happen, rather than having a configuration file that  
>> gets placed in obscure parts of the system.
>
> The programmer does decide what will happen and defines it in a config  
> file.  It's almost like saying: The administrator chooses which  
> templates to load.  Which may or may not be handy.  And may or may not  
> be extra hassle for the programmer.  Hmm.. now you've got me > wondering.

Good!  Why would the administrator ever want to alter the presentation  
logic of the application?  I can understand the programmer maybe  
wanting to do it programatically though :-)

>> We do that at Fotango for CIG as well as other systems that are being  
>> worked on at the moment.  We have a Site-map class that maps URLs to  
>> abstract paths in the system, and back to templates.  The site-map  
>> also carries all the text and error messages that are used by the  
>> templates.  The problem with it is that although the information is  
>> kept in one place and one place only it also seems to be a pain to  
>> remember just where that place is.  Again, I hate presentation layers  
>> so I'm probably not best to comment on this mechanism as opposed to  
>> any other - I hate them all :-)
>
> Hmm..  The idea of a site map that maps URLs to paths and back seems  
> like a sound idea to me.  But including all the text + error messages  
> in this object seems misplaced to me.  Yes, they all contain text that  
> can be localized, but that's the only thing they share in common.  To  
> me, that's not enough of a reason to lump them all together.  Have you  
> considered introducing a Template class that includes messages (errors  
> and text), and knows how to localize them?

The system doesn't work exactly like that.  It has various elements of  
the site-map, that are separate.  The Template is aware of how to  
localize things (based on the Locale thats loaded in a separate segment  
of course), and all the stuff can be weaved together in an  
aspect-oriented type manner.

ABW summarized the system pretty well here:

http://lists.template-toolkit.org/pipermail/templates/2002-June/ 
003267.html

and I'd rather not repeat him, and while I don't agree with everything  
Andy says, most of it is bang on; the bits where I disagree with him  
are pointless engineering arguments that people can have all month long  
and never get anywhere with :-)

Regards,
James.



More information about the Pangloss mailing list