I would like to be able to get to the list of parameters that are referred to from inside a loop. When I call $tmpl->param() I get a list of the top-level template parameters, but I only get LOOP names, and I don't know how to get to the params inside. Is this even possible?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's not possible currently, but I have been thinking about the issue lately. If you have any
suggestions for an interface I'd like to hear them. Implementing such querying isn't so hard
but designing a simple interface that works through the existing param() interface is proving somewhat hard.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I *need* this for my current project. I'm quite willing to write a patch if need be, but of course it would be best to have a clean solution designed first.
Currently if I call param(), I get a list of the top-level parameters. What happens if I call param('listname')? Is there some reason this couldn't return a list of the parameters inside that namespace?
If there is a reason, perhaps a new method would be better, something like introspect(). This would prevent any existing conflict with the param('listname') by providing introspect('listname') instead. Then the current behavior of param() could just be deprecated, but included for a while for backward compatibility.
I will try to re-post this thread to the mailing list, if I can get that to work. Perhaps we can get this resolved more quickly that way.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes, this would definitely be something to discuss on the mailinglist. I'm sure we could get
some useful feedback from the other list members. Just send a blank message to
htmltmpl-subscribe@lists.vm.com to join.
As for why $template->param('name') couldn't do what you want - param('name') currently
returns the contents of the parameter 'name', be it VAR, LOOP or whatever. Also, any solution would have to support the recursive cases - loops within loops within... I do end up thinking that
a new method will be needed, although I am loathe to add one. Something about have just
three simple methods seems very good to me.
I've considered, for this and other purposes, creating a companion module. Something like
HTML::Template::Inspector, which would provide access to in depth information about
an HTML::Template object. I think it would also support an interactive CGI environment
for working with template files online. But it's a lot of work and I can't make any promises
about when I might get around to it. Quite likely not before the summer.
-sam
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I really need this functionality. The project I'm working on relies on this ability. Since I saw that the top-level template namespace, I designed my project around the capability, and now I'm stuck. I do need to find some kind of solution within the next couple of days.
I understand that you would want to keep the interface simple, for the sake of elegance. However, re-using the one param() method for multiple purposes may actually be kind of clumsy, and not really elegant at all. What do you think?
On the other hand, if param('listname') returns a LOOP object, could there be a way for me to query the LOOP object for the parameters it contains?
--Chouser
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
> I do need to find some kind of solution within the next couple of days.
That seems pretty unlikely - I've been looking for a solution to this problem for a couple months now and I haven't found anything I'm happy with. Honestly, you'd have to be paying me to get a solution in that kind of timeframe!
If what you want is a cheap hack... I could help you work something out. There are certain dark secrets about the internals of HTML::Template that you could use to get the information you want. I'd rather not put stuff like that in a public place though, since I don't want to make any promises about future compatibility. Email me at sam@tregar.com if you're interested.
> On the other hand, if param('listname') returns a LOOP object, could there be a way for me
> to query the LOOP object for the parameters it contains?
I don't think I've been clear. param('loop_name') already returns something, it's just not what you want it to return! It returns whatever you've set with param('loop_name' => [...]), or undef if nothing has been set. I'm sure that people are using this functionality - I know I have.
So, single-arg param() is not available for this purpose. It will have to be a separate method, or preferably, a feature of a separate module that also does other useful introspection.
-sam
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey chouser. I'm not sure if you're on the mailinglist yet, but I just sent this message out. Thought you might be interested:
Hello all. I recently recieved a rather impassioned plea for the ability
to test for the existence of TMPL_VARs within TMPL_LOOPs. I'd like to add
this functionality and a bit more. I think HTML::Template could benefit
from a general introspective interface. Here's my first draft docs for a
new method, query(), tell me what you think:
=head2 query()
This method allow you to get information about the template structure.
It can be called in a number of ways. The simplest usage of query is
simply to check whether a parameter name exists in the template, using
the C<name> option:
if ($template->query(name => 'FOO')) {
# do something if a varaible of any type named FOO is in the template
}
This same usage returns the type of the parameter. The type is the
same as the tag minus the leading 'TMPL_'. So, for example, a
TMPL_VAR parameter returns 'VAR' from query().
if ($template->query(name => 'FOO') eq 'VAR') {
# do something if FOO exists and is a TMPL_VAR
}
Note that the variables associated with TMPL_IFs and TMPL_UNLESSs will
be identified as 'VAR' unless they are also used in a TMPL_LOOP, in
which case they will return 'LOOP'.
C<query()> also allows you to get a list of parameters inside a loop
(and inside loops inside loops). Example loop:
# and this one returns 'LOOP'
$type = $template->query(name => ['EXAMPLE_LOOP',
'EXAMPLE_INNER_LOOP']);
# and finally, this returns ('INNER_BEE', 'INNER_BOP')
@inner_param_names = $template->query(loop => ['EXAMPLE_LOOP',
'EXAMPLE_INNER_LOOP']);
As you can see above the C<loop> option returns a list of parameter
names and both C<name> and C<loop> take array refs in order to refer
to parameters inside loops. It is an error to use C<loop> with a
parameter that is not a loop.
Just like C<param()>, C<query()> with no arguements returns all the
parameter names in the template at the top level.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I *need* this for my current project. I'm quite willing to write a patch if need be, but of course it would be best to have a clean solution designed first.
Currently if I call param(), I get a list of the top-level parameters. What happens if I call param('listname')? Is there some reason this couldn't return a list of the parameters inside that namespace?
If there is a reason, perhaps a new method would be better, something like introspect(). This would prevent any existing conflict with the param('listname') by providing introspect('listname') instead. Then the current behavior of param() could just be deprecated, but included for a while for backward compatibility.
I will try to re-post this thread to the mailing list, if I can get that to work. Perhaps we can get this resolved more quickly that way.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I would like to be able to get to the list of parameters that are referred to from inside a loop. When I call $tmpl->param() I get a list of the top-level template parameters, but I only get LOOP names, and I don't know how to get to the params inside. Is this even possible?
It's not possible currently, but I have been thinking about the issue lately. If you have any
suggestions for an interface I'd like to hear them. Implementing such querying isn't so hard
but designing a simple interface that works through the existing param() interface is proving somewhat hard.
I *need* this for my current project. I'm quite willing to write a patch if need be, but of course it would be best to have a clean solution designed first.
Currently if I call param(), I get a list of the top-level parameters. What happens if I call param('listname')? Is there some reason this couldn't return a list of the parameters inside that namespace?
If there is a reason, perhaps a new method would be better, something like introspect(). This would prevent any existing conflict with the param('listname') by providing introspect('listname') instead. Then the current behavior of param() could just be deprecated, but included for a while for backward compatibility.
I will try to re-post this thread to the mailing list, if I can get that to work. Perhaps we can get this resolved more quickly that way.
Yes, this would definitely be something to discuss on the mailinglist. I'm sure we could get
some useful feedback from the other list members. Just send a blank message to
htmltmpl-subscribe@lists.vm.com to join.
As for why $template->param('name') couldn't do what you want - param('name') currently
returns the contents of the parameter 'name', be it VAR, LOOP or whatever. Also, any solution would have to support the recursive cases - loops within loops within... I do end up thinking that
a new method will be needed, although I am loathe to add one. Something about have just
three simple methods seems very good to me.
I've considered, for this and other purposes, creating a companion module. Something like
HTML::Template::Inspector, which would provide access to in depth information about
an HTML::Template object. I think it would also support an interactive CGI environment
for working with template files online. But it's a lot of work and I can't make any promises
about when I might get around to it. Quite likely not before the summer.
-sam
I really need this functionality. The project I'm working on relies on this ability. Since I saw that the top-level template namespace, I designed my project around the capability, and now I'm stuck. I do need to find some kind of solution within the next couple of days.
I understand that you would want to keep the interface simple, for the sake of elegance. However, re-using the one param() method for multiple purposes may actually be kind of clumsy, and not really elegant at all. What do you think?
On the other hand, if param('listname') returns a LOOP object, could there be a way for me to query the LOOP object for the parameters it contains?
--Chouser
> I do need to find some kind of solution within the next couple of days.
That seems pretty unlikely - I've been looking for a solution to this problem for a couple months now and I haven't found anything I'm happy with. Honestly, you'd have to be paying me to get a solution in that kind of timeframe!
If what you want is a cheap hack... I could help you work something out. There are certain dark secrets about the internals of HTML::Template that you could use to get the information you want. I'd rather not put stuff like that in a public place though, since I don't want to make any promises about future compatibility. Email me at sam@tregar.com if you're interested.
> On the other hand, if param('listname') returns a LOOP object, could there be a way for me
> to query the LOOP object for the parameters it contains?
I don't think I've been clear. param('loop_name') already returns something, it's just not what you want it to return! It returns whatever you've set with param('loop_name' => [...]), or undef if nothing has been set. I'm sure that people are using this functionality - I know I have.
So, single-arg param() is not available for this purpose. It will have to be a separate method, or preferably, a feature of a separate module that also does other useful introspection.
-sam
Hey chouser. I'm not sure if you're on the mailinglist yet, but I just sent this message out. Thought you might be interested:
Hello all. I recently recieved a rather impassioned plea for the ability
to test for the existence of TMPL_VARs within TMPL_LOOPs. I'd like to add
this functionality and a bit more. I think HTML::Template could benefit
from a general introspective interface. Here's my first draft docs for a
new method, query(), tell me what you think:
=head2 query()
This method allow you to get information about the template structure.
It can be called in a number of ways. The simplest usage of query is
simply to check whether a parameter name exists in the template, using
the C<name> option:
if ($template->query(name => 'FOO')) {
# do something if a varaible of any type named FOO is in the template
}
This same usage returns the type of the parameter. The type is the
same as the tag minus the leading 'TMPL_'. So, for example, a
TMPL_VAR parameter returns 'VAR' from query().
if ($template->query(name => 'FOO') eq 'VAR') {
# do something if FOO exists and is a TMPL_VAR
}
Note that the variables associated with TMPL_IFs and TMPL_UNLESSs will
be identified as 'VAR' unless they are also used in a TMPL_LOOP, in
which case they will return 'LOOP'.
C<query()> also allows you to get a list of parameters inside a loop
(and inside loops inside loops). Example loop:
<TMPL_LOOP NAME="EXAMPLE_LOOP">
<TMPL_VAR NAME="BEE">
<TMPL_VAR NAME="BOP">
<TMPL_LOOP NAME="EXAMPLE_INNER_LOOP">
<TMPL_VAR NAME="INNER_BEE">
<TMPL_VAR NAME="INNER_BOP">
</TMPL_LOOP>
</TMPL_LOOP>
And some query calls:
# returns 'LOOP'
$type = $template->query(name => 'EXAMPLE_LOOP');
# returns ('BEE', 'BOP', 'EXAMPLE_INNER_LOOP')
@param_names = $template->query(loop => 'EXAMPLE_LOOP');
# both return 'VAR'
$type = $template->query(name => ['EXAMPLE_LOOP', 'BEE']);
$type = $template->query(name => ['EXAMPLE_LOOP', 'BOP']);
# and this one returns 'LOOP'
$type = $template->query(name => ['EXAMPLE_LOOP',
'EXAMPLE_INNER_LOOP']);
# and finally, this returns ('INNER_BEE', 'INNER_BOP')
@inner_param_names = $template->query(loop => ['EXAMPLE_LOOP',
'EXAMPLE_INNER_LOOP']);
As you can see above the C<loop> option returns a list of parameter
names and both C<name> and C<loop> take array refs in order to refer
to parameters inside loops. It is an error to use C<loop> with a
parameter that is not a loop.
Just like C<param()>, C<query()> with no arguements returns all the
parameter names in the template at the top level.
Ugh. Sourceforge totally screwed my formatting. I dislike this message board system more and more the more I use it.
-sam
I *need* this for my current project. I'm quite willing to write a patch if need be, but of course it would be best to have a clean solution designed first.
Currently if I call param(), I get a list of the top-level parameters. What happens if I call param('listname')? Is there some reason this couldn't return a list of the parameters inside that namespace?
If there is a reason, perhaps a new method would be better, something like introspect(). This would prevent any existing conflict with the param('listname') by providing introspect('listname') instead. Then the current behavior of param() could just be deprecated, but included for a while for backward compatibility.
I will try to re-post this thread to the mailing list, if I can get that to work. Perhaps we can get this resolved more quickly that way.