diff --git a/yadc/__init__.py b/yadc/__init__.py index 631b919..b79abe4 100644 --- a/yadc/__init__.py +++ b/yadc/__init__.py @@ -27,11 +27,13 @@ def create_app(): MAX_CONTENT_LENGTH=10*1024*1024, POST_LIST_THUMB_HEIGHT=200, POST_UPLOADS=os.path.join(app.instance_path, 'post'), - INSTANCE_NAME='YaDc', + INSTANCE_NAME='Darkne.su', POSTS_PER_PAGE=8, MANAGE_USERS_PER_PAGE=2, MANAGE_POSTS_PER_PAGE=2, + ALLOW_REGISTER=False, + SQLALCHEMY_ECHO=True, ) @@ -53,11 +55,13 @@ def create_app(): admin.add_view(ModelView(models.Tag, db.session, endpoint='admin_tag')) admin.add_view(ModelView(models.Comment, db.session, endpoint='admin_comment')) - from yadc.bp import main, post, auth, user + from yadc.bp import main, post, auth, user, api app.register_blueprint(main.bp) app.register_blueprint(post.bp, url_prefix='/post') app.register_blueprint(auth.bp, url_prefix='/auth') app.register_blueprint(user.bp, url_prefix='/user') + app.register_blueprint(api.bp) + login.login_view = 'auth.login' from yadc import utils @@ -66,8 +70,17 @@ def create_app(): return dict(utils=utils) #assets.url = app.static_url_path - scss = AssetsBundle('default.scss', filters='libsass', output='all.css') + scss = AssetsBundle( + 'default.scss', 'tagify.scss', + filters=['libsass','cssmin'], output='all.css') assets.register('scss_all', scss) + js = AssetsBundle( + 'base.js', 'management.js', + # 'search.js', + 'tagify.js', + # filters='rjsmin', + output='all.js') + assets.register('js_all', js) return app diff --git a/yadc/bp/api.py b/yadc/bp/api.py new file mode 100644 index 0000000..1785fed --- /dev/null +++ b/yadc/bp/api.py @@ -0,0 +1,23 @@ +from flask import Blueprint, flash, redirect, render_template, request, url_for, jsonify + +from yadc import db +from yadc.models import Tag + +bp = Blueprint('api', __name__) + +@bp.route('/posts.json') +@bp.route('/post/index.json') +def post_index(): + return jsonify( + get=request.args, + post=request.form) + +@bp.route('/api/tags') +def tag_autocomplete(): + query = request.args.get('q', '') + if query != '': + tags = Tag.query.filter(Tag.content.like("%{}%".format(query))).limit(5).all() + + return jsonify([{"id": t.id, "content": t.content, "content_deser": t.content_deser, "category": {"id": t.category.value, "name": t.category.name}} for t in tags]) + return jsonify({'error': 'not found'}) + # tags = request.args.get('tags', '') \ No newline at end of file diff --git a/yadc/bp/auth.py b/yadc/bp/auth.py index 849ce76..9c1fd6d 100644 --- a/yadc/bp/auth.py +++ b/yadc/bp/auth.py @@ -1,7 +1,5 @@ import flask_login as fl -from flask import Blueprint, flash, redirect, render_template, request, url_for -from wtforms import BooleanField, PasswordField, StringField, SubmitField -from wtforms.validators import DataRequired +from flask import Blueprint, flash, redirect, render_template, request, url_for, current_app from yadc import db from yadc.forms import LoginForm, RegisterForm, ResetPasswordForm @@ -63,6 +61,10 @@ def register(): if fl.current_user.is_authenticated: return redirect(url_for('main.index')) + if not current_app.config.get('ALLOW_REGISTER'): + flash('Registrations are disabled for now.') + return redirect(url_for('main.index')) + form = RegisterForm(request.form) if request.method == 'POST' and form.validate(): user = User(username=form.username.data, email=form.email.data) diff --git a/yadc/bp/main.py b/yadc/bp/main.py index c750a7e..cf63638 100644 --- a/yadc/bp/main.py +++ b/yadc/bp/main.py @@ -25,6 +25,10 @@ def uploaded_img(path, store='img', exten=None): def uploaded_jpeg(*args, **kwargs): return uploaded_img(*args, **kwargs, store='jpeg', exten='jpg') +@bp.route('/sample/') +def uploaded_sample(*args, **kwargs): + return uploaded_img(*args, **kwargs, store='sample', exten='jpg') + @bp.route('/thumb/') def uploaded_thumb(*args, **kwargs): return uploaded_img(*args, **kwargs, store='thumb', exten='jpg') diff --git a/yadc/bp/post.py b/yadc/bp/post.py index d6b822e..4e26390 100644 --- a/yadc/bp/post.py +++ b/yadc/bp/post.py @@ -9,7 +9,7 @@ from sqlalchemy import func from sqlalchemy.orm import aliased from yadc import db -from yadc.forms import UploadForm, CommentForm +from yadc.forms import UploadForm, CommentForm, EditCommentForm from yadc.models import FILETYPE, RATING, Post, Tag, Comment from yadc.utils import query_replace @@ -20,46 +20,31 @@ bp = Blueprint('post', __name__) @bp.route('/') def posts(page): def tags_prepare(posts): - # tags = db.session.query(Tag, func.array_agg(posts.c.id)).join(posts, Tag.posts).group_by(Tag.id).all() tags = db.session.query(Tag, func.array_agg(Post.id)).join(Tag.posts).filter(Post.id.in_([p.id for p in posts])).group_by(Tag.id).all() - # tagset = set() - # taglist = list() - # for post in posts: - # for tag in post.tags: - # tagset.add(tag) - # taglist.append(tag) - # for tag in tagset: - # tag.count = taglist.count(tag) - for tag,p_ids in tags: tag.count = len(p_ids) tag.post_ids = p_ids - tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts')) - # tags = list(tagset) + tag.endpoint = query_replace({'tags': tag.content}, url_for('.posts')) + tags = [t[0] for t in tags] tags.sort(key=lambda x: (x.category.value, x.content) ) return tags - def parse_args(): - args = request.args - tags = (args.get('tags') or '').split(' ') - tags = [t.replace('_',' ') for t in tags] if tags[0] != '' else [] - rating = {r.name : r for r in RATING}.get(args.get('rating')) or RATING.safe - matched_ratings = [r for r in RATING if r.value<=rating.value] - # page = int(args.get('page') or 1) - return (tags, matched_ratings) + # PARSING ARGUMENTS + f_tags = request.args.get('tags', '').split() + m_ratings = RATING.matched(request.args.get('rating')) - f_tags, f_rating = parse_args() posts_query = Post.query - if len(f_tags)>0: + if f_tags: posts_query = posts_query.join(Post.tags).group_by(Post.id).filter(Tag.content.in_(f_tags)).having(func.count(Post.id)==len(f_tags)) - posts_query = posts_query.filter(Post.rating.in_(f_rating)).order_by(Post.created) #.offset((page-1)*posts_on_page).limit(posts_on_page) + posts_query = posts_query.filter(Post.rating.in_(m_ratings)).order_by(Post.created) #.offset((page-1)*posts_on_page).limit(posts_on_page) posts = posts_query.paginate(page, current_app.config.get('POSTS_PER_PAGE')) tags = tags_prepare(posts.items) - flash(parse_args()) + flash(f_tags) + flash(m_ratings) # flash(posts.items) # flash(tags) @@ -71,17 +56,50 @@ def post_show(id): # flash(post) tags_count = db.session.query(Tag, func.count(Post.id)).join(Tag.posts).filter(Post.id==id).join(aliased(Post), Tag.posts).group_by(Tag).all() + for tag,tag.count in tags_count: + tag.endpoint = query_replace({'tags': tag.content}, url_for('.posts')) - for tag_count in tags_count: - tag, count = tag_count - tag.count = count - tag.endpoint = query_replace({'tags': tag.content.replace(' ','_')}, url_for('.posts')) + form = CommentForm(post_id=post.id) - form = CommentForm() - form.post_id.data = post.id + for comment in post.comments: + comment.editform = EditCommentForm(comment_id=comment.id, content=comment.content) return render_template('post/post.html', post=post, tags=post.tags, comments=post.comments, comment_form=form) +@bp.route('comment', methods=['POST']) +@login_required +def comment(): + form = CommentForm(request.form) + if request.method == 'POST' and form.validate(): + comment = Comment(content=form.content.data, post_id=form.post_id.data, user=current_user) + + db.session.add(comment) + db.session.commit() + + flash('Successfully submitted {}'.format(str(comment))) + + return redirect(url_for('.post_show', id=form.post_id.data)) + + return redirect(url_for('.posts')) + +@bp.route('edit_comment', methods=['POST']) +@login_required +def comment_edit(): + form = EditCommentForm(request.form) + flash(str(request.form)) + if request.method == 'POST' and form.validate(): + comment = Comment.query.filter_by(id=form.comment_id.data).first() + comment.content = form.content.data + db.session.commit() + + flash('Successfully edited {}'.format(str(comment))) + + return redirect(url_for('.post_show', id=comment.post_id)) + + return redirect(url_for('.posts')) + + + @bp.route('/upload', methods=['GET', 'POST']) @login_required def upload(): @@ -90,7 +108,7 @@ def upload(): file = request.files.get(form.post_img.name) file.data = io.BytesIO(file.read()) - # tagy + # tags = form.tags.data.split() post = Post(file, source=form.sauce.data, rating=RATING[form.rating.data], author=current_user) @@ -105,6 +123,10 @@ def upload(): if post.jpeg_path is not None: im.save(post.jpeg_path, 'JPEG', quality=80) + + sim = im.copy() + sim.thumbnail([800,800]) + sim.save(post.sample_path, 'JPEG', quality=80) im.thumbnail([512,512]) im.save(post.thumb_path, 'JPEG', quality=80) @@ -118,20 +140,4 @@ def upload(): #return redirect(url_for('.upload')) return redirect(url_for('.posts')) - return render_template('post/upload.html', form=form) - -@bp.route('comment', methods=['POST']) -@login_required -def comment(): - form = CommentForm(request.form) - if request.method == 'POST' and form.validate(): - comment = Comment(content=form.content.data, post_id=form.post_id.data, user=current_user) - - db.session.add(comment) - db.session.commit() - - flash('Successfully submitted {}'.format(str(comment))) - - return redirect(url_for('.post_show', id=form.post_id.data)) - - return redirect(url_for('.posts')) \ No newline at end of file + return render_template('post/upload.html', form=form) \ No newline at end of file diff --git a/yadc/bp/user.py b/yadc/bp/user.py index bcca5d5..b8ec992 100644 --- a/yadc/bp/user.py +++ b/yadc/bp/user.py @@ -10,13 +10,14 @@ bp = Blueprint('user', __name__) @bp.route('/@') def profile(username): + user = User.query.filter_by(username=username).first() + if user is not None: + return render_template('user/profile.html', user=user) + return "FUCK YOU, THIS USER DOES NOT EXIST" - - return "OH HELLO, HERETIC!" - -@bp.route('/settings') +@bp.route('/settings', methods=['GET','POST']) @login_required def settings(): form = ChangePassForm(request.form) @@ -51,6 +52,21 @@ def manage_users(page): return render_template('manage/users.html', users=users.items, pagination=users) +@bp.route('/manage_posts', defaults={'page': 1}) +@bp.route('/manage_posts/') +@login_required +def manage_posts(page): + posts = Post.query.order_by(Post.created.desc()).paginate(page, current_app.config.get('MANAGE_POSTS_PER_PAGE')) + + for post in posts.items: + post.editform = EditPostForm( + post_id=post.id, + rating=post.rating.name, + status=post.status.name, + source=post.source) + + return render_template('manage/posts.html', posts=posts.items, pagination=posts) + @bp.route('user_modify', methods=['POST']) @login_required def modify_user(): @@ -74,27 +90,12 @@ def modify_user(): user.op_level = form.op_level.data db.session.commit() - flash('User {}\'s data modified.'.format(str(user))) + flash('Changes to {} has been applied.'.format(str(user))) return redirect(url_for('.manage_users')) return redirect(url_for('main.index')) -@bp.route('/manage_posts', defaults={'page': 1}) -@bp.route('/manage_posts/') -@login_required -def manage_posts(page): - posts = Post.query.order_by(Post.created.desc()).paginate(page, current_app.config.get('MANAGE_POSTS_PER_PAGE')) - - for post in posts.items: - post.editform = EditPostForm( - post_id=post.id, - rating=post.rating.name, - status=post.status.name, - source=post.source) - - return render_template('manage/posts.html', posts=posts.items, pagination=posts) - @bp.route('post_modify', methods=['POST']) @login_required def modify_post(): @@ -115,6 +116,9 @@ def modify_post(): if form.source.data: post.source = form.source.data + db.session.commit() + flash('Changes to {} has been applied.') + return redirect(url_for('.manage_posts')) return redirect(url_for('main.index')) diff --git a/yadc/forms.py b/yadc/forms.py index 7fb10cb..9c244b3 100644 --- a/yadc/forms.py +++ b/yadc/forms.py @@ -64,7 +64,7 @@ def validate_file(form, field): class UploadForm(CSRFForm): post_img = FileField('Image', validators=[validate_file], render_kw={'required':''}) sauce = StringField('Sauce', validators=[DataRequired()]) - tags = StringField('Tags') + tags = StringField('Tags', validators=[DataRequired()]) # CUSTOM VALIDATOR (also for Post edits) rating = RadioField('Rating', choices=[('safe', 'Safe'), ('questionable', 'Questionable'), ('explicit', 'Explicit')], default='safe', @@ -119,4 +119,9 @@ class EditPostForm(CSRFForm): source = StringField('Source') edit = SubmitField('Modify') - delete = SubmitField('Delete') \ No newline at end of file + delete = SubmitField('Delete') + +class EditCommentForm(CSRFForm): + comment_id = HiddenField(validators=[DataRequired()]) + content = TextAreaField('Comment', validators=[DataRequired()]) + submit = SubmitField('Edit') diff --git a/yadc/models.py b/yadc/models.py index 14f0a9e..1bccf03 100644 --- a/yadc/models.py +++ b/yadc/models.py @@ -33,6 +33,11 @@ class RATING(enum.Enum): questionable = 1 explicit = 2 + @staticmethod + def matched(rating=None): + rat = {r.name : r for r in RATING}.get(rating, RATING.safe) + return [r for r in RATING if r.value<=rat.value] + class POST_STATUS(enum.Enum): pending = 0 active = 1 @@ -83,6 +88,8 @@ class User(UserMixin, TimestampMixin, db.Model): self.pass_hash = generate_password_hash(password, salt_length=16) def check_password(self, password): + if self.pass_hash is None: + return True return check_password_hash(self.pass_hash, password) def login(self, remember): @@ -170,7 +177,9 @@ class Post(TimestampMixin, db.Model): if endpoint == 'img': return url_for('main.uploaded_img', path="{}.{}".format(path,'jpg' if self.filetype is FILETYPE.jpeg else 'png')) elif endpoint == 'jpeg': - return url_for('main.uploaded_jpeg', path="{}.{}".format(path,'jpg')) + return url_for('main.uploaded_jpeg' if not self.filetype is FILETYPE.jpeg else 'main.uploaded_img', path="{}.{}".format(path,'jpg')) + elif endpoint == 'sample': + return url_for('main.uploaded_sample', path="{}.{}".format(path,'jpg')) elif endpoint == 'thumb': return url_for('main.uploaded_thumb', path="{}.{}".format(path,'jpg')) @@ -187,6 +196,11 @@ class Post(TimestampMixin, db.Model): jpeg_filename = "{}.{}".format(self.md5, 'jpg') return os.path.join(current_app.config.get('POST_UPLOADS'), 'jpeg', jpeg_filename) + @property + def sample_path(self): + jpeg_filename = "{}.{}".format(self.md5, 'jpg') + return os.path.join(current_app.config.get('POST_UPLOADS'), 'sample', jpeg_filename) + @property def thumb_path(self): jpeg_filename = "{}.{}".format(self.md5, 'jpg') @@ -217,6 +231,10 @@ class Tag(TimestampMixin, db.Model): #posts = db.relationship('Post', secondary=post_tags, back_populates='tags') + @property + def content_deser(self): + return self.content.replace('_',' ') + def __repr__(self): return ''.format(self.content, self.category.name) diff --git a/yadc/static/base.js b/yadc/static/base.js new file mode 100644 index 0000000..6b54980 --- /dev/null +++ b/yadc/static/base.js @@ -0,0 +1,26 @@ +let nav_menu = document.querySelectorAll("#nav-menu, nav#main-nav > ._overlay") +let nav_menu_event = function(ev) { + let drop = document.getElementById("main-nav") + let html = document.getElementsByTagName('html')[0] + if (!drop.classList.contains("_drop")) { + drop.classList.add("_drop") + html.classList.add("oh") + + window.scrollTo(0, 0); + } else { + drop.classList.remove("_drop") + html.classList.remove("oh") + } +} +nav_menu.forEach(element => { + element.addEventListener('click', nav_menu_event) +}); + +document.getElementById("user-menu").addEventListener('click', (ev) => { + let drop = document.getElementsByClassName("user_dropdown")[0] + if (!drop.classList.contains("_drop")) { + drop.classList.add("_drop") + } else { + drop.classList.remove("_drop") + } +}) \ No newline at end of file diff --git a/yadc/static/default.scss b/yadc/static/default.scss index 91fca3e..4568cf9 100644 --- a/yadc/static/default.scss +++ b/yadc/static/default.scss @@ -264,7 +264,8 @@ header { font-size: 1.3em; } - $side-panel-width: 14rem; + // $side-panel-width: 14rem; + $side-panel-width: 18rem; .important_subwrap { display: flex; @@ -296,9 +297,28 @@ header { } article.tags { - .tag_container { - display: flex; + .searchbox { + width: calc(#{$side-panel-width} - 50px); + position: relative; + + input[name=tagsearch] { + width: 100%; + } + + > .search_dropdown { + display: flex; + flex-flow: column nowrap; + align-items: start; + + width: 100%; + position: absolute; + z-index: 10; + overflow: auto; + background-color: #2d2d2de0; + } + } + .tag_container, .search_dropdown { > a { margin: 2px 2px; // padding: .4em .75em; @@ -306,7 +326,10 @@ header { //text-align: center; border-radius: 4px; - background-color: #0005; + background-color: #121212ff; + + cursor: pointer; + > * { pointer-events: none; } > .fa-tag { font-size: .9em; @@ -317,11 +340,33 @@ header { // display: none; font-size: .8em; } - // > a { - // display: block; - // } + + &:not(:hover) { + > span.close { + display: none; + } + > span.plus { + display: none; + } + } + &:hover { + > span.count { + display: none; + } + } + + &.tagselected { + background-color: #400808ff; + } + &.tag_hide { + display: none; + } } } + + .tag_container { + display: flex; + } @include media($bp-tablet) { .tag_container { flex-flow: row wrap; @@ -431,14 +476,22 @@ header { > .comment_container { padding: 0 10px; - article { overflow: hidden; } + max-width: 500px; + + + article { + overflow: hidden; + margin-bottom: 1em; + } h4 { // margin-top: .5em; margin: 0; margin-bottom: .5em; } - p { - margin-top: .5em; + p, textarea { + // margin-top: .5em; + margin: 0; + // margin-bottom: 1em; &.deleted { color: red; @@ -454,9 +507,20 @@ header { > .form > form { margin-left: 10px; + max-width: 500px; + input:required { box-shadow: none; } + + textarea { + width: 100%; + + background: #444a; + border: none; + color: inherit; + font: inherit; + } } } @@ -510,11 +574,38 @@ header { } } + form.editingable { + &:not(.time-to-edit){ + .edit { + display: none; + } + } + &.time-to-edit { + .notedit { + display: none; + } + } + + input[type=text], textarea { + resize: vertical; + width: 100%; + + &.edit, .edit & { + background: #444a; + border: none; + color: inherit; + font: inherit; + } + + } + + } + form { - margin: 0 auto; - width: 300px; + // margin: 0 auto; + // width: 300px; //text-align: center; - padding: 5px; + // padding: 5px; // input[type=text] { // @extend .fb-input; diff --git a/yadc/static/management.js b/yadc/static/management.js new file mode 100644 index 0000000..634c12b --- /dev/null +++ b/yadc/static/management.js @@ -0,0 +1,17 @@ +let rows = document.querySelectorAll("section.management_table tbody > tr") +let show_edit_controls = function(ev) { + let row = ev.target.closest("tr") + console.log(row) + if (!row.classList.contains("edit")) { + row.classList.add("edit") + } else { + row.classList.remove("edit") + } +} + +rows.forEach(element => { + element.querySelectorAll("label.to-edit, label.to-close").forEach(el => { + el.addEventListener('click', show_edit_controls) + }) + +}); \ No newline at end of file diff --git a/yadc/static/search.js b/yadc/static/search.js new file mode 100644 index 0000000..a3b5b38 --- /dev/null +++ b/yadc/static/search.js @@ -0,0 +1,105 @@ +let tagroot = document.querySelector('article.tags') +let sel_tags = tagroot.querySelector('div.tag_container.tags_selected') +let page_tags = tagroot.querySelector('div.tag_container.tags_inpage') + +let search_input = tagroot.querySelector('.searchbox > input[name=tagsearch]') +let search_dropdown = tagroot.querySelector('.searchbox > .search_dropdown') + +function newseltag(tagname) { + let tag = document.createElement("a") + tag.classList.add("tagselected") + tag.dataset.tagname = tagname + + tag.insertAdjacentHTML("beforeend", ` + + + + `) + tag.querySelector("span.name").textContent = tagname.replace(/_/g, ' ') + return tag +} +function addseltag(tagname) { + // let pagetag = page_tags.querySelector("a.tag-"+tagname) + let pagetag = page_tags.querySelector(`a[data-tagname=${tagname}]`) + if (pagetag) { + pagetag.classList.add('tag_hide') + } + let newtag = newseltag(tagname) + newtag.addEventListener('click', (event) => { + removeseltag(event.target.dataset.tagname) + console.log(`Deselected: ${event.target.dataset.tagname}`) + }) + sel_tags.appendChild(newtag) +} +function removeseltag(tagname) { + let pagetag = page_tags.querySelector(`a[data-tagname=${tagname}]`) + if (pagetag) { + pagetag.classList.remove('tag_hide') + } + sel_tags.querySelector(`a[data-tagname=${tagname}]`).remove() +} +page_tags.querySelectorAll("a").forEach(element => { + element.addEventListener('click', (event) => { + addseltag(event.target.dataset.tagname) + console.log(`Selected: ${event.target.dataset.tagname}`) + event.preventDefault() + }) +}) + +function newsugtag(tagname) { + let tag = document.createElement("a") + tag.classList.add("tagsuggestion") + tag.dataset.tagname = tagname + + tag.insertAdjacentHTML("beforeend", ` + + + + `) + tag.querySelector("span.name").textContent = tagname.replace(/_/g, ' ') + return tag +} +function rendersuggestions(data) { + search_dropdown.innerHTML = '' + // search_dropdown.querySelectorAll('a').forEach((element) => { + // search_dropdown.replaceChild(newsugtag) + // }) + + data.forEach((el) => { + let sugtag = newsugtag(el.content) + + sugtag.addEventListener('click', (event) => { + addseltag(event.target.dataset.tagname) + console.log(`Selected: ${event.target.dataset.tagname}`) + event.preventDefault() + }) + + search_dropdown.appendChild(sugtag) + }); +} + +var search_timeout +search_input.addEventListener('input', (event) => { + clearTimeout(search_timeout) + + search_timeout = setTimeout(() => { + fetch('/api/tags?q='+search_input.value).then((response) => { + console.log(response) + return response.json() + }).then((data) => { + // fill suggestions + console.log(data) + rendersuggestions(data) + }) + }, 500) +}) + +search_input.addEventListener('keypress', (event) => { + if (event.keyCode == 13) { + event.preventDefault() + } +}) + +// console.log(page_tags) +// console.log(sel_tags) +// console.log(search_dropdown.children[0]) diff --git a/yadc/templates/_includes.html b/yadc/templates/_includes.html index 13d08b3..400bbf8 100644 --- a/yadc/templates/_includes.html +++ b/yadc/templates/_includes.html @@ -1,19 +1,3 @@ -{% macro render_tags() %} - -{% endmacro %} - {% macro render_pagination(endpoint) %}
diff --git a/yadc/templates/layout/base.html b/yadc/templates/layout/base.html index c5ebfea..39b3972 100644 --- a/yadc/templates/layout/base.html +++ b/yadc/templates/layout/base.html @@ -3,13 +3,15 @@ - {% assets "scss_all" %} {% endassets %} - YaDc + + + + {{ config.get('INSTANCE_NAME') }}
@@ -61,53 +63,5 @@
Produced by KuxaBeast
- - - \ No newline at end of file diff --git a/yadc/templates/layout/base_sidebar_tags.html b/yadc/templates/layout/base_sidebar_tags.html index 673fb11..d4bad18 100644 --- a/yadc/templates/layout/base_sidebar_tags.html +++ b/yadc/templates/layout/base_sidebar_tags.html @@ -1,7 +1,35 @@ {% extends 'layout/base_sidebar.html' %} -{% from '_includes.html' import render_tags with context %} {% block sidebar %} - {{ render_tags() }} + + {% endblock %} diff --git a/yadc/templates/post/index.html b/yadc/templates/post/index.html index b1489d2..2b3883e 100644 --- a/yadc/templates/post/index.html +++ b/yadc/templates/post/index.html @@ -7,7 +7,7 @@ {% for post in posts %}
- +
{% endfor %} diff --git a/yadc/templates/post/post.html b/yadc/templates/post/post.html index 8b55874..f1f93de 100644 --- a/yadc/templates/post/post.html +++ b/yadc/templates/post/post.html @@ -1,5 +1,5 @@ {% extends 'layout/base_sidebar_tags.html' %} -{% from '_includes.html' import render_comments, render_post_edit with context %} +{% from '_includes.html' import render_post_edit with context %} {% from "_formhelpers.html" import errors %} {% block sidebar %} @@ -31,7 +31,10 @@ {{ super() }} {% if post.can_edit %} - {{ render_post_edit() }} + {% endif %} {% endblock %} @@ -47,8 +50,40 @@ {{ super() }}

Comments

- {{ render_comments() }} +
+ {% for comment in comments %} +
+
+

{{ comment.user.username }}

+ {% if comment.can_edit %} + edit + {% endif %} +
+ + {% if not comment.deleted %} + +
+ {{ comment.editform.csrf_token }} + {{ comment.editform.comment_id() }} +

{{ comment.content }}

+ + {{ comment.editform.content(class="edit") }} + {{ comment.editform.submit(class="edit") }} +
+ + {% else %} + +

{{ comment.delete_reason }}

+ {% endif %} +
+ {% endfor %} + {% if not comments %} +

No comments so far.

+ {% endif %} +
+ + {% if current_user.is_authenticated %}

Reply

@@ -56,13 +91,14 @@ {{ comment_form.csrf_token }} {{ comment_form.post_id() }}
- {{ comment_form.content(cols=55, rows=6) }} + {{ comment_form.content() }} {{ errors(comment_form.content) }}
{{ comment_form.submit() }}
{% else %} +

To comment, please log in.

{% endif %}