##// END OF EJS Templates
Updated the Snow White theme. Scroll to the new post after posting to thread.
neko259 -
r41:68192446 default
parent child Browse files
Show More
@@ -1,163 +1,174 b''
1 * {
1 * {
2 font-size: inherit;
2 font-size: inherit;
3 margin: 0;
3 margin: 0;
4 padding: 0;
4 padding: 0;
5 }
5 }
6 html {
6 html {
7 background: #fff;
7 background: #fff;
8 color: #000;
8 color: #000;
9 font: medium sans-serif;
9 font: medium sans-serif;
10 }
10 }
11 a {
11 a {
12 color: inherit;
12 color: inherit;
13 text-decoration: underline;
13 text-decoration: underline;
14 }
14 }
15
15
16 #admin_panel {
16 #admin_panel {
17 background: #182F6F;
17 background: #182F6F;
18 color: #fff;
18 color: #fff;
19 padding: .5ex 1ex .5ex 1ex;
19 padding: .5ex 1ex .5ex 1ex;
20 }
20 }
21
21
22 #navigation_panel {
22 #navigation_panel {
23 background: #182F6F;
23 background: #182F6F;
24 color: #B4CFEC;
24 color: #B4CFEC;
25 margin-bottom: 1em;
25 margin-bottom: 1em;
26 padding: .5ex 1ex 1ex 1ex;
26 padding: .5ex 1ex 1ex 1ex;
27 }
27 }
28 #navigation_panel::after {
28 #navigation_panel::after {
29 clear: both;
29 clear: both;
30 content: ".";
30 content: ".";
31 display: block;
31 display: block;
32 height: 0;
32 height: 0;
33 line-height: 0;
33 line-height: 0;
34 visibility: hidden;
34 visibility: hidden;
35 }
35 }
36
36
37 #navigation_panel a:link, #navigation_panel a:visited, #navigation_panel a:hover {
37 #navigation_panel a:link, #navigation_panel a:visited, #navigation_panel a:hover {
38 text-decoration: none;
38 text-decoration: none;
39 }
39 }
40
40
41 #navigation_panel .link {
41 #navigation_panel .link {
42 border-right: 1px solid #fff;
42 border-right: 1px solid #fff;
43 color: #fff;
43 color: #fff;
44 font-weight: bold;
44 font-weight: bold;
45 margin-right: 1ex;
45 margin-right: 1ex;
46 padding-right: 1ex;
46 padding-right: 1ex;
47 }
47 }
48 #navigation_panel .link:last-child {
48 #navigation_panel .link:last-child {
49 border-left: 1px solid #fff;
49 border-left: 1px solid #fff;
50 border-right: none;
50 border-right: none;
51 float: right;
51 float: right;
52 margin-left: 1ex;
52 margin-left: 1ex;
53 margin-right: 0;
53 margin-right: 0;
54 padding-left: 1ex;
54 padding-left: 1ex;
55 padding-right: 0;
55 padding-right: 0;
56 }
56 }
57
57
58 #navigation_panel .tag {
58 #navigation_panel .tag {
59 color: #fff;
59 color: #fff;
60 }
60 }
61
61
62 .title {
62 .title {
63 color: #182F6F;
63 color: #182F6F;
64 font-weight: bold;
64 font-weight: bold;
65 }
65 }
66
66
67 .post-form-w {
67 .post-form-w {
68 background: #182F6F;
68 background: #182F6F;
69 border-radius: 1ex;
69 border-radius: 1ex;
70 color: #fff;
70 color: #fff;
71 margin: 1em 1ex;
71 margin: 1em 1ex;
72 padding: 1ex;
72 padding: 1ex;
73 }
73 }
74 .post-form {
74 .post-form {
75 display: table;
75 display: table;
76 border-collapse: collapse;
76 border-collapse: collapse;
77 width: 100%;
77 width: 100%;
78
78
79 }
79 }
80 .form-row {
80 .form-row {
81 display: table-row;
81 display: table-row;
82 }
82 }
83 .form-label, .form-input {
83 .form-label, .form-input {
84 display: table-cell;
84 display: table-cell;
85 vertical-align: top;
85 vertical-align: top;
86 }
86 }
87 .form-label {
87 .form-label {
88 padding: .25em 1ex .25em 0;
88 padding: .25em 1ex .25em 0;
89 }
89 }
90 .form-input {
90 .form-input {
91 padding: .25em 0;
91 padding: .25em 0;
92 }
92 }
93 .form-input > * {
93 .form-input > * {
94 background: #fff;
94 background: #fff;
95 color: #000;
95 color: #000;
96 border: none;
96 border: none;
97 padding: 0;
97 padding: 0;
98 resize: vertical;
98 resize: vertical;
99 width: 100%;
99 width: 100%;
100 }
100 }
101 .form-submit {
101 .form-submit {
102 border-bottom: 1px solid #666;
102 border-bottom: 1px solid #666;
103 margin-bottom: .5em;
103 margin-bottom: .5em;
104 padding-bottom: .5em;
104 padding-bottom: .5em;
105 }
105 }
106 .form-title {
106 .form-title {
107 font-weight: bold;
107 font-weight: bold;
108 margin-bottom: .5em;
108 margin-bottom: .5em;
109 }
109 }
110 .post-form .settings_item {
110 .post-form .settings_item {
111 margin: .5em 0;
111 margin: .5em 0;
112 }
112 }
113 .form-submit input {
113 .form-submit input {
114 margin-top: .5em;
114 margin-top: .5em;
115 padding: .2em 1ex;
115 padding: .2em 1ex;
116 }
116 }
117 .form-label {
117 .form-label {
118 text-align: right;
118 text-align: right;
119 }
119 }
120
120
121 .block {
121 .block {
122 display: inline-block;
122 display: inline-block;
123 vertical-align: top;
123 vertical-align: top;
124 }
124 }
125
125
126 .post_id {
126 .post_id {
127 color: #a00;
127 color: #a00;
128 }
128 }
129
129
130 .post {
130 .post {
131 background: #FFF;
131 background: #FFF;
132 border-bottom: 1px solid #182F6F;
132 border-bottom: 1px solid #182F6F;
133 margin: 0 1ex 1em 1ex;
133 margin: 0 1ex 1em 1ex;
134 overflow-x: auto;
134 overflow-x: auto;
135 padding-bottom: 1em;
135 padding-bottom: 1em;
136 }
136 }
137
137
138 .metadata {
138 .metadata {
139 background: #C0E4E8;
139 background: #C0E4E8;
140 border: 1px solid #7F9699;
140 border: 1px solid #7F9699;
141 border-radius: .4ex;
141 border-radius: .4ex;
142 display: table;
142 display: table;
143 margin-top: .5em;
143 margin-top: .5em;
144 padding: .4em;
144 padding: .4em;
145 }
145 }
146
146
147 .post ul, .post ol {
147 .post ul, .post ol {
148 margin: .5em 0 .5em 3ex;
148 margin: .5em 0 .5em 3ex;
149 }
149 }
150 .post li {
150 .post li {
151 margin: .2em 0;
151 margin: .2em 0;
152 }
152 }
153 .post p {
153 .post p {
154 margin: .5em 0;
154 margin: .5em 0;
155 }
155 }
156 .post blockquote {
156 .post blockquote {
157 border-left: 3px solid #182F6F;
157 border-left: 3px solid #182F6F;
158 margin: .5em 0 .5em 3ex;
158 margin: .5em 0 .5em 3ex;
159 padding-left: 1ex;
159 padding-left: 1ex;
160 }
160 }
161 .post blockquote > blockquote {
161 .post blockquote > blockquote {
162 padding-top: .1em;
162 padding-top: .1em;
163 } No newline at end of file
163 }
164
165 .post > .image {
166 float: left;
167 margin-right: 1ex;
168 }
169 .post > .metadata {
170 clear: left;
171 }
172 .post {
173 clear: left;
174 }
@@ -1,164 +1,172 b''
1 from django.core.urlresolvers import reverse
1 from django.template import RequestContext
2 from django.template import RequestContext
2 from boards import forms
3 from boards import forms
3 import boards
4 import boards
4 from boards.forms import ThreadForm, PostForm, SettingsForm
5 from boards.forms import ThreadForm, PostForm, SettingsForm
5 from boards.models import Post, Admin, Tag
6 from boards.models import Post, Admin, Tag
6 from django.shortcuts import render, get_list_or_404, redirect
7 from django.shortcuts import render, get_list_or_404, redirect
7 from django.http import HttpResponseRedirect, Http404
8 from django.http import HttpResponseRedirect, Http404
8 import neboard
9 import neboard
9
10
10
11
11 def index(request):
12 def index(request):
12 context = RequestContext(request)
13 context = RequestContext(request)
13
14
14 if request.method == 'POST':
15 if request.method == 'POST':
15 return new_post(request)
16 return new_post(request)
16 else:
17 else:
17 threads = Post.objects.get_threads()
18 threads = Post.objects.get_threads()
18
19
19 context['threads'] = None if len(threads) == 0 else threads
20 context['threads'] = None if len(threads) == 0 else threads
20 context['form'] = forms.ThreadForm()
21 context['form'] = forms.ThreadForm()
21 context['tags'] = Tag.objects.get_not_empty_tags()
22 context['tags'] = Tag.objects.get_not_empty_tags()
22 context['theme'] = _get_theme(request)
23 context['theme'] = _get_theme(request)
23
24
24 return render(request, 'posting_general.html',
25 return render(request, 'posting_general.html',
25 context)
26 context)
26
27
27
28
28 def new_post(request, thread_id=boards.models.NO_PARENT):
29 def new_post(request, thread_id=boards.models.NO_PARENT):
29 """Add a new post (in thread or as a reply)."""
30 """Add a new post (in thread or as a reply)."""
30
31
31 if thread_id == boards.models.NO_PARENT:
32 if thread_id == boards.models.NO_PARENT:
32 form = ThreadForm(request.POST, request.FILES)
33 form = ThreadForm(request.POST, request.FILES)
33 else:
34 else:
34 form = PostForm(request.POST, request.FILES)
35 form = PostForm(request.POST, request.FILES)
35
36
36 if form.is_valid():
37 if form.is_valid():
37 data = form.cleaned_data
38 data = form.cleaned_data
38 else:
39 else:
39 return redirect(index)
40 return redirect(index)
40
41
41 title = data['title']
42 title = data['title']
42 text = data['text']
43 text = data['text']
43
44
44 if 'image' in data.keys():
45 if 'image' in data.keys():
45 image = data['image']
46 image = data['image']
46 else:
47 else:
47 image = None
48 image = None
48
49
49 ip = request.META['REMOTE_ADDR']
50 ip = request.META['REMOTE_ADDR']
50
51
51 tags = []
52 tags = []
52 if thread_id == boards.models.NO_PARENT:
53
54 new_thread = thread_id == boards.models.NO_PARENT
55 if new_thread:
53 tag_strings = data['tags']
56 tag_strings = data['tags']
54
57
55 if tag_strings:
58 if tag_strings:
56 tag_strings = tag_strings.split(' ')
59 tag_strings = tag_strings.split(' ')
57 for tag_name in tag_strings:
60 for tag_name in tag_strings:
58 tag_name = tag_name.strip()
61 tag_name = tag_name.strip()
59 if len(tag_name) > 0:
62 if len(tag_name) > 0:
60 tag, created = Tag.objects.get_or_create(name=tag_name)
63 tag, created = Tag.objects.get_or_create(name=tag_name)
61 tags.append(tag)
64 tags.append(tag)
62
65
63 # TODO Add a possibility to define a link image instead of an image file.
66 # TODO Add a possibility to define a link image instead of an image file.
64 # If a link is given, download the image automatically.
67 # If a link is given, download the image automatically.
65
68
66 post = Post.objects.create_post(title=title, text=text, ip=ip,
69 post = Post.objects.create_post(title=title, text=text, ip=ip,
67 parent_id=thread_id, image=image,
70 parent_id=thread_id, image=image,
68 tags=tags)
71 tags=tags)
69
72
70 thread_to_show = (post.id if thread_id == boards.models.NO_PARENT else
73 thread_to_show = (post.id if new_thread else thread_id)
71 thread_id)
74
75 if new_thread:
72 return redirect(thread, post_id=thread_to_show)
76 return redirect(thread, post_id=thread_to_show)
77 else:
78 return redirect(reverse(thread,
79 kwargs={'post_id': thread_to_show}) + '#'
80 + str(post.id))
73
81
74
82
75 def tag(request, tag_name):
83 def tag(request, tag_name):
76 """Get all tag threads (posts without a parent)."""
84 """Get all tag threads (posts without a parent)."""
77
85
78 tag = Tag.objects.get(name=tag_name)
86 tag = Tag.objects.get(name=tag_name)
79 threads = Post.objects.get_threads(tag=tag)
87 threads = Post.objects.get_threads(tag=tag)
80
88
81 if request.method == 'POST':
89 if request.method == 'POST':
82 return new_post(request)
90 return new_post(request)
83 else:
91 else:
84 context = RequestContext(request)
92 context = RequestContext(request)
85 context['threads'] = None if len(threads) == 0 else threads
93 context['threads'] = None if len(threads) == 0 else threads
86 context['tag'] = tag_name
94 context['tag'] = tag_name
87 context['tags'] = Tag.objects.get_not_empty_tags()
95 context['tags'] = Tag.objects.get_not_empty_tags()
88 context['theme'] = _get_theme(request)
96 context['theme'] = _get_theme(request)
89
97
90 context['form'] = forms.ThreadForm(initial={'tags': tag_name})
98 context['form'] = forms.ThreadForm(initial={'tags': tag_name})
91
99
92 return render(request, 'posting_general.html',
100 return render(request, 'posting_general.html',
93 context)
101 context)
94
102
95
103
96 def thread(request, post_id):
104 def thread(request, post_id):
97 """Get all thread posts"""
105 """Get all thread posts"""
98
106
99 if request.method == 'POST':
107 if request.method == 'POST':
100 return new_post(request, post_id)
108 return new_post(request, post_id)
101 else:
109 else:
102 # TODO Show 404 if there is no such thread
110 # TODO Show 404 if there is no such thread
103 posts = Post.objects.get_thread(post_id)
111 posts = Post.objects.get_thread(post_id)
104
112
105 context = RequestContext(request)
113 context = RequestContext(request)
106
114
107 context['posts'] = posts
115 context['posts'] = posts
108 context['form'] = forms.PostForm()
116 context['form'] = forms.PostForm()
109 context['tags'] = Tag.objects.get_not_empty_tags()
117 context['tags'] = Tag.objects.get_not_empty_tags()
110 context['theme'] = _get_theme(request)
118 context['theme'] = _get_theme(request)
111
119
112 return render(request, 'thread.html', context)
120 return render(request, 'thread.html', context)
113
121
114
122
115 def login(request):
123 def login(request):
116 """Log in as admin"""
124 """Log in as admin"""
117
125
118 if 'name' in request.POST and 'password' in request.POST:
126 if 'name' in request.POST and 'password' in request.POST:
119 request.session['admin'] = False
127 request.session['admin'] = False
120
128
121 isAdmin = len(Admin.objects.filter(name=request.POST['name'],
129 isAdmin = len(Admin.objects.filter(name=request.POST['name'],
122 password=request.POST[
130 password=request.POST[
123 'password'])) > 0
131 'password'])) > 0
124
132
125 if isAdmin:
133 if isAdmin:
126 request.session['admin'] = True
134 request.session['admin'] = True
127
135
128 response = HttpResponseRedirect('/')
136 response = HttpResponseRedirect('/')
129
137
130 else:
138 else:
131 response = render(request, 'login.html', {'error': 'Login error'})
139 response = render(request, 'login.html', {'error': 'Login error'})
132 else:
140 else:
133 response = render(request, 'login.html', {})
141 response = render(request, 'login.html', {})
134
142
135 return response
143 return response
136
144
137
145
138 def logout(request):
146 def logout(request):
139 request.session['admin'] = False
147 request.session['admin'] = False
140 return HttpResponseRedirect('/')
148 return HttpResponseRedirect('/')
141
149
142
150
143 def settings(request):
151 def settings(request):
144 context = RequestContext(request)
152 context = RequestContext(request)
145
153
146 if request.method == 'POST':
154 if request.method == 'POST':
147 form = SettingsForm(request.POST)
155 form = SettingsForm(request.POST)
148 if form.is_valid():
156 if form.is_valid():
149 selected_theme = form.cleaned_data['theme']
157 selected_theme = form.cleaned_data['theme']
150 request.session['theme'] = selected_theme
158 request.session['theme'] = selected_theme
151
159
152 return redirect(settings)
160 return redirect(settings)
153 else:
161 else:
154 selected_theme = _get_theme(request)
162 selected_theme = _get_theme(request)
155 form = SettingsForm(initial={'theme': selected_theme})
163 form = SettingsForm(initial={'theme': selected_theme})
156 context['form'] = form
164 context['form'] = form
157 context['tags'] = Tag.objects.get_not_empty_tags()
165 context['tags'] = Tag.objects.get_not_empty_tags()
158 context['theme'] = _get_theme(request)
166 context['theme'] = _get_theme(request)
159
167
160 return render(request, 'settings.html', context)
168 return render(request, 'settings.html', context)
161
169
162
170
163 def _get_theme(request):
171 def _get_theme(request):
164 return request.session.get('theme', neboard.settings.DEFAULT_THEME) No newline at end of file
172 return request.session.get('theme', neboard.settings.DEFAULT_THEME)
@@ -1,76 +1,76 b''
1 {% extends "base.html" %}
1 {% extends "base.html" %}
2
2
3 {% load i18n %}
3 {% load i18n %}
4 {% load markup %}
4 {% load markup %}
5
5
6 {% block head %}
6 {% block head %}
7 <title>Neboard</title>
7 <title>Neboard</title>
8 {% endblock %}
8 {% endblock %}
9
9
10 {% block content %}
10 {% block content %}
11
11
12 {% if posts %}
12 {% if posts %}
13 {% for post in posts %}
13 {% for post in posts %}
14 <a name="{{ post.id }}"></a>
14 <a name="{{ post.id }}"></a>
15 <div class="post">
15 <div class="post">
16 {% if post.image %}
16 {% if post.image %}
17 <div class="block">
17 <div class="image">
18 <a href="{{ post.image.url }}"><img
18 <a href="{{ post.image.url }}"><img
19 src="{{ post.image.url_200x150 }}" />
19 src="{{ post.image.url_200x150 }}" />
20 </a>
20 </a>
21 </div>
21 </div>
22 {% endif %}
22 {% endif %}
23 <div class="block">
23 <div class="message">
24 <span class="title">{{ post.title }}</span>
24 <span class="title">{{ post.title }}</span>
25 <a class="post_id" href="#{{ post.id }}">
25 <a class="post_id" href="#{{ post.id }}">
26 (#{{ post.id }})</a>
26 (#{{ post.id }})</a>
27 [{{ post.pub_time }}]
27 [{{ post.pub_time }}]
28 {% autoescape off %}
28 {% autoescape off %}
29 {{ post.text.rendered }}
29 {{ post.text.rendered }}
30 {% endautoescape %}
30 {% endautoescape %}
31 </div>
31 </div>
32 {% if post.tags.all %}
32 {% if post.tags.all %}
33 <div class="metadata">
33 <div class="metadata">
34 <span class="tags">{% trans 'Tags' %}:
34 <span class="tags">{% trans 'Tags' %}:
35 {% for tag in post.tags.all %}
35 {% for tag in post.tags.all %}
36 <a class="tag" href="{% url 'tag' tag.name %}">
36 <a class="tag" href="{% url 'tag' tag.name %}">
37 {{ tag.name }}</a>
37 {{ tag.name }}</a>
38 {% endfor %}
38 {% endfor %}
39 </span>
39 </span>
40 </div>
40 </div>
41 {% endif %}
41 {% endif %}
42 </div>
42 </div>
43 {% endfor %}
43 {% endfor %}
44 {% else %}
44 {% else %}
45 No threads found.
45 No threads found.
46 <hr />
46 <hr />
47 {% endif %}
47 {% endif %}
48
48
49 <form enctype="multipart/form-data" method="post">{% csrf_token %}
49 <form enctype="multipart/form-data" method="post">{% csrf_token %}
50 <div class="post-form-w">
50 <div class="post-form-w">
51 <div class="form-title">{% trans "Reply to thread" %}</div>
51 <div class="form-title">{% trans "Reply to thread" %}</div>
52 <div class="post-form">
52 <div class="post-form">
53 <div class="form-row">
53 <div class="form-row">
54 <div class="form-label">{% trans 'Title' %}</div>
54 <div class="form-label">{% trans 'Title' %}</div>
55 <div class="form-input">{{ form.title }}</div>
55 <div class="form-input">{{ form.title }}</div>
56 </div>
56 </div>
57 <div class="form-row">
57 <div class="form-row">
58 <div class="form-label">{% trans 'Text' %}</div>
58 <div class="form-label">{% trans 'Text' %}</div>
59 <div class="form-input">{{ form.text }}</div>
59 <div class="form-input">{{ form.text }}</div>
60 </div>
60 </div>
61 <div class="form-row">
61 <div class="form-row">
62 <div class="form-label">{% trans 'Image' %}</div>
62 <div class="form-label">{% trans 'Image' %}</div>
63 <div class="form-input">{{ form.image }}</div>
63 <div class="form-input">{{ form.image }}</div>
64 </div>
64 </div>
65 </div>
65 </div>
66 <div class="form-submit"><input type="submit"
66 <div class="form-submit"><input type="submit"
67 value="{% trans "Post" %}"/></div>
67 value="{% trans "Post" %}"/></div>
68 <div>Use <a
68 <div>Use <a
69 href="http://daringfireball.net/projects/markdown/basics">
69 href="http://daringfireball.net/projects/markdown/basics">
70 markdown</a> syntax for posting.</div>
70 markdown</a> syntax for posting.</div>
71 <div>Example: *<i>italic</i>*, **<b>bold</b>**</div>
71 <div>Example: *<i>italic</i>*, **<b>bold</b>**</div>
72 <div>Insert quotes with "&gt;"</div>
72 <div>Insert quotes with "&gt;"</div>
73 </div>
73 </div>
74 </form>
74 </form>
75
75
76 {% endblock %}
76 {% endblock %}
General Comments 0
You need to be logged in to leave comments. Login now