'Render data_input back into a file.
data_input is either a string or a filename
search_table is a dict of metadata keys and values
(though results are always returned)
subject is a profile or system object, if available (for snippet eval)'

def render_cheetah(self, raw_data, search_table, subject=None):

    self.check_for_invalid_imports(raw_data)
    raw_data = raw_data.replace('TEMPLATE::', '$')
    newdata = ''
    if (('tree' in search_table) and search_table['tree'].startswith('nfs://')):
        for line in raw_data.split('\n'):
            if ((line.find('--url') != (-1)) and (line.find('url    ') != (-1))):
                rest = search_table['tree'][6:]
                try:
                    (server, dir) = rest.split(':', 2)
                except:
                    raise CX(('Invalid    syntax    for    NFS    path    given    during    import:    %s' % search_table['tree']))
                line = ('nfs    --server    %s    --dir    %s' % (server, dir))
                line += ('\n' + ('#url    --url=%s' % search_table['tree']))
            newdata += (line + '\n')
        raw_data = newdata
    raw_data = ('#errorCatcher    ListErrors\n' + raw_data)
    table_copy = search_table.copy()
    search_table.update({'template_universe': table_copy})
    t = Template(source=raw_data, searchList=[search_table], compilerSettings={'useStackFrame': False})
    if fix_cheetah_class:
        t.SNIPPET = functools.partial(t.SNIPPET, t)
        t.read_snippet = functools.partial(t.read_snippet, t)
    try:
        data_out = t.respond()
        self.last_errors = t.errorCatcher().listErrors()
        if self.last_errors:
            self.logger.warning('errors    were    encountered    rendering    the    template')
            self.logger.warning(('\n' + pprint.pformat(self.last_errors)))
    except Exception as e:
        self.logger.error(utils.cheetah_exc(e))
        raise CX('Error    templating    file,    check    cobbler.log    for    more    details')
    return data_out
