Skip to content

Commit f391792

Browse files
Merge pull request #8381 from live627/feat/tpl
Add ability to add multiple sub-templates
2 parents 2536358 + f69a6d7 commit f391792

File tree

2 files changed

+68
-31
lines changed

2 files changed

+68
-31
lines changed

Sources/Theme.php

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -391,39 +391,82 @@ public static function loadTemplate(string|bool $template_name, array|string $st
391391
}
392392

393393
/**
394-
* Loads a sub-template.
394+
* Loads sub-templates into the current theme context.
395395
*
396-
* - Loads the sub template specified by sub_template_name, which must be
397-
* in an already-loaded template.
396+
* This method loads each sub-template in the `sub_templates` array. If it is
397+
* not defined, loads a single sub-template specified by `sub_template` or
398+
* falls back to loading the `main` template.
399+
*/
400+
public static function loadSubTemplates(): void
401+
{
402+
if (isset(Utils::$context['sub_templates'])) {
403+
foreach (Utils::$context['sub_templates'] as $sub_template) {
404+
self::loadSubTemplate($sub_template);
405+
}
406+
} else {
407+
self::loadSubTemplate(Utils::$context['sub_template'] ?? 'main');
408+
}
409+
}
410+
411+
/**
412+
* Loads a sub-template.
398413
*
399-
* - If ?debug is in the query string, shows administrators a marker after
400-
* every sub template for debugging purposes.
414+
* This function attempts to load and execute a sub-template by constructing its function name
415+
* and calling it dynamically. If the sub-template cannot be loaded, it handles errors based
416+
* on the `$fatal` parameter.
401417
*
402-
* @todo get rid of reading $_REQUEST directly
418+
* - Sub-template function names must follow the format `template_{name}`.
419+
* - When debugging is enabled, administrators can see markers after each loaded sub-template.
403420
*
404-
* @param string $sub_template_name The name of the sub-template to load
405-
* @param bool|string $fatal Whether to die with an error if the sub-template can't be loaded
421+
* @param string|array $sub_template_name The name of the sub-template to load.
422+
* If an array is provided, the first element is the name,
423+
* and the second element is an array of parameters to pass to the sub-template.
424+
* @param bool|string $fatal Specifies error handling behavior:
425+
* - `false` (default): Logs and handles the error.
426+
* - `true`: Dies with an error message.
427+
* - `'ignore'`: Silently ignore any errors.
406428
*/
407-
public static function loadSubTemplate(string $sub_template_name, bool|string $fatal = false): void
429+
public static function loadSubTemplate(string|array $sub_template_name, bool|string $fatal = false): void
408430
{
431+
$template_name = is_array($sub_template_name) ? $sub_template_name[0] : $sub_template_name;
432+
433+
// Add the sub-template to the debug context if debugging is enabled.
409434
if (!empty(Config::$db_show_debug)) {
410-
Utils::$context['debug']['sub_templates'][] = $sub_template_name;
435+
Utils::$context['debug']['sub_templates'][] = $template_name;
411436
}
412437

413-
// Figure out what the template function is named.
414-
$theme_function = 'template_' . $sub_template_name;
438+
// Determine the template function name and any associated parameters.
439+
if (is_array($sub_template_name)) {
440+
$theme_function = 'template_' . $sub_template_name[0];
441+
$function_params = $sub_template_name[1] ?? [];
442+
} else {
443+
$theme_function = 'template_' . $sub_template_name;
444+
$function_params = [];
445+
}
415446

416-
if (function_exists($theme_function)) {
417-
$theme_function();
418-
} elseif ($fatal === false) {
419-
ErrorHandler::fatalLang('theme_template_error', 'template', ['template_name' => (string) $sub_template_name, 'type' => 'sub']);
420-
} elseif ($fatal !== 'ignore') {
421-
die(ErrorHandler::log(Lang::formatText(Lang::$txt['theme_template_error'] ?? 'Unable to load the {template_name} sub-template.', ['template_name' => (string) $sub_template_name, 'type' => 'sub']), 'template'));
447+
// Attempt to call the sub-template function.
448+
if (is_callable($theme_function)) {
449+
call_user_func_array($theme_function, $function_params);
450+
} else {
451+
// Handle errors based on the $fatal parameter.
452+
if ($fatal === false) {
453+
ErrorHandler::fatalLang(
454+
'theme_template_error',
455+
'template',
456+
['template_name' => $template_name, 'type' => 'sub']
457+
);
458+
} elseif ($fatal !== 'ignore') {
459+
$error_message = Lang::formatText(
460+
Lang::$txt['theme_template_error'] ?? 'Unable to load the {template_name} sub-template.',
461+
['template_name' => $template_name, 'type' => 'sub']
462+
);
463+
die(ErrorHandler::log($error_message, 'template'));
464+
}
422465
}
423466

424-
// Are we showing debugging for templates? Just make sure not to do it before the doctype...
425-
if (isset(User::$me) && User::$me->allowedTo('admin_forum') && isset($_REQUEST['debug']) && !in_array($sub_template_name, ['init', 'main_below']) && ob_get_length() > 0 && !isset($_REQUEST['xml'])) {
426-
echo "\n" . '<div class="noticebox">---- ', $sub_template_name, ' ends ----</div>';
467+
// Show debug markers for administrators if enabled.
468+
if (isset(User::$me) && User::$me->allowedTo('admin_forum') && isset($_REQUEST['debug']) && !in_array($template_name, ['init', 'html_below']) && ob_get_length() > 0 && !isset($_REQUEST['xml'])) {
469+
echo "\n" . '<div class="noticebox">---- ', $template_name, ' ends ----</div>';
427470
}
428471
}
429472

@@ -1290,18 +1333,12 @@ public static function template_header(): void
12901333

12911334
header('content-type: text/' . (isset($_REQUEST['xml']) ? 'xml' : 'html') . '; charset=' . (empty(Utils::$context['character_set']) ? 'ISO-8859-1' : Utils::$context['character_set']));
12921335

1293-
// We need to splice this in after the body layer, or after the main layer for older stuff.
1336+
// We need to splice this in after the body layer.
12941337
if (Utils::$context['in_maintenance'] && User::$me->is_admin) {
12951338
$position = array_search('body', Utils::$context['template_layers']);
12961339

1297-
if ($position === false) {
1298-
$position = array_search('main', Utils::$context['template_layers']);
1299-
}
1300-
13011340
if ($position !== false) {
1302-
$before = array_slice(Utils::$context['template_layers'], 0, $position + 1);
1303-
$after = array_slice(Utils::$context['template_layers'], $position + 1);
1304-
Utils::$context['template_layers'] = array_merge($before, ['maint_warning'], $after);
1341+
array_splice(Utils::$context['template_layers'], $position + 1, 0, ['maint_warning']);
13051342
}
13061343
}
13071344

Sources/Utils.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,7 +2350,6 @@ public static function obExit(?bool $header = null, ?bool $do_footer = null, boo
23502350
],
23512351
);
23522352
}
2353-
23542353
}
23552354

23562355
// Start up the session URL fixer.
@@ -2388,7 +2387,7 @@ public static function obExit(?bool $header = null, ?bool $do_footer = null, boo
23882387
}
23892388

23902389
if ($do_footer) {
2391-
Theme::loadSubTemplate(Utils::$context['sub_template'] ?? 'main');
2390+
Theme::loadSubTemplates();
23922391

23932392
// Anything special to put out?
23942393
if (!empty(Utils::$context['insert_after_template']) && !isset($_REQUEST['xml'])) {
@@ -2400,6 +2399,7 @@ public static function obExit(?bool $header = null, ?bool $do_footer = null, boo
24002399
$footer_done = true;
24012400
Theme::template_footer();
24022401

2402+
// Add $db_show_debug = true; to Settings.php if you want to show the debugging information.
24032403
// (since this is just debugging... it's okay that it's after </html>.)
24042404
if (!isset($_REQUEST['xml'])) {
24052405
Logging::displayDebug();

0 commit comments

Comments
 (0)