Loading ...
Sorry, an error occurred while loading the content.
 

Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions

Expand Messages
  • Paul Sorenson
    I have managed to write a small CGI wrapper that runs a template using my transaction: ... transaction = MyTransaction() template.respond(trans=transaction)
    Message 1 of 19 , Jul 1, 2003
      I have managed to write a small CGI wrapper that runs a template using my
      transaction:

      ...
      transaction = MyTransaction()
      template.respond(trans=transaction)
      print transaction.response().getvalue()
      ...

      That is fine except that respond does not seem to pass the transaction
      object to other methods #def'd in the template even though it somehow seems
      to take care of calling them all.

      Is this deliberate? How do I get the transaction object I pass into
      template.respond() to be passed into the other #def'd methods?

      The bottom line is, I would like to call a template's "main" method and have
      all of its output written to a single transaction.

      Any tips would be appreciated.

      Thanks

      ----- Original Message -----
      From: "Tavis Rudd" <tavis@...>
      To: "Paul Sorenson" <sosman@...>; "cheetah"
      <cheetahtemplate-discuss@...>
      Sent: Saturday, June 28, 2003 1:18 AM
      Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


      > On Friday 27 June 2003 01:18, Paul Sorenson wrote:
      > > Tavis,
      > >
      > > Thanks for the tip - I did notice that. I was hoping that somehow in
      the
      > > infrastructure that calls each of the generated #def code I could pass
      in a
      > > transaction either by specifying at compile time or a run time.
      > >
      > > Also in your example below, how do I pass the transaction to the code
      for
      > > "respond"?
      > >
      > > #def respond(trans = $MyTrans)
      > > ...
      > > #end def
      > >
      > > results in "duplicate argument trans"
      >
      > template = Template(src)
      > template.respond(trans=MyTrans)
      >
      > or even
      >
      > template.anyOtherMethod(trans=MyTrans)
      >
      > Cheers,
      > Tavis



      -------------------------------------------------------
      This SF.Net email sponsored by: Free pre-built ASP.NET sites including
      Data Reports, E-commerce, Portals, and Forums are available now.
      Download today and enter to win an XBOX or Visual Studio .NET.
      http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
      _______________________________________________
      Cheetahtemplate-discuss mailing list
      Cheetahtemplate-discuss@...
      https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
    • Tavis Rudd
      Paul, ... So long as you explicitly pass your transaction object to all methods that are called from the respond() method and do the same for all methods that
      Message 2 of 19 , Jul 3, 2003
        Paul,

        On Tuesday 01 July 2003 06:47, Paul Sorenson wrote:
        > I have managed to write a small CGI wrapper that runs a template using my
        > transaction:
        >
        > ...
        > transaction = MyTransaction()
        > template.respond(trans=transaction)
        > print transaction.response().getvalue()
        > ...
        >
        > That is fine except that respond does not seem to pass the transaction
        > object to other methods #def'd in the template even though it somehow seems
        > to take care of calling them all.
        >
        > Is this deliberate? How do I get the transaction object I pass into
        > template.respond() to be passed into the other #def'd methods?

        So long as you explicitly pass your transaction object to all methods that are
        called from the respond() method and do the same for all methods that they in
        turn call, etc. you should be fine.

        For example:

        #def respond
        $test
        #end def
        #def test
        This is a test $trans.request().field('a')
        #end def

        Will not work. You need to do it like this:

        #def respond
        $test($trans=$trans)
        #end def
        #def test
        This is a test $trans.request().field('a')
        #end def

        Cheers,
        Tavis



        -------------------------------------------------------
        This SF.Net email sponsored by: Free pre-built ASP.NET sites including
        Data Reports, E-commerce, Portals, and Forums are available now.
        Download today and enter to win an XBOX or Visual Studio .NET.
        http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
        _______________________________________________
        Cheetahtemplate-discuss mailing list
        Cheetahtemplate-discuss@...
        https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
      • Mike Orr
        ... [The following is advanced stuff that beginners can ignore if it doesn t amke sense.] Curiously, if you use #block, it implicitly creates a placeholder
        Message 3 of 19 , Jul 3, 2003
          On Thu, Jul 03, 2003 at 04:03:08PM -0700, Tavis Rudd wrote:
          > Paul,
          >
          > On Tuesday 01 July 2003 06:47, Paul Sorenson wrote:
          > > I have managed to write a small CGI wrapper that runs a template using my
          > > transaction:
          > >
          > > ...
          > > transaction = MyTransaction()
          > > template.respond(trans=transaction)
          > > print transaction.response().getvalue()
          > > ...
          > >
          > > That is fine except that respond does not seem to pass the transaction
          > > object to other methods #def'd in the template even though it somehow seems
          > > to take care of calling them all.
          > >
          > > Is this deliberate? How do I get the transaction object I pass into
          > > template.respond() to be passed into the other #def'd methods?
          >
          > So long as you explicitly pass your transaction object to all methods that are
          > called from the respond() method and do the same for all methods that they in
          > turn call, etc. you should be fine.

          [The following is advanced stuff that beginners can ignore if it doesn't
          amke sense.]

          Curiously, if you use #block, it implicitly creates a placeholder
          thus:
          self.abc(trans=trans)

          but if you use an ordinary placeholder ($abc), it compiles to:
          write(filter(VFS(SL + [globals(), __builtin__],"abc",True), rawExpr='$abc'))

          In the first case, the transaction is automatically passed. In the
          second, it's not.

          Is there some reason ordinary placeholders shouldn't pass the
          transction (and the dummyTrans variable) automatically too?
          Is it only because we have to pass the result through the #filter?

          I'm also wondering if the name 'dummyTrans' is unfortunate, or whether
          the 'dummyTrans' variable is even necessary. It's supposed to mean
          'trans' behaves like DummyTransaction. AFAICT this means
          trans.response() is StringIO-like and thus, trans.response().write()
          doesn't do anything useful but instead just stores the result. So
          if dummyTransaction is true, we end the method with:
          return trans.response().getvalue()
          rather than:
          return ""
          This brings up a couple points.

          1) Paul Sorenson has "print trans.response().getvalue()" in his code.
          The .respond() method would return the value automatically if Paul
          passes in dummyTrans=True . But is this something we want to
          guarantee for future versions of Cheetah?

          2) Shouldn't the transaction itself know if it's StringIO-like?
          We can test via isinstance(), or check whether
          .response().getvalue() exists, and thus eliminate the need for
          'dummyTrans'.

          --
          -Mike (Iron) Orr, mso@... (iron@...)
          http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


          -------------------------------------------------------
          This SF.Net email sponsored by: Free pre-built ASP.NET sites including
          Data Reports, E-commerce, Portals, and Forums are available now.
          Download today and enter to win an XBOX or Visual Studio .NET.
          http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
          _______________________________________________
          Cheetahtemplate-discuss mailing list
          Cheetahtemplate-discuss@...
          https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
        • Paul Sorenson
          Thanks Tavis and Mike for your responses. It helps explain what is happening for me. I can t really respond to your specific technical points but would like
          Message 4 of 19 , Jul 4, 2003
            Thanks Tavis and Mike for your responses. It helps explain what is
            happening for me. I can't really respond to your specific technical points
            but would like to keep the thread going with these comments (perhaps a bit
            philosophical) - because the outcome from me isn't what I had hoped. It is
            quite possible that I am wrong on some of these points:

            - I am assuming respond() is the main entry point to the templates when
            called programmatically.

            - respond() seems to take care of "calling" all #def ... #end def
            methods automatically - ie even though they are exposed in the template
            class there is not much point calling them directly.

            - I expected that having passed a parameter (trans=MyTrans) to
            respond(), that it would be passed on to all methods called by it. In fact
            it doesn't. Each "sub-method" creates its own instance of DummyTransaction
            then the string value of it is added to the transaction instance that
            respond() has. This seems broken to me.

            Presumably passing a single instance of a transaction all the way through
            would remove the need for these lines in every method:
            if not trans:
            trans = DummyTransaction()
            dummyTrans = True
            Also I can't see why you would need a dummyTrans flag at all (to be fair I
            don't know how cheetah works with webware).

            Am I barking up the wrong tree here?

            ----- Original Message -----
            From: "Mike Orr" <mso@...>
            To: "Cheetah Template List" <cheetahtemplate-discuss@...>
            Sent: Friday, July 04, 2003 2:15 PM
            Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


            > On Thu, Jul 03, 2003 at 04:03:08PM -0700, Tavis Rudd wrote:
            > > Paul,
            > >
            > > On Tuesday 01 July 2003 06:47, Paul Sorenson wrote:
            > > > I have managed to write a small CGI wrapper that runs a template using
            my
            > > > transaction:
            > > >
            > > > ...
            > > > transaction = MyTransaction()
            > > > template.respond(trans=transaction)
            > > > print transaction.response().getvalue()
            > > > ...
            > > >
            > > > That is fine except that respond does not seem to pass the transaction
            > > > object to other methods #def'd in the template even though it somehow
            seems
            > > > to take care of calling them all.
            > > >
            > > > Is this deliberate? How do I get the transaction object I pass into
            > > > template.respond() to be passed into the other #def'd methods?
            > >
            > > So long as you explicitly pass your transaction object to all methods
            that are
            > > called from the respond() method and do the same for all methods that
            they in
            > > turn call, etc. you should be fine.
            >
            > [The following is advanced stuff that beginners can ignore if it doesn't
            > amke sense.]
            >
            > Curiously, if you use #block, it implicitly creates a placeholder
            > thus:
            > self.abc(trans=trans)
            >
            > but if you use an ordinary placeholder ($abc), it compiles to:
            > write(filter(VFS(SL + [globals(), __builtin__],"abc",True),
            rawExpr='$abc'))
            >
            > In the first case, the transaction is automatically passed. In the
            > second, it's not.
            >
            > Is there some reason ordinary placeholders shouldn't pass the
            > transction (and the dummyTrans variable) automatically too?
            > Is it only because we have to pass the result through the #filter?
            >
            > I'm also wondering if the name 'dummyTrans' is unfortunate, or whether
            > the 'dummyTrans' variable is even necessary. It's supposed to mean
            > 'trans' behaves like DummyTransaction. AFAICT this means
            > trans.response() is StringIO-like and thus, trans.response().write()
            > doesn't do anything useful but instead just stores the result. So
            > if dummyTransaction is true, we end the method with:
            > return trans.response().getvalue()
            > rather than:
            > return ""
            > This brings up a couple points.
            >
            > 1) Paul Sorenson has "print trans.response().getvalue()" in his code.
            > The .respond() method would return the value automatically if Paul
            > passes in dummyTrans=True . But is this something we want to
            > guarantee for future versions of Cheetah?
            >
            > 2) Shouldn't the transaction itself know if it's StringIO-like?
            > We can test via isinstance(), or check whether
            > .response().getvalue() exists, and thus eliminate the need for
            > 'dummyTrans'.
            >
            > --
            > -Mike (Iron) Orr, mso@... (iron@...)
            > http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol
            >
            >
            > -------------------------------------------------------
            > This SF.Net email sponsored by: Free pre-built ASP.NET sites including
            > Data Reports, E-commerce, Portals, and Forums are available now.
            > Download today and enter to win an XBOX or Visual Studio .NET.
            > http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
            > _______________________________________________
            > Cheetahtemplate-discuss mailing list
            > Cheetahtemplate-discuss@...
            > https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss



            -------------------------------------------------------
            This SF.Net email sponsored by: Free pre-built ASP.NET sites including
            Data Reports, E-commerce, Portals, and Forums are available now.
            Download today and enter to win an XBOX or Visual Studio .NET.
            http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
            _______________________________________________
            Cheetahtemplate-discuss mailing list
            Cheetahtemplate-discuss@...
            https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
          • Tavis Rudd
            ... I think you are. If all you want to do is capture the output of the template, do this: templ = MyTemplate() output = str(templ) This is explained in the
            Message 5 of 19 , Jul 4, 2003
              On Friday 04 July 2003 03:22, Paul Sorenson wrote:
              > Thanks Tavis and Mike for your responses. It helps explain what is
              > happening for me. I can't really respond to your specific technical points
              > but would like to keep the thread going with these comments (perhaps a bit
              > philosophical) - because the outcome from me isn't what I had hoped. It is
              > quite possible that I am wrong on some of these points:
              >
              > - I am assuming respond() is the main entry point to the templates when
              > called programmatically.
              >
              > - respond() seems to take care of "calling" all #def ... #end def
              > methods automatically - ie even though they are exposed in the template
              > class there is not much point calling them directly.
              >
              > - I expected that having passed a parameter (trans=MyTrans) to
              > respond(), that it would be passed on to all methods called by it. In fact
              > it doesn't. Each "sub-method" creates its own instance of DummyTransaction
              > then the string value of it is added to the transaction instance that
              > respond() has. This seems broken to me.
              >
              > Presumably passing a single instance of a transaction all the way through
              > would remove the need for these lines in every method:
              > if not trans:
              > trans = DummyTransaction()
              > dummyTrans = True
              > Also I can't see why you would need a dummyTrans flag at all (to be fair I
              > don't know how cheetah works with webware).
              >
              > Am I barking up the wrong tree here?

              I think you are.

              If all you want to do is capture the output of the template, do this:
              templ = MyTemplate()
              output = str(templ)
              This is explained in the User's Guide.

              Transactions are specific to Webware and DummyTransaction is an internal
              implementation detail that you don't need to be concerned about.

              Cheers,
              Tavis






              -------------------------------------------------------
              This SF.Net email sponsored by: Free pre-built ASP.NET sites including
              Data Reports, E-commerce, Portals, and Forums are available now.
              Download today and enter to win an XBOX or Visual Studio .NET.
              http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
              _______________________________________________
              Cheetahtemplate-discuss mailing list
              Cheetahtemplate-discuss@...
              https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
            • Mike Orr
              ... Usually. See #implements in the Users Guide for why it sometimes isn t. But str(t) and print t call the main entry point without you having to worry
              Message 6 of 19 , Jul 4, 2003
                On Fri, Jul 04, 2003 at 08:17:30AM -0700, Tavis Rudd wrote:
                > On Friday 04 July 2003 03:22, Paul Sorenson wrote:
                > > - I am assuming respond() is the main entry point to the templates when
                > > called programmatically.

                Usually. See #implements in the Users' Guide for why it sometimes isn't.
                But "str(t)" and "print t" call the main entry point without you having to
                worry about the name.

                > > - respond() seems to take care of "calling" all #def ... #end def
                > > methods automatically - ie even though they are exposed in the template
                > > class there is not much point calling them directly.

                "#def abc" is called wherever "$abc" appears. If you have "#def" but
                no placeholder, it won't be called.

                Whether you call #def methods from Python depends on how you choose to
                structure your application. Sometimes a #def is useful standalone.
                Sometimes you want a place to put a bunch of little "templates":
                a template consisting solely of #def's makes a nice library.

                > > - I expected that having passed a parameter (trans=MyTrans) to
                > > respond(), that it would be passed on to all methods called by it. In fact
                > > it doesn't. Each "sub-method" creates its own instance of DummyTransaction
                > > then the string value of it is added to the transaction instance that
                > > respond() has. This seems broken to me.
                > >
                > > Presumably passing a single instance of a transaction all the way through
                > > would remove the need for these lines in every method:
                > > if not trans:
                > > trans = DummyTransaction()
                > > dummyTrans = True
                > > Also I can't see why you would need a dummyTrans flag at all (to be fair I
                > > don't know how cheetah works with webware).
                > >
                > > Am I barking up the wrong tree here?
                >
                > I think you are.
                >
                > If all you want to do is capture the output of the template, do this:
                > templ = MyTemplate()
                > output = str(templ)
                > This is explained in the User's Guide.
                >
                > Transactions are specific to Webware and DummyTransaction is an internal
                > implementation detail that you don't need to be concerned about.

                Why again do you need a custom transaction? It's much easier to
                get the result as a string and then write it somewhere. The only
                reason you'd have to use a custom transaction is if your framework
                does not allow you to do that; i.e., if it insists on calling transaction
                methods directly, like Webware does.

                --
                -Mike (Iron) Orr, mso@... (iron@...)
                http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


                -------------------------------------------------------
                This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                Data Reports, E-commerce, Portals, and Forums are available now.
                Download today and enter to win an XBOX or Visual Studio .NET.
                http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                _______________________________________________
                Cheetahtemplate-discuss mailing list
                Cheetahtemplate-discuss@...
                https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
              • Mike Orr
                ... What if you put headers directly into the template instance? #set $self.headers = [] #silent $self.headers.append( cookie: ABC n ) ## Whatever the
                Message 7 of 19 , Jul 4, 2003
                  On Sat, Jul 05, 2003 at 09:00:15AM +1000, spam wrote:
                  > ----- Original Message -----
                  > From: "Mike Orr" <mso@...>
                  > To: "Cheetah Template List" <cheetahtemplate-discuss@...>
                  > Sent: Saturday, July 05, 2003 3:54 AM
                  > Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions
                  >
                  >
                  > > Why again do you need a custom transaction? It's much easier to
                  > > get the result as a string and then write it somewhere. The only
                  > > reason you'd have to use a custom transaction is if your framework
                  > > does not allow you to do that; i.e., if it insists on calling transaction
                  > > methods directly, like Webware does.
                  >
                  > The reason why I would like a custom transaction is this:
                  >
                  > - My web server doesn't have webware.
                  > - I would like to use cheetah
                  > - I want to maintain sessions (using cookies).
                  > - To use cookies I need to write out the appropriate headers.
                  > - I don't know what headers (eg cookie value) to write out until I have
                  > processed my form action.
                  >
                  > The pattern I wanted to use goes something like this:
                  > - Create custom transaction (MyTrans) and pass it to respond()
                  > - In my #def formAction ... #end def I might get a request to register a
                  > user, so:
                  > o I create a session with assocated Set-Cookie header.
                  > o Add the cookie to MyTrans.headers
                  > o When all processing is done, ie respond() returns, I write out the
                  > string value of MyTrans which includes the correct headers.

                  What if you put 'headers' directly into the template instance?

                  #set $self.headers = []
                  #silent $self.headers.append('cookie: ABC\n') ## Whatever the header is.

                  Then to render:
                  body = str(t) # Same as "body = t.respond()"
                  sys.stdout.writelines(t.headers)
                  sys.stdout.write('\n')
                  sys.stdout.write(body)

                  Or make a '#def formatHeaders' that stringifies the headers, and:
                  body = str(t)
                  print t.formatHeaders() # Automatically adds the blank line.
                  print body

                  --
                  -Mike (Iron) Orr, mso@... (iron@...)
                  http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


                  -------------------------------------------------------
                  This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                  Data Reports, E-commerce, Portals, and Forums are available now.
                  Download today and enter to win an XBOX or Visual Studio .NET.
                  http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                  _______________________________________________
                  Cheetahtemplate-discuss mailing list
                  Cheetahtemplate-discuss@...
                  https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                • Paul Sorenson
                  ... From: Mike Orr To: Cheetah Template List Sent: Saturday, July 05, 2003 3:54 AM Subject:
                  Message 8 of 19 , Jul 4, 2003
                    ----- Original Message -----
                    From: "Mike Orr" <mso@...>
                    To: "Cheetah Template List" <cheetahtemplate-discuss@...>
                    Sent: Saturday, July 05, 2003 3:54 AM
                    Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


                    > Why again do you need a custom transaction? It's much easier to
                    > get the result as a string and then write it somewhere. The only
                    > reason you'd have to use a custom transaction is if your framework
                    > does not allow you to do that; i.e., if it insists on calling transaction
                    > methods directly, like Webware does.

                    The reason why I would like a custom transaction is this:

                    - My web server doesn't have webware.
                    - I would like to use cheetah
                    - I want to maintain sessions (using cookies).
                    - To use cookies I need to write out the appropriate headers.
                    - I don't know what headers (eg cookie value) to write out until I have
                    processed my form action.

                    The pattern I wanted to use goes something like this:
                    - Create custom transaction (MyTrans) and pass it to respond()
                    - In my #def formAction ... #end def I might get a request to register a
                    user, so:
                    o I create a session with assocated Set-Cookie header.
                    o Add the cookie to MyTrans.headers
                    o When all processing is done, ie respond() returns, I write out the
                    string value of MyTrans which includes the correct headers.

                    Hope that answers your question.




                    -------------------------------------------------------
                    This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                    Data Reports, E-commerce, Portals, and Forums are available now.
                    Download today and enter to win an XBOX or Visual Studio .NET.
                    http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                    _______________________________________________
                    Cheetahtemplate-discuss mailing list
                    Cheetahtemplate-discuss@...
                    https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                  • Paul Sorenson
                    ... From: Mike Orr To: Cheetah Template List Sent: Saturday, July 05, 2003 10:01 AM Subject:
                    Message 9 of 19 , Jul 4, 2003
                      ----- Original Message -----
                      From: "Mike Orr" <mso@...>
                      To: "Cheetah Template List" <cheetahtemplate-discuss@...>
                      Sent: Saturday, July 05, 2003 10:01 AM
                      Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


                      >
                      > What if you put 'headers' directly into the template instance?
                      >
                      > #set $self.headers = []
                      > #silent $self.headers.append('cookie: ABC\n') ## Whatever the header is.
                      >
                      > Then to render:
                      > body = str(t) # Same as "body = t.respond()"
                      > sys.stdout.writelines(t.headers)
                      > sys.stdout.write('\n')
                      > sys.stdout.write(body)
                      >
                      > Or make a '#def formatHeaders' that stringifies the headers, and:
                      > body = str(t)
                      > print t.formatHeaders() # Automatically adds the blank line.
                      > print body

                      Thanks - I will give that a try.



                      -------------------------------------------------------
                      This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                      Data Reports, E-commerce, Portals, and Forums are available now.
                      Download today and enter to win an XBOX or Visual Studio .NET.
                      http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                      _______________________________________________
                      Cheetahtemplate-discuss mailing list
                      Cheetahtemplate-discuss@...
                      https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                    • Paul Sorenson
                      ... From: Mike Orr To: Paul Sorenson Sent: Saturday, July 05, 2003 12:22 PM Subject: Re:
                      Message 10 of 19 , Jul 4, 2003
                        ----- Original Message -----
                        From: "Mike Orr" <mso@...>
                        To: "Paul Sorenson" <sosman@...>
                        Sent: Saturday, July 05, 2003 12:22 PM
                        Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


                        > On Sat, Jul 05, 2003 at 12:10:16PM +1000, Paul Sorenson wrote:
                        > > Thanks - I will give that a try.
                        >
                        > Let me know if it works so I can add it to the (nonexistent) FAQ.
                        > Also let me know if it doesn't work, of course.

                        Will do. And I appreciate the time folk have taken to answer my questions.

                        > I'd better add a chapter in the Users' Guide about transactions.
                        > This experience helps clarify what to say.

                        Aside from all the valuable suggestions and explanations I have received on
                        this topic - my question still remains (sure perhaps somewhat academic if
                        the workaround works):

                        Why can't I pass in a Transaction instance to respond() and have it used
                        (and accessible) throughout my template?




                        -------------------------------------------------------
                        This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                        Data Reports, E-commerce, Portals, and Forums are available now.
                        Download today and enter to win an XBOX or Visual Studio .NET.
                        http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                        _______________________________________________
                        Cheetahtemplate-discuss mailing list
                        Cheetahtemplate-discuss@...
                        https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                      • Mike Orr
                        ... Because Tavis wrote it that way. Because that s how Cheetah evolved. Chronologically: 1) Cheetah was created because Webware needed a template system. We
                        Message 11 of 19 , Jul 4, 2003
                          On Sat, Jul 05, 2003 at 12:43:03PM +1000, Paul Sorenson wrote:
                          > Why can't I pass in a Transaction instance to respond() and have it used
                          > (and accessible) throughout my template?

                          Because Tavis wrote it that way. Because that's how Cheetah evolved.
                          Chronologically:

                          1) Cheetah was created because Webware needed a template system.
                          We wanted the templates usable as servlets.
                          => The main method has to be called .respond().
                          => It must accept a Webware transaction as an argument.
                          => It must call trans.response().write() for the output since
                          that's what a servlet would do.

                          2) We realized Cheetah would also be useful standalone.
                          => DummyTransaction with .response().write() connected to a StringIO.
                          => Return the output like Python users want.

                          3) NameMapper lookup evolved similar to its current form.
                          => "$abc" compiles to a function call:
                          write(VFS(SL + [globals(), __builtin__],"abc",True))
                          => write() is an aias for trans.response().write()
                          => VFS() automatically calls abc() if it's a function/method.
                          => This depends on the called method using DummyTransaction because it
                          has to return the value. Tavis must have noticed this at the time,
                          but I'm sure nobody else did.
                          => Notwithstanding the previous, if you were to pass through 'trans',
                          where would you put it? Would you teach VFS (a generic function,
                          not Cheetah or Webware specific) to pass it? (I was wrong about
                          this yesterday when I said it would be easy to pass.)
                          => We must not put type-specific information into the compiled
                          template. So calling abc() ourselves is verboten:
                          VFS(SL + [globals(), __builtin__],"abc",False)(trans=trans)
                          We cannot assume $abc exists at compile time, much less check its
                          type. We tried that in an earlier Cheetah version, and it breaks
                          if 'abc' changes type during runtime.
                          => Theoretically we could have passed trans=trans and avoided the
                          write() call, maybe. But we didn't, and the previous two
                          problems would have remained anyway.


                          4) Users clamored for #filter.
                          => The function call changes to:
                          write(filter(VFS(SL + [globals(), __builtin__],"abc",True), rawExpr='$abc'))


                          5) 1 1/2 years later, Paul Sorenson notices his transaction isn't being
                          passed to #def's and complains.
                          => Even if we can get around (3), #filter is now a bitch because
                          we *can't* just trans=trans now even if we could before. We
                          have to filter() the method output before putting it on the
                          stream, and we can't do that if it's already in the stream.
                          => But we can't get rid of #filter because many users want it,
                          many more than want auto-passing of transactions.




                          By the way, the non-passing of transactions also affects Webware.
                          I guess nobody noticed this before, but the following template-servlet
                          demonstrates it:

                          #def aMethod
                          In aMethod: $trans.__class__.__name__
                          ## $trans.request._fields
                          #end def
                          $trans.__class__.__name__<BR>
                          $trans.request._fields<BR>
                          $aMethod

                          If you invoke it as "http://example.com/test?hello=world", it prints:

                          Transaction
                          {'hello': 'world'}
                          In aMethod: DummyTransaction

                          If you uncomment the line in aMethod, you get an exception because
                          $trans.request doesn't exist. Webware defines it but DummyTransaction
                          doesn't. So in other words, you can't access Webware services from
                          #def methods. One would expect them to be accessible throughout the
                          template. You can get around this with "#set global":


                          #def aMethod
                          In aMethod: $trans.__class__.__name__<BR>
                          ## $trans.request._fields<BR>
                          $req.fields<BR>
                          #end def
                          #set global $req = $trans.request
                          $trans.__class__.__name__<BR>
                          $trans.request._fields<BR>
                          $aMethod

                          Which prints:

                          Transaction
                          {'hello': 'world'}
                          In aMethod: DummyTransaction
                          {'hello': 'world'}

                          --
                          -Mike (Iron) Orr, mso@... (iron@...)
                          http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


                          -------------------------------------------------------
                          This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                          Data Reports, E-commerce, Portals, and Forums are available now.
                          Download today and enter to win an XBOX or Visual Studio .NET.
                          http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                          _______________________________________________
                          Cheetahtemplate-discuss mailing list
                          Cheetahtemplate-discuss@...
                          https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                        • Paul Sorenson
                          Ok so I wondered how webware got around this issue - it doesn t. As for your other comments they all make sense in so far as my knowledge of the internals are
                          Message 12 of 19 , Jul 4, 2003
                            Ok so I wondered how webware got around this issue - it doesn't. As for
                            your other comments they all make sense in so far as my knowledge of the
                            internals are limited (andI have never used #filter).

                            And don't worry, I still recommend cheetah to my friends :-)

                            So is it fair to say that the parameter lists of #def'd methods are never
                            "filled"?

                            Here is the generated method call of #def abc:
                            def abc(self,
                            trans=None,
                            dummyTrans=False,
                            VFS=valueFromSearchList,
                            VFN=valueForName,
                            getmtime=getmtime,
                            currentTime=time.time,
                            globals=globals,
                            locals=locals,
                            __builtin__=__builtin__):

                            And here is the "metacall" to $abc

                            write(filter(VFS(SL + [globals(), __builtin__],"abc",True), rawExpr='$abc'))

                            I imagine globals() and __builtin__ are passed to abc(). Would it be
                            practical to:

                            a) Add trans to the list in the metacall (that is a bit arbitrary), or

                            b) Change the signature of abc() to something like
                            def abc(self, *env):
                            At the top of respond() initialise env:
                            env = [trans, VFS, VFN, ... , globals(), __builtin__]
                            And change the write call to something like:

                            write(filter(VFS(SL, env,"abc",True), rawExpr='$abc'))
                            making sure that env gets passed to #def'd function.

                            ----- Original Message -----
                            From: "Mike Orr" <mso@...>
                            To: "Cheetah Template List" <cheetahtemplate-discuss@...>
                            Sent: Saturday, July 05, 2003 2:00 PM
                            Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


                            > On Sat, Jul 05, 2003 at 12:43:03PM +1000, Paul Sorenson wrote:
                            > > Why can't I pass in a Transaction instance to respond() and have it used
                            > > (and accessible) throughout my template?
                            >
                            > Because Tavis wrote it that way. Because that's how Cheetah evolved.
                            > Chronologically:
                            >
                            > 1) Cheetah was created because Webware needed a template system.
                            > We wanted the templates usable as servlets.
                            > => The main method has to be called .respond().
                            > => It must accept a Webware transaction as an argument.
                            > => It must call trans.response().write() for the output since
                            > that's what a servlet would do.
                            >
                            > 2) We realized Cheetah would also be useful standalone.
                            > => DummyTransaction with .response().write() connected to a StringIO.
                            > => Return the output like Python users want.
                            >
                            > 3) NameMapper lookup evolved similar to its current form.
                            > => "$abc" compiles to a function call:
                            > write(VFS(SL + [globals(), __builtin__],"abc",True))
                            > => write() is an aias for trans.response().write()
                            > => VFS() automatically calls abc() if it's a function/method.
                            > => This depends on the called method using DummyTransaction because it
                            > has to return the value. Tavis must have noticed this at the time,
                            > but I'm sure nobody else did.
                            > => Notwithstanding the previous, if you were to pass through 'trans',
                            > where would you put it? Would you teach VFS (a generic function,
                            > not Cheetah or Webware specific) to pass it? (I was wrong about
                            > this yesterday when I said it would be easy to pass.)
                            > => We must not put type-specific information into the compiled
                            > template. So calling abc() ourselves is verboten:
                            > VFS(SL + [globals(), __builtin__],"abc",False)(trans=trans)
                            > We cannot assume $abc exists at compile time, much less check its
                            > type. We tried that in an earlier Cheetah version, and it breaks
                            > if 'abc' changes type during runtime.
                            > => Theoretically we could have passed trans=trans and avoided the
                            > write() call, maybe. But we didn't, and the previous two
                            > problems would have remained anyway.
                            >
                            >
                            > 4) Users clamored for #filter.
                            > => The function call changes to:
                            > write(filter(VFS(SL + [globals(), __builtin__],"abc",True),
                            rawExpr='$abc'))
                            >
                            >
                            > 5) 1 1/2 years later, Paul Sorenson notices his transaction isn't being
                            > passed to #def's and complains.
                            > => Even if we can get around (3), #filter is now a bitch because
                            > we *can't* just trans=trans now even if we could before. We
                            > have to filter() the method output before putting it on the
                            > stream, and we can't do that if it's already in the stream.
                            > => But we can't get rid of #filter because many users want it,
                            > many more than want auto-passing of transactions.
                            >
                            >
                            >
                            >
                            > By the way, the non-passing of transactions also affects Webware.
                            > I guess nobody noticed this before, but the following template-servlet
                            > demonstrates it:
                            >
                            > #def aMethod
                            > In aMethod: $trans.__class__.__name__
                            > ## $trans.request._fields
                            > #end def
                            > $trans.__class__.__name__<BR>
                            > $trans.request._fields<BR>
                            > $aMethod
                            >
                            > If you invoke it as "http://example.com/test?hello=world", it prints:
                            >
                            > Transaction
                            > {'hello': 'world'}
                            > In aMethod: DummyTransaction
                            >
                            > If you uncomment the line in aMethod, you get an exception because
                            > $trans.request doesn't exist. Webware defines it but DummyTransaction
                            > doesn't. So in other words, you can't access Webware services from
                            > #def methods. One would expect them to be accessible throughout the
                            > template. You can get around this with "#set global":
                            >
                            >
                            > #def aMethod
                            > In aMethod: $trans.__class__.__name__<BR>
                            > ## $trans.request._fields<BR>
                            > $req.fields<BR>
                            > #end def
                            > #set global $req = $trans.request
                            > $trans.__class__.__name__<BR>
                            > $trans.request._fields<BR>
                            > $aMethod
                            >
                            > Which prints:
                            >
                            > Transaction
                            > {'hello': 'world'}
                            > In aMethod: DummyTransaction
                            > {'hello': 'world'}



                            -------------------------------------------------------
                            This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                            Data Reports, E-commerce, Portals, and Forums are available now.
                            Download today and enter to win an XBOX or Visual Studio .NET.
                            http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                            _______________________________________________
                            Cheetahtemplate-discuss mailing list
                            Cheetahtemplate-discuss@...
                            https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                          • Mike Orr
                            ... That s the important part. :) ... Any positional arguments in your #def appear here. ... Cheetah doesn t pass this but you can. ... Cheetah doesn t pass
                            Message 13 of 19 , Jul 5, 2003
                              On Sat, Jul 05, 2003 at 03:09:32PM +1000, Paul Sorenson wrote:
                              > Ok so I wondered how webware got around this issue - it doesn't. As for
                              > your other comments they all make sense in so far as my knowledge of the
                              > internals are limited (andI have never used #filter).
                              >
                              > And don't worry, I still recommend cheetah to my friends :-)

                              That's the important part. :)

                              > So is it fair to say that the parameter lists of #def'd methods are never
                              > "filled"?
                              >
                              > Here is the generated method call of #def abc:
                              > def abc(self,

                              Any positional arguments in your #def appear here.

                              > trans=None,

                              Cheetah doesn't pass this but you can.

                              > dummyTrans=False,

                              Cheetah doesn't pass this but you can.

                              > VFS=valueFromSearchList,
                              > VFN=valueForName,
                              > getmtime=getmtime,
                              > currentTime=time.time,
                              > globals=globals,
                              > locals=locals,
                              > __builtin__=__builtin__):

                              These are all Python's "local variable kludge". Because local variable
                              lookups are much faster than global, some users do this for a slight
                              speed improvement. Someday when Python optimizes global variable
                              lookups, these won't be necessary. You would never pass these variables
                              in a method call. We also take the opportunity to rename VFN, VFS and
                              currentTime, to kill two birds with one stone.

                              If your #def has *$args and **$kw, they would appear here.

                              > And here is the "metacall" to $abc
                              >
                              > write(filter(VFS(SL + [globals(), __builtin__],"abc",True), rawExpr='$abc'))
                              >
                              > I imagine globals() and __builtin__ are passed to abc().


                              No. "SL + [globals(), __builtin__]" is the first argument to VFS.
                              That's the searchList VFS looks up in. "abc" is the second
                              argument, what we're looking for. True is the third argument, whether
                              to autocall. Autocalling is done without arguments: abc() .
                              If you want to pass arguments to your method, you'd write $abc("arg1")
                              and it would compile to:

                              write(filter(VFS(SL + [globals(), __builtin__],"abc",False)("arg1"),
                              rawExpr='$abc("arg1")'))

                              The entire VFS call is the first argument to filter.
                              rawExpr is a keyword argument to filter.



                              --
                              -Mike (Iron) Orr, mso@... (iron@...)
                              http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


                              -------------------------------------------------------
                              This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                              Data Reports, E-commerce, Portals, and Forums are available now.
                              Download today and enter to win an XBOX or Visual Studio .NET.
                              http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                              _______________________________________________
                              Cheetahtemplate-discuss mailing list
                              Cheetahtemplate-discuss@...
                              https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                            • Mike Orr
                              ... For the curious, each part of this long expression was added per a specific user request. write -- Make it work with Webware. filter -- We
                              Message 14 of 19 , Jul 5, 2003
                                On Sat, Jul 05, 2003 at 12:03:09AM -0700, Mike Orr wrote:
                                > > write(filter(VFS(SL + [globals(), __builtin__],"abc",True), rawExpr='$abc'))
                                > >
                                > > I imagine globals() and __builtin__ are passed to abc().
                                >
                                >
                                > No. "SL + [globals(), __builtin__]" is the first argument to VFS.
                                > That's the searchList VFS looks up in. "abc" is the second
                                > argument, what we're looking for. True is the third argument, whether
                                > to autocall. Autocalling is done without arguments: abc() .

                                For the curious, each part of this long expression was added per a specific
                                user request.

                                write -- Make it work with Webware.
                                filter -- We want #filter.
                                VFS -- We want searchList, uniform dotted notation, etc.
                                SL -- We love searchList's.
                                globals() -- Needed to make #import variables visible.
                                __builtin__ -- Needed to access Python builtins. This was to fix
                                a bug in the previous strategy.
                                True -- We want autocalling.
                                rawExpr -- Allows the filter to print a useful error message.

                                --
                                -Mike (Iron) Orr, mso@... (iron@...)
                                http://iron.cx/ English * Esperanto * Russkiy * Deutsch * Espan~ol


                                -------------------------------------------------------
                                This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                                Data Reports, E-commerce, Portals, and Forums are available now.
                                Download today and enter to win an XBOX or Visual Studio .NET.
                                http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                                _______________________________________________
                                Cheetahtemplate-discuss mailing list
                                Cheetahtemplate-discuss@...
                                https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                              • Paul Sorenson
                                Mike, Did you try this? ... From: Mike Orr To: Cheetah Template List Sent: Saturday, July 05,
                                Message 15 of 19 , Jul 5, 2003
                                  Mike,

                                  Did you try this?

                                  ----- Original Message -----
                                  From: "Mike Orr" <mso@...>
                                  To: "Cheetah Template List" <cheetahtemplate-discuss@...>
                                  Sent: Saturday, July 05, 2003 2:00 PM
                                  Subject: Re: [Cheetahtemplate-discuss] DummyResponse and CGI sessions


                                  > You can get around this with "#set global":
                                  >
                                  > #def aMethod
                                  > In aMethod: $trans.__class__.__name__<BR>
                                  > ## $trans.request._fields<BR>
                                  > $req.fields<BR>
                                  > #end def
                                  > #set global $req = $trans.request
                                  > $trans.__class__.__name__<BR>
                                  > $trans.request._fields<BR>
                                  > $aMethod
                                  >
                                  > Which prints:
                                  >
                                  > Transaction
                                  > {'hello': 'world'}
                                  > In aMethod: DummyTransaction
                                  > {'hello': 'world'}



                                  -------------------------------------------------------
                                  This SF.Net email sponsored by: Free pre-built ASP.NET sites including
                                  Data Reports, E-commerce, Portals, and Forums are available now.
                                  Download today and enter to win an XBOX or Visual Studio .NET.
                                  http://aspnet.click-url.com/go/psa00100006ave/direct;at.asp_061203_01/01
                                  _______________________________________________
                                  Cheetahtemplate-discuss mailing list
                                  Cheetahtemplate-discuss@...
                                  https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
                                Your message has been successfully submitted and would be delivered to recipients shortly.