From 20a67eddc2b35ed31615373e53d79a73c90e2857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89lie=20Bouttier?= Date: Fri, 6 Oct 2017 01:33:57 +0200 Subject: [PATCH] implementing volunteers enrollment --- cfp/admin.py | 12 +- cfp/forms.py | 32 ++- cfp/migrations/0011_auto_20171005_2328.py | 78 ++++++ cfp/models.py | 79 ++++-- cfp/signals.py | 3 +- cfp/templates/cfp/volunteer.html | 29 +++ cfp/templates/cfp/volunteer_enrole.html | 36 +++ cfp/urls.py | 4 + cfp/views.py | 45 +++- locale/fr/LC_MESSAGES/django.mo | Bin 13949 -> 14665 bytes locale/fr/LC_MESSAGES/django.po | 277 ++++++++++++---------- ponyconf/templates/base.html | 3 + 12 files changed, 449 insertions(+), 149 deletions(-) create mode 100644 cfp/migrations/0011_auto_20171005_2328.py create mode 100644 cfp/templates/cfp/volunteer.html create mode 100644 cfp/templates/cfp/volunteer_enrole.html diff --git a/cfp/admin.py b/cfp/admin.py index c01570f..adadfab 100644 --- a/cfp/admin.py +++ b/cfp/admin.py @@ -2,7 +2,7 @@ from django.contrib import admin from django.contrib.sites.models import Site from .mixins import OnSiteAdminMixin -from .models import Conference, Participant, Talk, TalkCategory, Track, Vote +from .models import Conference, Participant, Talk, TalkCategory, Track, Vote, Volunteer, Activity class ConferenceAdmin(OnSiteAdminMixin, admin.ModelAdmin): @@ -41,8 +41,18 @@ class VoteAdmin(admin.ModelAdmin): return super().get_queryset(request).filter(talk__site=request.conference.site) +class VolunteerAdmin(OnSiteAdminMixin, admin.ModelAdmin): + pass + + +class ActivityAdmin(OnSiteAdminMixin, admin.ModelAdmin): + pass + + admin.site.register(Conference, ConferenceAdmin) admin.site.register(Participant, ParticipantAdmin) admin.site.register(Talk, TalkAdmin) admin.site.register(TalkCategory, TalkCategoryAdmin) admin.site.register(Vote, VoteAdmin) +admin.site.register(Volunteer, VolunteerAdmin) +admin.site.register(Activity, ActivityAdmin) diff --git a/cfp/forms.py b/cfp/forms.py index 0ea6d62..125cf1b 100644 --- a/cfp/forms.py +++ b/cfp/forms.py @@ -9,7 +9,7 @@ from django.utils.crypto import get_random_string from django_select2.forms import ModelSelect2MultipleWidget -from .models import Participant, Talk, TalkCategory, Track, Conference, Room +from .models import Participant, Talk, TalkCategory, Track, Conference, Room, Volunteer STATUS_CHOICES = [ @@ -175,7 +175,10 @@ class UsersWidget(ModelSelect2MultipleWidget): class ConferenceForm(forms.ModelForm): class Meta: model = Conference - fields = ['name', 'home', 'venue', 'city', 'contact_email', 'schedule_publishing_date', 'reply_email', 'secure_domain', 'staff',] + fields = [ + 'name', 'home', 'venue', 'city', 'contact_email', 'schedule_publishing_date', + 'volunteers_opening_date', 'volunteers_closing_date', 'reply_email', 'secure_domain', 'staff', + ] widgets = { 'staff': UsersWidget(), } @@ -248,3 +251,28 @@ class RoomForm(OnSiteNamedModelForm): class Meta: model = Room fields = ['name', 'label', 'capacity'] + + +class VolunteerForm(forms.ModelForm): + def __init__(self, *args, **kwargs): + self.conference = kwargs.pop('conference') + super().__init__(*args, **kwargs) + + # we should manually check (site, email) uniqueness as the site is not part of the form + def clean_email(self): + email = self.cleaned_data['email'] + if (not self.instance or self.instance.email != email) \ + and self._meta.model.objects.filter(site=self.conference.site, email=email).exists(): + raise self.instance.unique_error_message(self._meta.model, ['email']) + return email + + def save(self, commit=True): + obj = super().save(commit=False) + obj.site = self.conference.site + if commit: + obj.save() + return obj + + class Meta: + model = Volunteer + fields = ['name', 'email', 'phone_number', 'notes'] diff --git a/cfp/migrations/0011_auto_20171005_2328.py b/cfp/migrations/0011_auto_20171005_2328.py new file mode 100644 index 0000000..7e28547 --- /dev/null +++ b/cfp/migrations/0011_auto_20171005_2328.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.5 on 2017-10-05 23:28 +from __future__ import unicode_literals + +import autoslug.fields +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('mailing', '0002_message_author'), + ('sites', '0002_alter_domain_unique'), + ('cfp', '0010_auto_20170927_1820'), + ] + + operations = [ + migrations.CreateModel( + name='Activity', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=256, verbose_name='Name')), + ('slug', autoslug.fields.AutoSlugField(editable=False, populate_from='name')), + ('description', models.TextField(blank=True, verbose_name='Description')), + ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ], + options={ + 'verbose_name': 'Activity', + 'verbose_name_plural': 'Activities', + }, + ), + migrations.CreateModel( + name='Volunteer', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=128, verbose_name='Your Name')), + ('email', models.EmailField(max_length=254)), + ('token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)), + ('phone_number', models.CharField(blank=True, default='', max_length=64, verbose_name='Phone number')), + ('language', models.CharField(blank=True, max_length=10)), + ('notes', models.TextField(blank=True, default='', help_text='If you have some constraints, you can indicate them here.', verbose_name='Notes')), + ('conversation', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='mailing.MessageThread')), + ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sites.Site')), + ], + ), + migrations.AddField( + model_name='conference', + name='volunteers_closing_date', + field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='Volunteers enrollment closing date'), + ), + migrations.AddField( + model_name='conference', + name='volunteers_opening_date', + field=models.DateTimeField(blank=True, default=None, null=True, verbose_name='Volunteers enrollment opening date'), + ), + migrations.AlterField( + model_name='talk', + name='description', + field=models.TextField(help_text='This field is only visible by organizers.', verbose_name='Description of your talk'), + ), + migrations.AddField( + model_name='activity', + name='volunteers', + field=models.ManyToManyField(blank=True, related_name='activities', to='cfp.Volunteer', verbose_name='Volunteer'), + ), + migrations.AlterUniqueTogether( + name='volunteer', + unique_together=set([('site', 'email')]), + ), + migrations.AlterUniqueTogether( + name='activity', + unique_together=set([('site', 'name')]), + ), + ] diff --git a/cfp/models.py b/cfp/models.py index 3861f28..2f57337 100644 --- a/cfp/models.py +++ b/cfp/models.py @@ -22,8 +22,8 @@ from mailing.models import MessageThread class Conference(models.Model): - site = models.OneToOneField(Site, on_delete=models.CASCADE) + name = models.CharField(blank=True, max_length=100, verbose_name=_('Conference name')) home = models.TextField(blank=True, default="", verbose_name=_('Homepage (markdown)')) venue = models.TextField(blank=True, default="", verbose_name=_('Venue information')) @@ -33,6 +33,8 @@ class Conference(models.Model): staff = models.ManyToManyField(User, blank=True, verbose_name=_('Staff members')) secure_domain = models.BooleanField(default=True, verbose_name=_('Secure domain (HTTPS)')) schedule_publishing_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Schedule publishing date')) + volunteers_opening_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Volunteers enrollment opening date')) + volunteers_closing_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Volunteers enrollment closing date')) custom_css = models.TextField(blank=True) external_css_link = models.URLField(blank=True) @@ -43,6 +45,12 @@ class Conference(models.Model): # events = Event.objects.filter(site=self.site) # return any(map(lambda x: x.is_open(), events)) + def volunteers_enrollment_is_open(self): + now = timezone.now() + opening = self.volunteers_opening_date + closing = self.volunteers_closing_date + return opening and opening < now and (not closing or closing > now) + @property def opened_categories(self): now = timezone.now() @@ -83,30 +91,22 @@ class ParticipantManager(models.Manager): class Participant(PonyConfModel): - site = models.ForeignKey(Site, on_delete=models.CASCADE) - name = models.CharField(max_length=128, verbose_name=_('Your Name')) email = models.EmailField() - biography = models.TextField(verbose_name=_('Biography')) token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) - twitter = models.CharField(max_length=100, blank=True, default='', verbose_name=_('Twitter')) linkedin = models.CharField(max_length=100, blank=True, default='', verbose_name=_('LinkedIn')) github = models.CharField(max_length=100, blank=True, default='', verbose_name=_('Github')) website = models.CharField(max_length=100, blank=True, default='', verbose_name=_('Website')) facebook = models.CharField(max_length=100, blank=True, default='', verbose_name=_('Facebook')) mastodon = models.CharField(max_length=100, blank=True, default='', verbose_name=_('Mastodon')) - phone_number = models.CharField(max_length=64, blank=True, default='', verbose_name=_('Phone number')) - language = models.CharField(max_length=10, blank=True) - - notes = models.TextField(default='', blank=True, verbose_name=_("Notes"), help_text=_('This field is only visible by organizers.')) - + notes = models.TextField(default='', blank=True, verbose_name=_("Notes"), + help_text=_('This field is only visible by organizers.')) vip = models.BooleanField(default=False) - conversation = models.OneToOneField(MessageThread) objects = ParticipantManager() @@ -133,9 +133,7 @@ class Participant(PonyConfModel): class Track(PonyConfModel): - site = models.ForeignKey(Site, on_delete=models.CASCADE) - name = models.CharField(max_length=128, verbose_name=_('Name')) slug = AutoSlugField(populate_from='name') description = models.TextField(blank=True, verbose_name=_('Description')) @@ -156,10 +154,9 @@ class Track(PonyConfModel): class Room(models.Model): - site = models.ForeignKey(Site, on_delete=models.CASCADE) - slug = AutoSlugField(populate_from='name') name = models.CharField(max_length=256, blank=True, default="") + slug = AutoSlugField(populate_from='name') label = models.CharField(max_length=256, blank=True, default="") capacity = models.IntegerField(default=0) @@ -187,7 +184,6 @@ class Room(models.Model): class TalkCategory(models.Model): # type of talk (conf 30min, 1h, stand, …) - site = models.ForeignKey(Site, on_delete=models.CASCADE) name = models.CharField(max_length=64) duration = models.PositiveIntegerField(default=0, verbose_name=_('Default duration (min)')) @@ -252,7 +248,6 @@ def talks_materials_destination(talk, filename): class Talk(PonyConfModel): - LICENCES = ( ('CC-Zero CC-BY', 'CC-Zero CC-BY'), ('CC-BY-SA', 'CC-BY-SA'), @@ -268,12 +263,17 @@ class Talk(PonyConfModel): title = models.CharField(max_length=128, verbose_name=_('Talk Title')) slug = AutoSlugField(populate_from='title', unique=True) #abstract = models.CharField(max_length=255, blank=True, verbose_name=_('Abstract')) - description = models.TextField(verbose_name=_('Description of your talk')) + description = models.TextField(verbose_name=_('Description of your talk'), + help_text=_('This field is only visible by organizers.')) track = models.ForeignKey(Track, blank=True, null=True, verbose_name=_('Track')) - notes = models.TextField(blank=True, verbose_name=_('Message to organizers'), help_text=_('If you have any constraint or if you have anything that may help you to select your talk, like a video or slides of your talk, please write it down here')) + notes = models.TextField(blank=True, verbose_name=_('Message to organizers'), + help_text=_('If you have any constraint or if you have anything that may ' + 'help you to select your talk, like a video or slides of your' + ' talk, please write it down here')) category = models.ForeignKey(TalkCategory, verbose_name=_('Talk Category')) videotaped = models.BooleanField(_("I'm ok to be recorded on video"), default=True) - video_licence = models.CharField(choices=LICENCES, default='CC-BY-SA', max_length=10, verbose_name=_("Video licence")) + video_licence = models.CharField(choices=LICENCES, default='CC-BY-SA', + max_length=10, verbose_name=_("Video licence")) sound = models.BooleanField(_("I need sound"), default=False) accepted = models.NullBooleanField(default=None) start_date = models.DateTimeField(null=True, blank=True, default=None, verbose_name=_('Beginning date and time')) @@ -330,7 +330,6 @@ class Talk(PonyConfModel): class Vote(PonyConfModel): - talk = models.ForeignKey(Talk) user = models.ForeignKey(User) vote = models.IntegerField(validators=[MinValueValidator(-2), MaxValueValidator(2)], default=0) @@ -343,3 +342,41 @@ class Vote(PonyConfModel): def get_absolute_url(self): return self.talk.get_absolute_url() + + +class Volunteer(PonyConfModel): + site = models.ForeignKey(Site, on_delete=models.CASCADE) + name = models.CharField(max_length=128, verbose_name=_('Your Name')) + email = models.EmailField() + token = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) + phone_number = models.CharField(max_length=64, blank=True, default='', verbose_name=_('Phone number')) + language = models.CharField(max_length=10, blank=True) + notes = models.TextField(default='', blank=True, verbose_name=_('Notes'), + help_text=_('If you have some constraints, you can indicate them here.')) + conversation = models.OneToOneField(MessageThread) + + def get_absolute_url(self): + return reverse('volunteer-details', kwargs={'volunteer_id': self.token}) + + class Meta: + # A volunteer can participe only once to a Conference (= Site) + unique_together = ('site', 'email') + + def __str__(self): + return str(self.name) + + +class Activity(models.Model): + site = models.ForeignKey(Site, on_delete=models.CASCADE) + name = models.CharField(max_length=256, verbose_name=_('Name')) + slug = AutoSlugField(populate_from='name') + description = models.TextField(blank=True, verbose_name=_('Description')) + volunteers = models.ManyToManyField(Volunteer, blank=True, related_name='activities', verbose_name=_('Volunteer')) + + class Meta: + unique_together = ('site', 'name') + verbose_name = _('Activity') + verbose_name_plural = _('Activities') + + def __str__(self): + return self.name diff --git a/cfp/signals.py b/cfp/signals.py index 1675b8f..77e1426 100644 --- a/cfp/signals.py +++ b/cfp/signals.py @@ -8,7 +8,7 @@ from django.core.urlresolvers import reverse from ponyconf.decorators import disable_for_loaddata from mailing.models import MessageThread, Message -from .models import Participant, Talk, Conference +from .models import Participant, Talk, Conference, Volunteer @receiver(post_save, sender=Site, dispatch_uid="Create Conference for Site") @@ -22,6 +22,7 @@ def create_conversation(sender, instance, **kwargs): instance.conversation = MessageThread.objects.create() pre_save.connect(create_conversation, sender=Participant) pre_save.connect(create_conversation, sender=Talk) +pre_save.connect(create_conversation, sender=Volunteer) @receiver(pre_save, sender=Message, dispatch_uid="Set message author") diff --git a/cfp/templates/cfp/volunteer.html b/cfp/templates/cfp/volunteer.html new file mode 100644 index 0000000..572e3ed --- /dev/null +++ b/cfp/templates/cfp/volunteer.html @@ -0,0 +1,29 @@ +{% extends 'base.html' %} + +{% load i18n %} + +{% block volunteerstab %} class="active"{% endblock %} + +{% block content %} + +

{% trans "Become a volunteers!" %}

+ +{% for activity in activities %} +{% if forloop.first %}
{% endif %} +
+

{{ activity.name }}

+

+

{{ activity.description }}

+

+ {% if volunteer not in activity.volunteers.all %} + {% trans "I will be happy to help on that!" %} + {% else %} + {% trans "Sorry, I have a setback" %} + {% endif %} +

+

+
+{% if forloop.last %}
{% endif %} +{% endfor %} + +{% endblock %} diff --git a/cfp/templates/cfp/volunteer_enrole.html b/cfp/templates/cfp/volunteer_enrole.html new file mode 100644 index 0000000..86e69a3 --- /dev/null +++ b/cfp/templates/cfp/volunteer_enrole.html @@ -0,0 +1,36 @@ +{% extends 'base.html' %} + +{% load i18n %} + +{% block volunteerstab %} class="active"{% endblock %} + +{% block content %} + +

{% trans "Become a volunteers!" %}

+ +

+{% blocktrans %}We need you! To participate, please enter your name and e-mail.{% endblocktrans %} +

+ +{% include '_form.html' %} + + +{% for activity in activities %} +{% if forloop.first %} +
+
+{% blocktrans %}We are looking for help with the following activities:{% endblocktrans %} +
+ +
+{% endif %} +{% endfor %} + +{% endblock %} diff --git a/cfp/urls.py b/cfp/urls.py index a2aadf6..e2e2978 100644 --- a/cfp/urls.py +++ b/cfp/urls.py @@ -8,6 +8,10 @@ urlpatterns = [ url(r'^cfp/(?P[\w\-]+)/speaker/add/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-add'), url(r'^cfp/(?P[\w\-]+)/speaker/(?P[\w\-]+)/$', views.talk_proposal_speaker_edit, name='talk-proposal-speaker-edit'), url(r'^cfp/(?P[\w\-]+)/(?P[\w\-]+)/$', views.talk_proposal, name='talk-proposal-edit'), + url(r'^volunteer/$', views.volunteer_enrole, name='volunteer-enrole'), + url(r'^volunteer/(?P[\w\-]+)/$', views.volunteer, name='volunteer'), + url(r'^volunteer/(?P[\w\-]+)/join/(?P[\w\-]+)/$', views.volunteer_activity, {'join': True}, name='volunteer-join'), + url(r'^volunteer/(?P[\w\-]+)/quit/(?P[\w\-]+)/$', views.volunteer_activity, {'join': False}, name='volunteer-quit'), url(r'^staff/$', views.staff, name='staff'), url(r'^staff/conference/$', views.conference, name='conference'), url(r'^staff/talks/$', views.talk_list, name='talk-list'), diff --git a/cfp/views.py b/cfp/views.py index 91eee69..cb44e48 100644 --- a/cfp/views.py +++ b/cfp/views.py @@ -22,10 +22,11 @@ from .planning import Program from .decorators import staff_required from .mixins import StaffRequiredMixin, OnSiteMixin, OnSiteFormMixin from .utils import is_staff -from .models import Participant, Talk, TalkCategory, Vote, Track, Room +from .models import Participant, Talk, TalkCategory, Vote, Track, Room, Volunteer, Activity from .forms import TalkForm, TalkStaffForm, TalkFilterForm, TalkActionForm, \ ParticipantForm, ParticipantStaffForm, ParticipantFilterForm, \ - ConferenceForm, CreateUserForm, STATUS_VALUES, TrackForm, RoomForm + ConferenceForm, CreateUserForm, STATUS_VALUES, TrackForm, RoomForm, \ + VolunteerForm def home(request): @@ -35,6 +36,46 @@ def home(request): return redirect(reverse('talk-proposal')) +def volunteer_enrole(request): + if not request.conference.volunteers_enrollment_is_open(): + raise PermissionDenied + form = VolunteerForm(request.POST or None, conference=request.conference) + if request.method == 'POST' and form.is_valid(): + volunteer = form.save(commit=False) + volunteer.language = request.LANGUAGE_CODE + volunteer.save() + messages.success(request, _('Thank you for your participation! You can now subscribe to some activities.')) + return redirect(reverse('volunteer', kwargs=dict(volunteer_id=volunteer.token))) + return render(request, 'cfp/volunteer_enrole.html', { + 'activities': Activity.objects.filter(site=request.conference.site), + 'form': form, + }) + + +def volunteer(request, volunteer_id): + volunteer = get_object_or_404(Volunteer, token=volunteer_id, site=request.conference.site) + return render(request, 'cfp/volunteer.html', { + 'activities': Activity.objects.filter(site=request.conference.site), + 'volunteer': volunteer, + }) + + +def volunteer_activity(request, volunteer_id, activity, join): + if not request.conference.volunteers_enrollment_is_open(): + raise PermissionDenied + volunteer = get_object_or_404(Volunteer, token=volunteer_id, site=request.conference.site) + activity = get_object_or_404(Activity, slug=activity, site=request.conference.site) + if join: + activity.volunteers.add(volunteer) + activity.save() + messages.success(request, _('Thank you for your participation!')) + else: + activity.volunteers.remove(volunteer) + activity.save() + messages.success(request, _('Okay, no problem!')) + return redirect(reverse('volunteer', kwargs=dict(volunteer_id=volunteer.token))) + + def talk_proposal(request, talk_id=None, participant_id=None): conference = request.conference diff --git a/locale/fr/LC_MESSAGES/django.mo b/locale/fr/LC_MESSAGES/django.mo index f6e10fd9405ceffa8ea2603cf09b04cc91342049..a5be45e2d9a815eeeffbb2a8f6813565870f02a6 100644 GIT binary patch delta 5272 zcmai%dvsLA9mi)AA|QlUKpqO*5D2dj5)wcV1q1~pfFPhqwQM$5_R8kou#ZG2x)iFS zB2rg;6^m#sMx++EK2WQ)sh;X-salJ))Z(GG)p~4g@l@(5($9Byg89dG4&Quc=FXk@ zz2+vIjJ+05|DjK(?S|Hd&Ox(i|CO`VZKf?a-1ndfX z^)cowI0$01sfIG>T-XWDgq&qAhL^)DpbXsud%|a6G3T3C>FC9`;XwE<)PbMb`R=%@ zgZjZ?umZ}Xg>V2|0p)QLc7~gv47lCSZ-ZLD6SAe*17*NVu$c4BK{|Tz_fUqs59Q&< zP@a7TtKk=L6s*F!5pX#yg=ts;cR`kzgHWCygL3FN)IP=i^6U$B-q|o6rBg`Hi3(3b6xC3s0hoC&Yg0KvQ5vZEl1hvmYknEYgP$_?T z0P&ZluP`Bx4?#uXJv;u;E<6t9!N2Wuxux}8ElZ$kV=yd+6Cu8sS@!vIsN6@OBIZLm zx@{owpG9Xo6YOn%3uWm)p$<4@*>zBUz68oZ2kQA~sEupv^9!Inn+N6TBB+Q&pmH8S zIh=-UZMLbS10RR7{8^|Xd&MsJ0P27O?v9=pLv46Alm{cB4y>@_2~Y-3hH_{Il%dO^ z42VEQCIR(+`c^s(bhbiSbQ~%~#UxH49SVjPCk;eAks9ELLFJy?>a^C6u&coOQMOC4h-z$I`byakrQC!r$pYd8k}9gc&8 zh+`p~3$<|_EPzYx_)0qtLmAotWrzpUDyB7b6xti0BCy+z_d=!Q9jF&Rf!g4NkrPG)>1 z)Qj8T4ETWM5vcX&jL5UrvJUFN2FSO{1W*p#Z0EPaBF6WRApY`jCllAf=b$1|R-V5m z_hF_0#$Q&z=68|JLzbn{jeMS86QhGjA>Sn{PunwjjI?L$DfEK80xDl!*?tyw?AB@8NkQ-`- z@pa-Xb1~$bWm+JQ%)L-4dJXE}x1bz3412+kp$z!~YTu$7;;#=zaZNtgBVixL)1fw6 z3>~-vx^O+@*MvC+H^Ea-ACgVA`5M^;^}RR%_5KMcLqZet2X?mXY1w}w`Pagsc48D% zXsV!!Zz^=)VyMt3pghrRh|*k-zyB=nvP@aNY_3;^UwSM)uW4%$%J~Aq?NUc&;WEZQd^DA&-IMC0DcWA3AzgppeIlpQX8Fzc@XYG zDpw^&)iWJEiN1~0wxY{X65WBGZjZ~?89a}osJ%7Nxe7&)hg2l!66-bq}O#|C*fvTdhihiY?bm2NgMdj{h~M42f7rMqwk?XXbrj( zU57fhA2V2rGAL^wyZ~cpAUY3y2leLsT$|0$R`eWNiJn0_k=ku}m~TP-hEN-YUPL#c z-RM^I81hj9H6b-V48~E1b{}fV_4uy~45Rcz{OF3}sJ;D&PMIC(GQEU;Xvh8FEL4P^ zMVBGnmu0A9)18@tR-wJl<4G^#HHDL2;Fp>u(XhYzf30wq+hhHp z#Yv><6Op)A&)GrV!f+(%HG4_VO;l#<&RHDF>>fO8ky&=y!46%=_2WS-*68|4ClU)1 zp1;azz>lw35;VDf`;yE@gJ-5=L9kjAawY1N@l|7KG`>`Q=!aNHH%l7 z3r{wq+1Iw&DJ8QPDmRmz_AVVp39CTWo_WRpC0_~an_jAs<_n!B? zc`Nv>FY-zI7Ml#|1aUXfp_MTnk1^@#sx>Av)0jMLhpH;aEF6KYu?p|NYFnvkSr#?i4KuanVP-o?7%)l5j2lG37{Ug*_xPV%*E1g+??NuArXEckv5d=Q;qSdG+eI9kVUPm?jcT|VhQ3Jby8h8pDtu5+ky&F~E19e}i^`_yp?Izl$3A1=LDiL9Ni2)-+y$L6mbb-XX?2L_I$r$KWcAZvpn9d=B&V z{45`KGoOKl*o4Kn1C#MjsD{sA5}vnyh8o!Cr~zC;osDa#mAiqOSe}z87ok>s zDn|4`fQ%YwLXB{#Ew9GWdv2>^A0pox^BHOaU)%cspk{hU&%_Kf z@e#@e7=K$(r+z!CzgK!j67S*b_J-4_hR>sx=qr0;MsA|q3HdW6{HVdH=wLPKd(n(q zk@cv7Z9#qWpS8Y>YX41C`=3O}=%2*bs0Ui*B_3#lYA72u<3iN+emE2dV_#g31sKD8 zJdYExB?T7MOha|J1a;~+qGrAy)oC40ZLSEA!n^rFN04)X88 zTtXJde2cv?r_h*Za2%e*tEd(E4Hxgh6R5Z3DyqJK1I1QEOn)-k<1xq^VQNtWX|}FI zt-vNs$L*-sb3f|7qp0hrZ23LZ9{(A2_^zT3tzISF*9Frs7xU@gl#)rNq6%l>Ow>$Y zLoLzAn2ujy241)IEtrZl)Cvv7mN*6V{0!6p=AyPDgdOPLJWfU(?nLd? z3Dn^@i}&L{kZm=6zMtr@3N^zysMl&4s-q34t=x<$xD8WrH#&F#HGtEo=gwh7Be_OK z52TeO{{LqoZ<1Mx{F&|ibjQ=E_x4NF()XaCj*Cz;?t__Fi5kc>RJ#wOwqOowt5>4l ziY=wAzZ%*{1)q6y2%GVJ)CXiL-$|W`FzP!IMcw~4s^c@L4nDSCv|dKt_fK2?H)0;ESjRW2hM)$BFnyRL9x8o4Q_z znpj^Pj}vVD4rEMbUxZ9PnNLwOPU)983%ST5m|@6jn-C`9bEt;*pbqUpY>S6b1A7BC z&_7tuqT0ELTCooO6QA-f*pYIil8lycrqx9ql6q8w3z5&j&9sT!qePfc14=82mkF(y zk_L2?n4|(}EzyBcyRQ*StB4=z{hv=}2CmwL z2&zCTAoj;|eDSQku@@1uyXvL@KeFm_`H$rH6_82^}J(T4EmY zYvM^_EOC4K1qGcO-fZ(2kw$DKbhzVRL(C*1I(!F+WyDX3a^nBfvsCB{w%lGAh`+M= z!#LgMpT;G`5h7~qs;oNPO2>$iL_6Z8?{;hj1-&L)2qhgzB^|&gh~X-brVz!1PCn<- zc!^oWbHopbLSi+cluc|PYE&R~BPPdlw|*Yd{{NhE2Jy(Pdhe}1<1J*1Y zb=&oO$&a?>J8>$}NHo|wKmLsP2{D^kN>ph7^<`U3EF|=f?jd>-uMlg9=ZV3DQW^1M zqBYS>6cI{K5xe5K#J^i*bBV_Zm#8F^UL^(*Gl_|WRx_SP@Ean0iK2PXx(>$?za;Wv zZsrP4^k3~hh`rIiyC-XeKN#@2jyL2i2>2TPVb=}DKF=!kv>w^$^ZC8?ZY-ko%w)m@sBVwGLTcv?>hxk23--Pob}ww^=5BNvBQYo$R3?mGO)PM z0H?HkP}#ufgq*HvCFR9sB~D4{pwhmvMLEZkqGNNvNgW>WhrKm460692z|+3MUEuob zf=>0xz5bJXnU)*dn7`T6W_*x}K)u7bAl9p(GZ$W8v=d1aK$N{)S17V%__wI+~2H6;l2K!B7ibehN#`;|+6sWIvLrw#W=lW{`K^L5$TQk=U5>74iyE%l! rr0czPA?{#&?qa9G*BElb-e9eh9s8pHCQo!-`Qgl4PnZRPuxtJch|w2B diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po index d5797a5..8a7edb3 100644 --- a/locale/fr/LC_MESSAGES/django.po +++ b/locale/fr/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2017-09-27 18:39+0000\n" -"PO-Revision-Date: 2017-08-30 01:14+0200\n" +"POT-Creation-Date: 2017-10-05 23:31+0000\n" +"PO-Revision-Date: 2017-10-06 01:31+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: fr\n" @@ -22,11 +22,11 @@ msgstr "" msgid "Pending decision" msgstr "Décision en attente" -#: cfp/forms.py:17 cfp/templates/cfp/staff/talk_list.html:64 +#: cfp/forms.py:17 cfp/templates/cfp/staff/talk_list.html:66 msgid "Accepted" msgstr "Accepté" -#: cfp/forms.py:18 cfp/templates/cfp/staff/talk_list.html:66 +#: cfp/forms.py:18 cfp/templates/cfp/staff/talk_list.html:68 msgid "Declined" msgstr "Décliné" @@ -40,16 +40,16 @@ msgstr "Durée par défaut : %(duration)d min" msgid "Category" msgstr "Catégorie" -#: cfp/forms.py:56 cfp/templates/cfp/staff/talk_list.html:39 +#: cfp/forms.py:56 cfp/templates/cfp/staff/talk_list.html:41 msgid "Title" msgstr "Titre" -#: cfp/forms.py:57 cfp/models.py:141 -#: cfp/templates/cfp/staff/talk_details.html:61 volunteers/models.py:14 +#: cfp/forms.py:57 cfp/models.py:139 cfp/models.py:373 +#: cfp/templates/cfp/staff/talk_details.html:61 msgid "Description" msgstr "Description" -#: cfp/forms.py:58 cfp/models.py:106 +#: cfp/forms.py:58 cfp/models.py:107 cfp/models.py:354 #: cfp/templates/cfp/staff/participant_details.html:16 #: cfp/templates/cfp/staff/talk_details.html:75 msgid "Notes" @@ -62,13 +62,13 @@ msgstr "Visible par les orateurs" #: cfp/forms.py:73 cfp/forms.py:149 #: cfp/templates/cfp/staff/talk_details.html:18 #: cfp/templates/cfp/staff/talk_details.html:81 -#: cfp/templates/cfp/staff/talk_list.html:43 +#: cfp/templates/cfp/staff/talk_list.html:45 msgid "Status" msgstr "Statut" -#: cfp/forms.py:79 cfp/forms.py:155 cfp/models.py:276 +#: cfp/forms.py:79 cfp/forms.py:155 cfp/models.py:268 #: cfp/templates/cfp/staff/talk_details.html:21 -#: cfp/templates/cfp/staff/talk_list.html:42 +#: cfp/templates/cfp/staff/talk_list.html:44 #: cfp/templates/cfp/staff/track_form.html:14 msgid "Track" msgstr "Session" @@ -100,7 +100,8 @@ msgstr "Programmé" msgid "Filter talks already / not yet scheduled" msgstr "Filtrer les exposés déjà / pas encore planifiées" -#: cfp/forms.py:97 cfp/models.py:287 +#: cfp/forms.py:97 cfp/models.py:283 +#: cfp/templates/cfp/staff/talk_details.html:51 msgid "Materials" msgstr "Supports" @@ -108,7 +109,7 @@ msgstr "Supports" msgid "Filter talks with / without materials" msgstr "Filtrer les exposés avec / sans supports" -#: cfp/forms.py:101 +#: cfp/forms.py:101 cfp/templates/cfp/staff/talk_details.html:55 msgid "Video" msgstr "Vidéo" @@ -132,22 +133,22 @@ msgstr "Assigner à une session" msgid "Put in a room" msgstr "Assigner à une salle" -#: cfp/forms.py:137 cfp/models.py:139 -#: cfp/templates/cfp/staff/participant_list.html:34 volunteers/models.py:12 +#: cfp/forms.py:137 cfp/models.py:137 cfp/models.py:371 +#: cfp/templates/cfp/staff/participant_list.html:34 msgid "Name" msgstr "Nom" -#: cfp/forms.py:183 +#: cfp/forms.py:186 msgid "New staff members will be informed of their new position by e-mail." msgstr "" "Les nouveaux membres du staff seront informés de leur nouveau rôle par " "courrier électronique." -#: cfp/forms.py:203 +#: cfp/forms.py:206 msgid "An user with that firstname and that lastname already exists." msgstr "Un utilisateur avec ce prénom et ce nom existe déjà." -#: cfp/forms.py:208 +#: cfp/forms.py:211 msgid "A user with that email already exists." msgstr "Un utilisateur avec cet email existe déjà." @@ -187,7 +188,15 @@ msgstr "Domaine sécurisé (HTTPS)" msgid "Schedule publishing date" msgstr "Date de publication du programme" -#: cfp/models.py:67 +#: cfp/models.py:36 +msgid "Volunteers enrollment opening date" +msgstr "Date d’ouverture de l’appel à bénévole" + +#: cfp/models.py:37 +msgid "Volunteers enrollment closing date" +msgstr "Date de fermeture de l’appel à bénévole" + +#: cfp/models.py:75 #, python-brace-format msgid "" "The reply email should be a formatable string accepting a token argument (e." @@ -196,78 +205,78 @@ msgstr "" "L’adresse de réponse doit être une chaine de texte formatable avec un " "argument « token » (e.g. ponyconf+{token}@exemple.com)." -#: cfp/models.py:89 +#: cfp/models.py:95 cfp/models.py:349 msgid "Your Name" msgstr "Votre Nom" -#: cfp/models.py:92 cfp/templates/cfp/staff/participant_details.html:12 +#: cfp/models.py:97 cfp/templates/cfp/staff/participant_details.html:12 msgid "Biography" msgstr "Biographie" -#: cfp/models.py:95 +#: cfp/models.py:99 msgid "Twitter" msgstr "Twitter" -#: cfp/models.py:96 +#: cfp/models.py:100 msgid "LinkedIn" msgstr "LinkedIn" -#: cfp/models.py:97 +#: cfp/models.py:101 msgid "Github" msgstr "Github" -#: cfp/models.py:98 +#: cfp/models.py:102 msgid "Website" msgstr "Site web" -#: cfp/models.py:99 +#: cfp/models.py:103 msgid "Facebook" msgstr "Facebook" -#: cfp/models.py:100 +#: cfp/models.py:104 msgid "Mastodon" msgstr "Mastodon" -#: cfp/models.py:102 +#: cfp/models.py:105 cfp/models.py:352 msgid "Phone number" msgstr "Numéro de téléphone" -#: cfp/models.py:106 +#: cfp/models.py:108 cfp/models.py:267 msgid "This field is only visible by organizers." msgstr "Ce champs est uniquement visible par les organisateurs." -#: cfp/models.py:193 +#: cfp/models.py:189 msgid "Default duration (min)" msgstr "Durée par défaut (min)" -#: cfp/models.py:194 +#: cfp/models.py:190 msgid "Color on program" msgstr "Couleur sur le programme" -#: cfp/models.py:195 +#: cfp/models.py:191 msgid "Label on program" msgstr "Label dans le xml du programme" -#: cfp/models.py:271 cfp/templates/cfp/staff/base.html:17 +#: cfp/models.py:262 cfp/templates/cfp/staff/base.html:17 #: cfp/templates/cfp/staff/participant_list.html:8 #: cfp/templates/cfp/staff/talk_details.html:65 -#: cfp/templates/cfp/staff/talk_list.html:41 +#: cfp/templates/cfp/staff/talk_list.html:43 msgid "Speakers" msgstr "Orateurs" -#: cfp/models.py:272 +#: cfp/models.py:263 msgid "Talk Title" msgstr "Titre de la proposition" -#: cfp/models.py:275 +#: cfp/models.py:266 msgid "Description of your talk" msgstr "Description de votre proposition" -#: cfp/models.py:277 +#: cfp/models.py:269 msgid "Message to organizers" msgstr "Message aux organisateurs" -#: cfp/models.py:277 +#: cfp/models.py:270 msgid "" "If you have any constraint or if you have anything that may help you to " "select your talk, like a video or slides of your talk, please write it down " @@ -277,48 +286,64 @@ msgstr "" "votre proposition, comme une vidéo, des slides, n'hésitez pas à les ajouter " "ici." -#: cfp/models.py:278 +#: cfp/models.py:273 msgid "Talk Category" msgstr "Catégorie de proposition" -#: cfp/models.py:279 +#: cfp/models.py:274 msgid "I'm ok to be recorded on video" msgstr "J’accepte d’être enregistré en vidéo" -#: cfp/models.py:280 +#: cfp/models.py:276 msgid "Video licence" msgstr "Licence vidéo" -#: cfp/models.py:281 +#: cfp/models.py:277 msgid "I need sound" msgstr "J’ai besoin de son" -#: cfp/models.py:283 +#: cfp/models.py:279 msgid "Beginning date and time" msgstr "Date et heure de début" -#: cfp/models.py:284 +#: cfp/models.py:280 msgid "Duration (min)" msgstr "Durée (min)" -#: cfp/models.py:288 +#: cfp/models.py:284 msgid "" "You can use this field to share some materials related to your intervention." msgstr "" "Vous pouvez utiliser ce champs pour partager les supports de votre " "intervention." -#: cfp/signals.py:79 +#: cfp/models.py:355 +msgid "If you have some constraints, you can indicate them here." +msgstr "Si vous avez des contraintes, vous pouvez les indiquer ici." + +#: cfp/models.py:374 +msgid "Volunteer" +msgstr "Bénévole" + +#: cfp/models.py:378 +msgid "Activity" +msgstr "Activité" + +#: cfp/models.py:379 +msgid "Activities" +msgstr "Activités" + +#: cfp/signals.py:80 #, python-format msgid "[%(prefix)s] Message from the staff" msgstr "[%(prefix)s] Message du staff" -#: cfp/signals.py:80 +#: cfp/signals.py:81 #, python-format msgid "[%(prefix)s] Conversation with %(dest)s" msgstr "[%(prefix)s] Conversation avec %(dest)s" -#: cfp/signals.py:96 +#: cfp/signals.py:97 #, python-format msgid "[%(prefix)s] Talk: %(talk)s" msgstr "[%(prefix)s] Talk: %(talk)s" @@ -458,7 +483,7 @@ msgstr "par" #: cfp/templates/cfp/staff/participant_details.html:43 #: cfp/templates/cfp/staff/room_details.html:21 #: cfp/templates/cfp/staff/room_details.html:39 -#: cfp/templates/cfp/staff/talk_list.html:57 +#: cfp/templates/cfp/staff/talk_list.html:59 msgid "and" msgstr "et" @@ -489,19 +514,16 @@ msgstr "Éditer un orateur" #: cfp/templates/cfp/staff/participant_list.html:10 #: cfp/templates/cfp/staff/talk_list.html:10 -#: volunteers/templates/volunteers/volunteer_list.html:11 msgid "Show filtering options…" msgstr "Afficher les options de filtrage…" #: cfp/templates/cfp/staff/participant_list.html:24 -#: cfp/templates/cfp/staff/talk_list.html:27 -#: volunteers/templates/volunteers/volunteer_list.html:19 +#: cfp/templates/cfp/staff/talk_list.html:29 msgid "Filter" msgstr "Filtrer" #: cfp/templates/cfp/staff/participant_list.html:30 -#: cfp/templates/cfp/staff/talk_list.html:35 -#: volunteers/templates/volunteers/volunteer_list.html:25 +#: cfp/templates/cfp/staff/talk_list.html:37 msgid "Total:" msgstr "Total :" @@ -568,7 +590,7 @@ msgid "Some talks are not scheduled yet." msgstr "Certains exposés ne sont pas encore planifiés." #: cfp/templates/cfp/staff/room_list.html:24 -#: cfp/templates/cfp/staff/talk_list.html:35 +#: cfp/templates/cfp/staff/talk_list.html:37 #: cfp/templates/cfp/staff/track_list.html:21 msgid "talk" msgstr "exposé" @@ -636,6 +658,10 @@ msgstr "Créneau" msgid "not defined" msgstr "non défini" +#: cfp/templates/cfp/staff/talk_details.html:56 +msgid "download" +msgstr "Télécharger" + #: cfp/templates/cfp/staff/talk_details.html:63 msgid "No description provided." msgstr "Aucune description fournie." @@ -672,20 +698,20 @@ msgstr "" msgid "Edit a talk" msgstr "Éditer un exposé" -#: cfp/templates/cfp/staff/talk_list.html:40 +#: cfp/templates/cfp/staff/talk_list.html:42 msgid "Intervention kind" msgstr "Type d’intervention" -#: cfp/templates/cfp/staff/talk_list.html:68 +#: cfp/templates/cfp/staff/talk_list.html:70 #, python-format msgid "Pending, score: %(score)s" msgstr "En cours, score : %(score)s" -#: cfp/templates/cfp/staff/talk_list.html:80 +#: cfp/templates/cfp/staff/talk_list.html:82 msgid "For selected talks:" msgstr "Pour les exposés sélectionnés :" -#: cfp/templates/cfp/staff/talk_list.html:85 +#: cfp/templates/cfp/staff/talk_list.html:87 msgid "Apply" msgstr "Appliquer" @@ -701,7 +727,44 @@ msgstr "responsable" msgid "No tracks." msgstr "Aucune session." -#: cfp/views.py:76 +#: cfp/templates/cfp/volunteer.html:9 cfp/templates/cfp/volunteer_enrole.html:9 +msgid "Become a volunteers!" +msgstr "Devenez un bénévole !" + +#: cfp/templates/cfp/volunteer.html:19 +msgid "I will be happy to help on that!" +msgstr "Je serai heureux d’aider à cela !" + +#: cfp/templates/cfp/volunteer.html:21 +msgid "Sorry, I have a setback" +msgstr "Désolé, j’ai un contretemps" + +#: cfp/templates/cfp/volunteer_enrole.html:12 +msgid "We need you! To participate, please enter your name and e-mail." +msgstr "" +"Nous avons besoin de vous ! Pour participer, veuillez indiquer votre nom et " +"votre adresse e-mail." + +#: cfp/templates/cfp/volunteer_enrole.html:22 +msgid "We are looking for help with the following activities:" +msgstr "Nous cherchons de l’aide pour les activités suivantes :" + +#: cfp/views.py:47 +msgid "" +"Thank you for your participation! You can now subscribe to some activities." +msgstr "" +"Merci pour votre participation ! Vous pouvez maintenant vous inscrire à une " +"ou plusieurs activités." + +#: cfp/views.py:71 +msgid "Thank you for your participation!" +msgstr "Merci pour votre participation !" + +#: cfp/views.py:75 +msgid "Okay, no problem!" +msgstr "Ok, pas de soucis !" + +#: cfp/views.py:117 msgid "" "Hi {},\n" "\n" @@ -741,35 +804,35 @@ msgstr "" "{}\n" "\n" -#: cfp/views.py:196 cfp/views.py:291 +#: cfp/views.py:237 cfp/views.py:332 msgid "The talk has been accepted." msgstr "L’exposé a été accepté." -#: cfp/views.py:198 cfp/views.py:293 +#: cfp/views.py:239 cfp/views.py:334 msgid "The talk has been declined." msgstr "L’exposé a été décliné." -#: cfp/views.py:261 cfp/views.py:349 +#: cfp/views.py:302 cfp/views.py:390 msgid "Message sent!" msgstr "Message envoyé !" -#: cfp/views.py:274 +#: cfp/views.py:315 msgid "Vote successfully created" msgstr "A voté !" -#: cfp/views.py:274 +#: cfp/views.py:315 msgid "Vote successfully updated" msgstr "Vote mis à jour" -#: cfp/views.py:295 +#: cfp/views.py:336 msgid "Decision taken in account" msgstr "Décision enregistrée" -#: cfp/views.py:377 +#: cfp/views.py:418 msgid "[{}] You have been added to the staff team" msgstr "[{}] Vous avez été ajouté aux membres du staff" -#: cfp/views.py:378 +#: cfp/views.py:419 msgid "" "Hi {},\n" "\n" @@ -793,15 +856,15 @@ msgstr "" "{}\n" "\n" -#: cfp/views.py:399 +#: cfp/views.py:440 msgid "Modifications successfully saved." msgstr "Modification enregistrée avec succès." -#: cfp/views.py:476 +#: cfp/views.py:517 msgid "User created successfully." msgstr "Utilisateur créé avec succès." -#: cfp/views.py:497 +#: cfp/views.py:538 #, python-format msgid "Format '%s' not available" msgstr "Format '%s' non disponible" @@ -839,15 +902,19 @@ msgstr "Accueil" msgid "Call for participation" msgstr "Appel à participation" -#: ponyconf/templates/base.html:39 ponyconf/templates/base.html:50 +#: ponyconf/templates/base.html:28 +msgid "Volunteers" +msgstr "Bénévoles" + +#: ponyconf/templates/base.html:42 ponyconf/templates/base.html:53 msgid "Staff" msgstr "Staff" -#: ponyconf/templates/base.html:48 +#: ponyconf/templates/base.html:51 msgid "Logout" msgstr "Déconnection" -#: ponyconf/templates/base.html:67 +#: ponyconf/templates/base.html:70 msgid "Powered by" msgstr "Propulsé par" @@ -875,56 +942,25 @@ msgstr "Changement de mot de passe" msgid "Email address" msgstr "Adresse e-mail" -#: volunteers/models.py:15 -msgid "Participants" -msgstr "Participants" +#~ msgid "Participants" +#~ msgstr "Participants" -#: volunteers/models.py:19 -msgid "Activity" -msgstr "Activité" +#~ msgid "We are not yet looking for volunteers … come back later!" +#~ msgstr "" +#~ "Nous ne sommes pas encore en recherche de bénévoles … mais revenez plus " +#~ "tard !" -#: volunteers/models.py:20 -#: volunteers/templates/volunteers/volunteer_list.html:31 -msgid "Activities" -msgstr "Activités" +#~ msgid "volunteer" +#~ msgstr "bénévole" -#: volunteers/templates/volunteers/volunteer_enrole.html:9 -msgid "Enrole as volunteer" -msgstr "Devenir bénévole" +#~ msgid "Username" +#~ msgstr "Nom d’utilisateur" -#: volunteers/templates/volunteers/volunteer_enrole.html:19 -msgid "Sorry, I have a setback" -msgstr "Désolé, j’ai un contretemps" +#~ msgid "Fullname" +#~ msgstr "Prénom et nom" -#: volunteers/templates/volunteers/volunteer_enrole.html:21 -msgid "I will be happy to help on that!" -msgstr "Je serai heureux d’aider à cela !" - -#: volunteers/templates/volunteers/volunteer_enrole.html:28 -msgid "We are not yet looking for volunteers … come back later!" -msgstr "" -"Nous ne sommes pas encore en recherche de bénévoles … mais revenez plus " -"tard !" - -#: volunteers/templates/volunteers/volunteer_list.html:9 -msgid "Volunteers" -msgstr "Bénévoles" - -#: volunteers/templates/volunteers/volunteer_list.html:25 -msgid "volunteer" -msgstr "bénévole" - -#: volunteers/templates/volunteers/volunteer_list.html:29 -msgid "Username" -msgstr "Nom d’utilisateur" - -#: volunteers/templates/volunteers/volunteer_list.html:30 -msgid "Fullname" -msgstr "Prénom et nom" - -#: volunteers/templates/volunteers/volunteer_list.html:48 -msgid "Contact" -msgstr "Contacter" +#~ msgid "Contact" +#~ msgstr "Contacter" #~ msgid "" #~ "For example, you need to be back on saturday evening, you cannot eat meat." @@ -1185,9 +1221,6 @@ msgstr "Contacter" #~ msgid "required but unlimited" #~ msgstr "requis mais non limité" -#~ msgid "download" -#~ msgstr "Télécharger" - #~ msgid "Assign to" #~ msgstr "Assigner à" diff --git a/ponyconf/templates/base.html b/ponyconf/templates/base.html index 9002583..6c6c0a6 100644 --- a/ponyconf/templates/base.html +++ b/ponyconf/templates/base.html @@ -24,6 +24,9 @@ {% if conference.schedule_available %}  {% trans "Schedule" %} {% endif %} + {% if conference.volunteers_enrolement_is_open %} +  {% trans "Volunteers" %} + {% endif %} {% comment %} {% if request.user.is_authenticated %}  {% trans "Exhibitor" %}