1
0
mirror of https://github.com/vichan-devel/vichan.git synced 2024-11-24 23:50:11 +01:00

[#184] Added <body> tag classes. Style selector now adds a <body> class. Moved board list under moderator dashboard.

This commit is contained in:
unknown 2014-10-18 20:07:04 -05:00
parent 6850301595
commit 2d6d449bd2
16 changed files with 915 additions and 227 deletions

553
d Normal file
View File

@ -0,0 +1,553 @@
diff --git a/inc/instance-config.php b/inc/instance-config.php
index 699d1a1..475f3ed 100644
--- a/inc/instance-config.php
+++ b/inc/instance-config.php
@@ -18,15 +18,15 @@
$config['db']['user'] = 'root';
$config['db']['password'] = '';
$config['timezone'] = 'UTC';
- $config['cache']['enabled'] = 'apc';
-
-
+ $config['cache']['enabled'] = false;
+ 
+ 
$config['cookies']['mod'] = 'mod';
$config['cookies']['salt'] = '';
-
+ 
$config['spam']['hidden_inputs_max_pass'] = 128;
$config['spam']['hidden_inputs_expire'] = 60 * 60 * 4; // three hours
-
+ 
$config['flood_time'] = 5;
$config['flood_time_ip'] = 30;
$config['flood_time_same'] = 2;
@@ -46,10 +46,10 @@
$config['thread_subject_in_title'] = true;
$config['spam']['hidden_inputs_max_pass'] = 128;
$config['ayah_enabled'] = true;
-
+ 
// Load database credentials
require "secrets.php";
-
+ 
// Image shit
$config['thumb_method'] = 'gm+gifsicle';
$config['thumb_ext'] = '';
diff --git a/install.php b/install.php
index 8b3815a..07e94e7 100644
--- a/install.php
+++ b/install.php
@@ -579,7 +579,8 @@ if ($step == 0) {
</p>';

echo Element('page.html', $page);
-} elseif ($step == 1) {
+}
+elseif ($step == 1) {
$page['title'] = 'Pre-installation test';

$can_exec = true;
@@ -761,7 +762,8 @@ if ($step == 0) {
'title' => 'Checking environment',
'config' => $config
));
-} elseif ($step == 2) {
+}
+elseif ($step == 2) {
// Basic config
$page['title'] = 'Configuration';

@@ -775,7 +777,8 @@ if ($step == 0) {
'title' => 'Configuration',
'config' => $config
));
-} elseif ($step == 3) {
+}
+elseif ($step == 3) {
$instance_config = 
'<?php

@@ -814,7 +817,8 @@ if ($step == 0) {

if (@file_put_contents('inc/instance-config.php', $instance_config)) {
header('Location: ?step=4', true, $config['redirect_http']);
- } else {
+ }
+ else {
$page['title'] = 'Manual installation required';
$page['body'] = '
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p>
@@ -826,7 +830,8 @@ if ($step == 0) {
';
echo Element('page.html', $page);
}
-} elseif ($step == 4) {
+}
+elseif ($step == 4) {
// SQL installation

buildJavascript();
@@ -846,11 +851,15 @@ if ($step == 0) {

$sql_errors = '';
foreach ($queries as $query) {
- if ($mysql_version < 50503)
+ if ($mysql_version < 50503) {
$query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query);
+ }
+ 
$query = preg_replace('/^([\w\s]*)`([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)`/u', '$1``$2``', $query);
- if (!query($query))
+ 
+ if (!query($query)) {
$sql_errors .= '<li>' . db_error() . '</li>';
+ }
}

$page['title'] = 'Installation complete';
@@ -858,7 +867,8 @@ if ($step == 0) {

if (!empty($sql_errors)) {
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a vichan installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>';
- } else {
+ }
+ else {
$boards = listBoards();
foreach ($boards as &$_board) {
setupBoard($_board);
@@ -866,13 +876,11 @@ if ($step == 0) {
}

file_write($config['has_installed'], VERSION);
- /*if (!file_unlink(__FILE__)) {
- $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
- }*/
}

echo Element('page.html', $page);
-} elseif ($step == 5) {
+}
+elseif ($step == 5) {
$page['title'] = 'Installation complete';
$page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover.</p>';

diff --git a/templates/8chan/index.html b/templates/8chan/index.html
index 459e7e8..4f25473 100644
--- a/templates/8chan/index.html
+++ b/templates/8chan/index.html
@@ -223,7 +223,7 @@
</style>
</head>

- <body>
+ <body class="8chan index">

<div id="main">

diff --git a/templates/generic_page.html b/templates/generic_page.html
index 0fe1f9c..4cd3116 100644
--- a/templates/generic_page.html
+++ b/templates/generic_page.html
@@ -6,7 +6,7 @@
<title>{{ board.url }} - {{ board.name }}</title>
{% endblock %}
</head>
-<body> 
+<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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 %}
diff --git a/templates/index.html b/templates/index.html
index aae87c1..5638fd6 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -14,7 +14,7 @@
{% include 'header.html' %}
<title>{{ board.url }} - {{ board.title|e }}</title>
</head>
-<body> 
+<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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 %}
diff --git a/templates/main.js b/templates/main.js
index 1ec4d26..d100f93 100644
--- a/templates/main.js
+++ b/templates/main.js
@@ -73,11 +73,6 @@ 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) {
@@ -92,36 +87,78 @@ function changeStyle(styleName, link) {
{% endif %}
{% raw %}

- if (!document.getElementById('stylesheet')) {
- var s = document.createElement('link');
- s.rel = 'stylesheet';
- s.type = 'text/css';
- s.id = 'stylesheet';
+ // Find the <dom> for the stylesheet. May be nothing.
+ var domStylesheet = document.getElementById('stylesheet');
+ // Determine if this stylesheet is the default.
+ var setToDefault = ( styles[styleName] == "" || styles[styleName] == "/stylesheets/" );
+ // Turn "Yotsuba B" to "yotsuba_b" 
+ var attributeName = styleName.replace(/[^a-z0-9_\-]/gi, '_').toLowerCase();
+ 
+ if( !domStylesheet && !setToDefault ) {
+ domStylesheet = document.createElement('link');
+ domStylesheet.rel = 'stylesheet';
+ domStylesheet.type = 'text/css';
+ domStylesheet.id = 'stylesheet';
+ 
var x = document.getElementsByTagName('head')[0];
- x.appendChild(s);
+ x.appendChild(domStylesheet);
}
-
- {% endraw %}
- var root = "{{ config.root }}";
- {% raw %}
- root = root.replace(/\/$/, "");
- 
- document.getElementById('stylesheet').href = root + 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( !setToDefault ) {
+ {% endraw %}
+ var root = "{{ config.root }}";
+ {% raw %}
+ root = root.replace(/\/$/, "");
+ 
+ domStylesheet.href = root + 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';
+ }
+ }
+ else if( domStylesheet ) {
+ domStylesheet.parentNode.removeChild( domStylesheet );
}

- if (link) {
- link.className = 'selected';
+ // Fix the classes on the body tag.
+ var body = document.getElementsByTagName('body')[0];
+ 
+ if( body ) {
+ var bodyClasses = document.getElementsByTagName('body')[0].getAttribute('class').split(" ");
+ var bodyClassesNew = [];
+ 
+ for( i = 0; i < bodyClasses.length; ++i ) {
+ var bodyClass = bodyClasses[ i ];
+ 
+ // null class from a double-space.
+ if( bodyClass == "" ) {
+ continue;
+ }
+ 
+ if( bodyClass.indexOf( "stylesheet-" ) == 0 ) {
+ continue;
+ }
+ 
+ bodyClassesNew.push( bodyClass );
+ }
+ 
+ // Add stylesheet-yotsuba_b at the end.
+ bodyClassesNew.push( "stylesheet-" + attributeName );
+ body.setAttribute( 'class', bodyClassesNew.join(" ") );
+ body.setAttribute( 'data-stylesheet', attributeName );
}

- if (typeof $ != 'undefined')
+ if (typeof $ != 'undefined') {
$(window).trigger('stylesheet', styleName);
+ }
}


@@ -167,7 +204,7 @@ function init_stylechooser() {
}
}
}
- {% endraw%}
+ {% endraw %}
{% else %}
{% raw %}
if (localStorage.stylesheet) {
@@ -185,10 +222,13 @@ function init_stylechooser() {

function get_cookie(cookie_name) {
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
- if (results)
+ 
+ if (results) {
return (unescape(results[2]));
- else
+ }
+ else {
return null;
+ }
}

function highlightReply(id) {
diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html
index 4f76625..87e67c8 100644
--- a/templates/mod/dashboard.html
+++ b/templates/mod/dashboard.html
@@ -1,40 +1,5 @@
-<fieldset>
- <legend>{% trans 'Boards' %}</legend>
- 
- <ul>
- {% for board in boards %}
- {% if board.uri in mod.boards or mod.boards[0] == '*' %}
- <li>
- <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
- - 
- {{ board.title|e }}
- {% if board.subtitle %}
- <small>&mdash; 
- {% if config.allow_subtitle_html %}
- {{ board.subtitle }}
- {% else %}
- {{ board.subtitle|e }}
- {% endif %}
- </small>
-
- {% endif %}
- {% if mod.type == "20" %}
- <a href="?/settings/{{ board.uri }}"><small>[{% trans 'settings' %}]</small></a>
- {% endif %}
- {% if mod|hasPermission(config.mod.manageboards) %}
- <a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a>
- {% endif %}
- </li>
- {% endif %}
- {% endfor %}
- 
- {% if mod|hasPermission(config.mod.newboard) %}
- <li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li>
- {% endif %}
- </ul>
-</fieldset>
-
-<fieldset>
+<!-- Messages -->
+<fieldset class="mod-dash mod-dash-set mod-dash-messages">
<legend>{% trans 'Messages' %}</legend>
<ul>
{% if mod|hasPermission(config.mod.noticeboard) %}
@@ -78,7 +43,8 @@
</ul>
</fieldset>

-<fieldset>
+<!-- Administration -->
+<fieldset class="mod-dash mod-dash-set mod-dash-messages">
<legend>{% trans 'Administration' %}</legend>

<ul>
@@ -123,57 +89,99 @@
</ul>
</fieldset>

+<!-- Search -->
{% if mod|hasPermission(config.mod.search) %}
- <fieldset>
- <legend>{% trans 'Search' %}</legend>
- 
- <ul>
+<fieldset class="mod-dash mod-dash-set mod-dash-search">
+ <legend>{% trans 'Search' %}</legend>
+ 
+ <ul>
+ <li>
+ {% include 'mod/search_form.html' %}
+ </li>
+ </ul>
+</fieldset>
+{% endif %}
+
+<!-- Boards -->
+<fieldset class="mod-dash mod-dash-set mod-dash-boards">
+ <legend>{% trans 'Boards' %}</legend>
+ 
+ <ul>
+ {% for board in boards %}
+ {% if board.uri in mod.boards or mod.boards[0] == '*' %}
<li>
- {% include 'mod/search_form.html' %}
+ <a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
+  - 
+ {{ board.title|e }}
+ {% if board.subtitle %}
+ <small>&mdash; 
+ {% if config.allow_subtitle_html %}
+ {{ board.subtitle }}
+ {% else %}
+ {{ board.subtitle|e }}
+ {% endif %}
+ </small>
+
+ {% endif %}
+ {% if mod.type == "20" %}
+ <a href="?/settings/{{ board.uri }}"><small>[{% trans 'settings' %}]</small></a>
+ {% endif %}
+ {% if mod|hasPermission(config.mod.manageboards) %}
+  <a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a>
+ {% endif %}
</li>
- </ul>
- </fieldset>
-{% endif %}
+ {% endif %}
+ {% endfor %}
+ 
+ {% if mod|hasPermission(config.mod.newboard) %}
+ <li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li>
+ {% endif %}
+ </ul>
+</fieldset>

+<!-- Misc -->
{% 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>
+<fieldset class="mod-dash mod-dash-set mod-dash-misc">
+ <legend>{% trans 'Other' %}</legend>
+
+ <ul>
+ {% for label,link in config.mod.dashboard_links %}
+ <li><a href="{{ link }}">{{ label }}</a></li>
+ {% endfor %}
+ </ul>
+</fieldset>
{% endif %}

+<!-- Debug Information -->
{% if config.debug %}
- <fieldset>
- <legend>{% trans 'Debug' %}</legend>
- <ul>
- <li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
- <li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
- {% if mod|hasPermission(config.mod.debug_sql) %}
- <li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
- {% endif %}
- </ul>
- </fieldset>
+<fieldset class="mod-dash mod-dash-set mod-dash-debug">
+ <legend>{% trans 'Debug' %}</legend>
+ <ul>
+ <li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
+ <li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
+ {% if mod|hasPermission(config.mod.debug_sql) %}
+ <li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
+ {% endif %}
+ </ul>
+</fieldset>
{% endif %}

+<!-- Update -->
{% 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>
+<fieldset class="mod-dash mod-dash-set mod-dash-update">
+ <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>
+<!-- Account Actions -->
+<fieldset class="mod-dash mod-dash-set mod-dash-account">
<legend>{% trans 'User account' %}</legend>

<ul>
diff --git a/templates/page.html b/templates/page.html
index b136566..a3916b6 100644
--- a/templates/page.html
+++ b/templates/page.html
@@ -6,9 +6,10 @@
active_page = "page";
</script>
{% include 'header.html' %}
+ {% if mod %}{% include 'mod/header.html' %}{% endif %}
<title>{{ title }}</title>
</head>
-<body>
+<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} stylesheet-{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{% 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>
diff --git a/templates/themes/basic/index.html b/templates/themes/basic/index.html
index 3376a68..0ec18f9 100644
--- a/templates/themes/basic/index.html
+++ b/templates/themes/basic/index.html
@@ -11,7 +11,7 @@
{% 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" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
</head>
-<body>
+<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ boardlist.top }}
<header>
<h1>{{ settings.title }}</h1>
diff --git a/templates/thread.html b/templates/thread.html
index af2a6e0..a3ace9b 100644
--- a/templates/thread.html
+++ b/templates/thread.html
@@ -10,7 +10,7 @@
{% 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>
+<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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="board_image" src="{{ config.url_banner }}?board={{ board.uri }}" {% 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 %}

View File

@ -18,7 +18,7 @@
$config['db']['user'] = 'root';
$config['db']['password'] = '';
$config['timezone'] = 'UTC';
$config['cache']['enabled'] = 'apc';
$config['cache']['enabled'] = false;
$config['cookies']['mod'] = 'mod';

View File

@ -2266,6 +2266,7 @@ function mod_reports($global = false) {
if ($mod['type'] == '20' and $global)
error($config['error']['noaccess']);
// Get REPORTS.
$query = prepare("SELECT * FROM ``reports`` " . ($mod["type"] == "20" ? "WHERE board = :board" : "") . " ORDER BY `time` DESC LIMIT :limit");
if ($mod['type'] == '20')
$query->bindValue(':board', $mod['boards'][0]);
@ -2276,79 +2277,153 @@ function mod_reports($global = false) {
$query->bindValue(':limit', $config['mod']['recent_reports'], PDO::PARAM_INT);
$query->execute() or error(db_error($query));
$reports = $query->fetchAll(PDO::FETCH_ASSOC);
$report_queries = array();
foreach ($reports as $report) {
if (!isset($report_queries[$report['board']]))
$report_queries[$report['board']] = array();
$report_queries[$report['board']][] = $report['post'];
}
// Cut off here if we don't have any reports.
$reportCount = 0;
$reportHTML = '';
if( count( $reports ) > 0 ) {
$report_posts = array();
foreach ($report_queries as $board => $posts) {
$report_posts[$board] = array();
// Build queries to fetch content.
$report_queries = array();
foreach ($reports as $report) {
if (!isset($report_queries[$report['board']]))
$report_queries[$report['board']] = array();
$report_queries[$report['board']][] = $report['post'];
}
$query = query(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error());
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
$report_posts[$board][$post['id']] = $post;
// Get reported CONTENT.
$report_posts = array();
foreach ($report_queries as $board => $posts) {
$report_posts[$board] = array();
$query = query(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error());
while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
$report_posts[$board][$post['id']] = $post;
}
}
// Develop an associative array of posts to reports.
$report_index = array();
foreach( $reports as &$report ) {
// Delete reports which are for removed content.
if( !isset( $report_posts[ $report['board'] ][ $report['post'] ] ) ) {
// Invalid report (post has since been deleted)
$query = prepare("DELETE FROM ``reports`` WHERE `post` = :id AND `board` = :board");
$query->bindValue(':id', $report['post'], PDO::PARAM_INT);
$query->bindValue(':board', $report['board']);
$query->execute() or error(db_error($query));
continue;
}
// Build a unique ID.
$content_key = "{$report['board']}.{$report['post']}";
// Create a dummy array if it doesn't already exist.
if( !isset( $report_index[ $content_key ] ) ) {
$report_index[ $content_key ] = array(
"board_id" => $report['board'],
"post_id" => $report['post'],
"content" => &$report_posts[ $report['board'] ][ $report['post'] ],
"reports" => array(),
);
}
// Add the report to the list of reports.
$report_index[ $content_key ]['reports'][ $report['id'] ] = &$report;
// Increment the total report count.
++$reportCount;
}
// Only continue if we have something to do.
// If there are no valid reports left, we're done.
if( $reportCount > 0 ) {
// Sort this report index by number of reports, desc.
usort( $report_index, function( $a, $b ) {
$ra = $a['reports'];
$rb = $b['reports'];
if( $ra < $rb ) {
return 1;
}
else if( $rb > $ra ) {
return -1;
}
else {
return 0;
}
} );
// Loop through the custom index.
foreach( $report_index as &$report_item ) {
$content = $report_item['content'];
// Load board content.
openBoard($report_item['board_id']);
// Load the reported content.
if( !$content['thread'] ) {
// Still need to fix this:
$po = new Thread($content, '?/', $mod, false);
}
else {
$po = new Post($content, '?/', $mod);
}
// Add each report's template to this container.
$report_html = "";
$content_reports = 0;
foreach( $report_item['reports'] as $report ) {
$report_html .= Element('mod/report.html', array(
'report' => $report,
'config' => $config,
'mod' => $mod,
'token' => make_secure_link_token('reports/' . $report['id'] . '/dismiss'),
'token_all' => make_secure_link_token('reports/' . $report['id'] . '/dismissall')
));
++$content_reports;
}
// Build the ">>>/b/ thread reported 3 times" title.
$report_title = sprintf(
_('<a href="%s" title="View content" target="_new">&gt;&gt;&gt;/%s/</a> %s reported %d time(s).'),
"?/{$report_item['board_id']}/res/" . ( $content['thread'] ?: $content['id'] ) . ".html#{$content['thread']}",
$report_item['board_id'],
_( $content['thread'] ? "reply" : "thread" ),
$content_reports
);
$content_html = Element('mod/report_content.html', array(
'reports_html' => $report_html,
'report_count' => $content_reports,
'content_html' => $po->build(true),
'content_board' => $report_item['board_id'],
'content' => $content,
'config' => $config,
'mod' => $mod,
'report_title' => $report_title,
));
$reportHTML .= $content_html;
}
}
}
$count = 0;
$body = '';
foreach ($reports as $report) {
if (!isset($report_posts[$report['board']][$report['post']])) {
// // Invalid report (post has since been deleted)
$query = prepare("DELETE FROM ``reports`` WHERE `post` = :id AND `board` = :board");
$query->bindValue(':id', $report['post'], PDO::PARAM_INT);
$query->bindValue(':board', $report['board']);
$query->execute() or error(db_error($query));
continue;
}
$pageArgs = array(
'count' => $reportCount,
'reports' => $reportHTML,
'global' => $global,
);
openBoard($report['board']);
$post = &$report_posts[$report['board']][$report['post']];
if (!$post['thread']) {
// Still need to fix this:
$po = new Thread($post, '?/', $mod, false);
} else {
$po = new Post($post, '?/', $mod);
}
// a little messy and inefficient
$append_html = Element('mod/report.html', array(
'report' => $report,
'config' => $config,
'mod' => $mod,
'token' => make_secure_link_token('reports/' . $report['id'] . '/dismiss'),
'token_all' => make_secure_link_token('reports/' . $report['id'] . '/dismissall')
));
// Bug fix for https://github.com/savetheinternet/Tinyboard/issues/21
$po->body = truncate($po->body, $po->link(), $config['body_truncate'] - substr_count($append_html, '<br>'));
if (mb_strlen($po->body) + mb_strlen($append_html) > $config['body_truncate_char']) {
// still too long; temporarily increase limit in the config
$__old_body_truncate_char = $config['body_truncate_char'];
$config['body_truncate_char'] = mb_strlen($po->body) + mb_strlen($append_html);
}
$po->body .= $append_html;
$body .= $po->build(true) . '<hr>';
if (isset($__old_body_truncate_char))
$config['body_truncate_char'] = $__old_body_truncate_char;
$count++;
}
mod_page(sprintf('%s (%d)', _('Report queue'), $count), 'mod/reports.html', array('reports' => $body, 'count' => $count));
mod_page( sprintf('%s (%d)', _( ( $global ? 'Global report queue' : 'Report queue' ) ), $reportCount), 'mod/reports.html', $pageArgs );
}
function mod_report_dismiss($id, $all = false) {
@ -2361,7 +2436,8 @@ function mod_report_dismiss($id, $all = false) {
$ip = $report['ip'];
$board = $report['board'];
$post = $report['post'];
} else
}
else
error($config['error']['404']);
if (!$all && !hasPermission($config['mod']['report_dismiss'], $board))

View File

@ -579,7 +579,8 @@ if ($step == 0) {
</p>';
echo Element('page.html', $page);
} elseif ($step == 1) {
}
elseif ($step == 1) {
$page['title'] = 'Pre-installation test';
$can_exec = true;
@ -761,7 +762,8 @@ if ($step == 0) {
'title' => 'Checking environment',
'config' => $config
));
} elseif ($step == 2) {
}
elseif ($step == 2) {
// Basic config
$page['title'] = 'Configuration';
@ -775,7 +777,8 @@ if ($step == 0) {
'title' => 'Configuration',
'config' => $config
));
} elseif ($step == 3) {
}
elseif ($step == 3) {
$instance_config =
'<?php
@ -814,7 +817,8 @@ if ($step == 0) {
if (@file_put_contents('inc/instance-config.php', $instance_config)) {
header('Location: ?step=4', true, $config['redirect_http']);
} else {
}
else {
$page['title'] = 'Manual installation required';
$page['body'] = '
<p>I couldn\'t write to <strong>inc/instance-config.php</strong> with the new configuration, probably due to a permissions error.</p>
@ -826,7 +830,8 @@ if ($step == 0) {
';
echo Element('page.html', $page);
}
} elseif ($step == 4) {
}
elseif ($step == 4) {
// SQL installation
buildJavascript();
@ -846,11 +851,15 @@ if ($step == 0) {
$sql_errors = '';
foreach ($queries as $query) {
if ($mysql_version < 50503)
if ($mysql_version < 50503) {
$query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query);
}
$query = preg_replace('/^([\w\s]*)`([0-9a-zA-Z$_\x{0080}-\x{FFFF}]+)`/u', '$1``$2``', $query);
if (!query($query))
if (!query($query)) {
$sql_errors .= '<li>' . db_error() . '</li>';
}
}
$page['title'] = 'Installation complete';
@ -858,7 +867,8 @@ if ($step == 0) {
if (!empty($sql_errors)) {
$page['body'] .= '<div class="ban"><h2>SQL errors</h2><p>SQL errors were encountered when trying to install the database. This may be the result of using a database which is already occupied with a vichan installation; if so, you can probably ignore this.</p><p>The errors encountered were:</p><ul>' . $sql_errors . '</ul><p><a href="?step=5">Ignore errors and complete installation.</a></p></div>';
} else {
}
else {
$boards = listBoards();
foreach ($boards as &$_board) {
setupBoard($_board);
@ -866,13 +876,11 @@ if ($step == 0) {
}
file_write($config['has_installed'], VERSION);
/*if (!file_unlink(__FILE__)) {
$page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>';
}*/
}
echo Element('page.html', $page);
} elseif ($step == 5) {
}
elseif ($step == 5) {
$page['title'] = 'Installation complete';
$page['body'] = '<p style="text-align:center">Thank you for using vichan. Please remember to report any bugs you discover.</p>';

View File

@ -658,7 +658,7 @@ pre {
margin-left: -20px;
}
div.thread:hover {
.theme-catalog div.thread:hover {
background: #D6DAF0;
border-color: #B7C5D9;
}

View File

@ -223,7 +223,7 @@
</style>
</head>
<body>
<body class="8chan index">
<div id="main">

View File

@ -6,7 +6,7 @@
<title>{{ board.url }} - {{ board.name }}</title>
{% endblock %}
</head>
<body>
<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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 %}

View File

@ -14,7 +14,7 @@
{% include 'header.html' %}
<title>{{ board.url }} - {{ board.title|e }}</title>
</head>
<body>
<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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 %}

View File

@ -73,11 +73,6 @@ 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) {
@ -92,36 +87,78 @@ function changeStyle(styleName, link) {
{% endif %}
{% raw %}
if (!document.getElementById('stylesheet')) {
var s = document.createElement('link');
s.rel = 'stylesheet';
s.type = 'text/css';
s.id = 'stylesheet';
// Find the <dom> for the stylesheet. May be nothing.
var domStylesheet = document.getElementById('stylesheet');
// Determine if this stylesheet is the default.
var setToDefault = ( styles[styleName] == "" || styles[styleName] == "/stylesheets/" );
// Turn "Yotsuba B" to "yotsuba_b"
var attributeName = styleName.replace(/[^a-z0-9_\-]/gi, '_').toLowerCase();
if( !domStylesheet && !setToDefault ) {
domStylesheet = document.createElement('link');
domStylesheet.rel = 'stylesheet';
domStylesheet.type = 'text/css';
domStylesheet.id = 'stylesheet';
var x = document.getElementsByTagName('head')[0];
x.appendChild(s);
x.appendChild(domStylesheet);
}
{% endraw %}
var root = "{{ config.root }}";
{% raw %}
root = root.replace(/\/$/, "");
if( !setToDefault ) {
{% endraw %}
var root = "{{ config.root }}";
{% raw %}
root = root.replace(/\/$/, "");
document.getElementById('stylesheet').href = root + styles[styleName];
selectedstyle = styleName;
domStylesheet.href = root + 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 (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';
}
}
if (link) {
link.className = 'selected';
else if( domStylesheet ) {
domStylesheet.parentNode.removeChild( domStylesheet );
}
if (typeof $ != 'undefined')
// Fix the classes on the body tag.
var body = document.getElementsByTagName('body')[0];
if( body ) {
var bodyClasses = document.getElementsByTagName('body')[0].getAttribute('class').split(" ");
var bodyClassesNew = [];
for( i = 0; i < bodyClasses.length; ++i ) {
var bodyClass = bodyClasses[ i ];
// null class from a double-space.
if( bodyClass == "" ) {
continue;
}
if( bodyClass.indexOf( "stylesheet-" ) == 0 ) {
continue;
}
bodyClassesNew.push( bodyClass );
}
// Add stylesheet-yotsuba_b at the end.
bodyClassesNew.push( "stylesheet-" + attributeName );
body.setAttribute( 'class', bodyClassesNew.join(" ") );
body.setAttribute( 'data-stylesheet', attributeName );
}
if (typeof $ != 'undefined') {
$(window).trigger('stylesheet', styleName);
}
}
@ -167,7 +204,7 @@ function init_stylechooser() {
}
}
}
{% endraw%}
{% endraw %}
{% else %}
{% raw %}
if (localStorage.stylesheet) {
@ -185,10 +222,13 @@ function init_stylechooser() {
function get_cookie(cookie_name) {
var results = document.cookie.match ( '(^|;) ?' + cookie_name + '=([^;]*)(;|$)');
if (results)
if (results) {
return (unescape(results[2]));
else
}
else {
return null;
}
}
function highlightReply(id) {

View File

@ -1,40 +1,5 @@
<fieldset>
<legend>{% trans 'Boards' %}</legend>
<ul>
{% for board in boards %}
{% if board.uri in mod.boards or mod.boards[0] == '*' %}
<li>
<a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
-
{{ board.title|e }}
{% if board.subtitle %}
<small>&mdash;
{% if config.allow_subtitle_html %}
{{ board.subtitle }}
{% else %}
{{ board.subtitle|e }}
{% endif %}
</small>
{% endif %}
{% if mod.type == "20" %}
<a href="?/settings/{{ board.uri }}"><small>[{% trans 'settings' %}]</small></a>
{% endif %}
{% if mod|hasPermission(config.mod.manageboards) %}
<a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a>
{% endif %}
</li>
{% endif %}
{% endfor %}
{% if mod|hasPermission(config.mod.newboard) %}
<li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li>
{% endif %}
</ul>
</fieldset>
<fieldset>
<!-- Messages -->
<fieldset class="mod-dash mod-dash-set mod-dash-messages">
<legend>{% trans 'Messages' %}</legend>
<ul>
{% if mod|hasPermission(config.mod.noticeboard) %}
@ -78,7 +43,8 @@
</ul>
</fieldset>
<fieldset>
<!-- Administration -->
<fieldset class="mod-dash mod-dash-set mod-dash-messages">
<legend>{% trans 'Administration' %}</legend>
<ul>
@ -123,57 +89,99 @@
</ul>
</fieldset>
<!-- Search -->
{% if mod|hasPermission(config.mod.search) %}
<fieldset>
<legend>{% trans 'Search' %}</legend>
<fieldset class="mod-dash mod-dash-set mod-dash-search">
<legend>{% trans 'Search' %}</legend>
<ul>
<li>
{% include 'mod/search_form.html' %}
</li>
</ul>
</fieldset>
<ul>
<li>
{% include 'mod/search_form.html' %}
</li>
</ul>
</fieldset>
{% endif %}
{% if config.mod.dashboard_links|count %}
<fieldset>
<legend>{% trans 'Other' %}</legend>
<!-- Boards -->
<fieldset class="mod-dash mod-dash-set mod-dash-boards">
<legend>{% trans 'Boards' %}</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>
<ul>
<li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
<li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
{% if mod|hasPermission(config.mod.debug_sql) %}
<li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
{% endif %}
</ul>
</fieldset>
{% endif %}
{% if newer_release %}
<fieldset>
<legend>Update</legend>
<ul>
<ul>
{% for board in boards %}
{% if board.uri in mod.boards or mod.boards[0] == '*' %}
<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.
<a href="?/{{ config.board_path|sprintf(board.uri) }}{{ config.file_index }}">{{ config.board_abbreviation|sprintf(board.uri) }}</a>
-
{{ board.title|e }}
{% if board.subtitle %}
<small>&mdash;
{% if config.allow_subtitle_html %}
{{ board.subtitle }}
{% else %}
{{ board.subtitle|e }}
{% endif %}
</small>
{% endif %}
{% if mod.type == "20" %}
<a href="?/settings/{{ board.uri }}"><small>[{% trans 'settings' %}]</small></a>
{% endif %}
{% if mod|hasPermission(config.mod.manageboards) %}
<a href="?/edit/{{ board.uri }}"><small>[{% trans 'edit' %}]</small></a>
{% endif %}
</li>
</ul>
</fieldset>
{% endif %}
{% endfor %}
{% if mod|hasPermission(config.mod.newboard) %}
<li style="margin-top:15px"><a href="?/new-board"><strong>{% trans 'Create new board' %}</strong></a></li>
{% endif %}
</ul>
</fieldset>
<!-- Misc -->
{% if config.mod.dashboard_links|count %}
<fieldset class="mod-dash mod-dash-set mod-dash-misc">
<legend>{% trans 'Other' %}</legend>
<ul>
{% for label,link in config.mod.dashboard_links %}
<li><a href="{{ link }}">{{ label }}</a></li>
{% endfor %}
</ul>
</fieldset>
{% endif %}
<fieldset>
<!-- Debug Information -->
{% if config.debug %}
<fieldset class="mod-dash mod-dash-set mod-dash-debug">
<legend>{% trans 'Debug' %}</legend>
<ul>
<li><a href="?/debug/antispam">{% trans 'Anti-spam' %}</a></li>
<li><a href="?/debug/recent">{% trans 'Recent posts' %}</a></li>
{% if mod|hasPermission(config.mod.debug_sql) %}
<li><a href="?/debug/sql">{% trans 'SQL' %}</a></li>
{% endif %}
</ul>
</fieldset>
{% endif %}
<!-- Update -->
{% if newer_release %}
<fieldset class="mod-dash mod-dash-set mod-dash-update">
<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 %}
<!-- Account Actions -->
<fieldset class="mod-dash mod-dash-set mod-dash-account">
<legend>{% trans 'User account' %}</legend>
<ul>

View File

@ -1,26 +1,26 @@
<div class="report">
<hr>
{% trans 'Board' %}: <a href="?/{{ report.board }}/{{ config.file_index }}">{{ config.board_abbreviation|sprintf(report.board) }}</a>
<br>
{% trans 'Reason' %}: {{ report.reason }}
<br>
{% trans 'Report date' %}: {{ report.time|date(config.post_date) }}
<br>
{% if mod|hasPermission(config.mod.show_ip, report.board) %}
{% trans 'Reported by' %}: <a href="?/IP/{{ report.ip }}">{{ report.ip }}</a>
<li class="report-item">
<div class="report">
{% trans 'Board' %}: <a href="?/{{ report.board }}/{{ config.file_index }}">{{ config.board_abbreviation|sprintf(report.board) }}</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="{% trans 'Discard abuse report' %}" href="?/reports/{{ report.id }}/dismiss/{{ token }}">Dismiss</a>
{% trans 'Reason' %}: {{ report.reason }}
<br>
{% trans 'Report date' %}: {{ report.time|date(config.post_date) }}
<br>
{% if mod|hasPermission(config.mod.show_ip, report.board) %}
{% trans 'Reported by' %}: <a href="?/IP/{{ report.ip }}">{{ report.ip }}</a>
<br>
{% endif %}
{% if mod|hasPermission(config.mod.report_dismiss_ip, report.board) %}
{% 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="{% trans 'Discard abuse report' %}" href="?/reports/{{ report.id }}/dismiss/{{ token }}">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="{% trans 'Discard all abuse reports by this IP address' %}" href="?/reports/{{ report.id }}/dismissall/{{ token_all }}">Dismiss+</a>
{% endif %}
<a title="{% trans 'Discard all abuse reports by this IP address' %}" href="?/reports/{{ report.id }}/dismissall/{{ token_all }}">Dismiss+</a>
{% endif %}
{% endif %}
</div>
</div>
</li>

View File

@ -1,5 +1,7 @@
{% if reports %}
{{ reports }}
<ul class="mod-reports reports-global">
{{ reports }}
</ul>
{% else %}
<p style="text-align:center" class="unimportant">({% trans 'There are no reports.' %})</p>
{% endif %}

View File

@ -6,9 +6,10 @@
active_page = "page";
</script>
{% include 'header.html' %}
{% if mod %}{% include 'mod/header.html' %}{% endif %}
<title>{{ title }}</title>
</head>
<body>
<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %} stylesheet-{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{% 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>

View File

@ -1,7 +1,7 @@
{% filter remove_whitespace %}
{# tabs and new lines will be ignored #}
<div id="thread_{{ post.id }}" data-board="{{ board.uri }}">
<div class="thread" id="thread_{{ post.id }}" data-board="{{ board.uri }}">
{% if not index %}<a id="{{ post.id }}" class="post_anchor"></a>{% endif %}
{% include 'post/fileinfo.html' %}

View File

@ -11,7 +11,7 @@
{% 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" href="{{ config.root }}{{ config.font_awesome_css }}">{% endif %}
</head>
<body>
<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ boardlist.top }}
<header>
<h1>{{ settings.title }}</h1>

View File

@ -10,7 +10,7 @@
{% 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>
<body class="8chan {% if mod %}is-moderator{% else %}is-not-moderator{% endif %}" data-stylesheet="{% if config.default_stylesheet.1 != '' and not mod %}{{ config.default_stylesheet.1 }}{% else %}default{% endif %}">
{{ 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="board_image" src="{{ config.url_banner }}?board={{ board.uri }}" {% 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 %}