diff options
Diffstat (limited to 'src/application/templates/modern/base.twig')
-rw-r--r-- | src/application/templates/modern/base.twig | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/src/application/templates/modern/base.twig b/src/application/templates/modern/base.twig new file mode 100644 index 0000000..819af80 --- /dev/null +++ b/src/application/templates/modern/base.twig @@ -0,0 +1,222 @@ +{%- if title -%} + {%- set title = title ~ " | " -%} +{%- endif -%} +{%- set title = title ~ (g.env.MYSTIC_FORUM_TITLE|default("Forum")) -%} +{%- set nextParam = "" -%} +{%- if g.globals.action in ["login", "register"] -%} + {%- set nextParam = g.get.next|default("") -%} +{%- else -%} + {%- set nextParam = g.server.REQUEST_URI -%} +{%- endif -%} +<!DOCTYPE html> +<html lang="{{ __("en", context: "HTML language") }}"> +<head> + <meta charset="utf-8"> + <meta name="color-scheme" content="light dark"> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <meta name="generator" content="mysticBB {{ constant("MYSTICBB_VERSION") }}"> + <title>{{ title }}</title> + <link rel="stylesheet" href=".?_action=ctheme"> + <script src=".?_action=ji18n"></script> + {% block head_after %}{% endblock %} +</head> +<body> + +{% block nav %} +<header> + <a id="brand" href=".">{{ g.env.MYSTIC_FORUM_TITLE|default("Forum") }}</a> + <nav> + {% block navbar %} + {% if currentUser %} + <a aria-label="{{ __("Search") }}" href="?_action=search"{{ g.globals.action == "search" ? ' class="active"'|raw : '' }}> + <svg viewBox="0 0 24 24" class="icon"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg> + </a> + <a aria-label="{{ __("View profile") }}" href="?_action=viewuser&user={{ currentUser.id|url_encode }}"{{ (g.globals.action == "viewuser" and g.get.user == currentUser.id) ? ' class="active"'|raw : '' }}> + <svg viewBox="0 0 24 24" class="icon"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg> + </a> + <a aria-label="{{ __("Log out") }}" href="?_action=logout&next={{ g.server.REQUEST_URI|url_encode }}"> + <svg viewBox="0 0 24 24" class="icon"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></svg> + </a> + {% else %} + <a aria-label="{{ __("Search") }}" href="?_action=search"{{ g.globals.action == "search" ? ' class="active"'|raw : '' }}> + <svg viewBox="0 0 24 24" class="icon"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg> + </a> + <a href="?_action=auth&next={{ nextParam|url_encode }}"{{ g.globals.action == "auth" ? ' class="active"'|raw : '' }}>{{ __("Log in") }}</a> + {% if constant("REGISTRATION_ENABLED") %} + <a href="?_action=register&next={{ nextParam|url_encode }}"{{ g.globals.action == "register" ? ' class="active"'|raw : '' }}>{{ __("Register") }}</a> + {% endif %} + {% endif %} + {% endblock %} + </nav> +</header> +{% endblock %} + +{% block main %} +<main> + {% block content %}{% endblock %} +</main> +{% endblock %} + +{% block footer %} +<footer> + <div id="about"> + © {{ "now"|date("Y") }} {{ g.env.MYSTIC_FORUM_COPYRIGHT|default(g.env.MYSTIC_FORUM_TITLE)|default("Forum") }}. + Powered by <a href="https://git.jkohl.link/mystic-forum.git/tag/?h=v{{ constant("MYSTICBB_VERSION")|url_encode }}">mysticBB v{{ constant("MYSTICBB_VERSION") }}</a>. + </div> + <div id="preferences"> + <form action="?_action=settheme" class="form-inline" method="post"> + <input type="hidden" name="next" value="{{ g.server.REQUEST_URI }}"> + <div class="form-group"> + <label for="theme-select">{{ __("Theme:") }}</label> + <select id="theme-select" name="theme" onchange="this.form.submit()"> + {% for themeKey, themeInfo in availableThemes %} + <option value="{{ themeKey }}"{{ themeKey == currentTheme ? " selected" : "" }}>{{ themeInfo.name }}</option> + {% endfor %} + </select> + </div> + </form> + <form action="?_action=setlang" class="form-inline" method="post"> + <input type="hidden" name="next" value="{{ g.server.REQUEST_URI }}"> + <div class="form-group"> + <label for="lang-select">{{ __("Language:") }}</label> + <select id="lang-select" name="lang" onchange="this.form.submit()"> + {% for langKey, langName in availableLangs %} + <option value="{{ langKey }}"{{ langKey == currentLang ? " selected" : "" }}>{{ langName }}</option> + {% endfor %} + </select> + </div> + </form> + </div> +</footer> +{% endblock %} + +{% block scripts %} +<script type="text/javascript"> + (function() { + function insertAroundSelection(textarea, before, after) { + var start = textarea.selectionStart; + var end = textarea.selectionEnd; + var text = textarea.value; + var pre = text.substring(0, start); + var inner = text.substring(start, end); + var post = text.substring(end); + start += before.length; + end += before.length; + text = pre + before + inner + after + post; + textarea.value = text; + textarea.focus(); + textarea.selectionStart = start; + textarea.selectionEnd = end; + } + + function getTextarea(btn) { + return document.querySelector(btn.dataset.area); + } + + var commands = { + bold: function(textarea) { + insertAroundSelection(textarea, "[b]", "[/b]"); + }, + italic: function(textarea) { + insertAroundSelection(textarea, "[i]", "[/i]"); + }, + underline: function(textarea) { + insertAroundSelection(textarea, "[u]", "[/u]"); + }, + strikethrough: function(textarea) { + insertAroundSelection(textarea, "[s]", "[/s]"); + }, + sup: function(textarea) { + insertAroundSelection(textarea, "[^]", "[/^]"); + }, + sub: function(textarea) { + insertAroundSelection(textarea, "[_]", "[/_]"); + }, + quote: function(textarea) { + insertAroundSelection(textarea, "> ", ""); + }, + spoiler: function(textarea) { + insertAroundSelection(textarea, "[spoiler]", "[/spoiler]"); + } + } + + document.querySelectorAll("button[data-editor-command]").forEach(e => { + e.addEventListener("click", function() { + const command = e.dataset.editorCommand; + const textarea = getTextarea(e); + commands[command](textarea); + }); + }); + })(); +</script> + +<script> + document.querySelectorAll("._time").forEach(e => { + const date = new Date(e.textContent.trim()); + e.textContent = date.toLocaleString(); + }); + document.querySelectorAll("._date").forEach(e => { + const date = new Date(e.textContent.trim()); + e.textContent = date.toLocaleDateString(); + }); + document.querySelectorAll("._time-only").forEach(e => { + const date = new Date(e.textContent.trim()); + e.textContent = date.toLocaleTimeString(); + }); + document.querySelectorAll("[data-dismiss='modal']").forEach(e => { + e.addEventListener("click", () => { + const modal = e.closest(".modal"); + if (!modal) + return; + modal.classList.add("fade"); + modal.dispatchEvent(new Event("hidemodal")); + }); + }) +</script> + +<script> + // feature detection + (function() { + var unsupportedFeatures = []; + + function notSupported(feat) { + unsupportedFeatures.push("- " + feat); + } + + var supports = { + cssNesting: ((function() { + try { + document.querySelector("&"); + return true; + } catch (e) { + return false; + } + })()), + es6Syntax: ((function() { + try { + Function("() => {};"); + return true; + } catch (e) { + return false; + } + })()) + }; + + if (!supports.cssNesting) notSupported("CSS nesting"); + if (!supports.es6Syntax) notSupported("ECMAScript 6 Syntax"); + + if (unsupportedFeatures.length > 0) { + alert( + "ATTENTION: This site might not work properly because your " + + "browser does not support some required features: \n\n" + + unsupportedFeatures.join("\n") + + "\n\n" + + "Please try chaning the theme to something else!" + ); + } + })(); +</script> +{% endblock %} + +</body> +</html> |