# Beamer theme pass options to inner/outer theme with pgfkeys

I want to design my own beamer theme and I have split the theme into inner and outer theme. The outer theme can take some options. So basically, I want to be able to write

\usetheme[some options]{MyFancyTheme}


in my LaTeX files. The main theme file should then load inner and outer themes and pass the options to theme. I think this is how the metropolis theme works. However, I can't get it work in my code with pgfkeys. Heres my attempt:

\documentclass{beamer}
\usepackage{filecontents}
%
% File B.sty
%
\begin{filecontents}{B.sty}
\ProvidesPackage{B}
\RequirePackage{pgfopts}
%
\pgfkeys{
/myPkg/B/.cd,
wB/.code={\setlength{\yyy}{#1}},
wB/.default={1cm}
}
\newlength{\yyy}
\ProcessPgfPackageOptions{/myPkg/B}
\useoutertheme[right, hideallsubsections, height=1cm, width=\yyy]{sidebar}
\end{filecontents}
%
% File A.sty (depends on B.sty)
%
\begin{filecontents}{A.sty}
\ProvidesPackage{A}
\RequirePackage{pgfopts}
%
\pgfkeys{
/myPkg/.cd,
.search also={/myPkg/B},
wA/.code={\setlength{\xxx}{#1}},
wA/.default={1cm}
}
\RequirePackage{B}
\newlength{\xxx}
\ProcessPgfPackageOptions{/myPkg}
%\useoutertheme[right, hideallsubsections, height=1cm, width=\xxx]{sidebar}
\end{filecontents}
%
\usepackage[wB=2cm]{A} % This is not working
% \usepackage[wB=2cm]{B} % This is working as expected
\usepackage{xcolor}
%
\setbeamercolor{sidebar right}{bg=green}
\begin{document}
\begin{frame}
X
\end{frame}
\end{document}


Loading B directly, works. I can control the width of the sidebar. Loading A (which then loads B) doesn't work. The option wB is simply ignored. So what do I have to change so that \usepackage[wB=2cm]{A} lets me change the width of the sidebar? The issue seems to be that options are not properly forwarded. It works if I set the outer theme in A.sty.

You could use beamer's mechanism to pass options on to outer/inner themes:

\documentclass{beamer}

\usepackage{filecontents}

%
% outer theme
%
\begin{filecontents*}{beamerouterthemeMyFancy.sty}
\DeclareOptionBeamer{wB}{\def\beamer@MyFancy@wB{#1}}
\ExecuteOptionsBeamer{wB=1cm} % default value
\ProcessOptionsBeamer
\useoutertheme[right, hideallsubsections, height=1cm, width=\beamer@MyFancy@wB]{sidebar}
\end{filecontents*}

%
% main theme
%
\begin{filecontents*}{beamerthemeMyFancy.sty}
\DeclareOptionBeamer{wB}{
\PassOptionsToPackage{wB=#1}{beamerouterthemeMyFancy}
}
\ProcessOptionsBeamer
\useoutertheme{MyFancy}
\end{filecontents*}

\usetheme[
wB=3cm
]{MyFancy}

\setbeamercolor{sidebar right}{bg=green}

\begin{document}
\begin{frame}
X
\end{frame}
\end{document}


I do not find it too surprising that your code does not work. All you do is to set a length. How would beamer know what to do with it. Of course, if you load the package, then the code runs through the corresponding instructions, that's why B works. To fix it, I'd propose to make the code really do the desired manipulations. I guess that @samcarter's answer is the more adequate way to go, though.

\documentclass{beamer}
\usepackage{filecontents}
%
% File B.sty
%
\begin{filecontents}{B.sty}
\ProvidesPackage{B}
\RequirePackage{pgfopts}
%
\pgfkeys{
/myPkg/B/.cd,
wB/.code={\useoutertheme[right, hideallsubsections, height=1cm, width=#1]{sidebar}},
wB/.default={1cm}
}
\ProcessPgfPackageOptions{/myPkg/B}

\end{filecontents}
%
% File A.sty (depends on B.sty)
%
\begin{filecontents}{A.sty}
\ProvidesPackage{A}
\RequirePackage{pgfopts}
%
\pgfkeys{
/myPkg/.cd,
.search also={/myPkg/B},
wA/.code={\useoutertheme[right, hideallsubsections, height=1cm, width=#1]{sidebar}},
wA/.default={1cm}
}
\RequirePackage{B}
\ProcessPgfPackageOptions{/myPkg}
%\useoutertheme[right, hideallsubsections, height=1cm, width=\xxx]{sidebar}
\end{filecontents}
%
\usepackage[wB=2cm]{A} % This is now working
% \usepackage[wB=2cm]{B} % This is working as expected
\usepackage{xcolor}
%
\setbeamercolor{sidebar right}{bg=green}
\begin{document}
\begin{frame}
X
\end{frame}
\end{document}