Первая версия, написанная гопотой. Не работает нормально лента и поиск, сломана авторизация
This commit is contained in:
43
app/templates/add.html
Normal file
43
app/templates/add.html
Normal file
@@ -0,0 +1,43 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Добавить пост{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Добавить пост</h2>
|
||||
<form method="post" id="addform">
|
||||
<div><input name="title" placeholder="Заголовок (необязательно)" style="width:100%"></div>
|
||||
<div><textarea name="body" rows="10" style="width:100%" placeholder="Текст"></textarea></div>
|
||||
<div>
|
||||
<input id="tagsinput" name="tags" placeholder="Теги через запятую" style="width:100%" />
|
||||
<div id="suggestions" class="suggestions"></div>
|
||||
</div>
|
||||
<div><button type="submit">Опубликовать</button></div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
(async function(){
|
||||
const input = document.getElementById("tagsinput");
|
||||
const sugg = document.getElementById("suggestions");
|
||||
let last = "";
|
||||
input.addEventListener("input", async (e) => {
|
||||
const val = input.value.split(",").pop().trim();
|
||||
if (!val || val === last) { sugg.innerHTML=""; return; }
|
||||
last = val;
|
||||
try {
|
||||
const res = await fetch('/_tags?q=' + encodeURIComponent(val));
|
||||
const arr = await res.json();
|
||||
sugg.innerHTML = arr.slice(0,10).map(t => `<button class="tag-sugg" type="button" data-tag="${t}">#${t}</button>`).join(" ");
|
||||
document.querySelectorAll(".tag-sugg").forEach(b => {
|
||||
b.addEventListener("click",(ev)=>{
|
||||
const tag = ev.currentTarget.dataset.tag;
|
||||
const parts = input.value.split(",");
|
||||
parts[parts.length-1] = " " + tag;
|
||||
input.value = parts.map(p=>p.trim()).filter(Boolean).join(", ") + ", ";
|
||||
input.focus();
|
||||
sugg.innerHTML = "";
|
||||
});
|
||||
});
|
||||
} catch(e) { console.warn(e); }
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
60
app/templates/base.html
Normal file
60
app/templates/base.html
Normal file
@@ -0,0 +1,60 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{% block title %}Text-Booru{% endblock %}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
||||
</head>
|
||||
<body>
|
||||
<header class="header">
|
||||
<div class="container">
|
||||
<h1 class="logo"><a href="{{ url_for('index') }}">text.booru</a></h1>
|
||||
<nav class="nav">
|
||||
<a href="{{ url_for('index') }}">Лента</a>
|
||||
<a href="{{ url_for('add_route') }}">Добавить</a>
|
||||
<a href="{{ url_for('mod_index') }}">Модерация</a>
|
||||
<a href="{{ url_for('api_export_zip') }}">Экспорт</a>
|
||||
</nav>
|
||||
<form class="search" action="{{ url_for('search') }}" method="get">
|
||||
<input name="q" placeholder="Поиск..." value="{{ request.args.get('q','') }}">
|
||||
<button>🔎</button>
|
||||
</form>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main class="container">
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<aside class="sidebar">
|
||||
<section>
|
||||
<h3>Теги</h3>
|
||||
<ul class="taglist">
|
||||
{% for t in all_tags %}
|
||||
<li><a href="{{ url_for('tag_page', name=t.name) }}">#{{ t.name }}</a> <span class="count">({{ t.cnt }})</span></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
<section>
|
||||
<h3>Страницы</h3>
|
||||
<ul>
|
||||
{% if page and pages %}
|
||||
<li>Страница {{ page }} / {{ pages }}</li>
|
||||
{% for p in range(1, pages+1) %}
|
||||
<li><a href="{{ url_for('index') }}?page={{ p }}">{{ p }}</a></li>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</section>
|
||||
</aside>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<small>Прототип — хранение коротких текстов, tags, search, moderation</small>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
32
app/templates/index.html
Normal file
32
app/templates/index.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Лента — Text-Booru{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if current_tag %}
|
||||
<h2>Тег: #{{ current_tag }}</h2>
|
||||
{% else %}
|
||||
<h2>Последние посты</h2>
|
||||
{% endif %}
|
||||
|
||||
{% for p in posts %}
|
||||
<article class="card">
|
||||
<h3><a href="{{ url_for('view_post', pid=p.id) }}">{{ p.title or ("#" ~ p.id) }}</a></h3>
|
||||
<div class="excerpt">{{ markdown(p.body[:400])|safe }}</div>
|
||||
<div class="meta">#{{ p.id }} • {{ p.created_at }} •
|
||||
{% for t in get_tags(p.id) %}<a href="{{ url_for('tag_page', name=t) }}">#{{ t }}</a> {% endfor %}
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
|
||||
<div class="pagination">
|
||||
{% if page and pages %}
|
||||
{% if page > 1 %}
|
||||
<a href="{{ url_for('index') }}?page={{ page-1 }}">« Prev</a>
|
||||
{% endif %}
|
||||
<span>Page {{ page }} / {{ pages }}</span>
|
||||
{% if page < pages %}
|
||||
<a href="{{ url_for('index') }}?page={{ page+1 }}">Next »</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
31
app/templates/mod.html
Normal file
31
app/templates/mod.html
Normal file
@@ -0,0 +1,31 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Модерация{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Модерация — флаги</h2>
|
||||
{% if flags %}
|
||||
<table class="flags">
|
||||
<thead><tr><th>ID</th><th>Post</th><th>Reason</th><th>Created</th><th>Resolved</th><th>Action</th></tr></thead>
|
||||
<tbody>
|
||||
{% for f in flags %}
|
||||
<tr>
|
||||
<td>{{ f.id }}</td>
|
||||
<td><a href="{{ url_for('view_post', pid=f.post_id) }}">{{ f.title or ('#'+f.post_id|string) }}</a></td>
|
||||
<td>{{ f.reason }}</td>
|
||||
<td>{{ f.created_at }}</td>
|
||||
<td>{{ 'yes' if f.resolved else 'no' }}</td>
|
||||
<td>
|
||||
{% if not f.resolved %}
|
||||
<form action="{{ url_for('mod_resolve', fid=f.id) }}" method="post">
|
||||
<button type="submit">Resolve</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<p>Нет флагов.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
29
app/templates/post.html
Normal file
29
app/templates/post.html
Normal file
@@ -0,0 +1,29 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ post.title or ("Пост #" ~ post.id) }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<article class="post-full">
|
||||
<h2>{{ post.title or ("Пост #" ~ post.id) }}</h2>
|
||||
<div class="meta">{{ post.created_at }} • #{{ post.id }}</div>
|
||||
<div class="body">{{ markdown(post.body)|safe }}</div>
|
||||
|
||||
<div class="post-actions">
|
||||
<form action="{{ url_for('vote', pid=post.id) }}" method="post" style="display:inline;">
|
||||
<input type="hidden" name="vote" value="up">
|
||||
<button type="submit">▲ {{ votes.ups }}</button>
|
||||
</form>
|
||||
<form action="{{ url_for('vote', pid=post.id) }}" method="post" style="display:inline;">
|
||||
<input type="hidden" name="vote" value="down">
|
||||
<button type="submit">▼ {{ votes.downs }}</button>
|
||||
</form>
|
||||
<span class="score">Score: {{ votes.score }}</span>
|
||||
|
||||
<form action="{{ url_for('flag_post', pid=post.id) }}" method="post" class="flag-form" style="display:inline;">
|
||||
<input type="text" name="reason" placeholder="Пожаловаться..." />
|
||||
<button type="submit">Flag ({{ flags }})</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<p><a href="{{ url_for('index') }}">← Назад в ленту</a></p>
|
||||
</article>
|
||||
{% endblock %}
|
||||
23
app/templates/search.html
Normal file
23
app/templates/search.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Поиск — Text-Booru{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Поиск</h2>
|
||||
<form action="{{ url_for('search') }}" method="get">
|
||||
<input name="q" placeholder="Поиск..." value="{{ q }}">
|
||||
<button>Искать</button>
|
||||
</form>
|
||||
|
||||
{% if q %}
|
||||
<h3>Результаты для «{{ q }}»</h3>
|
||||
{% if posts %}
|
||||
<ul>
|
||||
{% for p in posts %}
|
||||
<li><a href="{{ url_for('view_post', pid=p.id) }}">{{ p.title or p.body[:80] }}</a> — {{ p.created_at }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p>Ничего не найдено.</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user