From 7d685c5e64149e20c7dc8977f645e050be53ddfd Mon Sep 17 00:00:00 2001
From: Jonas Kohl
Date: Tue, 10 Dec 2024 17:15:10 +0100
Subject: Add classic theme

---
 src/application/templates/old/base.twig            | 223 +++++++++++++++++++
 .../templates/old/components/alert_error.twig      |  11 +
 .../templates/old/components/alert_info.twig       |  11 +
 .../templates/old/components/alert_success.twig    |  11 +
 src/application/templates/old/components/post.twig | 169 +++++++++++++++
 .../templates/old/components/post_editor.twig      |  37 ++++
 .../templates/old/components/topic_log.twig        |  60 ++++++
 src/application/templates/old/delete_post.twig     |  42 ++++
 src/application/templates/old/delete_topic.twig    |  36 ++++
 src/application/templates/old/error_page.twig      |  12 ++
 src/application/templates/old/info_page.twig       |  12 ++
 src/application/templates/old/login.twig           |  51 +++++
 src/application/templates/old/new_password.twig    |  40 ++++
 src/application/templates/old/new_topic.twig       |  32 +++
 src/application/templates/old/password_reset.twig  |  45 ++++
 src/application/templates/old/register.twig        |  77 +++++++
 src/application/templates/old/search.twig          |  77 +++++++
 src/application/templates/old/view_topic.twig      | 237 +++++++++++++++++++++
 src/application/templates/old/view_topics.twig     |  30 +++
 src/application/templates/old/view_user.twig       | 196 +++++++++++++++++
 20 files changed, 1409 insertions(+)
 create mode 100644 src/application/templates/old/base.twig
 create mode 100644 src/application/templates/old/components/alert_error.twig
 create mode 100644 src/application/templates/old/components/alert_info.twig
 create mode 100644 src/application/templates/old/components/alert_success.twig
 create mode 100644 src/application/templates/old/components/post.twig
 create mode 100644 src/application/templates/old/components/post_editor.twig
 create mode 100644 src/application/templates/old/components/topic_log.twig
 create mode 100644 src/application/templates/old/delete_post.twig
 create mode 100644 src/application/templates/old/delete_topic.twig
 create mode 100644 src/application/templates/old/error_page.twig
 create mode 100644 src/application/templates/old/info_page.twig
 create mode 100644 src/application/templates/old/login.twig
 create mode 100644 src/application/templates/old/new_password.twig
 create mode 100644 src/application/templates/old/new_topic.twig
 create mode 100644 src/application/templates/old/password_reset.twig
 create mode 100644 src/application/templates/old/register.twig
 create mode 100644 src/application/templates/old/search.twig
 create mode 100644 src/application/templates/old/view_topic.twig
 create mode 100644 src/application/templates/old/view_topics.twig
 create mode 100644 src/application/templates/old/view_user.twig

(limited to 'src/application/templates/old')

diff --git a/src/application/templates/old/base.twig b/src/application/templates/old/base.twig
new file mode 100644
index 0000000..7b358d0
--- /dev/null
+++ b/src/application/templates/old/base.twig
@@ -0,0 +1,223 @@
+{%- 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 PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html lang="{{ __("en", context: "HTML language") }}">
+<head>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+    <meta name="generator" content="mysticBB {{ constant("MYSTICBB_VERSION") }}">
+    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+    <meta http-equiv="imagetoolbar" content="no">
+    <meta http-equiv="MSThemeCompatible" content="yes">
+    <title>{{ title }}</title>
+    <link rel="stylesheet" href="?_action=ctheme&amp;theme={{ g.cookie.theme|url_encode }}" type="text/css">
+    <script type="text/javascript" src="/ui/jquery-1.12.4.min.js"></script>
+    {% block head_after %}{% endblock %}
+</head>
+<body bgcolor="white" text="black" link="blue" vlink="blue" alink="red">
+<table width="100%">
+
+{% block nav %}
+<tr>
+<td>
+<table width="100%">
+<tr>
+<td align="right">
+<table border="1" cellspacing="0" cellpadding="4" bordercolor="silver" bgcolor="white">
+<tr>
+{% block navbar %}
+    {% if currentUser %}
+        <td>{{ __("Welcome, %user%!", {
+            user: currentUser.id == constant("mystic\\forum\\orm\\User::SUPERUSER_ID") ? ('<strong class="text-danger">' ~ (currentUser.displayName|e("html")) ~ '</strong>')|raw : ('<strong>' ~ (currentUser.displayName|e("html")) ~ '</strong>')|raw
+        }) }}</td>
+        <td><img src="/ui/theme-files/old/home.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href=".">{{ __("Start") }}</a></td>
+        <td{{ g.globals.action == "search" ? ' class="active"'|raw : '' }}><img src="/ui/theme-files/old/search.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=search">{{ __("Search") }}</a></td>
+        <td{{ (g.globals.action == "viewuser" and g.get.user == currentUser.id) ? ' class="active"'|raw : '' }}><img src="/ui/theme-files/old/user.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=viewuser&amp;user={{ currentUser.id|url_encode }}">{{ __("View profile") }}</a></td>
+        <td><img src="/ui/theme-files/old/exit.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=logout&amp;next={{ g.server.REQUEST_URI|url_encode }}">{{ __("Log out") }}</a></td>
+    {% else %}
+        <td><img src="/ui/theme-files/old/home.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href=".">{{ __("Start") }}</a></td>
+        <td{{ g.globals.action == "search" ? ' class="active"'|raw : '' }}><img src="/ui/theme-files/old/search.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=search">{{ __("Search") }}</a></td>
+        <td{{ g.globals.action == "auth" ? ' class="active"'|raw : '' }}><img src="/ui/theme-files/old/user.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=auth&amp;next={{ nextParam|url_encode }}">{{ __("Log in") }}</a></td>
+        {% if constant("REGISTRATION_ENABLED") %}
+            <td{{ g.globals.action == "register" ? ' class="active"'|raw : '' }}><img src="/ui/theme-files/old/user_add.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;<a href="?_action=register&amp;next={{ nextParam|url_encode }}">{{ __("Register") }}</a></td>
+        {% endif %}
+    {% endif %}
+{% endblock %}
+</tr>
+</table>
+</tr>
+</table>
+</td>
+</tr>
+{% endblock %}
+
+{% block main %}
+<tr><td>
+    {% block content %}{% endblock %}
+</td></tr>
+{% endblock %}
+
+{% block footer %}
+<tr>
+<td>
+<table border="1" width="100%" cellpadding="4" cellspacing="0" bordercolor="silver" bgcolor="white" class="footer">
+<tr>
+    <td align="left">
+        &copy; {{ "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>.
+    </td>
+    <td align="right">
+        <table><tr><td>
+        <form action="?_action=settheme" 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>
+        </td><td>
+            <span>{{ __("Language:") }}</span>
+            {% for langKey, langName in availableLangs %}
+                <form action="?_action=setlang" method="post" class="inline">
+                    <input type="hidden" name="next" value="{{ g.server.REQUEST_URI }}">
+                    <input type="hidden" name="lang" value="{{ langKey }}">
+                    <button type="submit" class="seamless inline-icon"><img src="/ui/theme-files/old/lang_{{ langKey }}.gif" width="16" height="16" border="0" draggable="false" alt="{{ langName }}"></button>
+                </form>
+            {% endfor %}
+        </td></tr></table>
+    </td>
+</tr>
+</table>
+</td>
+</tr>
+{% 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 $($(btn).attr("data-area"))[0];
+        }
+
+        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]");
+            }
+        }
+
+        $("button[data-editor-command]").attr("data-toggle", "tooltip").attr("data-placement", "bottom").click(function() {
+            var command = $(this).attr("data-editor-command");
+            var textarea = getTextarea(this);
+            commands[command](textarea);
+        });
+    });
+</script>
+<script type="text/javascript">
+    $(function() {
+        function parseISODate(str) {
+            var matches = str.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})([+-]\d{2}(?::?\d{2}))?$/);
+            matches.shift();
+            var year = matches[0];
+            var month = matches[1];
+            var day = matches[2];
+            var hours = matches[3];
+            var minutes = matches[4];
+            var seconds = matches[5];
+            var timezone = matches[6];
+            if (timezone.indexOf(":") >= 0) {
+                var factor = 1;
+                if (timezone[0] == "+") {
+                    factor = 1;
+                    timezone = timezone.substr(1);
+                } else if (timezone[0] == "-") {
+                    factor = -1;
+                    timezone = timezone.substr(1);
+                }
+                timezone = timezone.split(":");
+                var tzHours = timezone[0];
+                var tzMinutes = timezone[1];
+                tzHours = parseInt(tzHours);
+                tzMinutes = parseInt(tzMinutes) / 60;
+                timezone = tzHours + tzMinutes;
+            } else {
+                timezone = parseInt(timezone);
+            }
+
+            var date = new Date();
+            date.setUTCFullYear(year);
+            date.setUTCMonth(month - 1);
+            date.setUTCDate(day);
+            date.setUTCHours(hours);
+            date.setUTCMinutes(minutes);
+            date.setUTCSeconds(seconds);
+
+            return date;
+        }
+
+        $("._time").each(function(i, e) {
+            var date = parseISODate($(e).text());
+            $(e).text(date.toLocaleString());
+        });
+        $("._date").each(function(i, e) {
+            var date = parseISODate($(e).text());
+            $(e).text(date.toLocaleDateString());
+        });
+        $("._time-only").each(function(i, e) {
+            var date = parseISODate($(e).text());
+            $(e).text(date.toLocaleTimeString());
+        });
+    });
+</script>
+{% endblock %}
+
+</table>
+</body>
+</html>
diff --git a/src/application/templates/old/components/alert_error.twig b/src/application/templates/old/components/alert_error.twig
new file mode 100644
index 0000000..a45559c
--- /dev/null
+++ b/src/application/templates/old/components/alert_error.twig
@@ -0,0 +1,11 @@
+<table cellspacing="0" cellpadding="4" bgcolor="pink" border="1" bordercolor="red">
+<tr><td>
+    <img src="/ui/theme-files/old/delete.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;
+    {%- if message starts with "?!HTML::" -%}
+        {{- message|slice(8)|raw -}}
+    {%- else -%}
+        {{- message -}}
+    {%- endif -%}
+</td></tr>
+</table>
+<br>
diff --git a/src/application/templates/old/components/alert_info.twig b/src/application/templates/old/components/alert_info.twig
new file mode 100644
index 0000000..d45410c
--- /dev/null
+++ b/src/application/templates/old/components/alert_info.twig
@@ -0,0 +1,11 @@
+<table cellspacing="0" cellpadding="4" bgcolor="lightskyblue" border="1" bordercolor="skyblue">
+<tr><td>
+    <img src="/ui/theme-files/old/information.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;
+    {%- if message starts with "?!HTML::" -%}
+        {{- message|slice(8)|raw -}}
+    {%- else -%}
+        {{- message -}}
+    {%- endif -%}
+</td></tr>
+</table>
+<br>
\ No newline at end of file
diff --git a/src/application/templates/old/components/alert_success.twig b/src/application/templates/old/components/alert_success.twig
new file mode 100644
index 0000000..2192358
--- /dev/null
+++ b/src/application/templates/old/components/alert_success.twig
@@ -0,0 +1,11 @@
+<table cellspacing="0" cellpadding="4" bgcolor="#99FF99" border="1" bordercolor="green">
+<tr><td>
+    <img src="/ui/theme-files/old/check.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;
+    {%- if message starts with "?!HTML::" -%}
+        {{- message|slice(8)|raw -}}
+    {%- else -%}
+        {{- message -}}
+    {%- endif -%}
+</td></tr>
+</table>
+<br>
diff --git a/src/application/templates/old/components/post.twig b/src/application/templates/old/components/post.twig
new file mode 100644
index 0000000..6b04bca
--- /dev/null
+++ b/src/application/templates/old/components/post.twig
@@ -0,0 +1,169 @@
+{%- set fileAttachments = attachments|filter(a => not (a.mimeType starts with "image/" or a.mimeType starts with "video/")) -%}
+{%- set imageAttachments = attachments|filter(a => a.mimeType starts with "image/" or a.mimeType starts with "video/") -%}
+
+{%- set canReply =
+    not post.deleted
+    and not topic.isLocked
+    and currentUser is not null
+    and currentUser.hasPermission(permission("CREATE_OWN_POST"))
+-%}
+
+{%- set canEdit =
+    not post.deleted
+    and not topic.isLocked
+    and currentUser is not null
+    and (
+        (
+            postAuthor is not null
+            and postAuthor.id == currentUser.id
+            and postAuthor.hasPermission(permission("EDIT_OWN_POST"))
+        )
+        or currentUser.hasPermission(permission("EDIT_OTHER_POST"))
+    ) -%}
+
+{%- set canDelete =
+    not post.deleted
+    and currentUser is not null
+    and (
+        (
+            postAuthor is not null
+            and postAuthor.id == currentUser.id
+            and postAuthor.hasPermission(permission("DELETE_OWN_POST"))
+        )
+        or currentUser.hasPermission(permission("DELETE_OTHER_POST"))
+    ) -%}
+
+{%- set canViewAttachments = currentUser is not null -%}
+
+{%- set your_are_the_author =
+    currentUser is not null
+    and postAuthor is not null
+    and currentUser.id == postAuthor.id
+-%}
+
+{%- set is_op =
+    topicAuthor is not null
+    and postAuthor is not null
+    and postAuthor.id == topicAuthor.id
+-%}
+
+{%- set hasOtherAttachments = (fileAttachments|length > 0) -%}
+
+{% if post.deleted %}
+    <tr>
+        <td width="64"></td>
+        <td>
+            <a id="post-{{ post.id }}"></a>
+            <table cellspacing="0" cellpadding="4" bgcolor="pink" border="1" bordercolor="red">
+            <tr><td>
+                <img src="/ui/theme-files/old/delete.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;{#
+                #}{{ __("This post has been deleted") }}
+            </td></tr>
+            </table>
+        </td>
+    </tr>
+{% else %}
+    <tr>
+        <td width="64" rowspan="{{ hasOtherAttachments ? "3" : "2" }}" valign="top">
+            {% if not hide_pfp %}
+                {% if postAuthor %}
+                    {% if hide_actions %}
+                        <img class="media-object" alt="{{ __("Profile picture") }}" src="?_action=profilepicture&amp;user={{ postAuthor.id|url_encode }}" width="64" height="64">
+                    {% else %}
+                        <a href="?_action=viewuser&amp;user={{ postAuthor.id|url_encode }}">
+                            <img border="0" class="media-object" alt="{{ __("Profile picture") }}" src="?_action=profilepicture&amp;user={{ postAuthor.id|url_encode }}" width="64" height="64">
+                        </a>
+                    {% endif %}
+                {% else %}
+                    <div class="media-object" style="width:64px;height:64px"></div>
+                {% endif %}
+            {% endif %}
+        </td>
+        <th align="left" height="1" class="no-bold">
+            <a id="post-{{ post.id }}" data-text="{{ post.content }}"></a>
+            {% if not hide_actions %}
+                <div class="pull-right">{#
+                    #}<a href="#post-{{ post.id }}" class="seamless m-r"><img class="inline-icon" src="/ui/theme-files/old/link.gif" alt="{{ __("Permalink") }}" width="16" height="16" border="0" draggable="false"></a>
+                    {%- if canReply -%}
+                        <button data-post-id="{{ post.id }}" class="seamless m-r js-only _reply-post"><img class="inline-icon" src="/ui/theme-files/old/message.gif" alt="{{ __("Reply to post") }}" width="16" height="16" border="0" draggable="false"></button>
+                    {%- endif -%}
+                    {%- if canEdit -%}
+                        <form action="?_action=editpost" method="post" class="inline">{#
+                            #}<input type="hidden" name="post" value="{{ post.id }}">{#
+                            #}<button type="submit" class="seamless m-r"><img class="inline-icon" src="/ui/theme-files/old/message_edit.gif" alt="{{ __("Edit post") }}" width="16" height="16" border="0" draggable="false"></button>{#
+                        #}</form>
+                    {%- endif -%}
+                    {%- if canDelete -%}
+                        <form action="?_action=deletepost" method="post" class="inline">{#
+                            #}<input type="hidden" name="post" value="{{ post.id }}">{#
+                            #}<button type="submit" class="seamless m-r"><img class="inline-icon" src="/ui/theme-files/old/message_delete.gif" alt="{{ __("Delete post") }}" width="16" height="16" border="0" draggable="false"></button>{#
+                        #}</form>
+                    {%- endif -%}
+                </div>
+            {% endif %}
+            {% if postAuthor %}
+                {% if hide_actions %}
+                    <b>{{ postAuthor.displayName }}</b>
+                {% else %}
+                    <a href="?_action=viewuser&amp;user={{ postAuthor.id|url_encode }}"><b>{{ postAuthor.displayName }}</b></a>
+                {% endif %}
+                {% if your_are_the_author %}
+                    <font color="red"><small>[{{ __("You") }}]</small></font>
+                {% endif %}
+                {% if is_op %}
+                    <img alt="{{ __("Created this topic") }}" title="{{ __("Created this topic") }}" class="m-l inline-icon" width="16" height="16" draggable="false" src="/ui/theme-files/old/microphone.gif">
+                {% endif %}
+            {% else %}
+                <font color="gray"><i>{{ __("(deleted)") }}</i></font>
+            {% endif %}
+            <br>
+            <span class="_time">{{ post.postDate.format("c") }}</span>
+            {% if post.edited %}
+                <font color="gray"><i>{{ __("(edited)") }}</i></font>
+            {% endif %}
+        </th>
+    </tr>
+    <tr>
+        <td>
+            {{ renderPost(post.content) }}
+            {% if imageAttachments|length > 0 %}
+                <div class="post-images clearfix">
+                    {% for attachment in imageAttachments %}
+                        {% if hide_actions %}
+                            <span class="image-attachment" title="{{ attachment.name }}">
+                                <img border="0" class="image-attachment-image" src="?_action=thumb&amp;attachment={{ attachment.id|url_encode }}" alt="" width="100">
+                            </span>
+                        {% else %}
+                            <a class="image-attachment attachment" href="?_action=attachment&amp;attachment={{ attachment.id|url_encode }}" title="{{ attachment.name }}">
+                                <img border="0" class="image-attachment-image" src="?_action=thumb&amp;attachment={{ attachment.id|url_encode }}" alt="" width="100">
+                                {% if canViewAttachments %}
+                                    <img alt="" border="0" class="attachment-icon" width="18" height="18" draggable="false" src="/ui/theme-files/old/{{ attachment.mimeType starts with "video/" ? "film" : "photo" }}.gif">
+                                {% else %}
+                                    <img alt="" border="0" class="attachment-icon" width="18" height="18" draggable="false" src="/ui/theme-files/old/attachment_forbidden.gif">
+                                {% endif %}
+                            </a>
+                        {% endif %}
+                    {% endfor %}
+                </div>
+            {% endif %}
+        </td>
+    </tr>
+    {% if hasOtherAttachments %}
+        <tr>
+            <td>
+                {% for attachment in fileAttachments %}
+                    {% if hide_actions %}
+                        <u>{{ attachment.name }}</u>
+                    {% else %}
+                        <a class="attachment" href="?_action=attachment&amp;attachment={{ attachment.id|url_encode }}">
+                            {% if not canViewAttachments %}
+                                <img alt="" class="inline-icon" width="16" height="16" border="0" draggable="false" src="/ui/theme-files/old/forbidden.gif">
+                            {% endif %}
+                            {{ attachment.name }}
+                        </a>
+                    {% endif %}
+                {% endfor %}
+            </td>
+        </tr>
+    {% endif %}
+{% endif %}
diff --git a/src/application/templates/old/components/post_editor.twig b/src/application/templates/old/components/post_editor.twig
new file mode 100644
index 0000000..b9d688e
--- /dev/null
+++ b/src/application/templates/old/components/post_editor.twig
@@ -0,0 +1,37 @@
+<table border="1" bordercolor="silver" cellpadding="0" cellspacing="0" width="100%">
+<tr>
+<td style="line-height:1">
+    <button data-area="#{{ id }}" title="{{ __("Bold") }}" data-editor-command="bold" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_bold.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    <button data-area="#{{ id }}" title="{{ __("Italic") }}" data-editor-command="italic" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_italics.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    <button data-area="#{{ id }}" title="{{ __("Underlined") }}" data-editor-command="underline" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_underlined.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    <button data-area="#{{ id }}" title="{{ __("Strikethrough") }}" data-editor-command="strikethrough" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_strikethrough.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    &nbsp;
+    <button data-area="#{{ id }}" title="{{ __("Superscript") }}" data-editor-command="sup" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_superscript.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    <button data-area="#{{ id }}" title="{{ __("Subscript") }}" data-editor-command="sub" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/text_subscript.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    &nbsp;
+    <button data-area="#{{ id }}" title="{{ __("Quote") }}" data-editor-command="quote" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/message.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+    <button data-area="#{{ id }}" title="{{ __("Spoiler") }}" data-editor-command="spoiler" type="button" class="seamless editor-tool">{#
+        #}<img src="/ui/theme-files/old/eye.gif" width="16" height="16" border="0" draggable="false" alt="">{#
+    #}</button>
+</td>
+</tr>
+<tr>
+<td>
+    <textarea class="post-editor" id="{{ id }}" name="{{ name }}" required rows="12" cols="60">{{ value }}</textarea>
+</td>
+</tr>
+</table>
diff --git a/src/application/templates/old/components/topic_log.twig b/src/application/templates/old/components/topic_log.twig
new file mode 100644
index 0000000..b03024c
--- /dev/null
+++ b/src/application/templates/old/components/topic_log.twig
@@ -0,0 +1,60 @@
+{%- set user = "" -%}
+{%- if postAuthor is null -%}
+    {%- set user = __("(deleted)")|e("html") -%}
+{%- else -%}
+    {%- set user =
+        '<a href="?_action=viewuser&amp;user='
+        ~ postAuthor.id|url_encode|e("html")
+        ~ '">'
+        ~ postAuthor.displayName|e("html")
+        ~ '</a>'
+    -%}
+{%- endif -%}
+
+<tr>
+<td width="64">
+    <a id="post-{{ logMessage.id }}"></a>
+    {% if postAuthor %}
+        {% if hideActions %}
+            <img class="media-object" alt="{{ __("Profile picture") }}" src="?_action=profilepicture&amp;user={{ postAuthor.id|url_encode }}" width="64" height="64">
+        {% else %}
+            <a href="?_action=viewuser&amp;user={{ postAuthor.id|url_encode }}">
+                <img border="0" class="media-object" alt="{{ __("Profile picture") }}" src="?_action=profilepicture&amp;user={{ postAuthor.id|url_encode }}" width="64" height="64">
+            </a>
+        {% endif %}
+    {% else %}
+        <div class="media-object" style="width:64px;height:64px"></div>
+    {% endif %}
+</td>
+{% if logMessage.type == constant("mystic\\forum\\orm\\TopicLogMessage::LOCKED") %}
+    <td bgcolor="#FFCC99" align="center">
+        <span class="fa fa-lock text-info" aria-hidden="true"></span>
+        <em>{{ __("%user% locked this topic", {
+            "user": user,
+        }) }}</em>
+        <br>
+        <small class="_time">{{ logMessage.postDate.format("c") }}</small>
+{% elseif logMessage.type == constant("mystic\\forum\\orm\\TopicLogMessage::UNLOCKED") %}
+    <td bgcolor="#CCFFCC" align="center">
+        <span class="fa fa-unlock text-success" aria-hidden="true"></span>
+        <em>{{ __("%user% unlocked this topic", {
+            "user": user,
+        }) }}</em>
+        <br>
+        <small class="_time">{{ logMessage.postDate.format("c") }}</small>
+{% elseif logMessage.type == constant("mystic\\forum\\orm\\TopicLogMessage::TITLE_CHANGED") %}
+    <td bgcolor="#99CCFF" align="center">
+        <span class="fa fa-pencil text-info" aria-hidden="true"></span>
+        <em>{{ __("%user% changed the title of this topic from %old_title% to %new_title%", {
+            "user": user,
+            "old_title": '<strong>' ~ logMessage.params.old_value|default(__("unknown"))|e("html") ~ '</strong>',
+            "new_title": '<strong>' ~ logMessage.params.new_value|default(__("unknown"))|e("html") ~ '</strong>',
+        }) }}</em>
+        <br>
+        <small class="_time">{{ logMessage.postDate.format("c") }}</small>
+{% else %}
+    <td>
+        {{ __("unknown") }}
+{% endif %}
+</td>
+</tr>
diff --git a/src/application/templates/old/delete_post.twig b/src/application/templates/old/delete_post.twig
new file mode 100644
index 0000000..62c25fe
--- /dev/null
+++ b/src/application/templates/old/delete_post.twig
@@ -0,0 +1,42 @@
+{% set title = __("Delete post") %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<table border="1" bordercolor="silver" cellspacing="0" cellpadding="4" width="100%">
+    <tr>
+        <td bgcolor="pink">
+            <h3 class="m-0"><font color="red">{{ __("Do you want to delete this post?") }}</font></h3>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            {{ __("Are you sure you want to delete the following post:") }}<br><br>
+            <table border="1" bordercolor="silver" cellspacing="0" cellpadding="4" width="100%">
+            {% include "components/post.twig" with {
+                post: ctx.post,
+                postAuthor: ctx.postAuthor,
+                attachments: ctx.attachments,
+                hide_actions: true,
+            } %}
+            </table>
+        </td>
+    </tr>
+    <tr>
+        <td class="text-right">
+            <form action="?_action=deletepost" method="post" class="inline">
+                <input type="hidden" name="post" value="{{ ctx.post.id }}">
+                <input type="hidden" name="confirm" value="{{ ("confirm" ~ ctx.post.id)|hash("sha256", true)|base64_encode }}">
+                <button><font color="red"><b>{{ __("Delete post") }}</b></font></button>
+            </form>
+            <form action=".#post-{{ ctx.post.id }}" method="get" class="inline">
+                <input type="hidden" name="_action" value="viewtopic">
+                <input type="hidden" name="topic" value="{{ ctx.post.topicId }}">
+                <button>{{ __("Keep post") }}</button>
+            </form>
+        </td>
+    </tr>
+</table>
+
+{% endblock %}
diff --git a/src/application/templates/old/delete_topic.twig b/src/application/templates/old/delete_topic.twig
new file mode 100644
index 0000000..59d2a02
--- /dev/null
+++ b/src/application/templates/old/delete_topic.twig
@@ -0,0 +1,36 @@
+{% set title = __("Delete topic") %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<table border="1" bordercolor="silver" cellspacing="0" cellpadding="4" width="100%">
+    <tr>
+        <td bgcolor="pink">
+            <h3 class="m-0"><font color="red">{{ __("Do you want to delete this topic?") }}</font></h3>
+        </td>
+    </tr>
+    <tr>
+        <td>
+            {{ __("Are you sure you want to delete the topic <em>%topic%</em> including <strong>all posts and attachments</strong>?", {
+                "topic": ctx.topic.title|e("html"),
+            }) }}
+        </td>
+    </tr>
+    <tr>
+        <td class="text-right">
+            <form action="?_action=deletetopic" method="post" class="inline">
+                <input type="hidden" name="topic" value="{{ ctx.topic.id }}">
+                <input type="hidden" name="confirm" value="{{ ("confirm" ~ ctx.topic.id)|hash("sha256", true)|base64_encode }}">
+                <button><font color="red"><b>{{ __("Delete topic &amp; posts") }}</b></font></button>
+            </form>
+            <form action="." method="get" class="inline">
+                <input type="hidden" name="_action" value="viewtopic">
+                <input type="hidden" name="topic" value="{{ ctx.topic.id }}">
+                <button>{{ __("Keep topic") }}</button>
+            </form>
+        </td>
+    </tr>
+</table>
+
+{% endblock %}
diff --git a/src/application/templates/old/error_page.twig b/src/application/templates/old/error_page.twig
new file mode 100644
index 0000000..dde4057
--- /dev/null
+++ b/src/application/templates/old/error_page.twig
@@ -0,0 +1,12 @@
+{% set title = __("Error") %}
+{% extends "base.twig" %}
+
+{% block navbar %}
+    {% if not ctx.skipLoginCheck %}
+        {{ parent() }}
+    {% endif %}
+{% endblock %}
+
+{% block content %}
+    {% include "components/alert_error.twig" with { message: ctx.message } %}
+{% endblock %}
diff --git a/src/application/templates/old/info_page.twig b/src/application/templates/old/info_page.twig
new file mode 100644
index 0000000..e243b36
--- /dev/null
+++ b/src/application/templates/old/info_page.twig
@@ -0,0 +1,12 @@
+{% set title = __("Information") %}
+{% extends "base.twig" %}
+
+{% block navbar %}
+    {% if not ctx.skipLoginCheck %}
+        {{ parent() }}
+    {% endif %}
+{% endblock %}
+
+{% block content %}
+    {% include "components/alert_info.twig" with { message: ctx.message } %}
+{% endblock %}
diff --git a/src/application/templates/old/login.twig b/src/application/templates/old/login.twig
new file mode 100644
index 0000000..cbbb929
--- /dev/null
+++ b/src/application/templates/old/login.twig
@@ -0,0 +1,51 @@
+{% set title = __("Log in") %}
+{% set formId = "login" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<hr color="silver" noshade>
+<h1>{{ __("Log in") }}</h1>
+
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+<form action="{{ g.server.REQUEST_URI }}" method="post">
+    <input type="hidden" name="form_id" value="{{ formId }}">
+
+    <label for="i_username">{{ __("Username:") }}</label><br>
+    <input type="text" id="i_username" name="username" value="{{ lastFormField(formId, "username") }}" required><br>
+    <br>
+    <label for="i_password">{{ __("Password:") }}</label><br>
+    <input type="password" id="i_password" name="password" required><br>
+    <br>
+    <button type="submit">{{ __("Log in") }}</button>
+    <a href="?_action=pwreset">{{ __("I forgot my password") }}</a>
+
+    {% if constant("REGISTRATION_ENABLED") %}
+        <br><br>
+        <table border="1" bordercolor="green" cellspacing="0" cellpadding="4">
+        <tr>
+        <td>
+        {{ __("Don't have an account? %link%Register now%/link%", {
+            "link": '<a href="?_action=register">',
+            "/link": '</a>',
+        }) }}
+        </td>
+        </tr>
+        </table>
+    {% endif %}
+</form>
+
+{% endblock %}
+
+{% block scripts %}
+{{ parent() }}
+<script type="text/javascript">
+$(function() {
+    $("#i_username").focus();
+});
+</script>
+{% endblock %}
diff --git a/src/application/templates/old/new_password.twig b/src/application/templates/old/new_password.twig
new file mode 100644
index 0000000..02d6037
--- /dev/null
+++ b/src/application/templates/old/new_password.twig
@@ -0,0 +1,40 @@
+{% set title = __("Reset password") %}
+{% set formId = "pwnew" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<hr color="silver" noshade>
+<h1>{{ __("Reset password") }}</h1>
+
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+<form action="{{ g.server.REQUEST_URI }}" method="post">
+    <input type="hidden" name="form_id" value="{{ formId }}">
+    <input type="hidden" name="token" value="{{ g.get.token }}">
+    <input type="hidden" name="sig" value="{{ g.get.sig }}">
+
+    <label for="i_new_password">{{ __("New password:") }}</label><br>
+    <input class="form-control" type="password" id="i_new_password" name="new_password" required><br>
+    <br>
+
+    <label for="i_retype_password">{{ __("Retype password:") }}</label><br>
+    <input class="form-control" type="password" id="i_retype_password" name="retype_password" required><br>
+    <br>
+
+    <button type="submit">{{ __("Set new password") }}</button>
+</form>
+
+{% endblock %}
+
+{% block scripts %}
+{{ parent() }}
+<script type="text/javascript">
+$(function() {
+    $("#i_new_password").focus();
+});
+</script>
+{% endblock %}
diff --git a/src/application/templates/old/new_topic.twig b/src/application/templates/old/new_topic.twig
new file mode 100644
index 0000000..5063db1
--- /dev/null
+++ b/src/application/templates/old/new_topic.twig
@@ -0,0 +1,32 @@
+{% set title = __("New topic") %}
+{% set formId = "newtopic" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+<hr color="silver" noshade>
+
+<h1>{{ __("New topic") }}</h1>
+
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+<form action="{{ g.server.REQUEST_URI }}" method="post" enctype="multipart/form-data">
+    <input type="hidden" name="form_id" value="{{ formId }}">
+    <label for="i_title">{{ __("Topic title:") }}</label><br>
+    <input type="text" class="fw" id="i_title" name="title" value="{{ lastFormField(formId, "title") }}" required><br>
+    <br>
+    <label for="i_message">{{ __("Message:") }}</label><br>
+    {% include "components/post_editor.twig" with { name: "message", id: "i_message", value: lastFormField(formId, "message") } %}
+    <br>
+    <label for="i_files">{{ __("Attachments: <small>(max. %max_attachment_count% files, max. %max_attachment_size% MiB each)</small>", {
+        "max_attachment_count": constant("MAX_ATTACHMENT_COUNT"),
+        "max_attachment_size": constant("MAX_ATTACHMENT_SIZE") // (2**20),
+    }) }}</label><br>
+    <input type="file" name="files[]" id="i_files" multiple accept="*/*"><br>
+    <br>
+    <button type="submit">{{ __("Create topic") }}</button>
+</form>
+
+{% endblock %}
diff --git a/src/application/templates/old/password_reset.twig b/src/application/templates/old/password_reset.twig
new file mode 100644
index 0000000..c6e98c2
--- /dev/null
+++ b/src/application/templates/old/password_reset.twig
@@ -0,0 +1,45 @@
+{% set title = __("Reset password") %}
+{% set formId = "pwreset" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<hr color="silver" noshade>
+<h1>{{ __("Reset password") }}</h1>
+
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+<form action="{{ g.server.REQUEST_URI }}" method="post">
+    <input type="hidden" name="form_id" value="{{ formId }}">
+
+    <label for="i_email">{{ __("Email address:") }}</label><br>
+    <input class="form-control" type="email" id="i_email" name="email" value="{{ lastFormField(formId, "email") }}" required><br>
+    <br>
+    <button type="submit">{{ __("Reset password") }}</button><br>
+    <br>
+    <table border="1" bordercolor="green" cellspacing="0" cellpadding="4">
+    <tr>
+    <td>
+        {{ __("I know my password and I want to %link%log in%/link%!", {
+            "link": '<a href="?_action=auth">',
+            "/link": '</a>',
+        }) }}
+    </td>
+    </tr>
+    </table>
+</form>
+
+{% endblock %}
+
+{% block scripts %}
+{{ parent() }}
+<script type="text/javascript">
+$(function() {
+    $("#i_email").focus();
+});
+</script>
+{% endblock %}
+
diff --git a/src/application/templates/old/register.twig b/src/application/templates/old/register.twig
new file mode 100644
index 0000000..02e2bd0
--- /dev/null
+++ b/src/application/templates/old/register.twig
@@ -0,0 +1,77 @@
+{% set title = __("Register") %}
+{% set formId = "register" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<hr color="silver" noshade>
+    <h1>{{ __("Register") }}</h1>
+
+
+    {% if formError %}
+        {% include "components/alert_error.twig" with { message: formError } %}
+    {% endif %}
+    <form action="{{ g.server.REQUEST_URI }}" method="post">
+        <input type="hidden" name="form_id" value="{{ formId }}">
+
+        <label for="i_df82a9bc21">{{ __("Username:") }}</label><br>
+        <input class="form-control" id="i_df82a9bc21" type="text" name="df82a9bc21" value="{{ lastFormField(formId, "df82a9bc21") }}" required><br>
+        <br>
+        <label for="i_display_name">{{ __("Display name:") }}</label><br>
+        <input class="form-control" id="i_display_name" type="text" name="display_name" value="{{ lastFormField(formId, "display_name") }}" required><br>
+        <br>
+        <label for="i_password">{{ __("Choose password:") }}</label><br>
+        <input class="form-control" id="i_password" type="password" name="password" required><br>
+        <br>
+        <label for="i_password_retype">{{ __("Repeat password:") }}</label><br>
+        <input class="form-control" id="i_password_retype" type="password" name="password_retype" required><br>
+        <br>
+        <label for="i_email">{{ __("Email address:") }}</label><br>
+        <input class="form-control" id="i_email" type="email" name="email" value="{{ lastFormField(formId, "email") }}" required><br>
+        <br>
+        <label for="i_captcha">{{ __("CAPTCHA:") }}</label><br>
+        <img src="?_action=captcha&amp;t={{ "now"|date("Uv") }}" alt="CAPTCHA" width="192" height="48" id="captcha-img" border="1">
+        <table cellspacing="0" cellpadding="0"><tr>
+        <td>
+            <input type="text" name="captcha" id="i_captcha" class="form-control" required>
+        </td>
+        <td>
+            &nbsp;<button class="seamless" type="button" id="btn-refresh-captcha"><img src="/ui/theme-files/old/refresh.gif" width="16" height="16" border="0" draggable="false" alt="{{ __("New CAPTCHA") }}"></button>
+        </td>
+        </tr></table>
+        <br>
+
+        <button type="submit">{{ __("Register now") }}</button>
+        
+        <br><br>
+        <table border="1" bordercolor="green" cellspacing="0" cellpadding="4">
+        <tr>
+        <td>
+            {{ __("Already have an account? %link%Sign in now%/link%", {
+                "link": '<a href="?_action=auth">',
+                "/link": '</a>',
+            }) }}
+        </td>
+        </tr>
+        </table>
+    </form>
+{% endblock %}
+
+{% block scripts %}
+{{ parent() }}
+<script type="text/javascript">
+$(function() {
+    $("#btn-refresh-captcha").click(function() {
+        $("#captcha-img").attr("src", "?_action=captcha&t=" + new Date().getTime().toString());
+    });
+});
+</script>
+<script type="text/javascript">
+$(function() {
+    $("#i_df82a9bc21").focus();
+});
+</script>
+{% endblock %}
+
diff --git a/src/application/templates/old/search.twig b/src/application/templates/old/search.twig
new file mode 100644
index 0000000..0bdd497
--- /dev/null
+++ b/src/application/templates/old/search.twig
@@ -0,0 +1,77 @@
+{% set title = __("Search") %}
+{% set formId = "search" %}
+{% set formError = getAndClearFormError(formId) %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<hr color="silver" noshade>
+<h1>{{ __("Search") }}</h1>
+
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+
+<form action="." method="get">
+    <input type="hidden" name="form_id" value="{{ formId }}">
+    <input type="hidden" name="_action" value="search">
+    <table border="1" cellspacing="0" cellpadding="4" bordercolor="silver" width="100%">
+    <tr>
+    <td width="100%">
+        <input class="fw" type="search" id="i_query" name="query" value="{{ lastFormField(formId, "query")|default(g.get.query)|default("") }}" required placeholder="{{ __("Enter your search query...") }}">
+    </td>
+    <td>
+    <nobr>
+        <button type="submit">{{ __("Search") }}</button>
+    </nobr>
+    </td>
+    </tr>
+    </table>
+</form>
+
+{% if g.get.query is defined and g.get.query is not null and g.get.query != "" %}
+    {% if ctx.posts|length > 0 %}
+        <p>{{ __("%result_count% result(s) in %search_duration% second(s)", {
+            "result_count": ctx.posts|length,
+            "search_duration": ctx.search_duration|number_format(2, __(".", context: "Number formatting"), __(",", context: "Number formatting")),
+        }) }}</p>
+
+        {% for post in ctx.posts|filter(p => not p.deleted) %}
+            {% set hasAttachments = ctx.attachments[post.id]|length > 0 %}
+            {% set postAuthor = ctx.users[post.authorId] %}
+            <font size="2"><b><a href="?_action=viewtopic&amp;topic={{ post.topicId|url_encode }}#post-{{ post.id|url_encode }}">{{ renderPostSummary(post.content) }}</a></b></font><br>
+            {{ __("posted by %author% on %post_date% in %topic%", {
+                "author": '<b>' ~ (postAuthor ? postAuthor.displayName : __("unknown"))|e("html") ~ '</b>',
+                "post_date": '<br><span class="_time">' ~ post.postDate.format("c")|e("html") ~ '</span>',
+                "topic": '<br><font color="green">'
+                    ~ (ctx.topics[post.topicId].isLocked ? ('<img src="/ui/theme-files/old/lock_small.gif" class="inline-icon" width="10" height="10" draggable="false" alt="' ~ __("This topic has been locked") ~ '"> ') : '')
+                    ~ (ctx.topics[post.topicId] ? ctx.topics[post.topicId].title : null)|default(__("unknown"))|e("html") ~ '</font>',
+            }) }}
+            <br><br>
+        {% endfor %}
+    {% else %}
+        <hr color="silver" noshade>
+        <table cellspacing="0" cellpadding="4" bgcolor="lightskyblue" border="1" bordercolor="skyblue">
+        <tr><td>
+            <img src="/ui/theme-files/old/information.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;{#
+            #}{{ __("No results for this search") }}
+        </td></tr>
+        </table>
+        <br>
+    {% endif %}
+{% endif %}
+
+{% endblock %}
+
+
+{% block scripts %}
+{{ parent() }}
+{% if not (g.get.query is defined and g.get.query is not null and g.get.query != "") %}
+<script type="text/javascript">
+$(function() {
+    $("#i_query").focus();
+});
+</script>
+{% endif %}
+{% endblock %}
diff --git a/src/application/templates/old/view_topic.twig b/src/application/templates/old/view_topic.twig
new file mode 100644
index 0000000..613de49
--- /dev/null
+++ b/src/application/templates/old/view_topic.twig
@@ -0,0 +1,237 @@
+{% set canReply =
+    not ctx.topic.isLocked
+    and currentUser is not null
+    and currentUser.hasPermission(permission("CREATE_OWN_POST")) %}
+
+{% set canEdit =
+    currentUser is not null and (
+        (
+            ctx.topicAuthor is not null
+            and currentUser.id == ctx.topicAuthor.id
+            and ctx.topicAuthor.hasPermission(permission("EDIT_OWN_TOPIC"))
+        )
+        or currentUser.hasPermission(permission("EDIT_OTHER_TOPIC"))
+    ) %}
+
+{% set couldEditPost =
+    currentUser is not null
+    and (
+        currentUser.hasPermission(permission("EDIT_OWN_POST"))
+        or currentUser.hasPermission(permission("EDIT_OTHER_POST"))
+    ) %}
+
+{% set canDelete =
+    currentUser is not null and (
+        (
+            ctx.topicAuthor is not null
+            and currentUser.id == ctx.topicAuthor.id
+            and ctx.topicAuthor.hasPermission(permission("DELETE_OWN_TOPIC"))
+        )
+        or currentUser.hasPermission(permission("DELETE_OTHER_TOPIC"))
+    ) %}
+
+{% set title = ctx.topic.title %}
+{% extends "base.twig" %}
+
+{% block content %}
+
+{% set formError = getAndClearFormError("updateTopic") %}
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+{% set formError = getAndClearFormError("lockTopic") %}
+{% if formError %}
+    {% include "components/alert_error.twig" with { message: formError } %}
+{% endif %}
+{% set formError = null %}
+
+<hr color="silver" noshade>
+
+<div class="page-header margin-top-0 clearfix">
+    <div id="displayHeading">
+        <h1>
+            {% if ctx.topic.isLocked %}
+                <span class="fa fa-lock text-muted" aria-hidden="true"></span>
+            {% endif %}
+            {{ ctx.topic.title }}
+            <div class="pull-right text-normal">
+                {%- if canEdit and not ctx.topic.isLocked -%}
+                    <button id="btn-edit-title" class="seamless js-only m-r"><img src="/ui/theme-files/old/pencil.gif" width="16" height="16" draggable="false" alt="{{ __("Edit title") }}"></button>
+                {%- endif -%}
+                {%- if canReply -%}
+                    <button id="btn-reply" class="seamless js-only m-r"><img src="/ui/theme-files/old/undo.gif" width="16" height="16" draggable="false" alt="{{ __("Reply") }}"></button>
+                {%- endif -%}
+                {%- if canEdit -%}
+                    {%- if ctx.topic.isLocked -%}
+                        <form action="?_action=locktopic" method="post" class="inline">{#
+                            #}<input type="hidden" name="topic" value="{{ ctx.topic.id }}">{#
+                            #}<input type="hidden" name="locked" value="false">{#
+                            #}<button type="submit" class="seamless m-r"><img src="/ui/theme-files/old/lock_open.gif" width="16" height="16" draggable="false" alt="{{ __("Unlock topic") }}"></button>{#
+                        #}</form>
+                    {%- else -%}
+                        <form action="?_action=locktopic" method="post" class="inline">{#
+                            #}<input type="hidden" name="topic" value="{{ ctx.topic.id }}">{#
+                            #}<input type="hidden" name="locked" value="true">{#
+                            #}<button type="submit" class="seamless m-r"><img src="/ui/theme-files/old/lock.gif" width="16" height="16" draggable="false" alt="{{ __("Lock topic") }}"></button>{#
+                        #}</form>
+                    {%- endif -%}
+                {%- endif -%}
+                {%- if canDelete -%}
+                    <form action="?_action=deletetopic" method="post" class="inline">{#
+                        #}<input type="hidden" name="topic" value="{{ ctx.topic.id }}">{#
+                        #}<button type="submit" class="seamless m-r"><img src="/ui/theme-files/old/garbage.gif" width="16" height="16" draggable="false" alt="{{ __("Delete topic") }}"></button>{#
+                    #}</form>
+                {%- endif -%}
+            </div>
+        </h1>
+        {{ __("Started by %user% on %date%", {
+            "user": (ctx.topicAuthor is not null) ? ('<a href="?_action=viewuser&amp;user=' ~ ctx.topicAuthor.id|url_encode|e("html") ~ '">' ~ ctx.topicAuthor.displayName|e("html") ~ '</a>') : __("(deleted)"),
+            "date": '<span class="_time">' ~ ctx.topic.creationDate.format("c")|e("html") ~ '</span>',
+        }) }}
+    </div>
+    {% if canEdit %}
+        <form action="?_action=updatetopic" method="post" id="editHeading" style="display: none;" class="inline">
+            <input type="hidden" name="topic" value="{{ ctx.topic.id }}">
+            <table width="100%" cellspacing="0">
+            <tr>
+                <td width="100%">
+                    <input type="text" class="fw h1" name="title" id="i_edit_title" data-original-value="{{ ctx.topic.title }}" value="{{ ctx.topic.title }}">
+                </td>
+                <td align="right">
+                    <nobr>
+                        <button type="submit" class="btn btn-success">{{ __("Save changes") }}</button>
+                        <button type="button" id="topicTitleEditCancel">{{ __("Cancel") }}</button>
+                    </nobr>
+                </td>
+            </tr>
+            </table>
+        </form>
+    {% endif %}
+</div>
+<script>
+{% if canEdit %}
+$(function() {
+    $("#btn-edit-title").click(function() {
+        $("#displayHeading").hide();
+        $("#editHeading").show();
+        $("#i_edit_title").val($("#i_edit_title").attr("data-original-value")).focus();
+    });
+    $("#topicTitleEditCancel").click(function() {
+        $("#displayHeading").show();
+        $("#editHeading").hide();
+    });
+});
+{% endif %}
+</script>
+{% if couldEditPost %}
+<script>
+$(function() {
+    $("._edit-post").click(function() {
+        var $post = $("#post-" + $(this).attr("data-post-id"));
+        var $postContent = $post.find(".post-content");
+        $("#i_edit_message").css("height", "").val($post.attr("data-text"));
+        $("#i_edit_post").val($(this).attr("data-post-id"));
+        $("#diag-edit-post").modal();
+    });
+    $("#diag-edit-post").on("shown.bs.modal", function() {
+        $("#i_edit_message").focus();
+    });
+});
+{% endif %}
+{% if canReply %}
+$(function() {
+    function focusReplyBox() {
+        var msgInput = $("#i_message");
+        msgInput[0].scrollIntoView();
+        msgInput.focus();
+    }
+    $("#btn-reply").click(function() {
+        focusReplyBox();
+    });
+    $("._reply-post").click(function() {
+        var text = $("#post-" + $(this).attr("data-post-id")).attr("data-text");
+        var val = $("#i_message").val();
+        var lines = text.split("\n");
+        for (var i = 0; i < lines.length; ++i)
+            val += "\n> " + lines[i];
+        val += "\n\n";
+        $("#i_message").val(val.replace(/^\n+/, ""));
+        focusReplyBox();
+    });
+});
+{% endif %}
+</script>
+
+<table border="1" cellspacing="0" cellpadding="4" bordercolor="silver" width="100%" bgcolor="white">
+{% for item in ctx.allItems %}
+    {% if item.type == "post" %}
+        {% include "components/post.twig" with {
+            post: item.post,
+            postAuthor: item.postAuthor,
+            topicAuthor: item.topicAuthor,
+            topic: item.topic,
+            attachments: item.attachments,
+            hide_actions: false,
+            hide_pfp: false,
+        } %}
+    {% elseif item.type == "logMessage" %}
+        {% include "components/topic_log.twig" with {
+            type: item.type,
+            logMessage: item.logMessage,
+            postAuthor: item.postAuthor,
+            topicAuthor: item.topicAuthor,
+            topic: item.topic,
+            hide_actions: false,
+            hide_pfp: false,
+        } %}
+    {% endif %}
+{% endfor %}
+</table>
+
+{% if ctx.topic.isLocked %}
+    <br>
+    <table cellspacing="0" cellpadding="8" bgcolor="#FFCC99" border="1" bordercolor="#996633" width="100%">
+    <tr><td align="center">
+        <img src="/ui/theme-files/old/lock_large.gif" border="0" alt="" width="32" height="32" draggable="false"><br>
+        <i>{{ __("This topic has been locked") }}</i>
+    </td></tr>
+    </table>
+    <br>
+{% elseif currentUser is not null %}
+    {% set formId = "addpost" %}
+    <h3 id="form">{{ __("Reply to this topic") }}</h3>
+    {% set formError = getAndClearFormError(formId) %}
+    {% if formError %}
+        {% include "components/alert_error.twig" with { message: formError } %}
+    {% endif %}
+    <form action="{{ g.server.REQUEST_URI }}#form" method="post" enctype="multipart/form-data">
+        <input type="hidden" name="form_id" value="{{ formId }}">
+        
+        <label for="i_message">{{ __("Message:") }}</label><br>
+        {% include "components/post_editor.twig" with { value: "", name: "message", id: "i_message" } %}
+        <br>
+        <label for="i_files">{{ __("Attachments: <small>(max. %max_attachment_count% files, max. %max_attachment_size% MiB each)</small>", {
+            "max_attachment_count": constant("MAX_ATTACHMENT_COUNT"),
+            "max_attachment_size": constant("MAX_ATTACHMENT_SIZE") // (2**20),
+        }) }}</label><br>
+        <input type="file" name="files[]" id="i_files" multiple accept="*/*"><br>
+        <br>
+        <button type="submit">{{ __("Post reply") }}</button>
+    </form>
+{% else %}
+    <br>
+    <table cellspacing="0" cellpadding="8" bgcolor="lightskyblue" border="1" bordercolor="skyblue" width="100%">
+    <tr><td align="center">
+        <h3>{{ __("Log in to reply to this topic") }}</h3>
+        <form action="." method="get" class="inline">
+            <input type="hidden" name="_action" value="auth">
+            <input type="hidden" name="next" value="{{ g.server.REQUEST_URI }}">
+            <button type="submit">{{ __("Log in") }}</button>
+        </form>
+    </td></tr>
+    </table>
+    <br>
+{% endif %}
+
+
+{% endblock %}
diff --git a/src/application/templates/old/view_topics.twig b/src/application/templates/old/view_topics.twig
new file mode 100644
index 0000000..e6e69b7
--- /dev/null
+++ b/src/application/templates/old/view_topics.twig
@@ -0,0 +1,30 @@
+{% extends "base.twig" %}
+
+{% block content %}
+
+{% if currentUser.hasPermission(permission("CREATE_OWN_TOPIC")) %}
+    <p align="right">
+        <img src="/ui/theme-files/old/message_add.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon">&nbsp;{#
+        #}<a href="?_action=newtopic">{{ __("New topic") }}</a>
+    </p>
+    <hr color="silver" noshade>
+{% endif %}
+
+<table width="100%" border="1" cellpadding="4" cellspacing="0" bordercolor="silver" bgcolor="white">
+{% for topic in ctx.topics %}
+    <tr>
+        <td>
+            <a class="list-group-item" href="?_action=viewtopic&amp;topic={{ topic.id|url_encode }}">
+                {% if topic.isLocked -%}
+                    <img src="/ui/theme-files/old/lock.gif" border="0" alt="" width="16" height="16" draggable="false" class="inline-icon m-r">
+                {%- endif -%}
+                {{ topic.title }}
+                <br>
+                <small class="_time">{{ topic.creationDate.format("c") }}</small>
+            </a>
+        </td>
+    </tr>
+{% endfor %}
+</table>
+
+{% endblock %}
diff --git a/src/application/templates/old/view_user.twig b/src/application/templates/old/view_user.twig
new file mode 100644
index 0000000..311dfb1
--- /dev/null
+++ b/src/application/templates/old/view_user.twig
@@ -0,0 +1,196 @@
+{% set canEdit =
+    currentUser is not null
+    and (
+        (
+            ctx.user.id == currentUser.id
+            and currentUser.hasPermission(permission("EDIT_OWN_USER"))
+        )
+        or currentUser.hasPermission(permission("EDIT_OTHER_USER"))
+    ) %}
+
+{% set isOwnProfile =
+    currentUser is not null
+    and currentUser.id == ctx.user.id %}
+
+{% set sUserPossessive = isOwnProfile ? "Your posts" : "%display_name%'s posts" %}
+
+{% set emailPending = isOwnProfile and ctx.user.pendingEmail is not null %}
+
+{% set title = ctx.user.displayName %}
+
+{% extends "base.twig" %}
+
+{% block content %}
+
+<div class="clearfix">
+    <img class="pull-left m-r-lg" src="?_action=profilepicture&amp;user={{ ctx.user.id|url_encode }}" alt="{{ __("Profile picture") }}" width="64" height="64">
+    <span class="h1">{{ ctx.user.displayName }}</span>
+    {% if isOwnProfile %}
+        <font color="red">[{{ __("You") }}]</font>
+    {% endif %}<br>
+    @{{ ctx.user.name }}<br>
+    <font color="gray">{{ __("Member since %join_date%", {
+        "join_date": '<span class="_date">' ~ (ctx.dateJoined.format("c")|e("html")) ~ '</span>',
+    }) }}</font>
+</div>
+<hr color="silver" noshade>
+
+{% if canEdit %}
+<table>
+<tr>
+<td valign="top" width="100%">
+{% endif %}
+
+<h3>{{ __(sUserPossessive, {
+    "display_name": ctx.user.displayName|e("html"),
+}) }}</h3>
+
+{% if ctx.posts|length > 0 %}
+    <table border="1" width="100%" cellspacing="0" cellpadding="4" bordercolor="silver">
+        {% for post in ctx.posts %}
+            <tr>
+                <td>
+                    {% set hasAttachments = ctx.attachments[post.id] is defined and ctx.attachments[post.id]|length > 0 %}
+                    {% if hasAttachments %}
+                        <img src="/ui/theme-files/old/paperclip_small.gif" class="inline-icon" width="10" height="10" draggable="false" alt="">
+                    {% endif %}
+                    <a href="?_action=viewtopic&amp;topic={{ post.topicId|url_encode }}#post-{{ post.id|url_encode }}">{{ renderPostSummary(post.content) }}</a>
+                    <br>
+                    {{ __("posted on %post_date% in %topic%", {
+                        "post_date": '<span class="_time">' ~ post.postDate.format("c")|e("html") ~ '</span>',
+                        "topic": '<br><font color="green">'
+                            ~ (ctx.topics[post.topicId].isLocked ? ('<img src="/ui/theme-files/old/lock_small.gif" class="inline-icon" width="10" height="10" draggable="false" alt="' ~ __("This topic has been locked") ~ '"> ') : '')
+                            ~ (ctx.topics[post.topicId] ? ctx.topics[post.topicId].title : null)|default(__("unknown"))|e("html") ~ '</font>',
+                    }) }}
+                </td>
+            </tr>
+        {% endfor %}
+    </table>
+{% else %}
+    {% include "components/alert_info.twig" with { message: __("This user has not posted anything yet") } %}
+{% endif %}
+
+{% if canEdit %}
+</td>
+<td width="250" valign="top">
+    <h3>{{ __("Edit profile") }}</h3>
+    {% set formId = "update_profile" %}
+    {% set formError = getAndClearFormError(formId) %}
+    {% if formError %}
+        {% include "components/alert_error.twig" with { message: formError } %}
+    {% endif %}
+    <form action="{{ g.server.REQUEST_URI }}" method="post" enctype="multipart/form-data">
+        <input type="hidden" name="form_id" value="{{ formId }}">
+        
+        <label for="i_display_name">{{ __("Display name:") }}</label><br>
+        <input required type="text" name="display_name" id="i_display_name" value="{{ ctx.user.displayName }}"><br>
+        <br>
+        
+        <label for="i_name">{{ __("Username:") }}</label><br>
+        {% if ctx.lastNameChangeTooRecent %}
+            <input type="text" id="i_name" value="{{ ctx.user.name }}" disabled><br>
+            <font color="red"><small><strong>{{ __("You can only change your username every 30 days!") }}</strong></small></font><br>
+        {% else %}
+            <input required type="text" name="name" id="i_name" value="{{ ctx.user.name }}"><br>
+        {% endif %}
+        <br>
+        
+        <label for="i_email">{{ __("Email address:") }}</label><br>
+        {% if emailPending %}
+            <input type="email" id="i_email" value="{{ ctx.user.email }}" disabled><br>
+        {% else %}
+            <input required type="email" id="i_email" name="email" value="{{ ctx.user.email }}"><br>
+        {% endif %}
+
+        
+        <label>{{ __("Profile picture:") }}</label><br>
+        <div class="radio margin-top-0 {{ ctx.user.profilePicture is empty ? " disabled text-muted" }}">
+            <label>
+                <input type="radio" name="pfp_action" id="pfp_action_1" value="keep"{{ ctx.user.profilePicture is not empty ? ' checked' : ' disabled' }}>
+                {{ __("Keep current profile picture") }}
+            </label>
+        </div>
+        <div class="radio">
+            <label>
+                <input type="radio" name="pfp_action" id="pfp_action_2" value="remove"{{ ctx.user.profilePicture is empty ? ' checked' : '' }}>
+                {% if ctx.user.profilePicture is empty %}
+                    {{ __("No profile picture") }}
+                {% else %}
+                    {{ __("Remove profile picture") }}
+                {% endif %}
+            </label>
+        </div>
+        <div class="radio">
+            <label>
+                <input type="radio" name="pfp_action" value="replace" id="pfp_action_3">
+                {{ __("Upload new profile picture") }}
+            </label>
+        </div>
+        <input type="file" name="pfp" id="i_pfp" accept="image/png,image/jpeg" class="m-l-lg" style="width:180px"><br>
+        <br>
+        
+        <button type="submit">{{ __("Save changes") }}</button><br>
+    </form>
+    {% if isOwnProfile %}
+        <hr color="silver" noshade>
+        <h3>{{ __("Change password") }}</h3>
+        {% set formId = "update_password" %}
+        {% set formError = getAndClearFormError(formId) %}
+        {% if formError %}
+            {% include "components/alert_error.twig" with { message: formError } %}
+        {% endif %}
+        <form action="{{ g.server.REQUEST_URI }}" method="post">
+            <input type="hidden" name="form_id" value="{{ formId }}">
+            
+            <label for="i_current_password">{{ __("Current password:") }}</label><br>
+            <input autocomplete="current-password" required class="form-control" type="password" name="current_password" id="i_current_password" required><br>
+            <br>
+
+            <label for="i_new_password">{{ __("New password:") }}</label><br>
+            <input autocomplete="new-password" required class="form-control" type="password" name="new_password" id="i_new_password" required><br>
+            <br>
+            
+            <label for="i_retype_password">{{ __("Retype password:") }}</label><br>
+            <input autocomplete="new-password" required class="form-control" type="password" name="retype_password" id="i_retype_password" required><br>
+            <br>
+            
+            <button type="submit">{{ __("Change password") }}</button>
+        </form>
+    {% endif %}
+</td>
+</tr>
+</table>
+{% endif %}
+
+<script>
+$(function() {
+    $(".post-container").each(function(i, e) {
+        if ($(e).height() > 900) { // more than 800 so it doesn't collapse just a few pixels
+            $(e).addClass("collapsed");
+        }
+        $(e).find(".post-container-controls button").click(function() {
+            $(e).removeClass("collapsed");
+        });
+    });
+});
+{% if canEdit %}
+$(function() {
+    function _hide() {
+        $("#i_pfp").hide().prop("disabled", true).prop("required", false);
+        $("#i_pfp + .file-input-group").hide().find("button").prop("disabled", true);
+    }
+    _hide();
+    setTimeout(_hide, 10);
+    $("[name='pfp_action']").on("change input check click", function() {
+        if ($("#pfp_action_3").is(":checked")) {
+            $("#i_pfp").show().prop("disabled", false).prop("required", true);
+            $("#i_pfp + .file-input-group").show().find("button").prop("disabled", false);
+        } else {
+            _hide();
+        }
+    })
+});
+{% endif %}
+</script>
+
+{% endblock %}
-- 
cgit v1.2.3