list of params inside a LOOP

Chouser
2000-03-15
2000-03-18
  • Chouser
    Chouser
    2000-03-15

    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?

     
    • Sam Tregar
      Sam Tregar
      2000-03-16

      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.

       
      • Chouser
        Chouser
        2000-03-17

        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.

         
        • Sam Tregar
          Sam Tregar
          2000-03-17

          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

           
          • Chouser
            Chouser
            2000-03-17

            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

             
            • Sam Tregar
              Sam Tregar
              2000-03-17

              > 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

               
            • Sam Tregar
              Sam Tregar
              2000-03-18

              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.

               
              • Sam Tregar
                Sam Tregar
                2000-03-18

                Ugh.  Sourceforge totally screwed my formatting.  I dislike this message board system more and more the more I use it.

                -sam

                 
      • Chouser
        Chouser
        2000-03-17

        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.