At the risk of getting voted down by everybody else here who thinks this is OK. I say: No, you shouldn't define functions in template files. This should be considered bad practice. Let's have a look at the documentation:
- Functions File Explained.
The functions file behaves like a WordPress Plugin, adding features
and functionality to a WordPress site. You can use it to call
functions, both PHP and built-in WordPress, and to define your own
functions. You can produce the same results by adding code to a
WordPress Plugin or through the WordPress Theme functions file.
The core of WordPress is designed to be lean and lightweight, to
maximize flexibility and minimize code bloat. Plugins then offer
custom functions and features so that each user can tailor their site
to their specific needs.
- Page Templates have the purpose to render your content – getting values, wrap them in markup, done. The maximum you'll find there are some simple conditions. And honestly, for the sake of any other developer who may have to overtake your project one day in the future that really should be the maximum. Don't tweak the functionality of your page inside template files itself. In my opinion they should be kept as untouched as possible.
What would happen if one future day you might want to switch your theme? Then it really gets difficult to find and grab custom stuff from various template files and put them in your new theme's templates. That's monkey work.
Same when you have to find that piece of code that is responsible for overriding certain output. It's really annoying to read through template files which are tweaked that way. Defining functions has places. But none of them should be a page template.
When I have to decide wether to tweak a template or not, I'ld ask myself:
- Is it on markup level? Then it's fine. For example if/else-wrapping the title in
FALSE. Or foreaching through posts to provide some extra wrappers. That would be done in a template file.
- But when it comes to advanced logic I'ld write a plugin or define some helper functions in functions.php. For example adding dynamic classes to some
<div> depending on the path. That would be a special function maybe
path_to_class() where the logic happens and then I'ld add that to the markup as
<div class="<?php print path_to_class(); ?>">.
- Yes, even checking for multiple or complex conditions as you suggested shouldn't be done in templates. Even for mere readability. That also should be a function defined somewhere else and finally simply called in a condition like
<?php if ( complex_condition() ) : ?><div ....
I'm a big fan of having readable and reusable plugins written and put on GitHub. There may be a future project where you need the same or similar stuff again. Then you simply pull the repo from GitHub, activate the plugin and move on. You also always have it as reference online. It's forkable, it's social, others can help you to improve your plugins and you can use it over and over again.