Migrate to Bulma
Bulma is simple and free full-CSS framework. Unlike Bootstrap, it fits within a single small CSS file. It is also well integrated in Django. https://bulma.io/
This commit is contained in:
parent
2e7c42f61f
commit
b0b8f30580
50 changed files with 439 additions and 21641 deletions
6
Pipfile
6
Pipfile
|
@ -1,18 +1,14 @@
|
|||
[[source]]
|
||||
|
||||
url = "https://pypi.python.org/simple"
|
||||
verify_ssl = true
|
||||
name = "pypi"
|
||||
|
||||
|
||||
[packages]
|
||||
|
||||
django = "*"
|
||||
python-decouple = "*"
|
||||
markdown = "*"
|
||||
django-npb = "*"
|
||||
|
||||
django-bulma = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
gunicorn = "*"
|
||||
|
|
|
@ -49,6 +49,7 @@ You can set the following variables in the `.env` file:
|
|||
* `KHAGANAT_EMAIL_PORT`: Port to use for the SMTP server, default is `25`.
|
||||
* `KHAGANAT_EMAIL_HOST_USER`: Username to use for the SMTP server, default is empty (no authentication).
|
||||
* `KHAGANAT_EMAIL_HOST_PASSWORD`: Password to use for the SMTP server, default is empty.
|
||||
* `KHAGANAT_EMAIL_USE_STARTTLS`: Whether to use STARTTLS to connect to the SMTP server, default is `False`.
|
||||
* `KHAGANAT_EMAIL_USE_TLS`: Whether to use a TLS connection to the SMTP server, default is `False`.
|
||||
* `KHAGANAT_EMAIL_SUBJECT_PREFIX`: Subject-line prefix for email, default is empty.
|
||||
* `KHAGANAT_DEFAULT_FROM_EMAIL`: Default email address to use, default is `no-reply@localhost`.
|
||||
|
|
|
@ -47,6 +47,7 @@ INSTALLED_APPS = [
|
|||
'navbar.apps.NavbarConfig',
|
||||
'logs.apps.LogsConfig',
|
||||
'npb.apps.NpbConfig',
|
||||
'bulma',
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -99,7 +100,8 @@ EMAIL_HOST = config('KHAGANAT_EMAIL_HOST', default='localhost')
|
|||
EMAIL_PORT = config('KHAGANAT_EMAIL_PORT', default=25, cast=int)
|
||||
EMAIL_HOST_USER = config('KHAGANAT_EMAIL_HOST_USER', default='')
|
||||
EMAIL_HOST_PASSWORD = config('KHAGANAT_EMAIL_HOST_PASSWORD', default='')
|
||||
EMAIL_USE_TLS = config('KHAGANAT_EMAIL_USE_TLS', default=False, cast=bool)
|
||||
EMAIL_USE_TLS = config('KHAGANAT_EMAIL_USE_STARTTLS', default=False, cast=bool)
|
||||
EMAIL_USE_SSL = config('KHAGANAT_EMAIL_USE_TLS', default=False, cast=bool)
|
||||
|
||||
EMAIL_SUBJECT_PREFIX = config('KHAGANAT_EMAIL_SUBJECT_PREFIX', default='')
|
||||
DEFAULT_FROM_EMAIL = config(
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,343 +0,0 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v4.0.0-beta.3 (https://getbootstrap.com)
|
||||
* Copyright 2011-2017 The Bootstrap Authors
|
||||
* Copyright 2011-2017 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-ms-overflow-style: scrollbar;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
@-ms-viewport {
|
||||
width: device-width;
|
||||
}
|
||||
|
||||
article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-size: 1rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #212529;
|
||||
text-align: left;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
abbr[title],
|
||||
abbr[data-original-title] {
|
||||
text-decoration: underline;
|
||||
-webkit-text-decoration: underline dotted;
|
||||
text-decoration: underline dotted;
|
||||
cursor: help;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
address {
|
||||
margin-bottom: 1rem;
|
||||
font-style: normal;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
ol,
|
||||
ul,
|
||||
dl {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
ol ol,
|
||||
ul ul,
|
||||
ol ul,
|
||||
ul ol {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: .5rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
sub,
|
||||
sup {
|
||||
position: relative;
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -.25em;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]) {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:not([href]):not([tabindex]):focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
pre,
|
||||
code,
|
||||
kbd,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
overflow: auto;
|
||||
-ms-overflow-style: scrollbar;
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0 0 1rem;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
a,
|
||||
area,
|
||||
button,
|
||||
[role="button"],
|
||||
input:not([type="range"]),
|
||||
label,
|
||||
select,
|
||||
summary,
|
||||
textarea {
|
||||
-ms-touch-action: manipulation;
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
caption {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
color: #868e96;
|
||||
text-align: left;
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
margin-bottom: .5rem;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: 1px dotted;
|
||||
outline: 5px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
select,
|
||||
optgroup,
|
||||
textarea {
|
||||
margin: 0;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
button,
|
||||
html [type="button"],
|
||||
[type="reset"],
|
||||
[type="submit"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner,
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="date"],
|
||||
input[type="time"],
|
||||
input[type="datetime-local"],
|
||||
input[type="month"] {
|
||||
-webkit-appearance: listbox;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: auto;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
fieldset {
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
legend {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
margin-bottom: .5rem;
|
||||
font-size: 1.5rem;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
outline-offset: -2px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
::-webkit-file-upload-button {
|
||||
font: inherit;
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
|
||||
output {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: list-item;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
/*# sourceMappingURL=bootstrap-reboot.css.map */
|
File diff suppressed because one or more lines are too long
|
@ -1,8 +0,0 @@
|
|||
/*!
|
||||
* Bootstrap Reboot v4.0.0-beta.3 (https://getbootstrap.com)
|
||||
* Copyright 2011-2017 The Bootstrap Authors
|
||||
* Copyright 2011-2017 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
|
||||
*/*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}[role=button],a,area,button,input:not([type=range]),label,select,summary,textarea{-ms-touch-action:manipulation;touch-action:manipulation}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#868e96;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}
|
||||
/*# sourceMappingURL=bootstrap-reboot.min.css.map */
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Before Width: | Height: | Size: 162 KiB |
4
khaganat/static/khaganat/jquery-3.2.1.min.js
vendored
4
khaganat/static/khaganat/jquery-3.2.1.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,3 +0,0 @@
|
|||
$(function () {
|
||||
$('[data-toggle="tooltip"]').tooltip()
|
||||
})
|
|
@ -1,49 +1,46 @@
|
|||
{% load static %}{% load i18n %}{% load navbar %}{% load get_page %}{% get_current_language as LANGUAGE_CODE %}<!doctype html>
|
||||
<html lang="{{ LANGUAGE_CODE }}">
|
||||
<head>
|
||||
<!-- Begin bootstrap headers -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
<link rel="stylesheet" href="{% static "khaganat/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" %}" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" />
|
||||
<!-- End bootstrap headers -->
|
||||
|
||||
<!-- Begin global headers -->
|
||||
<link rel="shortcut icon" href="{% static "khaganat/images/favicon.ico" %}" />
|
||||
<link rel="stylesheet" href="{% static "khaganat/css/khaganat.css" %}" />
|
||||
<!-- End global headers -->
|
||||
|
||||
<!-- Begin custom headers -->
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="{% static 'bulma/css/font-awesome.min.css' %}">
|
||||
<link rel="stylesheet" href="{% static 'bulma/css/style.css' %}">
|
||||
<link rel="shortcut icon" href="{% static "khaganat/images/favicon.ico" %}">
|
||||
<!-- <link rel="stylesheet" href="{% static "khaganat/css/khaganat.css" %}" /> -->
|
||||
<script defer src="{% static "khaganat/js/khaganat.js" %}"></script>
|
||||
{% block headers %}{% endblock %}
|
||||
<!-- End custom headers -->
|
||||
|
||||
<title>Khaganat - {% block title %}{% endblock %}</title>
|
||||
</head>
|
||||
<body>
|
||||
{% navbar %}
|
||||
<div class="container" id="main-content">
|
||||
<section class="section">
|
||||
{% if messages %}
|
||||
<div id="messages">
|
||||
<div class="container">
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}danger{% elif message.level == DEFAULT_MESSAGE_LEVELS.WARNING %}warning{% elif message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %}success{% elif message.level == DEFAULT_MESSAGE_LEVELS.INFO %}info{% else %}secondary{% endif %}" role="alert">
|
||||
{% if 'safe' in message.tags %}
|
||||
{{ message|safe }}
|
||||
{% else %}
|
||||
{{ message }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<article class="message{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %} is-danger{% elif message.level == DEFAULT_MESSAGE_LEVELS.WARNING %} is-warning{% elif message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %} is-success{% elif message.level == DEFAULT_MESSAGE_LEVELS.INFO %} is-info{% endif %}">
|
||||
<div class="message-body">
|
||||
{% if 'safe' in message.tags %}
|
||||
{{ message|safe }}
|
||||
{% else %}
|
||||
{{ message }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% block content %}{% endblock %}
|
||||
<footer id="page-footer" class="content-bloc">
|
||||
<div class="container">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</section>
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
{% get_page 'legal' as legal_page %}
|
||||
{% if legal_page %}
|
||||
<a href="{% url 'page' 'legal' %}">{{ legal_page.title }}</a>
|
||||
{% endif %}
|
||||
</footer>
|
||||
</div>
|
||||
<script src="{% static "khaganat/jquery-3.2.1.min.js" %}"></script>
|
||||
<script src="{% static "khaganat/bootstrap/4.0.0-beta.3/js/bootstrap.bundle.min.js" %}"></script>
|
||||
<script src="{% static "khaganat/js/khaganat.js" %}"></script>
|
||||
<ul>
|
||||
<li><a href="https://khaganat.net/wikhan/fr:licence">Licences</a></li>
|
||||
{% if legal_page %}<li><a href="{% url 'page' 'legal' %}">{{ legal_page.title }}</a></li>{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
|
20
khaganat/templates/khaganat/centered_dialog.html
Normal file
20
khaganat/templates/khaganat/centered_dialog.html
Normal file
|
@ -0,0 +1,20 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block content %}
|
||||
<div class="columns">
|
||||
<div class="column"></div>
|
||||
<div class="column {% block dialog_size %}{% endblock %}">
|
||||
<article class="message {% block dialog_class %}{% endblock %}">
|
||||
<div class="message-header">
|
||||
<p>{% block title %}{% endblock %}</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
{% block dialog %}{% endblock %}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<div class="column"></div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1 +0,0 @@
|
|||
{% extends "khaganat/base.html" %}
|
35
khaganat/templates/npb/paste_detail.html
Normal file
35
khaganat/templates/npb/paste_detail.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block headers %}
|
||||
<link rel="stylesheet" href="{% static css_file_name %}">
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}{% trans "Untitled" as untitled %}{{ paste.title|default:untitled }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if paste.is_suspended %}
|
||||
{% else %}
|
||||
{% trans "Untitled" as untitled %}
|
||||
<a class="button is-danger is-pulled-right" href="{% url 'npb:report_paste' paste.uuid %}">{% trans 'report this paste'|capfirst %}</a>
|
||||
|
||||
<h1 class="title is-3">{{ paste.title|default:untitled }}</h1>
|
||||
<p class="subtitle is-5">
|
||||
{% trans "anonymous" as anonymous %}
|
||||
{% blocktrans with author=paste.author|default:anonymous date=paste.created_on %}By {{ author }} on {{ date }}{% endblocktrans %}
|
||||
|
||||
{% if paste.edited %}
|
||||
<br />
|
||||
{% blocktrans with date=paste.edited_on %}Edited on {{ date }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% if paste.expire_on %}
|
||||
<br />
|
||||
{% blocktrans with date=paste.expire_on %}Expires on {{ date }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
{{ paste.formated_content|safe }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
15
khaganat/templates/npb/paste_form.html
Normal file
15
khaganat/templates/npb/paste_form.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans 'New paste' %}{% endblock %}
|
||||
{% block dialog_class %}is-link{% endblock %}
|
||||
{% block dialog_size %}is-two-thirds{% endblock %}
|
||||
|
||||
{% block dialog %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form|bulma }}
|
||||
<button type="submit" class="button is-link">{% trans "Submit" %}</button>
|
||||
</form>
|
||||
{% endblock %}
|
15
khaganat/templates/npb/report_form.html
Normal file
15
khaganat/templates/npb/report_form.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans 'Report paste' %}{% endblock %}
|
||||
{% block dialog_class %}is-warning{% endblock %}
|
||||
{% block dialog_size %}is-two-thirds{% endblock %}
|
||||
|
||||
{% block dialog %}
|
||||
<form action="" method="post">
|
||||
{% csrf_token %}
|
||||
{{ form|bulma }}
|
||||
<button type="submit" class="button is-warning">{% trans "Submit" %}</button>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -9,6 +9,6 @@ class SearchForm(forms.Form):
|
|||
date = forms.DateField(
|
||||
label=_('date'),
|
||||
initial=datetime.date.today(),
|
||||
widget=DateInput(format='%d-%m-%Y'),
|
||||
input_formats=['%d-%m-%Y'],
|
||||
widget=DateInput(format='%Y-%m-%d'),
|
||||
input_formats=['%Y-%m-%d'],
|
||||
)
|
||||
|
|
|
@ -1,24 +1,77 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ source_channel.name }}{% endblock %}
|
||||
{% block title %}{% trans "logs_title" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<h2>{{ source_channel.name }} ({{ date }})</h2>
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{% url 'log_index' %}" role="button">{% trans "logs_back" %}</a>
|
||||
</div>
|
||||
<div>
|
||||
{% for entry in entries%}
|
||||
{% if request.user.is_staff %}
|
||||
<a href="{% url 'log_switch_entry' entry.pk %}?next={{ request.path_info }}">{% if entry.hidden %}<span class="text-warning">⚠</span>{% else %}<span class="text-success">✓</span>{% endif %}</a>
|
||||
{% endif %}
|
||||
{{ entry.created|date:"H:i:s" }} {% if entry.nick %}<span class="log-nick"><{{ entry.nick }}></span> <span class="log-content">{{ entry.content }}</span>{% else %}<span class="log-action">* {{ entry.content }}</span>{% endif %}<br />
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{% url 'log_index' %}" role="button">{% trans "logs_back" %}</a>
|
||||
<div class="columns">
|
||||
<div class="column is-one-quarter">
|
||||
<nav class="panel">
|
||||
<p class="panel-heading">{% trans "logs_title" %}</p>
|
||||
{% for source in sources %}
|
||||
{% with date=source.first_date %}
|
||||
<a class="panel-block{% if source.source__id == current_source.id %} is-active has-text-weight-semibold{% endif %}" href="{% url 'log_day' source=source.source__slug year=date.year month=date.month day=date.day %}">{{ source.source__name }}</a>
|
||||
{% endwith %}
|
||||
{% empty %}
|
||||
<a class="panel-block">{% trans "logs_no_logs_available" %}</a>
|
||||
{% endfor %}
|
||||
{% if current_source and request.user.is_staff %}
|
||||
<div class="panel-block">
|
||||
<form method="post" action="{% url 'log_search' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="{{ form.source.name }}" value="{{ current_source.slug }}" />
|
||||
<div class="field has-addons">
|
||||
<p class="control">
|
||||
<input class="input" type="date" name="{{ form.date.name }}" value="{{ form.date.value|date:"Y-m-d" }}" id="{{ form.date.id }}" required pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}">
|
||||
</p>
|
||||
<p class="control">
|
||||
<button type="submit" class="button is-link">{% trans 'go'|capfirst %}</button>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="panel-block">
|
||||
{% if current_source.hidden %}
|
||||
{% blocktrans with name=current_source.name %}{{ name }} is hidden.{% endblocktrans %}
|
||||
<a href="{% url 'log_switch_source' current_source.id %}?next={% url 'log_day' source=current_source.slug year=current_date.year month=current_date.month day=current_date.day %}" class="button is-warning">{% trans 'show'|capfirst %}</a>
|
||||
{% else %}
|
||||
{% blocktrans with name=current_source.name %}{{ name }} is published.{% endblocktrans %}
|
||||
<a href="{% url 'log_switch_source' current_source.id %}?next={% url 'log_day' source=current_source.slug year=current_date.year month=current_date.month day=current_date.day %}" class="button is-warning">{% trans 'hide'|capfirst %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
<div class="column">
|
||||
{% if dates %}
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
{% for date in dates %}
|
||||
<li class="{% if date == current_date %}is-active{% endif %}"><a href="{% url 'log_day' source=current_source.slug year=date.year month=date.month day=date.day %}">{{ date }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if entries %}
|
||||
<table class="table is-narrow is-striped">
|
||||
<tbody>
|
||||
{% for entry in entries %}
|
||||
<tr>
|
||||
{% if request.user.is_staff %}
|
||||
<td>
|
||||
<a href="{% url 'log_switch_entry' entry.pk %}?next={{ request.path_info }}">{% if entry.hidden %}<span class="has-text-danger">⚠</span>{% else %}<span class="has-text-success">✓</span>{% endif %}</a>
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>{{ entry.created|date:"H:i:s" }}</td>
|
||||
<td class="has-text-right">{% if entry.nick %}{{ entry.nick }}{% else %}*{% endif %}</td>
|
||||
<td>{{ entry.content }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "logs_title" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<h2>{% trans "logs_title" %}</h2>
|
||||
{% if sources %}
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<div class="list-group" id="list-tab" role="tablist">
|
||||
{% for source in sources %}
|
||||
<a class="list-group-item list-group-item-action" id="list-{{ source.source }}-list" data-toggle="list" href="#list-{{ source.source }}" role="tab" aria-controls="home">{{ source.source__name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{% for source in sources %}
|
||||
<div class="tab-pane fade show" id="list-{{ source.source }}" role="tabpanel" aria-labelledby="list-{{ source.source }}-list">
|
||||
<div class="list-group">
|
||||
{% for date in source.stats %}
|
||||
<a href="{% url 'log_day' source=source.source__slug year=date.date.year month=date.date.month day=date.date.day %}" class="list-group-item list-group-item-action">{{ date.date }}</a>
|
||||
{% endfor %}
|
||||
{% if request.user.is_staff %}
|
||||
<div class="list-group-item list-group-item-action">
|
||||
<form method="post" action="{% url 'log_search' %}">
|
||||
{% csrf_token %}
|
||||
{{ form.date }}
|
||||
<input type="hidden" name="{{ form.source.name }}" value="{{ source.source__slug }}" />
|
||||
<input type="submit" value="{% trans 'go'|capfirst %}" class="btn btn-secondary" />
|
||||
</form>
|
||||
|
||||
{% if source.source__hidden %}
|
||||
{% blocktrans with name=source.source__name %}{{ name }} is hidden.{% endblocktrans %}
|
||||
<a href="{% url 'log_switch_source' source.source__id %}" class="btn btn-warning">{% trans 'show'|capfirst %}</a>
|
||||
{% else %}
|
||||
{% blocktrans with name=source.source__name %}{{ name }} is published.{% endblocktrans %}
|
||||
<a href="{% url 'log_switch_source' source.source__id %}" class="btn btn-warning">{% trans 'hide'|capfirst %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p>{% trans "logs_no_logs_available" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -3,7 +3,7 @@ from . import views
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.IndexView.as_view(), name='log_index'),
|
||||
path('', views.EntriesView.as_view(), name='log_index'),
|
||||
path(
|
||||
'<slug:source>/<int:year>/<int:month>/<int:day>/',
|
||||
views.EntriesView.as_view(),
|
||||
|
|
139
logs/views.py
139
logs/views.py
|
@ -9,6 +9,7 @@ from django.http import Http404
|
|||
from neluser import nsfw
|
||||
from .models import Source, Entry
|
||||
from .forms import SearchForm
|
||||
from utils import is_link_legit
|
||||
import datetime
|
||||
|
||||
|
||||
|
@ -28,8 +29,8 @@ def _switch_hidden(request, obj, pk):
|
|||
e.hidden = not e.hidden
|
||||
e.save()
|
||||
|
||||
next_page = request.GET.get('next', '')
|
||||
if next_page == '':
|
||||
next_page = request.GET.get('next', '/')
|
||||
if not is_link_legit(next_page):
|
||||
next_page = reverse('log_index')
|
||||
return redirect(next_page)
|
||||
|
||||
|
@ -45,9 +46,14 @@ def switch_entry(request, pk):
|
|||
|
||||
|
||||
def search_view(request):
|
||||
print('Debug: 1')
|
||||
if request.method == 'POST':
|
||||
print('Debug: 2')
|
||||
form = SearchForm(request.POST)
|
||||
print('Debug: form is_valid: %s' % form.is_valid())
|
||||
print('Debug: form: %s' % form)
|
||||
if form.is_valid():
|
||||
print('Debug: 3')
|
||||
date = form.cleaned_data['date']
|
||||
return redirect(reverse('log_day', kwargs={
|
||||
'source': form.cleaned_data['source'],
|
||||
|
@ -58,50 +64,9 @@ def search_view(request):
|
|||
raise Http404('No search parameters.')
|
||||
|
||||
|
||||
class IndexView(generic.ListView):
|
||||
template_name = 'logs/index.html'
|
||||
context_object_name = 'sources'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = SearchForm()
|
||||
return context
|
||||
|
||||
def get_queryset(self):
|
||||
now, start_date, end_date = _get_dates()
|
||||
out = []
|
||||
qs = Entry.objects.all()
|
||||
|
||||
if not self.request.user.is_staff:
|
||||
qs = qs.filter(
|
||||
hidden=False,
|
||||
source__hidden=False,
|
||||
created__range=(start_date, end_date)
|
||||
)
|
||||
qs = qs.values(
|
||||
'source', 'source__name', 'source__slug',
|
||||
'source__id', 'source__hidden'
|
||||
).annotate(
|
||||
nb=Count('id')
|
||||
)
|
||||
|
||||
for src in qs:
|
||||
src['stats'] = Entry.objects.filter(
|
||||
hidden=False,
|
||||
source=src['source'],
|
||||
created__range=(start_date, end_date)
|
||||
).annotate(
|
||||
date=TruncDate('created')
|
||||
).values('date').annotate(nb=Count('date')).order_by('-date')
|
||||
out.append(src)
|
||||
|
||||
return out
|
||||
|
||||
|
||||
class EntriesView(generic.ListView):
|
||||
context_object_name = 'entries'
|
||||
template_name = 'logs/entries.html'
|
||||
allow_empty = False
|
||||
context_object_name = 'entries'
|
||||
|
||||
def is_nsfw(self):
|
||||
for e in self.get_queryset():
|
||||
|
@ -118,27 +83,87 @@ class EntriesView(generic.ListView):
|
|||
nsfw.alert(request)
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['date'] = datetime.date(
|
||||
def get_date(self):
|
||||
"""Return the date object corresponding to the URL parameters
|
||||
or None if missing.
|
||||
"""
|
||||
has_date = all([
|
||||
self.kwargs.get('year') is not None,
|
||||
self.kwargs.get('month') is not None,
|
||||
self.kwargs.get('day') is not None,
|
||||
])
|
||||
if not has_date:
|
||||
return None
|
||||
return datetime.date(
|
||||
self.kwargs['year'],
|
||||
self.kwargs['month'],
|
||||
self.kwargs['day']
|
||||
)
|
||||
context['source_channel'] = Source.objects.get(
|
||||
slug=self.kwargs['source']
|
||||
|
||||
def get_dates(self, source):
|
||||
"""Return a list if available dates for the current source."""
|
||||
_, start_date, end_date = _get_dates()
|
||||
if source is None:
|
||||
return []
|
||||
lst = Entry.objects.filter(
|
||||
hidden=False,
|
||||
source=source,
|
||||
created__range=(start_date, end_date)
|
||||
).annotate(
|
||||
date=TruncDate('created')
|
||||
).values('date').annotate(
|
||||
nb=Count('date')
|
||||
).order_by('-date')
|
||||
return [o['date'] for o in lst]
|
||||
|
||||
def get_source(self):
|
||||
"""Return the current source."""
|
||||
if self.kwargs.get('source') is None:
|
||||
return None
|
||||
return Source.objects.get(slug=self.kwargs['source'])
|
||||
|
||||
def get_sources(self):
|
||||
"""Return available sources."""
|
||||
now, start_date, end_date = _get_dates()
|
||||
qs = Entry.objects.all()
|
||||
|
||||
if not self.request.user.is_staff:
|
||||
qs = qs.filter(
|
||||
hidden=False,
|
||||
source__hidden=False,
|
||||
created__range=(start_date, end_date)
|
||||
)
|
||||
qs = qs.values(
|
||||
'source', 'source__name', 'source__slug',
|
||||
'source__id', 'source__hidden'
|
||||
).annotate(
|
||||
nb=Count('id')
|
||||
)
|
||||
if isinstance(context['source_channel'], tuple):
|
||||
context['source_channel'] = context['source_channel'][0]
|
||||
|
||||
out = []
|
||||
for src in qs:
|
||||
dts = self.get_dates(src['source'])
|
||||
src['first_date'] = dts[0] if dts else None
|
||||
out.append(src)
|
||||
|
||||
return out
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context['form'] = SearchForm()
|
||||
context['sources'] = self.get_sources()
|
||||
context['current_source'] = self.get_source()
|
||||
context['dates'] = self.get_dates(context['current_source'])
|
||||
context['current_date'] = self.get_date()
|
||||
return context
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return the entries to be displayed."""
|
||||
dt = self.get_date()
|
||||
if dt is None:
|
||||
return []
|
||||
|
||||
is_staff = self.request.user.is_staff
|
||||
dt = datetime.date(
|
||||
self.kwargs['year'],
|
||||
self.kwargs['month'],
|
||||
self.kwargs['day']
|
||||
)
|
||||
now = datetime.date.today()
|
||||
out_of_bounds = any((
|
||||
(now - dt).days > settings.KHAGANAT_LOGS_MAX_DAYS,
|
||||
|
@ -146,7 +171,7 @@ class EntriesView(generic.ListView):
|
|||
))
|
||||
if out_of_bounds and not is_staff:
|
||||
return Entry.objects.none()
|
||||
src = Source.objects.get(slug=self.kwargs['source'])
|
||||
src = self.get_source()
|
||||
if src is None:
|
||||
return Entry.objects.none()
|
||||
if src.hidden and not is_staff:
|
||||
|
|
|
@ -1,71 +1,64 @@
|
|||
{% load static %}
|
||||
{% load i18n %}
|
||||
|
||||
<nav class="navbar navbar-expand-lg navbar-light" id="mainNav">
|
||||
<a class="navbar-brand" href="{% url 'index' %}">
|
||||
<img src="{% static "khaganat/images/icon_khaganat.png" %}" alt="Khaganat">
|
||||
</a>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav">
|
||||
{% for e in elems %}
|
||||
{% if e.localized_link %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{ e.localized_link }}"{% if e.new_window %} target="_blank"{% endif %}>{{ e }}</a>
|
||||
</li>
|
||||
{% elif e.children %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ e.description.short_name }}
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
||||
{% for c in e.children %}
|
||||
{% if c.is_separator %}
|
||||
<hr />
|
||||
{% else %}
|
||||
<a class="dropdown-item" href="{% if c.add_locale %}/{{ current_lang_code }}{% endif %}{{ c.localized_link }}"{% if c.new_window %} target="_blank"{% endif %}{% if c.description.full_name or c.description.description %} data-toggle="tooltip" data-placement="right" data-html="true" title="{% if c.description.full_name %}<b>{{ c.description.full_name }}</b>{% endif %}{% if c.description.full_name and c.description.description %}<hr />{% endif %}{{ c.description.description }}"{% endif %}>
|
||||
<img src="{% static c.icon_path %}" alt="" /> {{ c }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link disabled" href="#">{{ e }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{% trans "my_account"|capfirst %}</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
<!--
|
||||
<a class="dropdown-item" href="{% url "settings" %}">{% trans "settings"|capfirst %}</a>
|
||||
-->
|
||||
{% if user.is_superuser %}
|
||||
<a class="dropdown-item" href="{% url "admin:index" %}">{% trans "administration"|capfirst %}</a>
|
||||
{% endif %}
|
||||
<a class="dropdown-item" href="{% url "logout" %}">{% trans "logout"|capfirst %}</a>
|
||||
</div>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a class="btn btn-primary" href="{% url "login" %}?next={{ current_url }}" role="button">{% trans "login"|capfirst %}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="btn btn-secondary" href="{% url "register" %}" role="button">{% trans "register"|capfirst %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-item nav-link dropdown-toggle mr-md-2" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ current_lang_name|capfirst }}</a>
|
||||
<div class="dropdown-menu dropdown-menu-right">
|
||||
{% for lang_code, lang_name, lang_url in all_langs %}
|
||||
<a class="dropdown-item{% if lang_code == current_lang_code %} active{% endif %}" href="{{ lang_url }}">{{ lang_name|capfirst }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<nav class="navbar is-light">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="{% url 'index' %}"><img src="{% static "khaganat/images/icon_khaganat.png" %}" alt="Khaganat"></a>
|
||||
</div>
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
{% for e in elems %}
|
||||
{% if e.localized_link %}
|
||||
<a class="navbar-item" href="{{ e.localized_link }}"{% if e.new_window %} target="_blank"{% endif %}>{{ e }}</a>
|
||||
{% elif e.children %}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link">{{ e.description.short_name }}</a>
|
||||
<div class="navbar-dropdown">
|
||||
{% for c in e.children %}
|
||||
{% if c.is_separator %}<hr class="navbar-divider">{% else %}
|
||||
<a class="navbar-item" href="{% if c.add_locale %}/{{ current_lang_code }}{% endif %}{{ c.localized_link }}"{% if c.new_window %} target="_blank"{% endif %}{% if c.description.description %} title="{{ c.description.description }}"{% endif %}>
|
||||
<span>
|
||||
<span><img src="{% static c.icon_path %}" alt="" /></span>
|
||||
<span>{{ c }}</span>
|
||||
</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<span class="navbar-item">{{ e }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
{% if user.is_authenticated %}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link">{% trans "my_account"|capfirst %}</a>
|
||||
<div class="navbar-dropdown">
|
||||
{% if user.is_superuser %}
|
||||
<a class="navbar-item" href="{% url "admin:index" %}">{% trans "administration"|capfirst %}</a>
|
||||
{% endif %}
|
||||
<a class="navbar-item" href="{% url "logout" %}">{% trans "logout"|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="navbar-item">
|
||||
<div>
|
||||
<a class="button is-link" href="{% url "login" %}?next={{ current_url }}">{% trans "login"|capfirst %}</a>
|
||||
<a class="button is-white" href="{% url "register" %}">{% trans "register"|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="navbar-link">{{ current_lang_name|capfirst }}</a>
|
||||
<div class="navbar-dropdown">
|
||||
{% for lang_code, lang_name, lang_url in all_langs %}
|
||||
<a class="navbar-item{% if lang_code == current_lang_code %} is-active{% endif %}" href="{{ lang_url }}">{{ lang_name|capfirst }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -1,20 +1,12 @@
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.http import HttpResponseRedirect, QueryDict
|
||||
from django.template.loader import render_to_string
|
||||
from django.urls.exceptions import Resolver404
|
||||
from django.shortcuts import render
|
||||
from django.contrib import messages
|
||||
from neluser.models import NelUser
|
||||
from django.urls import reverse, resolve
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
def is_link_legit(url):
|
||||
try:
|
||||
resolve(url)
|
||||
except Resolver404:
|
||||
return False
|
||||
return True
|
||||
from django.urls import reverse
|
||||
from utils import is_link_legit
|
||||
|
||||
|
||||
def is_nsfw_allowed(request):
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "register" %}{% endblock %}
|
||||
{% block title %}{% trans "register"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-success{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<div class="alert alert-success" role="alert">
|
||||
<p>{% trans 'account_activated' %}</p>
|
||||
<a class="btn btn-secondary" href="{% url "login" %}" role="button">{% trans "login"|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<p>{% trans 'account_activated'|capfirst %}</p>
|
||||
<a class="button is-success" href="{% url "login" %}" role="button">{% trans "login"|capfirst %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "login" %}{% endblock %}
|
||||
{% block title %}{% trans "login"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-link{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<form method="post" action="{% url 'login' %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="hidden" name="next" value="{{ request.GET.next }}" />
|
||||
<button type="submit" class="btn btn-success">{% trans "login"|capfirst %}</button>
|
||||
<a class="btn btn-primary" href="{% url "register" %}" role="button">{% trans "register"|capfirst %}</a>
|
||||
<a class="btn btn-secondary" href="{% url "password_reset" %}" role="button">{% trans "forgotten_password"|capfirst %}</a>
|
||||
</form>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<form method="post" action="{% url 'login' %}">
|
||||
{% csrf_token %}
|
||||
{{ form|bulma }}
|
||||
<input type="hidden" name="next" value="{{ request.GET.next }}" />
|
||||
<button type="submit" class="button is-link">{% trans "login"|capfirst %}</button>
|
||||
<a class="button is-light" href="{% url "password_reset" %}" role="button">{% trans "forgotten_password"|capfirst %}</a>
|
||||
<a class="button is-light" href="{% url "register" %}" role="button">{% trans "register"|capfirst %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -4,17 +4,24 @@
|
|||
{% block title %}{% trans "NSFW content" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<h2>{% trans "NSFW content" %}</h2>
|
||||
<p>{% trans "The content you were about to see is flagged as sensitive and therefore cannot be seen while the safe mode is activated." %}</p>
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{% url "index" %}" role="button">{% trans "Go back home" %}</a>
|
||||
<a class="btn btn-danger" href="{% url "enable_nsfw" "0" %}?next={{ next_url }}" role="button">{% trans "Permanently disable safe mode" %}</a>
|
||||
<br>
|
||||
{% trans "Or disable safe mode for:" %}
|
||||
<a class="badge badge-warning" href="{% url "enable_nsfw" "300" %}?next={{ next_url }}">{% trans "5 minutes" %}</a>
|
||||
<a class="badge badge-warning" href="{% url "enable_nsfw" "3600" %}?next={{ next_url }}">{% trans "1 hour" %}</a>
|
||||
<a class="badge badge-warning" href="{% url "enable_nsfw" "86400" %}?next={{ next_url }}">{% trans "1 day" %}</a>
|
||||
<article class="message is-warning">
|
||||
<div class="message-header">
|
||||
<p>{% trans "NSFW content" %}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
<p>{% trans "The content you were about to see is flagged as sensitive and therefore cannot be seen while the safe mode is activated." %}</p>
|
||||
<div>
|
||||
<p>
|
||||
<a class="button is-link" href="{% url "index" %}" role="button">{% trans "Go back home" %}</a>
|
||||
<a class="button is-danger" href="{% url "enable_nsfw" "0" %}?next={{ next_url }}" role="button">{% trans "Permanently disable safe mode" %}</a>
|
||||
</p>
|
||||
<p>
|
||||
{% trans "Or disable safe mode for:" %}<br>
|
||||
<a class="button is-warning" href="{% url "enable_nsfw" "300" %}?next={{ next_url }}">{% trans "5 minutes" %}</a>
|
||||
<a class="button is-warning" href="{% url "enable_nsfw" "3600" %}?next={{ next_url }}">{% trans "1 hour" %}</a>
|
||||
<a class="button is-warning" href="{% url "enable_nsfw" "86400" %}?next={{ next_url }}">{% trans "1 day" %}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "password_reset" %}{% endblock %}
|
||||
{% block title %}{% trans "password_reset"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-link{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<form method="post" action="{% url 'password_reset' %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="btn btn-success">{% trans "reset_my_password" %}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<form method="post" action="{% url 'password_reset' %}">
|
||||
{% csrf_token %}
|
||||
{{ form|bulma }}
|
||||
<button type="submit" class="button is-link">{% trans "reset_my_password"|capfirst %}</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "password_reset" %}{% endblock %}
|
||||
{% block title %}{% if validlink %}{% trans "set_new_password"|capfirst %}{% else %}{% trans "password_reset"|capfirst %}{% endif %}{% endblock %}
|
||||
{% block dialog_class %}{% if validlink %}is-link{% else %}is-danger{% endif %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
{% if validlink %}
|
||||
<h2>{% trans "set_new_password" %}</h2>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="btn btn-success">{% trans "change_my_password"|capfirst %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="alert alert-danger" role="alert">{% trans "reset_password_invalid_link" %}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% block dialog %}
|
||||
{% if validlink %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="button is-link">{% trans "change_my_password"|capfirst %}</button>
|
||||
</form>
|
||||
{% else %}
|
||||
{% trans "reset_password_invalid_link" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "password_reset" %}{% endblock %}
|
||||
{% block title %}{% trans "password_reset"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-success{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<div class="alert alert-success" role="alert">
|
||||
<p>{% trans "password_reset_success" %}</p>
|
||||
<a class="btn btn-secondary" href="{% url "login" %}" role="button">{% trans "login"|capfirst %}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<p>{% trans "password_reset_success" %}</p>
|
||||
<a class="button is-success" href="{% url "login" %}" role="button">{% trans "login"|capfirst %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "password_reset" %}{% endblock %}
|
||||
{% block title %}{% trans "password_reset"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-link{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<div class="alert alert-success" role="alert">{% trans "password_reset_success_email" %}</div>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
{% trans "password_reset_success_email" %}
|
||||
<a class="button is-link" href="{% url "index" %}" role="button">{% trans "Go back home" %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load bulma_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "register" %}{% endblock %}
|
||||
{% block title %}{% trans "register"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-link{% endblock %}
|
||||
{% block dialog_size %}is-two-thirds{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="content-bloc">
|
||||
<form method="post" action="{% url 'register' %}">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit" class="btn btn-success">{% trans "register"|capfirst %}</button>
|
||||
</form>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<form method="post" action="{% url 'register' %}">
|
||||
{% csrf_token %}
|
||||
{{ form|bulma }}
|
||||
<button type="submit" class="button is-link">{% trans "register"|capfirst %}</button>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
{% extends "khaganat/base.html" %}
|
||||
{% extends "khaganat/centered_dialog.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "register" %}{% endblock %}
|
||||
{% block title %}{% trans "almost_there"|capfirst %}{% endblock %}
|
||||
{% block dialog_class %}is-success{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="alert alert-success" role="alert">
|
||||
<h4 class="alert-heading">{% trans 'almost_there' %}</h4>
|
||||
<p>{% trans 'activate_your_account' %}</p>
|
||||
<a class="btn btn-secondary" href="{% url "index" %}" role="button">{% trans "take_me_home"|capfirst %}</a>
|
||||
</div>
|
||||
{% block dialog %}
|
||||
<p>{% trans 'activate_your_account' %}</p>
|
||||
<a class="button is-success" href="{% url "index" %}" role="button">{% trans "take_me_home"|capfirst %}</a>
|
||||
{% endblock %}
|
||||
|
|
|
@ -3,5 +3,7 @@
|
|||
{% block title %}{{ page.title }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ page.formated_content|safe }}
|
||||
<div class="content">
|
||||
{{ page.formated_content|safe }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
10
utils.py
Normal file
10
utils.py
Normal file
|
@ -0,0 +1,10 @@
|
|||
from django.urls.exceptions import Resolver404
|
||||
from django.urls import resolve
|
||||
|
||||
|
||||
def is_link_legit(url):
|
||||
try:
|
||||
resolve(url)
|
||||
except Resolver404:
|
||||
return False
|
||||
return True
|
Loading…
Reference in a new issue