From dpinte at itae.be Fri Feb 17 22:19:50 2006 From: dpinte at itae.be (Didrik Pinte) Date: Fri, 17 Feb 2006 12:19:50 +0100 Subject: [albatross-users] al-input and id Message-ID: <1140175190.10111.163.camel@geru-itae> Hi, al-input has nameexpr and valueexpr. Is there any way to have an idexpr ? Thank you in advance for your help. Didrik -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Ceci est une partie de message num?riquement sign?e URL: From andrewm at object-craft.com.au Fri Feb 17 22:56:41 2006 From: andrewm at object-craft.com.au (Andrew McNamara) Date: Fri, 17 Feb 2006 22:56:41 +1100 Subject: [albatross-users] al-input and id In-Reply-To: <1140175190.10111.163.camel@geru-itae> References: <1140175190.10111.163.camel@geru-itae> Message-ID: <20060217115641.CDC706F425E@longblack.object-craft.com.au> >al-input has nameexpr and valueexpr. > >Is there any way to have an idexpr ? Recent versions of Albatross let you do exactly that (if you're not already using 1.33, I suggest you download that anyway). -- Andrew McNamara, Senior Developer, Object Craft http://www.object-craft.com.au/ From dpinte at itae.be Sat Feb 18 00:06:37 2006 From: dpinte at itae.be (Didrik Pinte) Date: Fri, 17 Feb 2006 14:06:37 +0100 Subject: [albatross-users] al-input and id In-Reply-To: <20060217115641.CDC706F425E@longblack.object-craft.com.au> References: <1140175190.10111.163.camel@geru-itae> <20060217115641.CDC706F425E@longblack.object-craft.com.au> Message-ID: <1140181597.10111.171.camel@geru-itae> Le vendredi 17 f?vrier 2006 ? 22:56 +1100, Andrew McNamara a ?crit : > >al-input has nameexpr and valueexpr. > > > >Is there any way to have an idexpr ? > > Recent versions of Albatross let you do exactly that (if you're not > already using 1.33, I suggest you download that anyway). I'm using 1.33-2 version of Debian/Sid. It does not work. I had a look a /usr/lib/python2.3/site-packages/albatross/tags.py and there is no reference do "idexpr" in the Input class. What I am doing wrong ? -- Didrik -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Ceci est une partie de message num?riquement sign?e URL: From andrewm at object-craft.com.au Sat Feb 18 00:45:28 2006 From: andrewm at object-craft.com.au (Andrew McNamara) Date: Sat, 18 Feb 2006 00:45:28 +1100 Subject: [albatross-users] al-input and id In-Reply-To: <1140181597.10111.171.camel@geru-itae> References: <1140175190.10111.163.camel@geru-itae> <20060217115641.CDC706F425E@longblack.object-craft.com.au> <1140181597.10111.171.camel@geru-itae> Message-ID: <20060217134528.CD10A6F425E@longblack.object-craft.com.au> >> Recent versions of Albatross let you do exactly that (if you're not >> already using 1.33, I suggest you download that anyway). > >I'm using 1.33-2 version of Debian/Sid. It does not work. > >I had a look a /usr/lib/python2.3/site-packages/albatross/tags.py and >there is no reference do "idexpr" in the Input class. No, it's "magic" - the attribute handling in the Input class is for the classic al-input attributes. The code that allows any attribute to be the product of an expr is in the write_attribs_except() method of the template.Tag class. >What I am doing wrong ? I'm not sure - to check I wasn't deluding myself, I tried it myself and got the expected result: 1$ python Python 2.3.5 (#2, Aug 30 2005, 15:50:26) [GCC 4.0.2 20050821 (prerelease) (Debian 4.0.1-6)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import albatross >>> albatross.__version__ '1.33' >>> ctx = albatross.SimpleContext('.') >>> ctx.locals.names = ['Alex', 'Fred', 'Guido', 'Martin', 'Raymond', 'Tim'] >>> albatross.Template(ctx, '', ... '').to_html(ctx) >>> ctx.flush_content() -- Andrew McNamara, Senior Developer, Object Craft http://www.object-craft.com.au/ From dpinte at itae.be Sat Feb 18 04:16:33 2006 From: dpinte at itae.be (Didrik Pinte) Date: Fri, 17 Feb 2006 18:16:33 +0100 Subject: [albatross-users] labels Message-ID: <1140196593.10111.191.camel@geru-itae> Hi, Thank you Andrew for the great information on idexpr. It works fine now. Another related question. Using those id's, i'm trying to add labels to my web application. First I tried to this : but the tag is not interpreted. I transformed it to the following which is pretty dirty ... : Stations : Is there a more subtle way to do that ? I did not find in the documentation information on how albatross tags are interpreted. Is there some information on that somewhere on the web ? Thanks Didrik -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 189 bytes Desc: Ceci est une partie de message num?riquement sign?e URL: From andrewm at object-craft.com.au Mon Feb 20 10:24:52 2006 From: andrewm at object-craft.com.au (Andrew McNamara) Date: Mon, 20 Feb 2006 10:24:52 +1100 Subject: [albatross-users] labels In-Reply-To: <1140196593.10111.191.camel@geru-itae> References: <1140196593.10111.191.camel@geru-itae> Message-ID: <20060219232452.A36B3794218@longblack.object-craft.com.au> >Another related question. Using those id's, i'm trying to add labels to >my web application. > >First I tried to this : > > > >but the tag is not interpreted. Hmmm - that should have worked. >I transformed it to the following which is pretty dirty ... : > >noescape>Stations : > >Is there a more subtle way to do that ? I'd suggest: Stations : However, the above is slightly different to what you have - do you really want the noescape - it's a safety measure, and should really be retained if possible? >I did not find in the documentation information on how albatross tags >are interpreted. Is there some information on that somewhere on the >web ? The documentation is included with Albatross, and it does describe all this in excruciating detail (the biggest problem is finding the bit you need). The latest version of the doco is also available on the Object Craft web site: http://www.object-craft.com.au/projects/albatross/albatross/ -- Andrew McNamara, Senior Developer, Object Craft http://www.object-craft.com.au/ From korg at darkqueen.org Thu Feb 23 14:40:07 2006 From: korg at darkqueen.org (Cameron Blackwood) Date: Thu, 23 Feb 2006 14:40:07 +1100 Subject: [albatross-users] Some questions and my albatross wrapper.... Message-ID: <20060223034007.AAA5453912@firewall.darkqueen.org> Hi everyone. Im an on again, off again albatross user and Ive been working on a 'wrapper class' to make my albatross programming easier. This post is kind of long, but first Ill as some silly questions :) and some comments and then Ill talk about the wrapper Im writing. Im a system admin my trade, not a web designer so _please_ do post any opinions or comments on better ways to do this (because it probably hasnt occured to me :) Doc request: Extending tags & input_add --------------------------------------- I was coding up a Custom tag to make input/command buttons easier, and it took me ages to get the input value into the context. It took me a while to locate the input_add() function :). Maybe make a note of that in the docs? Yes, it was quickly obvious from looking at the source, but how about adding: "If your tag does form input, you need to register the input name with the input_add function" :) Oh and I just want to say that Id been avoiding making my own tags, but boy, is it ever easy and cool! Again albatross rocks with its simplicity and easy of use. Doc request: Extended tag names ------------------------------- Could we get some documentation on what is makes a _valid_ name for an extended tag? Or maybe register_tagclasses() should produce an error if the name isnt valid (so you dont register stuff that is never called). Lets play 'Which of the following are valid'? :) alx-foo_moo: valid alx-foo-moo: invalid al-foo-moo: ah, its too hard, lets just stick with alx-foomoo :) :) Defining a tag alx-test_for that silently stops working if I rename it alx-test-for is just plain weird. I guess I expected that if you register a tag that cant be called, register would say something. :) Either that or put something in the docs? For loops with var="foo"? ------------------------- I keep using for loops and I keep needing 'iter.value()' all through my templates which is ugly and kind of annoying. (I tend to use the object more than the iterator, but maybe thats just me.) Is there any reason we cant make the al-for optionally set a variable in the context? I hacked up a test version and I have this working:
  • produces: * 1 * 1.4 * foo * [1, 2] * end Which seems handy to me. Maybe there could be an optional tag in al-for, rather than everyone rolling their own? Now, what to call it.... value? valuename? variable? var? item? itemname? name? dagnamit? Templates? ---------- I love my albatross :), but what I want is for a single meta-template over my whole site. Currently I have the following in all my tempaltes: **my stuff** But really thats kind of ugly. Is there a better way to do it? (header and footer are magically loaded, obviously). I thought about hacking the load_template code to chuck this on automatically or some ugly system where you always just render a base template, rather than the page template, and the page code itself is just a macro or something. Nothing was really obvious or clear. Comments and ideas welcome here. (note my sudden idea below might solve this...) More on templates... -------------------- As I said, Im working on a wrapper function for albatross and it seems to me that the one could argue that the template should be provided by the page object, not passed to the page object in... *BING!* *SUDDEN IDEA!* Let me change this topic to: moron templates! :) Myself being the moron. I was passing the template to the page's __init__ function as shown in some of the demo code, but I dont have to do that, do I? I just realised that writing this. I can dynamically locate the template in my page's display function. Maybe. Hmm. That may solve my 'standard layout' problem. Hmm. Maybe I can make my page class have a 'return_template_string' function which generates the actual template from the file and the headers and creates a Template. [Note, I might just be ranting for this section, I havnt thought it through fully.] templates wrong? ---------------- Maybe Ive been doing them incorrectly... I think I need to think about them some more. Maybe ill end up with my page class doing the loading and creating of the Template (from the headers & footers and the actual template file) as that seems to be the 'right thing'(tm). My wrapper class ================ Why a wrapper class? Well I always found it kind of hard to revisit albatross code that Id written. There were a number of reasons for that but mostly they boil down to the fact that I want to write code that is 'just magically loaded and works' rather than having to tinker with albtross startup itself. Now when Im in 'albatross' mode, its all easy enough and flowing, but getting there was always a bit of a struggle (and it was usually the annoying startup & setup stuff and not the everyday pages stuff that got to me). So I tried to create a better wrapper for Applications and Pages that did most of the work for me. * Creating the APP. problem: All those register_page()'s were kind of annoying. solution: give the APP a single directory on start up and make it locate and load all the pages in that directory tree and register them. (It also finds the start page automatically too.) * global and locals problem: Kind of obscure to use globals and locals in the ctx solution: page has a create_global and create_local function and automatically flushes the locals on page change. Much less overhead. * looking up variables problem: ctx.locals.foo is a bit confusing to people new to albatross (especially if foo is a global) solution: page and ctx now support self['foo']='moo' (If foo doesnt exist, it barfs, so you need to set it as local or global before use.) * debugging messages you can just self.DEBUG("Im looking at foo... v==%s",foo) and it appears in a log. Also DEBUGvars dumps all the variables in the context into the DEBUG output. (Which I usually just display in my footer while developing.) It also writes what its calling and doing into the DEBUG output so you can see page changes and what is being called. * page class. An actual base page class which supports some short cuts to use the ctx. Eg, def work_process(s): login,username,passwd=s['login','username','password'] s.DEBUG('login [%s][%s]',username,passwd) if login and username=='admin' and passwd=='foo': s.goto('ok') seems easier to read and maintain. Also s['notset'] return None if the variable doenst exist so you can go: if s['login'] and s['username']=='admin' and s['passwd']=='foo': * command buttons Smarter wrapping of buttons so you can do template code like this: :: which will make a button with the label and call a method 'add' with the arguments specified if you click it. (It stores the details in a list in the context and makes an name="id" and then checks that id against the list of pressed buttons before page_process. It calls them automatically just after process.) (Im going to extend this to other buttons (radio/choice) too.) (There might be a nicer way to do this, any ideas are welcome.) * goto (set_page) acts like 'cd' Given I loaded all the pages in from a single directory, you can end up with pages like login, user/info, user/edit, user/messages so the goto function is relative to where you are now. (Its a small thing, I know.) Im trying to get this stuff neated up and postable by the weekend so that I can use it as a library in the pyweek.org contest (write a game in python in a week) for a web based game. Ill post a url to it here once its up (IE readable by non insane humans :) and I have the template thing worked out more. (Then its off to do my image library... :) cheers, cam PS: I feel stupid wrapping albatross, because i guess im really just wrapping away all the stuff that always gave me trouble. But it seems to me that everyone in the universe has to make their own web framework at some stage and albatross always seems 'so close' to perfect that wrapping the bits that annoyed me seems the easiest solution. :) No offence to the object-craft. I love albatross and even used the template stuff to dynamically generate c and c++ code in a research project. :) :) :) :) -- / `Rev Dr' cam at darkqueen.org Roleplaying, virtual goth \ < http://darkqueen.org Poly, *nix, Python, C/C++, genetics, ATM > \ [+61 3] 9809 1523[h] skeptic, Evil GM(tm). Sysadmin for hire / ---------- Random Quote ---------- modesty, n.: Being comfortable that others will discover your greatness. From andrewm at object-craft.com.au Thu Feb 23 18:42:54 2006 From: andrewm at object-craft.com.au (Andrew McNamara) Date: Thu, 23 Feb 2006 18:42:54 +1100 Subject: [albatross-users] Some questions and my albatross wrapper.... In-Reply-To: <20060223034007.AAA5453912@firewall.darkqueen.org> References: <20060223034007.AAA5453912@firewall.darkqueen.org> Message-ID: <20060223074254.1E3BB794093@longblack.object-craft.com.au> >Im a system admin my trade, not a web designer so _please_ do post any >opinions or comments on better ways to do this (because it probably >hasnt occured to me :) All feedback is valuable - you get to see the package from a different point of view, and can see weaknesses that we're blind to. >Doc request: Extending tags & input_add [...] >It took me a while to locate the input_add() function :). Maybe make >a note of that in the docs? Yes, it was quickly obvious from looking >at the source, but how about adding: > > "If your tag does form input, you need to register the input name > with the input_add function" :) Noted. >Oh and I just want to say that Id been avoiding making my own tags, >but boy, is it ever easy and cool! Again albatross rocks with its >simplicity and easy of use. Yep - blame Dave. >Doc request: Extended tag names >------------------------------- >Could we get some documentation on what is makes a _valid_ name for an >extended tag? Or maybe register_tagclasses() should produce an error >if the name isnt valid (so you dont register stuff that is never >called). > >Lets play 'Which of the following are valid'? :) > alx-foo_moo: valid > alx-foo-moo: invalid > al-foo-moo: ah, its too hard, lets just stick with alx-foomoo :) >:) > >Defining a tag alx-test_for that silently stops working if I rename it >alx-test-for is just plain weird. I guess I expected that if you >register a tag that cant be called, register would say something. :) I've added a check to register_tagclasses. We should also document what is valid (I've made a note to do this). XML says only a-z, 0-9 and underscore are valid, but what counts in this context is what the parsing regular expression thinks is valid - currently this matches the XML spec, but think we could add hypen at some point (then again, maybe we should disallow underscore?). >For loops with var="foo"? >------------------------- >I keep using for loops and I keep needing 'iter.value()' all through my >templates which is ugly and kind of annoying. (I tend to use the >object more than the iterator, but maybe thats just me.) > >Is there any reason we cant make the al-for optionally set a variable >in the context? > >I hacked up a test version and I have this working: > >
  • > > I like this! What do others think? I usually do something like the following, but it irritates me every time: ... >Templates? >---------- >I love my albatross :), but what I want is for a single meta-template >over my whole site. Currently I have the following in all my >tempaltes: > > > > **my stuff** > > > >But really thats kind of ugly. Is there a better way to do it? >(header and footer are magically loaded, obviously). You can put the al-form in the macro, if you like. I do something like this in nearly every application. I usually find there are occasional pages where I want an alternate page layout macro, however. So a solution that automatically wrapped every page with a macro wouldn't be flexible enough for these times. Unfortunately, most of the apps I'm working on at the moment have a 20 line copyright header at the top of every template to keep the lawyers happy. Compared to that, a couple of lines to expand the macro are nothing. 8-) >My wrapper class >================ >Why a wrapper class? > >Well I always found it kind of hard to revisit albatross code that Id >written. There were a number of reasons for that but mostly they boil >down to the fact that I want to write code that is 'just magically loaded >and works' rather than having to tinker with albtross startup itself. I agree that it's a bit of a bugger getting started with an Albatross app. >Now when Im in 'albatross' mode, its all easy enough and flowing, but >getting there was always a bit of a struggle (and it was usually the >annoying startup & setup stuff and not the everyday pages stuff that got >to me). So I tried to create a better wrapper for Applications and Pages >that did most of the work for me. > > * Creating the APP. > problem: All those register_page()'s were kind of annoying. > solution: give the APP a single directory on start up and make it > locate and load all the pages in that directory tree > and register them. (It also finds the start page > automatically too.) Isn't this pretty much what a "Modular" app does anyway? > * global and locals > problem: Kind of obscure to use globals and locals in the ctx > solution: page has a create_global and create_local function and > automatically flushes the locals on page change. Much > less overhead. Uh - I'm not sure what you mean. Within the template, the local namespace is ctx.locals, and the global (module) namespace is module namespace of the module that called run_template (I think - someone correct me if I'm wrong). > * looking up variables > problem: ctx.locals.foo is a bit confusing to people new to > albatross (especially if foo is a global) > solution: page and ctx now support self['foo']='moo' > (If foo doesnt exist, it barfs, so you need to set it as > local or global before use.) Uh, no comment... 8-) > * debugging messages > you can just self.DEBUG("Im looking at foo... v==%s",foo) > and it appears in a log. Also DEBUGvars dumps all the variables in > the context into the DEBUG output. (Which I usually just display > in my footer while developing.) It also writes what its calling > and doing into the DEBUG output so you can see page changes and what > is being called. Fair enough. At one point we were thinking of attaching a logging object of some sort to the ctx, but then the python logging module came along, and reduced the need for us to do our own logging code. > * page class. > An actual base page class which supports some short cuts to use > the ctx. Eg, > > def work_process(s): > login,username,passwd=s['login','username','password'] > s.DEBUG('login [%s][%s]',username,passwd) > if login and username=='admin' and passwd=='foo': > s.goto('ok') > > seems easier to read and maintain. Also s['notset'] return None if > the variable doenst exist so you can go: > > if s['login'] and s['username']=='admin' and s['passwd']=='foo': Okay. > * command buttons > Smarter wrapping of buttons so you can do > template code like this: > > > :: > > > which will make a button with the label and call a method 'add' > with the arguments specified if you click it. > > (It stores the details in a list in the context and makes an > name="id" and then checks that id against the list of pressed > buttons before page_process. It calls them automatically just > after process.) > > (Im going to extend this to other buttons (radio/choice) too.) > > (There might be a nicer way to do this, any ideas are welcome.) I've been thinking about similar ideas myself, without coming up with anything I really like. I have a branch in CVS that implements something like macros, but each macro has an associated object. Inputs defined within that macro are relative to the object's namespace, which allows you to implement composite "inputs" (call them web widgets). Submit buttons are still a bit of a sticking point, however. Care has to be taken not to open up a potential remotely exploitable vulnerability. > * goto (set_page) acts like 'cd' > Given I loaded all the pages in from a single directory, you can > end up with pages like login, user/info, user/edit, user/messages > so the goto function is relative to where you are now. (Its a > small thing, I know.) Nice idea. In my apps I prefer the explicit path each time, however. >PS: I feel stupid wrapping albatross, because i guess im really just > wrapping away all the stuff that always gave me trouble. > > But it seems to me that everyone in the universe has to make their > own web framework at some stage and albatross always seems 'so > close' to perfect that wrapping the bits that annoyed me seems the > easiest solution. :) > > No offence to the object-craft. I love albatross and even used the > template stuff to dynamically generate c and c++ code in a research > project. :) :) :) :) No offence taken - it was an important goal in the development of Albatross for people to be able to pick it up and click the bits together in new ways. -- Andrew McNamara, Senior Developer, Object Craft http://www.object-craft.com.au/ From gabriel.cooper at mediapulse.com Fri Feb 24 07:37:42 2006 From: gabriel.cooper at mediapulse.com (Gabriel Cooper) Date: Thu, 23 Feb 2006 15:37:42 -0500 Subject: [albatross-users] Some questions and my albatross wrapper.... In-Reply-To: <20060223034007.AAA5453912@firewall.darkqueen.org> References: <20060223034007.AAA5453912@firewall.darkqueen.org> Message-ID: <43FE1D16.8090608@mediapulse.com> >For loops with var="foo"? >------------------------- >I keep using for loops and I keep needing 'iter.value()' all through my >templates which is ugly and kind of annoying. (I tend to use the >object more than the iterator, but maybe thats just me.) > > Given that one necessarily desires readable over concise code (otherwise we'd be in the PERL forums, no?), I always found that my first line after a for loop was: This was a constant annoyance I had with Albatross, so we did exactly what you suggested when we created Snakeskin and implemented it like so: ... where the "expand" parameter expands the list given into locals. Seems to work pretty well. I suppose we could make naming the iterator optional as well... I've found use for it on count() and so on, so I like to keep it around. =D > > >Templates? >---------- >I love my albatross :), but what I want is for a single meta-template >over my whole site. Currently I have the following in all my >tempaltes: > > > > **my stuff** > > > > here's an overly complicated example of what I usually end up with. [some javascript function named someLoadEvent() to extend the example =P] put html page content here with the following for subpage_template: <al-usearg name="title"/> "> [site structure specific to this template....] [finish structure specific to this template] (<--- expands the content given in the body of the "al-expand" tag) [call various other common macros... footer...privacy policy... copyright... terms of use... etc. etc.] Actually... It's been a while since I used the original Albatross. Does it let you set default macro parameters? If not, move the parameters in the al-macro tag other than "name" to each individual al-expand call and I think move the parameters (once again, other than "name") out of the al-expand into their own tags. Gabriel. From gabriel.cooper at mediapulse.com Fri Feb 24 09:23:39 2006 From: gabriel.cooper at mediapulse.com (Gabriel Cooper) Date: Thu, 23 Feb 2006 17:23:39 -0500 Subject: [albatross-users] Some questions and my albatross wrapper.... In-Reply-To: <43FE1D16.8090608@mediapulse.com> References: <20060223034007.AAA5453912@firewall.darkqueen.org> <43FE1D16.8090608@mediapulse.com> Message-ID: <43FE35EB.9010806@mediapulse.com> > > iter="iter" > expand="(first_name,last_name)"> > ... > > where the "expand" parameter expands the list given into locals. > > Seems to work pretty well. I suppose we could make naming the iterator > optional as well... I've found use for it on count() and so on, so I > like to keep it around. =D Continuing that thought process.... Hm. One could combine the iter and expand parameters where, instead of being joined to locals, the names given in the expand parameter would become attributes of the iterator or perhaps dictionary keys, like so: iter.first_name iter.last_name or iter['first_name'] iter['last_name'] then we'd still have access to iter.value() iter.count() etc. Heck we could easily implement both the dictionary and attribute method by using this class here: class DictObj(dict): ''' DictObj is a normal dictionary that allows you to access its members via the standard ``var[key]`` method as well as the more-readable ``var.key``. ''' def __init__(self,dic={}): dict.__init__(self,dic) self.__dict__ = self Mostly I enjoy the attribute implementation (iter.name) because it removes so much confusion with regard to quoting inside HTML code. i.e. onclick="window.open('', 'windowname');" A syntax hilighter that can make it through that mess of quotes would be mighty impressive. Compare to: onclick="window.open('', 'windowname');" Much easier for syntax highlighters as it would consider the al-value nonsense a jumble of characters inside a double-quoted (") string, as opposed to a syntax-breaking bit of code inside an anchor tag. And also, the Designers here don't do much by way of programming, but they can do a bit by example. Dictionaries aren't as easy to remember from one month of disuse to the next (or how to do them) as the attribute implementation, since it's so much more readable and memorable. We also wouldn't have to worry about muddying locals with for-loop refuse. Gabriel. From korg at darkqueen.org Sun Feb 26 12:23:37 2006 From: korg at darkqueen.org (Cameron Blackwood) Date: Sun, 26 Feb 2006 12:23:37 +1100 Subject: [albatross-users] Re: Some questions and my albatross wrapper.... In-Reply-To: Your message of "Thu, 23 Feb 2006 14:40:07 +1100." Message-ID: <20060226012337.EDF7A540D7@firewall.darkqueen.org> If I may be rude and reply to my own message.... :) "Cameron Blackwood" (thats ME!) writes: | | Hi everyone. Im an on again, off again albatross user and Ive been | working on a 'wrapper class' to make my albatross programming easier. | | | For loops with var="foo"? | ------------------------- Im so glad you liked this idea :) *does happy dance* Iter.value() has always been an annoying point for al-for's for me. | | My wrapper class | ================ Im not proud of this code but...... http://darkqueen.org/docs/code/korg_web/ You should be able to: * extract the tarball * have a look at the sample pages and templates in korg_web/stuff (korg_web/stuff/template_ten.html is the only non standard template) (korg_web/stuff/pages.py korg_web/stuff/obj_a/pages.py korg_web/stuff/obj_a/obj_a/pages.py have the page code.) * edit the test.py to add albatross to your path (if it isnt site-installed) * [ note: the first arg of TestApp is your content directory. If you use this with your own application you need to change this :)] * run python test.py and point a web browser to http://localhost:7722/ And no, I dont like the name either.... :) this is a way alpha release and to be honest, if people like any of the ideas, then id rather they rolled them into albatross rather than using my code. :) :) :) :) | | Why a wrapper class? Because to make a change: * copy an existing template_???.html to template_myfoo.html * create a class myfoo in the pages.py * edit an existing page class so you can goto the new page (see index class in stuff/pages.py) * restart the app Easy. All done via the files. If you add the page to stuff/obj_a then the page appears as stuff/obj_a/myfoo as you'd expect. :) Combined with the hiding of ctx.locals, I find the code more readable. This makes coming back to any project using it easier. (IMHO) There was a question about the security of..... | | * command buttons | Smarter wrapping of buttons so you can do | template code like this: | | | :: | | | which will make a button with the label and call a method 'add' | with the arguments specified if you click it. Let me explain a bit more about how that works.... When your dtml code marks up something like: | The tag creates a button_id (the name="xxx" setting on the submit button). The function op and args are stored in a dictionary in the context under that button_id. When the page is processed, the dictionary keys (button_id's) are looked up in the submitted inputs and any that are selected then the op and args are placed in the 'commands to run' queue. Then process_page() is call (so you can edit/check/add/remove them if you want). Then the 'commands to run' queue calls all the specified (by op) methods with the specified arguments. So, these buttons _cant_ execute anything that you didnt put in your dtml code. Only the functions/args that you marked up are available in the dictionary, so the user can _only_ send button_id's that you created, not call random methods with arguments that you dont want. (Obviously you dont want the context stored in the browser, but my wrapper code uses session files, so that isnt an issue for me.) Again, Im a sysadmin, not a webdev, so sanity checking, comments or pointing out the better way to do this is always welcome. cheers, cam -- / `Rev Dr' cam at darkqueen.org Roleplaying, virtual goth \ < http://darkqueen.org Poly, *nix, Python, C/C++, genetics, ATM > \ [+61 3] 9809 1523[h] skeptic, Evil GM(tm). Sysadmin for hire / ---------- Random Quote ---------- Q: Why do ducks have big flat feet? A: To stamp out forest fires. Q: Why do elephants have big flat feet? A: To stamp out flaming ducks.