def make_template(name, args, num_first=False):
    """Creates the wikitext for a template invocation.

    Parameters
    ----------
    name : str
        The name of the template to be invoked.
    args : OrderedDict, dict, list
        The arguments for the invocation. The keys for numbered parameters
        should be integers, not strings, while all other keys should be strings.
        If a dict, the order is not well-defined.
        If a list, every element should be a 2-tuple (key, value).
    num_first : bool, default: False
        Whether numbered parameters are first regardless of their order
        in args.

    Returns
    -------
    str
        The wikitext that invokes the template.
    """

    if isinstance(args, dict):
        args = list(args.items())

    if num_first:
        numargs = [
            v for k, v in sorted(args, key=lambda t: t[0]) if type(k) == int
        ]
        posargs, nonposargs = ["|" + x for x in numargs], []
        for key, value in args:
            if type(key) == str:
                nonposargs += "|" + key + "=" + str(value)
            elif type(key) == int:
                pass
            else:
                raise TypeError(f"invalid key type {type(key)}")
        return "{{" + name + "".join(posargs) + "".join(nonposargs) + "}}"
    else:
        argstr, argindx = "", 0
        pathological = False
        while True:
            for key, value in args:
                if type(key) == str:
                    argstr += "|" + key + "=" + str(value)
                elif type(key) == int:
                    if key > argindx:
                        argindx = key
                        argstr += "|" + str(value)
                    elif key < argindx:
                        pathological = True
                        argsorig = args
                        argsresolve = dict(args)
                        args = []
                        skip = 1
                        for key, value in argsorig:
                            if type(key) == str:
                                args.append((key, value))
                            elif type(key) == int:
                                if key <= skip:
                                    continue
                                for j in range(skip, key):
                                    args.append((j, argsresolve.get(j, "")))
                                args.append((key, value))
                                skip = key
                        break
            if pathological:
                pathological = False
                argstr = ""
                argindx = 0
                continue
            break
        return "{{" + name + argstr + "}}"