Ejemplo n.º 1
0
    def template_loader(self):
        """A :class:`genshi.template.TemplateLoader` that loads templates
        from the same places as Flask.

        """
        path = loader.directory(os.path.join(self.app.root_path, 'templates'))
        module_paths = {}
        modules = getattr(self.app, 'modules', {})
        for name, module in list(modules.items()):
            module_path = os.path.join(module.root_path, 'templates')
            if os.path.isdir(module_path):
                module_paths[name] = loader.directory(module_path)
        return TemplateLoader([path, loader.prefixed(**module_paths)],
                              auto_reload=self.app.debug,
                              callback=self.callback)
Ejemplo n.º 2
0
    def template_loader(self):
        """A :class:`genshi.template.TemplateLoader` that loads templates
        from the same places as Flask.

        """
        path = loader.directory(os.path.join(self.app.root_path, 'templates'))
        module_paths = {}
        modules = getattr(self.app, 'modules', {})
        for name, module in modules.iteritems():
            module_path = os.path.join(module.root_path, 'templates')
            if os.path.isdir(module_path):
                module_paths[name] = loader.directory(module_path)
        return TemplateLoader([path, loader.prefixed(**module_paths)],
                              auto_reload=self.app.debug,
                              callback=self.callback)
Ejemplo n.º 3
0
    def template_loader(self):
        """A :class:`genshi.template.TemplateLoader` that loads templates
        from the same places as Flask.

        """
        path = loader.directory(
            os.path.join(self.app.root_path, self.app.template_folder))
        return TemplateLoader(path,
                              auto_reload=self.app.debug,
                              callback=self.callback)
Ejemplo n.º 4
0
    def template_loader(self):
        """A :class:`genshi.template.TemplateLoader` that loads templates
        from the same places as Flask.

        """
        search_paths = {}
        for name, jinja_loader in self._iter_jinja_loaders():
            assert type(jinja_loader.searchpath) is list and len(jinja_loader.searchpath) == 1
            search_paths[name] = loader.directory(jinja_loader.searchpath[0])
        return TemplateLoader(loader.prefixed(**search_paths),
                              auto_reload=self.app.debug,
                              callback=self.callback)
Ejemplo n.º 5
0
    def template_loader(self):
        """A :class:`genshi.template.TemplateLoader` that loads templates
        from the same places as Flask.

        .. versionchanged:: 0.6
            Removed support for flask modules and enabled support for blueprints
        """
        path = loader.directory(
            os.path.join(self.app.root_path, self.app.template_folder or 'templates')
        )
        blueprint_paths = {}
        blueprints = getattr(self.app, 'blueprints', {})
        for name, blueprint in blueprints.items():
            blueprint_path = os.path.join(
                blueprint.root_path, blueprint.template_folder or 'templates'
            )
            if os.path.isdir(blueprint_path):
                blueprint_paths[name] = loader.directory(blueprint_path)
        return TemplateLoader([path, loader.prefixed(**blueprint_paths)],
                              auto_reload=self.app.debug,
                              callback=self.callback)
Ejemplo n.º 6
0
    def load(self, filename, relative_to=None, cls=None, encoding=None):
        """Load the template with the given name.

        XXX: This code copied and modified from Genshi 0.6

        If the `filename` parameter is relative, this method searches the
        search path trying to locate a template matching the given name. If the
        file name is an absolute path, the search path is ignored.

        If the requested template is not found, a `TemplateNotFound` exception
        is raised. Otherwise, a `Template` object is returned that represents
        the parsed template.

        Template instances are cached to avoid having to parse the same
        template file more than once. Thus, subsequent calls of this method
        with the same template file name will return the same `Template`
        object (unless the ``auto_reload`` option is enabled and the file was
        changed since the last parse.)

        If the `relative_to` parameter is provided, the `filename` is
        interpreted as being relative to that path.

        :param filename: the relative path of the template file to load
        :param relative_to: the filename of the template from which the new
                            template is being loaded, or ``None`` if the
                            template is being loaded directly
        :param cls: the class of the template object to instantiate
        :param encoding: the encoding of the template to load; defaults to the
                         ``default_encoding`` of the loader instance
        :return: the loaded `Template` instance
        :raises TemplateNotFound: if a template with the given name could not
                                  be found
        """
        if cls is None:
            cls = self.default_class
        search_path = self.search_path

        # Make the filename relative to the template file its being loaded
        # from, but only if that file is specified as a relative path, or no
        # search path has been set up
        if relative_to and (not search_path or not os.path.isabs(relative_to)):
            filename = os.path.join(os.path.dirname(relative_to), filename)

        filename = os.path.normpath(filename)
        cachekey = filename

        self._lock.acquire()
        try:
            # First check the cache to avoid reparsing the same file
            try:
                tmpl = self._cache[cachekey]
                if not self.auto_reload:
                    return tmpl
                uptodate = self._uptodate[cachekey]
                if uptodate is not None and uptodate():
                    return tmpl
            except (KeyError, OSError):
                pass

            isabs = False

            retry_vars = {}
            if os.path.isabs(filename):
                # Set up secondary search options for template paths that don't
                # resolve with our relative path trick below.
                retry_vars = dict(
                    filename = os.path.basename(filename),
                    relative_to = os.path.dirname(filename) + '/',
                    cls = cls,
                    encoding = encoding
                )
                # Make absolute paths relative to the base search path.
                log.debug('Modifying the default TemplateLoader behaviour '
                          'for path %r; treating the absolute template path '
                          'as relative to the template search path.', filename)
                relative_to = None
                filename = filename[1:] # strip leading slash

            if relative_to and os.path.isabs(relative_to):
                # Make sure that the directory containing the including
                # template is on the search path
                dirname = os.path.dirname(relative_to)
                if dirname not in search_path:
                    search_path = list(search_path) + [dirname]
                isabs = True

            elif not search_path:
                # Uh oh, don't know where to look for the template
                raise TemplateError('Search path for templates not configured')

            for loadfunc in search_path:
                if isinstance(loadfunc, basestring):
                    loadfunc = directory(loadfunc)
                try:
                    filepath, filename, fileobj, uptodate = loadfunc(filename)
                except IOError:
                    continue
                except TemplateNotFound:
                    continue
                else:
                    try:
                        if isabs:
                            # If the filename of either the included or the
                            # including template is absolute, make sure the
                            # included template gets an absolute path, too,
                            # so that nested includes work properly without a
                            # search path
                            filename = filepath
                        tmpl = self._instantiate(cls, fileobj, filepath,
                                                 filename, encoding=encoding)
                        if self.callback:
                            self.callback(tmpl)
                        self._cache[cachekey] = tmpl
                        self._uptodate[cachekey] = uptodate
                    finally:
                        if hasattr(fileobj, 'close'):
                            fileobj.close()
                    return tmpl

            if retry_vars:
                return self.load(**retry_vars)

            raise TemplateNotFound(filename, search_path)

        finally:
            self._lock.release()
Ejemplo n.º 7
0
    def load(self, filename, relative_to=None, cls=None, encoding=None):
        """Load the template with the given name.

        XXX: This code copied and modified from Genshi 0.6

        If the `filename` parameter is relative, this method searches the
        search path trying to locate a template matching the given name. If the
        file name is an absolute path, the search path is ignored.

        If the requested template is not found, a `TemplateNotFound` exception
        is raised. Otherwise, a `Template` object is returned that represents
        the parsed template.

        Template instances are cached to avoid having to parse the same
        template file more than once. Thus, subsequent calls of this method
        with the same template file name will return the same `Template`
        object (unless the ``auto_reload`` option is enabled and the file was
        changed since the last parse.)

        If the `relative_to` parameter is provided, the `filename` is
        interpreted as being relative to that path.

        :param filename: the relative path of the template file to load
        :param relative_to: the filename of the template from which the new
                            template is being loaded, or ``None`` if the
                            template is being loaded directly
        :param cls: the class of the template object to instantiate
        :param encoding: the encoding of the template to load; defaults to the
                         ``default_encoding`` of the loader instance
        :return: the loaded `Template` instance
        :raises TemplateNotFound: if a template with the given name could not
                                  be found
        """
        if cls is None:
            cls = self.default_class
        search_path = self.search_path

        # Make the filename relative to the template file its being loaded
        # from, but only if that file is specified as a relative path, or no
        # search path has been set up
        if relative_to and (not search_path or not os.path.isabs(relative_to)):
            filename = os.path.join(os.path.dirname(relative_to), filename)

        filename = os.path.normpath(filename)
        cachekey = filename

        self._lock.acquire()
        try:
            # First check the cache to avoid reparsing the same file
            try:
                tmpl = self._cache[cachekey]
                if not self.auto_reload:
                    return tmpl
                uptodate = self._uptodate[cachekey]
                if uptodate is not None and uptodate():
                    return tmpl
            except (KeyError, OSError):
                pass

            isabs = False

            retry_vars = {}
            if os.path.isabs(filename):
                # Set up secondary search options for template paths that don't
                # resolve with our relative path trick below.
                retry_vars = dict(
                    filename = os.path.basename(filename),
                    relative_to = os.path.dirname(filename) + '/',
                    cls = cls,
                    encoding = encoding
                )
                # Make absolute paths relative to the base search path.
                log.debug('Modifying the default TemplateLoader behaviour '
                          'for path %r; treating the absolute template path '
                          'as relative to the template search path.', filename)
                relative_to = None
                filename = filename[1:] # strip leading slash

            if relative_to and os.path.isabs(relative_to):
                # Make sure that the directory containing the including
                # template is on the search path
                dirname = os.path.dirname(relative_to)
                if dirname not in search_path:
                    search_path = list(search_path) + [dirname]
                isabs = True

            elif not search_path:
                # Uh oh, don't know where to look for the template
                raise TemplateError('Search path for templates not configured')

            for loadfunc in search_path:
                if isinstance(loadfunc, basestring):
                    loadfunc = directory(loadfunc)
                try:
                    filepath, filename, fileobj, uptodate = loadfunc(filename)
                except IOError:
                    continue
                except TemplateNotFound:
                    continue
                else:
                    try:
                        if isabs:
                            # If the filename of either the included or the
                            # including template is absolute, make sure the
                            # included template gets an absolute path, too,
                            # so that nested includes work properly without a
                            # search path
                            filename = filepath
                        tmpl = self._instantiate(cls, fileobj, filepath,
                                                 filename, encoding=encoding)
                        if self.callback:
                            self.callback(tmpl)
                        self._cache[cachekey] = tmpl
                        self._uptodate[cachekey] = uptodate
                    finally:
                        if hasattr(fileobj, 'close'):
                            fileobj.close()
                    return tmpl

            if retry_vars:
                return self.load(**retry_vars)

            raise TemplateNotFound(filename, search_path)

        finally:
            self._lock.release()
Ejemplo n.º 8
0
 def setUp(self):
     super(TestGenshiRenderer, self).setUp()
     self.renderer = genshirenderer.GenshiRenderer(
         loader.directory(self.tmpdir))
     self.add_content('dynamic', '<p>${foo}</p>')
Ejemplo n.º 9
0
 def setUp(self):
     super(TestGenshiRenderer, self).setUp()
     self.renderer = genshirenderer.GenshiRenderer(
         loader.directory(self.tmpdir))
     self.add_content('dynamic', '<p>${foo}</p>')