From e7bebbe5e4d1a7c2515bc7c352f87c4c5165ca4f Mon Sep 17 00:00:00 2001 From: Phuoc CAO Date: Tue, 3 May 2022 19:24:51 +0200 Subject: [PATCH] finalize topic template --- cao_blogr.sqlite | Bin 151552 -> 151552 bytes cao_blogr/forms.py | 4 +-- cao_blogr/routes.py | 3 +- cao_blogr/services/blog_record.py | 12 +++---- cao_blogr/static/theme.css | 7 +++- cao_blogr/templates/admin.jinja2 | 23 +++++++++++++ cao_blogr/templates/blog.jinja2 | 4 +-- cao_blogr/templates/blog_edit.jinja2 | 32 ++++++----------- cao_blogr/templates/home.jinja2 | 3 +- cao_blogr/templates/layout.jinja2 | 4 +-- cao_blogr/templates/topic.jinja2 | 16 ++------- cao_blogr/views/blog.py | 49 +++++++++++++++++++-------- cao_blogr/views/default.py | 9 +++++ 13 files changed, 101 insertions(+), 65 deletions(-) create mode 100644 cao_blogr/templates/admin.jinja2 diff --git a/cao_blogr.sqlite b/cao_blogr.sqlite index 4b6dea885c660f63f46ed922e8e33b874677b5f9..a8312d93832773af7579bfece88ca35056eca07b 100644 GIT binary patch literal 151552 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 YV=3p4Qg-gN(|&MN`bBwej5fF51*G3=^TANM- zT5D$-lSp^um{=X?^pDuo5yZ|qO|YhEn@-avU~Q&Ut(cjn$&5Cb#H0#n?|pB>gc6lva7Ads||`bK{sEKA5!Eegw0oYLJCg;&R2viD(*Po3TraQ*x_5<(&gLX zQ^X*1?^6xTBeD0`1@>!pntjZASO@zN`w44d^{k9}xcf#H6AQA=Yy#E!z^c068};m@ z#HQF~_D43#PV!AhS>R;zCY_#5NF(yLH(6i3JTlR4j~mOk)*bp@)72XQ;6VZC@-DPr(uG_j7#MRtbmsFntqdm&vlj zQQzrr+wSl1btyaFIMMdTiO!bpJ!0Ll(bv`C?`(O>-`*xu_9rmNPrdaC><2kmw-%hh zr#-jeCLcPg`BV-LddEzJ42oE7xwrN)PJw?+{Q&eEfU!qIvz9&<=lfJ8jQpw>bVF0FgZt|vUOOclV$tkbbbcxhqq!4$cKL>iuCXw zuw>EnRa0>)rqDBhM@9PVv=Z@UVcJfUdW@qRwdkSsVVK5q)ERI^>Ot0B{(f$mx?tbZMqEUdRY;9 zH%{clU6#=DeUNkbEpftaz)a!A1OWZ~I zh1DDLH~5tY+uL>;B5e{%Yoy3@X-(hWBJI;c(4Ag7)d0~_?n&Fww<{~nCQ=5Vbi{Y$ zV1z~c=HPp52L1=4_DfOwhxa}mW!m@i`Y?l3u#Xbtd`PF}d^82CUW4y}h`hR#SHNR(dlYU7QjXyw z5p0EVe&X$VNauEf`bNm*`(-L?f<&><)CB7xc&Gt3hd~E@^i_B)Lg86aa?1nH9sNqG z_EX;EYu)YZdaBc>lqxQlE3`wV@mFAV*s9!);N&LwD8lB=@sucTPpQXS>M3-2yhVj2 z#p-t+_au#0+=Jq|2j)Jd{a;X8mS{hPwp@ad`;_*-Nog@(P#Vvaorcn|{ywAqw;1h? zXovLRta$GQqg_>b%R&90!$0RU+Kj5npq6Wp7_NSLyXFzwkjiA4bij;-oY;OBA~wGr TU($$;KgRr@<%Nh%@Y;U>&ibI& diff --git a/cao_blogr/forms.py b/cao_blogr/forms.py index bda9f69..dff66ba 100644 --- a/cao_blogr/forms.py +++ b/cao_blogr/forms.py @@ -1,6 +1,6 @@ from wtforms import Form, StringField, TextAreaField, SelectField from wtforms import IntegerField, PasswordField -from wtforms.validators import InputRequired, DataRequired, Length +from wtforms.validators import InputRequired, Length from wtforms.widgets import HiddenInput strip_filter = lambda x: x.strip() if x else None @@ -10,7 +10,7 @@ class BlogCreateForm(Form): filters=[strip_filter]) body = TextAreaField('Corps du texte', validators=[InputRequired(), Length(min=1)], filters=[strip_filter]) - tag = SelectField('Tag', validators=[DataRequired()], id='select_tag') + tag = SelectField('Sous-rubrique') class BlogUpdateForm(BlogCreateForm): diff --git a/cao_blogr/routes.py b/cao_blogr/routes.py index c1cce48..cd82953 100644 --- a/cao_blogr/routes.py +++ b/cao_blogr/routes.py @@ -1,9 +1,10 @@ def includeme(config): config.add_static_view('static', 'static', cache_max_age=3600) config.add_route('home', '/') + config.add_route('admin', '/admin') config.add_route('apropos', '/apropos') config.add_route('blog', '/blog/{id:\d+}/{slug}') - config.add_route('blog_edit', '/blog_edit/{id}') + config.add_route('blog_edit', '/blog_edit/{topic}/{id}') config.add_route('blog_search', '/blog_search') config.add_route('login', '/login') config.add_route('logout', '/logout') diff --git a/cao_blogr/services/blog_record.py b/cao_blogr/services/blog_record.py index 61818f5..ffb567a 100644 --- a/cao_blogr/services/blog_record.py +++ b/cao_blogr/services/blog_record.py @@ -10,9 +10,9 @@ from markdown2 import Markdown class BlogRecordService(object): @classmethod - def by_topic(cls, request, topic): + def by_topic(cls, request, topic, tag): # get posts by topic - query = request.dbsession.query(BlogRecord).filter(BlogRecord.topic_id == topic) + query = request.dbsession.query(BlogRecord).filter(BlogRecord.topic_id == topic, BlogRecord.tag == tag) query = query.order_by(BlogRecord.tag, BlogRecord.title).all() return query @@ -25,8 +25,8 @@ class BlogRecordService(object): @classmethod def by_id(cls, request, _id): - query = request.dbsession.query(BlogRecord) - return query.get(_id) + query = request.dbsession.query(BlogRecord).filter(BlogRecord.id == _id).first() + return query @classmethod def get_last_five(cls, request): @@ -39,12 +39,12 @@ class BlogRecordService(object): def get_tags_byTopic(cls, request, topic): # gest the last 5 items modified query = request.dbsession.query(Tags).filter(Tags.topic == topic) - query = query.order_by(Tags.tag).all() + query = query.order_by(Tags.tag_name).all() return query @classmethod def get_topic_name(cls, request, id): - # gest the last 5 items modified + # gest the name of a given topic query = request.dbsession.query(Topics).filter(Topics.topic == id).first() return query.topic_name.upper() diff --git a/cao_blogr/static/theme.css b/cao_blogr/static/theme.css index e601f8e..f8d8239 100644 --- a/cao_blogr/static/theme.css +++ b/cao_blogr/static/theme.css @@ -145,4 +145,9 @@ textarea { content: "*"; color: red; margin-left:2px; -} \ No newline at end of file +} + +.icone-big { + color: #f4511e; + font-size: 50px; +} diff --git a/cao_blogr/templates/admin.jinja2 b/cao_blogr/templates/admin.jinja2 new file mode 100644 index 0000000..9945ba9 --- /dev/null +++ b/cao_blogr/templates/admin.jinja2 @@ -0,0 +1,23 @@ +{% extends "cao_blogr:templates/layout.jinja2" %} + +{% block content %} + +
+
+
+ +

UTILISATEURS

+
+
+ +

TOPICS / TAGS

+
+
+ +

PAGES ADMIN

+
+
+
+ + +{% endblock %} diff --git a/cao_blogr/templates/blog.jinja2 b/cao_blogr/templates/blog.jinja2 index beab5f2..feee89b 100644 --- a/cao_blogr/templates/blog.jinja2 +++ b/cao_blogr/templates/blog.jinja2 @@ -4,8 +4,8 @@ {% if request.authenticated_userid %}

- [ Retour ] - [ Modifier ] + [ Retour ] + [ Modifier ]

{% endif %} diff --git a/cao_blogr/templates/blog_edit.jinja2 b/cao_blogr/templates/blog_edit.jinja2 index 3a7cbf6..cc82354 100644 --- a/cao_blogr/templates/blog_edit.jinja2 +++ b/cao_blogr/templates/blog_edit.jinja2 @@ -20,37 +20,27 @@ {{ form.body(class_='form-control', cols="35", rows="20") }} - {% for error in form.topic.errors %} -
{{ error }}
- {% endfor %} -
- - {{ form.topic(class_='form-control') }} -
- - {% for error in form.tag.errors %} -
{{ error }}
- {% endfor %}
{{ form.tag(class_='form-control') }}
-

- Topic : {{ entry.topic }} -  |  - Tag : {{ entry.tag }} -  |  - Créé le : {{ entry.created.strftime("%d-%m-%Y - %H:%M") }} -  |  - Modifié le : {{ entry.edited.strftime("%d-%m-%Y - %H:%M") }} +

+ Topic : {{ entry.topic_id }} + {% if blog_id != '0' %} +  |  + Créé le : {{ entry.created.strftime("%d-%m-%Y - %H:%M") }} +  |  + Modifié le : {{ entry.edited.strftime("%d-%m-%Y - %H:%M") }} + {% endif %}


- Retour + + Retour - {% if action == 'edit' %} + {% if blog_id != '0' %} {% endif %} diff --git a/cao_blogr/templates/home.jinja2 b/cao_blogr/templates/home.jinja2 index ea84226..1c487cb 100644 --- a/cao_blogr/templates/home.jinja2 +++ b/cao_blogr/templates/home.jinja2 @@ -149,7 +149,6 @@

-

DERNIERES PUBLICATIONS

    @@ -174,7 +173,7 @@
    -

     Centre Méditation Sunyata Paris
    +

     Centre de Méditation Sunyata
    116 bd Maréchal Foch
    93160 NOISY LE GRAND

    diff --git a/cao_blogr/templates/layout.jinja2 b/cao_blogr/templates/layout.jinja2 index 8d4185e..6b5bd90 100644 --- a/cao_blogr/templates/layout.jinja2 +++ b/cao_blogr/templates/layout.jinja2 @@ -91,7 +91,7 @@ | Pratique  | Qi Gong  | Sciences  - | Méditation Sunyata  + | A propos  |

    @@ -99,7 +99,7 @@  | Mentions légales {% if request.authenticated_userid == 'admin' %} -  | Utilisateurs +  | Admin {% endif %}

    diff --git a/cao_blogr/templates/topic.jinja2 b/cao_blogr/templates/topic.jinja2 index 9cf7e1c..60a432d 100644 --- a/cao_blogr/templates/topic.jinja2 +++ b/cao_blogr/templates/topic.jinja2 @@ -3,21 +3,11 @@ {% block content %} {% if request.authenticated_userid %} -

    +

    [Nouveau post]

    {% endif%} - - + {{ liste | safe }} + {% endblock %} diff --git a/cao_blogr/views/blog.py b/cao_blogr/views/blog.py index a854cf5..862f395 100644 --- a/cao_blogr/views/blog.py +++ b/cao_blogr/views/blog.py @@ -12,8 +12,8 @@ def blog(request): blog_id = request.matchdict['id'] entry = BlogRecordService.by_id(request, blog_id) if not entry: - request.session.flash(u"Page non trouvée : %s" % blog_id, 'warning') - return HTTPFound(location=request.route_url('home')) + request.session.flash(u"Page non trouvée : %s" % blog_id, 'warning') + return HTTPFound(location=request.route_url('home')) # just created ? convert body to html if entry.body_html == '': @@ -29,18 +29,21 @@ def blog(request): renderer='cao_blogr:templates/blog_edit.jinja2', permission='view') def blog_edit(request): - # get post id from request + # get post parameters from request + topic = request.matchdict['topic'] blog_id = request.matchdict['id'] - url = request.route_url('blog_edit',id=blog_id) + url = request.route_url('blog_edit',topic=topic, id=blog_id) + + # get the list of tags of this topic + tags = BlogRecordService.get_tags_byTopic(request, topic) if blog_id == '0': # create a new post entry = BlogRecord() - # set default values - entry.tag = 'pyramid' - entry.topic = 'blog' + entry.topic_id = topic form = BlogCreateForm(request.POST, entry) - form.tag.choices = [(row.tag, row.title) for row in BlogRecordService.tags] + form.tag.choices = [(row.tag, row.tag_name) for row in tags] + else: # modify post entry = BlogRecordService.by_id(request, blog_id) @@ -48,15 +51,17 @@ def blog_edit(request): request.session.flash(u"Page non trouvée : %s" % blog_id, 'warning') return HTTPFound(location=request.route_url('home')) form = BlogUpdateForm(request.POST, entry) + form.tag.choices = [(row.tag, row.tag_name) for row in tags] if 'form.submitted' in request.params and form.validate(): if blog_id == '0': form.populate_obj(entry) entry.title_url = entry.slug + entry.topic_id = topic request.dbsession.add(entry) - return HTTPFound(location=request.route_url('home')) + return HTTPFound(location=request.route_url('topic', topic=topic)) else: del form.id # SECURITY: prevent overwriting of primary key form.populate_obj(entry) @@ -69,7 +74,8 @@ def blog_edit(request): return { 'page_title': entry.title, 'url': url, - 'form': form, + 'form': form, + 'blog_id': blog_id, 'entry': entry, } @@ -101,12 +107,25 @@ def topic(request): # get the topic_name topic_name = BlogRecordService.get_topic_name(request, topic) - - # lire toutes les docs du topic - items = BlogRecordService.by_topic(request, topic) - + # get all the tags of this topic + tags = BlogRecordService.get_tags_byTopic(request, topic) + + # generate the items list group by tag + liste = '' + for tag in tags: + liste += '

    ' + tag.tag_name + '

    ' + # lire toutes les docs du topic + items = BlogRecordService.by_topic(request, topic, tag.tag) + if items: + liste += '
      ' + for item in items: + liste += '
    • {0} {2}
    • '.format( + item.edited.strftime("%d-%m-%Y"), request.route_url('blog', id=item.id, slug=item.slug), item.title) + liste += '
    ' + else: + liste += '
    ' return { 'page_title': topic_name, 'topic': topic, - 'items': items, + 'liste': liste, } diff --git a/cao_blogr/views/default.py b/cao_blogr/views/default.py index d1cbdf2..0e540a5 100644 --- a/cao_blogr/views/default.py +++ b/cao_blogr/views/default.py @@ -33,6 +33,15 @@ def home(request): } +@view_config(route_name='admin', + renderer='cao_blogr:templates/admin.jinja2') +def admin(request): + + return { + 'page_title': "Admin", + } + + @view_config(route_name='apropos', renderer='cao_blogr:templates/apropos.jinja2') def apropos(request):