@petednz-fuzion pointed me in the right direction with this link:
cannot select profile for online event registration after upgrading civi on Joomla
So it turns out it was the theme after all. I am using Ambition from ThemeHorse and when I tried switching the theme to see if it was a theme problem, I should've picked a default theme to test; I did not.
The offending chunk of code was somewhere in here, in functions.php:
function ambition_load_files()
I basically took the same approach in the link from @petednz-fuzion to prevent loading the functions.php file. The problem is that if the theme's functions.php isn't loaded on front-end pages where CiviCRM data is displayed (like on an event page) then the page doesn't load. So I prevented the functions.php file from loading only on backend pages like this:
function ambition_load_files()
{
/**
* ambition_add_files hook
*
* Adding other addtional files if needed.
*/
do_action('ambition_add_files');
/** Load functions */
require_once (AMBITION_FUNCTIONS_DIR . '/i18n.php');
require_once (AMBITION_FUNCTIONS_DIR . '/custom-header.php');
require_once (AMBITION_FUNCTIONS_DIR . '/featured-content.php');
require_once (AMBITION_ADMIN_DIR . '/ambition-metaboxes.php');
require_once (AMBITION_FUNCTIONS_DIR . '/custom-style.php');
require_once (AMBITION_FUNCTIONS_DIR . '/customizer.php');
/** Load Footer Info */
require_once (AMBITION_SHORTCODES_DIR . '/ambition-footer-info.php');
/** Load Structure */
require_once (AMBITION_STRUCTURE_DIR . '/header-extensions.php');
require_once (AMBITION_STRUCTURE_DIR . '/footer-extensions.php');
require_once (AMBITION_STRUCTURE_DIR . '/content-extensions.php');
/** Load Widgets and Widgetized Area */
require_once (AMBITION_WIDGETS_DIR . '/ambition-widgets.php');
// ==========================================================================
// We don't load functions.php if we're in the backend or else CiviCRM breaks
$full_url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$uri = (parse_url($full_url, PHP_URL_PATH));
if($uri == '/wp-admin/admin.php') {
; // don't include
} else {
require_once (AMBITION_FUNCTIONS_DIR . '/functions.php');
}
// ==========================================================================
}
Now it's working like a charm.
Thanks everyone for your help!