Commit dbbe5d50 authored by Nicolas G.'s avatar Nicolas G.

Ajout de fonctionalité : recontres ponctuelles (avec une seule date).

Poursuite de l'effort de traduction
parent 38232da5
Qu'est-ce ?
===========
Permet de programmer des rendez-vous régulier avec inscription et localisation sur une carte.
Permet de programmer des rendez-vous réguliers (ou non) avec inscription et localisation sur une carte.
Licence
=======
......@@ -10,7 +10,7 @@ Historique
==========
* Firstjeudi a été écrit en PHP (3) initialement par : Fabien Seisen en 2001, Rodolphe Quiédeville en 2002.
* Puis adapté (PHP 4) en 2011 et 2012 par Nicolas Grandjean.
* La version actuelle en Django/Python reprend les mêmes principes initiaux en ajoutant une interface d'administration et la localisation de l'évènement en natif.
* La version actuelle en Django/Python reprend les mêmes principes initiaux en ajoutant une interface d'administration et la localisation de l'évènement en natif. Plus d'infos : http://wiki.rhizomes.org/index.php/Reprise_du_Firstjeudi_par_Rhizomes
Démonstration
=============
......
......@@ -42,6 +42,7 @@ INSTALLED_APPS = (
'fj',
'redactor',
'django.contrib.gis',
'ponctu',
)
MIDDLEWARE_CLASSES = (
......@@ -99,7 +100,6 @@ USE_L10N = True
LANGUAGES = (
('fr', _('Français')),
('en', _('Anglais')),
)
DEFAULT_LANGUAGE = 1
......
#-*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from fj.views import ListeVilles, InscritsDelete
from fj.views import InscritsDelete
from ponctu.views import InscritsDeletePonctu
from django.contrib import admin
from django.contrib.gis import admin as geoadmin
......@@ -17,16 +16,21 @@ urlpatterns = patterns('',
# Administration
url(r'^admin/', include(geoadmin.site.urls)),
# Page de désinscription
# Page de désinscription pour les régulières
url(r'^del/?(?P<unique>.+)$', InscritsDelete.as_view(), name='inscrit_delete'),
# Page de désinscription pour les ponctuelles
url(r'^r/del/?(?P<unique>.+)$', InscritsDeletePonctu.as_view(), name='inscrit_delete_ponctu'),
# Page d'une recontre : inscription
url(r'^r/?(?P<code>.+)$', 'ponctu.views.inscription'),
# Page d'une ville : inscription
url(r'^(?P<code>.+)$', 'fj.views.inscription'),
# Page d'index : la liste des villes
url(r'^$', ListeVilles.as_view(), name='index'),
# url(r'^$', ListeVilles.as_view(), name='index'),
url(r'^$', 'fj.views.liste_villes', name='index'),
#url(r'^(?P<code>.+)/stats$', 'fj.views.stats'),
......
......@@ -22,6 +22,7 @@
#
from django import forms
from models import Inscrits
from django.utils.translation import gettext_lazy as _
class InscritsForm(forms.ModelForm):
class Meta:
......@@ -31,7 +32,7 @@ class InscritsForm(forms.ModelForm):
def clean_verif(self):
verif = self.cleaned_data['verif']
if verif!=u"quatre":
raise forms.ValidationError("Désolé !")
raise forms.ValidationError(_("Désolé !"))
return verif
......@@ -19,7 +19,7 @@ def pas_de_zero(value):
def pas_plus_de_cinq(value):
if value > 5:
raise ValidationError(u"C'est un peu trop, %s, non ?!" % value)
raise ValidationError(_("C'est un peu trop, %s, non ?!") % value)
# Description de la base de données
#
......@@ -28,65 +28,58 @@ def pas_plus_de_cinq(value):
class Ville(models.Model):
JOURS = (
(0,u'Dimanche'),
(1,u'Lundi'),
(2,u'Mardi'),
(3,u'Mercredi'),
(4,u'Jeudi'),
(5,u'Vendredi'),
(6,u'Samedi'),
(0,_('Dimanche')),
(1,_('Lundi')),
(2,_('Mardi')),
(3,_('Mercredi')),
(4,_('Jeudi')),
(5,_('Vendredi')),
(6,_('Samedi')),
)
code = models.CharField(verbose_name=u"Raccourci (utilisé dans les URL)", max_length =10, unique=True, null=False)
nom = models.CharField(verbose_name=u"Nom complet", max_length=30, unique=True, null=False)
#message = models.TextField(verbose_name=u"Message long (apparaît sur la page de la ville)")
#description = models.TextField(verbose_name=u"Message plus court (apparaît sur le résumé)")
code = models.CharField(verbose_name=_("Raccourci (utilisé dans les URL)"), max_length =10, unique=True, null=False)
nom = models.CharField(verbose_name=_("Nom complet"), max_length=30, unique=True, null=False)
message = RedactorField(
verbose_name=u"Message long (apparaît sur la page de la ville)",
verbose_name=_("Message long (apparaît sur la page de la ville)"),
allow_file_upload=False,
allow_image_upload=False,
)
)
description = RedactorField(
verbose_name=u"Message plus court (apparaît sur le résumé)",
verbose_name=_("Message plus court (apparaît sur le résumé)"),
allow_file_upload=False,
allow_image_upload=False,
)
#lat = models.FloatField(verbose_name=u"Latitude (utilisé pour afficher une carte OpenLayers)", null=False, default=47.5963)
#lon = models.FloatField(verbose_name=u"Longitude (utilisé pour afficher une carte OpenLayers)", null=False, default=-2.778)
champGeo = geomodels.PointField(verbose_name=u"Lieu")
zoom = models.FloatField(verbose_name=u"Zoom de la carte", null=False, default=17)
#champGeo = gismodels.PointField(verbose_name=u"Champ point")
numday = models.IntegerField(verbose_name=u"nième jour de la semaine",null=False, choices=JOURS)
numweek = models.IntegerField(verbose_name=u"nième semaine du mois",null=False, validators=[pas_de_zero, pas_plus_de_cinq], max_length=1)
#objects = gismodels.GeoManager()
)
champGeo = geomodels.PointField(verbose_name=_("Lieu"))
zoom = models.FloatField(verbose_name=_("Zoom de la carte"), null=False, default=17)
numday = models.IntegerField(verbose_name=_("Jour de la semaine"),null=False, choices=JOURS)
numweek = models.IntegerField(verbose_name=_("nième semaine du mois"),null=False, validators=[pas_de_zero, pas_plus_de_cinq], max_length=1)
objects = geomodels.GeoManager()
def __unicode__ (self):
return self.nom
class Meta:
verbose_name=u"Ville (ou lieu) de l'évènement"
verbose_name_plural=u"Villes (ou lieux) des évènements"
verbose_name=_("Ville (ou lieu) de l'évènement")
verbose_name_plural=_("Villes (ou lieux) des évènements")
# -- inscrits
class Inscrits(models.Model):
unique = models.CharField(verbose_name=u"Numéro unique d'inscription", max_length=32, unique=True, null=False)
nom = models.CharField(verbose_name=u"Nom de l'inscrit", max_length=40, null=False)
prenom = models.CharField(verbose_name=u"Prénom de l'inscrit", max_length=40, null=False)
asso = models.CharField(verbose_name=u"Association", max_length=150, null=False)
verif = models.CharField(verbose_name=u"Anti-spam : indiquer en lettres minuscules, la somme de deux et deux (ça fait 4)", max_length=10, null=False)
courriel = models.CharField(verbose_name=u"Adresse de courriel de l'inscrit", max_length=40, null=False)
nb = models.IntegerField(verbose_name=u"Nombre d'inscrits",validators=[pas_plus_de_cinq], default=1)
num = models.CharField(verbose_name=u"Numéro du rendez-vous correspondant à la date AAAAMMJJ", max_length=8, null=False)
#ville = models.CharField(verbose_name=u"Code de la vile (mais il faudrait une liaison là !", max_length=10)
unique = models.CharField(verbose_name=_("Numéro unique d'inscription"), max_length=32, unique=True, null=False)
nom = models.CharField(verbose_name=_("Nom de l'inscrit"), max_length=40, null=False)
prenom = models.CharField(verbose_name=_("Prénom de l'inscrit"), max_length=40, null=False)
asso = models.CharField(verbose_name=_("Association"), max_length=150, null=False)
verif = models.CharField(verbose_name=_("Anti-spam : indiquer en lettres minuscules, la somme de deux et deux (ça fait 4)"), max_length=10, null=False)
courriel = models.CharField(verbose_name=_("Adresse de courriel de l'inscrit"), max_length=40, null=False)
nb = models.IntegerField(verbose_name=_("Nombre d'inscrits"),validators=[pas_plus_de_cinq], default=1)
num = models.CharField(verbose_name=_("Numéro du rendez-vous correspondant à la date AAAAMMJJ"), max_length=8, null=False)
ville = models.ForeignKey('Ville')
ip = models.CharField(verbose_name=u"Adresse IP (voir IPAdressField ??)", max_length=40)
ip = models.CharField(verbose_name=_("Adresse IP"), max_length=40)
def __unicode__ (self):
return self.nom
class Meta:
verbose_name=u"Inscription"
verbose_name_plural=u"Inscriptions"
verbose_name=_("Inscription")
verbose_name_plural=_("Inscriptions")
......@@ -20,6 +20,8 @@ from datetime import *
import locale, time
locale.setlocale(locale.LC_TIME, "fr_FR.utf8")
# Filtrage par date
import datetime
# Envoi de courriels
from django.core.mail import send_mail
......@@ -39,12 +41,23 @@ from fj.models import Ville, Inscrits
from fj.forms import InscritsForm
from django.utils.translation import gettext_lazy as _
from ponctu.models import Rencontre
class ListeVilles(ListView):
model = Ville
context_object_name= "liste_villes" # url.py
template_name = "fj/index.html"
#class ListeVilles(ListView):
# model = Ville
# context_object_name= "liste_villes" # url.py
# template_name = "fj/index.html"
def liste_villes(request):
# La liste des villes
liste_villes = Ville.objects.all()
# La liste des rencontres ponctuelles
liste_rencontres = Rencontre.objects.filter(date__gte = datetime.datetime.now())
# Le gabartit
return render(request, 'fj/index.html', locals())
# ------- Page d'inscription ----------------
def inscription(request, code):
......@@ -151,6 +164,9 @@ def inscription(request, code):
# La liste des villes
liste_villes = Ville.objects.all()
# La liste des rencontres ponctuelles
liste_rencontres = Rencontre.objects.filter(date__gte = datetime.datetime.now())
# La liste des inscrits
liste_inscrits = Inscrits.objects.filter(ville_id=ville.id, num=court)
total = 0
......
{% extends "openlayers.html" %}
{% block openlayers %}{% include "gis/admin/openlayers_extralayers.js" %}{% endblock %}
{% extends "gis/admin/openlayers.js" %}
{% block extra_layers %}
topo_layer = new OpenLayers.Layer.OSM( "Simple OSM Map" );
{{ module }}.map.addLayer(topo_layer);
{% endblock extra_layers %}
{% extends "gis/admin/openlayers.js" %}
{% block extra_layers %}
topo_layer = new OpenLayers.Layer.WMS( "USA Topo", "http://terraservice.net/ogcmap.ashx", {layers: 'DRG'} );
{{ module }}.map.addLayer(topo_layer);
nexrad_layer = new OpenLayers.Layer.WMS( "NEXRAD", "http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi?", {layers:"nexrad-n0r",transparent:"true",format:'image/png'} );
{{ module }}.map.addLayer(nexrad_layer);
{% endblock extra_layers %}
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Firstjeudy\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-07-08 21:30+0200\n"
"POT-Creation-Date: 2014-07-09 19:49+0200\n"
"PO-Revision-Date: 2014-07-28 20:59+0200\n"
"Last-Translator: N. Grandjean <nicolas@microniko.net>\n"
"Language-Team: \n"
......@@ -21,7 +21,7 @@ msgstr ""
msgid "Français"
msgstr ""
#: firstjeudy/settings-dist.py:102 firstjeudy/settings.py:99
#: firstjeudy/settings.py:99
msgid "Anglais"
msgstr ""
......@@ -29,6 +29,11 @@ msgstr ""
msgid "Vous ne pouvez pas mettre zéro !"
msgstr ""
#: fj/models.py:22
#, python-format
msgid "C'est un peu trop, %s, non ?!"
msgstr ""
#: templates/fj/base.html:29
msgid "est maintenu par"
msgstr ""
......
#-*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.gis import admin as geoadmin
# Register your models here.
from ponctu.models import Rencontre, Inscrits
admin.site.register(Rencontre, geoadmin.OSMGeoAdmin)
# Inscriptions
class InscritsAdmin (admin.ModelAdmin):
list_display = ('prenom', 'nom', 'nb', 'asso', 'rencontre', 'ip')
list_filter = ('asso', 'rencontre',)
admin.site.register(Inscrits, InscritsAdmin)
# -*- coding: utf-8 -*-
#
# forms.py
#
# Copyright 2014 Nicolas Grandjean <nicolas@microniko.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#
from django import forms
from models import Inscrits
from django.utils.translation import gettext_lazy as _
class InscritsForm(forms.ModelForm):
class Meta:
model = Inscrits
fields = ('nom', 'prenom', 'asso', 'courriel', 'nb', 'verif')
def clean_verif(self):
verif = self.cleaned_data['verif']
if verif!=u"six":
raise forms.ValidationError(_("Désolé !"))
return verif
#-*- coding: utf-8 -*-
from django.db import models
# Create your models here.
# Zones de texte avec du Wysiwyg
from redactor.fields import RedactorField
# Create your models here.
from django.contrib.gis.db import models as geomodels
#from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
# Description de la base de données
#
def pas_plus_de_cinq(value):
if value > 5:
raise ValidationError(_("C'est un peu trop, %s, non ?!") % value)
# --- Rencontre
class Rencontre(models.Model):
code = models.CharField(verbose_name=_("Raccourci (utilisé dans les URL)"), max_length =10, unique=True, null=False)
nom = models.CharField(verbose_name=_("Nom complet"), max_length=30, unique=True, null=False)
message = RedactorField(
verbose_name=_("Message long (apparaît sur la page de la Recontre)"),
allow_file_upload=False,
allow_image_upload=False,
)
description = RedactorField(
verbose_name=_("Message plus court (apparaît sur le résumé)"),
allow_file_upload=False,
allow_image_upload=False,
)
champGeo = geomodels.PointField(verbose_name=_("Lieu"), null=True, )
zoom = models.FloatField(verbose_name=_("Zoom de la carte"), null=False, default=17)
date = models.DateField(verbose_name=_("Date"),help_text=_('Saisissez donc la date !'), null=False)
objects = geomodels.GeoManager()
def __unicode__ (self):
return self.nom
class Meta:
verbose_name=_("Recontre ponctuelle")
verbose_name_plural=_("Recontres ponctuelles")
# -- inscrits
class Inscrits(models.Model):
unique = models.CharField(verbose_name=_("Numéro unique d'inscription"), max_length=32, unique=True, null=False)
nom = models.CharField(verbose_name=_("Nom de l'inscrit"), max_length=40, null=False)
prenom = models.CharField(verbose_name=_("Prénom de l'inscrit"), max_length=40, null=False)
asso = models.CharField(verbose_name=_("Association"), max_length=150, null=False)
verif = models.CharField(verbose_name=_("Anti-spam : indiquer en lettres minuscules, la somme de quatre et deux (ça fait 6)"), max_length=10, null=False)
courriel = models.CharField(verbose_name=_("Adresse de courriel de l'inscrit"), max_length=40, null=False)
nb = models.IntegerField(verbose_name=_("Nombre d'inscrits"),validators=[pas_plus_de_cinq], default=1)
rencontre = models.ForeignKey('Rencontre')
ip = models.CharField(verbose_name=_("Adresse IP"), max_length=40)
def __unicode__ (self):
return self.nom
class Meta:
verbose_name=_("Inscription")
verbose_name_plural=_("Inscriptions")
#-*- coding: utf-8 -*-
from django.test import TestCase
# Create your tests here.
#-*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import Http404
from django.shortcuts import render, get_object_or_404
import uuid
from django import http
from django.views.generic import ListView, DeleteView
from django.core.urlresolvers import reverse_lazy
from django.contrib.gis.geos import Point
# Import de bidules pour le calcul de date
#from dateutil.rrule import *
#from dateutil.parser import *
#from datetime import *
# dates en français
import locale, time
locale.setlocale(locale.LC_TIME, "fr_FR.utf8")
# Filtrage par date
import datetime
# Envoi de courriels
from django.core.mail import send_mail
# Create your views here.
from ponctu.models import Rencontre, Inscrits
from ponctu.forms import InscritsForm
from django.utils.translation import gettext_lazy as _
from fj.models import Ville
#class ListeRencontres(ListView):
# model = Rencontres
# context_object_name= "liste_rencontres" # url.py
# template_name = "ponctu/index.html"
# ------- Page d'inscription ----------------
def inscription(request, code):
"""Afficher la page d'inscription des rencontres ponctuelles
- D'abord, sa description
- Ensuite le formulaire d'inscription
- Puis le menu
- Et enfin, la liste des inscrits
"""
# Pour la description de la ville :
rencontre = get_object_or_404(Rencontre, code=code, date__gte=datetime.date.today())
# jour = foo.strftime('%A %d %B %Y').capitalize()
# court = foo.strftime("%Y%m%d")
# humain = str(foo.strftime('%A %d %B %Y')).decode("utf-8")
#humain = foo.strftime("%d/%m/%Y")
# traitements
zoom = str(rencontre.zoom).replace(',','.',1)
latlong = str(rencontre.champGeo).split(' ')
lon = latlong[1].replace('(','')
lat = latlong[2].replace(')','')
# Le formulaire d'inscription
if request.method== 'POST':
form = InscritsForm(request.POST)
if form.is_valid():
unique=str(uuid.uuid4())
adresse_ip =request.META["REMOTE_ADDR"]
url_fj =request.META["SERVER_NAME"]
# Est-ce une IPv6 ?
longueur = len(adresse_ip)
i=0
v6=""
while i < longueur:
if adresse_ip[i] == ":":
v6= u"IPv6 :-)"
i = i + 1
# Sauvegarde en base
Inscrits(
nom=form.cleaned_data['nom'],
prenom=form.cleaned_data['prenom'],
asso=form.cleaned_data['asso'],
courriel=form.cleaned_data['courriel'],
nb=form.cleaned_data['nb'],
unique=unique,
rencontre_id=rencontre.id,
ip=adresse_ip
).save()
# Envoi d'un courriel
send_mail(
u'Rencontre ' + rencontre.nom +' du ' + str(rencontre.date.strftime('%A %d %B %Y')).decode("utf-8"),
u'Bonjour ' + form.cleaned_data['prenom'] + ' ' + form.cleaned_data['nom'] + u'.\n\n'
u'Vous venez de vous inscrire a pour '+ rencontre.code + u' : \n'
u'- Ville : ' + rencontre.nom + u'\n' +
u'- Date : '+ str(rencontre.date.strftime('%A %d %B %Y')).decode("utf-8") + u'\n' +
u'- Adresse IP : ' + adresse_ip + " " + v6 + u'\n\n'
u'Pour annuler votre inscription, vous pouvez cliquer sur le lien suivant : \n http://' + url_fj + '/r/del/' +unique+ u'' ,
'contact@firstjeudi.org',
[form.cleaned_data['courriel']],
fail_silently=False
)
ok = True
else:
form=InscritsForm()
# La liste des recontres
liste_rencontres = Rencontre.objects.filter(date__gte = datetime.datetime.now())
# La liste des villes
liste_villes = Ville.objects.all()
# La liste des inscrits
liste_inscrits = Inscrits.objects.filter(rencontre_id=rencontre.id)
total = 0
for insc in liste_inscrits:
total = total + insc.nb
# Le gabartit
return render(request, 'ponctu/rencontre.html', locals())
# ------- Page de suppression ----------------
class InscritsDeletePonctu(DeleteView):
model = Inscrits
context_object_name = "supprime_inscrit"
template_name = 'ponctu/del.html'
success_url = reverse_lazy('index')
supprime = True
def get_object(self, queryset=None):
unique = self.kwargs.get('unique', None)
return get_object_or_404(Inscrits, unique=unique)
# ------- Page des statistiques ----------------
......@@ -26,9 +26,9 @@
<footer>
<p><em>Firstjeudi</em> {% trans "est maintenu par" %}<a
href="http://www.rhizomes.org">Rhizomes</a> {% trans "sur les serveurs de" %}<a
href="http://www.microniko.net">Microniko.net</a>{% trans " avec" %}<a
<p><em>Firstjeudi</em> {% trans "est maintenu par" %} <a
href="http://www.rhizomes.org">Rhizomes</a> {% trans "sur les serveurs de" %} <a
href="http://www.microniko.net">Microniko.net</a>{% trans " avec" %} <a
href="http://www.debian.org/">Debian GNU/Linux</a>. {% trans "Fonctionne avec Python et une base SQLite/Spacialite." %} <a href="https://gitlab.com/microniko/firstjeudy/">{% trans "Sources sur Gitlab" %}</a>
</p>
{% now "DATETIME_FORMAT" %}
......
......@@ -9,19 +9,34 @@
{% block content %}
<div class="wrapper">
{% for ville in liste_villes %}
{% for ville in liste_villes %}
<div class="grey">
<h2>{{ ville.nom }} </h2>
<p>{{ ville.description|safe}}</p>
<p class="date">{{ ville.numweek }}<sup>e</sup>
{% if ville.numday == 0 %} dimanche
{% elif ville.numday == 1 %} lundi
{% elif ville.numday == 2 %} mardi
{% elif ville.numday == 3 %} mercredi
{% elif ville.numday == 4 %} jeudi
{% elif ville.numday == 5 %} vendredi
{% elif ville.numday == 6 %} samedi
{% endif %} du mois</p>
<p class="inscription"><a href="{{ ville.code }}">{% trans "Inscription" %}</a></p>
</div>
{% empty %}
<p>{% trans "Il n'y a rien pour l'instant !" %}</p>
{% endfor %}
{% empty %}
<p>{% trans "Il n'y a rien pour l'instant !" %}</p>
{% endfor %}
{% for rencontre in liste_rencontres %}
<div class="grey">
<h2>{{ rencontre.nom }} </h2>
<p> {{ rencontre.description|safe}}</p>
<p class="date">{{ rencontre.date|date:"l d F Y"|capfirst }}</p>
<p class="inscription"><a href="/r/{{ rencontre.code }}">{% trans "Inscription" %}</a></p>
</div>
{% endfor %}
</div>
......@@ -29,7 +44,7 @@
<h4>{% trans "Vous aussi" %}</h4>
<p>{% trans "N'hésitez-pas à nous contactez si vous souhaitez qu'une de vos rencontres régulières apparaisse ici !" %}</p>
<h4>{% trans "Cr&eacute;dits" %}</h4>
<p>{% trans "Ce script sous GPL est la version Django/Python de Firstjeudi initialement en PHP (sous licence GPL initi&eacute; par&nbsp;: Fabien Seisen en 2001, Rodolphe Qui&eacute;deville en 2002. Adapt&eacute; en 2011 et 2012 par Nicolas Grandjean)." %}</p>
<p>{% trans "Ce script sous GPL est la version Django/Python de Firstjeudi initialement en PHP (sous licence GPL initi&eacute; par&nbsp;: Fabien Seisen en 2001, Rodolphe Qui&eacute;deville en 2002 puis adapt&eacute; en 2011 et 2012 par Nicolas Grandjean)." %}</p>
<p>{% trans " Si vous avez des questions ... mailto:contact &Agrave; rhizomes.org" %}</p>
<p>
......
......@@ -16,6 +16,11 @@
</li>
{% endfor %}
</ul>
<ul>
{% for une_rencontre in liste_rencontres %}
<li><a href='/r/{{ une_rencontre.code }}'>{{ une_rencontre.nom }}</a></li>
{% endfor %}
</ul>
</nav>
{% endblock %}
......
{% load i18n %}
{% load static %}
<!DOCTYPE html>
<html{% block classHTML %}{% endblock %}>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="{% static 'styles.css' %}" />
<link rel="shortcut icon" type="image/png" href="{% static 'favicon.ico' %}" />
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
<title>{% block title %}Bienvenue sur Firstjeudi !{% endblock %}</title>
</head>
<body>
<header>{% block header %} En-tête ... {% endblock %}</header>
<nav>
{% block nav %}
{% endblock %}
</nav>
<section id="content">
{% block content %}{% endblock %}
</section>
<footer>
<p><em>Firstjeudi</em> {% trans "est maintenu par" %} <a
href="http://www.rhizomes.org">Rhizomes</a> {% trans "sur les serveurs de" %} <a
href="http://www.microniko.net">Microniko.net</a>{% trans " avec" %} <a
href="http://www.debian.org/">Debian GNU/Linux</a>. {% trans "Fonctionne avec Python et une base SQLite/Spacialite." %} <a href="https://gitlab.com/microniko/firstjeudy/">{% trans "Sources sur Gitlab" %}</a>
</p>
{% now "DATETIME_FORMAT" %}
</footer>
</body>
</html>
{% extends "ponctu/base.html" %}
{% load i18n %}
{% block header %}
<h1>{{ rencontre.date|date:"l d F Y"|capfirst }}</h1>
{% endblock %}
{% block nav %}
<nav id="menu">
<ul>
<li><a href="/">{% trans "Accueil" %}</a></li>
{% for une_ville in liste_villes %}
<li><a href='{{ une_ville.code }}'>{{ une_ville.nom }}</a></li>
{% endfor %}
</ul>
<ul>
{% for une_rencontre in liste_rencontres %}
<li{% if une_rencontre.code = rencontre.code %} class="actif"{% endif %}>
<a href='{{ une_rencontre.code }}'>{{ une_rencontre.nom }}</a>
</li>
{% endfor %}
</ul>
</nav>
{% endblock %}
{% block content %}
<div id="milieu">
<p class="infos">{% trans "Confirmez-vous la suppression de votre inscription ?" %}</p>
<form method="post" action="">
{% csrf_token %}
<input type="submit" value"{% trans "Oui, je ne viens pas" %}" />
- <a href="{% url "index" %}">{% trans "Si, si je viens !" %}</a>
</form>
</div>