Issues (1061)

Themes/default/index.template.php (3 issues)

1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines https://www.simplemachines.org
7
 * @copyright 2020 Simple Machines and individual contributors
8
 * @license https://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1 RC2
11
 */
12
13
/*	This template is, perhaps, the most important template in the theme. It
14
	contains the main template layer that displays the header and footer of
15
	the forum, namely with main_above and main_below. It also contains the
16
	menu sub template, which appropriately displays the menu; the init sub
17
	template, which is there to set the theme up; (init can be missing.) and
18
	the linktree sub template, which sorts out the link tree.
19
20
	The init sub template should load any data and set any hardcoded options.
21
22
	The main_above sub template is what is shown above the main content, and
23
	should contain anything that should be shown up there.
24
25
	The main_below sub template, conversely, is shown after the main content.
26
	It should probably contain the copyright statement and some other things.
27
28
	The linktree sub template should display the link tree, using the data
29
	in the $context['linktree'] variable.
30
31
	The menu sub template should display all the relevant buttons the user
32
	wants and or needs.
33
34
	For more information on the templating system, please see the site at:
35
	https://www.simplemachines.org/
36
*/
37
38
/**
39
 * Initialize the template... mainly little settings.
40
 */
41
function template_init()
42
{
43
	global $settings, $txt;
44
45
	/* $context, $options and $txt may be available for use, but may not be fully populated yet. */
46
47
	// The version this template/theme is for. This should probably be the version of SMF it was created for.
48
	$settings['theme_version'] = '2.1';
49
50
	// Set the following variable to true if this theme requires the optional theme strings file to be loaded.
51
	$settings['require_theme_strings'] = false;
52
53
	// Set the following variable to true if this theme wants to display the avatar of the user that posted the last and the first post on the message index and recent pages.
54
	$settings['avatars_on_indexes'] = false;
55
56
	// Set the following variable to true if this theme wants to display the avatar of the user that posted the last post on the board index.
57
	$settings['avatars_on_boardIndex'] = false;
58
59
	// This defines the formatting for the page indexes used throughout the forum.
60
	$settings['page_index'] = array(
61
		'extra_before' => '<span class="pages">' . $txt['pages'] . '</span>',
62
		'previous_page' => '<span class="main_icons previous_page"></span>',
63
		'current_page' => '<span class="current_page">%1$d</span> ',
64
		'page' => '<a class="nav_page" href="{URL}">%2$s</a> ',
65
		'expand_pages' => '<span class="expand_pages" onclick="expandPages(this, {LINK}, {FIRST_PAGE}, {LAST_PAGE}, {PER_PAGE});"> ... </span>',
66
		'next_page' => '<span class="main_icons next_page"></span>',
67
		'extra_after' => '',
68
	);
69
70
	// Allow css/js files to be disabled for this specific theme.
71
	// Add the identifier as an array key. IE array('smf_script'); Some external files might not add identifiers, on those cases SMF uses its filename as reference.
72
	if (!isset($settings['disable_files']))
73
		$settings['disable_files'] = array();
74
}
75
76
/**
77
 * The main sub template above the content.
78
 */
79
function template_html_above()
80
{
81
	global $context, $scripturl, $txt, $modSettings;
82
83
	// Show right to left, the language code, and the character set for ease of translating.
84
	echo '<!DOCTYPE html>
85
<html', $context['right_to_left'] ? ' dir="rtl"' : '', !empty($txt['lang_locale']) ? ' lang="' . str_replace("_", "-", substr($txt['lang_locale'], 0, strcspn($txt['lang_locale'], "."))) . '"' : '', '>
86
<head>
87
	<meta charset="', $context['character_set'], '">';
88
89
	/*
90
		You don't need to manually load index.css, this will be set up for you.
91
		Note that RTL will also be loaded for you.
92
		To load other CSS and JS files you should use the functions
93
		loadCSSFile() and loadJavaScriptFile() respectively.
94
		This approach will let you take advantage of SMF's automatic CSS
95
		minimization and other benefits. You can, of course, manually add any
96
		other files you want after template_css() has been run.
97
98
	*	Short example:
99
			- CSS: loadCSSFile('filename.css', array('minimize' => true));
100
			- JS:  loadJavaScriptFile('filename.css', array('minimize' => true));
101
			You can also read more detailed usages of the parameters for these
102
			functions on the SMF wiki.
103
104
	*	Themes:
105
			The most efficient way of writing multi themes is to use a master
106
			index.css plus variant.css files. If you've set them up properly
107
			(through $settings['theme_variants']), the variant files will be loaded
108
			for you automatically.
109
110
	*	MODs:
111
			If you want to load CSS or JS files in here, the best way is to use the
112
			'integrate_load_theme' hook for adding multiple files, or using
113
			'integrate_pre_css_output', 'integrate_pre_javascript_output' for a single file.
114
	*/
115
116
	// load in any css from mods or themes so they can overwrite if wanted
117
	template_css();
118
119
	// load in any javascript files from mods and themes
120
	template_javascript();
121
122
	echo '
123
	<title>', $context['page_title_html_safe'], '</title>
124
	<meta name="viewport" content="width=device-width, initial-scale=1">';
125
126
	// Content related meta tags, like description, keywords, Open Graph stuff, etc...
127
	foreach ($context['meta_tags'] as $meta_tag)
128
	{
129
		echo '
130
	<meta';
131
132
		foreach ($meta_tag as $meta_key => $meta_value)
133
			echo ' ', $meta_key, '="', $meta_value, '"';
134
135
		echo '>';
136
	}
137
138
	/*	What is your Lollipop's color?
139
		Theme Authors, you can change the color here to make sure your theme's main color gets visible on tab */
140
	echo '
141
	<meta name="theme-color" content="#557EA0">';
142
143
	// Please don't index these Mr Robot.
144
	if (!empty($context['robot_no_index']))
145
		echo '
146
	<meta name="robots" content="noindex">';
147
148
	// Present a canonical url for search engines to prevent duplicate content in their indices.
149
	if (!empty($context['canonical_url']))
150
		echo '
151
	<link rel="canonical" href="', $context['canonical_url'], '">';
152
153
	// Show all the relative links, such as help, search, contents, and the like.
154
	echo '
155
	<link rel="help" href="', $scripturl, '?action=help">
156
	<link rel="contents" href="', $scripturl, '">', ($context['allow_search'] ? '
157
	<link rel="search" href="' . $scripturl . '?action=search">' : '');
158
159
	// If RSS feeds are enabled, advertise the presence of one.
160
	if (!empty($modSettings['xmlnews_enable']) && (!empty($modSettings['allow_guestAccess']) || $context['user']['is_logged']))
161
		echo '
162
	<link rel="alternate" type="application/rss+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['rss'], '" href="', $scripturl, '?action=.xml;type=rss2', !empty($context['current_board']) ? ';board=' . $context['current_board'] : '', '">
163
	<link rel="alternate" type="application/atom+xml" title="', $context['forum_name_html_safe'], ' - ', $txt['atom'], '" href="', $scripturl, '?action=.xml;type=atom', !empty($context['current_board']) ? ';board=' . $context['current_board'] : '', '">';
164
165
	// If we're viewing a topic, these should be the previous and next topics, respectively.
166
	if (!empty($context['links']['next']))
167
		echo '
168
	<link rel="next" href="', $context['links']['next'], '">';
169
170
	if (!empty($context['links']['prev']))
171
		echo '
172
	<link rel="prev" href="', $context['links']['prev'], '">';
173
174
	// If we're in a board, or a topic for that matter, the index will be the board's index.
175
	if (!empty($context['current_board']))
176
		echo '
177
	<link rel="index" href="', $scripturl, '?board=', $context['current_board'], '.0">';
178
179
	// Output any remaining HTML headers. (from mods, maybe?)
180
	echo $context['html_headers'];
181
182
	echo '
183
</head>
184
<body id="', $context['browser_body_id'], '" class="action_', !empty($context['current_action']) ? $context['current_action'] : (!empty($context['current_board']) ?
185
		'messageindex' : (!empty($context['current_topic']) ? 'display' : 'home')), !empty($context['current_board']) ? ' board_' . $context['current_board'] : '', '">
186
<div id="footerfix">';
187
}
188
189
/**
190
 * The upper part of the main template layer. This is the stuff that shows above the main forum content.
191
 */
192
function template_body_above()
193
{
194
	global $context, $settings, $scripturl, $txt, $modSettings, $maintenance;
195
196
	// Wrapper div now echoes permanently for better layout options. h1 a is now target for "Go up" links.
197
	echo '
198
	<div id="top_section">
199
		<div class="inner_wrap">';
200
201
	// If the user is logged in, display some things that might be useful.
202
	if ($context['user']['is_logged'])
203
	{
204
		// Firstly, the user's menu
205
		echo '
206
			<ul class="floatleft" id="top_info">
207
				<li>
208
					<a href="', $scripturl, '?action=profile"', !empty($context['self_profile']) ? ' class="active"' : '', ' id="profile_menu_top" onclick="return false;">';
209
210
		if (!empty($context['user']['avatar']))
211
			echo $context['user']['avatar']['image'];
212
213
		echo $context['user']['name'], '</a>
214
					<div id="profile_menu" class="top_menu"></div>
215
				</li>';
216
217
		// Secondly, PMs if we're doing them
218
		if ($context['allow_pm'])
219
			echo '
220
				<li>
221
					<a href="', $scripturl, '?action=pm"', !empty($context['self_pm']) ? ' class="active"' : '', ' id="pm_menu_top">', $txt['pm_short'], !empty($context['user']['unread_messages']) ? ' <span class="amt">' . $context['user']['unread_messages'] . '</span>' : '', '</a>
222
					<div id="pm_menu" class="top_menu scrollable"></div>
223
				</li>';
224
225
		// Thirdly, alerts
226
		echo '
227
				<li>
228
					<a href="', $scripturl, '?action=profile;area=showalerts;u=', $context['user']['id'], '"', !empty($context['self_alerts']) ? ' class="active"' : '', ' id="alerts_menu_top">', $txt['alerts'], !empty($context['user']['alerts']) ? ' <span class="amt">' . $context['user']['alerts'] . '</span>' : '', '</a>
229
					<div id="alerts_menu" class="top_menu scrollable"></div>
230
				</li>';
231
232
		// A logout button for people without JavaScript.
233
		echo '
234
				<li id="nojs_logout">
235
					<a href="', $scripturl, '?action=logout;', $context['session_var'], '=', $context['session_id'], '">', $txt['logout'], '</a>
236
					<script>document.getElementById("nojs_logout").style.display = "none";</script>
237
				</li>';
238
239
		// And now we're done.
240
		echo '
241
			</ul>';
242
	}
243
	// Otherwise they're a guest. Ask them to either register or login.
244
	elseif (empty($maintenance))
245
		echo '
246
			<ul class="floatleft welcome">
247
				<li>', sprintf($txt[$context['can_register'] ? 'welcome_guest_register' : 'welcome_guest'], $txt['guest_title'], $context['forum_name_html_safe'], $scripturl . '?action=login', 'return reqOverlayDiv(this.href, ' . JavaScriptEscape($txt['login']) . ');', $scripturl . '?action=signup'), '</li>
248
			</ul>';
249
	else
250
		// In maintenance mode, only login is allowed and don't show OverlayDiv
251
		echo '
252
			<ul class="floatleft welcome">
253
				<li>', sprintf($txt['welcome_guest'], $txt['guest_title'], '', $scripturl . '?action=login', 'return true;'), '</li>
254
			</ul>';
255
256
	if (!empty($modSettings['userLanguage']) && !empty($context['languages']) && count($context['languages']) > 1)
257
	{
258
		echo '
259
			<form id="languages_form" method="get" class="floatright">
260
				<select id="language_select" name="language" onchange="this.form.submit()">';
261
262
		foreach ($context['languages'] as $language)
263
			echo '
264
					<option value="', $language['filename'], '"', isset($context['user']['language']) && $context['user']['language'] == $language['filename'] ? ' selected="selected"' : '', '>', str_replace('-utf8', '', $language['name']), '</option>';
265
266
		echo '
267
				</select>
268
				<noscript>
269
					<input type="submit" value="', $txt['quick_mod_go'], '">
270
				</noscript>
271
			</form>';
272
	}
273
274
	if ($context['allow_search'])
275
	{
276
		echo '
277
			<form id="search_form" class="floatright" action="', $scripturl, '?action=search2" method="post" accept-charset="', $context['character_set'], '">
278
				<input type="search" name="search" value="">&nbsp;';
279
280
		// Using the quick search dropdown?
281
		$selected = !empty($context['current_topic']) ? 'current_topic' : (!empty($context['current_board']) ? 'current_board' : 'all');
282
283
		echo '
284
				<select name="search_selection">
285
					<option value="all"', ($selected == 'all' ? ' selected' : ''), '>', $txt['search_entireforum'], ' </option>';
286
287
		// Can't limit it to a specific topic if we are not in one
288
		if (!empty($context['current_topic']))
289
			echo '
290
					<option value="topic"', ($selected == 'current_topic' ? ' selected' : ''), '>', $txt['search_thistopic'], '</option>';
291
292
		// Can't limit it to a specific board if we are not in one
293
		if (!empty($context['current_board']))
294
			echo '
295
					<option value="board"', ($selected == 'current_board' ? ' selected' : ''), '>', $txt['search_thisboard'], '</option>';
296
297
		// Can't search for members if we can't see the memberlist
298
		if (!empty($context['allow_memberlist']))
299
			echo '
300
					<option value="members"', ($selected == 'members' ? ' selected' : ''), '>', $txt['search_members'], ' </option>';
301
302
		echo '
303
				</select>';
304
305
		// Search within current topic?
306
		if (!empty($context['current_topic']))
307
			echo '
308
				<input type="hidden" name="sd_topic" value="', $context['current_topic'], '">';
309
310
		// If we're on a certain board, limit it to this board ;).
311
		elseif (!empty($context['current_board']))
312
			echo '
313
				<input type="hidden" name="sd_brd" value="', $context['current_board'], '">';
314
315
		echo '
316
				<input type="submit" name="search2" value="', $txt['search'], '" class="button">
317
				<input type="hidden" name="advanced" value="0">
318
			</form>';
319
	}
320
321
	echo '
322
		</div><!-- .inner_wrap -->
323
	</div><!-- #top_section -->';
324
325
	echo '
326
	<div id="header">
327
		<h1 class="forumtitle">
328
			<a id="top" href="', $scripturl, '">', empty($context['header_logo_url_html_safe']) ? $context['forum_name_html_safe'] : '<img src="' . $context['header_logo_url_html_safe'] . '" alt="' . $context['forum_name_html_safe'] . '">', '</a>
329
		</h1>';
330
331
	echo '
332
		', empty($settings['site_slogan']) ? '<img id="smflogo" src="' . $settings['images_url'] . '/smflogo.svg" alt="Simple Machines Forum" title="Simple Machines Forum">' : '<div id="siteslogan">' . $settings['site_slogan'] . '</div>', '';
333
334
	echo '
335
	</div>
336
	<div id="wrapper">
337
		<div id="upper_section">
338
			<div id="inner_section">
339
				<div id="inner_wrap">
340
					<div class="user">
341
						', $context['current_time'], '
342
					</div>';
343
344
	// Show a random news item? (or you could pick one from news_lines...)
345
	if (!empty($settings['enable_news']) && !empty($context['random_news_line']))
346
		echo '
347
					<div class="news">
348
						<h2>', $txt['news'], ': </h2>
349
						<p>', $context['random_news_line'], '</p>
350
					</div>';
351
352
	echo '
353
					<hr class="clear">
354
				</div>';
355
356
	// Show the menu here, according to the menu sub template, followed by the navigation tree.
357
	// Load mobile menu here
358
	echo '
359
				<a class="menu_icon mobile_user_menu"></a>
360
				<div id="main_menu">
361
					<div id="mobile_user_menu" class="popup_container">
362
						<div class="popup_window description">
363
							<div class="popup_heading">', $txt['mobile_user_menu'], '
364
								<a href="javascript:void(0);" class="main_icons hide_popup"></a>
365
							</div>
366
							', template_menu(), '
0 ignored issues
show
Are you sure the usage of template_menu() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

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.

Loading history...
367
						</div>
368
					</div>
369
				</div>';
370
371
	theme_linktree();
372
373
	echo '
374
			</div><!-- #inner_section -->
375
		</div><!-- #upper_section -->';
376
377
	// The main content should go here.
378
	echo '
379
		<div id="content_section">
380
			<div id="main_content_section">';
381
}
382
383
/**
384
 * The stuff shown immediately below the main content, including the footer
385
 */
386
function template_body_below()
387
{
388
	global $context, $txt, $scripturl, $modSettings;
389
390
	echo '
391
			</div><!-- #main_content_section -->
392
		</div><!-- #content_section -->
393
	</div><!-- #wrapper -->
394
</div><!-- #footerfix -->';
395
396
	// Show the footer with copyright, terms and help links.
397
	echo '
398
	<div id="footer">
399
		<div class="inner_wrap">';
400
401
	// There is now a global "Go to top" link at the right.
402
	echo '
403
		<ul>
404
			<li class="floatright"><a href="', $scripturl, '?action=help">', $txt['help'], '</a> ', (!empty($modSettings['requireAgreement'])) ? '| <a href="' . $scripturl . '?action=help;sa=rules">' . $txt['terms_and_rules'] . '</a>' : '', ' | <a href="#top_section">', $txt['go_up'], ' &#9650;</a></li>
405
			<li class="copyright">', theme_copyright(), '</li>
0 ignored issues
show
Are you sure the usage of theme_copyright() is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

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.

Loading history...
406
		</ul>';
407
408
	// Show the load time?
409
	if ($context['show_load_time'])
410
		echo '
411
		<p>', sprintf($txt['page_created_full'], $context['load_time'], $context['load_queries']), '</p>';
412
413
	echo '
414
		</div>
415
	</div><!-- #footer -->';
416
417
}
418
419
/**
420
 * This shows any deferred JavaScript and closes out the HTML
421
 */
422
function template_html_below()
423
{
424
	// Load in any javascipt that could be deferred to the end of the page
425
	template_javascript(true);
426
427
	echo '
428
</body>
429
</html>';
430
}
431
432
/**
433
 * Show a linktree. This is that thing that shows "My Community | General Category | General Discussion"..
434
 *
435
 * @param bool $force_show Whether to force showing it even if settings say otherwise
436
 */
437
function theme_linktree($force_show = false)
438
{
439
	global $context, $shown_linktree, $scripturl, $txt;
440
441
	// If linktree is empty, just return - also allow an override.
442
	if (empty($context['linktree']) || (!empty($context['dont_default_linktree']) && !$force_show))
443
		return;
444
	echo '
445
				<div class="navigate_section">
446
					<ul>';
447
448
	if ($context['user']['is_logged'])
449
		echo '
450
						<li class="unread_links">
451
							<a href="', $scripturl, '?action=unread" title="', $txt['unread_since_visit'], '">', $txt['view_unread_category'], '</a>
452
							<a href="', $scripturl, '?action=unreadreplies" title="', $txt['show_unread_replies'], '">', $txt['unread_replies'], '</a>
453
						</li>';
454
455
	// Each tree item has a URL and name. Some may have extra_before and extra_after.
456
	foreach ($context['linktree'] as $link_num => $tree)
457
	{
458
		echo '
459
						<li', ($link_num == count($context['linktree']) - 1) ? ' class="last"' : '', '>';
460
461
		// Don't show a separator for the first one.
462
		// Better here. Always points to the next level when the linktree breaks to a second line.
463
		// Picked a better looking HTML entity, and added support for RTL plus a span for styling.
464
		if ($link_num != 0)
465
			echo '
466
							<span class="dividers">', $context['right_to_left'] ? ' &#9668; ' : ' &#9658; ', '</span>';
467
468
		// Show something before the link?
469
		if (isset($tree['extra_before']))
470
			echo $tree['extra_before'], ' ';
471
472
		// Show the link, including a URL if it should have one.
473
		if (isset($tree['url']))
474
			echo '
475
							<a href="' . $tree['url'] . '"><span>' . $tree['name'] . '</span></a>';
476
		else
477
			echo '
478
							<span>' . $tree['name'] . '</span>';
479
480
		// Show something after the link...?
481
		if (isset($tree['extra_after']))
482
			echo ' ', $tree['extra_after'];
483
484
		echo '
485
						</li>';
486
	}
487
488
	echo '
489
					</ul>
490
				</div><!-- .navigate_section -->';
491
492
	$shown_linktree = true;
493
}
494
495
/**
496
 * Show the menu up top. Something like [home] [help] [profile] [logout]...
497
 */
498
function template_menu()
499
{
500
	global $context;
501
502
	echo '
503
					<ul class="dropmenu menu_nav">';
504
505
	// Note: Menu markup has been cleaned up to remove unnecessary spans and classes.
506
	foreach ($context['menu_buttons'] as $act => $button)
507
	{
508
		echo '
509
						<li class="button_', $act, '', !empty($button['sub_buttons']) ? ' subsections"' : '"', '>
510
							<a', $button['active_button'] ? ' class="active"' : '', ' href="', $button['href'], '"', isset($button['target']) ? ' target="' . $button['target'] . '"' : '', '>
511
								', $button['icon'], '<span class="textmenu">', $button['title'], !empty($button['amt']) ? ' <span class="amt">' . $button['amt'] . '</span>' : '', '</span>
512
							</a>';
513
514
		// 2nd level menus
515
		if (!empty($button['sub_buttons']))
516
		{
517
			echo '
518
							<ul>';
519
520
			foreach ($button['sub_buttons'] as $childbutton)
521
			{
522
				echo '
523
								<li', !empty($childbutton['sub_buttons']) ? ' class="subsections"' : '', '>
524
									<a href="', $childbutton['href'], '"', isset($childbutton['target']) ? ' target="' . $childbutton['target'] . '"' : '', '>
525
										', $childbutton['title'], !empty($childbutton['amt']) ? ' <span class="amt">' . $childbutton['amt'] . '</span>' : '', '
526
									</a>';
527
				// 3rd level menus :)
528
				if (!empty($childbutton['sub_buttons']))
529
				{
530
					echo '
531
									<ul>';
532
533
					foreach ($childbutton['sub_buttons'] as $grandchildbutton)
534
						echo '
535
										<li>
536
											<a href="', $grandchildbutton['href'], '"', isset($grandchildbutton['target']) ? ' target="' . $grandchildbutton['target'] . '"' : '', '>
537
												', $grandchildbutton['title'], !empty($grandchildbutton['amt']) ? ' <span class="amt">' . $grandchildbutton['amt'] . '</span>' : '', '
538
											</a>
539
										</li>';
540
541
					echo '
542
									</ul>';
543
				}
544
545
				echo '
546
								</li>';
547
			}
548
			echo '
549
							</ul>';
550
		}
551
		echo '
552
						</li>';
553
	}
554
555
	echo '
556
					</ul><!-- .menu_nav -->';
557
}
558
559
/**
560
 * Generate a strip of buttons.
561
 *
562
 * @param array $button_strip An array with info for displaying the strip
563
 * @param string $direction The direction
564
 * @param array $strip_options Options for the button strip
565
 */
566
function template_button_strip($button_strip, $direction = '', $strip_options = array())
567
{
568
	global $context, $txt;
569
570
	if (!is_array($strip_options))
0 ignored issues
show
The condition is_array($strip_options) is always true.
Loading history...
571
		$strip_options = array();
572
573
	// Create the buttons...
574
	$buttons = array();
575
	foreach ($button_strip as $key => $value)
576
	{
577
		// As of 2.1, the 'test' for each button happens while the array is being generated. The extra 'test' check here is deprecated but kept for backward compatibility (update your mods, folks!)
578
		if (!isset($value['test']) || !empty($context[$value['test']]))
579
		{
580
			if (!isset($value['id']))
581
				$value['id'] = $key;
582
583
			$button = '
584
				<a class="button button_strip_' . $key . (!empty($value['active']) ? ' active' : '') . (isset($value['class']) ? ' ' . $value['class'] : '') . '" ' . (!empty($value['url']) ? 'href="' . $value['url'] . '"' : '') . ' ' . (isset($value['custom']) ? ' ' . $value['custom'] : '') . '>'.(!empty($value['icon']) ? '<span class="main_icons '.$value['icon'].'"></span>' : '').'' . $txt[$value['text']] . '</a>';
585
586
			if (!empty($value['sub_buttons']))
587
			{
588
				$button .= '
589
					<div class="top_menu dropmenu ' . $key . '_dropdown">
590
						<div class="viewport">
591
							<div class="overview">';
592
				foreach ($value['sub_buttons'] as $element)
593
				{
594
					if (isset($element['test']) && empty($context[$element['test']]))
595
						continue;
596
597
					$button .= '
598
								<a href="' . $element['url'] . '"><strong>' . $txt[$element['text']] . '</strong>';
599
					if (isset($txt[$element['text'] . '_desc']))
600
						$button .= '<br><span>' . $txt[$element['text'] . '_desc'] . '</span>';
601
					$button .= '</a>';
602
				}
603
				$button .= '
604
							</div><!-- .overview -->
605
						</div><!-- .viewport -->
606
					</div><!-- .top_menu -->';
607
			}
608
609
			$buttons[] = $button;
610
		}
611
	}
612
613
	// No buttons? No button strip either.
614
	if (empty($buttons))
615
		return;
616
617
	echo '
618
		<div class="buttonlist', !empty($direction) ? ' float' . $direction : '', '"', (empty($buttons) ? ' style="display: none;"' : ''), (!empty($strip_options['id']) ? ' id="' . $strip_options['id'] . '"' : ''), '>
619
			', implode('', $buttons), '
620
		</div>';
621
}
622
623
/**
624
 * Generate a list of quickbuttons.
625
 *
626
 * @param array $list_items An array with info for displaying the strip
627
 * @param string $list_class Used for integration hooks and as a class name
628
 * @param string $output_method The output method. If 'echo', simply displays the buttons, otherwise returns the HTML for them
629
 * @return void|string Returns nothing unless output_method is something other than 'echo'
630
 */
631
function template_quickbuttons($list_items, $list_class = null, $output_method = 'echo')
632
{
633
	global $txt;
634
635
	// Enable manipulation with hooks
636
	if (!empty($list_class))
637
		call_integration_hook('integrate_' . $list_class . '_quickbuttons', array(&$list_items));
638
639
	// Make sure the list has at least one shown item
640
	foreach ($list_items as $key => $li)
641
	{
642
		// Is there a sublist, and does it have any shown items
643
		if ($key == 'more')
644
		{
645
			foreach ($li as $subkey => $subli)
646
				if (isset($subli['show']) && !$subli['show'])
647
					unset($list_items[$key][$subkey]);
648
649
			if (empty($list_items[$key]))
650
				unset($list_items[$key]);
651
		}
652
		// A normal list item
653
		elseif (isset($li['show']) && !$li['show'])
654
			unset($list_items[$key]);
655
	}
656
657
	// Now check if there are any items left
658
	if (empty($list_items))
659
		return;
660
661
	// Print the quickbuttons
662
	$output = '
663
		<ul class="quickbuttons' . (!empty($list_class) ? ' quickbuttons_' . $list_class : '') . '">';
664
665
	// This is used for a list item or a sublist item
666
	$list_item_format = function($li)
667
	{
668
		$html = '
669
			<li' . (!empty($li['class']) ? ' class="' . $li['class'] . '"' : '') . (!empty($li['id']) ? ' id="' . $li['id'] . '"' : '') . (!empty($li['custom']) ? $li['custom'] : '') . '>';
670
671
		if (isset($li['content']))
672
			$html .= $li['content'];
673
		else
674
			$html .= '
675
				<a' . (!empty($li['href']) ? ' href="' . $li['href'] . '"' : '') . (!empty($li['javascript']) ? $li['javascript'] : '') . '>
676
					' . (!empty($li['icon']) ? '<span class="main_icons ' . $li['icon'] . '"></span>' : '') . (!empty($li['label']) ? $li['label'] : '') . '
677
				</a>';
678
679
		$html .= '
680
			</li>';
681
682
		return $html;
683
	};
684
685
	foreach ($list_items as $key => $li)
686
	{
687
		// Handle the sublist
688
		if ($key == 'more')
689
		{
690
			$output .= '
691
			<li class="post_options">' . $txt['post_options'] . '
692
				<ul>';
693
694
			foreach ($li as $subli)
695
				$output .= $list_item_format($subli);
696
697
			$output .= '
698
				</ul>
699
			</li>';
700
		}
701
		// Ordinary list item
702
		else
703
			$output .= $list_item_format($li);
704
	}
705
706
	$output .= '
707
		</ul><!-- .quickbuttons -->';
708
709
	// There are a few spots where the result needs to be returned
710
	if ($output_method == 'echo')
711
		echo $output;
712
	else
713
		return $output;
714
}
715
716
/**
717
 * The upper part of the maintenance warning box
718
 */
719
function template_maint_warning_above()
720
{
721
	global $txt, $context, $scripturl;
722
723
	echo '
724
	<div class="errorbox" id="errors">
725
		<dl>
726
			<dt>
727
				<strong id="error_serious">', $txt['forum_in_maintenance'], '</strong>
728
			</dt>
729
			<dd class="error" id="error_list">
730
				', sprintf($txt['maintenance_page'], $scripturl . '?action=admin;area=serversettings;' . $context['session_var'] . '=' . $context['session_id']), '
731
			</dd>
732
		</dl>
733
	</div>';
734
}
735
736
/**
737
 * The lower part of the maintenance warning box.
738
 */
739
function template_maint_warning_below()
740
{
741
742
}
743
744
?>