elkarte /
Elkarte
| 1 | <?php |
||||
| 2 | |||||
| 3 | /** |
||||
| 4 | * @package ElkArte Forum |
||||
| 5 | * @copyright ElkArte Forum contributors |
||||
| 6 | * @license BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file) |
||||
| 7 | * |
||||
| 8 | * This file contains code covered by: |
||||
| 9 | * copyright: 2011 Simple Machines (http://www.simplemachines.org) |
||||
| 10 | * |
||||
| 11 | * @version 2.0 dev |
||||
| 12 | * |
||||
| 13 | */ |
||||
| 14 | |||||
| 15 | /** |
||||
| 16 | * This template is, perhaps, the most important template in the theme. It |
||||
| 17 | * contains the main template layer that displays the header and footer of |
||||
| 18 | * the forum, namely with body_above and body_below. It also contains the |
||||
| 19 | * menu sub template, which appropriately displays the menu; the init sub |
||||
| 20 | * template, which is there to set the theme up; (init can be missing.) and |
||||
| 21 | * the breadcrumb sub template, which sorts out the breadcrumbs. |
||||
| 22 | * |
||||
| 23 | * The init sub template should load any data and set any hardcoded options. |
||||
| 24 | * |
||||
| 25 | * The body_above sub template is what is shown above the main content, and |
||||
| 26 | * should contain anything that should be shown up there. |
||||
| 27 | * |
||||
| 28 | * The body_below sub template, conversely, is shown after the main content. |
||||
| 29 | * It should probably contain the copyright statement and some other things. |
||||
| 30 | * |
||||
| 31 | * The breadcrumb sub template should display the breadcrumbs, using the data |
||||
| 32 | * in the $context['breadcrumbs'] variable. |
||||
| 33 | * |
||||
| 34 | * The menu sub template should display all the relevant buttons the user |
||||
| 35 | * wants and or needs. |
||||
| 36 | */ |
||||
| 37 | |||||
| 38 | /** |
||||
| 39 | * Start off the template by loading some helpers like |
||||
| 40 | * quick buttons, page index, etc |
||||
| 41 | */ |
||||
| 42 | function template_Index_init() |
||||
| 43 | { |
||||
| 44 | theme()->getTemplates()->load('GenericHelpers'); |
||||
| 45 | } |
||||
| 46 | |||||
| 47 | /** |
||||
| 48 | * Simplify the use of callbacks in the templates. |
||||
| 49 | * |
||||
| 50 | * @param string $id - A prefix for the template functions the final name |
||||
| 51 | * should look like: template_{$id}_{$array[n]} |
||||
| 52 | * @param string[] $array - The array of function suffixes |
||||
| 53 | */ |
||||
| 54 | function call_template_callbacks($id, $array) |
||||
| 55 | { |
||||
| 56 | if (empty($array)) |
||||
| 57 | { |
||||
| 58 | return; |
||||
| 59 | } |
||||
| 60 | |||||
| 61 | foreach ($array as $callback) |
||||
| 62 | { |
||||
| 63 | $func = 'template_' . $id . '_' . $callback; |
||||
| 64 | if (function_exists($func)) |
||||
| 65 | { |
||||
| 66 | $func(); |
||||
| 67 | } |
||||
| 68 | } |
||||
| 69 | } |
||||
| 70 | |||||
| 71 | /** |
||||
| 72 | * The main sub template above the content. |
||||
| 73 | */ |
||||
| 74 | function template_html_above() |
||||
| 75 | { |
||||
| 76 | global $context, $scripturl, $txt; |
||||
| 77 | |||||
| 78 | // Show right to left and the character set for ease of translating. |
||||
| 79 | echo '<!DOCTYPE html> |
||||
| 80 | <html dir=', $context['right_to_left'] ? ' "RTL"' : 'LTR', ' lang="', str_replace('_', '-', $txt['lang_locale']), '"> |
||||
| 81 | <head> |
||||
| 82 | <title>', $context['page_title_html_safe'], '</title> |
||||
| 83 | <meta charset="utf-8" />'; |
||||
| 84 | |||||
| 85 | $description = $context['page_title_html_safe']; |
||||
| 86 | if (isset($context['page_description'])) |
||||
| 87 | { |
||||
| 88 | $description .= ': ' . $context['page_description']; |
||||
| 89 | } |
||||
| 90 | |||||
| 91 | echo ' |
||||
| 92 | <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> |
||||
| 93 | <meta name="mobile-web-app-capable" content="yes" /> |
||||
| 94 | <meta name="description" content="', $description, '" /> |
||||
| 95 | <meta name="theme-color" content="', $context['theme-color'], '" />'; |
||||
| 96 | |||||
| 97 | // Please don't index these Mr Robot. |
||||
| 98 | if (!empty($context['robot_no_index'])) |
||||
| 99 | { |
||||
| 100 | echo ' |
||||
| 101 | <meta name="robots" content="noindex" />'; |
||||
| 102 | } |
||||
| 103 | |||||
| 104 | // If we have any Open Graph data, here is where is inserted. |
||||
| 105 | if (!empty($context['open_graph'])) |
||||
| 106 | { |
||||
| 107 | echo ' |
||||
| 108 | ' .implode("\n\t", $context['open_graph']); |
||||
| 109 | } |
||||
| 110 | |||||
| 111 | // Present a canonical url for search engines to prevent duplicate content in their indices. |
||||
| 112 | if (!empty($context['canonical_url'])) |
||||
| 113 | { |
||||
| 114 | echo ' |
||||
| 115 | <link rel="canonical" href="', $context['canonical_url'], '" />'; |
||||
| 116 | } |
||||
| 117 | |||||
| 118 | // Various icons and optionally a PWA manifest |
||||
| 119 | echo ' |
||||
| 120 | <link rel="icon" sizes="any" href="' . $context['favicon'] . '" /> |
||||
| 121 | <link rel="apple-touch-icon" href="' . $context['apple_touch'] . '" />'; |
||||
| 122 | |||||
| 123 | // Personal Web Application Manifest |
||||
| 124 | if (!empty($context['pwa_manifest_enabled'])) |
||||
| 125 | { |
||||
| 126 | echo ' |
||||
| 127 | <link rel="manifest" href="./elkManifest.php">'; |
||||
| 128 | } |
||||
| 129 | |||||
| 130 | // Show all the relative links, such as help, search, contents, and the like. |
||||
| 131 | echo ' |
||||
| 132 | <link rel="help" href="', getUrl('action', ['action' => 'help']), '" /> |
||||
| 133 | <link rel="contents" href="', $scripturl, '" />', ($context['allow_search'] ? ' |
||||
| 134 | <link rel="search" href="' . getUrl('action', ['action' => 'search']) . '" />' : ''); |
||||
| 135 | |||||
| 136 | // If RSS feeds are enabled, advertise the presence of one. |
||||
| 137 | if (!empty($context['newsfeed_urls'])) |
||||
| 138 | { |
||||
| 139 | echo ' |
||||
| 140 | <link rel="alternate" type="application/rss+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['rss'], '" href="', $context['newsfeed_urls']['rss'], '" /> |
||||
| 141 | <link rel="alternate" type="application/rss+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['atom'], '" href="', $context['newsfeed_urls']['atom'], '" />'; |
||||
| 142 | } |
||||
| 143 | |||||
| 144 | // If we're viewing a topic, these should be the previous and next topics, respectively. |
||||
| 145 | if (!empty($context['links']['next'])) |
||||
| 146 | { |
||||
| 147 | echo ' |
||||
| 148 | <link rel="next" href="', $context['links']['next'], '" />'; |
||||
| 149 | } |
||||
| 150 | elseif (!empty($context['current_topic'])) |
||||
| 151 | { |
||||
| 152 | echo ' |
||||
| 153 | <link rel="next" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=next" />'; |
||||
| 154 | } |
||||
| 155 | |||||
| 156 | if (!empty($context['links']['prev'])) |
||||
| 157 | { |
||||
| 158 | echo ' |
||||
| 159 | <link rel="prev" href="', $context['links']['prev'], '" />'; |
||||
| 160 | } |
||||
| 161 | elseif (!empty($context['current_topic'])) |
||||
| 162 | { |
||||
| 163 | echo ' |
||||
| 164 | <link rel="prev" href="', $scripturl, '?topic=', $context['current_topic'], '.0;prev_next=prev" />'; |
||||
| 165 | } |
||||
| 166 | |||||
| 167 | // If we're in a board, or a topic for that matter, the index will be the board's index. |
||||
| 168 | if (!empty($context['current_board'])) |
||||
| 169 | { |
||||
| 170 | echo ' |
||||
| 171 | <link rel="index" href="', $scripturl, '?board=', $context['current_board'], '.0" />'; |
||||
| 172 | } |
||||
| 173 | |||||
| 174 | // load in CSS from addons or themes, do it first so overrides are possible |
||||
| 175 | theme()->themeCss()->template_css(); |
||||
| 176 | |||||
| 177 | // load in any JavaScript files and inline from addons and themes |
||||
| 178 | theme()->themeJs()->template_javascript(); |
||||
| 179 | |||||
| 180 | // load in any inline CSS files from addons and themes |
||||
| 181 | theme()->themeCss()->template_inlinecss(); |
||||
| 182 | |||||
| 183 | // Output any remaining HTML headers. (from addons, maybe?) |
||||
| 184 | echo $context['html_headers']; |
||||
| 185 | |||||
| 186 | echo ' |
||||
| 187 | </head>'; |
||||
| 188 | |||||
| 189 | // Start defining the body class |
||||
| 190 | $bodyClass = 'action_'; |
||||
| 191 | |||||
| 192 | if (!empty($context['current_action'])) |
||||
| 193 | { |
||||
| 194 | $bodyClass .= htmlspecialchars($context['current_action'], ENT_COMPAT, 'UTF-8'); |
||||
| 195 | } |
||||
| 196 | elseif (!empty($context['current_board'])) |
||||
| 197 | { |
||||
| 198 | $bodyClass .= 'messageindex'; |
||||
| 199 | } |
||||
| 200 | elseif (!empty($context['current_topic'])) |
||||
| 201 | { |
||||
| 202 | $bodyClass .= 'display'; |
||||
| 203 | } |
||||
| 204 | else |
||||
| 205 | { |
||||
| 206 | $bodyClass .= 'home'; |
||||
| 207 | } |
||||
| 208 | |||||
| 209 | if (!empty($context['current_board'])) |
||||
| 210 | { |
||||
| 211 | $bodyClass .= ' board_' . htmlspecialchars($context['current_board'], ENT_COMPAT, 'UTF-8'); |
||||
| 212 | } |
||||
| 213 | |||||
| 214 | echo ' |
||||
| 215 | <body class="', $bodyClass . '">'; |
||||
| 216 | } |
||||
| 217 | |||||
| 218 | /** |
||||
| 219 | * Section above the main contents of the page, after opening the body tag |
||||
| 220 | */ |
||||
| 221 | function template_body_above() |
||||
| 222 | { |
||||
| 223 | global $context, $settings, $txt; |
||||
| 224 | |||||
| 225 | // Go to top/bottom of page links and skipnav link for a11y. |
||||
| 226 | echo ' |
||||
| 227 | <a id="top" href="#skipnav" tabindex="0">', $txt['skip_nav'], '</a> |
||||
| 228 | <a id="gotop" href="#top_section" title="', $txt['go_up'], '">↑</a> |
||||
| 229 | <a id="gobottom" href="#footer_section" title="', $txt['go_down'], '">↓</a>'; |
||||
| 230 | |||||
| 231 | echo ' |
||||
| 232 | <header id="top_section" class="', (empty($context['minmax_preferences']['upshrink']) ? 'th_expand' : 'th_collapse'), '"> |
||||
| 233 | <aside id="top_header" class="wrapper">'; |
||||
| 234 | |||||
| 235 | // Load in all register header templates |
||||
| 236 | call_template_callbacks('th', $context['theme_header_callbacks']); |
||||
| 237 | |||||
| 238 | echo ' |
||||
| 239 | </aside> |
||||
| 240 | <section id="header" class="wrapper', empty($settings['header_layout']) ? '' : ($settings['header_layout'] == 1 ? ' centerheader' : ' rightheader'), empty($context['minmax_preferences']['upshrink']) ? '"' : ' hide" aria-hidden="true"', '> |
||||
| 241 | <h1 id="forumtitle"> |
||||
| 242 | <a class="forumlink" href="', getUrl('boardindex', []), '">', $context['forum_name'], '</a>'; |
||||
| 243 | |||||
| 244 | echo ' |
||||
| 245 | <span id="logobox"> |
||||
| 246 | <img id="logo" src="', $context['header_logo_url_html_safe'], '" alt="', $context['forum_name_html_safe'], '" title="', $context['forum_name_html_safe'], '" />', empty($settings['site_slogan']) ? '' : ' |
||||
| 247 | <span id="siteslogan">' . $settings['site_slogan'] . '</span>', ' |
||||
| 248 | </span> |
||||
| 249 | </h1>'; |
||||
| 250 | |||||
| 251 | // Show the menu here, according to the menu sub template. |
||||
| 252 | echo ' |
||||
| 253 | </section>'; |
||||
| 254 | |||||
| 255 | template_menu(); |
||||
| 256 | |||||
| 257 | echo ' |
||||
| 258 | </header> |
||||
| 259 | <div id="wrapper" class="wrapper"> |
||||
| 260 | <aside id="upper_section"', empty($context['minmax_preferences']['upshrink']) ? '' : ' class="hide" aria-hidden="true"', '>'; |
||||
| 261 | |||||
| 262 | // Load in all registered upper content templates |
||||
| 263 | call_template_callbacks('uc', $context['upper_content_callbacks']); |
||||
| 264 | |||||
| 265 | echo ' |
||||
| 266 | </aside>'; |
||||
| 267 | |||||
| 268 | // Show the navigation tree. |
||||
| 269 | theme_breadcrumbs(); |
||||
| 270 | |||||
| 271 | // The main content should go here. |
||||
| 272 | echo ' |
||||
| 273 | <div id="main_content_section"> |
||||
| 274 | <a id="skipnav"></a>'; |
||||
| 275 | } |
||||
| 276 | |||||
| 277 | /** |
||||
| 278 | * More or less a place holder for now, sits at the very page top. |
||||
| 279 | * The maintenance mode warning for admins is an obvious one, but this could also be used for moderation notifications. |
||||
| 280 | * I also assumed this would be an obvious place for sites to put a string of icons to link to their FB, Twitter, etc. |
||||
| 281 | * This could still be done via conditional, so that administration and moderation notices were still active when |
||||
| 282 | * applicable. |
||||
| 283 | */ |
||||
| 284 | function template_th_header_bar() |
||||
| 285 | { |
||||
| 286 | global $context, $txt, $scripturl; |
||||
| 287 | |||||
| 288 | echo ' |
||||
| 289 | <div id="top_section_notice" class="user', (empty($context['minmax_preferences']['upshrink']) ? '' : ' hide'), '"> |
||||
| 290 | </div>'; |
||||
| 291 | } |
||||
| 292 | |||||
| 293 | /** |
||||
| 294 | * Search bar form, expands to input form when search icon is clicked |
||||
| 295 | */ |
||||
| 296 | function template_search_form() |
||||
| 297 | { |
||||
| 298 | global $context, $modSettings, $txt; |
||||
| 299 | |||||
| 300 | echo ' |
||||
| 301 | <form id="search_form_menu" action="', getUrl('action', ['action' => 'search', 'sa' => 'results']), '" method="post" role="search" accept-charset="UTF-8">'; |
||||
| 302 | |||||
| 303 | // Using the quick search dropdown? |
||||
| 304 | if (!empty($modSettings['search_dropdown'])) |
||||
| 305 | { |
||||
| 306 | $selected = empty($context['current_topic']) ? (!empty($context['current_board']) ? 'current_board' : 'all') : ('current_topic'); |
||||
| 307 | echo ' |
||||
| 308 | <label for="search_selection"> |
||||
| 309 | <select name="search_selection" id="search_selection" class="linklevel1" aria-label="search selection"> |
||||
| 310 | <option value="all"', ($selected === 'all' ? ' selected="selected"' : ''), '>', $txt['search_entireforum'], ' </option>'; |
||||
| 311 | |||||
| 312 | // Can't limit it to a specific topic if we are not in one |
||||
| 313 | if (!empty($context['current_topic'])) |
||||
| 314 | { |
||||
| 315 | echo ' |
||||
| 316 | <option value="topic"', ($selected === 'current_topic' ? ' selected="selected"' : ''), '>', $txt['search_thistopic'], '</option>'; |
||||
| 317 | } |
||||
| 318 | |||||
| 319 | // Can't limit it to a specific board if we are not in one |
||||
| 320 | if (!empty($context['current_board'])) |
||||
| 321 | { |
||||
| 322 | echo ' |
||||
| 323 | <option value="board"', ($selected === 'current_board' ? ' selected="selected"' : ''), '>', $txt['search_thisbrd'], '</option>'; |
||||
| 324 | } |
||||
| 325 | |||||
| 326 | if (!empty($context['additional_dropdown_search'])) |
||||
| 327 | { |
||||
| 328 | foreach ($context['additional_dropdown_search'] as $name => $engine) |
||||
| 329 | { |
||||
| 330 | echo ' |
||||
| 331 | <option value="', $name, '">', $engine['name'], '</option>'; |
||||
| 332 | } |
||||
| 333 | } |
||||
| 334 | |||||
| 335 | echo ' |
||||
| 336 | <option value="members"', ($selected === 'members' ? ' selected="selected"' : ''), '>', $txt['search_members'], ' </option> |
||||
| 337 | </select> |
||||
| 338 | </label>'; |
||||
| 339 | } |
||||
| 340 | |||||
| 341 | // Search within current topic? |
||||
| 342 | if (!empty($context['current_topic'])) |
||||
| 343 | { |
||||
| 344 | echo ' |
||||
| 345 | <input type="hidden" name="', (empty($modSettings['search_dropdown']) ? 'topic' : 'sd_topic'), '" value="', $context['current_topic'], '" />'; |
||||
| 346 | } |
||||
| 347 | |||||
| 348 | // If we're on a certain board, limit it to this board ;). |
||||
| 349 | if (!empty($context['current_board'])) |
||||
| 350 | { |
||||
| 351 | echo ' |
||||
| 352 | <input type="hidden" name="', (empty($modSettings['search_dropdown']) ? 'brd[' : 'sd_brd['), $context['current_board'], ']"', ' value="', $context['current_board'], '" />'; |
||||
| 353 | } |
||||
| 354 | |||||
| 355 | echo ' |
||||
| 356 | <label for="quicksearch" class="hide">', $txt['search'], '</label> |
||||
| 357 | <input type="search" name="search" id="quicksearch" value="" class="linklevel1" placeholder="', $txt['search'], '" /> |
||||
| 358 | <button type="submit" aria-label="' . $txt['search'] . '" name="search;sa=results" class="', (empty($modSettings['search_dropdown'])) ? '' : 'with_select', '"> |
||||
| 359 | <i class="icon i-search"><s>', $txt['search'], '</s></i> |
||||
| 360 | </button> |
||||
| 361 | <button type="button" aria-label="' . $txt['find_close'] . '"> |
||||
| 362 | <label for="search_form_check"> |
||||
| 363 | <i class="icon i-close"><s>', $txt['find_close'], '</s></i> |
||||
| 364 | </label> |
||||
| 365 | </button> |
||||
| 366 | <input type="hidden" name="advanced" value="0" /> |
||||
| 367 | </form>'; |
||||
| 368 | } |
||||
| 369 | |||||
| 370 | /** |
||||
| 371 | * Search bar main menu icon |
||||
| 372 | */ |
||||
| 373 | function template_mb_search_bar() |
||||
| 374 | { |
||||
| 375 | global $txt; |
||||
| 376 | |||||
| 377 | echo ' |
||||
| 378 | <li id="search_form_button" class="listlevel1" role="none"> |
||||
| 379 | <label for="search_form_check"> |
||||
| 380 | <a class="linklevel1 panel_search" role="menuitem"> |
||||
| 381 | <i class="main-menu-icon i-search colorize-white"><s>', $txt['search'], '</s></i> |
||||
| 382 | </a> |
||||
| 383 | </label> |
||||
| 384 | </li>'; |
||||
| 385 | } |
||||
| 386 | |||||
| 387 | /** |
||||
| 388 | * The news fader wrapped in a div and with "news" text |
||||
| 389 | */ |
||||
| 390 | function template_uc_news_fader() |
||||
| 391 | { |
||||
| 392 | global $settings, $context, $txt; |
||||
| 393 | |||||
| 394 | // Display either news fader and random news lines (not both). These now run most of the same mark up and CSS. Less complication = happier n00bz. :) |
||||
| 395 | if (!empty($settings['enable_news']) && !empty($context['random_news_line'])) |
||||
| 396 | { |
||||
| 397 | echo ' |
||||
| 398 | <div id="news"> |
||||
| 399 | <h2>', $txt['news'], '</h2>'; |
||||
| 400 | |||||
| 401 | template_news_fader(); |
||||
| 402 | |||||
| 403 | echo ' |
||||
| 404 | </div>'; |
||||
| 405 | } |
||||
| 406 | } |
||||
| 407 | |||||
| 408 | /** |
||||
| 409 | * Section down the page, before closing body |
||||
| 410 | */ |
||||
| 411 | function template_body_below() |
||||
| 412 | { |
||||
| 413 | global $context, $txt; |
||||
| 414 | |||||
| 415 | echo ' |
||||
| 416 | </div> |
||||
| 417 | </div>'; |
||||
| 418 | |||||
| 419 | // Show RSS link, as well as the copyright. |
||||
| 420 | // Footer is full-width. Wrapper inside automatically matches admin width setting. |
||||
| 421 | echo ' |
||||
| 422 | <footer id="footer_section"> |
||||
| 423 | <div class="wrapper"> |
||||
| 424 | <ul> |
||||
| 425 | <li class="copyright">', |
||||
| 426 | theme_copyright(), ' |
||||
|
0 ignored issues
–
show
Are you sure
theme_copyright() of type void can be used in echo?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 427 | </li>', |
||||
| 428 | empty($context['newsfeed_urls']['rss']) ? '' : ' |
||||
| 429 | <li> |
||||
| 430 | <a id="button_rss" href="' . $context['newsfeed_urls']['rss'] . '" class="rssfeeds new_win"> |
||||
| 431 | <i class="icon icon-margin i-rss icon-big"><s>' . $txt['rss'] . '</s></i> |
||||
| 432 | </a> |
||||
| 433 | </li>', ' |
||||
| 434 | </ul>'; |
||||
| 435 | |||||
| 436 | // Show the load time? |
||||
| 437 | if ($context['show_load_time']) |
||||
| 438 | { |
||||
| 439 | echo ' |
||||
| 440 | <p>', sprintf($txt['page_created_full'], $context['load_time'], $context['load_queries']), '</p>'; |
||||
| 441 | } |
||||
| 442 | } |
||||
| 443 | |||||
| 444 | /** |
||||
| 445 | * Section down the page, at closing html tag |
||||
| 446 | */ |
||||
| 447 | function template_html_below() |
||||
| 448 | { |
||||
| 449 | global $context; |
||||
| 450 | |||||
| 451 | echo ' |
||||
| 452 | </div> |
||||
| 453 | </footer>'; |
||||
| 454 | |||||
| 455 | // This is here to catch any late loading of JS files via templates |
||||
| 456 | theme()->themeJs()->outputJavascriptFiles(theme()->themeJs()->getJSFiles()); |
||||
| 457 | |||||
| 458 | // load inline javascript that needed to be deferred to the end of the page |
||||
| 459 | theme()->themeJs()->template_inline_javascript(true); |
||||
| 460 | |||||
| 461 | // Schema microdata about the organization? |
||||
| 462 | if (!empty($context['smd_site'])) |
||||
| 463 | { |
||||
| 464 | echo ' |
||||
| 465 | <script type="application/ld+json"> |
||||
| 466 | ', json_encode($context['smd_site'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), ' |
||||
| 467 | </script>'; |
||||
| 468 | } |
||||
| 469 | |||||
| 470 | // Schema microdata about the post? |
||||
| 471 | if (!empty($context['smd_article'])) |
||||
| 472 | { |
||||
| 473 | echo ' |
||||
| 474 | <script type="application/ld+json"> |
||||
| 475 | ', json_encode($context['smd_article'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), ' |
||||
| 476 | </script>'; |
||||
| 477 | } |
||||
| 478 | |||||
| 479 | // Anything special to put out? |
||||
| 480 | if (!empty($context['insert_after_template'])) |
||||
| 481 | { |
||||
| 482 | echo $context['insert_after_template']; |
||||
| 483 | } |
||||
| 484 | |||||
| 485 | echo ' |
||||
| 486 | </body> |
||||
| 487 | </html>'; |
||||
| 488 | } |
||||
| 489 | |||||
| 490 | /** |
||||
| 491 | * Show breadcrumbs. This is that thing that shows |
||||
| 492 | * "My Community | General Category | General Discussion".. |
||||
| 493 | * |
||||
| 494 | * @param string $default a string representing the index in $context where |
||||
| 495 | * the breadcrumbs are stored (default value is 'breadcrumbs') |
||||
| 496 | */ |
||||
| 497 | function theme_breadcrumbs($default = 'breadcrumbs') |
||||
| 498 | { |
||||
| 499 | global $context, $settings, $txt; |
||||
| 500 | |||||
| 501 | // If breadcrumbs is empty, just return - also allow an override. |
||||
| 502 | if (empty($context[$default])) |
||||
| 503 | { |
||||
| 504 | return; |
||||
| 505 | } |
||||
| 506 | |||||
| 507 | echo ' |
||||
| 508 | <nav class="breadcrumb" aria-label="breadcrumbs">'; |
||||
| 509 | |||||
| 510 | // Each tree item has a URL and name. Some may have extra_before and extra_after. |
||||
| 511 | // Added a crumb class to make targeting dividers easy. |
||||
| 512 | foreach ($context[$default] as $pos => $tree) |
||||
| 513 | { |
||||
| 514 | $tree['name'] = ($tree['extra_before'] ?? '') . $tree['name'] . ($tree['extra_after'] ?? ''); |
||||
| 515 | |||||
| 516 | // Show the link, including a URL if it should have one. |
||||
| 517 | echo isset($tree['url']) |
||||
| 518 | ? ' |
||||
| 519 | <span class="crumb"> |
||||
| 520 | <a href="' . $tree['url'] . '">' . |
||||
| 521 | ($pos === 0 |
||||
| 522 | ? '<i class="icon i-home"><s>' . $txt['home'] . '</s></i>' |
||||
| 523 | : $tree['name']) . ' |
||||
| 524 | </a> |
||||
| 525 | </span>' |
||||
| 526 | : ' |
||||
| 527 | <span class="crumb"> |
||||
| 528 | ' . $tree['name'] . ' |
||||
| 529 | </span>'; |
||||
| 530 | } |
||||
| 531 | |||||
| 532 | echo ' |
||||
| 533 | </nav>'; |
||||
| 534 | } |
||||
| 535 | |||||
| 536 | /** |
||||
| 537 | * Show the menu up top. Something like [home] [help] [profile] [logout]... |
||||
| 538 | */ |
||||
| 539 | function template_menu() |
||||
| 540 | { |
||||
| 541 | global $context, $txt; |
||||
| 542 | |||||
| 543 | // WAI-ARIA a11y tweaks have been applied here. |
||||
| 544 | echo ' |
||||
| 545 | <nav id="menu_nav" aria-label="', $txt['main_menu'], '"> |
||||
| 546 | <div class="wrapper no_js"> |
||||
| 547 | <input type="checkbox" id="search_form_check" aria-hidden="true" /> |
||||
| 548 | <ul id="main_menu" aria-label="', $txt['main_menu'], '" role="menubar">'; |
||||
| 549 | |||||
| 550 | // Add any additional menu buttons from addons |
||||
| 551 | call_template_callbacks('mb', $context['theme_header_callbacks']); |
||||
| 552 | |||||
| 553 | // This defines the start of right-aligned buttons, set your button order > 10 |
||||
| 554 | echo ' |
||||
| 555 | <li id="button_none" class="listlevel1" role="none"> |
||||
| 556 | <a role="none"></a> |
||||
| 557 | </li>'; |
||||
| 558 | |||||
| 559 | // The upshrink image. |
||||
| 560 | echo ' |
||||
| 561 | <li id="collapse_button" class="listlevel1" role="none"> |
||||
| 562 | <a class="linklevel1 panel_toggle" role="menuitem"> |
||||
| 563 | <i id="upshrink" class="hide main-menu-icon i-chevron-up" title="', $txt['upshrink_description'], '"></i> |
||||
| 564 | </a> |
||||
| 565 | </li>'; |
||||
| 566 | |||||
| 567 | // Now all the buttons from menu.subs |
||||
| 568 | foreach ($context['menu_buttons'] as $act => $button) |
||||
| 569 | { |
||||
| 570 | // Top link details, easier to maintain broken out |
||||
| 571 | $class = 'class="linklevel1' . (empty($button['active_button']) ? '' : ' active') . (empty($button['indicator']) ? '' : ' indicator') . '"'; |
||||
| 572 | $href = ' href="' . $button['href'] . '"'; |
||||
| 573 | $target = isset($button['target']) ? ' target="' . $button['target'] . '"' : ''; |
||||
| 574 | $onclick = isset($button['onclick']) ? ' onclick="' . $button['onclick'] . '"' : ''; |
||||
| 575 | $altTitle = 'title="' . (empty($button['alttitle']) ? $button['title'] : $button['alttitle']) . '"'; |
||||
| 576 | $ally = empty($button['active_button']) ? '' : ' aria-current="page"'; |
||||
| 577 | |||||
| 578 | echo ' |
||||
| 579 | <li id="button_', $act, '" class="listlevel1', empty($button['sub_buttons']) ? '"' : ' subsections"', ' role="none"> |
||||
| 580 | <a ', $class, $href, $target, $ally, $onclick, ' role="menuitem"', empty($button['sub_buttons']) ? '' : ' aria-haspopup="true"', '>', |
||||
| 581 | (empty($button['data-icon']) ? '' : '<i class="icon icon-menu icon-lg ' . $button['data-icon'] . (empty($button['active_button']) ? '' : ' enabled') . '" ' . $altTitle . '></i> '), |
||||
| 582 | '<span class="button_title" aria-hidden="', (empty($button['sub_buttons']) ? 'false' : 'true'), '">', $button['title'], '</span> |
||||
| 583 | </a>'; |
||||
| 584 | |||||
| 585 | // Any 2nd level menus? |
||||
| 586 | if (!empty($button['sub_buttons'])) |
||||
| 587 | { |
||||
| 588 | echo ' |
||||
| 589 | <ul class="menulevel2" role="menu">'; |
||||
| 590 | |||||
| 591 | foreach ($button['sub_buttons'] as $childact => $childbutton) |
||||
| 592 | { |
||||
| 593 | echo ' |
||||
| 594 | <li id="button_', $childact, '" class="listlevel2', empty($childbutton['sub_buttons']) ? '"' : ' subsections"', ' role="none"> |
||||
| 595 | <a class="linklevel2" href="', $childbutton['href'], '" ', isset($childbutton['target']) ? 'target="' . $childbutton['target'] . '"' : '', isset($childbutton['onclick']) ? ' onclick="' . $childbutton['onclick'] . '"' : '', empty($childbutton['sub_buttons']) ? '' : ' aria-haspopup="true"', ' role="menuitem">', |
||||
| 596 | $childbutton['title'], ' |
||||
| 597 | </a>'; |
||||
| 598 | |||||
| 599 | // 3rd level menus :) |
||||
| 600 | if (!empty($childbutton['sub_buttons'])) |
||||
| 601 | { |
||||
| 602 | echo ' |
||||
| 603 | <ul class="menulevel3" role="menu">'; |
||||
| 604 | |||||
| 605 | foreach ($childbutton['sub_buttons'] as $grandchildact => $grandchildbutton) |
||||
| 606 | { |
||||
| 607 | echo ' |
||||
| 608 | <li id="button_', $grandchildact, '" class="listlevel3" role="none"> |
||||
| 609 | <a class="linklevel3" href="', $grandchildbutton['href'], '" ', isset($grandchildbutton['target']) ? 'target="' . $grandchildbutton['target'] . '"' : '', isset($grandchildbutton['onclick']) ? ' onclick="' . $grandchildbutton['onclick'] . '"' : '', ' role="menuitem">', |
||||
| 610 | $grandchildbutton['title'], ' |
||||
| 611 | </a> |
||||
| 612 | </li>'; |
||||
| 613 | } |
||||
| 614 | |||||
| 615 | echo ' |
||||
| 616 | </ul>'; |
||||
| 617 | } |
||||
| 618 | |||||
| 619 | echo ' |
||||
| 620 | </li>'; |
||||
| 621 | } |
||||
| 622 | |||||
| 623 | echo ' |
||||
| 624 | </ul>'; |
||||
| 625 | } |
||||
| 626 | |||||
| 627 | echo ' |
||||
| 628 | </li>'; |
||||
| 629 | } |
||||
| 630 | |||||
| 631 | echo ' |
||||
| 632 | |||||
| 633 | </ul>'; |
||||
| 634 | |||||
| 635 | // If search is enabled, plop in the form |
||||
| 636 | if ($context['allow_search']) |
||||
| 637 | { |
||||
| 638 | template_search_form(); |
||||
| 639 | } |
||||
| 640 | |||||
| 641 | echo ' </div> |
||||
| 642 | </nav>'; |
||||
| 643 | |||||
| 644 | // Define the upper_section toggle in javascript. |
||||
| 645 | theme()->themeJs()->addInlineJavascript(' |
||||
| 646 | var oMainHeaderToggle = new elk_Toggle({ |
||||
| 647 | bToggleEnabled: true, |
||||
| 648 | bCurrentlyCollapsed: ' . (empty($context['minmax_preferences']['upshrink']) ? 'false' : 'true') . ', |
||||
| 649 | aSwappableContainers: [ |
||||
| 650 | \'upper_section\',\'header\',\'top_header\' |
||||
| 651 | ], |
||||
| 652 | aSwapClasses: [ |
||||
| 653 | { |
||||
| 654 | sId: \'upshrink\', |
||||
| 655 | classExpanded: \'main-menu-icon i-chevron-up\', |
||||
| 656 | titleExpanded: ' . JavaScriptEscape($txt['upshrink_description']) . ', |
||||
| 657 | classCollapsed: \'main-menu-icon i-chevron-down\', |
||||
| 658 | titleCollapsed: ' . JavaScriptEscape($txt['upshrink_description']) . ' |
||||
| 659 | }, |
||||
| 660 | ], |
||||
| 661 | oThemeOptions: { |
||||
| 662 | bUseThemeSettings: ' . ($context['user']['is_guest'] ? 'false' : 'true') . ', |
||||
| 663 | sOptionName: \'minmax_preferences\', |
||||
| 664 | sSessionId: elk_session_id, |
||||
| 665 | sSessionVar: elk_session_var, |
||||
| 666 | sAdditionalVars: \';minmax_key=upshrink\' |
||||
| 667 | }, |
||||
| 668 | oCookieOptions: { |
||||
| 669 | bUseCookie: elk_member_id == 0 ? true : false, |
||||
| 670 | sCookieName: \'upshrink\' |
||||
| 671 | }, |
||||
| 672 | funcOnBeforeCollapse: function () { |
||||
| 673 | let header = document.getElementById(\'top_section\'); |
||||
| 674 | header.classList.add(\'th_collapse\'); |
||||
| 675 | header.classList.remove(\'th_expand\'); |
||||
| 676 | }, |
||||
| 677 | funcOnBeforeExpand: function () { |
||||
| 678 | let header = document.getElementById(\'top_section\'); |
||||
| 679 | header.classList.add(\'th_expand\'); |
||||
| 680 | header.classList.remove(\'th_collapse\'); |
||||
| 681 | }, |
||||
| 682 | }); |
||||
| 683 | ', true); |
||||
| 684 | } |
||||
| 685 | |||||
| 686 | /** |
||||
| 687 | * Very simple and basic template to display a legend explaining the meaning |
||||
| 688 | * of some icons used in the messages listing (locked, sticky, etc.) |
||||
| 689 | */ |
||||
| 690 | function template_basicicons_legend() |
||||
| 691 | { |
||||
| 692 | global $context, $modSettings, $txt; |
||||
| 693 | |||||
| 694 | echo ' |
||||
| 695 | <p class="floatleft">', !empty($modSettings['enableParticipation']) && $context['user']['is_logged'] ? ' |
||||
| 696 | <span class="topicicon i-profile"></span> ' . $txt['participation_caption'] : '<span class="topicicon img_normal"> </span>' . $txt['normal_topic'], '<br /> |
||||
| 697 | ' . (empty($modSettings['pollMode']) ? '' : '<span class="topicicon i-poll"> </span>' . $txt['poll']) . ' |
||||
| 698 | </p> |
||||
| 699 | <p> |
||||
| 700 | <span class="topicicon i-locked"> </span>' . $txt['locked_topic'] . '<br /> |
||||
| 701 | <span class="topicicon i-sticky"> </span>' . $txt['sticky_topic'] . '<br /> |
||||
| 702 | </p>'; |
||||
| 703 | } |
||||
| 704 | |||||
| 705 | /** |
||||
| 706 | * Show a box with a message, mostly used to show errors, but can be used to show |
||||
| 707 | * success as well |
||||
| 708 | * |
||||
| 709 | * Looks for the display information in the $context[$error_id] array |
||||
| 710 | * Keys of array are 'type' |
||||
| 711 | * - empty or success for successbox |
||||
| 712 | * - serious for error box |
||||
| 713 | * - warning for warning box |
||||
| 714 | * 'title' - optional value to place above list |
||||
| 715 | * 'errors' - array of text strings to display in the box |
||||
| 716 | * |
||||
| 717 | * @param string $error_id |
||||
| 718 | */ |
||||
| 719 | function template_show_error($error_id) |
||||
| 720 | { |
||||
| 721 | global $context; |
||||
| 722 | |||||
| 723 | if (empty($error_id)) |
||||
| 724 | { |
||||
| 725 | return; |
||||
| 726 | } |
||||
| 727 | |||||
| 728 | $error = $context[$error_id] ?? array(); |
||||
| 729 | |||||
| 730 | echo ' |
||||
| 731 | <div id="', $error_id, '" class="', (isset($error['type']) ? ($error['type'] === 'serious' ? 'errorbox' : 'warningbox') : 'successbox'), empty($error['errors']) ? ' hide"' : '"', '>'; |
||||
| 732 | |||||
| 733 | // Optional title for our results |
||||
| 734 | if (!empty($error['title'])) |
||||
| 735 | { |
||||
| 736 | echo ' |
||||
| 737 | <dl> |
||||
| 738 | <dt> |
||||
| 739 | <strong id="', $error_id, '_title">', $error['title'], '</strong> |
||||
| 740 | </dt> |
||||
| 741 | <dd>'; |
||||
| 742 | } |
||||
| 743 | |||||
| 744 | // Everything that went wrong, or correctly :) |
||||
| 745 | if (!empty($error['errors'])) |
||||
| 746 | { |
||||
| 747 | echo ' |
||||
| 748 | <ul', (isset($error['type']) ? ' class="error"' : ''), ' id="', $error_id, '_list">'; |
||||
| 749 | |||||
| 750 | foreach ($error['errors'] as $key => $err) |
||||
| 751 | { |
||||
| 752 | echo ' |
||||
| 753 | <li id="', $error_id, '_', $key, '">', $err, '</li>'; |
||||
| 754 | } |
||||
| 755 | |||||
| 756 | echo ' |
||||
| 757 | </ul>'; |
||||
| 758 | } |
||||
| 759 | |||||
| 760 | // All done |
||||
| 761 | if (!empty($error['title'])) |
||||
| 762 | { |
||||
| 763 | echo ' |
||||
| 764 | </dd> |
||||
| 765 | </dl>'; |
||||
| 766 | } |
||||
| 767 | |||||
| 768 | echo ' |
||||
| 769 | </div>'; |
||||
| 770 | } |
||||
| 771 | |||||
| 772 | /** |
||||
| 773 | * Is this used? |
||||
| 774 | */ |
||||
| 775 | function template_uc_generic_infobox() |
||||
| 776 | { |
||||
| 777 | global $context; |
||||
| 778 | |||||
| 779 | if (empty($context['generic_infobox'])) |
||||
| 780 | { |
||||
| 781 | return; |
||||
| 782 | } |
||||
| 783 | |||||
| 784 | foreach ($context['generic_infobox'] as $key) |
||||
| 785 | { |
||||
| 786 | template_show_error($key); |
||||
| 787 | } |
||||
| 788 | } |
||||
| 789 | |||||
| 790 | /** |
||||
| 791 | * This is the news fader |
||||
| 792 | */ |
||||
| 793 | function template_news_fader() |
||||
| 794 | { |
||||
| 795 | global $settings, $context; |
||||
| 796 | |||||
| 797 | echo ' |
||||
| 798 | <ul id="elkFadeScroller"> |
||||
| 799 | <li> |
||||
| 800 | ', $settings['enable_news'] == 2 ? implode('</li><li>', $context['news_lines']) : $context['random_news_line'], ' |
||||
| 801 | </li> |
||||
| 802 | </ul> |
||||
| 803 | <script type="module"> |
||||
| 804 | Elk_NewsFader("elkFadeScroller", {' . (empty($settings['newsfader_time']) ? '' : 'iFadeDelay: ' . $settings['newsfader_time']) . '}) |
||||
| 805 | </script>'; |
||||
| 806 | } |
||||
| 807 | |||||
| 808 | /** |
||||
| 809 | * |
||||
| 810 | * @TODO: These need to be moved somewhere appropriate >_> |
||||
| 811 | * |
||||
| 812 | * @param array $member |
||||
| 813 | * @param bool $link |
||||
| 814 | * |
||||
| 815 | * @return string |
||||
| 816 | */ |
||||
| 817 | function template_member_online($member, $link = true) |
||||
| 818 | { |
||||
| 819 | global $context; |
||||
| 820 | |||||
| 821 | return ((!empty($context['can_send_pm']) && $link) ? '<a href="' . $member['online']['href'] . '" title="' . $member['online']['text'] . '">' : '') . |
||||
| 822 | '<i class="' . ($member['online']['is_online'] ? 'iconline' : 'icoffline') . '" title="' . $member['online']['text'] . '"></i>' . |
||||
| 823 | ((!empty($context['can_send_pm']) && $link) ? '</a>' : ''); |
||||
| 824 | } |
||||
| 825 | |||||
| 826 | /** |
||||
| 827 | * Similar to the above. Wanted to centralize this to make it easier to pull out the emailuser action and replace with |
||||
| 828 | * a mailto: href, which many sane board admins would prefer. |
||||
| 829 | * |
||||
| 830 | * @param array $member |
||||
| 831 | * @param bool $text |
||||
| 832 | * |
||||
| 833 | * @return string |
||||
| 834 | */ |
||||
| 835 | function template_member_email($member, $text = false) |
||||
| 836 | { |
||||
| 837 | global $context, $txt; |
||||
| 838 | |||||
| 839 | if ($context['can_send_email']) |
||||
| 840 | { |
||||
| 841 | if ($text) |
||||
| 842 | { |
||||
| 843 | if ($member !== false && $member['show_email']) |
||||
| 844 | { |
||||
| 845 | return '<a class="linkbutton" href="mailto:' . $member['email'] . '" rel="nofollow">' . $txt['email'] . '</a>'; |
||||
| 846 | } |
||||
| 847 | |||||
| 848 | return $txt['hidden']; |
||||
| 849 | } |
||||
| 850 | |||||
| 851 | if ($member !== false && $member['show_email']) |
||||
| 852 | { |
||||
| 853 | return '<a href="mailto:' . $member['email'] . '" rel="nofollow" class="icon i-envelope-o' . ($member['online']['is_online'] ? '' : '-blank') . '" title="' . $txt['email'] . ' ' . $member['name'] . '"><s>' . $txt['email'] . ' ' . $member['name'] . '</s></a>'; |
||||
| 854 | } |
||||
| 855 | |||||
| 856 | return '<i class="icon i-envelope-o" title="' . $txt['email'] . ' ' . $txt['hidden'] . '"><s>' . $txt['email'] . ' ' . $txt['hidden'] . '</s></i>'; |
||||
| 857 | } |
||||
| 858 | |||||
| 859 | return ''; |
||||
| 860 | } |
||||
| 861 |
This check looks for function or method calls that always return null and whose return value is used.
The method
getObject()can return nothing but null, so it makes no sense to use the return value.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.