# coding: utf-8 """ This module provides a Loader class for locating and reading templates. """ import os import sys from pystache import common from pystache import defaults from pystache.locator import Locator # We make a function so that the current defaults take effect. # TODO: revisit whether this is necessary. def _make_to_unicode(): def to_unicode(s, encoding=None): """ Raises a TypeError exception if the given string is already unicode. """ if encoding is None: encoding = defaults.STRING_ENCODING return unicode(s, encoding, defaults.DECODE_ERRORS) return to_unicode class Loader(object): """ Loads the template associated to a name or user-defined object. All load_*() methods return the template as a unicode string. """ def __init__(self, file_encoding=None, extension=None, to_unicode=None, search_dirs=None): """ Construct a template loader instance. Arguments: extension: the template file extension, without the leading dot. Pass False for no extension (e.g. to use extensionless template files). Defaults to the package default. file_encoding: the name of the encoding to use when converting file contents to unicode. Defaults to the package default. search_dirs: the list of directories in which to search when loading a template by name or file name. Defaults to the package default. to_unicode: the function to use when converting strings of type str to unicode. The function should have the signature: to_unicode(s, encoding=None) It should accept a string of type str and an optional encoding name and return a string of type unicode. Defaults to calling Python's built-in function unicode() using the package string encoding and decode errors defaults. """ if extension is None: extension = defaults.TEMPLATE_EXTENSION if file_encoding is None: file_encoding = defaults.FILE_ENCODING if search_dirs is None: search_dirs = defaults.SEARCH_DIRS if to_unicode is None: to_unicode = _make_to_unicode() self.extension = extension self.file_encoding = file_encoding # TODO: unit test setting this attribute. self.search_dirs = search_dirs self.to_unicode = to_unicode def _make_locator(self): return Locator(extension=self.extension) def unicode(self, s, encoding=None): """ Convert a string to unicode using the given encoding, and return it. This function uses the underlying to_unicode attribute. Arguments: s: a basestring instance to convert to unicode. Unlike Python's built-in unicode() function, it is okay to pass unicode strings to this function. (Passing a unicode string to Python's unicode() with the encoding argument throws the error, "TypeError: decoding Unicode is not supported.") encoding: the encoding to pass to the to_unicode attribute. Defaults to None. """ if isinstance(s, unicode): return unicode(s) return self.to_unicode(s, encoding) def read(self, path, encoding=None): """ Read the template at the given path, and return it as a unicode string. """ b = common.read(path) if encoding is None: encoding = self.file_encoding return self.unicode(b, encoding) def load_file(self, file_name): """ Find and return the template with the given file name. Arguments: file_name: the file name of the template. """ locator = self._make_locator() path = locator.find_file(file_name, self.search_dirs) return self.read(path) def load_name(self, name): """ Find and return the template with the given template name. Arguments: name: the name of the template. """ locator = self._make_locator() path = locator.find_name(name, self.search_dirs) return self.read(path) # TODO: unit-test this method. def load_object(self, obj): """ Find and return the template associated to the given object. Arguments: obj: an instance of a user-defined class. search_dirs: the list of directories in which to search. """ locator = self._make_locator() path = locator.find_object(obj, self.search_dirs) return self.read(path)