diff --git a/accounts/admin.py b/accounts/admin.py
index 0558e42ac6ca317beff825b438c2a7299e6bb516..59d7ab80cd20f0e7415bdab825e3ee7152d86f36 100644
--- a/accounts/admin.py
+++ b/accounts/admin.py
@@ -2,12 +2,13 @@ from django.contrib import admin
 from django.contrib.auth.models import Group
 
 from accounts.models import EmailUser
+from shared.admin import ExportCsvMixin
 
 # no need for groups - we only have regular users and superusers
 admin.site.unregister(Group)
 
 @admin.register(EmailUser)
-class EmailUserAdmin(admin.ModelAdmin):
+class EmailUserAdmin(admin.ModelAdmin, ExportCsvMixin):
 	"""option d'affichage des activités dans la vue django admin"""
 	list_display = ("email", "last_name", "first_name", "is_superuser", "is_active", "email_confirmed",)
 	list_filter = ("is_superuser","is_active", "email_confirmed",)
@@ -18,3 +19,4 @@ class EmailUserAdmin(admin.ModelAdmin):
 	ordering = ("last_name", "first_name")
 	readonly_fields = ("date_joined", "last_login",)
 	list_per_page = 200
+	actions = ["export_as_csv"]
diff --git a/accounts/forms.py b/accounts/forms.py
index c38d990aa900cd631b2e4a20c177488dd43dafdc..055b0987f3376b938e59b0a6c7614932477c4867 100644
--- a/accounts/forms.py
+++ b/accounts/forms.py
@@ -4,6 +4,7 @@ from django.contrib.auth.forms import UserCreationForm
 from django.utils.safestring import mark_safe
 
 from accounts.models import EmailUser
+from shared.forms import FormRenderMixin
 
 def password_criterions_html():
 	"""Wraps password criterions into nice html used by other forms"""
@@ -20,126 +21,6 @@ def password_criterions_html():
 	)
 	return mark_safe(criterions_html)
 
-class FormRenderMixin:
-	""" A mixin that can be included in any form to make it render to html as we want
-	it on this website.
-
-	The following class variables can be adjusted to tweak display:
-
-	* `tooltip_helptexts`: a list of fields whose helptexts, if any, should be rendered
-	  as a question mark's tooltip instead of being inlined.
-	* `field_groups`: if `None`, the fields will be rendered in order, as eg. `as_p`
-	  would.
-	  Else, can be set to any nested list structure, containing each field name exactly
-	  once. The structure `[['a', 'b'], ['c']]` would then group together the fields a
-	  and b, then group together the single field c.
-
-	"""
-
-	tooltip_helptexts = []
-	field_groups = None
-
-	class BadFieldGroups(Exception):
-		pass
-
-	def as_html(self):
-		""" Render the form to html """
-
-		def get_field_treelike():
-			def map_to_field(treelike):
-				if isinstance(treelike, str):
-					if treelike in self.fields:
-						return {
-							"field": self[treelike],
-							"tooltip": treelike in self.tooltip_helptexts,
-						}
-					raise self.BadFieldFroups
-				return list(map(map_to_field, treelike))
-
-			if self.field_groups is not None:
-				return map_to_field(self.field_groups)
-			else:
-				return [
-					list(
-						map(
-							lambda field: {
-								"field": self[field],
-								"tooltip": field in self.tooltip_helptexts,
-							},
-							self.fields,
-						)
-					)
-				]
-
-		def gen_html(treelike):
-			def gen_node(subtree):
-				if isinstance(subtree, list):
-					return '<div class="fieldgroup">\n{}</div>'.format(
-						gen_html(subtree)
-					)
-				else:  # Simple field
-					inline_helptext_html = (
-						(
-							'    <span class="helptext inline_helptext">'
-							"{inline_helptext}</span>\n"
-						).format(inline_helptext=subtree["field"].help_text)
-						if subtree["field"].help_text and not subtree["tooltip"]
-						else ""
-					)
-					tooltip_html = (
-						(
-							'<span class="tooltip" tabindex="0">\n'
-							'<i class="fa fa-question-circle" aria-hidden="true"></i>\n'
-							'<span class="tooltiptext">\n'
-							"  {tooltiphtml}\n"
-							"</span>\n"
-							"</span>"
-						).format(tooltiphtml=subtree["field"].help_text)
-						if subtree["field"].help_text and subtree["tooltip"]
-						else ""
-					)
-
-					field_classes = "formfield"
-					if subtree["field"].errors:
-						field_classes += " error_field"
-
-					labelled_input_classes = "labelled_input"
-					if subtree["field"].field.widget.input_type in [
-						"checkbox",
-						"radio",
-					]:
-						labelled_input_classes += " checkbox_input"
-
-					html = (
-						'<div class="{field_classes}" id="formfield_{label_for}">\n'
-						'  <div class="{labelled_input_classes}">\n'
-						'    <div class="label_line">\n'
-						'      <label for="{label_for}">{label_text}&nbsp;:</label>\n{errors}'
-						"    </div>\n"
-						"    {field_html}\n"
-            '    <div class="help">{tooltip}{inline_helptext_html}</div>\n'
-						"  </div>\n"
-						"</div>"
-					).format(
-						field_classes=field_classes,
-						labelled_input_classes=labelled_input_classes,
-						errors=subtree["field"].errors or "",
-						label_for=subtree["field"].id_for_label,
-						label_text=subtree["field"].label,
-						tooltip=tooltip_html,
-						inline_helptext_html=inline_helptext_html,
-						field_html=subtree["field"],
-					)
-					return html
-
-			return "\n".join(map(gen_node, treelike))
-
-		fields_html = gen_html(get_field_treelike())
-		with_errors = "{form_errors}\n{fields}\n".format(
-			form_errors=self.non_field_errors() if self.non_field_errors() else "",
-			fields=fields_html,
-		)
-		return mark_safe(with_errors)
 
 class CreateAccountForm(FormRenderMixin, UserCreationForm):
 	"""Form used to register a new user"""
@@ -147,6 +28,7 @@ class CreateAccountForm(FormRenderMixin, UserCreationForm):
 		model = EmailUser
 		fields = ('email', 'first_name', 'last_name', 'password1', 'password2',)
 
+
 class UpdateAccountForm(FormRenderMixin, forms.ModelForm):
 	"""Form used to update name/email"""
 	class Meta:
diff --git a/home/admin.py b/home/admin.py
index e9b02978fc860e11d0b714d26d1c9154910742ca..e8803c73945c9bdde119db1ea728841ec3ac8f3a 100644
--- a/home/admin.py
+++ b/home/admin.py
@@ -3,31 +3,13 @@ from django.contrib import admin
 from django.http import HttpResponse
 
 from home.models import InterludesActivity, InterludesParticipant, ActivityList
+from shared.admin import ExportCsvMixin
 
 # Titre de la vue (tag <h1>)
 admin.site.site_header = "Administration site interludes"
 # Tag html <title>
 admin.site.site_title = "Admin Interludes"
 
-class ExportCsvMixin:
-	"""class abstraite pour permettre l'export CSV rapide d'un modele"""
-	def export_as_csv(self, request, queryset):
-		"""renvoie un fichier CSV contenant l'information du queryset"""
-		meta = self.model._meta
-		field_names = [field.name for field in meta.fields]
-
-		response = HttpResponse(content_type='text/csv')
-		response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
-		writer = csv.writer(response)
-
-		writer.writerow(field_names)
-		for obj in queryset:
-			writer.writerow([getattr(obj, field) for field in field_names])
-
-		return response
-
-	export_as_csv.short_description = "Exporter au format CSV"
-
 
 @admin.register(InterludesActivity)
 class InterludesActivityAdmin(admin.ModelAdmin, ExportCsvMixin):
diff --git a/interludes/settings.py b/interludes/settings.py
index a70d8aa8dcb2c79ee43737db875197f1c2576da5..ba3a5dfb92373968e36dde19716db08e00f92118 100644
--- a/interludes/settings.py
+++ b/interludes/settings.py
@@ -40,9 +40,11 @@ INSTALLED_APPS = [
 	'django.contrib.messages',
 	'django.contrib.staticfiles',
 	'django.contrib.sitemaps',
+
 	'home.apps.HomeConfig',
 	'accounts.apps.AccountsConfig',
 	'site_settings.apps.SiteSettingsConfig',
+	'shared.apps.SharedConfig'
 ]
 
 MIDDLEWARE = [
diff --git a/shared/__init__.py b/shared/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/shared/admin.py b/shared/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d3431f99ed3e3c65739d8f53876b940edc062a7
--- /dev/null
+++ b/shared/admin.py
@@ -0,0 +1,19 @@
+
+class ExportCsvMixin:
+	"""class abstraite pour permettre l'export CSV rapide d'un modele"""
+	def export_as_csv(self, request, queryset):
+		"""renvoie un fichier CSV contenant l'information du queryset"""
+		meta = self.model._meta
+		field_names = [field.name for field in meta.fields]
+
+		response = HttpResponse(content_type='text/csv')
+		response['Content-Disposition'] = 'attachment; filename={}.csv'.format(meta)
+		writer = csv.writer(response)
+
+		writer.writerow(field_names)
+		for obj in queryset:
+			writer.writerow([getattr(obj, field) for field in field_names])
+
+		return response
+
+	export_as_csv.short_description = "Exporter au format CSV"
diff --git a/shared/apps.py b/shared/apps.py
new file mode 100644
index 0000000000000000000000000000000000000000..46de2639eb8c37f50fdbc430de381c5eac77b2d0
--- /dev/null
+++ b/shared/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SharedConfig(AppConfig):
+    name = 'shared'
diff --git a/shared/forms.py b/shared/forms.py
new file mode 100644
index 0000000000000000000000000000000000000000..d3b5964b58a30994505c55586fe5449475ef504e
--- /dev/null
+++ b/shared/forms.py
@@ -0,0 +1,122 @@
+
+
+class FormRenderMixin:
+	""" A mixin that can be included in any form to make it render to html as we want
+	it on this website.
+
+	The following class variables can be adjusted to tweak display:
+
+	* `tooltip_helptexts`: a list of fields whose helptexts, if any, should be rendered
+	  as a question mark's tooltip instead of being inlined.
+	* `field_groups`: if `None`, the fields will be rendered in order, as eg. `as_p`
+	  would.
+	  Else, can be set to any nested list structure, containing each field name exactly
+	  once. The structure `[['a', 'b'], ['c']]` would then group together the fields a
+	  and b, then group together the single field c.
+
+	"""
+
+	tooltip_helptexts = []
+	field_groups = None
+
+	class BadFieldGroups(Exception):
+		pass
+
+	def as_html(self):
+		""" Render the form to html """
+
+		def get_field_treelike():
+			def map_to_field(treelike):
+				if isinstance(treelike, str):
+					if treelike in self.fields:
+						return {
+							"field": self[treelike],
+							"tooltip": treelike in self.tooltip_helptexts,
+						}
+					raise self.BadFieldFroups
+				return list(map(map_to_field, treelike))
+
+			if self.field_groups is not None:
+				return map_to_field(self.field_groups)
+			else:
+				return [
+					list(
+						map(
+							lambda field: {
+								"field": self[field],
+								"tooltip": field in self.tooltip_helptexts,
+							},
+							self.fields,
+						)
+					)
+				]
+
+		def gen_html(treelike):
+			def gen_node(subtree):
+				if isinstance(subtree, list):
+					return '<div class="fieldgroup">\n{}</div>'.format(
+						gen_html(subtree)
+					)
+				else:  # Simple field
+					inline_helptext_html = (
+						(
+							'    <span class="helptext inline_helptext">'
+							"{inline_helptext}</span>\n"
+						).format(inline_helptext=subtree["field"].help_text)
+						if subtree["field"].help_text and not subtree["tooltip"]
+						else ""
+					)
+					tooltip_html = (
+						(
+							'<span class="tooltip" tabindex="0">\n'
+							'<i class="fa fa-question-circle" aria-hidden="true"></i>\n'
+							'<span class="tooltiptext">\n'
+							"  {tooltiphtml}\n"
+							"</span>\n"
+							"</span>"
+						).format(tooltiphtml=subtree["field"].help_text)
+						if subtree["field"].help_text and subtree["tooltip"]
+						else ""
+					)
+
+					field_classes = "formfield"
+					if subtree["field"].errors:
+						field_classes += " error_field"
+
+					labelled_input_classes = "labelled_input"
+					if subtree["field"].field.widget.input_type in [
+						"checkbox",
+						"radio",
+					]:
+						labelled_input_classes += " checkbox_input"
+
+					html = (
+						'<div class="{field_classes}" id="formfield_{label_for}">\n'
+						'  <div class="{labelled_input_classes}">\n'
+						'    <div class="label_line">\n'
+						'      <label for="{label_for}">{label_text}&nbsp;:</label>\n{errors}'
+						"    </div>\n"
+						"    {field_html}\n"
+            '    <div class="help">{tooltip}{inline_helptext_html}</div>\n'
+						"  </div>\n"
+						"</div>"
+					).format(
+						field_classes=field_classes,
+						labelled_input_classes=labelled_input_classes,
+						errors=subtree["field"].errors or "",
+						label_for=subtree["field"].id_for_label,
+						label_text=subtree["field"].label,
+						tooltip=tooltip_html,
+						inline_helptext_html=inline_helptext_html,
+						field_html=subtree["field"],
+					)
+					return html
+
+			return "\n".join(map(gen_node, treelike))
+
+		fields_html = gen_html(get_field_treelike())
+		with_errors = "{form_errors}\n{fields}\n".format(
+			form_errors=self.non_field_errors() if self.non_field_errors() else "",
+			fields=fields_html,
+		)
+		return mark_safe(with_errors)
diff --git a/shared/models.py b/shared/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..71a836239075aa6e6e4ecb700e9c42c95c022d91
--- /dev/null
+++ b/shared/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/shared/tests.py b/shared/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..7ce503c2dd97ba78597f6ff6e4393132753573f6
--- /dev/null
+++ b/shared/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/shared/views.py b/shared/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..91ea44a218fbd2f408430959283f0419c921093e
--- /dev/null
+++ b/shared/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.