Template-Parsing Klasse

Code-Stücke können hier veröffentlicht werden.
Vortec
User
Beiträge: 52
Registriert: Dienstag 10. Dezember 2002, 11:54

Template-Parsing Klasse

Beitragvon Vortec » Montag 24. Januar 2005, 13:12

Code: Alles auswählen

import os

class Template:
    """
        This class is used for replacing placeholders in templates
        with values. It's most useful for HTML templates, but you
        can use it for every kind of file you want. The class
        doesn't check which format the file has.
        Let's say you have a template file which looks like this:

        $what$ is going to be $how$.

        You want to replace $what$ with "This" and $how$ with
        "awesome". The example code would look like that:

        template = Template("filename_of_your_template")
        template.setPlaceholder("$")
        template.feed("what", "This")
        template.feed("how", "awesome")
        template.parse()
        print template.getOutput()

        In the end it will look like that:

        This is going to be awesome.

        Try it, it's easy!
    """

    def __init__(self, filename, content={}, placeholder="%"):
        """ Initialize method """
        self._fp = file(filename, "r")
        self._filesize = os.path.getsize(filename)
        self._parsed = 0
        self._template = ""
        self._content = content
        self._placeholder = placeholder

    def feed(self, key, value):
        """ Feed the content dict with a key anda value.
            Function does overwrite old keys if they exist. """
        if self._parsed == 0:
            self._content[key] = value
        else:
            raise ValueError, "Template has already been parsed."
           
    def empty(self):
        """ Resets the content dict. """
        if self._parsed == 0:
            self._content = {}
        else:
            raise ValueError, "Template has already been parsed."
           
    def assignContent(self, content={}):
        """ Updates content dict with the items of 'content'.
            Function does overwrite old keys if they exist. """
        if self._parsed == 0:
            for key in content:
                self._content[key] = content[key]
        else:
            raise ValueError, "Template has already been parsed."
           
    def setPlaceholder(self, placeholder):
        """ Sets the placeholder which is used in the templates. """
        if self._parsed == 0:
            self._placeholder = placeholder
        else:
            raise ValueError, "Template has already been parsed."

    def parse(self):
        """ Parses the template with the items that has been assigned
            before. """
        if self._parsed == 0:
            # Read file contents
            self._template = self._fp.read(self._filesize)
            # Replace placeholders with values
            for key in self._content:
                self._template = self._template.replace("%s%s%s" % \
                    (self._placeholder, key, self._placeholder), \
                    self._content[key])
            self._fp.close()
            self._parsed = 1
        else:
            raise ValueError, "Template has already been parsed."
           
    def getOutput(self):
        """ Returns the parsed template if it has been parsed. """
        if self._parsed == 1:
            return self._template
        else:
            raise ValueError, "Template has not been parsed yet."

    def reset(self):
        """ Resets everything, so you can parse again. """
        self.__init__()


Hab ich auf die Schnelle zusammengebastelt, funktioniert aber prima. Verbesserungsvorschläge sind natürlich immer willkommen.
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Montag 24. Januar 2005, 15:01

Hi Vortec,

bei __init__ öffnest du eine Datei, die du aber noch gar nicht benötigst und erst in einer anderen Methode schließt. Ich würde die Datei erst in der Methode parse öffnen, auslesen und schließen.
Das Parsen selbst erscheint mir auch etwas umständlich. Mit hilfe von re lässt sich das Template aufbereiten und dann der Content aus einem Dictionary einfügen, etwa so:

Code: Alles auswählen

    def parse(self):
        if not self._parsed: # find ich schöner als if self._parsed == 0:
            f = open(self._filename,'r')
            self._template = f.read() # read ohne Argument liest ganze Datei
            f.close()

            # erstelle Regularexpression für Ersetzung
            ph = re.escape(self._placeholder)
            regex = r"%(ph)s(.*?)%(ph)s" % {"ph" : ph}

            # wandle "$what$ is going to be $how$."
            # in "%(what)s is going to be %(how)s." um
            self._template = re.sub(regex, r"%(\1)s", self._template)

            self._output = self._template % self._content # Content einfügen
            self._parsed = True
        else:
           raise ValueError("Template has already been parsed")

    def getOutput(self):
        if self._parsed:
            return self._output
        else:
            raise ValueError, "Template has not been parsed yet."


Du könntest das einfügen vom Content auch erst in getOutput machen, in self._template steht das für den %-Operator aufberteitete Template ja zur Verfügung und kann dann auch mit anderem Content gefüllt werden.


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder