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

[Cheetahtemplate-discuss] Overriding the NotFound exception

Expand Messages
  • Brian Bird
    I d like to change the behaviour of my Template objects so that if a $placeholder variable doesn t exist then a blank string is printed instead of a NotFound
    Message 1 of 7 , Aug 27, 2004
    • 0 Attachment
      Overriding the NotFound exception

      I'd like to change the behaviour of my Template objects so that if a $placeholder variable doesn't exist then a blank string is printed instead of a NotFound exception being raised.

      Is there an easy way to do this without hacking the Template.py source code?


      I thought I might get it to work using an error handler (although should I really only use this for debugging?), but when I pass one to the template constructor I get an error. Here's the code:

       from Cheetah import ErrorCatchers, Template
       namespaces=[{"key":"value"}]
       t=Template.Template(source="Start $key $missingkey End", searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
       print t

      I get the error "AttributeError: class ErrorCatcher has no attribute '__class__' "

      I have to specify it as a class rather than a string because I want to use my own errorcatcher class if I could get it working.


      Thanks for any help

      Brian

    • Doug Wyatt
      What happens if you put an instance of something like this in your search list: class SafeDict(dict): def __getitem__(self, k): if not self.has_key(k): return
      Message 2 of 7 , Aug 27, 2004
      • 0 Attachment
        What happens if you put an instance of something like this in your
        search list:

        class SafeDict(dict):
        def __getitem__(self, k):
        if not self.has_key(k):
        return ""
        return dict.__getitem__(self, k)

        ?

        Actually it probably needs to override more dict methods like hasitem
        but it seems worth an experiment...

        Doug

        On Aug 27, 2004, at 8:40, Brian Bird wrote:
        > I'd like to change the behaviour of my Template objects so that if a
        > $placeholder variable doesn't exist then a blank string is printed
        > instead of a NotFound exception being raised.
        >
        > Is there an easy way to do this without hacking the Template.py source
        > code?
        >
        >
        >
        > I thought I might get it to work using an error handler (although
        > should I really only use this for debugging?), but when I pass one to
        > the template constructor I get an error. Here's the code:
        >
        >  from Cheetah import ErrorCatchers, Template
        >  namespaces=[{"key":"value"}]
        >  t=Template.Template(source="Start $key $missingkey End",
        > searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
        >  print t
        >
        > I get the error "AttributeError: class ErrorCatcher has no attribute
        > '__class__' "
        >
        > I have to specify it as a class rather than a string because I want to
        > use my own errorcatcher class if I could get it working.
        >
        >
        >
        > Thanks for any help
        >
        > Brian



        -------------------------------------------------------
        This SF.Net email is sponsored by BEA Weblogic Workshop
        FREE Java Enterprise J2EE developer tools!
        Get your free copy of BEA WebLogic Workshop 8.1 today.
        http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
        _______________________________________________
        Cheetahtemplate-discuss mailing list
        Cheetahtemplate-discuss@...
        https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
      • Tracy Ruggles
        ++ Om Mani Padme Hum ++ = SAT NAM = Here s a really useful class that I use inside my templates during testing... # === display.py ========== from
        Message 3 of 7 , Aug 28, 2004
        • 0 Attachment
          ++ Om Mani Padme Hum ++
          == SAT NAM =
          Here's a really useful class that I use inside my templates during testing...

          # === display.py ==========

          from Cheetah.Template import Template

          info = {'description':'this is the description'}
          # we won't define 'content' to see how the Null object works
          template = Template(file='example.tmpl', searchList=[locals()])
          print template


          # === example.tmpl =========

          #from Null import Null
          #set content = $getVar('content', $Null(alias='content'))
          #set info = $getVar('info', $Null(alias='info'))

          <h1>$content.title</h1>

          #for para in $content.paragraphs
          <p id="$para.id">$para.contents</p>
          <!-- $para.info -->
          #end for

          <p><hr /></p>
          <p>$info.description</p>


          # === begin Null.py ==========

          def get(obj, name):
          try:
          return object.__getattribute__(obj, name)
          except AttributeError:
          return ''

          class Null(object):
          class __metaclass__(type):
          def __new__(klass, name, bases, kw):
          return type(name, (), kw)
          def __init__(self, *args, **kw):
          if kw.get('alias'):
          object.__setattr__(self, '_alias', kw.get('alias'))
          def __getitem__(self, i):
          return self.__class__(alias='%s[%s]' % \
          (get(self, '_alias'), i))
          def __iter__(self):
          yield self
          def __getattr__(self, attr):
          return self.__class__(alias='%s.%s' % \
          (get(self, '_alias'), attr))
          def __setattr__(self, name, value):
          return self
          def __delattr__(self, name):
          return self
          def __repr__(self):
          alias = get(self, '_alias')
          return "<Null%s>" % (alias and ':'+alias or '')
          def __str__(self):
          alias = get(self, '_alias')
          return "Null%s" % (alias and ':'+alias or '')
          def __call__(self, *args, **kwargs):
          return self.__class__(alias='%s()' % get(self, '_alias'))


          -------------------------------------------------------
          This SF.Net email is sponsored by BEA Weblogic Workshop
          FREE Java Enterprise J2EE developer tools!
          Get your free copy of BEA WebLogic Workshop 8.1 today.
          http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
          _______________________________________________
          Cheetahtemplate-discuss mailing list
          Cheetahtemplate-discuss@...
          https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
        • Brian Bird
          Thanks - this is the solution I ended up using (I basically added an instance of SafeDict to the end of the searchList so I didn t need an errorCatcher): ie.
          Message 4 of 7 , Aug 31, 2004
          • 0 Attachment
            Thanks - this is the solution I ended up using (I basically added an
            instance of SafeDict to the end of the searchList so I didn't need an
            errorCatcher):
            ie.
            t=Template.Template(source="Start $key $missingkey
            End",searchList=namespaces+[SafeDict()])

            This works fine, but I just get the feeling there should be a built-in way
            to do this (maybe Template.py should have an optional default argument,
            which if not specified will raise the NotFound exception as normal?)

            Brian

            -----Original Message-----
            From: Doug Wyatt [mailto:doug@...]
            Sent: 27 August 2004 18:02
            To: Brian Bird
            Cc: cheetahtemplate-discuss@...
            Subject: Re: [Cheetahtemplate-discuss] Overriding the NotFound exception


            What happens if you put an instance of something like this in your
            search list:

            class SafeDict(dict):
            def __getitem__(self, k):
            if not self.has_key(k):
            return ""
            return dict.__getitem__(self, k)

            ?

            Actually it probably needs to override more dict methods like hasitem
            but it seems worth an experiment...

            Doug

            On Aug 27, 2004, at 8:40, Brian Bird wrote:
            > I'd like to change the behaviour of my Template objects so that if a
            > $placeholder variable doesn't exist then a blank string is printed
            > instead of a NotFound exception being raised.
            >
            > Is there an easy way to do this without hacking the Template.py source
            > code?
            >
            >
            >
            > I thought I might get it to work using an error handler (although
            > should I really only use this for debugging?), but when I pass one to
            > the template constructor I get an error. Here's the code:
            >
            >  from Cheetah import ErrorCatchers, Template
            >  namespaces=[{"key":"value"}]
            >  t=Template.Template(source="Start $key $missingkey End",
            > searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
            >  print t
            >
            > I get the error "AttributeError: class ErrorCatcher has no attribute
            > '__class__' "
            >
            > I have to specify it as a class rather than a string because I want to
            > use my own errorcatcher class if I could get it working.
            >
            >
            >
            > Thanks for any help
            >
            > Brian




            -------------------------------------------------------
            This SF.Net email is sponsored by BEA Weblogic Workshop
            FREE Java Enterprise J2EE developer tools!
            Get your free copy of BEA WebLogic Workshop 8.1 today.
            http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
            _______________________________________________
            Cheetahtemplate-discuss mailing list
            Cheetahtemplate-discuss@...
            https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
          • Brian Bird
            I ended up using Doug Wyatt s solution so I ve not looked much further into this bug. However, I know the errorCatcher parameter has to be a class rather than
            Message 5 of 7 , Aug 31, 2004
            • 0 Attachment
              I ended up using Doug Wyatt's solution so I've not looked much further into
              this bug. However, I know the errorCatcher parameter has to be a class
              rather than an instance (it won't get past the type checking in the Template
              constructor otherwise).

              I did have a quick play with trying to get it to work (around line 202 of
              Template.py) but had no luck. I suspect everything I tried would have broken
              using #errorCatcher in the template anyway :)

              Thanks,
              Brian

              -----Original Message-----
              From: Mike Orr [mailto:mso@...]
              Sent: 27 August 2004 19:18
              To: Brian Bird; Cheetah Template List; Tavis Rudd
              Subject: Re: [Cheetahtemplate-discuss] Overriding the NotFound exception


              On Fri, Aug 27, 2004 at 04:40:12PM +0100, Brian Bird wrote:
              > I'd like to change the behaviour of my Template objects so that if a
              > $placeholder variable doesn't exist then a blank string is printed
              > instead of a NotFound exception being raised.
              >
              > Is there an easy way to do this without hacking the Template.py source
              > code?
              >
              >
              > I thought I might get it to work using an error handler (although
              > should I really only use this for debugging?),

              Yes, an ErrorCatcher is what you want.

              > but when I pass one to the template
              > constructor I get an error. Here's the code:
              >
              > from Cheetah import ErrorCatchers, Template
              > namespaces=[{"key":"value"}] t=Template.Template(source="Start $key
              > $missingkey End",
              > searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
              > print t
              >
              > I get the error "AttributeError: class ErrorCatcher has no attribute
              > '__class__' "
              >
              > I have to specify it as a class rather than a string because I want to
              > use my own errorcatcher class if I could get it working.

              There must be a bug in the constructor. If you have time to analyze it and
              make a patch, we'll happily put it in. I've only done it via #errorCatcher,
              not the constructor.

              The only problem with error catchers is they're catching an exception, which
              is inefficient (i.e., slow) in Python. But the difference
              shouldn't be noticeable unless you're filling several templates a second.

              --
              -Mike Orr (aka. Sluggo), mso@... (iron@...)
              http://sluggo.kicks-ass.org/ Cxu vi parolas Esperante?



              -------------------------------------------------------
              This SF.Net email is sponsored by BEA Weblogic Workshop
              FREE Java Enterprise J2EE developer tools!
              Get your free copy of BEA WebLogic Workshop 8.1 today.
              http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
              _______________________________________________
              Cheetahtemplate-discuss mailing list
              Cheetahtemplate-discuss@...
              https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
            • Brian Bird
              I thought I d solved my problem by using a dictionary in the namespace which returns instead of raising NotFound if a key isn t available (thanks Doug for
              Message 6 of 7 , Aug 31, 2004
              • 0 Attachment
                I thought I'd solved my problem by using a dictionary in the namespace which
                returns "" instead of raising NotFound if a key isn't available (thanks Doug
                for the idea). However, this then means that any inherited methods in my
                templates aren't found (It appears that the namespace is searched before any
                inherited methods - is this right? It seems odd since a value a user submits
                could override a method).

                In my case I can't guarantee I know all the field names being submitted so I
                can't set all the relevant fields to "" before creating the Template.

                So I've re-vistited the errorCatcher solution. If I use #errorCatcher in all
                my templates then it seems to work ok, except that means editing hundreds of
                templates and adding this instruction. I also don't like this idea because
                other users can edit the templates and may accidentally remove this line
                without realising it's importance.


                So (simplified) my example now looks like this:

                class BlankError(ErrorCatchers.ErrorCatcher):
                def warn(self, exc_val, code, rawCode, lineCol):
                return ""
                t=Template.Template(filter=filter, source=source, searchList=[namespace],
                errorCatcher=BlankError)

                This gives an error because the Template constructor expects a class as the
                errorCatcher argument (line 128), but then later (line 202) it tries to
                access .__class__.__name__ which fails. Removing the __class__ bit stops any
                errors but then the compiler doesn't appear to use the errorCatcher I've
                specified.

                To fix this I added another line just before the compiler.compile() in the
                compile method (line 245). However, this will cause an error for anyone not
                using an error handler. Also, I can't make this dependant on whether
                self._errorCatcher has been set because this compile() method is called
                before self._errorCatcher is set!

                I'm using the latest 0.9.15 release from sourceforge. Does anyone who knows
                more than me about this code think they could fix it? I can't help thinking
                there should be a simple way to do this but I can't see it...

                Thanks,
                Brian

                -----Original Message-----
                From: Mike Orr [mailto:mso@...]
                Sent: 27 August 2004 19:18
                To: Brian Bird; Cheetah Template List; Tavis Rudd
                Subject: Re: [Cheetahtemplate-discuss] Overriding the NotFound exception


                On Fri, Aug 27, 2004 at 04:40:12PM +0100, Brian Bird wrote:
                > I'd like to change the behaviour of my Template objects so that if a
                > $placeholder variable doesn't exist then a blank string is printed
                > instead of a NotFound exception being raised.
                >
                > Is there an easy way to do this without hacking the Template.py source
                > code?
                >
                >
                > I thought I might get it to work using an error handler (although
                > should I really only use this for debugging?),

                Yes, an ErrorCatcher is what you want.

                > but when I pass one to the template
                > constructor I get an error. Here's the code:
                >
                > from Cheetah import ErrorCatchers, Template
                > namespaces=[{"key":"value"}] t=Template.Template(source="Start $key
                > $missingkey End",
                > searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
                > print t
                >
                > I get the error "AttributeError: class ErrorCatcher has no attribute
                > '__class__' "
                >
                > I have to specify it as a class rather than a string because I want to
                > use my own errorcatcher class if I could get it working.

                There must be a bug in the constructor. If you have time to analyze it and
                make a patch, we'll happily put it in. I've only done it via #errorCatcher,
                not the constructor.

                The only problem with error catchers is they're catching an exception, which
                is inefficient (i.e., slow) in Python. But the difference
                shouldn't be noticeable unless you're filling several templates a second.

                --
                -Mike Orr (aka. Sluggo), mso@... (iron@...)
                http://sluggo.kicks-ass.org/ Cxu vi parolas Esperante?



                -------------------------------------------------------
                This SF.Net email is sponsored by BEA Weblogic Workshop
                FREE Java Enterprise J2EE developer tools!
                Get your free copy of BEA WebLogic Workshop 8.1 today.
                http://ads.osdn.com/?ad_idP47&alloc_id808&op=click
                _______________________________________________
                Cheetahtemplate-discuss mailing list
                Cheetahtemplate-discuss@...
                https://lists.sourceforge.net/lists/listinfo/cheetahtemplate-discuss
              • Brian Bird
                Just to follow up on this bug: I ve written some tests to illustrate the problem. Attached is an updated Template.py from the Cheetah/Tests subdirectory.
                Message 7 of 7 , Aug 31, 2004
                • 0 Attachment
                  Just to follow up on this bug:
                  I've written some tests to illustrate the problem. Attached is an updated
                  Template.py from the Cheetah/Tests subdirectory.

                  (Sorry, there were no tests in it beforehand so I hope I haven't deviated
                  from convention too much)

                  Any help appreciated

                  Thanks,
                  Brian

                  -----Original Message-----
                  From: cheetahtemplate-discuss-admin@...
                  [mailto:cheetahtemplate-discuss-admin@...] On Behalf Of
                  Brian Bird
                  Sent: 31 August 2004 12:38
                  To: mso@...; 'Cheetah Template List'
                  Subject: RE: [Cheetahtemplate-discuss] Overriding the NotFound exception


                  I thought I'd solved my problem by using a dictionary in the namespace which
                  returns "" instead of raising NotFound if a key isn't available (thanks Doug
                  for the idea). However, this then means that any inherited methods in my
                  templates aren't found (It appears that the namespace is searched before any
                  inherited methods - is this right? It seems odd since a value a user submits
                  could override a method).

                  In my case I can't guarantee I know all the field names being submitted so I
                  can't set all the relevant fields to "" before creating the Template.

                  So I've re-vistited the errorCatcher solution. If I use #errorCatcher in all
                  my templates then it seems to work ok, except that means editing hundreds of
                  templates and adding this instruction. I also don't like this idea because
                  other users can edit the templates and may accidentally remove this line
                  without realising it's importance.


                  So (simplified) my example now looks like this:

                  class BlankError(ErrorCatchers.ErrorCatcher):
                  def warn(self, exc_val, code, rawCode, lineCol):
                  return ""
                  t=Template.Template(filter=filter, source=source, searchList=[namespace],
                  errorCatcher=BlankError)

                  This gives an error because the Template constructor expects a class as the
                  errorCatcher argument (line 128), but then later (line 202) it tries to
                  access .__class__.__name__ which fails. Removing the __class__ bit stops any
                  errors but then the compiler doesn't appear to use the errorCatcher I've
                  specified.

                  To fix this I added another line just before the compiler.compile() in the
                  compile method (line 245). However, this will cause an error for anyone not
                  using an error handler. Also, I can't make this dependant on whether
                  self._errorCatcher has been set because this compile() method is called
                  before self._errorCatcher is set!

                  I'm using the latest 0.9.15 release from sourceforge. Does anyone who knows
                  more than me about this code think they could fix it? I can't help thinking
                  there should be a simple way to do this but I can't see it...

                  Thanks,
                  Brian

                  -----Original Message-----
                  From: Mike Orr [mailto:mso@...]
                  Sent: 27 August 2004 19:18
                  To: Brian Bird; Cheetah Template List; Tavis Rudd
                  Subject: Re: [Cheetahtemplate-discuss] Overriding the NotFound exception


                  On Fri, Aug 27, 2004 at 04:40:12PM +0100, Brian Bird wrote:
                  > I'd like to change the behaviour of my Template objects so that if a
                  > $placeholder variable doesn't exist then a blank string is printed
                  > instead of a NotFound exception being raised.
                  >
                  > Is there an easy way to do this without hacking the Template.py source
                  > code?
                  >
                  >
                  > I thought I might get it to work using an error handler (although
                  > should I really only use this for debugging?),

                  Yes, an ErrorCatcher is what you want.

                  > but when I pass one to the template
                  > constructor I get an error. Here's the code:
                  >
                  > from Cheetah import ErrorCatchers, Template
                  > namespaces=[{"key":"value"}] t=Template.Template(source="Start $key
                  > $missingkey End",
                  > searchList=namespaces,errorCatcher=ErrorCatchers.Echo)
                  > print t
                  >
                  > I get the error "AttributeError: class ErrorCatcher has no attribute
                  > '__class__' "
                  >
                  > I have to specify it as a class rather than a string because I want to
                  > use my own errorcatcher class if I could get it working.

                  There must be a bug in the constructor. If you have time to analyze it and
                  make a patch, we'll happily put it in. I've only done it via #errorCatcher,
                  not the constructor.

                  The only problem with error catchers is they're catching an exception, which
                  is inefficient (i.e., slow) in Python. But the difference
                  shouldn't be noticeable unless you're filling several templates a second.

                  --
                  -Mike Orr (aka. Sluggo), mso@... (iron@...)
                  http://sluggo.kicks-ass.org/ Cxu vi parolas Esperante?



                  -------------------------------------------------------
                  This SF.Net email is sponsored by BEA Weblogic Workshop
                  FREE Java Enterprise J2EE developer tools!
                  Get your free copy of BEA WebLogic Workshop 8.1 today.
                  http://ads.osdn.com/?ad_idP47&alloc_id808&op=ick
                  _______________________________________________
                  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.