'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
out_path if not-none writes the results to a file
(though results are always returned)
subject is a profile or system object, if available (for snippet eval)'

def render(self, data_input, search_table, out_path, subject=None, template_type=None):

    if (not isinstance(data_input, basestring)):
        raw_data = data_input.read()
    else:
        raw_data = data_input
    lines = raw_data.split('\n')
    if (not template_type):
        if (self.settings and self.settings.default_template_type):
            template_type = self.settings.default_template_type
        else:
            template_type = 'cheetah'
    if ((len(lines) > 0) and (lines[0].find('#template=') == 0)):
        template_type = lines[0].split('=')[1].strip().lower()
        del lines[0]
        raw_data = string.join(lines, '\n')
    if (template_type == 'cheetah'):
        data_out = self.render_cheetah(raw_data, search_table, subject)
    elif (template_type == 'jinja2'):
        if jinja2_available:
            data_out = self.render_jinja2(raw_data, search_table, subject)
        else:
            return '#    ERROR:    JINJA2    NOT    AVAILABLE.    Maybe    you    need    to    install    python-jinja2?\n'
    else:
        return ('#    ERROR:    UNSUPPORTED    TEMPLATE    TYPE    (%s)' % str(template_type))
    hp = search_table.get('http_port', '80')
    server = search_table.get('server', 'server.example.org')
    if (hp not in (80, '80')):
        repstr = ('%s:%s' % (server, hp))
    else:
        repstr = server
    search_table['http_server'] = repstr
    for x in search_table.keys():
        if (type(x) == str):
            data_out = data_out.replace(('@@%s@@' % str(x)), str(search_table[str(x)]))
    if data_out.startswith('\n'):
        data_out = data_out.lstrip()
    if (out_path is not None):
        utils.mkdir(os.path.dirname(out_path))
        fd = open(out_path, 'w+')
        fd.write(data_out)
        fd.close()
    return data_out
