1.. currentmodule:: markupsafe
2
3String Formatting
4=================
5
6The :class:`Markup` class can be used as a format string. Objects
7formatted into a markup string will be escaped first.
8
9
10Format Method
11-------------
12
13The ``format`` method extends the standard :meth:`str.format` behavior
14to use an ``__html_format__`` method.
15
16#.  If an object has an ``__html_format__`` method, it is called as a
17    replacement for the ``__format__`` method. It is passed a format
18    specifier if it's given. The method must return a string or
19    :class:`Markup` instance.
20
21#.  If an object has an ``__html__`` method, it is called. If a format
22    specifier was passed and the class defined ``__html__`` but not
23    ``__html_format__``, a ``ValueError`` is raised.
24
25#.  Otherwise Python's default format behavior is used and the result
26    is escaped.
27
28For example, to implement a ``User`` that wraps its ``name`` in a
29``span`` tag, and adds a link when using the ``"link"`` format
30specifier:
31
32.. code-block:: python
33
34    class User(object):
35        def __init__(self, id, name):
36            self.id = id
37            self.name = name
38
39        def __html_format__(self, format_spec):
40            if format_spec == "link":
41                return Markup(
42                    '<a href="/user/{}">{}</a>'
43                ).format(self.id, self.__html__())
44            elif format_spec:
45                raise ValueError("Invalid format spec")
46            return self.__html__()
47
48        def __html__(self):
49            return Markup(
50                '<span class="user">{0}</span>'
51            ).format(self.name)
52
53
54.. code-block:: pycon
55
56    >>> user = User(3, "<script>")
57    >>> escape(user)
58    Markup('<span class="user">&lt;script&gt;</span>')
59    >>> Markup("<p>User: {user:link}").format(user=user)
60    Markup('<p>User: <a href="/user/3"><span class="user">&lt;script&gt;</span></a>
61
62See Python's docs on :ref:`format string syntax <python:formatstrings>`.
63
64
65printf-style Formatting
66-----------------------
67
68Besides escaping, there's no special behavior involved with percent
69formatting.
70
71.. code-block:: pycon
72
73    >>> user = User(3, "<script>")
74    >>> Markup('<a href="/user/%d">%s</a>') % (user.id, user.name)
75    Markup('<a href="/user/3">&lt;script&gt;</a>')
76
77See Python's docs on :ref:`printf-style formatting <python:old-string-formatting>`.
78