Discussion:
[cgi-prototype-users] CGI::Prototype::PathInfo
A. Pagaltzis
2005-08-03 03:06:44 UTC
Permalink
Hi all,

and hi Randall in particular. I have a working version of this,
largely derived from ::Hidden for consistency in slot names. (It
also let me copy 95% of the POD verbatim. Writing documentation
is easy when it’s already done for you. *g*)

It has a somewhat distinct personality in that it wants an
explicit list of page names to validate (I’d rather prefer if
::Hidden worked the same way – I like my code hardwired for “no
surprises ever possible”) and works slightly differently in a few
minor aspects. But by and large a well-written ::Hidden app would
translate to a ::PathInfo one with almost no changes.

I’ve also added a little twist so that “foo.cgi/bar/42” will
dispatch to “My::App::bar” and set the “page_id” slot to 42 in
the process. (The slot defaults to undef.) This is very handy for
cruft-free, clean URLs.

I’ve pondered doing more extensive URL parsing than what I
currently have, based on the fact that the list of valid page
names is known; but I couldn’t think of good, simple conventions
for the meaning of the addition path segments, so I left it out
for the time being. I think the best course of action would be to
pass those to a slot so the user can define any behaviour they
desire, and leave the default implementation of that slot empty.

Now my question is: should I put this on CPAN, or should I leave
the space to an “official” version? Or should I just post it
here, maybe? If I put this on CPAN myself, what should I put in
the AUTHOR and COPYRIGHT & LICENSE sections of the POD? There is
so little code in there that the notion of authorship is a bit
ridiculous either way, but I also copied several pages of POD
that I can hardly claim authorship of.

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
Terrence Brannon
2005-08-03 18:04:58 UTC
Permalink
Post by A. Pagaltzis
I have a working version of this,
largely derived from ::Hidden for consistency in slot names.
Now my question is: should I put this on CPAN, or should I leave
the space to an “official” version?
If you put it on CPAN and it is based on hidden, then perhaps it
should be CGI::Prototype::Hidden::PathInfo?

I never could figure out Hidden, I use the vanilla CGI::Prototype for
everything.

If the decision is to post at sf.net, just tell me what I need to do
on the sourceforge site to set you up since I admin this list and
sf.net site.
A. Pagaltzis
2005-08-03 18:51:54 UTC
Permalink
Post by Terrence Brannon
If you put it on CPAN and it is based on hidden, then perhaps
it should be CGI::Prototype::Hidden::PathInfo?
I never could figure out Hidden, I use the vanilla
CGI::Prototype for everything.
Hmm, I found it extremely straightforward. Just read the code, in
the worst case, and you’ll understand how it works. It’s just a
minor collection of shortcuts that saves you from setting up the
same scaffolding over and over.

In any case, ::Hidden::PathInfo is not the right name. I don’t
inherit from ::Hidden and the code has nothing to do with any
state parameter.

I just don’t want to step on Randalls’s toes in case he’s already
done this – but I also have very specific ideas about how to do
this and a CPAN directory longing for something to put in it. :-)

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
Randal L. Schwartz
2005-08-07 16:07:38 UTC
Permalink
A> I just don’t want to step on Randalls’s toes in case he’s already
A> done this – but I also have very specific ideas about how to do
A> this and a CPAN directory longing for something to put in it. :-)

And no, I have the idea to do it, but not the immediate motivation or
time. :( Glad to see someone else is finding the framework useful.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Terrence Brannon
2005-08-03 19:47:36 UTC
Permalink
Post by A. Pagaltzis
Post by Terrence Brannon
If you put it on CPAN and it is based on hidden, then perhaps
it should be CGI::Prototype::Hidden::PathInfo?
I never could figure out Hidden, I use the vanilla
CGI::Prototype for everything.
In any case, ::Hidden::PathInfo is not the right name. I don’t
inherit from ::Hidden and the code has nothing to do with any
state parameter.
good point.
Randal L. Schwartz
2005-08-07 16:06:56 UTC
Permalink
A> and hi Randall in particular. I have a working version of this,
A> largely derived from ::Hidden for consistency in slot names. (It
A> also let me copy 95% of the POD verbatim. Writing documentation
A> is easy when it’s already done for you. *g*)

Cool.

A> It has a somewhat distinct personality in that it wants an
A> explicit list of page names to validate (I’d rather prefer if
A> ::Hidden worked the same way – I like my code hardwired for “no
A> surprises ever possible”) and works slightly differently in a few
A> minor aspects. But by and large a well-written ::Hidden app would
A> translate to a ::PathInfo one with almost no changes.

Right now, my thoughts are that Hidden is actually doing two different
things:

1) Figuring out the state (from hidden fields, as named)
2) Mapping the state to classes (autoloading based on a prefix for the class)

I'd like to refactor Hidden so that the pieces are separate mixins, so
that the state tracking and the state-to-class mapping policy are
independently reusable. Your code would then provide an alternative
for each of those (state via URL, mapping via explicit table).

As usual, my time is limited, but if someone wants to go into more
thoughts on that, I'm willing to discuss it. I'm also looking at
moving my sources to SF so that I can have more committers.

A> I’ve also added a little twist so that “foo.cgi/bar/42” will
A> dispatch to “My::App::bar” and set the “page_id” slot to 42 in
A> the process. (The slot defaults to undef.) This is very handy for
A> cruft-free, clean URLs.

Nice.

A> Now my question is: should I put this on CPAN, or should I leave
A> the space to an “official” version? Or should I just post it
A> here, maybe? If I put this on CPAN myself, what should I put in
A> the AUTHOR and COPYRIGHT & LICENSE sections of the POD? There is
A> so little code in there that the notion of authorship is a bit
A> ridiculous either way, but I also copied several pages of POD
A> that I can hardly claim authorship of.

Well, if we create the SF archive, this can stay one or two distros.
I'd actually like to see separate distros like:

CGI::Prototype
CGI::Prototype::Hidden (mixin for param->state)
CGI::Prototype::Autoload (mixin for state->class via autoload)
CGI::Prototype::Pathinfo (mixin for info->state)
CGI::Prototype::$mumble (mixin for state->class via $mumble)

etc. Or maybe even go down one layer... where
CGI::Prototype::GetState::$mumble is for all state determiners, and
CGI::Prototype::DoState::$mumble is for all state mappers. I hate those
names, but I hope the idea is clear.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Terrence Brannon
2005-08-07 21:19:51 UTC
Permalink
Post by Randal L. Schwartz
A> Now my question is: should I put this on CPAN, or should I leave
A> the space to an “official” version? Or should I just post it
A> here, maybe? If I put this on CPAN myself, what should I put in
A> the AUTHOR and COPYRIGHT & LICENSE sections of the POD? There is
A> so little code in there that the notion of authorship is a bit
A> ridiculous either way, but I also copied several pages of POD
A> that I can hardly claim authorship of.
Well, if we create the SF archive, this can stay one or two distros.
I have added Aristotle (sf.net id: apag) as a developer with plenty of
liberal admin rights to the whole project - let me know if you need
more. I couldn't find Randal Schwartz in the sf.net user list and
someone has the name merlyn already.

Right now, it looks like Aristotle needs the privs more than Randal,
but as soon as I get his name, I will heap on lots of privs for him as
well.

Yes, as soon as this PathInfo baby gets uploaded, I can de-Mason-ize a
site of mine with the greatest of ease :)
--
Carter's Compass: I know I'm on the right track when,
by deleting something, I'm adding functionality.
Randal L. Schwartz
2005-08-07 21:40:17 UTC
Permalink
Terrence> I have added Aristotle (sf.net id: apag) as a developer with
Terrence> plenty of liberal admin rights to the whole project - let me
Terrence> know if you need more. I couldn't find Randal Schwartz in
Terrence> the sf.net user list and someone has the name merlyn
Terrence> already.

I'm "sourcemerlyn" there.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Terrence Brannon
2005-08-08 02:39:27 UTC
Permalink
Post by Randal L. Schwartz
Terrence> I have added Aristotle (sf.net id: apag) as a developer with
Terrence> plenty of liberal admin rights to the whole project - let me
Terrence> know if you need more. I couldn't find Randal Schwartz in
Terrence> the sf.net user list and someone has the name merlyn
Terrence> already.
I'm "sourcemerlyn" there.
added:

https://sourceforge.net/projects/cgi-prototype/
A. Pagaltzis
2005-08-10 23:13:31 UTC
Permalink
Post by Terrence Brannon
I have added Aristotle (sf.net id: apag) as a developer with
plenty of liberal admin rights to the whole project – let me
know if you need more.
Okay, I’ve gone in and put up a plain homepage cribbed together
from the Randall’s and your POD, and corrected the project
description (CGIP is not a template system and it does not use a
database).

Now back to the code…

Regards,
--
Aristotle
“Like punning, programming is a play on words.”
– Alan J. Perlis, “Epigrams in Programming”
Terrence Brannon
2005-08-11 02:40:29 UTC
Permalink
Post by A. Pagaltzis
Post by Terrence Brannon
I have added Aristotle (sf.net id: apag) as a developer with
plenty of liberal admin rights to the whole project – let me
know if you need more.
Okay, I’ve gone in and put up a plain homepage
Plain nothing! That's a very nice page. I use CGIP without Template
Toolkit, so I dont like that part of the description.
Post by A. Pagaltzis
cribbed together from the Randall’s and your POD, and corrected
the project description (CGIP is not a template system and it does
not use a database).
OMG. I hope I didnt write something that off-base.
--
Carter's Compass: I know I'm on the right track when,
by deleting something, I'm adding functionality.
A. Pagaltzis
2005-08-11 04:17:26 UTC
Permalink
Post by Terrence Brannon
Plain nothing! That's a very nice page. I use CGIP without
Template Toolkit, so I dont like that part of the description.
Heh, thanks. And well, CGIP *does* integrate TT by default, after
all. But I added a clause saying that TT is optional – that
better?
Post by Terrence Brannon
cribbed together from the Randall’s and your POD, and
corrected the project description (CGIP is not a template
system and it does not use a database).
OMG. I hope I didnt write something that off-base.
Write, not exactly, but it was categorized as templating system
and said that it used Perl/DBI as database environment. (It’s
true that one would likely use DBI for database apps written with
CGIP, but CGIP itself has nothing to do with that.)

I was kind of surprised to find those bits in the profile.

Anyway, it’s fixed.

Regards,
--
Aristotle
“If you can’t laugh at yourself, you don’t take life seriously enough.”
Randal L. Schwartz
2005-08-11 06:26:33 UTC
Permalink
A> Heh, thanks. And well, CGIP *does* integrate TT by default, after
A> all. But I added a clause saying that TT is optional – that
A> better?

My phrasing is "biased toward TT (Randal's favorite), but any templator
can be chosen insteasd".
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-08-11 06:51:12 UTC
Permalink
Post by Randal L. Schwartz
My phrasing is "biased toward TT (Randal's favorite), but any
templator can be chosen insteasd".
Okay then; I twiddled it to closely match that phrasing.

Note that I’ve made the file group-writable, so whoever of you
guys wants to change something there can go right ahead.

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
A. Pagaltzis
2005-08-10 23:34:31 UTC
Permalink
Post by Randal L. Schwartz
Cool.
Ok, great, then I’ll keep working on it.
Post by Randal L. Schwartz
Right now, my thoughts are that Hidden is actually doing two
1) Figuring out the state (from hidden fields, as named)
2) Mapping the state to classes (autoloading based on a prefix for the class)
Don’t forget the template location bits in #2.

Looking at the source, only `render_enter`, dispatch` and
`config_state_param` pertain to #1 at all. The rest is all
neutral.

I am thinking that the way to do this would be to pull all the
other bits into CGI::Prototype::Simple, then derive from that in
::Simple::Hidden or ::Simple::PathInfo.
Post by Randal L. Schwartz
I'd like to refactor Hidden so that the pieces are separate
mixins, so that the state tracking and the state-to-class
mapping policy are independently reusable. Your code would
then provide an alternative for each of those (state via URL,
mapping via explicit table).
The mapping is not entirely extricable from the state vehicle – I
need an explicit table for ::PathInfo because URLs look like
“/edit/post/261” or “/edit/user/ap” or “/user/ap”, and so the
pathinfo parser needs a means to know which part is the mode and
which is the positional parameters.

But that’s just a matter of refactoring `name2page` to call a
bunch of callbacks at the right points, and then it could provide
for basically any mapping scheme whatsoever. I’d already been
working on that, in fact.

So I think that rather than attempting to separate state
deduction and mapping entirely, it would be enough to factor out
the mapping into a common base and reuse that. As always, loads
of slots make the job pretty smooth.

Regards,
--
Aristotle
“Like punning, programming is a play on words.”
– Alan J. Perlis, “Epigrams in Programming”
A. Pagaltzis
2005-08-11 13:08:47 UTC
Permalink
Post by A. Pagaltzis
So I think that rather than attempting to separate state
deduction and mapping entirely, it would be enough to factor
out the mapping into a common base and reuse that. As always,
loads of slots make the job pretty smooth.
Ok, so I’d like to dive in there and get the bits moving right
now, but I don’t want to step on any toes, particularly with
architectural (more or less) decisions like this one. How are we
going to be handling issues like this one?

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
Randal L. Schwartz
2005-08-11 15:03:40 UTC
Permalink
A> Ok, so I’d like to dive in there and get the bits moving right
A> now, but I don’t want to step on any toes, particularly with
A> architectural (more or less) decisions like this one. How are we
A> going to be handling issues like this one?

I've checked in the current releases to "dist/*" in the CVS. If you
are proposing a separate release, feel free to start another leg. If
you are thinking that the release currently called CGI-Prototype
should be altered, we can talk about making the changes directly
there.

Let's settle on the naming first... :)
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-08-11 15:37:06 UTC
Permalink
If you are thinking that the release currently called
CGI-Prototype should be altered, we can talk about making the
changes directly there.
Well, kinda; I was hoping to start refactoring ::Hidden into bits
that can be reused in ::PathInfo and others and those which
can’t. ::PathInfo could then be separate or be part of the
distro, but that’s a different issue.

I’d like to know your thoughts on this; see my previous, more
detailed mail.
Let's settle on the naming first... :)
We need to sort out the structure first; do you agree with my
assessment that the state-to-class mapper can be reused by state
deductors, but vice versa does not work so well?

I used ::Simple for the mapper in ::Hidden which ::PathInfo would
reuse, but I’m not wedded to that name at all.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
A. Pagaltzis
2005-08-15 12:48:42 UTC
Permalink
Randal,
I was hoping to start refactoring ::Hidden into bits that can
be reused in ::PathInfo and others and those which can’t.
::PathInfo could then be separate or be part of the distro, but
that’s a different issue.
Do you agree with my assessment that the state-to-class mapper
can be reused by state deductors, but vice versa does not work
so well?
could you please give an answer to these questions?

Or if you are too busy to coordinate this right now, could you
please say that instead?

I need to get some work done in the Here And Now; I can’t spend
much more time waiting. If you don’t have time either, I’ll start
a separate ::PathInfo distro for now and we can always merge bits
later.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
Randal L. Schwartz
2005-08-15 16:30:23 UTC
Permalink
A> could you please give an answer to these questions?

See, that's the problem when I try to take a weekend off, like normal
people. :)

First, I hate ::Simple. On any module. If the interface was so
complicated that it needed a "simple" thing that doesn't describe how
it's simpler, then the designer failed.

So let's look at the problem:

Every hit requires four steps, not three. There's a bit of a misdesign,
which is affecting the proper refactoring:

1) map incoming to state
2) map state to a respond class
3) invoke responder, getting render class
4) invoke renderer

Right now CGIP->dispatch does the first two. The difference between
Hidden Fields and Pathinfo is only in step 1 though.

So, I propose a refactoring of CGIP so that CGIP->dispatch calls
CGIP->get_state, taking the results of that to call CGIP->get_class,
which then is returned as the result of CGIP->dispatch. This keeps
the top-level unchanged, and permits backward compatibility.

Then, I wanna refactor the current Hidden into its pieces:

a mixin for ->get_state (call it CGI::Prototype::State::Hidden)
- uses the hidden param to get a state name, or a default state
a mixin for ->get_class (call it CGI::Prototype::Mapper::Prefix)
- uses the state name with a prefix and does an autoload
a mixin for ->render_enter and ->engine_params (call it CGI::Prototype::Render::TT::Wrapper)
- uses a TT search path = @INC and defines a wrapper

And release those parts all as separate distros, although maybe just
bundled initially. The current "CGI::Prototype::Hidden" would then
be backward compatible, again.

The mixins would be added individually as:

package My::App;
use base CGI::Prototype;
__PACKAGE__->reflect->addSlots(
'*' => 'CGI::Prototype::State::Hidden',
'*' => 'CGI::Prototype::Mapper::Prefix',
'*' => 'CGI::Prototype::Render::TTWrapper',
);

## other subs for My::App;

1;

And in fact, the current CGI::Prototype::Hidden would be a pm with
just this in it, to be backward compatible.

Other mixins:

CGI::Prototype::State::Pathinfo (yours)
CGI::Prototype::Mapper::StrictLookup (yours)
CGI::Prototype::Render::HTMLTemplate::* (for people that prefer H::T)

I'm not attached to the ::Mapper::* name. Just making these up as I go.

How does this grab ya?
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-08-15 17:25:19 UTC
Permalink
Post by Randal L. Schwartz
a mixin for ->get_state (call it CGI::Prototype::State::Hidden)
- uses the hidden param to get a state name, or a default state
a mixin for ->get_class (call it CGI::Prototype::Mapper::Prefix)
- uses the state name with a prefix and does an autoload
a mixin for ->render_enter and ->engine_params (call it CGI::Prototype::Render::TT::Wrapper)
CGI::Prototype::State::Pathinfo (yours)
CGI::Prototype::Mapper::StrictLookup (yours)
CGI::Prototype::Render::HTMLTemplate::* (for people that prefer H::T)
How does this grab ya?
Looks sensible enough, but the mapper must be more abstract than
you propose. Abstraction on the level you have in mind is not
tenable because ::State::Pathinfo needs knowledge from
::Mapper::StrictLookup to be able to tell that

/edit/user/ap

is supposed to mean

state => 'My::App::edit::user',
positional_param => ['ap'],

rather than

state => 'My::App::edit',
positional_param => ['user,'ap'],

or

state => 'My::App::edit::user::ap',
positional_param => [],

How would a generic protocol for ::State::* to ask ::Mapper::*
for possible states look? Is it sensible to define one?
::Mapper::Prefix would have to crawl @INC or something like that,
f.ex.

After all is said and done, ::State::Pathinfo will have to be
specific to ::Mapper::StrictLookup anyway, so that separation
makes no sense. The only thing that does make sense to abstract
is how a state is mapped to a class *after* it is fully looked up
and validated.

But that is so trivial a task that I don’t really see the point
in a separate ::Mapper::* hierarchy. Putting a ->get_class with a
default `eval "require ${prefix}::${state}"` implementation into
CGIP would suffice.

Regards,
--
Aristotle
“Like punning, programming is a play on words.”
– Alan J. Perlis, “Epigrams in Programming”
Randal L. Schwartz
2005-08-15 17:43:43 UTC
Permalink
A> Looks sensible enough, but the mapper must be more abstract than
A> you propose. Abstraction on the level you have in mind is not
A> tenable because ::State::Pathinfo needs knowledge from
A> ::Mapper::StrictLookup to be able to tell that

A> /edit/user/ap

A> is supposed to mean

A> state => 'My::App::edit::user',
A> positional_param => ['ap'],

A> rather than

A> state => 'My::App::edit',
A> positional_param => ['user,'ap'],

A> or

A> state => 'My::App::edit::user::ap',
A> positional_param => [],

Ewww. I'd never use code like that. But if you want to do it,
I suppose you can replace all of ->dispatch isntead.

A> How would a generic protocol for ::State::* to ask ::Mapper::*
A> for possible states look? Is it sensible to define one?
A> ::Mapper::Prefix would have to crawl @INC or something like that,
A> f.ex.

Yeah, hadn't envisioned that. In my mind, state should come entirely
from the incoming environment. Mapping that to a class should be a
separate responsibility for maximum pluggability. Looks like the
best way is to leave ->dispatch and call yours something like

CGIP::Dispatch::VariablePathinfo

or something like that, using ::Dispatch:: rather than ::State:: or
::Mapping:: to show that it's replacing both.

A> After all is said and done, ::State::Pathinfo will have to be
A> specific to ::Mapper::StrictLookup anyway, so that separation
A> makes no sense. The only thing that does make sense to abstract
A> is how a state is mapped to a class *after* it is fully looked up
A> and validated.

A> But that is so trivial a task that I don’t really see the point
A> in a separate ::Mapper::* hierarchy. Putting a ->get_class with a
A> default `eval "require ${prefix}::${state}"` implementation into
A> CGIP would suffice.

I'm presuming the default ->get_class simply returns the prefixed
string classname, which is presumedly defined using some other means
(like all in one file). The autoload override allows it to be
dynloaded if it doesn't exist, but there are CGIP instances where that
won't be necessary, and I'm trying to keep the core CGIP as lean as
possible.

Consider also something like Slashdot, where the templates are loaded
from a database... I can also see that here. Maybe state-to-class is
dynamic based on current user ID or other security parameter? Really,
there's policy there, and it's best to let that be plugged in.

But if you need to poke around in order to even know the state, you've
got a tight coupling there, so you're going to be overriding all of
->dispatch, it seems.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Randal L. Schwartz
2005-08-15 17:51:22 UTC
Permalink
Randal> Consider also something like Slashdot, where the templates are loaded
Randal> from a database... I can also see that here. Maybe state-to-class is
Randal> dynamic based on current user ID or other security parameter? Really,
Randal> there's policy there, and it's best to let that be plugged in.

To further this, let's say I had a $big_client that needs to show a
login page if the user isn't logged in, regardless of whatever "state"
the ->get_state returns. They can override ->get_class to simply
return the login page if not logged in, regardless of whatever state
it's asked to show, and yet the old state is preserved for a "return
to FOO link". And then the ->get_state can be changed from hidden
fields to pathinfo without messing up the authorization section.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-08-15 18:35:40 UTC
Permalink
Post by Randal L. Schwartz
To further this, let's say I had a $big_client that needs to
show a login page if the user isn't logged in, regardless of
whatever "state" the ->get_state returns. They can override
->get_class to simply return the login page if not logged in,
regardless of whatever state it's asked to show, and yet the
old state is preserved for a "return to FOO link". And then
the ->get_state can be changed from hidden fields to pathinfo
without messing up the authorization section.
I currently do that by authenticating the user in ->app_enter.
The ->respond in pages which require authentication can then
switch to the login state for rendering a reponse. The login
state consists of nothing but a login form that includes all the
incoming state. So the user repeats the same request when he
submits the form, only this time with his credentials included.
->app_enter then picks them up, so the ->respond which previously
switched to the login state now finds the user authenticated, and
the request proceeds as it would have the first time around.

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
A. Pagaltzis
2005-08-15 18:19:05 UTC
Permalink
Post by Randal L. Schwartz
Ewww. I'd never use code like that.
At the HTTP level, it is cleaner design. Nobody on the other side
of the app interface will care whether it requires uglier
scaffolding under the hood, nor should they. Thus, neither do I.
Post by Randal L. Schwartz
Yeah, hadn't envisioned that. In my mind, state should come
entirely from the incoming environment. Mapping that to a
class should be a separate responsibility for maximum
pluggability. Looks like the best way is to leave ->dispatch
and call yours something like
CGIP::Dispatch::VariablePathinfo
or something like that, using ::Dispatch:: rather than
::State:: or ::Mapping:: to show that it's replacing both.
I suppose that I’ll stick with the current monolithic design and
mind my own business for the time being, then. Since ::PathInfo
builds onto CGIP itself it should be unaffected by stuff that
gets added on top of that. I will see how it can be merged with
the future CGIP design that materializes.

Regards,
--
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;
Terrence Brannon
2005-09-02 14:12:34 UTC
Permalink
Post by A. Pagaltzis
I suppose that I’ll stick with the current monolithic design and
mind my own business for the time being, then.
I'm also in need of using PathInfo to render pages on a dynamic
site. Can you make the PathInfo stuff you are doing available on
sourceforge or elsewhere?
--
Carter's Compass: I know I'm on the right track when,
by deleting something, I'm adding functionality.
Randal L. Schwartz
2005-09-02 14:41:19 UTC
Permalink
I suppose that I�����ll stick with the current monolithic design and
mind my own business for the time being, then.
Terrence> I'm also in need of using PathInfo to render pages on a dynamic
Terrence> site. Can you make the PathInfo stuff you are doing available on
Terrence> sourceforge or elsewhere?

And especially if you could organize it something along the line of my
proposal, or explain to me what isn't good about that. No discussion
on that after my pitch. :(
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-09-02 16:07:56 UTC
Permalink
Post by Randal L. Schwartz
And especially if you could organize it something along the
line of my proposal, or explain to me what isn't good about
that. No discussion on that after my pitch. :(
I just don’t currently see a way to cleanly implement the design
I want using that approach, so I’ve fallen back to my usual
stance that solving the problem a couple of times over and then
extracting abstractions from code is better than designing in the
abstract.

Of course I haven’t helped that along either, since I haven’t put
my code anywhere yet…


PS.: merlyn, your mailer is misconfigured. It’s sending UTF-8,
but the headers claim it’s UTF-16BE. The end result is that your
mail literally looked like a bunch of chinese. I was surprised
for a moment…

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
Ryan Tate
2005-09-02 21:41:10 UTC
Permalink
Post by A. Pagaltzis
The end result is that your
mail literally looked like a bunch of chinese.
I could not read it either, on gmail.

RT
Terrence Brannon
2005-09-02 23:38:19 UTC
Permalink
Post by A. Pagaltzis
PS.: merlyn, your mailer is misconfigured. It’s sending UTF-8,
Aristotle, what sort of control characters are in your mail? I see
little boxes and hex characters every so often, making the messages
harder to read... I read mail with plain text Xemacs/Gnus under Debian.
A. Pagaltzis
2005-09-03 00:32:18 UTC
Permalink
Post by Terrence Brannon
PS.: merlyn, your mailer is misconfigured. It’s
sending UTF-8,
Aristotle, what sort of control characters are in your mail?
There aren’t any control characters. It’s perfectly good
plaintext in UTF-8 encoding.
Post by Terrence Brannon
I see little boxes and hex characters every so often, making
the messages harder to read... I read mail with plain text
Xemacs/Gnus under Debian.
I read and write mine on the console using mutt and vim.

I also know for a fact that Gnus can handle UTF-8.

That means your mailer is also misconfigured…

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
Randal L. Schwartz
2005-09-03 13:08:55 UTC
Permalink
A> PS.: merlyn, your mailer is misconfigured. It’s sending UTF-8,
A> but the headers claim it’s UTF-16BE. The end result is that your
A> mail literally looked like a bunch of chinese. I was surprised
A> for a moment…

I've been having trouble for the past 24 hours with my existing emacs
session with regard to email. I have rebooted emacs... let's see if
this helps.

I run "screen emacs", connecting to the same emacs session for up to
four or five months at a time.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
A. Pagaltzis
2005-09-02 15:36:43 UTC
Permalink
Post by Terrence Brannon
Can you make the PathInfo stuff you are doing available on
sourceforge or elsewhere?
Yes, I shall, though it might take me a few days.

Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
Terrence Brannon
2005-09-04 18:17:02 UTC
Permalink
Post by A. Pagaltzis
Post by Terrence Brannon
Can you make the PathInfo stuff you are doing available on
sourceforge or elsewhere?
Yes, I shall, though it might take me a few days.
I really need this now, even if it's just a tarfile emailed to
***@metaperl.com.

Will your module work with plain CGI? I have avoided using REST
vocabulary in my URLs for something I'm working on because I don't
have your module:

<li> <a href="/gb/x.cgi?task=sign_book"> Sign Guestbook </a> </li>
<li> <a href="/gb/x.cgi?task=view_book"> View Guestbook </a> </li>
<li> <a href="/gb/x.cgi?task=book_stats"> Guestbook Stats </a> </li>

I want to be jet-set like you and use paths:

<li> <a href="/gb/x/sign"> Sign Guestbook </a> </li>
<li> <a href="/gb/x/view"> View Guestbook </a> </li>
<li> <a href="/gb/x/stats"> Guestbook Stats </a> </li>

So much cleaner
Post by A. Pagaltzis
Regards,
--
Aristotle Pagaltzis // <http://plasmasturm.org/>
What a cute use of icons!
--
Carter's Compass: I know I'm on the right track when,
by deleting something, I'm adding functionality.
A. Pagaltzis
2005-09-04 19:41:51 UTC
Permalink
Post by Terrence Brannon
Post by A. Pagaltzis
Yes, I shall, though it might take me a few days.
I really need this now, even if it's just a tarfile emailed to
Okay, the .pm is attached. I wanted to write a couple of tests,
but haven’t gotten to those (it’ll be a while before I get in the
habit of working by writing those first
), so this is offered at
your own risk. I’m also unsure about some of the design.

So I’d welcome any comments.
Post by Terrence Brannon
Will your module work with plain CGI?
Of course – what else?

Regards,
--
Aristotle
“If you can’t laugh at yourself, you don’t take life seriously enough.”
Terrence Brannon
2005-09-05 12:49:41 UTC
Permalink
Here is my unified diff of the attachment you emailed earlier. I like
this module a lot and will be retooling my simple guestbook app to use
it. This is our first step towards a CGI::Prototype on Rails type
thing. Maybe we could publish a Perl Review article if everything is
clean and easy to follow.

I am going to play with DBIx::SQLEngine for the database part of this
based on a recent discussion between Simon and Sebastien about their
interests in it.

***@Abulafia:~/perl/dl$ diff -u PathInfo.pm.orig PathInfo.pm
--- PathInfo.pm.orig 2005-09-05 11:34:56.000000000 +0000
+++ PathInfo.pm 2005-09-05 12:46:14.000000000 +0000
@@ -57,38 +57,73 @@

=head2 ENVIRONMENT INFORMATION SLOTS

+These slots provide access to information about the request loosely modelled
+on the REST architectural elements described in sectoin 5.2 of Fielding's
+seminal Ph.D disseration on the subject:
+
+http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_2
+
=over 4

-=item resource_type
+=item resource_name
+
+The resource name is, to quote Fielding, "the intended conceptual target of
+a hypertext reference." This would imply that such a target is a noun but in
+practical terms it may not be. In practical terms, the C<resource_name> is the
+first thing after the domain name and the cgi-script in the URL. Examples:
+
+http://metaperl.org/guestbook/sign has domain metaperl.org, cgi-script
+C<guestbook> and C<resource_name> sign
+Here we are providing a resource to sign the guestbook.

-FIXME
+=item resource_qualifiers

-=item resource_id
+path elements after the the resource name. Example:

-FIXME
+http://www.livingcosmos.org/meditation/ernest-wood/notes/
+
+would bind @resource_qualifiers to qw(ernest-wood notes)
+and of course resource_name would be 'meditation'
+
+This was initially a scalar named C<resource_id> but it is clear that many
+websites use more than one element after the resource_name, Drupal for
+instance:
+http://sequence.complete.org/node/add/blog

=back

+It is important to note that some resources just use paths to logically
+categorize all of its information. Taking the livingcosmos.org URL above,
+meditation is not a "service" or "resource" as much as it is just an area on a
+website. However, having access the path info is useful for dynamically
+rendering the look-and-feel of a website without resorting to things like
+HTML::Mason and its autohandler.
+
=cut

sub prototype_enter {
- my $self = shift;
+ my $self = shift;

- $self->SUPER::prototype_enter();
+ $self->SUPER::prototype_enter();

- my ( $resource, $id ) = $self->parse_path( $self->CGI->path_info() );
- $self->reflect->addSlot( resource_type => $resource, resource_id => $id );
+ my ( $resource, @qual ) = $self->parse_path( $self->CGI->path_info() );
+ $self->reflect->addSlot(
+ resource_name => $resource,
+ resource_qual => \@qual
+ );
}

=head2 MANAGEMENT SLOTS

-This is where the real changes over L<CGI::Prototype::Hidden> lie.
+This is where CGI::Prototype::PathInfo is quite different from
+L<CGI::Prototype::Hidden>

=over 4

-=item name_to_page
+=item resource_name_to_page

-Called with a page name, translates it to a package name, and returns a page
+Called with a resource name, translates it to a package name, and
+returns a page
object. Will also autoload the package.

This module expects page names to look like relative URLs and will translate to
@@ -98,22 +133,23 @@
=cut

sub name_to_page {
- my $self = shift;
- my ( $name ) = @_;
+ my $self = shift;
+ my ( $name ) = @_;

- my $pkg = join '::', (
- $self->config_class_prefix,
- split( m{/}, $self->validate_name( $name ) ),
- );
+ my $pkg = join '::', (
+ $self->config_class_prefix,
+ split( m{/}, $self->validate_name( $name ) ),
+ );
+
+ if ( do { no strict 'refs'; not defined ${ $pkg . '::' } } ) {
+ eval "require $pkg";
+ die $@ if $@;
+ }

- if( do { no strict 'refs'; not defined ${ $pkg . '::' } } ) {
- eval "require $pkg";
- die $@ if $@;
- }
-
- return $pkg->reflect->object;
+ return $pkg->reflect->object;
}

+
=item dispatch

Overridden from L<CGI::Prototype::Hidden>. Selects either the page named
@@ -127,7 +163,7 @@

my $prefixes = join '|', map quotemeta, $self->config_valid_pages;

- return $self->name_to_page( $self->resource_type || $self->config_default_page );
+ return $self->name_to_page( $self->resource_name || $self->config_default_page );
}

=item render_enter
@@ -186,17 +222,38 @@

L<CGI::Prototype::Hidden>, L<CGI::Prototype>, L<Template::Manual>

+=over 4
+
+=item Paul Prescod's REST resources
+
+L<http://www.prescod.net/rest/>
+
+=item the REST wiki
+
+L<http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage>
+
+=item The REST discussion email list
+
+L<http://groups.yahoo.com/group/rest-discuss/>
+
+
+=back
+
+
+
=head1 BUG REPORTS

-Please report any bugs or feature requests to
-L<mailto:bug-cgi-prototype-***@rt.cpan.org>, or through the web interface
-at L<http://rt.cpan.org/>. I will be notified, and then you'll automatically
-be notified of progress on your bug as I make changes.
+Please report any bugs or feature requests to the CGI::Prototype users mailing
+list on Sourceforge (L<http://cgi-prototype.sf.net)
+so that all 3 authors of the package (sourcemerlyn, apag, metaperl) can
+be notified.

=head1 AUTHOR

Aristote Pagaltzis, L<mailto:***@gmx.de>

+contributions from Terrence Brannon and Randal Schwartz.
+
=head1 COPYRIGHT AND LICENSE

Copyright (C) 2005 by Aristotle Pagaltzis
***@Abulafia:~/perl/dl$

Loading...