diff options
| author | Michael Save <savetheinternet@tinyboard.org> | 2012-05-06 01:33:10 +1000 |
|---|---|---|
| committer | Michael Save <savetheinternet@tinyboard.org> | 2012-05-06 01:33:10 +1000 |
| commit | a6104587203f1b1b448e6977066d6e649de91ae8 (patch) | |
| tree | 58f3f17daaeb47de3ecc87f9967b432612147e68 | |
| parent | ac2837c6204221554ceebc56c5fb9e38be4e0925 (diff) | |
a lot more improvements
40 files changed, 986 insertions, 271 deletions
diff --git a/inc/config.php b/inc/config.php index 414d5262..c202d8c9 100644 --- a/inc/config.php +++ b/inc/config.php @@ -816,8 +816,6 @@ // Do a DNS lookup on IP addresses to get their hostname on the IP summary page $config['mod']['dns_lookup'] = true; - // Show ban form on the IP summary page - $config['mod']['ip_banform'] = true; // How many recent posts, per board, to show in the IP summary page $config['mod']['ip_recentposts'] = 5; @@ -829,6 +827,9 @@ // How many bans to show per page in the ban list $config['mod']['banlist_page'] = 350; + // Number of news entries to display per page + $config['mod']['news_page'] = 40; + // Maximum number of results to display for a search, per board $config['mod']['search_results'] = 75; diff --git a/inc/functions.php b/inc/functions.php index 3ca5f599..ac0a1c96 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -32,7 +32,30 @@ function loadConfig() { if (!isset($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '0.0.0.0'; - $arrays = array('db', 'cache', 'cookies', 'error', 'dir', 'mod', 'spam', 'flood_filters', 'wordfilters', 'custom_capcode', 'custom_tripcode', 'dnsbl', 'dnsbl_exceptions', 'remote', 'allowed_ext', 'allowed_ext_files', 'file_icons', 'footer', 'stylesheets', 'additional_javascript', 'markup'); + $arrays = array( + 'db', + 'cache', + 'cookies', + 'error', + 'dir', + 'mod', + 'spam', + 'flood_filters', + 'wordfilters', + 'custom_capcode', + 'custom_tripcode', + 'dnsbl', + 'dnsbl_exceptions', + 'remote', + 'allowed_ext', + 'allowed_ext_files', + 'file_icons', + 'footer', + 'stylesheets', + 'additional_javascript', + 'markup', + 'custom_pages' + ); $config = array(); foreach ($arrays as $key) { diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 260ad94c..c56570a5 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -9,7 +9,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { exit; } -function mod_page($title, $template, $args) { +function mod_page($title, $template, $args, $subtitle = false) { global $config, $mod; echo Element('page.html', array( @@ -17,6 +17,7 @@ function mod_page($title, $template, $args) { 'mod' => $mod, 'hide_dashboard_link' => $template == 'mod/dashboard.html', 'title' => $title, + 'subtitle' => $subtitle, 'body' => Element($template, array_merge( array('config' => $config, 'mod' => $mod), @@ -28,6 +29,8 @@ function mod_page($title, $template, $args) { } function mod_login() { + global $config; + $args = array(); if (isset($_POST['login'])) { @@ -60,8 +63,14 @@ function mod_confirm($request) { mod_page('Confirm action', 'mod/confirm.html', array('request' => $request)); } +function mod_logout() { + destroyCookies(); + + header('Location: ?/', true, $config['redirect_http']); +} + function mod_dashboard() { - global $config; + global $config, $mod; $args = array(); @@ -79,9 +88,180 @@ function mod_dashboard() { } } + $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :id AND `unread` = 1'); + $query->bindValue(':id', $mod['id']); + $query->execute() or error(db_error($query)); + $args['unread_pms'] = $query->fetchColumn(0); + + if ($mod['type'] >= ADMIN && $config['check_updates']) { + if (!$config['version']) + error(_('Could not find current version! (Check .installed)')); + + if (isset($_COOKIE['update'])) { + $latest = unserialize($_COOKIE['update']); + } else { + $ctx = stream_context_create(array('http' => array('timeout' => 5))); + if ($code = @file_get_contents('http://tinyboard.org/version.txt', 0, $ctx)) { + eval($code); + if (preg_match('/v(\d+)\.(\d)\.(\d+)(-dev.+)?$/', $config['version'], $matches)) { + $current = array( + 'massive' => (int) $matches[1], + 'major' => (int) $matches[2], + 'minor' => (int) $matches[3] + ); + if (isset($m[4])) { + // Development versions are always ahead in the versioning numbers + $current['minor'] --; + } + // Check if it's newer + if (!( $latest['massive'] > $current['massive'] || + $latest['major'] > $current['major'] || + ($latest['massive'] == $current['massive'] && + $latest['major'] == $current['major'] && + $latest['minor'] > $current['minor'] + ))) + $latest = false; + } else { + $latest = false; + } + } else { + // Couldn't get latest version + $latest = false; + } + + setcookie('update', serialize($latest), time() + $config['check_updates_time'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', null, false, true); + } + + if ($latest) + $args['newer_release'] = $latest; + } + mod_page('Dashboard', 'mod/dashboard.html', $args); } +function mod_edit_board($boardName) { + global $board, $config; + + if (!openBoard($boardName)) + error($config['error']['noboard']); + + if (!hasPermission($config['mod']['manageboards'], $board['uri'])) + error($config['error']['noaccess']); + + if (isset($_POST['title'], $_POST['subtitle'])) { + if (isset($_POST['delete'])) { + if (!hasPermission($config['mod']['manageboards'], $board['uri'])) + error($config['error']['deleteboard']); + + $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri']); + $query->execute() or error(db_error($query)); + + modLog('Deleted board: ' . sprintf($config['board_abbreviation'], $board['uri']), false); + + // Delete entire board directory + rrmdir($board['uri'] . '/'); + + // Delete posting table + $query = query(sprintf('DROP TABLE IF EXISTS `posts_%s`', $board['uri'])) or error(db_error()); + + // Clear reports + $query = prepare('DELETE FROM `reports` WHERE `board` = :id'); + $query->bindValue(':id', $board['uri'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + // Delete from table + $query = prepare('DELETE FROM `boards` WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + + if ($config['cache']['enabled']) { + cache::delete('board_' . $board['uri']); + cache::delete('all_boards'); + } + + $query = prepare("SELECT `board`, `post` FROM `cites` WHERE `target_board` = :board"); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { + if ($board['uri'] != $cite['board']) { + if (!isset($tmp_board)) + $tmp_board = $board; + openBoard($cite['board']); + rebuildPost($cite['post']); + } + } + + $query = prepare('DELETE FROM `cites` WHERE `board` = :board OR `target_board` = :board'); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + + $query = prepare('DELETE FROM `antispam` WHERE `board` = :board'); + $query->bindValue(':board', $board['uri']); + $query->execute() or error(db_error($query)); + } else { + $query = prepare('UPDATE `boards` SET `title` = :title, `subtitle` = :subtitle WHERE `uri` = :uri'); + $query->bindValue(':uri', $board['uri']); + $query->bindValue(':title', $_POST['title']); + $query->bindValue(':subtitle', $_POST['subtitle']); + $query->execute() or error(db_error($query)); + } + + rebuildThemes('boards'); + + header('Location: ?/', true, $config['redirect_http']); + } else { + mod_page('Edit board: ' . sprintf($config['board_abbreviation'], $board['uri']), 'mod/board.html', array('board' => $board)); + } +} + +function mod_new_board() { + global $config, $board; + + if (!hasPermission($config['mod']['newboard'])) + error($config['error']['noaccess']); + + if (isset($_POST['uri'], $_POST['title'], $_POST['subtitle'])) { + if ($_POST['uri'] == '') + error(sprintf($config['error']['required'], 'URI')); + + if ($_POST['title'] == '') + error(sprintf($config['error']['required'], 'title')); + + if (!preg_match('/^\w+$/', $_POST['uri'])) + error(sprintf($config['error']['invalidfield'], 'URI')); + + if (openBoard($_POST['uri'])) { + error(sprintf($config['error']['boardexists'], $board['url'])); + } + + $query = prepare('INSERT INTO `boards` VALUES (:uri, :title, :subtitle)'); + $query->bindValue(':uri', $_POST['uri']); + $query->bindValue(':title', $_POST['title']); + $query->bindValue(':subtitle', $_POST['subtitle']); + $query->execute() or error(db_error($query)); + + modLog('Created a new board: ' . sprintf($config['board_abbreviation'], $_POST['uri'])); + + if (!openBoard($_POST['uri'])) + error(_("Couldn't open board after creation.")); + + query(Element('posts.sql', array('board' => $board['uri']))) or error(db_error()); + + if ($config['cache']['enabled']) + cache::delete('all_boards'); + + // Build the board + buildIndex(); + + rebuildThemes('boards'); + + header('Location: ?/' . $board['uri'] . '/' . $config['file_index'], true, $config['redirect_http']); + } + + mod_page('New board', 'mod/board.html', array('new' => true)); +} + function mod_noticeboard($page_no = 1) { global $config, $pdo, $mod; @@ -104,9 +284,11 @@ function mod_noticeboard($page_no = 1) { $query->bindValue(':body', $_POST['body']); $query->execute() or error(db_error($query)); - if($config['cache']['enabled']) + if ($config['cache']['enabled']) cache::delete('noticeboard_preview'); + modLog('Posted a noticeboard entry'); + header('Location: ?/noticeboard#' . $pdo->lastInsertId(), true, $config['redirect_http']); } @@ -126,6 +308,78 @@ function mod_noticeboard($page_no = 1) { mod_page('Noticeboard', 'mod/noticeboard.html', array('noticeboard' => $noticeboard, 'count' => $count)); } +function mod_noticeboard_delete($id) { + global $config; + + if (!hasPermission($config['mod']['noticeboard_delete'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `noticeboard` WHERE `id` = :id'); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + modLog('Deleted a noticeboard entry'); + + header('Location: ?/noticeboard', true, $config['redirect_http']); +} + +function mod_news($page_no = 1) { + global $config, $pdo, $mod; + + if ($page_no < 1) + error($config['error']['404']); + + if (isset($_POST['subject'], $_POST['body'])) { + if (!hasPermission($config['mod']['news'])) + error($config['error']['noaccess']); + + markup($_POST['body']); + + $query = prepare('INSERT INTO `news` VALUES (NULL, :name, :time, :subject, :body)'); + $query->bindValue(':name', isset($_POST['name']) && hasPermission($config['mod']['news_custom']) ? $_POST['name'] : $mod['username']); + $query->bindvalue(':time', time()); + $query->bindValue(':subject', $_POST['subject']); + $query->bindValue(':body', $_POST['body']); + $query->execute() or error(db_error($query)); + + modLog('Posted a news entry'); + + rebuildThemes('news'); + + header('Location: ?/news#' . $pdo->lastInsertId(), true, $config['redirect_http']); + } + + $query = prepare("SELECT * FROM `news` ORDER BY `id` DESC LIMIT :offset, :limit"); + $query->bindValue(':limit', $config['mod']['news_page'], PDO::PARAM_INT); + $query->bindValue(':offset', ($page_no - 1) * $config['mod']['news_page'], PDO::PARAM_INT); + $query->execute() or error(db_error($query)); + $news = $query->fetchAll(PDO::FETCH_ASSOC); + + if (empty($news) && $page_no > 1) + error($config['error']['404']); + + $query = prepare("SELECT COUNT(*) FROM `news`"); + $query->execute() or error(db_error($query)); + $count = $query->fetchColumn(0); + + mod_page('News', 'mod/news.html', array('news' => $news, 'count' => $count)); +} + +function mod_news_delete($id) { + global $config; + + if (!hasPermission($config['mod']['news_delete'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `news` WHERE `id` = :id'); + $query->bindValue(':id', $id); + $query->execute() or error(db_error($query)); + + modLog('Deleted a news entry'); + + header('Location: ?/news', true, $config['redirect_http']); +} + function mod_log($page_no = 1) { global $config; @@ -135,7 +389,7 @@ function mod_log($page_no = 1) { if (!hasPermission($config['mod']['modlog'])) error($config['error']['noaccess']); - $query = prepare("SELECT `username`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); + $query = prepare("SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` ORDER BY `time` DESC LIMIT :offset, :limit"); $query->bindValue(':limit', $config['mod']['modlog_page'], PDO::PARAM_INT); $query->bindValue(':offset', ($page_no - 1) * $config['mod']['modlog_page'], PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -196,7 +450,7 @@ function mod_ip_remove_note($ip, $id) { modLog("Removed a note for <a href=\"?/IP/{$ip}\">{$ip}</a>"); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + header('Location: ?/IP/' . $ip . '#notes', true, $config['redirect_http']); } function mod_page_ip($ip) { @@ -212,7 +466,8 @@ function mod_page_ip($ip) { require_once 'inc/mod/ban.php'; unban($_POST['ban_id']); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + + header('Location: ?/IP/' . $ip . '#bans', true, $config['redirect_http']); return; } @@ -230,7 +485,7 @@ function mod_page_ip($ip) { modLog("Added a note for <a href=\"?/IP/{$ip}\">{$ip}</a>"); - header('Location: ?/IP/' . $ip, true, $config['redirect_http']); + header('Location: ?/IP/' . $ip . '#notes', true, $config['redirect_http']); return; } @@ -238,6 +493,9 @@ function mod_page_ip($ip) { $args['ip'] = $ip; $args['posts'] = array(); + if ($config['mod']['dns_lookup']) + $args['hostname'] = rDNS($ip); + $boards = listBoards(); foreach ($boards as $board) { openBoard($board['uri']); @@ -287,7 +545,7 @@ function mod_page_ip($ip) { $args['notes'] = $query->fetchAll(PDO::FETCH_ASSOC); } - mod_page("IP: $ip", 'mod/view_ip.html', $args); + mod_page("IP: $ip", 'mod/view_ip.html', $args, $args['hostname']); } function mod_ban() { @@ -382,7 +640,7 @@ function mod_lock($board, $unlock, $post) { $query->bindValue(':id', $post); $query->bindValue(':locked', $unlock ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unlocked' : 'Locked') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -404,7 +662,7 @@ function mod_sticky($board, $unsticky, $post) { $query->bindValue(':id', $post); $query->bindValue(':sticky', $unsticky ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unstickied' : 'Stickied') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -426,7 +684,7 @@ function mod_bumplock($board, $unbumplock, $post) { $query->bindValue(':id', $post); $query->bindValue(':bumplock', $unbumplock ? 0 : 1); $query->execute() or error(db_error($query)); - if($query->rowCount()) { + if ($query->rowCount()) { modLog(($unlock ? 'Unbumplocked' : 'Bumplocked') . " thread #{$post}"); buildThread($post); buildIndex(); @@ -447,7 +705,7 @@ function mod_ban_post($board, $delete, $post) { $query = prepare(sprintf('SELECT `ip`, `thread` FROM `posts_%s` WHERE `id` = :id', $board)); $query->bindValue(':id', $post); $query->execute() or error(db_error($query)); - if(!$_post = $query->fetch(PDO::FETCH_ASSOC)) + if (!$_post = $query->fetch(PDO::FETCH_ASSOC)) error($config['error']['404']); $thread = $_post['thread']; @@ -624,25 +882,54 @@ function mod_user($uid) { } } + if (isset($_POST['delete'])) { + if (!hasPermission($config['mod']['deleteusers'])) + error($config['error']['noaccess']); + + $query = prepare('DELETE FROM `mods` WHERE `id` = :id'); + $query->bindValue(':id', $uid); + $query->execute() or error(db_error($query)); + + modLog('Deleted user ' . utf8tohtml($user['username']) . ' <small>(#' . $user['id'] . ')</small>'); + + header('Location: ?/users', true, $config['redirect_http']); + + return; + } + + if ($_POST['username'] == '') + error(sprintf($config['error']['required'], 'username')); + $query = prepare('UPDATE `mods` SET `username` = :username, `boards` = :boards WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':username', $_POST['username']); $query->bindValue(':boards', implode(',', $boards)); $query->execute() or error(db_error($query)); + if ($user['username'] !== $_POST['username']) { + // account was renamed + modLog('Renamed user "' . utf8tohtml($user['username']) . '" <small>(#' . $user['id'] . ')</small> to "' . utf8tohtml($_POST['username']) . '"'); + } + if ($_POST['password'] != '') { $query = prepare('UPDATE `mods` SET `password` = SHA1(:password) WHERE `id` = :id'); $query->bindValue(':id', $uid); $query->bindValue(':password', $_POST['password']); $query->execute() or error(db_error($query)); + modLog('Changed password for ' . utf8tohtml($_POST['username']) . ' <small>(#' . $user['id'] . ')</small>'); + if ($uid == $mod['id']) { login($_POST['username'], $_POST['password']); setCookies(); } } - header('Location: ?/users', true, $config['redirect_http']); + if (hasPermission($config['mod']['manageusers'])) + header('Location: ?/users', true, $config['redirect_http']); + else + header('Location: ?/', true, $config['redirect_http']); + return; } @@ -653,11 +940,17 @@ function mod_user($uid) { $query->bindValue(':password', $_POST['password']); $query->execute() or error(db_error($query)); - login($_POST['username'], $_POST['password']); + modLog('Changed own password'); + + login($user['username'], $_POST['password']); setCookies(); } - header('Location: ?/users', true, $config['redirect_http']); + if (hasPermission($config['mod']['manageusers'])) + header('Location: ?/users', true, $config['redirect_http']); + else + header('Location: ?/', true, $config['redirect_http']); + return; } @@ -675,6 +968,47 @@ function mod_user($uid) { mod_page('Edit user', 'mod/user.html', array('user' => $user, 'logs' => $log, 'boards' => listBoards())); } +function mod_user_new() { + if (isset($_POST['username'], $_POST['password'], $_POST['type'])) { + if ($_POST['username'] == '') + error(sprintf($config['error']['required'], 'username')); + if ($_POST['password'] == '') + error(sprintf($config['error']['required'], 'password')); + + if (isset($_POST['allboards'])) { + $boards = array('*'); + } else { + $_boards = listBoards(); + foreach ($_boards as &$board) { + $board = $board['uri']; + } + + $boards = array(); + foreach ($_POST as $name => $value) { + if (preg_match('/^board_(\w+)$/', $name, $matches) && in_array($matches[1], $_boards)) + $boards[] = $matches[1]; + } + } + + $_POST['type'] = (int) $_POST['type']; + if ($_POST['type'] !== JANITOR && $_POST['type'] !== MOD && $_POST['type'] !== ADMIN) + error(sprintf($config['error']['invalidfield'], 'type')); + + $query = prepare('INSERT INTO `mods` VALUES (NULL, :username, SHA1(:password), :type, :boards)'); + $query->bindValue(':username', $_POST['username']); + $query->bindValue(':password', $_POST['password']); + $query->bindValue(':type', $_POST['type']); + $query->bindValue(':boards', implode(',', $boards)); + $query->execute() or error(db_error($query)); + + header('Location: ?/users', true, $config['redirect_http']); + return; + } + + mod_page('Edit user', 'mod/user.html', array('new' => true, 'boards' => listBoards())); +} + + function mod_users() { global $config; @@ -734,12 +1068,38 @@ function mod_pm($id, $reply = false) { if (!$pm['to_username']) error($config['error']['404']); // deleted? - mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array('username' => $pm['to_username'], 'id' => $pm['to'], 'message' => quote($pm['message']))); + mod_page("New PM for {$pm['to_username']}", 'mod/new_pm.html', array( + 'username' => $pm['username'], 'id' => $pm['sender'], 'message' => quote($pm['message']) + )); } else { mod_page("Private message – #$id", 'mod/pm.html', $pm); } } +function mod_inbox() { + global $config, $mod; + + $query = prepare('SELECT `unread`,`pms`.`id`, `time`, `sender`, `to`, `message`, `username` FROM `pms` LEFT JOIN `mods` ON `mods`.`id` = `sender` WHERE `to` = :mod ORDER BY `unread` DESC, `time` DESC'); + $query->bindValue(':mod', $mod['id']); + $query->execute() or error(db_error($query)); + $messages = $query->fetchAll(PDO::FETCH_ASSOC); + + $query = prepare('SELECT COUNT(*) FROM `pms` WHERE `to` = :mod AND `unread` = 1'); + $query->bindValue(':mod', $mod['id']); + $query->execute() or error(db_error($query)); + $unread = $query->fetchColumn(0); + + foreach ($messages as &$message) { + $message['snippet'] = pm_snippet($message['message']); + } + + mod_page('PM inbox (' . (count($messages) > 0 ? $unread . ' unread' : 'empty') . ')', 'mod/inbox.html', array( + 'messages' => $messages, + 'unread' => $unread + )); +} + + function mod_new_pm($username) { global $config, $mod; @@ -920,7 +1280,7 @@ function mod_reports() { $body .= $po->build(true) . '<hr>'; - if(isset($__old_body_truncate_char)) + if (isset($__old_body_truncate_char)) $config['body_truncate_char'] = $__old_body_truncate_char; } @@ -971,7 +1331,7 @@ function mod_debug_antispam() { if (isset($_POST['board'], $_POST['thread'])) { $where = '`board` = ' . $pdo->quote($_POST['board']); - if($_POST['thread'] != '') + if ($_POST['thread'] != '') $where .= ' AND `thread` = ' . $pdo->quote($_POST['thread']); if (isset($_POST['purge'])) { diff --git a/install.php b/install.php index 2e732c4c..1e872911 100644 --- a/install.php +++ b/install.php @@ -1,7 +1,7 @@ <?php // Installation/upgrade file -define('VERSION', 'v0.9.6-dev-4'); +define('VERSION', 'v0.9.6-dev-5'); require 'inc/functions.php'; @@ -210,6 +210,8 @@ if (file_exists($config['has_installed'])) { } case 'v0.9.6-dev-3': query("ALTER TABLE `antispam` CHANGE `hash` `hash` CHAR( 40 ) NOT NULL") or error(db_error()); + case 'v0.9.6-dev-4': + query("ALTER TABLE `news` DROP INDEX `id`, ADD PRIMARY KEY ( `id` )") or error(db_error()); case false: // Update version number file_write($config['has_installed'], VERSION); diff --git a/js/show-op.js b/js/show-op.js index df9cf31b..d948ca3b 100644 --- a/js/show-op.js +++ b/js/show-op.js @@ -23,8 +23,6 @@ $(document).ready(function(){ OP = $('div.post.op a.post_no:eq(1)').text(); } - console.log(OP); - $(this).find('p.body a:not([rel="nofollow"])').each(function() { var postID; @@ -24,17 +24,28 @@ $pages = array( '!^$!' => ':?/', // redirect to dashboard '!^/$!' => 'dashboard', // dashboard '!^/confirm/(.+)$!' => 'confirm', // confirm action (if javascript didn't work) + '!^/logout$!' => 'logout', // logout '!^/users$!' => 'users', // manage users '!^/users/(\d+)$!' => 'user', // edit user '!^/users/(\d+)/(promote|demote)$!' => 'user_promote', // prmote/demote user + '!^/users/new$!' => 'user_new', // create a new user '!^/new_PM/([^/]+)$!' => 'new_pm', // create a new pm '!^/PM/(\d+)(/reply)?$!' => 'pm', // read a pm + '!^/inbox$!' => 'inbox', // pm inbox '!^/noticeboard$!' => 'noticeboard', // view noticeboard '!^/noticeboard/(\d+)$!' => 'noticeboard', // view noticeboard + '!^/noticeboard/delete/(\d+)$!' => 'noticeboard_delete',// delete from noticeboard '!^/log$!' => 'log', // modlog '!^/log/(\d+)$!' => 'log', // modlog + '!^/news$!' => 'news', // view news + '!^/news/(\d+)$!' => 'news', // view news + '!^/news/delete/(\d+)$!' => 'news_delete', // delete from news + + '!^/edit/(\w+)$!' => 'edit_board', // edit board details + '!^/new-board$!' => 'new_board', // create a new board + '!^/rebuild$!' => 'rebuild', // rebuild static files '!^/reports$!' => 'reports', // report queue '!^/reports/(\d+)/dismiss(all)?$!' => 'report_dismiss', // dismiss a report @@ -64,8 +75,14 @@ $pages = array( str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) . '$!' => 'view_thread', ); -if (!$mod) + +if (!$mod) { $pages = array('//' => 'login'); +} elseif (isset($_GET['status'], $_GET['r'])) { + header('Location: ' . $_GET['r'], true, (int)$_GET['stats']); +} elseif (isset($config['mod']['custom_pages'])) { + $pages = array_merge($pages, $config['mod']['custom_pages']); +} foreach ($pages as $uri => $handler) { if (preg_match($uri, $query, $matches)) { @@ -79,14 +96,20 @@ foreach ($pages as $uri => $handler) { ); } - if ($handler[0] == ':') { - header('Location: ' . substr($handler, 1), true, $config['redirect_http']); - } elseif (is_callable("mod_page_$handler")) { - call_user_func_array("mod_page_$handler", $matches); - } elseif (is_callable("mod_$handler")) { - call_user_func_array("mod_$handler", $matches); + if (is_string($handler)) { + if ($handler[0] == ':') { + header('Location: ' . substr($handler, 1), true, $config['redirect_http']); + } elseif (is_callable("mod_page_$handler")) { + call_user_func_array("mod_page_$handler", $matches); + } elseif (is_callable("mod_$handler")) { + call_user_func_array("mod_$handler", $matches); + } else { + error("Mod page '$handler' not found!"); + } + } elseif (is_callable($handler)) { + call_user_func_array($handler, $matches); } else { - error("Mod page '$handler' not found!"); + error("Mod page '$handler' not a string, and not callable!"); } exit; diff --git a/templates/generic_page.html b/templates/generic_page.html new file mode 100644 index 00000000..e834aad0 --- /dev/null +++ b/templates/generic_page.html @@ -0,0 +1,71 @@ +<!doctype html> +<html> +<head> + {% block head %} + <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}"> + {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}">{% endif %} + <title>{{ board.url }} - {{ board.name }}</title> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> + <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 not nojavascript %} + <script type="text/javascript" src="{{ config.url_javascript }}"></script> + {% if not config.additional_javascript_compile %} + {% for javascript in config.additional_javascript %}<script type="text/javascript" src="{{ config.additional_javascript_url }}{{ javascript }}"></script>{% endfor %} + {% endif %} + {% endif %} + {% if config.recaptcha %}<style type="text/css">{% raw %} + .recaptcha_image_cell { + background: none !important; + } + table.recaptchatable { + border: none !important; + } + #recaptcha_logo, #recaptcha_tagline { + display: none; + float: right; + } + .recaptchatable a { + display: block; + } + {% endraw %}</style>{% endif %} + {% endblock %} +</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.name }}</h1> + <div class="subtitle"> + {% if board.title %} + {{ board.title|e }} + {% endif %} + {% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %} + </div> + </header> + + {% 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> + <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 © 2010-2012 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/index.html b/templates/index.html index f12e2517..a28724a1 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1,13 +1,13 @@ <!doctype html>
<html>
<head>
- <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}" />
- {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}" />{% endif %}
+ <meta charset="utf-8">
+ <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}">
+ {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}">{% endif %}
<title>{{ board.url }} - {{ board.name }}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
- {% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}" />{% endif %}
- <link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}" />
+ <meta name="viewport" content="width=device-width, initial-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 not nojavascript %}
<script type="text/javascript" src="{{ config.url_javascript }}"></script>
{% if not config.additional_javascript_compile %}
@@ -35,10 +35,10 @@ {% 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 }}</h1>
+ <h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
- {{ board.subtitle }}
+ {{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
diff --git a/templates/mod/ban_form.html b/templates/mod/ban_form.html index 9d4d6728..5d5f2b81 100644 --- a/templates/mod/ban_form.html +++ b/templates/mod/ban_form.html @@ -16,19 +16,19 @@ <tr> <th> - <label for="ip">IP <span class="unimportant">(or subnet)</span></label> + <label for="ip">{% trans 'IP' %} <span class="unimportant">{% trans '(or subnet)' %}</span></label> </th> <td> {% if not hide_ip %} <input type="text" name="ip" id="ip" size="30" maxlength="40" value="{{ ip }}"> {% else %} - <em>hidden</em> + <em>{% trans 'hidden' %}</em> {% endif %} </td> </tr> <tr> <th> - <label for="reason">Reason</label> + <label for="reason">{% trans 'Reason' %}</label> </th> <td> <textarea name="reason" id="reason" rows="5" cols="30">{{ reason|e }}</textarea> @@ -37,12 +37,12 @@ {% if post and board and not delete %} <tr> <th> - <label for="reason">Message</label> + <label for="reason">{% trans 'Message' %}</label> </th> <td> <input type="checkbox" id="public_message" name="public_message"> <input type="text" name="message" id="message" size="35" maxlength="200" value="{{ config.mod.default_ban_message|e }}"> - <span class="unimportant">(public; attached to post)</span> + <span class="unimportant">({% trans 'public; attached to post' %})</span> <script type="text/javascript"> document.getElementById('message').disabled = true; document.getElementById('public_message').onchange = function() { @@ -54,20 +54,20 @@ {% endif %} <tr> <th> - <label for="length">Length</label> + <label for="length">{% trans 'Length' %}</label> </th> <td> <input type="text" name="length" id="length" size="20" maxlength="40"> <span class="unimportant">(eg. "2d1h30m" or "2 days")</span></td> </tr> <tr> - <th>Board</th> + <th>{% trans 'Board' %}</th> <td> <ul style="list-style:none;padding:2px 5px"> <li> <input type="radio" name="board" value="*" id="ban-allboards" checked> <label style="display:inline" for="ban-allboards"> - <em>all boards</em> + <em>{% trans 'all boards' %}</em> </label> </li> @@ -75,7 +75,7 @@ <li> <input type="radio" name="board" value="{{ board.uri }}" id="ban-board-{{ board.uri }}"> <label style="display:inline" for="ban-board-{{ board.uri }}"> - {{ config.board_abbreviation|sprintf(board.uri) }} - {{ board.title }} + {{ config.board_abbreviation|sprintf(board.uri) }} - {{ board.title|e }} </label> </li> {% endfor %} @@ -84,7 +84,7 @@ </tr> <tr> <td></td> - <td><input name="new_ban" type="submit" value="New Ban"></td> + <td><input name="new_ban" type="submit" value="{% trans 'New Ban' %}"></td> </tr> </table> </form> diff --git a/templates/mod/ban_list.html b/templates/mod/ban_list.html index ea8183d6..4a27b8f7 100644 --- a/templates/mod/ban_list.html +++ b/templates/mod/ban_list.html @@ -1,15 +1,15 @@ {% if bans|count == 0 %} - <p style="text-align:center" class="unimportant">(There are no active bans.)</p> + <p style="text-align:center" class="unimportant">({% trans 'There are no active bans.' %})</p> {% else %} <form action="" method="post"> <table class="mod"> <tr> - <th>{% trans %}IP address{% endtrans %}</th> - <th>{% trans %}Reason{% endtrans %}</th> - <th>{% trans %}Board{% endtrans %}</th> - <th>{% trans %}Set{% endtrans %}</th> - <th>{% trans %}Expires{% endtrans %}</th> - <th>{% trans %}Staff{% endtrans %}</th> + <th>{% trans 'IP address' %}</th> + <th>{% trans 'Reason' %}</th> + <th>{% trans 'Board' %}</th> + <th>{% trans 'Set' %}</th> + <th>{% trans 'Expires' %}</th> + <th>{% trans 'Staff' %}</th> </tr> {% for ban in bans %} <tr{% if ban.expires != 0 and ban.expires < time() %} style="text-decoration:line-through"{% endif %}> @@ -32,7 +32,7 @@ {% if ban.board %} {{ config.board_abbreviation|sprintf(ban.board) }} {% else %} - <em>{% trans %}all boards{% endtrans %} + <em>{% trans 'all boards' %}</em> {% endif %} </td> <td style="white-space: nowrap"> @@ -40,7 +40,7 @@ </td> <td style="white-space: nowrap"> {% if ban.expires == 0 %} - <em>never</em> + <em>{% trans 'never' %}</em> {% else %} {{ ban.expires|date(config.post_date) }} {% if ban.expires > time() %} @@ -59,8 +59,10 @@ {% endif %} {% endif %} + {% elseif ban.mod == -1 %} + <em>system</em> {% else %} - <em>deleted?</em> + <em>{% trans 'deleted?' %}</em> {% endif %} </td> </tr> @@ -68,7 +70,7 @@ </table> <p style="text-align:center"> - <input type="submit" name="unban" value="Unban selected"> + <input type="submit" name="unban" value="{% trans 'Unban selected' %}"> </p> </form> {% endif %} diff --git a/templates/mod/board.html b/templates/mod/board.html new file mode 100644 index 00000000..0775e421 --- /dev/null +++ b/templates/mod/board.html @@ -0,0 +1,44 @@ +{% if new %} + {% set action = '?/new-board' %} +{% else %} + {% set action = '?/edit/' ~ board.uri %} +{% endif %} + +<form action="{{ action }}" method="post"> + <table> + <tr> + <th>{% trans 'URI' %}</th> + <td> + {% if not new %} + {{ config.board_abbreviation|sprintf(board.uri) }} + {% else %} + /<input size="10" maxlength="255" type="text" name="uri" autocomplete="off">/ + {% endif %} + </td> + </tr> + <tr> + <th>{% trans 'Title' %}</th> + <td> + <input size="25" type="text" name="title" value="{{ board.title|e }}" autocomplete="off"> + </td> + </tr> + <tr> + <th>{% trans 'Subtitle' %}</th> + <td> + <input size="25" type="text" name="subtitle" value="{{ board.subtitle|e }}" autocomplete="off"> + </td> + </tr> + </table> + + <ul style="padding:0;text-align:center;list-style:none"> + {% if new %} + <li><input type="submit" value="{% trans 'Create board' %}"></li> + {% else %} + <li><input type="submit" value="{% trans 'Save changes' %}"></li> + {% if mod|hasPermission(config.mod.deleteboard) %} + <li><input name="delete" onclick="return confirm('Are you sure you want to permanently delete this board?');" type="submit" value="{% trans 'Delete board' %}"></li> + {% endif %} + {% endif %} + </ul> +</form> + diff --git a/templates/mod/confirm.html b/templates/mod/confirm.html index 7509ce3c..6dc4d66a 100644 --- a/templates/mod/confirm.html +++ b/templates/mod/confirm.html @@ -1,7 +1,7 @@ <p style="text-align:center;font-size:1.1em"> - Are you sure you want to do that? <a href="?/{{ request }}">Click to proceed to ?/{{ request }}</a>. + {% trans 'Are you sure you want to do that?' %} <a href="?/{{ request }}">{% trans 'Click to proceed to' %} ?/{{ request }}</a>. </p> <p class="unimportant" style="text-align:center"> - You are seeing this message because we were unable to serve a confirmation dialog, probably due to Javascript being disabled. + {% trans 'You are seeing this message because we were unable to serve a confirmation dialog, probably due to Javascript being disabled.' %} </p> diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index fc510ac7..9e50e6ed 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -6,30 +6,30 @@ <li> <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a> - - {{ board.title }} + {{ board.title|e }} {% if board.subtitle %} - <small>— {{ board.subtitle }}</small> + <small>— {{ board.subtitle|e }}</small> {% endif %} {% if mod|hasPermission(config.mod.manageboards) %} - <a href="?/manage/{{ board.uri }}"><small>[{% trans 'manage' %}]</small></a> + <a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a> {% endif %} </li> {% endfor %} {% if mod|hasPermission(config.mod.newboard) %} - <li style="margin-top:15px"><a href="?/new_board"><strong>{% trans 'Create new board' %}</strong></a></li> + <li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li> {% endif %} </ul> </fieldset> -{% if mod|hasPermission(config.mod.noticeboard) %} - <fieldset> - <legend>{% trans 'Noticeboard' %}</legend> - <ul> +<fieldset> + <legend>{% trans 'Messages' %}</legend> + <ul> + {% if mod|hasPermission(config.mod.noticeboard) %} {% if noticeboard|count > 0 %} <li> - {% trans 'Latest posts:' %} + {% trans 'Noticeboard' %}: <ul> {% for post in noticeboard %} <li> @@ -43,7 +43,7 @@ <small class="unimportant"> — by {% if post.username %} - {{ post.username }} + {{ post.username|e }} {% else %} <em>deleted?</em> {% endif %} @@ -56,9 +56,18 @@ </li> {% endif %} <li><a href="?/noticeboard">{% trans 'View all entries' %}</a></li> - </ul> - </fieldset> -{% endif %} + {% endif %} + <li><a href="?/news">{% trans 'News' %}</a></li> + <li> + <a href="?/inbox"> + {% trans 'PM inbox' %} + {% if unread_pms > 0 %} + <strong>({{ unread_pms }} unread)</strong> + {% endif %} + </a> + </li> + </ul> +</fieldset> <fieldset> <legend>{% trans 'Administration' %}</legend> @@ -115,3 +124,24 @@ </fieldset> {% endif %} +{% if newer_release %} + <fieldset> + <legend>Update</legend> + <ul> + <li> + A newer version of Tinyboard + (<strong>v{{ newer_release.massive }}.{{ newer_release.major }}.{{ newer_release.minor }}</strong>) is available! + See <a href="http://tinyboard.org">http://tinyboard.org/</a> for upgrade instructions. + </li> + </ul> + </fieldset> +{% endif %} + +<fieldset> + <legend>{% trans 'User account' %}</legend> + + <ul> + <li><a href="?/logout">{% trans 'Logout' %}</a></li> + </ul> +</fieldset> + diff --git a/templates/mod/inbox.html b/templates/mod/inbox.html new file mode 100644 index 00000000..97afe446 --- /dev/null +++ b/templates/mod/inbox.html @@ -0,0 +1,36 @@ +{% if messages|count == 0 %} + <p style="text-align:center" class="unimportant">({% trans 'No private messages for you.' %})</p> +{% else %} + <table class="modlog"> + <tr> + <th>{% trans 'ID' %}</th> + <th>{% trans 'From' %}</th> + <th>{% trans 'Date' %}</th> + <th>{% trans 'Message snippet' %}</th> + </tr> + {% for message in messages %} + <tr{% if message.unread %} style="font-weight:bold"{% endif %}> + <td class="minimal"> + <a href="?/PM/{{ message.id }}"> + {{ message.id }} + </a> + </td> + <td class="minimal"> + {% if message.username %} + <a href="?/new_PM/{{ message.username|e }}">{{ message.username|e }}</a> + {% else %} + <em>{% trans 'deleted?' %}</em> + {% endif %} + </td> + <td class="minimal"> + {{ message.time|date(config.post_date) }} + </td> + <td> + <a href="?/PM/{{ message.id }}"> + {{ message.snippet }} + </a> + </td> + </tr> + {% endfor %} + </table> +{% endif %} diff --git a/templates/mod/log.html b/templates/mod/log.html index 9b0979cb..dca1b2d0 100644 --- a/templates/mod/log.html +++ b/templates/mod/log.html @@ -1,15 +1,21 @@ <table class="modlog"> <tr> - <th>Staff</th> - <th>IP address</th> - <th>Time</th> - <th>Board</th> - <th>Action</th> + <th>{% trans 'Staff' %}</th> + <th>{% trans 'IP address' %}</th> + <th>{% trans 'Time' %}</th> + <th>{% trans 'Board' %}</th> + <th>{% trans 'Action' %}</th> </tr> {% for log in logs %} <tr> <td class="minimal"> - <a href="?/new_PM/{{ log.username }}">{{ log.username }}</a> + {% if log.username %} + <a href="?/new_PM/{{ log.username|e }}">{{ log.username|e }}</a> + {% elseif log.mod == -1 %} + <em>system</em> + {% else %} + <em>{% trans 'deleted?' %}</em> + {% endif %} </td> <td class="minimal"> <a href="?/IP/{{ log.ip }}">{{ log.ip }}</a> diff --git a/templates/mod/login.html b/templates/mod/login.html index 5ac308a3..43a28d56 100644 --- a/templates/mod/login.html +++ b/templates/mod/login.html @@ -3,7 +3,7 @@ <table style="margin-top:25px;">
<tr>
<th>
- {% trans %}Username{% endtrans %}
+ {% trans 'Username' %}
</th>
<td>
<input type="text" name="username" size="20" maxlength="30" value="{{ username|e }}">
@@ -11,7 +11,7 @@ </tr>
<tr>
<th>
- {% trans %}Password{% endtrans %}
+ {% trans 'Password' %}
</th>
<td>
<input type="password" name="password" size="20" maxlength="30" value="">
diff --git a/templates/mod/new_pm.html b/templates/mod/new_pm.html index ece1325c..3fd78ac6 100644 --- a/templates/mod/new_pm.html +++ b/templates/mod/new_pm.html @@ -1,7 +1,3 @@ -{#{% if id == mod.id %} - {% set username = 'me' %} -{% endif %}#} - <form action="?/new_PM/{{ username|e }}" method="post"> <table> <tr> @@ -18,5 +14,5 @@ </tr> </table> - <p style="text-align:center"><input type="submit" value="Send message"></p> + <p style="text-align:center"><input type="submit" value="{% trans 'Send message' %}"></p> </form> diff --git a/templates/mod/news.html b/templates/mod/news.html new file mode 100644 index 00000000..b6c35798 --- /dev/null +++ b/templates/mod/news.html @@ -0,0 +1,70 @@ +{% if mod|hasPermission(config.mod.news) %} + <fieldset> + <legend>{% trans 'New post' %}</legend> + <form style="margin:0" action="" method="post"> + <table> + <tr> + <th> + {% if mod|hasPermission(config.mod.news_custom) %} + <label for="name">{% trans 'Name' %}</label> + {% else %} + {% trans 'Name' %} + {% endif %} + </th> + <td> + {% if mod|hasPermission(config.mod.news_custom) %} + <input type="text" size="55" name="name" id="name" value="{{ mod.username|e }}"> + {% else %} + {{ mod.username|e }} + {% endif %} + </td> + </tr> + <tr> + <th><label for="subject">{% trans 'Subject' %}</label></th> + <td><input type="text" size="55" name="subject" id="subject"></td> + </tr> + <tr> + <th><label for="body">{% trans 'Body' %}</label></th> + <td><textarea name="body" id="body" style="width:100%;height:100px"></textarea></td> + </tr> + </table> + <p style="text-align:center"> + <input type="submit" value="{% trans 'Post news entry' %}"> + </p> + </form> + </fieldset> +{% endif %} + +{% for post in news %} + <div class="ban"> + {% if mod|hasPermission(config.mod.news_delete) %} + <span style="float:right;padding:2px"> + <a class="unimportant" href="?/news/delete/{{ post.id }}">[{% trans 'delete' %}]</a> + </span> + {% endif %} + <h2 id="{{ post.id }}"> + <small class="unimportant"> + <a href="#{{ post.id }}">#</a> + </small> + {% if post.subject %} + {{ post.subject|e }} + {% else %} + <em>{% trans 'no subject' %}</em> + {% endif %} + <small class="unimportant"> + — {% trans 'by' %} {{ post.name }} {% trans 'at' %} {{ notice.time|date(config.post_date) }} + </small> + </h2> + <p> + {{ post.body }} + </p> + </div> +{% endfor %} + +{% if count > news|count %} + <p class="unimportant" style="text-align:center;word-wrap:break-word"> + {% for i in range(0, (count - 1) / config.mod.news_page) %} + <a href="?/news/{{ i + 1 }}">[{{ i + 1 }}]</a> + {% endfor %} + </p> +{% endif %} diff --git a/templates/mod/noticeboard.html b/templates/mod/noticeboard.html index 4d764d80..4a0a068f 100644 --- a/templates/mod/noticeboard.html +++ b/templates/mod/noticeboard.html @@ -40,13 +40,13 @@ <em>{% trans 'no subject' %}</em> {% endif %} <small class="unimportant"> - — by + — {% trans 'by' %} {% if post.username %} - {{ post.username }} + {{ post.username|e }} {% else %} - <em>deleted?</em> + <em>{% trans 'deleted?' %}</em> {% endif %} - at + {% trans 'at' %} {{ notice.time|date(config.post_date) }} </small> </h2> diff --git a/templates/mod/pm.html b/templates/mod/pm.html index 511bcfef..c66dc883 100644 --- a/templates/mod/pm.html +++ b/templates/mod/pm.html @@ -1,11 +1,11 @@ <form action="" method="post"> <table> <tr> - <th>From</th> + <th>{% trans 'From' %}</th> {% if username %} <td><a href="?/new_PM/{{ username|e }}">{{ username|e }}</a></td> {% else %} - <td><em>deleted?</em></td> + <td><em>{% trans 'deleted?' %}</em></td> {% endif %} </tr> {% if to != mod.id %} @@ -14,27 +14,27 @@ {% if to_username %} <td><a href="?/new_PM/{{ to_username|e }}">{{ to_username|e }}</a></td> {% else %} - <td><em>deleted?</em></td> + <td><em>{% trans 'deleted?' %}</em></td> {% endif %} </tr> {% endif %} <tr> - <th>Date</th> + <th>{% trans 'Date' %}</th> <td>{{ time|date(config.post_date) }}</td> </tr> <tr> - <th>Message</th> + <th>{% trans 'Message' %}</th> <td>{{ message }}</td> </tr> </table> <ul style="list-style:none;text-align:center;padding:0"> <li style="padding:5px 0"> - <input type="submit" name="delete" value="Delete forever"> + <input type="submit" name="delete" value="{% trans 'Delete forever' %}"> </li> <li style="padding:5px 0"> <a href="?/PM/{{ id }}/reply"> - Reply with quote + {% trans 'Reply with quote' %} </a> </li> </ul> diff --git a/templates/mod/rebuild.html b/templates/mod/rebuild.html index 856855d7..7c6b28ba 100644 --- a/templates/mod/rebuild.html +++ b/templates/mod/rebuild.html @@ -2,7 +2,7 @@ <ul id="rebuild"> <li style="margin-bottom:8px"> <input type="checkbox" name="rebuild_all" id="rebuild_all" onchange="toggleall(this.checked)"> - <label for="rebuild_all"><strong>Toggle all</strong></label> + <label for="rebuild_all"><strong>{% trans 'Toggle all' %}</strong></label> <script> function toggleall(val) { /* TODO: something more suitable for all browsers? */ @@ -15,27 +15,27 @@ </li> <li> <input type="checkbox" name="rebuild_cache" id="rebuild_cache" checked> - <label for="rebuild_cache">Flush cache</label> + <label for="rebuild_cache">{% trans 'Flush cache' %}</label> </li> <li> <input type="checkbox" name="rebuild_javascript" id="rebuild_javascript" checked> - <label for="rebuild_javascript">Rebuild Javascript</label> + <label for="rebuild_javascript">{% trans 'Rebuild Javascript' %}</label> </li> <li> <input type="checkbox" name="rebuild_index" id="rebuild_index" checked> - <label for="rebuild_index">Rebuild index pages</label> + <label for="rebuild_index">{% trans 'Rebuild index pages' %}</label> </li> <li> <input type="checkbox" name="rebuild_thread" id="rebuild_thread" checked> - <label for="rebuild_thread">Rebuild thread pages</label> + <label for="rebuild_thread">{% trans 'Rebuild thread pages' %}</label> </li> <li> <input type="checkbox" name="rebuild_themes" id="rebuild_themes" checked> - <label for="rebuild_themes">Rebuild themes</label> + <label for="rebuild_themes">{% trans 'Rebuild themes' %}</label> </li> <li> <input type="checkbox" name="rebuild_posts" id="rebuild_posts"> - <label for="rebuild_posts">Rebuild replies</label> + <label for="rebuild_posts">{% trans 'Rebuild replies' %}</label> </li> </ul> @@ -44,7 +44,7 @@ <ul id="boards"> <li style="margin-bottom:8px"> <input type="checkbox" name="boards_all" id="boards_all" onchange="toggleallboards(this.checked)" checked> - <label for="boards_all"><strong>All boards</strong></label> + <label for="boards_all"><strong>{% trans 'All boards' %}</strong></label> <script> function toggleallboards(val) { /* TODO: something more suitable for all browsers? */ @@ -59,13 +59,13 @@ <li> <input type="checkbox" name="board_{{ board.uri }}" id="board-{{ board.uri }}" checked> <label for="board-{{ board.uri }}"> - {{ config.board_abbreviation|sprintf(board.uri) }} - {{ board.title }} + {{ config.board_abbreviation|sprintf(board.uri) }} - {{ board.title|e }} </label> </li> {% endfor %} </ul> <p style="text-align:center"> - <input type="submit" value="Rebuild" name="rebuild"> + <input type="submit" value="{% trans 'Rebuild' %}" name="rebuild"> </p> </form> diff --git a/templates/mod/rebuilt.html b/templates/mod/rebuilt.html index 8cc10bf9..57d16fff 100644 --- a/templates/mod/rebuilt.html +++ b/templates/mod/rebuilt.html @@ -1,12 +1,12 @@ <div class="ban"> - <h2>Rebuilt</h2> + <h2>{% trans 'Rebuilt' %}</h2> <ul> {% for log in logs %} <li>{{ log }}</li> {% endfor %} </ul> <p> - <a href="?/rebuild">Go back and rebuild again</a>. + <a href="?/rebuild">{% trans 'Go back and rebuild again' %}</a>. </p> </div> diff --git a/templates/mod/report.html b/templates/mod/report.html index c84e3c89..9c8463ed 100644 --- a/templates/mod/report.html +++ b/templates/mod/report.html @@ -1,25 +1,25 @@ <div class="report"> <hr> - Board: <a href="?/{{ report.board }}/{{ config.file_index }}">{{ config.board_abbreviation|sprintf(report.board) }}</a> + {% trans 'Board' %}: <a href="?/{{ report.board }}/{{ config.file_index }}">{{ config.board_abbreviation|sprintf(report.board) }}</a> <br> - Reason: {{ report.reason }} + {% trans 'Reason' %}: {{ report.reason }} <br> - Report date: {{ report.time|date(config.post_date) }} + {% trans 'Report date' %}: {{ report.time|date(config.post_date) }} <br> {% if mod|hasPermission(config.mod.show_ip, report.board) %} - Reported by: <a href="?/IP/{{ report.ip }}">{{ report.ip }}</a> + {% trans 'Reported by' %}: <a href="?/IP/{{ report.ip }}">{{ report.ip }}</a> <br> {% endif %} {% if mod|hasPermission(config.mod.report_dismiss, report.board) or mod|hasPermission(config.mod.report_dismiss_ip, report.board) %} <hr> {% if mod|hasPermission(config.mod.report_dismiss, report.board) %} - <a title="Discard abuse report" href="?/reports/{{ report.id }}/dismiss">Dismiss</a> + <a title="{% trans 'Discard abuse report' %}" href="?/reports/{{ report.id }}/dismiss">Dismiss</a> {% endif %} {% if mod|hasPermission(config.mod.report_dismiss_ip, report.board) %} {% if mod|hasPermission(config.mod.report_dismiss, report.board) %} | {% endif %} - <a title="Discard all abuse reports by this IP address" href="?/reports/{{ report.id }}/dismissall">Dismiss+</a> + <a title="{% trans 'Discard all abuse reports by this IP address' %}" href="?/reports/{{ report.id }}/dismissall">Dismiss+</a> {% endif %} {% endif %} </div> diff --git a/templates/mod/reports.html b/templates/mod/reports.html index 37322e35..26bceacc 100644 --- a/templates/mod/reports.html +++ b/templates/mod/reports.html @@ -1,5 +1,6 @@ {% if reports %} {{ reports }} {% else %} - <p style="text-align:center" class="unimportant">(There are no reports.)</p> + <p style="text-align:center" class="unimportant">({% trans 'There are no reports.' %})</p> {% endif %} + diff --git a/templates/mod/user.html b/templates/mod/user.html index 87a57d92..3c4b89cf 100644 --- a/templates/mod/user.html +++ b/templates/mod/user.html @@ -1,9 +1,15 @@ -<form action="?/users/{{ mod.id }}" method="post"> +{% if new %} + {% set action = '?/users/new' %} +{% else %} + {% set action = '?/users/' ~ user.id %} +{% endif %} + +<form action="{{ action }}" method="post"> <table> <tr> - <th>Username</th> + <th>{% trans 'Username' %}</th> <td> - {% if mod|hasPermission(config.mod.editusers) %} + {% if new or mod|hasPermission(config.mod.editusers) %} <input size="20" maxlength="30" type="text" name="username" value="{{ user.username|e }}" autocomplete="off"> {% else %} {{ user.username|e }} @@ -11,17 +17,38 @@ </td> </tr> <tr> - <th>Password <small style="font-weight:normal">(new; optional)</small></th> + <th>{% trans 'Password' %}{% if not new %} <small style="font-weight:normal">({% trans 'new; optional' %})</small>{% endif %}</th> <td> - {% if mod|hasPermission(config.mod.editusers) or (mod|hasPermission(config.mod.change_password) and user.id == mod.id) %} + {% if new or (mod|hasPermission(config.mod.editusers) or (mod|hasPermission(config.mod.change_password) and user.id == mod.id)) %} <input size="20" maxlength="30" type="password" name="password" value="" autocomplete="off"> {% else %} - {% endif %} </td> </tr> + {% if new %} + <tr> + <th>{% trans 'Class' %}</th> + <td> + <ul style="padding:5px 8px;list-style:none"> + <li> + <input type="radio" name="type" id="janitor" value="{{ constant('JANITOR') }}"> + <label for="janitor">{% trans 'Janitor' %}</label> + </li> + <li> + <input type="radio" name="type" id="mod" value="{{ constant('MOD') }}" checked> + <label for="mod">{% trans 'Mod' %}</label> + </li> + <li> + <input type="radio" name="type" id="admin" value="{{ constant('Admin') }}"> + <label for="admin">{% trans 'Admin' %}</label> + </li> + </ul> + </td> + </tr> + {% endif %} <tr> - <th>Boards</th> + <th>{% trans 'Boards' %}</th> <td> <ul style="padding:0 5px;list-style:none"> <li> @@ -31,7 +58,7 @@ disabled {% endif %} > - <label for="allboards">"*" - All boards</label> + <label for="allboards">"*" - {% trans 'All boards' %}</label> </li> {% for board in boards %} <li> @@ -44,7 +71,7 @@ <label for="board_{{ board.uri }}"> {{ config.board_abbreviation|sprintf(board.uri) }} - - {{ board.title }} + {{ board.title|e }} </label> </li> {% endfor %} @@ -53,10 +80,14 @@ </tr> </table> - <ul style="padding:0;text-align:center"> - <li><input type="submit" value="Save changes"></li> - {% if mod|hasPermission(config.mod.deleteusers) %} - <li><input type="submit" value="Delete user"></li> + <ul style="padding:0;text-align:center;list-style:none"> + {% if new %} + <li><input type="submit" value="{% trans 'Create user' %}"></li> + {% else %} + <li><input type="submit" value="{% trans 'Save changes' %}"></li> + {% if mod|hasPermission(config.mod.deleteusers) %} + <li><input name="delete" onclick="return confirm('Are you sure you want to permanently delete this user?');" type="submit" value="{% trans 'Delete user' %}"></li> + {% endif %} {% endif %} </ul> </form> @@ -64,10 +95,10 @@ {% if logs|count > 0 %} <table class="modlog" style="width:600px"> <tr> - <th>IP address</th> - <th>Time</th> - <th>Board</th> - <th>Action</th> + <th>{% trans 'IP address' %}</th> + <th>{% trans 'Time' %}</th> + <th>{% trans 'Board' %}</th> + <th>{% trans 'Action' %}</th> </tr> {% for log in logs %} <tr> @@ -91,3 +122,4 @@ {% endfor %} </table> {% endif %} + diff --git a/templates/mod/users.html b/templates/mod/users.html index 63d799d5..a0d216d3 100644 --- a/templates/mod/users.html +++ b/templates/mod/users.html @@ -1,39 +1,45 @@ <table class="modlog" style="width:auto"> <tr> - <th>ID</th> - <th>Username</th> - <th>Type</th> - <th>Boards</th> - <th>Last action</th> + <th>{% trans 'ID' %}</th> + <th>{% trans 'Username' %}</th> + <th>{% trans 'Type' %}</th> + <th>{% trans 'Boards' %}</th> + <th>{% trans 'Last action' %}</th> <th>…</th> </tr> {% for user in users %} <tr> <td><small>{{ user.id }}</small></td> - <td>{{ user.username }}</td> + <td>{{ user.username|e }}</td> <td> - {% if user.type == constant('JANITOR') %}Janitor - {% elseif user.type == constant('MOD') %}Mod - {% elseif user.type == constant('ADMIN') %}Admin + {% if user.type == constant('JANITOR') %}{% trans 'Janitor' %} + {% elseif user.type == constant('MOD') %}{% trans 'Mod' %} + {% elseif user.type == constant('ADMIN') %}{% trans 'Admin' %} {% endif %} </td> <td> - {# This is really messy, but IMO it beats doing it in PHP. #} - {% set boards = user.boards|split(',') %} - {% set _boards = [] %} - {% for board in boards %} - {% set _boards = _boards|push(board == '*' ? '*' : config.board_abbreviation|sprintf(board)) %} - {% endfor %} - {% set _boards = _boards|sort %} - {{ _boards|join(', ') }} + {% if user.boards == '' %} + <em>{% trans 'none' %}</em> + {% elseif user.boards == '*' %} + <em>{% trans 'all boards' %}</em> + {% else %} + {# This is really messy, but IMO it beats doing it in PHP. #} + {% set boards = user.boards|split(',') %} + {% set _boards = [] %} + {% for board in boards %} + {% set _boards = _boards|push(board == '*' ? '*' : config.board_abbreviation|sprintf(board)) %} + {% endfor %} + {% set _boards = _boards|sort %} + {{ _boards|join(', ') }} + {% endif %} </td> <td> {% if mod|hasPermission(config.mod.modlog) %} {% if user.last %} <span title="{{ user.action|e }}">{{ user.last|ago }}</span> {% else %} - <em>never</em> + <em>{% trans 'never' %}</em> {% endif %} {% else %} – @@ -41,18 +47,25 @@ </td> <td> {% if mod|hasPermission(config.mod.promoteusers) and user.type < constant('ADMIN') %} - <a style="float:left;text-decoration:none" href="?/users/{{ user.id }}/promote" title="Promote">▲</a> + <a style="float:left;text-decoration:none" href="?/users/{{ user.id }}/promote" title="{% trans 'Promote' %}">▲</a> {% endif %} {% if mod|hasPermission(config.mod.promoteusers) and user.type > constant('JANITOR') %} - <a style="float:left;text-decoration:none" href="?/users/{{ user.id }}/demote" title="Demote">▼</a> + <a style="float:left;text-decoration:none" href="?/users/{{ user.id }}/demote" title="{% trans 'Demote' %}">▼</a> {% endif %} {% if mod|hasPermission(config.editusers) or (mod|hasPermission(config.change_password) and mod.id == user.id) %} - <a class="unimportant" style="margin-left:5px;float:right" href="?/users/{{ user.id }}">[edit]</a> + <a class="unimportant" style="margin-left:5px;float:right" href="?/users/{{ user.id }}">[{% trans 'edit' %}]</a> {% endif %} {% if mod|hasPermission(config.mod.create_pm) %} - <a class="unimportant" style="margin-left:5px;float:right" href="?/new_PM/{{ user.username }}">[PM]</a> + <a class="unimportant" style="margin-left:5px;float:right" href="?/new_PM/{{ user.username|e }}">[{% trans 'PM' %}]</a> {% endif %} </td> </tr> {% endfor %} </table> + +{% if mod|hasPermission(config.mod.createusers) %} + <p style="text-align:center"> + <a href="?/users/new">Create a new user</a> + </p> +{% endif %} + diff --git a/templates/mod/view_ip.html b/templates/mod/view_ip.html index 3bc9654c..e69301fd 100644 --- a/templates/mod/view_ip.html +++ b/templates/mod/view_ip.html @@ -1,37 +1,38 @@ {% for board_posts in posts %} <fieldset> <legend> - <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board_posts.board.uri) }}</a> + <a href="?/{{ config.board_path|sprintf(board_posts.board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board_posts.board.uri) }}</a> - - {{ board_posts.board.title }} + {{ board_posts.board.title|e }} </legend> {{ board_posts.posts|join('<hr>') }} </fieldset> {% endfor %} {% if mod|hasPermission(config.mod.view_notes) %} - <fieldset> + <fieldset id="notes"> <legend> - {{ notes|count }} note{% if notes|count != 1 %}s{% endif %} on record + {% set notes_on_record = 'note' ~ (notes|count != 1 ? 's' : '') ~ ' on record' %} + <legend>{{ notes|count }} {% trans notes_on_record %}</legend> </legend> {% if notes|count > 0 %} <table class="modlog"> <tr> - <th>Staff</th> - <th>Note</th> - <th>Date</th> + <th>{% trans 'Staff' %}</th> + <th>{% trans 'Note' %}</th> + <th>{% trans 'Date' %}</th> {% if mod|hasPermission(config.mod.remove_notes) %} - <th>Actions</th> + <th>{% trans 'Actions' %}</th> {% endif %} </tr> {% for note in notes %} <tr> <td class="minimal"> {% if note.username %} - <a href="?/new_PM/{{ note.username }}">{{ note.username }}</a> + <a href="?/new_PM/{{ note.username|e }}">{{ note.username|e }}</a> {% else %} - <em>deleted?</em> + <em>{% trans 'deleted?' %}</em> {% endif %} </td> <td> @@ -42,7 +43,9 @@ </td> {% if mod|hasPermission(config.mod.remove_notes) %} <td class="minimal"> - <a href="?/IP/{{ ip }}/remove_note/{{ note.id }}"><small>[remove]</small></a> + <a href="?/IP/{{ ip }}/remove_note/{{ note.id }}"> + <small>[{% trans 'remove' %}]</small> + </a> </td> {% endif %} </tr> @@ -54,12 +57,12 @@ <form action="" method="post" style="margin:0"> <table> <tr> - <th>Staff</th> - <td>{{ mod.username }}</td> + <th>{% trans 'Staff' %}</th> + <td>{{ mod.username|e }}</td> </tr> <tr> <th> - <label for="note">Note</label> + <label for="note">{% trans 'Note' %}</label> </th> <td> <textarea id="note" name="note" rows="5" cols="30"></textarea> @@ -67,7 +70,7 @@ </tr> <tr> <td></td> - <td><input type="submit" value="New note"></td> + <td><input type="submit" value="{% trans 'New note' %}"></td> </tr> </table> </form> @@ -76,73 +79,74 @@ {% endif %} {% if bans|count > 0 and mod|hasPermission(config.mod.view_ban) %} - <fieldset> - <legend>Ban{% if bans|count != 1 %}s{% endif %} on record</legend> + <fieldset id="bans"> + {% set bans_on_record = 'ban' ~ (bans|count != 1 ? 's' : '') ~ ' on record' %} + <legend>{{ bans|count }} {% trans bans_on_record %}</legend> {% for ban in bans %} <form action="" method="post" style="text-align:center"> <table style="width:400px;margin-bottom:10px;border-bottom:1px solid #ddd;padding:5px"> <tr> - <th>Status</th> + <th>{% trans 'Status' %}</th> <td> {% if config.mod.view_banexpired and ban.expires != 0 and ban.expires < time() %} - Expired + {% trans 'Expired' %} {% else %} - Active + {% trans 'Active' %} {% endif %} </td> </tr> <tr> - <th>IP</th> + <th>{% trans 'IP' %}</th> <td>{{ ban.ip }}</td> </tr> <tr> - <th>Reason</th> + <th>{% trans 'Reason' %}</th> <td> {% if ban.reason %} {{ ban.reason }} {% else %} - <em>no reason</em> + <em>{% trans 'no reason' %}</em> {% endif %} </td> </tr> <tr> - <th>Board</th> + <th>{% trans 'Board' %}</th> <td> {% if ban.board %} {{ config.board_abbreviation|sprintf(ban.board) }} {% else %} - <em>all boards</em> + <em>{% trans 'all boards' %}</em> {% endif %} </td> </tr> <tr> - <th>Set</th> + <th>{% trans 'Set' %}</th> <td>{{ ban.set|date(config.post_date) }}</td> </tr> <tr> - <th>Expires</th> + <th>{% trans 'Expires' %}</th> <td> {% if ban.expires %} {{ ban.expires|date(config.post_date) }} {% else %} - <em>never</em> + <em>{% trans 'never' %}</em> {% endif %} </td> </tr> <tr> - <th>Staff</th> + <th>{% trans 'Staff' %}</th> <td> {% if ban.username %} - {{ ban.username }} + {{ ban.username|e }} {% else %} - <em>deleted?</em> + <em>{% trans 'deleted?' %}</em> {% endif %} </td> </tr> </table> <input type="hidden" name="ban_id" value="{{ ban.id }}"> - <input type="submit" name="unban" value="Remove ban"> + <input type="submit" name="unban" value="{% trans 'Remove ban' %}"> </form> {% endfor %} </fieldset> @@ -150,8 +154,8 @@ {% if mod|hasPermission(config.mod.ban) %} <fieldset> - <legend>New ban</legend> - {% set redirect = '?/IP/' ~ ip %} + <legend>{% trans 'New ban' %}</legend> + {% set redirect = '?/IP/' ~ ip ~ '#bans' %} {% include 'mod/ban_form.html' %} </fieldset> {% endif %} diff --git a/templates/page.html b/templates/page.html index 0c0264d1..a5dc3dc0 100644 --- a/templates/page.html +++ b/templates/page.html @@ -1,12 +1,12 @@ <!doctype html>
<html>
<head>
- <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}" />
- {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}" />{% endif %}
+ <meta charset="utf-8">
+ <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}">
+ {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}">{% endif %}
<title>{{ title }}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
- <link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}" />
+ <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=yes">
+ {% if config.default_stylesheet.1 != '' %}<link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}">{% endif %}
{% if not nojavascript %}<script type="text/javascript" src="{{ config.url_javascript }}"></script>{% endif %}
</head>
<body>
diff --git a/templates/themes/basic/info.php b/templates/themes/basic/info.php index b782a6d4..0b8ba98b 100644 --- a/templates/themes/basic/info.php +++ b/templates/themes/basic/info.php @@ -44,9 +44,9 @@ $theme['build_function'] = 'basic_build'; $theme['install_callback'] = 'build_install'; - if(!function_exists('build_install')) { + if (!function_exists('build_install')) { function build_install($settings) { - if(!is_numeric($settings['no_recent']) || $settings['no_recent'] < 0) + if (!is_numeric($settings['no_recent']) || $settings['no_recent'] < 0) return Array(false, '<strong>' . utf8tohtml($settings['no_recent']) . '</strong> is not a non-negative integer.'); } } diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php index a07dc7ec..806a331a 100644 --- a/templates/themes/basic/theme.php +++ b/templates/themes/basic/theme.php @@ -15,7 +15,7 @@ public static function build($action, $settings) { global $config; - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file'], Basic::homepage($settings)); } diff --git a/templates/themes/categories/info.php b/templates/themes/categories/info.php index 5ae3d296..62d8f6bb 100644 --- a/templates/themes/categories/info.php +++ b/templates/themes/categories/info.php @@ -54,11 +54,11 @@ Requires $config[\'categories\'].'; $theme['build_function'] = 'categories_build'; $theme['install_callback'] = 'categories_install'; - if(!function_exists('categories_install')) { + if (!function_exists('categories_install')) { function categories_install($settings) { global $config; - if(!isset($config['categories'])) { + if (!isset($config['categories'])) { return Array(false, '<h2>Prerequisites not met!</h2>' . 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.'); } diff --git a/templates/themes/categories/sidebar.html b/templates/themes/categories/sidebar.html index a4bc28ae..856930ab 100644 --- a/templates/themes/categories/sidebar.html +++ b/templates/themes/categories/sidebar.html @@ -31,7 +31,7 @@ </legend> {% for board in boards %} <li> - <a href="{{ board.uri }}">{{ board.title }}</a> + <a href="{{ board.uri }}">{{ board.title|e }}</a> </li> {% endfor %} </fieldset> diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php index 648034e7..11fcbbaf 100644 --- a/templates/themes/categories/theme.php +++ b/templates/themes/categories/theme.php @@ -15,13 +15,13 @@ public static function build($action, $settings) { global $config; - if($action == 'all') + if ($action == 'all') file_write($config['dir']['home'] . $settings['file_main'], Categories::homepage($settings)); - if($action == 'all' || $action == 'boards') + if ($action == 'all' || $action == 'boards') file_write($config['dir']['home'] . $settings['file_sidebar'], Categories::sidebar($settings)); - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file_news'], Categories::news($settings)); } @@ -52,10 +52,10 @@ $categories = $config['categories']; - foreach($categories as &$boards) { - foreach($boards as &$board) { + foreach ($categories as &$boards) { + foreach ($boards as &$board) { $title = boardTitle($board); - if(!$title) + if (!$title) $title = $board; // board doesn't exist, but for some reason you want to display it anyway $board = Array('title' => $title, 'uri' => sprintf($config['board_path'], $board)); } diff --git a/templates/themes/frameset/sidebar.html b/templates/themes/frameset/sidebar.html index 457ecec8..40e2d719 100644 --- a/templates/themes/frameset/sidebar.html +++ b/templates/themes/frameset/sidebar.html @@ -30,7 +30,7 @@ {% for board in boards %} <li> <a href="{{ config.board_path|sprintf(board.uri) }}"> - {{ board.title }} + {{ board.title|e }} </a> </li> {% endfor %} diff --git a/templates/themes/frameset/theme.php b/templates/themes/frameset/theme.php index f3e1b139..015eebaf 100644 --- a/templates/themes/frameset/theme.php +++ b/templates/themes/frameset/theme.php @@ -15,13 +15,13 @@ public static function build($action, $settings) { global $config; - if($action == 'all') + if ($action == 'all') file_write($config['dir']['home'] . $settings['file_main'], Frameset::homepage($settings)); - if($action == 'all' || $action == 'boards') + if ($action == 'all' || $action == 'boards') file_write($config['dir']['home'] . $settings['file_sidebar'], Frameset::sidebar($settings)); - if($action == 'all' || $action == 'news') + if ($action == 'all' || $action == 'news') file_write($config['dir']['home'] . $settings['file_news'], Frameset::news($settings)); } diff --git a/templates/themes/recent/info.php b/templates/themes/recent/info.php index 83d7477a..d4cf1029 100644 --- a/templates/themes/recent/info.php +++ b/templates/themes/recent/info.php @@ -60,11 +60,11 @@ $theme['build_function'] = 'recentposts_build'; $theme['install_callback'] = 'recentposts_install'; - if(!function_exists('recentposts_install')) { + if (!function_exists('recentposts_install')) { function recentposts_install($settings) { - if(!is_numeric($settings['limit_images']) || $settings['limit_images'] < 0) + if (!is_numeric($settings['limit_images']) || $settings['limit_images'] < 0) return Array(false, '<strong>' . utf8tohtml($settings['limit_images']) . '</strong> is not a non-negative integer.'); - if(!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) + if (!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) return Array(false, '<strong>' . utf8tohtml($settings['limit_posts']) . '</strong> is not a non-negative integer.'); } } diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index 13a5546f..986fac6a 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -17,13 +17,13 @@ public function build($action, $settings) { global $config, $_theme; - if($action == 'all') { + if ($action == 'all') { copy('templates/themes/recent/recent.css', $config['dir']['home'] . $settings['css']); } $this->excluded = explode(' ', $settings['exclude']); - if($action == 'all' || $action == 'post') + if ($action == 'all' || $action == 'post') file_write($config['dir']['home'] . $settings['html'], $this->homepage($settings)); } @@ -38,15 +38,15 @@ $boards = listBoards(); $query = ''; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + 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 = 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()) { openBoard($post['board']); // board settings won't be available in the template file, so generate links now @@ -58,15 +58,15 @@ $query = ''; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + 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 = 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()) { 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,8 +78,8 @@ // Total posts $query = 'SELECT SUM(`top`) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + 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']); } @@ -90,8 +90,8 @@ // Unique IPs $query = 'SELECT COUNT(DISTINCT(`ip`)) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT `ip` FROM `posts_%s` UNION ALL ", $_board['uri']); } @@ -102,8 +102,8 @@ // Active content $query = 'SELECT SUM(`filesize`) AS `count` FROM ('; - foreach($boards as &$_board) { - if(in_array($_board['uri'], $this->excluded)) + foreach ($boards as &$_board) { + if (in_array($_board['uri'], $this->excluded)) continue; $query .= sprintf("SELECT `filesize` FROM `posts_%s` UNION ALL ", $_board['uri']); } diff --git a/templates/themes/rrdtool/info.php b/templates/themes/rrdtool/info.php index 73658a22..46a20587 100644 --- a/templates/themes/rrdtool/info.php +++ b/templates/themes/rrdtool/info.php @@ -28,7 +28,7 @@ $__boards = listBoards(); $__default_boards = Array(); - foreach($__boards as $__board) + foreach ($__boards as $__board) $__default_boards[] = $__board['uri']; $theme['config'][] = Array( @@ -83,31 +83,31 @@ ); $theme['install_callback'] = 'rrdtool_install'; - if(!function_exists('rrdtool_install')) { + if (!function_exists('rrdtool_install')) { function rrdtool_install($settings) { global $config; - if(!is_numeric($settings['interval']) || $settings['interval'] < 1 || $settings['interval'] > 86400) + if (!is_numeric($settings['interval']) || $settings['interval'] < 1 || $settings['interval'] > 86400) return Array(false, 'Invalid interval: <strong>' . $settings['interval'] . '</strong>. Must be an integer greater than 1 and less than 86400.'); - if(!is_numeric($settings['width']) || $settings['width'] < 1) + if (!is_numeric($settings['width']) || $settings['width'] < 1) return Array(false, 'Invalid width: <strong>' . $settings['width'] . '</strong>!'); - if(!is_numeric($settings['height']) || $settings['height'] < 1) + if (!is_numeric($settings['height']) || $settings['height'] < 1) return Array(false, 'Invalid height: <strong>' . $settings['height'] . '</strong>!'); - if(!in_array($settings['rate'], Array('second', 'minute', 'day', 'hour', 'week', 'month', 'year'))) + if (!in_array($settings['rate'], Array('second', 'minute', 'day', 'hour', 'week', 'month', 'year'))) return Array(false, 'Invalid rate: <strong>' . $settings['rate'] . '</strong>!'); $job = '*/' . $settings['interval'] . ' * * * * php -q ' . str_replace('\\', '/', dirname(__FILE__)) . '/cron.php' . PHP_EOL; - if(function_exists('system')) { + if (function_exists('system')) { $crontab = tempnam($config['tmp'], 'tinyboard-rrdtool'); file_write($crontab, $job); @system('crontab ' . escapeshellarg($crontab), $ret); unlink($crontab); - if($ret === 0) + if ($ret === 0) return ''; // it seems to install okay? } diff --git a/templates/themes/rrdtool/theme.php b/templates/themes/rrdtool/theme.php index 20a00e76..eed2ac9a 100644 --- a/templates/themes/rrdtool/theme.php +++ b/templates/themes/rrdtool/theme.php @@ -17,7 +17,7 @@ public function build($action, $settings) { global $config, $_theme, $argv; - if(!$settings) { + if (!$settings) { error('This theme is not currently installed.'); } @@ -26,18 +26,18 @@ // exclude boards from the "combined" graph $this->combined_exclude = Array(); - if($action == 'cron') { - if(!file_exists($settings['path'])) + if ($action == 'cron') { + if (!file_exists($settings['path'])) mkdir($settings['path']); - if(!file_exists($settings['images'])) + if (!file_exists($settings['images'])) mkdir($settings['images']); - foreach($this->boards as &$board) { + foreach ($this->boards as &$board) { $file = $settings['path'] . '/' . $board . '.rrd'; - if(!file_exists($file)) { + if (!file_exists($file)) { // Create graph - if(!rrd_create($file, Array( + if (!rrd_create($file, Array( '-s 60', 'DS:posts:COUNTER:86400:0:10000', @@ -59,22 +59,22 @@ } // debug just the graphing (not updating) with the --debug switch - if(!isset($argv[1]) || $argv[1] != '--debug') { + 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']; - if(!rrd_update($file, Array( + if (!rrd_update($file, Array( '-t', 'posts', 'N:' . $count))) error('RRDtool failed: ' . htmlentities(rrd_error())); } - foreach($this->spans as &$span) { + foreach ($this->spans as &$span) { // Graph graph - if(!rrd_graph($settings['images'] . '/' . $board . '-' . $span . '.png', Array( + if (!rrd_graph($settings['images'] . '/' . $board . '-' . $span . '.png', Array( '-s -1' . $span, '-t Posts on ' . sprintf($config['board_abbreviation'], $board) .' this ' . $span, '--lazy', @@ -105,7 +105,7 @@ } // combined graph - foreach($this->spans as &$span) { + foreach ($this->spans as &$span) { $options = Array( '-s -1' . $span, '-t Posts this ' . $span, @@ -129,8 +129,8 @@ $c = 1; $cc = 0; $red = 2; - foreach($this->boards as &$board) { - if(in_array($board, $this->combined_exclude)) + foreach ($this->boards as &$board) { + if (in_array($board, $this->combined_exclude)) continue; $color = str_pad(dechex($red*85), 2, '0', STR_PAD_LEFT) . str_pad(dechex($green*85), 2, '0', STR_PAD_LEFT) . @@ -147,31 +147,35 @@ sprintf($config['board_abbreviation'], $board); // Randomize colors using this horrible undocumented algorithm I threw together while debugging - if($c == 0) + if ($c == 0) $red++; - elseif($c == 1) + elseif ($c == 1) $green++; - elseif($c == 2) + elseif ($c == 2) $blue++; - elseif($c == 3) + elseif ($c == 3) $green--; - elseif($c == 4) + elseif ($c == 4) $red--; $cc++; - if($cc > 2) { + if ($cc > 2) { $c++; $cc = 0; } - if($c>4) $c = 0; + if ($c > 4) + $c = 0; - if($red>3) $red = 0; - if($green>3) $green = 0; - if($blue>3) $blue = 0; + if ($red > 3) + $red = 0; + if ($green > 3) + $green = 0; + if ($blue > 3) + $blue = 0; } $options[] = 'HRULE:0#000000'; - if(!rrd_graph($settings['images'] . '/combined-' . $span . '.png', $options)) + if (!rrd_graph($settings['images'] . '/combined-' . $span . '.png', $options)) error('RRDtool failed: ' . htmlentities(rrd_error())); } } diff --git a/templates/thread.html b/templates/thread.html index 9a56a50f..e7c65f9b 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -1,13 +1,13 @@ <!doctype html>
<html>
<head>
- <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}" />
- {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}" />{% endif %}
+ <meta charset="utf-8">
+ <link rel="stylesheet" media="screen" href="{{ config.url_stylesheet }}">
+ {% if config.url_favicon %}<link rel="shortcut icon" href="{{ config.url_favicon }}">{% endif %}
<title>{{ board.url }} - {{ board.name }}</title>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
- {% if config.meta_keywords %}<meta name="keywords" content="{{ config.meta_keywords }}" />{% endif %}
- <link rel="stylesheet" type="text/css" id="stylesheet" href="{{ config.uri_stylesheets }}{{ config.default_stylesheet.1 }}" />
+ <meta name="viewport" content="width=device-width, initial-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 not nojavascript %}
<script type="text/javascript" src="{{ config.url_javascript }}"></script>
{% if not config.additional_javascript_compile %}
@@ -29,17 +29,16 @@ display: block;
}
{% endraw %}</style>{% endif %}
-
</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 }}</h1>
+ <h1>{{ board.url }} - {{ board.title|e }}</h1>
<div class="subtitle">
{% if board.subtitle %}
- {{ board.subtitle }}
+ {{ board.subtitle|e }}
{% endif %}
{% if mod %}<p><a href="?/">{% trans %}Return to dashboard{% endtrans %}</a></p>{% endif %}
</div>
|
