diff --git a/.gitattributes b/.gitattributes
index b97ca5dc8c5a6926fcbec5d5dbff8718879cf70e..20d27105d52df8e742d27e9f8d212bcf79a43044 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,6 +5,7 @@ action/changer_mode_document.php -text
 action/copier_local.php -text
 action/dissocier_document.php -text
 action/editer_document.php -text
+action/ordonner_liens_documents.php -text
 action/supprimer_document.php -text
 action/supprimer_tous_orphelins.php -text
 action/tourner.php -text
@@ -282,6 +283,8 @@ prive/themes/spip/images/base/video-16.png -text
 prive/themes/spip/images/base/video-22.png -text
 prive/themes/spip/images/base/video-32.png -text
 prive/themes/spip/images/base/vu-16.png -text
+prive/themes/spip/images/deplacer-16.png -text
+prive/themes/spip/images/deplacer-24.png -text
 prive/themes/spip/images/distant-16.png -text
 prive/themes/spip/images/doc-16.png -text
 prive/themes/spip/images/doc-24.png -text
diff --git a/action/ordonner_liens_documents.php b/action/ordonner_liens_documents.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1be0467a21c8c2d05a5649b7f6102290cab8d2c
--- /dev/null
+++ b/action/ordonner_liens_documents.php
@@ -0,0 +1,103 @@
+<?php
+
+/**
+ * Action ordonnant un lien sur une table de liens
+ *
+ * @plugin     Medias
+ * @copyright  2017
+ * @author     Matthieu Marcillaud
+ * @licence    GNU/GPL
+ * @package    SPIP\Ordoc\Action
+ */
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+function action_ordonner_liens_documents_dist() {
+	action_ordonner_liens_dist();
+}
+
+
+function action_ordonner_liens_dist() {
+	include_spip('inc/autoriser');
+	include_spip('base/objets');
+	include_spip('action/editer_liens');
+
+	// source (table spip_xx_liens)
+	$objet = objet_type(_request('objet_source'));
+
+	// objet lié
+	$objet_lie = _request('objet_lie');
+	$id_objet_lie = intval(_request('id_objet_lie'));
+
+	// ordre des éléments
+	$ordre = _request('ordre');
+
+	if (!$objet or !$objet_lie or !$id_objet_lie OR !$ordre or !objet_associable($objet)) {
+		return envoyer_json_erreur(_T('medias:erreur_objet_absent') . ' ' . _T('medias:erreur_deplacement_impossible'));
+	}
+
+	if (!autoriser('modifier', $objet_lie, $id_objet_lie)) {
+		return envoyer_json_erreur(_T('medias:erreur_autorisation') . ' ' . _T('medias:erreur_deplacement_impossible'));
+	}
+
+	list($_id_objet, $table_liens) = objet_associable($objet);
+
+	$success = $errors = array();
+
+	$actuels = sql_allfetsel(
+		array($_id_objet . ' AS id', 'rang_lien'),
+		$table_liens,
+		array(
+			sql_in($_id_objet, $ordre),
+			'objet = ' . sql_quote($objet_lie),
+			'id_objet = ' . sql_quote($id_objet_lie)
+		)
+	);
+
+	$futurs = array_flip($ordre);
+	// ordre de 1 à n (pas de 0 à n).
+	array_walk($futurs, function(&$v) { $v++; });
+
+	$updates = array();
+
+	foreach ($actuels as $l) {
+		if ($futurs[$l['id']] !== $l['rang_lien']) {
+			$updates[$l['id']] = $futurs[$l['id']];
+		}
+	}
+
+	if ($updates) {
+		foreach ($updates as $id => $ordre) {
+			sql_updateq(
+				$table_liens,
+				array('rang_lien' => $ordre),
+				array(
+					$_id_objet . ' = ' . $id,
+					'objet = ' . sql_quote($objet_lie),
+					'id_objet = ' . sql_quote($id_objet_lie)
+				)
+			);
+		}
+	}
+
+	return envoyer_json_envoi(array(
+		'done' => true,
+		'success' => $success,
+		'errors' => $errors,
+	));
+}
+
+function envoyer_json_envoi($data) {
+	header('Content-Type: application/json; charset=' . $GLOBALS['meta']['charset']);
+	echo json_encode($data);
+}
+
+function envoyer_json_erreur($msg) {
+	return envoyer_json_envoi(array(
+		'done' => false,
+		'success' => array(),
+		'errors' => array($msg)
+	));
+}
diff --git a/base/medias.php b/base/medias.php
index 778c457bb58b2bc60854d71f6618bbbd83fd30a9..73d508ca4698e394b870b7df0567a76361fbbd83 100644
--- a/base/medias.php
+++ b/base/medias.php
@@ -87,7 +87,8 @@ function medias_declarer_tables_auxiliaires($tables_auxiliaires) {
 		'id_document' => "bigint(21) DEFAULT '0' NOT NULL",
 		'id_objet' => "bigint(21) DEFAULT '0' NOT NULL",
 		'objet' => "VARCHAR (25) DEFAULT '' NOT NULL",
-		'vu' => "ENUM('non', 'oui') DEFAULT 'non' NOT NULL"
+		'vu' => "ENUM('non', 'oui') DEFAULT 'non' NOT NULL",
+		'rang_lien' => "int(4) DEFAULT '0' NOT NULL"
 	);
 
 	$spip_documents_liens_key = array(
diff --git a/lang/medias_fr.php b/lang/medias_fr.php
index e55b0288d46f347235cdb7426a28c54a72473b4b..b07ad0017fe5f15f6c684f597c72be3c5b9b8e90 100644
--- a/lang/medias_fr.php
+++ b/lang/medias_fr.php
@@ -74,14 +74,17 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
 	'entree_titre_image' => 'Titre de l’image :',
 	'erreur_aucun_document' => 'Ce document n’existe pas dans la médiathèque',
 	'erreur_aucun_fichier' => 'Aucun fichier n’a été trouvé',
+	'erreur_autorisation' => 'Échec de l’autorisation.',
 	'erreur_chemin_distant' => 'Le fichier distant @nom@ n’a pas pu être trouvé',
 	'erreur_chemin_ftp' => 'Le fichier indiqué n’a pas été trouvé sur le serveur',
 	'erreur_copie_fichier' => 'Impossible de copier le fichier @nom@',
+	'erreur_deplacement_impossible' => 'Déplacement impossible.',
 	'erreur_dossier_tmp_manquant' => 'Un dossier temporaire est manquant pour télécharger les fichiers',
 	'erreur_ecriture_fichier' => 'Erreur lors de l’écriture du fichier sur le disque',
 	'erreur_format_fichier_image' => 'Le format de @nom@ ne convient pas pour une image',
 	'erreur_indiquez_un_fichier' => 'Indiquez un fichier !',
 	'erreur_insertion_document_base' => 'Impossible d’enregistrer le document @fichier@ en base de données',
+	'erreur_objet_absent' => 'Informations reçues incomplètes.',
 	'erreur_suppression_vignette' => 'Erreur lors de la suppression de la vignette',
 	'erreur_upload_type_interdit' => 'Le téléchargement des fichiers du type de @nom@ n’est pas autorisé',
 	'erreur_upload_vignette' => 'Erreur lors du chargement de la vignette @nom@',
@@ -155,6 +158,7 @@ $GLOBALS[$GLOBALS['idx_lang']] = array(
 	// O
 	'objet_document' => 'Document',
 	'objet_documents' => 'Documents',
+	'ordonner_ce_document' => 'Ordonner ce document',
 
 	// P
 	'par_date' => 'Date',
diff --git a/medias_administrations.php b/medias_administrations.php
index 99922362715247026087987eec49d032c61050cf..1979fc9fba19862264fffe8f8f767e6c5f7da671 100644
--- a/medias_administrations.php
+++ b/medias_administrations.php
@@ -169,6 +169,10 @@ function medias_upgrade($nom_meta_base_version, $version_cible) {
 		// ajout de ics + vcf
 		array('creer_base_types_doc')
 	);
+	$maj['1.3.0'] = array(
+		// ajout de rang_lien
+		array('maj_tables', 'spip_documents_liens'),
+	);
 	include_spip('base/upgrade');
 	include_spip('base/medias');
 	maj_plugin($nom_meta_base_version, $version_cible, $maj);
diff --git a/modeles/document_desc.html b/modeles/document_desc.html
index 62e814bc8798173b89f3f29d0b86d96a903658ae..2908ed6ef41c88cd0eadb94d3fc7c7a063143130 100644
--- a/modeles/document_desc.html
+++ b/modeles/document_desc.html
@@ -12,7 +12,7 @@ Distribue sous licence GPL
 
 		<div class="descriptions">
 			<h4 class="titrem">
-				[(#VU|=={oui}|oui)<img src='#CHEMIN_IMAGE{vu-16-10.png}' width='16' height='10' alt='<:medias:document_vu:>' title='<:medias:document_vu:>'/> ]
+				[(#VU|=={oui}|oui)<img src='#CHEMIN_IMAGE{vu-16-10.png}' width='16' height='10' alt='<:medias:document_vu|attribut_html:>' title='<:medias:document_vu:>'/> ]
 				<span class="#EDIT{titre} titre" title="[(#FICHIER*|basename|attribut_html)]">
 					[(#TITRE|oui)#TITRE]
 					[(#TITRE|non)
@@ -27,7 +27,7 @@ Distribue sous licence GPL
 
 			<div class="infos">
 				<div class="permanentes">
-					[(#DISTANT|=={oui}|oui)<img src='#CHEMIN_IMAGE{distant-16.png}' width='16' height='16' alt='<:medias:fichier_distant:>' title='<:medias:fichier_distant:>'/> ]<:info_numero_abbreviation:>#ID_DOCUMENT - #EXTENSION
+					[(#DISTANT|=={oui}|oui)<img src='#CHEMIN_IMAGE{distant-16.png}' width='16' height='16' alt='<:medias:fichier_distant|attribut_html:>' title='<:medias:fichier_distant|attribut_html:>'/> ]<:info_numero_abbreviation:>#ID_DOCUMENT - #EXTENSION
 
 					<a class="lien_details"
 						onClick="$(this).parent().next('.detaillees').toggle(); return true;"
@@ -76,9 +76,10 @@ Distribue sous licence GPL
 		<BOUCLE_compte(documents_liens){id_document}{0,2} />
 		[(#TOTAL_BOUCLE|=={1}|et{#AUTORISER{dissocierdocuments,#OBJET,#ID_OBJET}}|et{#VU|=={non}})[(#BOUTON_ACTION{<:medias:bouton_enlever_supprimer_document:>,#URL_ACTION_AUTEUR{dissocier_document,#ID_OBJET-#OBJET-#ID_DOCUMENT-suppr-safe,#SELF},ajax,<:medias:bouton_enlever_supprimer_document_confirmation:>,'',[(function(){jQuery("#doc(#ID_DOCUMENT)").animateRemove();return true;})()]})]]
 		[(#AUTORISER{dissocierdocuments,#OBJET,#ID_OBJET})[(#BOUTON_ACTION{<:medias:bouton_enlever_document:>,#URL_ACTION_AUTEUR{dissocier_document,#ID_OBJET-#OBJET-#ID_DOCUMENT--safe,#SELF},ajax,'','',[(function(){jQuery("#doc(#ID_DOCUMENT)").animateRemove();return true;})()]})]]
-			[(#AUTORISER{modifier,document,#ID_DOCUMENT}|oui)
+		[(#AUTORISER{modifier,document,#ID_DOCUMENT}|oui)
+			<span class="deplacer-document"><img src='#CHEMIN_IMAGE{deplacer-16.png}' width='16' height='16' alt='<:medias:ordonner_ce_document|attribut_html:>' /></span>
 			<a href="#URL_ECRIRE{document_edit,id_document=#ID_DOCUMENT}" target="_blank" class="editbox" tabindex="0" role="button"><:medias:bouton_modifier_document:></a>
-			]<//B_compte>
+		]<//B_compte>
 		[(#PIPELINE{document_desc_actions,#ARRAY{args,#ARRAY{id_document,#ID_DOCUMENT,position,document_desc,objet,#OBJET,id_objet,#ID_OBJET},data,''}})]
 	</div>
 
diff --git a/paquet.xml b/paquet.xml
index d9a894f130a0fa8f9831590ee02a97548044394b..b8077a6a4ef75b119cfe70486f088c880752dade 100644
--- a/paquet.xml
+++ b/paquet.xml
@@ -1,11 +1,11 @@
 <paquet
 	prefix="medias"
 	categorie="multimedia"
-	version="2.16.0"
+	version="2.17.0"
 	etat="stable"
 	compatibilite="[3.2.0-dev;]"
 	logo="prive/themes/spip/images/portfolio-32.png"
-	schema="1.2.7"
+	schema="1.3.0"
 >
 
 	<nom>Medias</nom>
diff --git a/prive/squelettes/inclure/portfolio-documents.html b/prive/squelettes/inclure/portfolio-documents.html
index c9e9afb65a4c33cc0835a5144cf7b9d22422e20a..663c71dd22d98c8f8b191e18e841eb36792b428b 100644
--- a/prive/squelettes/inclure/portfolio-documents.html
+++ b/prive/squelettes/inclure/portfolio-documents.html
@@ -14,7 +14,7 @@
 <h3><span class="image_loading"></span><:medias:info_illustrations:></h3>
 <div class="liste_items documents" id="illustrations#ENV{id_unique}">
 [<p class="pagination">(#PAGINATION)</p>]
-<BOUCLE_illustrations(DOCUMENTS documents_liens types_documents){inclus=image}{mode=image}{id_objet}{objet}{par num titre,date,id_document}{pagination 50}{statut?}>
+<BOUCLE_illustrations(DOCUMENTS documents_liens types_documents){inclus=image}{mode=image}{id_objet}{objet}{par rang_lien, num titre, date,id_document}{pagination 50}{statut?}>
 	#MODELE{document_desc,id_document,id_objet,objet}
 </BOUCLE_illustrations>
 [(#TOTAL_BOUCLE|>{20}|oui)<p class="pagination">#PAGINATION</p>]
@@ -28,7 +28,7 @@
 <h3><:medias:info_portfolio:></h3>
 <div class="liste_items documents" id="portfolio#ENV{id_unique}">
 [<p class="pagination">(#PAGINATION)</p>]
-<BOUCLE_portfolio(DOCUMENTS documents_liens types_documents){inclus=image}{mode=document}{id_objet}{objet}{par num titre,date,id_document}{pagination 50}{statut?}>
+<BOUCLE_portfolio(DOCUMENTS documents_liens types_documents){inclus=image}{mode=document}{id_objet}{objet}{par rang_lien, num titre, date,id_document}{pagination 50}{statut?}>
 	#MODELE{document_desc,id_document,id_objet,objet}
 </BOUCLE_portfolio>
 [(#TOTAL_BOUCLE|>{20}|oui)<p class="pagination">#PAGINATION</p>]
@@ -42,7 +42,7 @@
 <h3><:medias:info_documents:></h3>
 <div class="liste_items documents" id="documents#ENV{id_unique}">
 [<p class="pagination">(#PAGINATION)</p>]
-<BOUCLE_documents(DOCUMENTS documents_liens types_documents){inclus!=image}{mode!=vignette}{id_objet}{objet}{par num titre,date,id_document}{pagination 50}{statut?}>
+<BOUCLE_documents(DOCUMENTS documents_liens types_documents){inclus!=image}{mode!=vignette}{id_objet}{objet}{par rang_lien, num titre, date,id_document}{pagination 50}{statut?}>
 	#MODELE{document_desc,id_document,id_objet,objet}
 </BOUCLE_documents>
 [(#TOTAL_BOUCLE|>{20}|oui)<p class="pagination">#PAGINATION</p>]
@@ -134,11 +134,90 @@ function choix_affichages_documents() {
 	});
 }
 
+/* Gestion du tri des listes de documents et de leur enregistrement */
+function ordonner_listes_documents() {
+	if ($.fn.sortable) {
+		$("#illustrations#ENV{id_unique}, #portfolio#ENV{id_unique}, #documents#ENV{id_unique}").each(function () {
+			// détruire / recréer le sortable à chaque appel ajax
+			if ($(this).has('.ui-sortable').length) {
+				$(this).sortable('destroy');
+			}
+			// pas de tri possible s'il n'y a qu'un seul élément.
+			if ($(this).find('> .item').length < 2) {
+				$(this).find('.deplacer-document').hide();
+				return true; // continue
+			} else {
+				$(this).find('.deplacer-document').show();
+			}
+			$(this).sortable({
+				/*axis: "y",*/ /* minidoc a un affichage en case */
+				handle: "",
+				placeholder: "ui-state-highlight deplacer-document-placeholder",
+				cancel: 'img.croix_centre_image',
+				start: function(event, ui) {
+					ui.item.addClass('document-en-mouvement');
+				},
+				stop: function(event, ui) {
+					ui.item.removeClass('document-en-mouvement');
+				},
+				update: function (event, ui) {
+					var items = $(this);
+					var item = ui.item;
+					var liste = items.sortable('toArray');
+					var ordre = [];
+
+					$.each(liste, function(i, id) {
+						if (id) {
+							ordre.push( id.substring(3) ); // doc123 => 123
+						}
+					});
+
+					var action = '[(#VAL{ordonner_liens_documents}|generer_url_action{"", 1})]';
+					var params = {
+						objet_source: 'document',
+						objet_lie: '#OBJET',
+						id_objet_lie: '#ID_OBJET',
+						ordre: ordre,
+					};
+
+					item.animateLoading();
+
+					$.ajax({
+						url: action,
+						data: params,
+						dataType: 'json',
+						cache: false,
+					}).done(function(data) {
+
+						var couleur_origine = item.css('background-color');
+						var couleur_erreur = $("<div class='remove'></div>").css('background-color');
+						var couleur_succes = $("<div class='append'></div>").css('background-color');
+						item.endLoading(true);
+
+						if (data.errors.length) {
+							items.sortable('cancel');
+							item.css({backgroundColor: couleur_erreur}).animate({backgroundColor: couleur_origine}, 'normal', function(){
+								item.css({backgroundColor: ''});
+							});
+						} else {
+							item.css({backgroundColor: couleur_succes}).animate({backgroundColor: couleur_origine}, 'normal', function(){
+								item.css({backgroundColor: ''});
+							});
+						}
+					});
+				}
+			});
+		});
+	}
+}
+
 if (window.jQuery) {
 	jQuery(function($){
 		onAjaxLoad(check_reload_page);
 		choix_affichages_documents();
 		onAjaxLoad(choix_affichages_documents);
+		ordonner_listes_documents();
+		onAjaxLoad(ordonner_listes_documents);
 	});
 }
 /*]]>*/</script>
diff --git a/prive/style_prive_plugin_medias.html b/prive/style_prive_plugin_medias.html
index ca0d7f0577aa69aa8d22589a0f26ee05b99ad199..51255b81c2ecadf8ebd9c26fb58f56b326127ad2 100644
--- a/prive/style_prive_plugin_medias.html
+++ b/prive/style_prive_plugin_medias.html
@@ -197,6 +197,12 @@ p.actions {clear:both;}
 
 .item.vu_oui {background:#f9f9f9;}
 
+.deplacer-document-placeholder { height:130px; }
+.deplacer-document { margin-#GET{right}:0.5em; float: #GET{left}; margin-top:2px; cursor:move; }
+.document-en-mouvement { cursor:move; }
+
+.portfolios .item .actions a.editbox { margin-top: 0 !important; }
+
 
 /* Types d'affichages des listes de douments */
 h3 .affichages {
@@ -275,13 +281,16 @@ h3 .affichages {
 }
 .portfolios .documents_liste .item .actions {
 	align-items:center;
+	text-align:#GET{right};
 	margin-#GET{left}:1em;
 	padding-#GET{right}:0;
+	min-width:80px;
 }
 .portfolios .documents_liste .item .actions .editbox,
-.portfolios .documents_liste .item .actions .ordoc-deplacer {
+.portfolios .documents_liste .item .actions .deplacer-document {
 	display:inline-block;
 }
+.documents_liste .deplacer-document-placeholder { height:40px; }
 
 
 /* Grille en cases des documents. */
@@ -310,10 +319,12 @@ h3 .affichages {
 	display:inline-block;
 	float:#GET{right};
 }
-.portfolios .documents_cases .item .actions .ordoc-deplacer {
+.portfolios .documents_cases .item .actions .deplacer-document {
 	display:inline-block;
-	float:#GET{left};
+	margin-top:0px;
 }
+.documents_cases .deplacer-document-placeholder { height:130px; width:113px; padding: 2px; margin: 2px;}
+
 .portfolios .documents_cases .item .vignette {
 	width:auto;
 	height:auto;
@@ -331,7 +342,7 @@ h3 .affichages {
 	width:100%;
 	margin-bottom:0;
 	box-sizing:border-box;
-	padding: 4px 6px;
+	padding: 2px 5px 1px 5px;
 }
 .portfolios .documents_cases .tout_supprimer {
 	flex-basis: 100%;
diff --git a/prive/themes/spip/images/deplacer-16.png b/prive/themes/spip/images/deplacer-16.png
new file mode 100644
index 0000000000000000000000000000000000000000..7823dce1acf400597e3d52634476d0485b5ed3a4
Binary files /dev/null and b/prive/themes/spip/images/deplacer-16.png differ
diff --git a/prive/themes/spip/images/deplacer-24.png b/prive/themes/spip/images/deplacer-24.png
new file mode 100644
index 0000000000000000000000000000000000000000..1b92b6afa36ca06f733e809246f149a18ae4531a
Binary files /dev/null and b/prive/themes/spip/images/deplacer-24.png differ