pass title and author to fancyhdr in class file

I am writing a class file that students will use for papers in one of my courses, and I am having trouble passing the title and author automatically to fancyhdr.

Here is a stripped down version of the class file:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{latex101}[]
\LoadClass{article}
\RequirePackage{fancyhdr}
\makeatletter
\let\runtitle\@title
\let\runauthor\@author
\makeatother
\AtBeginDocument{%
\lhead{\today}%
\chead{\runauthor}%
\rhead{\runtitle}%
\pagestyle{fancy}%
}
\endinput


When a student writes a paper, they set up their .tex file as follows:

\documentclass{latex101}
\title{My assignment}
\author{First Last}
\date{Semester Year}
\begin{document}
\maketitle
% content
\end{document}


However, this won't compile, throwing the error "No title given." If I remove the title from the header, the document compiles, but the header does not print the author.

Adding the header call to the preamble after \title{} and \author{} are specified works as expected, but I want the header to be defined in the class file, to avoid the possibility a student forgets to define the header in the preamble.

Any and all tips appreciated!

2 Answers

What is happening is that the assignment \let\runtitle\@title and \let\runauthor\@author are being done when the class is loaded, which is too early because the author will only use the commands after the class is loaded.

To work around this you can place the assignments inside the \AtBeginDocument:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{latex101}[]
\LoadClass{article}
\RequirePackage{fancyhdr}
\AtBeginDocument{%
\makeatletter
\let\runtitle\@title
\let\runauthor\@author
\makeatother
\lhead{\today}%
\chead{\runauthor}%
\rhead{\runtitle}%
\pagestyle{fancy}%
}
\endinput


But this still requires that \title{My assignment} is given before \begin{document}. My suggestion would be to patch \maketitle to avoid the redefinition of \@author and \@title:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{latex101}[]
\LoadClass{article}
\RequirePackage{etoolbox}
\makeatletter
\tracingpatches
\patchcmd\maketitle
{\global\let\@author\@empty
\global\let\@date\@empty
\global\let\@title\@empty}
{}{}{}
\RequirePackage{fancyhdr}
\AtBeginDocument{%
\lhead{\today}%
\chead{\@author}%
\rhead{\@title}%
\pagestyle{fancy}%
}
\makeatother
\endinput


@Phelype Oleinik's answer is good. The approach I took came from another post (https://stackoverflow.com/questions/2522173/how-to-get-the-value-of-the-document-title-in-latex). In the class file I redefined the title and author commands:

\def\title#1{\gdef\@title{#1}\gdef\runtitle{#1}}
\def\author#1{\gdef\@author{#1}\gdef\runauthor{#1}}


The class file now reads:

I am writing a class file that students will use for papers in one of my courses, and I am having trouble passing the title and author automatically to fancyhdr.

Here is a stripped down version of the class file:

\NeedsTeXFormat{LaTeX2e}
\ProvidesClass{latex101}[]
\LoadClass{article}
\RequirePackage{fancyhdr}
\makeatletter
\let\runtitle\@title
\let\runauthor\@author
\makeatother
\AtBeginDocument{%
\lhead{\today}%
\chead{\runauthor}%
\rhead{\runtitle}%
\pagestyle{fancy}%
}
\endinput