summaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
authorczaks <marcin@6irc.net>2013-08-05 06:03:40 -0400
committerczaks <marcin@6irc.net>2013-08-05 06:03:40 -0400
commita84c4510fccfdc0cfb6f187633daea10dc70f326 (patch)
tree6077f5211196ae40cac0184bb7cc67b81d320b0b /templates
parent33c7abf11f3a9b5c0964a2d7a25533c2849dbc78 (diff)
parenta8327c3a37fd22d2aa5d63061c9d3eaa30ae425a (diff)
Merge branch 'master' of github.com:vichan-devel/Tinyboard
Conflicts: js/post-hider.js
Diffstat (limited to 'templates')
-rw-r--r--templates/error.html18
-rw-r--r--templates/generic_page.html3
-rw-r--r--templates/header.html31
-rw-r--r--templates/index.html122
-rw-r--r--templates/installer/check-requirements.html54
-rw-r--r--templates/installer/config.html95
-rw-r--r--templates/main.js503
-rw-r--r--templates/mod/ban_form.html4
-rw-r--r--templates/mod/config-editor-php.html63
-rw-r--r--templates/mod/config-editor.html34
-rw-r--r--templates/mod/dashboard.html32
-rw-r--r--templates/mod/debug/recent_posts.html4
-rw-r--r--templates/mod/edit_post_form.html2
-rw-r--r--templates/mod/log.html6
-rw-r--r--templates/mod/login.html52
-rw-r--r--templates/mod/news.html2
-rw-r--r--templates/mod/search_results.html97
-rw-r--r--templates/page.html50
-rwxr-xr-xtemplates/post_form.html20
-rw-r--r--templates/post_reply.html222
-rw-r--r--templates/post_thread.html24
-rw-r--r--templates/posts.sql65
-rw-r--r--templates/themes/basic/theme.php2
-rw-r--r--templates/themes/catalog/theme.php4
-rw-r--r--templates/themes/categories/news.html8
-rw-r--r--templates/themes/categories/theme.php2
-rw-r--r--templates/themes/frameset/theme.php2
-rw-r--r--templates/themes/recent/theme.php29
-rw-r--r--templates/themes/rrdtool/theme.php5
-rw-r--r--templates/themes/sitemap/theme.php2
-rw-r--r--templates/themes/ukko/theme.php6
-rw-r--r--templates/themes/ukko/ukko.js108
-rw-r--r--templates/thread.html103
33 files changed, 1132 insertions, 642 deletions
diff --git a/templates/error.html b/templates/error.html
new file mode 100644
index 00000000..3b8eb693
--- /dev/null
+++ b/templates/error.html
@@ -0,0 +1,18 @@
+<div style="text-align:center">
+ <h2 style="margin:20px 0">{{ message }}</h2>
+ {% if board %}
+ <p>
+ <a href="{{ config.root }}{% if mod %}{{ config.file_mod }}?/{% endif %}{{ board.dir }}{{ config.file_index }}">
+ {% trans 'Go back' %}
+ </a>
+ </p>
+ {% endif %}
+</div>
+{% if debug and config.debug %}
+ <hr>
+ <h3>{% trans 'Error information' %}</h3>
+ <pre style="white-space:pre-wrap;font-size: 10px;">
+ {{ debug }}
+ </pre>
+ <hr>
+{% endif %} \ No newline at end of file
diff --git a/templates/generic_page.html b/templates/generic_page.html
index 41300f6b..70cb15aa 100644
--- a/templates/generic_page.html
+++ b/templates/generic_page.html
@@ -22,7 +22,8 @@
{% include 'attention_bar.html' %}
{% include 'post_form.html' %}
- {% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
+
+ {% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
<hr />
<form name="postcontrols" action="{{ config.post_url }}" method="post">
<input type="hidden" name="board" value="{{ board.uri }}" />
diff --git a/templates/header.html b/templates/header.html
index 95e0bc09..d054fd6d 100644
--- a/templates/header.html
+++ b/templates/header.html
@@ -4,6 +4,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=yes">
{% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}">{% endif %}
{% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
+ {% if config.font_awesome %}<link rel="stylesheet" media="screen" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
<script type="text/javascript">var configRoot="{{ config.root }}";</script>
{% if not nojavascript %}
<script type="text/javascript" src="{{ config.url_javascript }}"></script>
@@ -12,17 +13,31 @@
{% endif %}
{% endif %}
{% if config.recaptcha %}<style type="text/css">{% raw %}
- .recaptcha_image_cell {
- background: none !important;
+ #recaptcha_area {
+ float: none !important;
+ padding: 0 !important;
}
- table.recaptchatable {
+ #recaptcha_logo, #recaptcha_privacy {
+ display: none;
+ }
+ #recaptcha_table {
border: none !important;
}
- #recaptcha_logo, #recaptcha_tagline {
- display: none;
- float: right;
+ #recaptcha_table tr:first-child {
+ height: auto;
+ }
+ .recaptchatable img {
+ float: none !important;
+ }
+ #recaptcha_response_field {
+ font-size: 10pt !important;
+ border: 1px solid #a9a9a9 !important;
+ padding: 1px !important;
+ }
+ td.recaptcha_image_cell {
+ background: transparent !important;
}
- .recaptchatable a {
- display: block;
+ .recaptchatable, #recaptcha_area tr, #recaptcha_area td, #recaptcha_area th {
+ padding: 0 !important;
}
{% endraw %}</style>{% endif %}
diff --git a/templates/index.html b/templates/index.html
index 451ca8b1..12150d0b 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -1,61 +1,61 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
-
- <script type="text/javascript">
- {% if config.quick_reply %}
- var new_reply_string = "{{ config.button_reply }}";
- {% endif %}
- {% if not no_post_form %}
- var active_page = "index";
- {% else %}
- var active_page = "ukko";
- {% endif %}
- </script>
-
- {% include 'header.html' %}
- <title>{{ board.url }} - {{ board.title|e }}</title>
-</head>
-<body>
- {{ boardlist.top }}
- {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
- {% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
- <header>
- <h1>{{ board.url }} - {{ board.title|e }}</h1>
- <div class="subtitle">
- {% if board.subtitle %}
- {{ board.subtitle|e }}
- {% endif %}
- {% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
- </div>
- </header>
-
- {% include 'attention_bar.html' %}
- {% if not no_post_form %}
- {% include 'post_form.html' %}
- {% else %}
- {% include 'boardlist.html' %}
- {% endif %}
-
- {% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
- <hr />
- <form name="postcontrols" action="{{ config.post_url }}" method="post">
- <input type="hidden" name="board" value="{{ board.uri }}" />
- {% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
- {{ body }}
- {% include 'report_delete.html' %}
- </form>
- <div class="pages">{{ btn.prev }} {% for page in pages %}
- [<a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>]{% if loop.last %} {% endif %}
- {% endfor %} {{ btn.next }}</div>
- {{ boardlist.bottom }}
- <footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
- {% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
- </footer>
- <script type="text/javascript">{% raw %}
- ready();
- {% endraw %}</script>
-</body>
-</html>
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+
+ <script type="text/javascript">
+ {% if config.quick_reply %}
+ var new_reply_string = "{{ config.button_reply }}";
+ {% endif %}
+ {% if not no_post_form %}
+ var active_page = "index";
+ {% else %}
+ var active_page = "ukko";
+ {% endif %}
+ </script>
+
+ {% include 'header.html' %}
+ <title>{{ board.url }} - {{ board.title|e }}</title>
+</head>
+<body>
+ {{ boardlist.top }}
+ {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
+ {% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
+ <header>
+ <h1>{{ board.url }} - {{ board.title|e }}</h1>
+ <div class="subtitle">
+ {% if board.subtitle %}
+ {{ board.subtitle|e }}
+ {% endif %}
+ {% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
+ </div>
+ </header>
+
+ {% include 'attention_bar.html' %}
+ {% if not no_post_form %}
+ {% include 'post_form.html' %}
+ {% else %}
+ {% include 'boardlist.html' %}
+ {% endif %}
+
+ {% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
+ <hr />
+ <form name="postcontrols" action="{{ config.post_url }}" method="post">
+ <input type="hidden" name="board" value="{{ board.uri }}" />
+ {% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
+ {{ body }}
+ {% include 'report_delete.html' %}
+ </form>
+ <div class="pages">{{ btn.prev }} {% for page in pages %}
+ [<a {% if page.selected %}class="selected"{% endif %}{% if not page.selected %}href="{{ page.link }}"{% endif %}>{{ page.num }}</a>]{% if loop.last %} {% endif %}
+ {% endfor %} {{ btn.next }}</div>
+ {{ boardlist.bottom }}
+ <footer>
+ <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
+ {% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
+ </footer>
+ <script type="text/javascript">{% raw %}
+ ready();
+ {% endraw %}</script>
+</body>
+</html>
diff --git a/templates/installer/check-requirements.html b/templates/installer/check-requirements.html
new file mode 100644
index 00000000..b6003f3a
--- /dev/null
+++ b/templates/installer/check-requirements.html
@@ -0,0 +1,54 @@
+<div style="max-width:700px;margin:auto">
+ <h2 style="text-align:center">Pre-installation tests</h2>
+ <table class="modlog" style="margin-top:10px;max-width:600px">
+ <tr>
+ <th>Category</th>
+ <th>Test</th>
+ <th>Result</th>
+ </tr>
+ {% set errors = 0 %}
+ {% set warnings = 0 %}
+ {% for test in tests %}
+ <tr>
+ <td class="minimal"><strong>{{ test.category }}</strong></td>
+ <td>{{ test.name }}</td>
+ <td class="minimal" style="text-align:center">
+ {% if test.result %}
+ <i style="font-size:11pt;color:#090" class="icon-check-sign"></i>
+ {% else %}
+ {% if test.required %}
+ {% set errors = errors + 1 %}
+ <i style="font-size:11pt;color:#d00" class="icon-exclamation-sign"></i>
+ {% else %}
+ {% set warnings = warnings + 1 %}
+ <i style="font-size:11pt;color:#f80" class="icon-warning-sign"></i>
+ {% endif %}
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+ {% if errors or warnings %}
+ <p><strong>There were {{ errors }} error(s) and {{ warnings }} warning(s).</strong></p>
+ <ul>
+ {% for test in tests if not test.result%}
+ <li style="margin-bottom:5px">
+ {% if test.required %}
+ <i style="font-size:11pt;color:#d00" class="icon-exclamation-sign"></i> <strong>Error:</strong>
+ {% else %}
+ <i style="font-size:11pt;color:#f80" class="icon-warning-sign"></i> <strong>Warning:</strong>
+ {% endif %}
+ {{ test.message }}
+ </li>
+ {% endfor %}
+ </ul>
+ {% if errors %}
+ <p style="text-align:center"><a href="?step=2">Clik here to ignore errors and attempt installing anyway (not recommended).</a></p>
+ {% else %}
+ <p style="text-align:center"><a href="?step=2">Clik here to proceed with installation.</a></p>
+ {% endif %}
+ {% else %}
+ <p>There were no errors or warnings. Good!</p>
+ <p style="text-align:center"><a href="?step=2">Clik here to proceed with installation.</a></p>
+ {% endif %}
+</div>
diff --git a/templates/installer/config.html b/templates/installer/config.html
new file mode 100644
index 00000000..193bb98b
--- /dev/null
+++ b/templates/installer/config.html
@@ -0,0 +1,95 @@
+<form action="?step=3" method="post" autocomplete="off">
+ <fieldset>
+ <legend>Database (MySQL)</legend>
+ <label for="db_server">Server:</label>
+ <input type="text" id="db_server" name="db[server]" value="{{ config.db.server }}">
+
+ <label for="db_db">Database:</label>
+ <input type="text" id="db_db" name="db[database]" value="{{ config.db.database }}">
+
+ <label for="db_prefix">Table prefix (optional):</label>
+ <input type="text" id="db_prefix" name="db[prefix]" value="{{ config.db.prefix }}">
+
+ <label for="db_user">Username:</label>
+ <input type="text" id="db_user" name="db[user]" value="{{ config.db.user }}">
+
+ <label for="db_pass">Password:</label>
+ <input type="password" id="db_pass" name="db[password]" value="">
+ </fieldset>
+ <p style="text-align:center" class="unimportant">The following is all later configurable. For more options, <a href="http://tinyboard.org/docs/?p=Config">edit your configuration files</a> after installing.</p>
+ <fieldset>
+ <legend>Cookies</legend>
+ <label for="cookies_mod">Moderator cookie:</label>
+ <input type="text" id="cookies_mod" name="cookies[mod]" value="{{ config.cookies.mod }}">
+
+ <label for="cookies_salt">Secure salt:</label>
+ <input type="text" id="cookies_salt" name="cookies[salt]" value="{{ config.cookies.salt }}" size="40">
+ </fieldset>
+
+ <fieldset>
+ <legend>Flood control</legend>
+ <label for="flood_time">Seconds before each post:</label>
+ <input type="text" id="flood_time" name="flood_time" value="{{ config.flood_time }}">
+
+ <label for="flood_time_ip">Seconds before you can repost something (post the exact same text):</label>
+ <input type="text" id="flood_time_ip" name="flood_time_ip" value="{{ config.flood_time_ip }}">
+
+ <label for="flood_time_same">Same as above, but with a different IP address:</label>
+ <input type="text" id="flood_time_same" name="flood_time_same" value="{{ config.flood_time_same }}">
+
+ <label for="max_body">Maximum post body length:</label>
+ <input type="text" id="max_body" name="max_body" value="{{ config.max_body }}">
+
+ <label for="reply_limit">Replies in a thread before it can no longer be bumped:</label>
+ <input type="text" id="reply_limit" name="reply_limit" value="{{ config.reply_limit }}">
+
+ <label for="max_links">Maximum number of links in a single post:</label>
+ <input type="text" id="max_links" name="max_links" value="{{ config.max_links }}">
+ </fieldset>
+
+ <fieldset>
+ <legend>Images</legend>
+ <label for="max_filesize">Maximum image filesize (bytes):</label>
+ <input type="text" id="max_filesize" name="max_filesize" value="{{ config.max_filesize }}">
+
+ <label for="thumb_width">Thumbnail width:</label>
+ <input type="text" id="thumb_width" name="thumb_width" value="{{ config.thumb_width }}">
+
+ <label for="thumb_height">Thumbnail height:</label>
+ <input type="text" id="thumb_height" name="thumb_height" value="{{ config.thumb_height }}">
+
+ <label for="max_width">Maximum image width:</label>
+ <input type="text" id="max_width" name="max_width" value="{{ config.max_width }}">
+
+ <label for="max_height">Maximum image height:</label>
+ <input type="text" id="max_height" name="max_height" value="{{ config.max_height }}">
+ </fieldset>
+
+ <fieldset>
+ <legend>Display</legend>
+ <label for="threads_per_page">Threads per page:</label>
+ <input type="text" id="threads_per_page" name="threads_per_page" value="{{ config.threads_per_page }}">
+
+ <label for="max_pages">Page limit:</label>
+ <input type="text" id="max_pages" name="max_pages" value="{{ config.max_pages }}">
+
+ <label for="threads_preview">Number of replies to show per thread on the index page:</label>
+ <input type="text" id="threads_preview" name="threads_preview" value="{{ config.threads_preview }}">
+ </fieldset>
+
+ <fieldset>
+ <legend>Directories</legend>
+ <label for="root">Root URI (include trailing slash):</label>
+ <input type="text" id="root" name="root" value="{{ config.root }}" size="40">
+ </fieldset>
+
+ <fieldset>
+ <legend>Miscellaneous</legend>
+ <label for="secure_trip_salt">Secure trip (##) salt:</label>
+ <input type="text" id="secure_trip_salt" name="secure_trip_salt" value="{{ config.secure_trip_salt }}" size="40">
+ </fieldset>
+
+ <p style="text-align:center">
+ <input type="submit" value="Complete installation">
+ </p>
+</form>
diff --git a/templates/main.js b/templates/main.js
index 31c0254a..71dcd92a 100644
--- a/templates/main.js
+++ b/templates/main.js
@@ -1,232 +1,271 @@
-{% raw %}
-
-/* gettext-compatible _ function, example of usage:
- *
- * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php)
- * > alert(_("Hello!"));
- * Witaj!
- */
-function _(s) {
- return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s;
-}
-
-/* printf-like formatting function, example of usage:
- *
- * > alert(fmt("There are {0} birds on {1} trees", [3,4]));
- * There are 3 birds on 4 trees
- * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php)
- * > alert(fmt(_("{0} users"), [3]));
- * 3 uzytkownikow
- */
-function fmt(s,a) {
- return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; });
-}
-
-var saved = {};
-
-
-var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
-var styles = {
- {% endraw %}
- {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
- {% endraw %}{% endfor %}{% raw %}
-};
-
-function changeStyle(styleName, link) {
- localStorage.stylesheet = styleName;
-
- if (!document.getElementById('stylesheet')) {
- var s = document.createElement('link');
- s.rel = 'stylesheet';
- s.type = 'text/css';
- s.id = 'stylesheet';
- var x = document.getElementsByTagName('head')[0];
- x.appendChild(s);
- }
-
- document.getElementById('stylesheet').href = styles[styleName];
- selectedstyle = styleName;
-
- if (document.getElementsByClassName('styles').length != 0) {
- var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
- for (i = 0; i < styleLinks.length; i++) {
- styleLinks[i].className = '';
- }
- }
-
- if (link) {
- link.className = 'selected';
- }
-}
-
-if (localStorage.stylesheet) {
- for (styleName in styles) {
- if (styleName == localStorage.stylesheet) {
- changeStyle(styleName);
- break;
- }
- }
-}
-
-function init_stylechooser() {
- var newElement = document.createElement('div');
- newElement.className = 'styles';
-
- for (styleName in styles) {
- var style = document.createElement('a');
- style.innerHTML = '[' + styleName + ']';
- style.onclick = function() {
- changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
- };
- if (styleName == selectedstyle) {
- style.className = 'selected';
- }
- style.href = 'javascript:void(0);';
- newElement.appendChild(style);
- }
-
- document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
-}
-
-function get_cookie(cookie_name) {
- var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
- if (results)
- return (unescape(results[2]));
- else
- return null;
-}
-
-function highlightReply(id) {
- if (typeof window.event != "undefined" && event.which == 2) {
- // don't highlight on middle click
- return true;
- }
-
- var divs = document.getElementsByTagName('div');
- for (var i = 0; i < divs.length; i++)
- {
- if (divs[i].className.indexOf('post') != -1)
- divs[i].className = divs[i].className.replace(/highlighted/, '');
- }
- if (id) {
- var post = document.getElementById('reply_'+id);
- if (post)
- post.className += ' highlighted';
- }
-}
-
-function generatePassword() {
- var pass = '';
- var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
- for (var i = 0; i < 8; i++) {
- var rnd = Math.floor(Math.random() * chars.length);
- pass += chars.substring(rnd, rnd + 1);
- }
- return pass;
-}
-
-function dopost(form) {
- if (form.elements['name']) {
- localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
- }
- if (form.elements['email'] && form.elements['email'].value != 'sage') {
- localStorage.email = form.elements['email'].value;
- }
-
- saved[document.location] = form.elements['body'].value;
- sessionStorage.body = JSON.stringify(saved);
-
- return form.elements['body'].value != "" || form.elements['file'].value != "";
-}
-
-function citeReply(id) {
- var body = document.getElementById('body');
-
- if (document.selection) {
- // IE
- body.focus();
- var sel = document.selection.createRange();
- sel.text = '>>' + id + '\n';
- } else if (body.selectionStart || body.selectionStart == '0') {
- // Mozilla
- var start = body.selectionStart;
- var end = body.selectionEnd;
- body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length);
- } else {
- // ???
- body.value += '>>' + id + '\n';
- }
-}
-
-function rememberStuff() {
- if (document.forms.post) {
- if (document.forms.post.password) {
- if (!localStorage.password)
- localStorage.password = generatePassword();
- document.forms.post.password.value = localStorage.password;
- }
-
- if (localStorage.name && document.forms.post.elements['name'])
- document.forms.post.elements['name'].value = localStorage.name;
- if (localStorage.email && document.forms.post.elements['email'])
- document.forms.post.elements['email'].value = localStorage.email;
-
- if (window.location.hash.indexOf('q') == 1)
- citeReply(window.location.hash.substring(2));
-
- if (sessionStorage.body) {
- var saved = JSON.parse(sessionStorage.body);
- if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
- // Remove successful posts
- var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
- for (var url in successful) {
- saved[url] = null;
- }
- sessionStorage.body = JSON.stringify(saved);
-
- document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
- }
- if (saved[document.location]) {
- document.forms.post.body.value = saved[document.location];
- }
- }
-
- if (localStorage.body) {
- document.forms.post.body.value = localStorage.body;
- localStorage.body = '';
- }
- }
-}
-
-function init() {
- init_stylechooser();
-
- if (document.forms.postcontrols) {
- document.forms.postcontrols.password.value = localStorage.password;
- }
-
- if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
- highlightReply(window.location.hash.substring(1));
-}
-
-var RecaptchaOptions = {
- theme : 'clean'
-};
-
-onready_callbacks = [];
-function onready(fnc) {
- onready_callbacks.push(fnc);
-}
-
-function ready() {
- for (var i = 0; i < onready_callbacks.length; i++) {
- onready_callbacks[i]();
- }
-}
-
-onready(init);
-
-{% endraw %}{% if config.google_analytics %}{% raw %}
-
-var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %}
-
+{% raw %}
+
+/* gettext-compatible _ function, example of usage:
+ *
+ * > // Loading pl_PL.json here (containing polish translation strings generated by tools/i18n_compile.php)
+ * > alert(_("Hello!"));
+ * Witaj!
+ */
+function _(s) {
+ return (typeof l10n != 'undefined' && typeof l10n[s] != 'undefined') ? l10n[s] : s;
+}
+
+/* printf-like formatting function, example of usage:
+ *
+ * > alert(fmt("There are {0} birds on {1} trees", [3,4]));
+ * There are 3 birds on 4 trees
+ * > // Loading pl_PL.json here (containing polish translation strings generated by tools/locale_compile.php)
+ * > alert(fmt(_("{0} users"), [3]));
+ * 3 uzytkownikow
+ */
+function fmt(s,a) {
+ return s.replace(/\{([0-9]+)\}/g, function(x) { return a[x[1]]; });
+}
+
+var saved = {};
+
+
+var selectedstyle = '{% endraw %}{{ config.default_stylesheet.0|addslashes }}{% raw %}';
+var styles = {
+ {% endraw %}
+ {% for stylesheet in stylesheets %}{% raw %}'{% endraw %}{{ stylesheet.name|addslashes }}{% raw %}' : '{% endraw %}{{ stylesheet.uri|addslashes }}{% raw %}',
+ {% endraw %}{% endfor %}{% raw %}
+};
+var board_name = false;
+
+function changeStyle(styleName, link) {
+ {% endraw %}
+ {% if config.stylesheets_board %}{% raw %}
+ if (board_name) {
+ stylesheet_choices[board_name] = styleName;
+ localStorage.board_stylesheets = JSON.stringify(stylesheet_choices);
+ }
+ {% endraw %}{% else %}
+ localStorage.stylesheet = styleName;
+ {% endif %}
+ {% raw %}
+
+ if (!document.getElementById('stylesheet')) {
+ var s = document.createElement('link');
+ s.rel = 'stylesheet';
+ s.type = 'text/css';
+ s.id = 'stylesheet';
+ var x = document.getElementsByTagName('head')[0];
+ x.appendChild(s);
+ }
+
+ document.getElementById('stylesheet').href = styles[styleName];
+ selectedstyle = styleName;
+
+ if (document.getElementsByClassName('styles').length != 0) {
+ var styleLinks = document.getElementsByClassName('styles')[0].childNodes;
+ for (var i = 0; i < styleLinks.length; i++) {
+ styleLinks[i].className = '';
+ }
+ }
+
+ if (link) {
+ link.className = 'selected';
+ }
+}
+
+
+{% endraw %}
+{% if config.stylesheets_board %}
+ {# This is such an unacceptable mess. There needs to be an easier way. #}
+ var matches = document.URL.match(/\/(\w+)\/($|{{ config.dir.res|replace({'/': '\\/'}) }}{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }}|{{ config.file_index|replace({'.': '\\.'}) }}|{{ config.file_page|replace({'%d': '\\d+', '.': '\\.'}) }})/);
+ {% raw %}
+ if (matches) {
+ board_name = matches[1];
+ }
+
+ if (!localStorage.board_stylesheets) {
+ localStorage.board_stylesheets = '{}';
+ }
+
+ var stylesheet_choices = JSON.parse(localStorage.board_stylesheets);
+ if (board_name && stylesheet_choices[board_name]) {
+ for (var styleName in styles) {
+ if (styleName == stylesheet_choices[board_name]) {
+ changeStyle(styleName);
+ break;
+ }
+ }
+ }
+ {% endraw%}
+{% else %}
+ {% raw %}
+ if (localStorage.stylesheet) {
+ for (var styleName in styles) {
+ if (styleName == localStorage.stylesheet) {
+ changeStyle(styleName);
+ break;
+ }
+ }
+ }
+ {% endraw %}
+{% endif %}
+{% raw %}
+
+function init_stylechooser() {
+ var newElement = document.createElement('div');
+ newElement.className = 'styles';
+
+ for (styleName in styles) {
+ var style = document.createElement('a');
+ style.innerHTML = '[' + styleName + ']';
+ style.onclick = function() {
+ changeStyle(this.innerHTML.substring(1, this.innerHTML.length - 1), this);
+ };
+ if (styleName == selectedstyle) {
+ style.className = 'selected';
+ }
+ style.href = 'javascript:void(0);';
+ newElement.appendChild(style);
+ }
+
+ document.getElementsByTagName('body')[0].insertBefore(newElement, document.getElementsByTagName('body')[0].lastChild.nextSibling);
+}
+
+function get_cookie(cookie_name) {
+ var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
+ if (results)
+ return (unescape(results[2]));
+ else
+ return null;
+}
+
+function highlightReply(id) {
+ if (typeof window.event != "undefined" && event.which == 2) {
+ // don't highlight on middle click
+ return true;
+ }
+
+ var divs = document.getElementsByTagName('div');
+ for (var i = 0; i < divs.length; i++)
+ {
+ if (divs[i].className.indexOf('post') != -1)
+ divs[i].className = divs[i].className.replace(/highlighted/, '');
+ }
+ if (id) {
+ var post = document.getElementById('reply_'+id);
+ if (post)
+ post.className += ' highlighted';
+ }
+}
+
+function generatePassword() {
+ var pass = '';
+ var chars = '{% endraw %}{{ config.genpassword_chars }}{% raw %}';
+ for (var i = 0; i < 8; i++) {
+ var rnd = Math.floor(Math.random() * chars.length);
+ pass += chars.substring(rnd, rnd + 1);
+ }
+ return pass;
+}
+
+function dopost(form) {
+ if (form.elements['name']) {
+ localStorage.name = form.elements['name'].value.replace(/( |^)## .+$/, '');
+ }
+ if (form.elements['email'] && form.elements['email'].value != 'sage') {
+ localStorage.email = form.elements['email'].value;
+ }
+
+ saved[document.location] = form.elements['body'].value;
+ sessionStorage.body = JSON.stringify(saved);
+
+ return form.elements['body'].value != "" || form.elements['file'].value != "";
+}
+
+function citeReply(id) {
+ var body = document.getElementById('body');
+
+ if (document.selection) {
+ // IE
+ body.focus();
+ var sel = document.selection.createRange();
+ sel.text = '>>' + id + '\n';
+ } else if (body.selectionStart || body.selectionStart == '0') {
+ // Mozilla
+ var start = body.selectionStart;
+ var end = body.selectionEnd;
+ body.value = body.value.substring(0, start) + '>>' + id + '\n' + body.value.substring(end, body.value.length);
+ } else {
+ // ???
+ body.value += '>>' + id + '\n';
+ }
+}
+
+function rememberStuff() {
+ if (document.forms.post) {
+ if (document.forms.post.password) {
+ if (!localStorage.password)
+ localStorage.password = generatePassword();
+ document.forms.post.password.value = localStorage.password;
+ }
+
+ if (localStorage.name && document.forms.post.elements['name'])
+ document.forms.post.elements['name'].value = localStorage.name;
+ if (localStorage.email && document.forms.post.elements['email'])
+ document.forms.post.elements['email'].value = localStorage.email;
+
+ if (window.location.hash.indexOf('q') == 1)
+ citeReply(window.location.hash.substring(2));
+
+ if (sessionStorage.body) {
+ var saved = JSON.parse(sessionStorage.body);
+ if (get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}')) {
+ // Remove successful posts
+ var successful = JSON.parse(get_cookie('{% endraw %}{{ config.cookies.js }}{% raw %}'));
+ for (var url in successful) {
+ saved[url] = null;
+ }
+ sessionStorage.body = JSON.stringify(saved);
+
+ document.cookie = '{% endraw %}{{ config.cookies.js }}{% raw %}={};expires=0;path=/;';
+ }
+ if (saved[document.location]) {
+ document.forms.post.body.value = saved[document.location];
+ }
+ }
+
+ if (localStorage.body) {
+ document.forms.post.body.value = localStorage.body;
+ localStorage.body = '';
+ }
+ }
+}
+
+function init() {
+ init_stylechooser();
+
+ if (document.forms.postcontrols) {
+ document.forms.postcontrols.password.value = localStorage.password;
+ }
+
+ if (window.location.hash.indexOf('q') != 1 && window.location.hash.substring(1))
+ highlightReply(window.location.hash.substring(1));
+}
+
+var RecaptchaOptions = {
+ theme : 'clean'
+};
+
+onready_callbacks = [];
+function onready(fnc) {
+ onready_callbacks.push(fnc);
+}
+
+function ready() {
+ for (var i = 0; i < onready_callbacks.length; i++) {
+ onready_callbacks[i]();
+ }
+}
+
+onready(init);
+
+{% endraw %}{% if config.google_analytics %}{% raw %}
+
+var _gaq = _gaq || [];_gaq.push(['_setAccount', '{% endraw %}{{ config.google_analytics }}{% raw %}']);{% endraw %}{% if config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', '{% endraw %}{{ config.google_analytics_domain }}{% raw %}']){% endraw %}{% endif %}{% if not config.google_analytics_domain %}{% raw %}_gaq.push(['_setDomainName', 'none']){% endraw %}{% endif %}{% raw %};_gaq.push(['_trackPageview']);(function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);})();{% endraw %}{% endif %}
+
diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html
index edc1ab3b..6c7560ad 100644
--- a/templates/mod/ban_form.html
+++ b/templates/mod/ban_form.html
@@ -41,11 +41,11 @@
<label for="reason">{% trans 'Message' %}</label>
</th>
<td>
- <input type="checkbox" id="public_message" name="public_message">
+ <input type="checkbox" id="public_message" name="public_message"{% if config.mod.check_ban_message %} checked{% endif %}>
<input type="text" name="message" id="message" size="35" maxlength="200" value="{{ config.mod.default_ban_message|e }}">
<span class="unimportant">({% trans 'public; attached to post' %})</span>
<script type="text/javascript">
- document.getElementById('message').disabled = true;
+ document.getElementById('message').disabled = !document.getElementById('public_message').checked;
document.getElementById('public_message').onchange = function() {
document.getElementById('message').disabled = !this.checked;
}
diff --git a/templates/mod/config-editor-php.html b/templates/mod/config-editor-php.html
new file mode 100644
index 00000000..4f76b5dd
--- /dev/null
+++ b/templates/mod/config-editor-php.html
@@ -0,0 +1,63 @@
+<div style="max-width:800px;margin:auto">
+ <p>
+ Any changes you make here will simply be appended to <code>{{ file }}</code>. If you wish to make the most of Tinyboard's customizability, you can instead edit the file directly. This page is intended for making quick changes and for those who don't have a basic understanding of PHP code.
+ </p>
+ {% if boards|count %}
+ <ul>
+ {% if board %}
+ <li><a href="?/config">Edit site-wide config</a></li>
+ {% endif %}
+ {% for _board in boards if _board.uri != board %}
+ <li>
+ <a href="?/config/{{ _board.uri }}">Edit config for {{ config.board_abbreviation|sprintf(_board.uri) }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+ {% if readonly %}
+ <p>Tinyboard does not have the required permissions to edit <code>{{ file }}</code>. To make changes, you will need to change the file's permissions first or manually edit the code.</p>
+ {% endif %}
+
+
+ {% if not readonly %}<form method="post" action="">{% endif %}
+ <textarea name="code" id="code" style="margin:auto;width:100%;height:500px{% if readonly %};background:#eee" readonly{% else %}"{% endif %}>
+ {{ php }}
+ </textarea>
+
+ <ul style="padding:0;text-align:center;list-style:none">
+ <li><input name="save" type="submit" value="{% trans 'Save changes' %}"{% if readonly %} disabled{% endif %}></li>
+ </ul>
+ {% if not readonly %}</form>{% endif %}
+</div>
+
+<script type="text/javascript">
+var observe;
+if (window.attachEvent) {
+ observe = function (element, event, handler) {
+ element.attachEvent('on'+event, handler);
+ };
+}
+else {
+ observe = function (element, event, handler) {
+ element.addEventListener(event, handler, false);
+ };
+}
+
+var text = document.getElementById('code');
+function resize () {
+ text.style.height = 'auto';
+ text.style.height = text.scrollHeight+'px';
+}
+/* 0-timeout to get the already changed text */
+function delayedResize () {
+ window.setTimeout(resize, 0);
+}
+observe(text, 'change', resize);
+observe(text, 'cut', delayedResize);
+observe(text, 'paste', delayedResize);
+observe(text, 'drop', delayedResize);
+observe(text, 'keydown', delayedResize);
+
+resize();
+</script> \ No newline at end of file
diff --git a/templates/mod/config-editor.html b/templates/mod/config-editor.html
index ec7213bb..a43f8cf7 100644
--- a/templates/mod/config-editor.html
+++ b/templates/mod/config-editor.html
@@ -1,10 +1,25 @@
+<p>
+ Any changes you make here will simply be appended to <code>{{ file }}</code>. If you wish to make the most of Tinyboard's customizability, you can instead edit the file directly. This page is intended for making quick changes and for those who don't have a basic understanding of PHP code.
+</p>
+{% if boards|count %}
+ <ul>
+ {% if board %}
+ <li><a href="?/config">Edit site-wide config</a></li>
+ {% endif %}
+ {% for _board in boards if _board.uri != board %}
+ <li>
+ <a href="?/config/{{ _board.uri }}">Edit config for {{ config.board_abbreviation|sprintf(_board.uri) }}</a>
+ </li>
+ {% endfor %}
+ </ul>
+{% endif %}
<form method="post" action="">
<table class="mod config-editor">
<tr>
- <th class="minimal">Name</th>
- <th>Value</th>
- <th class="minimal">Type</th>
- <th>Description</th>
+ <th class="minimal">{% trans 'Name' %}</th>
+ <th>{% trans 'Value' %}</th>
+ <th class="minimal">{% trans 'Type' %}</th>
+ <th>{% trans 'Description' %}</th>
</tr>
{% for var in conf if var.type != 'array' %}
{% if var.name|count == 1 %}
@@ -25,6 +40,13 @@
<td>
{% if var.type == 'string' %}
<input name="{{ name }}" type="text" value="{{ var.value|e }}">
+ {% elseif var.permissions %}
+ <select name="{{ name }}">
+ <option value="{{ constant('JANITOR') }}"{% if var.value == constant('JANITOR')%} selected{% endif %}>JANITOR</option>
+ <option value="{{ constant('MOD') }}"{% if var.value == constant('MOD')%} selected{% endif %}>MOD</option>
+ <option value="{{ constant('ADMIN') }}"{% if var.value == constant('ADMIN')%} selected{% endif %}>ADMIN</option>
+ <option value="{{ constant('DISABLED') }}"{% if var.value == constant('DISABLED')%} selected{% endif %}>DISABLED</option>
+ </select>
{% elseif var.type == 'integer' %}
<input name="{{ name }}" type="number" value="{{ var.value|e }}">
{% elseif var.type == 'boolean' %}
@@ -42,8 +64,8 @@
{{ var.type|e }}
</td>
- <td>
- {{ var.comment|join('<br>') }}
+ <td style="word-wrap:break-word;width:50%">
+ {{ var.comment|join(' ') }}
</td>
</tr>
{% endfor %}
diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html
index 619663f5..e9fb7c9c 100644
--- a/templates/mod/dashboard.html
+++ b/templates/mod/dashboard.html
@@ -94,7 +94,7 @@
{% if mod|hasPermission(config.mod.rebuild) %}
<li><a href="?/rebuild">{% trans 'Rebuild' %}</a></li>
{% endif %}
- {% if mod|hasPermission(config.mod.show_config) %}
+ {% if mod|hasPermission(config.mod.edit_config) %}
<li><a href="?/config">{% trans 'Configuration' %}</a></li>
{% endif %}
@@ -102,17 +102,29 @@
</fieldset>
{% if mod|hasPermission(config.mod.search) %}
-<fieldset>
- <legend>{% trans 'Search' %}</legend>
-
- <ul>
- <li>
- {% include 'mod/search_form.html' %}
- </li>
- </ul>
-</fieldset>
+ <fieldset>
+ <legend>{% trans 'Search' %}</legend>
+
+ <ul>
+ <li>
+ {% include 'mod/search_form.html' %}
+ </li>
+ </ul>
+ </fieldset>
{% endif %}
+{% if config.mod.dashboard_links|count %}
+ <fieldset>
+ <legend>{% trans 'Other' %}</legend>
+
+ <ul>
+ {% for label,link in config.mod.dashboard_links %}
+ <li><a href="{{ link }}">{{ label }}</a></li>
+ {% endfor %}
+ </ul>
+ </fieldset>
+{% endif %}
+
{% if config.debug %}
<fieldset>
<legend>{% trans 'Debug' %}</legend>
diff --git a/templates/mod/debug/recent_posts.html b/templates/mod/debug/recent_posts.html
index 740ed21e..b84d24ab 100644
--- a/templates/mod/debug/recent_posts.html
+++ b/templates/mod/debug/recent_posts.html
@@ -1,4 +1,4 @@
-<table class="modlog">
+<table class="modlog" style="word-wrap: break-word;">
<tr>
<th>Time</th>
<th>Board</th>
@@ -24,7 +24,7 @@
{% else %}
{% set thread = post.id %}
{% endif %}
- <a href="{{ config.root ~ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
+ <a href="?/{{ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
{{ post.id }}
</a>
</td>
diff --git a/templates/mod/edit_post_form.html b/templates/mod/edit_post_form.html
index 146e725b..a2980d35 100644
--- a/templates/mod/edit_post_form.html
+++ b/templates/mod/edit_post_form.html
@@ -32,7 +32,7 @@
{% trans %}Comment{% endtrans %}
</th>
<td>
- <textarea name="body" id="body" rows="8" cols="35">{% if raw %}{{ post.body | e }}{% else %}{{ post.body_nomarkup }}{% endif %}</textarea>
+ <textarea name="body" id="body" rows="8" cols="35">{% if raw %}{{ post.body }}{% else %}{{ post.body_nomarkup }}{% endif %}</textarea>
</td>
</tr>
</table>
diff --git a/templates/mod/log.html b/templates/mod/log.html
index e75330b5..0aa3f110 100644
--- a/templates/mod/log.html
+++ b/templates/mod/log.html
@@ -18,7 +18,11 @@
{% endif %}
</td>
<td class="minimal">
- <a href="?/IP/{{ log.ip }}">{{ log.ip }}</a>
+ {% if mod|hasPermission(config.mod.show_ip_modlog) %}
+ <a href="?/IP/{{ log.ip }}">{{ log.ip }}</a>
+ {% else %}
+ <em>hidden</em>
+ {% endif %}
</td>
<td class="minimal">
<span title="{{ log.time|date(config.post_date) }}">{{ log.time|ago }}</span>
diff --git a/templates/mod/login.html b/templates/mod/login.html
index 43a28d56..476897a6 100644
--- a/templates/mod/login.html
+++ b/templates/mod/login.html
@@ -1,26 +1,26 @@
-{% if error %}<h2 style="text-align:center">{{ error }}</h2>{% endif %}
-<form action="" method="post">
-<table style="margin-top:25px;">
- <tr>
- <th>
- {% trans 'Username' %}
- </th>
- <td>
- <input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
- </td>
- </tr>
- <tr>
- <th>
- {% trans 'Password' %}
- </th>
- <td>
- <input type="password" name="password" size="20" maxlength="30" value="">
- </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <input type="submit" name="login" value="{% trans %}Continue{% endtrans %}" />
- </td>
-</table>
-</form>
+{% if error %}<h2 style="text-align:center">{{ error }}</h2>{% endif %}
+<form action="" method="post">
+<table style="margin-top:25px;">
+ <tr>
+ <th>
+ {% trans 'Username' %}
+ </th>
+ <td>
+ <input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
+ </td>
+ </tr>
+ <tr>
+ <th>
+ {% trans 'Password' %}
+ </th>
+ <td>
+ <input type="password" name="password" size="20" maxlength="30" value="">
+ </td>
+ </tr>
+ <tr>
+ <td></td>
+ <td>
+ <input type="submit" name="login" value="{% trans %}Continue{% endtrans %}" />
+ </td>
+</table>
+</form>
diff --git a/templates/mod/news.html b/templates/mod/news.html
index b6c35798..b0335e0a 100644
--- a/templates/mod/news.html
+++ b/templates/mod/news.html
@@ -52,7 +52,7 @@
<em>{% trans 'no subject' %}</em>
{% endif %}
<small class="unimportant">
- &mdash; {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ notice.time|date(config.post_date) }}
+ &mdash; {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ post.time|date(config.post_date) }}
</small>
</h2>
<p>
diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html
index b441a28f..0c87f75f 100644
--- a/templates/mod/search_results.html
+++ b/templates/mod/search_results.html
@@ -39,7 +39,7 @@
</tr>
{% endfor %}
</table>
-{% endif %}
+{% endif %}
{% if search_type == 'bans' %}
<table class="modlog" style="width:100%">
@@ -125,7 +125,7 @@
</tr>
{% endfor %}
</table>
-{% endif %}
+{% endif %}
{% if search_type == 'log' %}
<table class="modlog">
@@ -166,7 +166,98 @@
</tr>
{% endfor %}
</table>
-{% endif %}
+{% endif %}
+
+{% if search_type == 'posts' %}
+ <table class="modlog" style="word-wrap: break-word;">
+ <tr>
+ <th>Time</th>
+ <th>Board</th>
+ <th>ID</th>
+ <th>Thread</th>
+ <th>IP</th>
+ <th>Name</th>
+ <th>Subject</th>
+ <th>File</th>
+ <th>Body (snippet)</th>
+ </tr>
+ {% for post in results %}
+ <tr>
+ <td class="minimal">
+ <small>{{ post.time | ago }} ago</small>
+ </td>
+ <td class="minimal">
+ <a href="?/{{ config.board_path|sprintf(post.board) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(post.board) }}</a>
+ </td>
+ <td class="minimal">
+ {% if post.thread %}
+ {% set thread = post.thread %}
+ {% else %}
+ {% set thread = post.id %}
+ {% endif %}
+ <a href="?/{{ post.board ~ '/' ~ config.dir.res}}{{ config.file_page|sprintf(thread) }}#{{ post.id }}">
+ {{ post.id }}
+ </a>
+ </td>
+ <td class="minimal">
+ <small>
+ {% if post.thread %}
+ {{ post.thread }}
+ {% else %}
+ (OP)
+ {% endif %}
+ </small>
+ </td>
+ <td class="minimal">
+ {% if mod|hasPermission(config.mod.show_ip, post.board) %}
+ <a href="?/IP/{{ post.ip }}">
+ {{ post.ip }}
+ </a>
+ {% else %}
+ <em>hidden</em>
+ {% endif %}
+ </td>
+ <td style="max-width:100px">
+ <small>
+ {% if post.email|length > 0 %}
+ {# start email #}
+ <a class="email" href="mailto:{{ post.email }}">
+ {% endif %}
+ {% set capcode = post.capcode|capcode %}
+ <span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name }}</span>
+ {% if post.trip|length > 0 %}
+ <span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
+ {% endif %}
+ {% if post.email|length > 0 %}
+ {# end email #}
+ </a>
+ {% endif %}
+ {% if capcode %}
+ {{ capcode.cap }}
+ {% endif %}
+ </small>
+ </td>
+ <td style="max-width:250px">
+ {% if post.subject %}
+ <small>{{ post.subject }}</small>
+ {% else %}
+ &ndash;
+ {% endif %}
+ </td>
+ <td style="max-width:200px">
+ {% if post.file %}
+ <small>{{ post.filename }} ({{ post.filesize | filesize }})</small>
+ {% else %}
+ &ndash;
+ {% endif %}
+ </td>
+ <td>
+ <small><em>{{ post.snippet }}</em></small>
+ </td>
+ </tr>
+ {% endfor %}
+ </table>
+{% endif %}
{% if result_count > results|count %}
<p class="unimportant" style="text-align:center;word-wrap:break-word">
diff --git a/templates/page.html b/templates/page.html
index 07eea62e..0d33c16f 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -1,25 +1,25 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
- {% include 'header.html' %}
- <title>{{ title }}</title>
-</head>
-<body>
- {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr>{% endif %}
- <header>
- <h1>{{ title }}</h1>
- <div class="subtitle">
- {% if subtitle %}
- {{ subtitle }}
- {% endif %}
- {% if mod and not hide_dashboard_link %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
- </div>
- </header>
- {{ body }}
- <hr>
- <footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
- </footer>
-</body>
-</html>
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+ {% include 'header.html' %}
+ <title>{{ title }}</title>
+</head>
+<body>
+ {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr>{% endif %}
+ <header>
+ <h1>{{ title }}</h1>
+ <div class="subtitle">
+ {% if subtitle %}
+ {{ subtitle }}
+ {% endif %}
+ {% if mod and not hide_dashboard_link %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
+ </div>
+ </header>
+ {{ body }}
+ <hr>
+ <footer>
+ <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
+ </footer>
+</body>
+</html> \ No newline at end of file
diff --git a/templates/post_form.html b/templates/post_form.html
index 64451fb9..fa486263 100755
--- a/templates/post_form.html
+++ b/templates/post_form.html
@@ -4,6 +4,9 @@
{{ antibot.html() }}
<input type="hidden" name="board" value="{{ board.uri }}">
{{ antibot.html() }}
+{% if current_page %}
+ <input type="hidden" name="page" value="{{ current_page }}">
+{% endif %}
{% if mod %}<input type="hidden" name="mod" value="1">{% endif %}
<table>
{% if not config.field_disable_name or (mod and post.mod|hasPermission(config.mod.bypass_field_disable, board.uri)) %}<tr>
@@ -67,21 +70,6 @@
</td>
</tr>
{% endif %}
- {% if config.imgcaptcha %}
- <tr>
- <th>
- {% trans %}Verification{% endtrans %}
- {{ antibot.html() }}
- </th>
- <td>
- <input type="hidden" name="imgcaptcha_hash" id="imgcaptcha_hash" value="kucaj stad, kucu hakierze">
- <img src="{{ config.imgcaptcha_filler }}" width="{{ config.imgcaptcha_width }}px" height="{{ config.imgcaptcha_height }}px" id="imgcaptcha_img"></img><br>
- {{ config.imgcaptcha_question }} <input type="text" name="imgcaptcha_verify" id="imgcaptcha_verify" value=""></input><br>
- <a href="javascript:ic_odswiezKapcze()">Odswiez</a>
- {{ antibot.html() }}
- </td>
- </tr>
- {% endif %}
<tr>
<th>
{% trans %}File{% endtrans %}
@@ -103,7 +91,7 @@
</td>
</tr>
{% endif %}
- {% if mod %}
+ {% if mod and ((not id and post.mod|hasPermission(config.mod.sticky, board.uri)) or (not id and post.mod|hasPermission(config.mod.lock, board.uri)) or post.mod|hasPermission(config.mod.rawhtml, board.uri)) %}
<tr>
<th>
{% trans %}Flags{% endtrans %}
diff --git a/templates/post_reply.html b/templates/post_reply.html
index 450f8246..b0391f19 100644
--- a/templates/post_reply.html
+++ b/templates/post_reply.html
@@ -1,111 +1,111 @@
-{% filter remove_whitespace %}
-{# tabs and new lines will be ignored #}
-<div class="post reply" id="reply_{{ post.id }}">
-
-<p class="intro"{% if not index %} id="{{ post.id }}"{% endif %}>
- <input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
- <label for="delete_{{ post.id }}">
- {% if post.subject|length > 0 %}
- {# show subject #}
- <span class="subject">{{ post.subject|bidi_cleanup }}</span>
- {% endif %}
- {% if post.email|length > 0 %}
- {# start email #}
- <a class="email" href="mailto:{{ post.email }}">
- {% endif %}
- {% set capcode = post.capcode|capcode %}
- <span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
- {% if post.trip|length > 0 %}
- <span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
- {% endif %}
- {% if post.email|length > 0 %}
- {# end email #}
- </a>
- {% endif %}
- {% if capcode %}
- {{ capcode.cap }}
- {% endif %}
- {% if post.mod and post.mod|hasPermission(config.mod.show_ip, board.uri) %}
- [<a style="margin:0;" href="?/IP/{{ post.ip }}">{{ post.ip }}</a>]
- {% endif %}
- <time datetime="{{ post.time|date('%Y-%m-%dT%H:%M:%S') }}{{ timezone() }}">{{ post.time|date(config.post_date) }}</time>
- </label>
- {% if config.poster_ids %}
- ID: {{ post.ip|poster_id(post.thread) }}
- {% endif %}
- <a class="post_no" {% if not index %}onclick="highlightReply({{ post.id }})" {% endif %}href="{{ post.link }}">No.</a>
- <a class="post_no"
- {% if not index %}
- onclick="citeReply({{ post.id }});"
- {% endif %}
- href="{% if index %}
- {{ post.link('q') }}
- {% else %}
- javascript:void(0);
- {% endif %}">
- {{ post.id }}
- </a>
- </p>
- {% if post.embed %}
- {{ post.embed }}
- {% elseif post.file == 'deleted' %}
- <img src="{{ config.image_deleted }}" alt="" />
- {% elseif post.file and post.file %}
- <p class="fileinfo">File: <a href="{{ config.uri_img }}{{ post.file }}">{{ post.file }}</a> <span class="unimportant">
- (
- {% if post.thumb == 'spoiler' %}
- Spoiler Image,
- {% endif %}
- {{ post.filesize|filesize }}
- {% if post.filex and post.filey %}
- , {{ post.filex}}x{{ post.filey }}
- {% if config.show_ratio %}
- , {{ post.ratio }}
- {% endif %}
- {% endif %}
- {% if config.show_filename and post.filename %}
- ,
- {% if post.filename|length > config.max_filename_display %}
- <span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
- {% else %}
- <span class="postfilename">{{ post.filename|bidi_cleanup }}</span>
- {% endif %}
- {% endif %}
- {% if post.thumb != 'file' and config.image_identification %}
- ,
- <span class='image_id'>
- <a href="http://imgops.com/{{ config.domain }}{{ config.uri_img }}{{ post.file }}">io</a>
- {% if post.file|extension == 'jpg' %}
- <a href="http://regex.info/exif.cgi?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">e</a>
- {% endif %}
- <a href="http://www.google.com/searchbyimage?image_url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">g</a>
- <a href="http://www.tineye.com/search?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">t</a>
- </span>
- {% endif %}
-
- )
- </span>
-</p>
- <a href="{{ config.uri_img }}{{ post.file }}" target="_blank"{% if post.thumb == 'file' %} class="file"{% endif %}>
- <img src="
- {% if post.thumb == 'file' %}
- {{ config.root }}
- {% if config.file_icons[post.filename|extension] %}
- {{ config.file_thumb|sprintf(config.file_icons[post.filename|extension]) }}
- {% else %}
- {{ config.file_thumb|sprintf(config.file_icons.default) }}
- {% endif %}
- {% elseif post.thumb == 'spoiler' %}
- {{ config.root }}{{ config.spoiler_image }}
- {% else %}
- {{ config.uri_thumb }}{{ post.thumb }}
- {% endif %}" style="width:{{ post.thumbx }}px;height:{{ post.thumby }}px" alt="" />
- </a>
- {% endif %}
- {{ post.postControls }}
- <div class="body">
- {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
- </div>
-</div>
-<br/>
-{% endfilter %}
+{% filter remove_whitespace %}
+{# tabs and new lines will be ignored #}
+<div class="post reply" id="reply_{{ post.id }}">
+
+<p class="intro"{% if not index %} id="{{ post.id }}"{% endif %}>
+ <input type="checkbox" class="delete" name="delete_{{ post.id }}" id="delete_{{ post.id }}" />
+ <label for="delete_{{ post.id }}">
+ {% if post.subject|length > 0 %}
+ {# show subject #}
+ <span class="subject">{{ post.subject|bidi_cleanup }}</span>
+ {% endif %}
+ {% if post.email|length > 0 %}
+ {# start email #}
+ <a class="email" href="mailto:{{ post.email }}">
+ {% endif %}
+ {% set capcode = post.capcode|capcode %}
+ <span {% if capcode.name %}style="{{ capcode.name }}" {% endif %}class="name">{{ post.name|bidi_cleanup }}</span>
+ {% if post.trip|length > 0 %}
+ <span {% if capcode.trip %}style="{{ capcode.trip }}" {% endif %}class="trip">{{ post.trip }}</span>
+ {% endif %}
+ {% if post.email|length > 0 %}
+ {# end email #}
+ </a>
+ {% endif %}
+ {% if capcode %}
+ {{ capcode.cap }}
+ {% endif %}
+ {% if post.mod and post.mod|hasPermission(config.mod.show_ip, board.uri) %}
+ [<a style="margin:0;" href="?/IP/{{ post.ip }}">{{ post.ip }}</a>]
+ {% endif %}
+ <time datetime="{{ post.time|date('%Y-%m-%dT%H:%M:%S') }}{{ timezone() }}">{{ post.time|date(config.post_date) }}</time>
+ </label>
+ {% if config.poster_ids %}
+ ID: {{ post.ip|poster_id(post.thread) }}
+ {% endif %}
+ <a class="post_no" {% if not index %}onclick="highlightReply({{ post.id }})" {% endif %}href="{{ post.link }}">No.</a>
+ <a class="post_no"
+ {% if not index %}
+ onclick="citeReply({{ post.id }});"
+ {% endif %}
+ href="{% if index %}
+ {{ post.link('q') }}
+ {% else %}
+ javascript:void(0);
+ {% endif %}">
+ {{ post.id }}
+ </a>
+ </p>
+ {% if post.embed %}
+ {{ post.embed }}
+ {% elseif post.file == 'deleted' %}
+ <img src="{{ config.image_deleted }}" alt="" />
+ {% elseif post.file and post.file %}
+ <p class="fileinfo">File: <a href="{{ config.uri_img }}{{ post.file }}">{{ post.file }}</a> <span class="unimportant">
+ (
+ {% if post.thumb == 'spoiler' %}
+ Spoiler Image,
+ {% endif %}
+ {{ post.filesize|filesize }}
+ {% if post.filex and post.filey %}
+ , {{ post.filex}}x{{ post.filey }}
+ {% if config.show_ratio %}
+ , {{ post.ratio }}
+ {% endif %}
+ {% endif %}
+ {% if config.show_filename and post.filename %}
+ ,
+ {% if post.filename|length > config.max_filename_display %}
+ <span class="postfilename" title="{{ post.filename|e|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
+ {% else %}
+ <span class="postfilename">{{ post.filename|e|bidi_cleanup }}</span>
+ {% endif %}
+ {% endif %}
+ {% if post.thumb != 'file' and config.image_identification %}
+ ,
+ <span class='image_id'>
+ <a href="http://imgops.com/{{ config.domain }}{{ config.uri_img }}{{ post.file }}">io</a>
+ {% if post.file|extension == 'jpg' %}
+ <a href="http://regex.info/exif.cgi?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">e</a>
+ {% endif %}
+ <a href="http://www.google.com/searchbyimage?image_url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">g</a>
+ <a href="http://www.tineye.com/search?url={{ config.domain }}{{ config.uri_img }}{{ post.file }}">t</a>
+ </span>
+ {% endif %}
+
+ )
+ </span>
+</p>
+ <a href="{{ config.uri_img }}{{ post.file }}" target="_blank"{% if post.thumb == 'file' %} class="file"{% endif %}>
+ <img src="
+ {% if post.thumb == 'file' %}
+ {{ config.root }}
+ {% if config.file_icons[post.filename|extension] %}
+ {{ config.file_thumb|sprintf(config.file_icons[post.filename|extension]) }}
+ {% else %}
+ {{ config.file_thumb|sprintf(config.file_icons.default) }}
+ {% endif %}
+ {% elseif post.thumb == 'spoiler' %}
+ {{ config.root }}{{ config.spoiler_image }}
+ {% else %}
+ {{ config.uri_thumb }}{{ post.thumb }}
+ {% endif %}" style="width:{{ post.thumbx }}px;height:{{ post.thumby }}px" alt="" />
+ </a>
+ {% endif %}
+ {{ post.postControls }}
+ <div class="body">
+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %}
+ </div>
+</div>
+<br/>
+{% endfilter %}
diff --git a/templates/post_thread.html b/templates/post_thread.html
index edc07011..a24d7557 100644
--- a/templates/post_thread.html
+++ b/templates/post_thread.html
@@ -23,9 +23,9 @@
{% if config.show_filename and post.filename %}
,
{% if post.filename|length > config.max_filename_display %}
- <span class="postfilename" title="{{ post.filename|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
+ <span class="postfilename" title="{{ post.filename|e|bidi_cleanup }}">{{ post.filename|truncate(config.max_filename_display)|bidi_cleanup }}</span>
{% else %}
- <span class="postfilename">{{ post.filename|bidi_cleanup }}</span>
+ <span class="postfilename">{{ post.filename|e|bidi_cleanup }}</span>
{% endif %}
{% endif %}
{% if post.thumb != 'file' and config.image_identification %}
@@ -100,13 +100,25 @@
{{ post.id }}
</a>
{% if post.sticky %}
- <img class="icon" title="Sticky" src="{{ config.image_sticky }}" alt="Sticky" />
+ {% if config.font_awesome %}
+ <i class="icon-pushpin icon"></i>
+ {% else %}
+ <img class="icon" title="Sticky" src="{{ config.image_sticky }}" alt="Sticky" />
+ {% endif %}
{% endif %}
{% if post.locked %}
- <img class="icon" title="Locked" src="{{ config.image_locked }}" alt="Locked" />
+ {% if config.font_awesome %}
+ <i class="icon-lock icon"></i>
+ {% else %}
+ <img class="icon" title="Locked" src="{{ config.image_locked }}" alt="Locked" />
+ {% endif %}
{% endif %}
{% if post.bumplocked and (config.mod.view_bumplock < 0 or (post.mod and post.mod|hasPermission(config.mod.view_bumplock, board.uri))) %}
- <img class="icon" title="Bumplocked" src="{{ config.image_bumplocked }}" alt="Bumplocked" />
+ {% if config.font_awesome %}
+ <i class="icon-anchor icon"></i>
+ {% else %}
+ <img class="icon" title="Bumplocked" src="{{ config.image_bumplocked }}" alt="Bumplocked" />
+ {% endif %}
{% endif %}
{% if index %}
<a href="{{ post.root }}{{ board.dir }}{{ config.dir.res }}{{ config.file_page|sprintf(post.id) }}">[{% trans %}Reply{% endtrans %}]</a>
@@ -145,4 +157,4 @@
{% include 'post_reply.html' %}
{% endfor %}
<br class="clear"/>{% if hr %}<hr/>{% endif %}
-</div> \ No newline at end of file
+</div>
diff --git a/templates/posts.sql b/templates/posts.sql
index c766d38e..ca2ec304 100644
--- a/templates/posts.sql
+++ b/templates/posts.sql
@@ -1,32 +1,33 @@
-CREATE TABLE IF NOT EXISTS `posts_{{ board }}` (
- `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
- `thread` int(11) DEFAULT NULL,
- `subject` varchar(100) DEFAULT NULL,
- `email` varchar(30) DEFAULT NULL,
- `name` varchar(35) DEFAULT NULL,
- `trip` varchar(15) DEFAULT NULL,
- `capcode` varchar(50) DEFAULT NULL,
- `body` text NOT NULL,
- `body_nomarkup` text DEFAULT NULL,
- `time` int(11) NOT NULL,
- `bump` int(11) DEFAULT NULL,
- `thumb` varchar(50) DEFAULT NULL,
- `thumbwidth` int(11) DEFAULT NULL,
- `thumbheight` int(11) DEFAULT NULL,
- `file` varchar(50) DEFAULT NULL,
- `filewidth` int(11) DEFAULT NULL,
- `fileheight` int(11) DEFAULT NULL,
- `filesize` int(11) DEFAULT NULL,
- `filename` text DEFAULT NULL,
- `filehash` text DEFAULT NULL,
- `password` varchar(20) DEFAULT NULL,
- `ip` varchar(45) NOT NULL,
- `sticky` int(1) NOT NULL,
- `locked` int(1) NOT NULL,
- `sage` int(1) NOT NULL,
- `embed` text,
- UNIQUE KEY `id` (`id`),
- KEY `thread_id` (`thread`, `id`),
- KEY `time` (`time`),
- FULLTEXT KEY `body` (`body`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+CREATE TABLE IF NOT EXISTS ``posts_{{ board }}`` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
+ `thread` int(11) DEFAULT NULL,
+ `subject` varchar(100) DEFAULT NULL,
+ `email` varchar(30) DEFAULT NULL,
+ `name` varchar(35) DEFAULT NULL,
+ `trip` varchar(15) DEFAULT NULL,
+ `capcode` varchar(50) DEFAULT NULL,
+ `body` text NOT NULL,
+ `body_nomarkup` text,
+ `time` int(11) NOT NULL,
+ `bump` int(11) DEFAULT NULL,
+ `thumb` varchar(50) DEFAULT NULL,
+ `thumbwidth` int(11) DEFAULT NULL,
+ `thumbheight` int(11) DEFAULT NULL,
+ `file` varchar(50) DEFAULT NULL,
+ `filewidth` int(11) DEFAULT NULL,
+ `fileheight` int(11) DEFAULT NULL,
+ `filesize` int(11) DEFAULT NULL,
+ `filename` text,
+ `filehash` text CHARACTER SET ascii,
+ `password` varchar(20) DEFAULT NULL,
+ `ip` varchar(39) CHARACTER SET ascii NOT NULL,
+ `sticky` int(1) NOT NULL,
+ `locked` int(1) NOT NULL,
+ `sage` int(1) NOT NULL,
+ `embed` text,
+ UNIQUE KEY `id` (`id`),
+ KEY `thread_id` (`thread`,`id`),
+ KEY `time` (`time`),
+ FULLTEXT KEY `body` (`body`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ;
+ \ No newline at end of file
diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php
index 7ba0d1e7..6ba09ce6 100644
--- a/templates/themes/basic/theme.php
+++ b/templates/themes/basic/theme.php
@@ -25,7 +25,7 @@
$settings['no_recent'] = (int) $settings['no_recent'];
- $query = query("SELECT * FROM `news` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error());
+ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/basic/index.html', Array(
diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php
index e585cf17..4e2d40db 100644
--- a/templates/themes/catalog/theme.php
+++ b/templates/themes/catalog/theme.php
@@ -37,9 +37,9 @@
$recent_posts = array();
$stats = array();
- $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM `posts_%s` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
+ $query = query(sprintf("SELECT *, `id` AS `thread_id`, (SELECT COUNT(*) FROM ``posts_%s`` WHERE `thread` = `thread_id`) AS `reply_count`, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL ORDER BY `bump` DESC", $board_name, $board_name, $board_name)) or error(db_error());
- while ($post = $query->fetch()) {
+ while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
$post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id']));
$post['board_name'] = $board['name'];
$post['file'] = $config['uri_thumb'] . $post['thumb'];
diff --git a/templates/themes/categories/news.html b/templates/themes/categories/news.html
index 9c7d8340..b3bea2b1 100644
--- a/templates/themes/categories/news.html
+++ b/templates/themes/categories/news.html
@@ -7,7 +7,7 @@
<link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}"/>
</head>
<body>
- <h1>{{ settings.title }}</h1>
+ {{ boardlist.top }}
<header>
<h1>{{ settings.title }}</h1>
<div class="subtitle">{{ settings.subtitle }}</div>
@@ -15,16 +15,16 @@
<div class="ban">
{% if news|count == 0 %}
- <p style="text-align:center" class="unimportant">(No news to show.)</p>
+ <p style="text-align:center" class="unimportant">{% trans %}(No news to show.){% endtrans %}</p>
{% else %}
{% for entry in news %}
<h2 id="{{ entry.id }}">
{% if entry.subject %}
{{ entry.subject }}
{% else %}
- <em>no subject</em>
+ <em>{% trans %}no subject{% endtrans %}</em>
{% endif %}
- <span class="unimportant"> &mdash; by {{ entry.name }} at {{ entry.time|date(config.post_date) }}</span>
+ <span class="unimportant"> &mdash; {% trans %}by{% endtrans %} {{ entry.name }} {% trans %}at{% endtrans %} {{ entry.time|date(config.post_date) }}</span>
</h2>
<p>{{ entry.body }}</p>
{% endfor %}
diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php
index 7d468d0d..74ed61ed 100644
--- a/templates/themes/categories/theme.php
+++ b/templates/themes/categories/theme.php
@@ -36,7 +36,7 @@
public static function news($settings) {
global $config;
- $query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error());
+ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/categories/news.html', Array(
diff --git a/templates/themes/frameset/theme.php b/templates/themes/frameset/theme.php
index 5fd9d29e..ffab0538 100644
--- a/templates/themes/frameset/theme.php
+++ b/templates/themes/frameset/theme.php
@@ -36,7 +36,7 @@
public static function news($settings) {
global $config;
- $query = query("SELECT * FROM `news` ORDER BY `time` DESC") or error(db_error());
+ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error());
$news = $query->fetchAll(PDO::FETCH_ASSOC);
return Element('themes/frameset/news.html', Array(
diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php
index 75907e77..08d910f8 100644
--- a/templates/themes/recent/theme.php
+++ b/templates/themes/recent/theme.php
@@ -42,12 +42,12 @@
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
- $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']);
+ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `file` IS NOT NULL AND `file` != 'deleted' AND `thumb` != 'spoiler' UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_images'], $query);
$query = query($query) or error(db_error());
- while ($post = $query->fetch()) {
+ while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
openBoard($post['board']);
// board settings won't be available in the template file, so generate links now
@@ -62,12 +62,12 @@
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
- $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` UNION ALL ", $_board['uri'], $_board['uri']);
+ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `time` DESC LIMIT ' . (int)$settings['limit_posts'], $query);
$query = query($query) or error(db_error());
- while ($post = $query->fetch()) {
+ while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
openBoard($post['board']);
$post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id'];
@@ -78,40 +78,37 @@
}
// Total posts
- $query = 'SELECT SUM(`top`) AS `count` FROM (';
+ $query = 'SELECT SUM(`top`) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
- $query .= sprintf("SELECT MAX(`id`) AS `top` FROM `posts_%s` UNION ALL ", $_board['uri']);
+ $query .= sprintf("SELECT MAX(`id`) AS `top` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
- $res = $query->fetch();
- $stats['total_posts'] = number_format($res['count']);
+ $stats['total_posts'] = number_format($query->fetchColumn());
// Unique IPs
- $query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM (';
+ $query = 'SELECT COUNT(DISTINCT(`ip`)) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
- $query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']);
+ $query .= sprintf("SELECT `ip` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
- $res = $query->fetch();
- $stats['unique_posters'] = number_format($res['count']);
+ $stats['unique_posters'] = number_format($query->fetchColumn());
// Active content
- $query = 'SELECT SUM(`filesize`) AS `count` FROM (';
+ $query = 'SELECT SUM(`filesize`) FROM (';
foreach ($boards as &$_board) {
if (in_array($_board['uri'], $this->excluded))
continue;
- $query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']);
+ $query .= sprintf("SELECT `filesize` FROM ``posts_%s`` UNION ALL ", $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', ') AS `posts_all`', $query);
$query = query($query) or error(db_error());
- $res = $query->fetch();
- $stats['active_content'] = $res['count'];
+ $stats['active_content'] = $query->fetchColumn();
return Element('themes/recent/recent.html', Array(
'settings' => $settings,
diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php
index 68fc1850..a14169a3 100644
--- a/templates/themes/rrdtool/theme.php
+++ b/templates/themes/rrdtool/theme.php
@@ -61,9 +61,8 @@
// debug just the graphing (not updating) with the --debug switch
if (!isset($argv[1]) || $argv[1] != '--debug') {
// Update graph
- $query = query(sprintf("SELECT MAX(`id`) AS `count` FROM `posts_%s`", $board));
- $count = $query->fetch();
- $count = $count['count'];
+ $query = query(sprintf("SELECT MAX(`id`) FROM ``posts_%s``", $board));
+ $count = $query->fetchColumn();
if (!rrd_update($file, Array(
'-t',
diff --git a/templates/themes/sitemap/theme.php b/templates/themes/sitemap/theme.php
index e210316b..226f8357 100644
--- a/templates/themes/sitemap/theme.php
+++ b/templates/themes/sitemap/theme.php
@@ -19,7 +19,7 @@
$threads = array();
foreach ($boards as $board) {
- $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM `posts_%s` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM `posts_%s` WHERE `thread` IS NULL", $board, $board)) or error(db_error());
+ $query = query(sprintf("SELECT `id` AS `thread_id`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error());
$threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC);
}
diff --git a/templates/themes/ukko/theme.php b/templates/themes/ukko/theme.php
index 6fa5fa7e..1682b4ec 100644
--- a/templates/themes/ukko/theme.php
+++ b/templates/themes/ukko/theme.php
@@ -25,7 +25,7 @@
foreach($boards as &$_board) {
if(in_array($_board['uri'], explode(' ', $this->settings['exclude'])))
continue;
- $query .= sprintf("SELECT *, '%s' AS `board` FROM `posts_%s` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
+ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']);
}
$query = preg_replace('/UNION ALL $/', 'ORDER BY `bump` DESC', $query);
$query = query($query) or error(db_error());
@@ -48,7 +48,7 @@
$post['filename'], $post['ip'], $post['sticky'], $post['locked'], $post['sage'], $post['embed'], $mod ? '?/' : $config['root'], $mod
);
- $posts = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
+ $posts = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $post['board']));
$posts->bindValue(':id', $post['id']);
$posts->bindValue(':limit', ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT);
$posts->execute() or error(db_error($posts));
@@ -66,7 +66,7 @@
}
if ($posts->rowCount() == ($post['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) {
- $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM `posts_%s` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
+ $ct = prepare(sprintf("SELECT COUNT(`id`) as `num` FROM ``posts_%s`` WHERE `thread` = :thread UNION ALL SELECT COUNT(`id`) FROM `posts_%s` WHERE `file` IS NOT NULL AND `thread` = :thread", $post['board'], $post['board']));
$ct->bindValue(':thread', $post['id'], PDO::PARAM_INT);
$ct->execute() or error(db_error($count));
diff --git a/templates/themes/ukko/ukko.js b/templates/themes/ukko/ukko.js
index baf0f78d..4a36b394 100644
--- a/templates/themes/ukko/ukko.js
+++ b/templates/themes/ukko/ukko.js
@@ -1,37 +1,115 @@
+(function(){
+
var cache = new Array(),
thread = false,
- loading = false;
+ loading = false,
+ ukkotimer = false;
+if (localStorage.hiddenboards !== null) {
+ localStorage.hiddenboards = "{}";
+}
+
+// Load data from HTML5 localStorage
+var hiddenboards = JSON.parse(localStorage.hiddenboards);
+
+var storeboards = function() {
+ localStorage.hiddenboards = JSON.stringify(hiddenboards);
+};
+
$(document).ready(function() {
- $(window).on('scroll', function() {
- if($(window).scrollTop() + $(window).height() + 100 > $(document).height() && !loading && overflow.length > 0) {
+ var addukkohide = function() {
+ var ukkohide = $('<a href="javascript:void(0);" class="unimportant ukkohide"></a>');
+ var board = $(this).next().data("board");
+ var hr = $("<hr />");
+
+ $(this).append(ukkohide);
+ $(this).append(hr);
+
+ if (hiddenboards[board] !== true) {
+ ukkohide.html(_("(hide threads from this board)"));
+ hr.hide();
+ }
+ else {
+ ukkohide.html(_("(show threads from this board)"));
+ $(this).next().hide();
+ }
+ ukkohide.click(function() {
+ hiddenboards[board] = (hiddenboards[board] !== true);
+ if (hiddenboards[board] !== true) {
+ $('[data-board="'+board+'"]:not([data-cached="yes"])').show().prev().
+ find('.ukkohide').html(_("(hide threads from this board)")).
+ parent().find('hr').hide();
+ }
+ else {
+ $('[data-board="'+board+'"]:not([data-cached="yes"])').hide().prev().
+ find('.ukkohide').html(_("(show threads from this board)"))
+ .parent().find('hr').show();
+ }
+ storeboards();
+ return false;
+ });
+
+ };
+ $("h2").each(addukkohide);
+
+ $('.pages').hide();
+ var loadnext = function() {
+ if (overflow.length == 0) {
+ $('.pages').show().html(_("No more threads to display"));
+ }
+ while($(window).scrollTop() + $(window).height() + 1000 > $(document).height() && !loading && overflow.length > 0) {
var page = '../' + overflow[0].board + '/' + overflow[0].page;
+ thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]');
+ if (thread.length > 0 && thread.attr("data-cached") !== 'yes') { // already present
+ overflow.shift();
+ continue;
+ }
+
+ var boardheader = $('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a> </h2>');
+
if($.inArray(page, cache) != -1) {
- thread = $('div#thread_' + overflow[0].id);
- if(thread.length > 0) {
- thread.prepend('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a></h2>');
- $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block'));
- overflow.shift();
+ if (thread.length > 0) {
+ $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
+ boardheader.insertBefore(thread);
+ addukkohide.call(boardheader);
+ $(document).trigger('new_post', thread);
}
+ overflow.shift();
} else {
loading = true;
+ $('.pages').show().html(_("Loading..."));
$.get(page, function(data) {
cache.push(page);
$(data).find('div[id*="thread_"]').each(function() {
- $('body').prepend($(this).css('display', 'none').attr('data-board', overflow[0].board));
+ var checkout = $(this).attr('id').replace('thread_', '');
+ if ($('div#thread_' + checkout + '[data-board="' + overflow[0].board + '"]').length == 0) {
+ $('form[name="postcontrols"]').prepend($(this).css('display', 'none').attr("data-cached", "yes").attr('data-board', overflow[0].board));
+ }
});
- thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"]');
+ thread = $('div#thread_' + overflow[0].id + '[data-board="' + overflow[0].board + '"][data-cached="yes"]');
+
if(thread.length > 0) {
- thread.prepend('<h2><a href="/' + overflow[0].board + '/">/' + overflow[0].board + '/</a></h2>');
- $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).css('display', 'block'));
- overflow.shift();
+ $('div[id*="thread_"]').last().after(thread.attr('data-board', overflow[0].board).attr("data-cached", "no").css('display', 'block'));
+ boardheader.insertBefore(thread);
+ addukkohide.call(boardheader);
+ $(document).trigger('new_post', thread);
}
+ overflow.shift();
loading = false;
+ $('.pages').hide().html("");
});
+ break;
}
}
- });
+ clearTimeout(ukkotimer);
+ ukkotimer = setTimeout(loadnext, 1000);
+ };
+
+ $(window).on('scroll', loadnext);
+
+ ukkotimer = setTimeout(loadnext, 1000);
+});
-}); \ No newline at end of file
+})();
diff --git a/templates/thread.html b/templates/thread.html
index 1b217c2f..7fe60a39 100644
--- a/templates/thread.html
+++ b/templates/thread.html
@@ -1,51 +1,52 @@
-<!doctype html>
-<html>
-<head>
- <meta charset="utf-8">
-
- <script type="text/javascript">
- var active_page = "thread";
- </script>
-
- {% include 'header.html' %}
- <title>{{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %}</title>
-</head>
-<body>
- {{ boardlist.top }}
- {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
- {% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
- <header>
- <h1>{{ board.url }} - {{ board.title|e }}</h1>
- <div class="subtitle">
- {% if board.subtitle %}
- {{ board.subtitle|e }}
- {% endif %}
- {% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
- </div>
- </header>
-
- <div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a></div>
-
- {% include 'attention_bar.html' %}
- {% include 'post_form.html' %}
-
- {% if config.blotter %}<hr /><div class="blotter">{{ config.blotter }}</div>{% endif %}
- <hr />
- <form name="postcontrols" action="{{ config.post_url }}" method="post">
- <input type="hidden" name="board" value="{{ board.uri }}" />
- {% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
- {{ body }}
- {% include 'report_delete.html' %}
- </form>
- <a href="{{ return }}">[{% trans %}Return{% endtrans %}]</a>
-
- {{ boardlist.bottom }}
- <footer>
- <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
- {% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
- </footer>
- <script type="text/javascript">{% raw %}
- ready();
- {% endraw %}</script>
-</body>
-</html>
+<!doctype html>
+<html>
+<head>
+ <meta charset="utf-8">
+
+ <script type="text/javascript">
+ var active_page = "thread";
+ </script>
+
+ {% include 'header.html' %}
+ <title>{{ board.url }} - {% if config.thread_subject_in_title and thread.subject %}{{ thread.subject }}{% else %}{{ board.title|e }}{% endif %}</title>
+</head>
+<body>
+ {{ boardlist.top }}
+ {% if pm %}<div class="top_notice">You have <a href="?/PM/{{ pm.id }}">an unread PM</a>{% if pm.waiting > 0 %}, plus {{ pm.waiting }} more waiting{% endif %}.</div><hr />{% endif %}
+ {% if config.url_banner %}<img class="banner" src="{{ config.url_banner }}" {% if config.banner_width or config.banner_height %}style="{% if config.banner_width %}width:{{ config.banner_width }}px{% endif %};{% if config.banner_width %}height:{{ config.banner_height }}px{% endif %}" {% endif %}alt="" />{% endif %}
+ <header>
+ <h1>{{ board.url }} - {{ board.title|e }}</h1>
+ <div class="subtitle">
+ {% if board.subtitle %}
+ {{ board.subtitle|e }}
+ {% endif %}
+ {% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
+ </div>
+ </header>
+
+ <div class="banner">{% trans %}Posting mode: Reply{% endtrans %} <a class="unimportant" href="{{ return }}">[{% trans %}Return{% endtrans %}]</a></div>
+
+ {% include 'attention_bar.html' %}
+
+ {% include 'post_form.html' %}
+
+ {% if config.global_message %}<hr /><div class="blotter">{{ config.global_message }}</div>{% endif %}
+ <hr />
+ <form name="postcontrols" action="{{ config.post_url }}" method="post">
+ <input type="hidden" name="board" value="{{ board.uri }}" />
+ {% if mod %}<input type="hidden" name="mod" value="1" />{% endif %}
+ {{ body }}
+ {% include 'report_delete.html' %}
+ </form>
+ <a href="{{ return }}">[{% trans %}Return{% endtrans %}]</a>
+
+ {{ boardlist.bottom }}
+ <footer>
+ <p class="unimportant" style="margin-top:20px;text-align:center;">Powered by <a href="http://tinyboard.org/">Tinyboard</a> {{ config.version }} | <a href="http://tinyboard.org/">Tinyboard</a> Copyright &copy; 2010-2013 Tinyboard Development Group</p>
+ {% for footer in config.footer %}<p class="unimportant" style="text-align:center;">{{ footer }}</p>{% endfor %}
+ </footer>
+ <script type="text/javascript">{% raw %}
+ ready();
+ {% endraw %}</script>
+</body>
+</html>