[albatross-users] Some questions and my albatross wrapper....

Andrew McNamara andrewm at object-craft.com.au
Thu Feb 23 18:42:54 EST 2006


>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:
>  <alx-kwfor obj="o" expr="[1,1.4,'foo',[1,2],'end']">
>    <li><al-value expr="type(o)">
>    <al-value expr="o">
>  </alx-kwfor>

I like this! What do others think? I usually do something like the
following, but it irritates me every time:

        <al-for iter="widget_iter" expr="widgets">
         <al-exec expr="widget = widget_iter.value()">
         ...
        </al-for>

>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:
>
>  <al-expand name="header"/>
>  <al-form method="post">
>  **my stuff**
>  </al-form>
>  <al-expand name="footer"/>
>
>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 <input type="submit"> buttons so you can do
>    template code like this:
>
>      <al-for iter="i" expr="ten_list">
>         <al-value expr="i.value()">::
>         <alx-kwbutton label="inc this number" op="add" args="[i.index(), 1]">
>
>    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/



More information about the Albatross-users mailing list