There are some commands in the LaTeX kernel that allow two or three optional arguments in a row:
\makebox[<length>][<alignment>]{<text>}
\parbox[<outer alignment>][<height>][<inner alignment>]{<width>}{<text>}
(note that minipage accepts the same arguments as \parbox, without the last one, of course). In both cases, the optional arguments after the first are meaningful only if the preceding one appears. For instance, the <alignment> option to \makebox makes sense only if a <width> has been specified. The case of \parbox is slightly different, but the first optional argument is used also for the third, if this is not specified; probably a better syntax would have been
\parbox[<outer alignment>]{<width>}[<height>][<inner alignment>]{<text>}
so as to never require an optional argument.
The \cite command of biblatex (together with variations thereof) accepts two optional arguments:
\cite[<postnote>]{<key>}
\cite[<prenote>][<postnote>]{<key>}
Here an empty <postnote> must be specified if only a <prenote> is wanted as in
\cite[See][]{mykey}
In amsref an alternative syntax was proposed: instead of \cite[<postnote>]{<key>}, for the typical case in which one wants
[3, Lemma 4]
traditionally input as \cite[Lemma~4]{mykey}, the package provides
\cite{mykey}*{Lemma~4}
I find this quite interesting, but it doesn't conform to the standard practices. Note that this would allow (but it doesn't, actually) a syntax such as
\cite[<prenote>]{key}*{<postnote>}
that would probably be even more readable.
Building a good user interface is not an easy task, as you see. But one has to think deeply whenever it appears that an optional argument becomes almost mandatory.
In these cases a good alternative is a key-value interface; the example of \parbox might be
\PARBOX[
outer=<character>,% c (default), t or b
inner=<character>,% default=outer, c, t, b or s
height=<length>,
]{<width>}{<text>}
and it would be easy to make the outer and inner options to accept also longer values such as top, bottom, center or spread.
A key-value interface should be preferred whenever the options are independent of each other.
This said, you can augment the facilities of xparse by defining a new “check command”
\ExplSyntaxOn
\DeclareExpandableDocumentCommand{\IfBlankTF}{mmm}
{
\tl_if_blank:nTF { #1 } { #2 } { #3 }
}
\ExplSyntaxOff
so that you can later define your command as
\NewDocumentCommand{\test}{o o}
{%
\IfNoValueTF{#1}
{%
Something for the case of no optional argument%
}%
{%
\IfNoValueTF{#2}
{%
Something with #1 for the case of just one optional argument%
}%
{%
\IfBlankTF{#1}
{%
Something with #2 for the case \string\test[][...]%
}%
{%
Something with #1 and #2%
}%
}%
}%
}
\tl_if_blank:nTFfor the test in the first case). Perhaps worth noting that for complex optional arguments, it's usually considered a good idea to consider a keyval interface. (Of course, that does depend on the real use case.) – Joseph Wright Jul 08 '14 at 06:06