예제 #1
0
    def fetch_section_data(self, context, name, location):
        data = self.resolve_context(context, name, location)

        # From the spec:
        #
        #   If the data is not of a list type, it is coerced into a list
        #   as follows: if the data is truthy (e.g. `!!data == true`),
        #   use a single-element list containing the data, otherwise use
        #   an empty list.
        #
        if not data:
            data = []
        else:
            # The least brittle way to determine whether something
            # supports iteration is by trying to call iter() on it:
            #
            #   http://docs.python.org/library/functions.html#iter
            #
            # It is not sufficient, for example, to check whether the item
            # implements __iter__ () (the iteration protocol).  There is
            # also __getitem__() (the sequence protocol).  In Python 2,
            # strings do not implement __iter__(), but in Python 3 they do.
            try:
                iter(data)
            except TypeError:
                # Then the value does not support iteration.
                data = [data]
            else:
                if is_string(data) or isinstance(data, dict):
                    # Do not treat strings and dicts (which are iterable) as lists.
                    data = [data]
                # Otherwise, treat the value as a list.

        return data
예제 #2
0
    def fetch_section_data(self, context, name, location):
        data = self.resolve_context(context, name, location)

        # From the spec:
        #
        #   If the data is not of a list type, it is coerced into a list
        #   as follows: if the data is truthy (e.g. `!!data == true`),
        #   use a single-element list containing the data, otherwise use
        #   an empty list.
        #
        if not data:
            data = []
        else:
            # The least brittle way to determine whether something
            # supports iteration is by trying to call iter() on it:
            #
            #   http://docs.python.org/library/functions.html#iter
            #
            # It is not sufficient, for example, to check whether the item
            # implements __iter__ () (the iteration protocol).  There is
            # also __getitem__() (the sequence protocol).  In Python 2,
            # strings do not implement __iter__(), but in Python 3 they do.
            try:
                iter(data)
            except TypeError:
                # Then the value does not support iteration.
                data = [data]
            else:
                if is_string(data) or isinstance(data, dict):
                    # Do not treat strings and dicts (which are iterable) as lists.
                    data = [data]
                # Otherwise, treat the value as a list.

        return data
예제 #3
0
    def render(self, template, *context, **kwargs):
        """
        Render the given template string, view template, or parsed template.

        Returns a unicode string.

        Prior to rendering, this method will convert a template that is a
        byte string (type str in Python 2) to unicode using the string_encoding
        and decode_errors attributes.  See the constructor docstring for
        more information.

        Arguments:

          template: a template string that is unicode or a byte string,
            a ParsedTemplate instance, or another object instance.  In the
            final case, the function first looks for the template associated
            to the object by calling this class's get_associated_template()
            method.  The rendering process also uses the passed object as
            the first element of the context stack when rendering.

          *context: zero or more dictionaries, ContextStack instances, or objects
            with which to populate the initial context stack.  None
            arguments are skipped.  Items in the *context list are added to
            the context stack in order so that later items in the argument
            list take precedence over earlier items.

          **kwargs: additional key-value data to add to the context stack.
            As these arguments appear after all items in the *context list,
            in the case of key conflicts these values take precedence over
            all items in the *context list.

        """
        if is_string(template) and os.path.isfile(template) and os.access(template, os.R_OK):
            return self.render_path(self, template, *context, **kwargs)
        if is_string(template):
            return self._render_string(template, *context, **kwargs)
        if isinstance(template, ParsedTemplate):
            render_func = lambda engine, stack: template.render(engine, stack)
            return self._render_final(render_func, *context, **kwargs)
        # Otherwise, we assume the template is an object.

        return self._render_object(template, *context, **kwargs)
예제 #4
0
    def _render_value(self, val, context, delimiters=None):
        """
        Render an arbitrary value.

        """
        if not is_string(val):
            # In case the template is an integer, for example.
            val = self.to_str(val)
        if type(val) is not unicode:
            val = self.literal(val)
        return self.render(val, context, delimiters)
예제 #5
0
    def _render_value(self, val, context, delimiters=None, location=None):
        """
        Render an arbitrary value.

        """
        if not is_string(val):
            # In case the template is an integer, for example.
            val = str(val)
        if type(val) is not str:
            val = self.interpolate(val, 'literal', location)
        return self.render(val, context, delimiters)
예제 #6
0
    def _render_value(self, val, context, delimiters=None, location=None):
        """
        Render an arbitrary value.

        """
        if not is_string(val):
            # In case the template is an integer, for example.
            val = str(val)
        if type(val) is not str:
            val = self.interpolate(val, 'literal', location)
        return self.render(val, context, delimiters)
예제 #7
0
    def fetch_string(self, context, name):
        """
        Get a value from the given context as a basestring instance.

        """
        val = self.resolve_context(context, name)

        if callable(val):
            # Return because _render_value() is already a string.
            return self._render_value(val(), context)

        if not is_string(val):
            return self.to_str(val)

        return val
예제 #8
0
    def render(self, template, *context, **kwargs):
        """
        Render the given template string, view template, or parsed template.

        Returns a unicode string.

        Prior to rendering, this method will convert a template that is a
        byte string (type str in Python 2) to unicode using the string_encoding
        and decode_errors attributes.  See the constructor docstring for
        more information.

        Arguments:

          template: a template string that is unicode or a byte string,
            a ParsedTemplate instance, or another object instance.  In the
            final case, the function first looks for the template associated
            to the object by calling this class's get_associated_template()
            method.  The rendering process also uses the passed object as
            the first element of the context stack when rendering.

          *context: zero or more dictionaries, ContextStack instances, or objects
            with which to populate the initial context stack.  None
            arguments are skipped.  Items in the *context list are added to
            the context stack in order so that later items in the argument
            list take precedence over earlier items.

          **kwargs: additional key-value data to add to the context stack.
            As these arguments appear after all items in the *context list,
            in the case of key conflicts these values take precedence over
            all items in the *context list.

        """
        if is_string(template):
            return self._render_string(template, *context, **kwargs)
        if isinstance(template, ParsedTemplate):
            render_func = lambda engine, stack: template.render(engine, stack)
            return self._render_final(render_func, *context, **kwargs)
        # Otherwise, we assume the template is an object.

        return self._render_object(template, *context, **kwargs)