# How can fields appear conditionally upon presence of fields in biblatex-philosophy?

I am trying to match a bibliography style with biblatex-philosophy. The format for online resources are as follows:

Online with author: Online without author (same details for simplicity's sake):

By default, using this code (already with a couple of tweaks to formatting):

\documentclass[11pt, parskip=false]{scrartcl}

% Bibliography preamble
\usepackage[giveninits=true, style=philosophy-modern, yearleft=true, dateabbrev=false]{biblatex}

\DeclareFieldFormat[online]{title}{#1}

\renewcommand{\postsep}{% Add comma to end of author section
\null\par\nobreak\vskip\postnamesep%
\hskip-\bibhang\ignorespaces}

\DeclareFieldFormat{urldate}{% Reformats urldate field to read "accessed", replacing "(visted on)"
accessed %
\thefield{urlyear}\isdot}

\renewbibmacro*{url+urldate}{% Makes URL begin on a new line, adds comma after URL, before URLdate
\printunit{\newline}\usebibmacro{url}%
\iffieldundef{urlyear}
{}
\usebibmacro{urldate}}}

\begin{document}
Sentence containing citation \parencite{blogWithoutAuthor, blogWithAuthor}.

\printbibliography
\end{document}


With this .bib file:

@online{blogWithoutAuthor,
date = {2018},
title = {Historians in the News},
maintitle = {History Matters},
organization = {The University of Sydney},
url = {http://blogs.usyd.edu.au/historymatters/2018/02/historians_in_the_news_2018.html},
urldate = {2018-02-23}
}

@online{blogWithAuthor,
date = {2018},
title = {Historians in the News},
maintitle = {History Matters},
organization = {The University of Sydney},
url = {http://blogs.usyd.edu.au/historymatters/2018/02/historians_in_the_news_2018.html},
urldate = {2018-02-23},
author = {McDonnell, Mike}
}


Outputs this: As you can see, there is no website title (in addition to the page title) and by default the philosophy-modern settings replaces author with title when author is not present.

I added the following code to the above to make the field "maintitle" (serving as website title) recognisable to the online bibdriver, as well as cutting out the author field completely:

\usepackage{xpatch}% Modifies online bibdriver to remove author field, and add maintitle field after title
\xpatchbibdriver{online}
{\usebibmacro{author/editor+others/translator+others}%
\setunit{\labelnamepunct}\newblock
\usebibmacro{title}}
\setunit{\labelnamepunct}\newblock
\usebibmacro{title}%
\newunit\newblock
\usebibmacro{maintitle}%
\newunit}
{}
{\typeout{failed to remove author field, add maintitle field to driver for 'online'}}


Which outputs this:

Great, except obviously as I've removed the author macro from running, I don't get any author even when one is specified.

My question is, how do I run the xpatch snippet above conditionally, only when author is absent (undefined?), in order to match the required formatting?

I'm only still getting my head around xpatch command, so I doubt if my attempt is optimal anyway. Please let me know how the code could be improved.

• I don't think you can perform the patch conditionally to the presence of the field. But you can, of course, perform a patch which will result in a bibdriver which will take care of that. However, I'm not sure I understand what you want in this case. If you want to have the author information, why did you remove it in the patch? What exactly is the conditional you are trying to achieve? "if there is a (main)title, do not use author"? – gusbrs Feb 23 '18 at 1:00
• I removed author in the patch as an attempt to get the formatting I need straightened out, but it's only a preliminary attempt as author is still required. The philosophy-modern settings of biblatex-philosophy stores all the "author, line-break, year, tab" formatting in the author macro. The conditional I need would be something like, "if there is an author, don't change author formatting; if there is not an author, don't put title where author would be, keep title on same line as year" – anunlikelypseudonym Feb 23 '18 at 1:13
• There are much safer ways than your \DeclareFieldFormat{urldate} to change the format or the urldate. The default English localisation uses American-style dates, if you want Australian-style dates, load babel with australian. – moewe Feb 23 '18 at 7:52
• @moewe I don't doubt it - I'm really just hacking together what my understanding at this stage allows, which isn't exactly conducive to best practice. I'll play with the localisations to see if I can't create something more scalable. – anunlikelypseudonym Feb 23 '18 at 11:40
• See tex.stackexchange.com/q/129170/35864 and tex.stackexchange.com/q/141355/35864 for conceptually nicer (I would even say better) solutions. – moewe Feb 23 '18 at 11:46

I think I get what you mean. But, anyway, the way to proceed is not to "conditionally perform a patch" but rather "perform a patch with the conditional included".

If I get it correctly, this should work (notice I'm testing for the presence of either "author", "editor" or "translator", given the macro in question):

\documentclass[11pt, parskip=false]{scrartcl}

% Bibliography preamble
\usepackage[giveninits=true, style=philosophy-modern, yearleft=true, dateabbrev=false]{biblatex}

\DeclareFieldFormat[online]{title}{#1}

\renewcommand{\postsep}{% Add comma to end of author section
\null\par\nobreak\vskip\postnamesep%
\hskip-\bibhang\ignorespaces}

\DeclareFieldFormat{urldate}{% Reformats urldate field to read "accessed", replacing "(visted on)"
accessed %
\thefield{urlyear}\isdot}

\renewbibmacro*{url+urldate}{% Makes URL begin on a new line, adds comma after URL, before URLdate
\printunit{\newline}\usebibmacro{url}%
\iffieldundef{urlyear}
{}
\usebibmacro{urldate}}}

\usepackage{xpatch}% Modifies online bibdriver to remove author field, and add maintitle field after title

\xpatchbibdriver{online}
{\usebibmacro{author/editor+others/translator+others}%
\setunit{\labelnamepunct}\newblock
\usebibmacro{title}}
{\ifboolexpr{
test {\ifnameundef{author}}
and
test {\ifnameundef{editor}}
and
test {\ifnameundef{translator}}
}
{\usebibmacro{author/editor+others/translator+others}}%
\setunit{\labelnamepunct}\newblock
\usebibmacro{title}%
\newunit\newblock
\usebibmacro{maintitle}%
\newunit}
{}
{\typeout{failed to remove author field, add maintitle field to driver for 'online'}}

\begin{document}
Sentence containing citation \parencite{blogWithoutAuthor, blogWithAuthor}.

\printbibliography
\end{document}


• You nailed it. "perform a patch with the conditional included" is what I meant, but didn't express myself clearly. I had already tried \iffieldundef{author} alone where you have \ifboolexpr{...} but that didn't work. Thanks very much! – anunlikelypseudonym Feb 23 '18 at 1:31
• Glad to know. Just one more comment. \iffieldundef{author} would indeed not work, even if standing alone. Name fields must be tested with \ifnameundef. As list fields must be tested with \iflistundef. – gusbrs Feb 23 '18 at 1:34
• Ah, thanks for the tip - I had forgotten about the different data types of fields – anunlikelypseudonym Feb 23 '18 at 1:38

The title is used as a fallback in the author, editor and translation macros so that you never end up with an empty 'name heading' in case no name is given at all.

You could now suppress the execution of the name printing macro in case there is no name as shown in gusbrs' answer. But I prefer a different approach: Tell the name printing macros not to fall back on the title if there is no name. This can be done by redefining the author, bbx:editor and bbx:translator bibmacros.

\documentclass[australian, 11pt, parskip=false]{scrartcl}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[giveninits=true, style=philosophy-modern, yearleft=true, dateabbrev=false, urldate=comp, uniquename=init]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@online{blogWithoutAuthor,
date = {2018},
title = {Historians in the News},
maintitle = {History Matters},
organization = {The University of Sydney},
url = {http://blogs.usyd.edu.au/historymatters/2018/02/historians_in_the_news_2018.html},
urldate = {2018-02-23}
}

@online{blogWithAuthor,
date = {2018},
title = {Historians in the News},
maintitle = {History Matters},
organization = {The University of Sydney},
url = {http://blogs.usyd.edu.au/historymatters/2018/02/historians_in_the_news_2018.html},
urldate = {2018-02-23},
author = {McDonnell, Mike}
}
\end{filecontents}

\DeclareFieldFormat[online]{title}{#1}

\renewcommand{\postsep}{%
\null\par\nobreak\vskip\postnamesep
\hskip-\bibhang\ignorespaces}

\DefineBibliographyStrings{english}{
urlseen = {accessed},
}

\DeclareFieldFormat{urldate}{\bibstring{urlseen}\space#1}

\renewbibmacro*{url+urldate}{%
\printunit{\newline}\newblock
\usebibmacro{url}%
\iffieldundef{urlyear}
{}
\usebibmacro{urldate}}}

\makeatletter

\renewbibmacro*{author}{%
\ifboolexpr{
test \ifuseauthor
and
not test {\ifnameundef{author}}
}
{\usebibmacro{bbx:dashcheck}
{}%
{\usebibmacro{bbx:savehash}%
\printnames{author}%
{}%
\postsep}%
\iffieldundef{authortype}
{}%
{\usebibmacro{authorstrg}%
\printtext{\printdelim{nametitledelim}}}}%
{\global\undef\bbx@lasthash

\renewbibmacro*{bbx:editor}[1]{%
\ifboolexpr{%
test \ifuseeditor
and
not test {\ifnameundef{editor}}
}%
{\usebibmacro{bbx:dashcheck}%
{}%
{\printnames{editor}%
\postsep%
\usebibmacro{bbx:savehash}}%
\usebibmacro{#1}%
\clearname{editor}%
\printtext{\printdelim{nametitledelim}}}%
{\global\undef\bbx@lasthash

\renewbibmacro*{bbx:translator}[1]{%
\ifboolexpr{%
test \ifusetranslator
and
not test {\ifnameundef{translator}}
}%
{\usebibmacro{bbx:dashcheck}%
{}%
{\printnames{translator}%
\postsep%
\usebibmacro{bbx:savehash}}%
\usebibmacro{#1}%
\clearname{translator}%
\printtext{\printdelim{nametitledelim}}}%
{\global\undef\bbx@lasthash
\makeatother

\usepackage{xpatch}% Modifies online bibdriver to add maintitle field after title
\xpatchbibdriver{online}
{\usebibmacro{title}}
{\usebibmacro{title}%
\newunit\newblock
\usebibmacro{maintitle}}
{}
{\typeout{failed to add maintitle field to driver for 'online'}}

\begin{document}
Sentence containing citation \parencite{blogWithoutAuthor, blogWithAuthor, westfahl:frontier, westfahl:space}.

\printbibliography
\end{document}


Note how I got the Australian-style dates using babel with the global option australian and the biblatex option urldate=comp.

• @anunlikelypseudonym, You got here a better solution in every respect to your problem. I restrained myself to the problem as you posed it, within your own approach. moewe went further to what you were actually trying to achieve, and proposed a better way to do it. Not only that, you got full code review for your style tweaks! (moewe, +1, of course). – gusbrs Feb 23 '18 at 18:13