[#4774 #4779] URL complète avec slug facultatif, et ajout url canonique
authorPA Parent <paparent@paparent.me>
Tue, 4 Dec 2012 21:10:20 +0000 (16:10 -0500)
committerPA Parent <paparent@paparent.me>
Tue, 4 Dec 2012 21:10:20 +0000 (16:10 -0500)
16 files changed:
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/chercheurs/views.py
auf_savoirs_en_partage/savoirs/models.py
auf_savoirs_en_partage/savoirs/views.py
auf_savoirs_en_partage/templates/chercheurs/groupe_membres.html
auf_savoirs_en_partage/templates/chercheurs/groupe_message_display.html
auf_savoirs_en_partage/templates/chercheurs/groupe_message_display_full.html
auf_savoirs_en_partage/templates/chercheurs/groupe_retrieve.html
auf_savoirs_en_partage/templates/chercheurs/index.html
auf_savoirs_en_partage/templates/container_base.html
auf_savoirs_en_partage/templates/savoirs/actualite_resultat.html
auf_savoirs_en_partage/templates/savoirs/evenement_resultat.html
auf_savoirs_en_partage/templates/savoirs/index.html
auf_savoirs_en_partage/templates/savoirs/recherche.html
auf_savoirs_en_partage/templates/savoirs/ressource_resultat.html
auf_savoirs_en_partage/urls.py

index ae989c3..3341728 100644 (file)
@@ -7,6 +7,7 @@ from django.contrib.auth.models import User
 from django.core.urlresolvers import reverse as url
 from django.db import models
 from django.db.models import Q
+from django.template.defaultfilters import slugify
 from django.utils.encoding import smart_str
 from django.utils.hashcompat import sha_constructor
 from django.db.models.signals import post_save
@@ -372,7 +373,14 @@ class Chercheur(Personne):
         return sha_constructor(settings.SECRET_KEY + unicode(self.id)).hexdigest()[::2]
 
     def get_absolute_url(self):
-        return url('chercheur', kwargs={'id': self.id})
+        slug = '%s.html' % (slugify('%s %s' % (self.prenom, self.nom)),)
+        return url('chercheur', kwargs={'id': self.id, 'slug': slug})
+
+    @property
+    def canonical_url(self):
+        return 'http://%s%s' % (settings.SITE_DOMAIN,
+                                url('chercheur-canonical', kwargs={'id': self.id}))
+
 
 class ChercheurVoir(Chercheur):
 
index b33b3b4..4eba638 100644 (file)
@@ -211,11 +211,12 @@ def perso(request):
     })
 
 
-def retrieve(request, id):
+def retrieve(request, id, slug=None):
     """Fiche du chercheur"""
     chercheur = get_object_or_404(Chercheur, id=id)
     return render(request, "chercheurs/retrieve.html", {
-        'chercheur': chercheur
+        'chercheur': chercheur,
+        'canonical_url': chercheur.canonical_url,
     })
 
 
index 546a8a8..ba6668b 100644 (file)
@@ -15,6 +15,7 @@ from urllib import urlencode
 from backend_config import RESOURCES
 from babel.dates import get_timezone_name
 from caldav.lib import error
+from django.conf import settings
 from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.core.mail import EmailMultiAlternatives
@@ -22,6 +23,7 @@ from django.core.urlresolvers import reverse
 from django.db import models
 from django.db.models import Q
 from django.db.models.signals import pre_delete
+from django.template.defaultfilters import slugify
 from django.utils.encoding import smart_unicode, smart_str
 from djangosphinx.models import SphinxQuerySet, SearchError
 from markdown2 import markdown
@@ -277,7 +279,13 @@ class Actualite(models.Model):
         return "%s" % (self.titre)
 
     def get_absolute_url(self):
-        return reverse('actualite', kwargs={'id': self.id})
+        slug = '%s.html' % (slugify(self.titre),)
+        return reverse('actualite', kwargs={'id': self.id, 'slug': slug})
+
+    @property
+    def canonical_url(self):
+        return 'http://%s%s' % (settings.SITE_DOMAIN,
+                                reverse('actualite-canonical', kwargs={'id': self.id}))
 
     def assigner_disciplines(self, disciplines):
         self.disciplines.add(*disciplines)
@@ -436,7 +444,13 @@ class Evenement(models.Model):
         return "[%s] %s" % (self.uid, self.titre)
 
     def get_absolute_url(self):
-        return reverse('evenement', kwargs={'id': self.id})
+        slug = '%s.html' % (slugify(self.titre),)
+        return reverse('evenement', kwargs={'id': self.id, 'slug': slug})
+
+    @property
+    def canonical_url(self):
+        return 'http://%s%s' % (settings.SITE_DOMAIN,
+                                reverse('evenement-canonical', kwargs={'id': self.id}))
 
     def duration_display(self):
         delta = self.fin - self.debut
@@ -734,7 +748,13 @@ class Record(models.Model):
         return "[%s] %s" % (self.server, self.title)
 
     def get_absolute_url(self):
-        return reverse('ressource', kwargs={'id': self.id})
+        slug = '%s.html' % (slugify(self.title),)
+        return reverse('ressource', kwargs={'id': self.id, 'slug': slug})
+
+    @property
+    def canonical_url(self):
+        return 'http://%s%s' % (settings.SITE_DOMAIN,
+                                reverse('ressource-canonical', kwargs={'id': self.id}))
 
     def getServeurURL(self):
         """Retourne l'URL du serveur de provenance"""
index d848085..7209465 100644 (file)
@@ -165,13 +165,14 @@ def ressource_index(request):
     })
 
 
-def ressource_retrieve(request, id):
+def ressource_retrieve(request, id, slug=None):
     """Notice OAI de la ressource"""
     ressource = get_object_or_404(Record, id=id)
     return render(request, "savoirs/ressource_retrieve.html", {
         'ressource': ressource,
         'disciplines': ressource.disciplines.all(),
         'regions': ressource.regions.all(),
+        'canonical_url': ressource.canonical_url,
     })
 
 
@@ -228,9 +229,12 @@ def actualite_index(request, type='actu'):
     })
 
 
-def actualite(request, id):
+def actualite(request, id, slug=None):
     actualite = get_object_or_404(Actualite, pk=id)
-    return render(request, "savoirs/actualite.html", {'actualite': actualite})
+    return render(request, "savoirs/actualite.html", {
+        'actualite': actualite,
+        'canonical_url': actualite.canonical_url,
+    })
 
 
 # agenda
@@ -287,9 +291,12 @@ def evenement_utilisation(request):
     return render(request, "savoirs/evenement_utilisation.html")
 
 
-def evenement(request, id):
+def evenement(request, id, slug=None):
     evenement = get_object_or_404(Evenement, pk=id)
-    return render(request, "savoirs/evenement.html", {'evenement': evenement})
+    return render(request, "savoirs/evenement.html", {
+        'evenement': evenement,
+        'canonical_url': evenement.canonical_url,
+    })
 
 
 def evenement_ajout(request):
index d9d9b9d..0d6bc28 100644 (file)
@@ -12,7 +12,7 @@
 {% if membres %}
        <ul>
        {% for membre in membres.all %}
-               <li><a href="{% url "chercheurs.views.retrieve" membre.chercheur.pk %}">{{ membre.chercheur.prenom }} {{ membre.chercheur.nom|upper }}</a></li>
+               <li><a href="{{ membre.chercheur.get_absolute_url }}">{{ membre.chercheur.prenom }} {{ membre.chercheur.nom|upper }}</a></li>
        {% endfor %}
        </ul>
        <div class="pagination">{% paginate %}</div>
index 587cbf3..214b6f5 100644 (file)
@@ -1,5 +1,5 @@
 {% load url from future %}
 <div class="message">
-       <div class="info">{{ message.date_creation|date:"j N Y, G:i" }} par <a href="{% url "chercheurs.views.retrieve" message.chercheur.pk %}">{{ message.chercheur }}</a></div>
+       <div class="info">{{ message.date_creation|date:"j N Y, G:i" }} par <a href="{{ message.chercheur.get_absolute_url }}">{{ message.chercheur }}</a></div>
        <div class="msg"><strong>{{ message.titre }}</strong><br>{{ message.contenu|safe }}</div>
 </div>
index 4270de8..974e5b9 100644 (file)
@@ -1,5 +1,5 @@
 {% load url from future %}
 <div class="message">
-       <div class="info"><strong>{{ message.groupe }}</strong> - {{ message.date_creation|date:"j N Y, G:i" }} par <a href="{% url "chercheurs.views.retrieve" message.chercheur.pk %}">{{ message.chercheur }}</a></div>
+       <div class="info"><strong>{{ message.groupe }}</strong> - {{ message.date_creation|date:"j N Y, G:i" }} par <a href="{{ message.chercheur.get_absolute_url }}">{{ message.chercheur }}</a></div>
        <div class="msg"><strong>{{ message.titre }}</strong><br>{{ message.contenu|safe }}</div>
 </div>
index fa7ec8d..0b3bad3 100644 (file)
@@ -39,7 +39,7 @@
                <h2>Membres</h2>
                <ul>
                        {% for membre in membres.all %}
-                       <li><a href="{% url "chercheurs.views.retrieve" membre.chercheur.pk %}">{{ membre.chercheur.prenom }} {{ membre.chercheur.nom|upper }}</a></li>
+                       <li><a href="{{ membre.chercheur.get_absolute_url }}">{{ membre.chercheur.prenom }} {{ membre.chercheur.nom|upper }}</a></li>
                        {% endfor %}
                </ul>
                {% if plus_que_20 %}
index c9c928e..39e9812 100644 (file)
@@ -47,7 +47,7 @@
     </tr>
     {% for chercheur in chercheurs %}
     <tr class="{% cycle 'odd' 'notodd' %}">
-        <td><a href="{% url "chercheurs.views.retrieve" id=chercheur.id %}">{{ chercheur }}</a></td>
+        <td><a href="{{ chercheur.get_absolute_url }}">{{ chercheur }}</a></td>
         <td>{% firstof chercheur.etablissement.nom chercheur.etablissement_autre_nom %}</td>
         <td>{% firstof chercheur.etablissement.pays.nom chercheur.etablissement_autre_pays.nom %}</td>
     </tr>
index 53dfeb6..7b42614 100644 (file)
@@ -5,6 +5,7 @@
     <head>
         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
         <title>{% block title %}Savoirs en partage - Agence universitaire de la Francophonie{% endblock %}</title>
+        {% if canonical_url %}<link rel="canonical" href="{{ canonical_url }}" />{% endif %}
         <link rel="icon" type="image/png" href="{% static "img/favicon.ico" %}" />
         <link href="{% static "css/global.css" %}" rel="stylesheet" type="text/css" />
         <link rel="stylesheet" href="{% static "css/jquery-ui/jquery-ui.css" %}" type="text/css" />
index 8566b73..7fb210d 100644 (file)
@@ -4,7 +4,7 @@
 <div class="resultatRecherche">
   <div>{{ actualite.date|date:"d F Y" }}</div>
   <div class="titre">
-      <a href="{% url "actualite" actualite.id %}">{{ actualite.titre|apply:excerpt }}</a>
+      <a href="{{ actualite.get_absolute_url }}">{{ actualite.titre|apply:excerpt }}</a>
   </div>
   <div>{{ actualite.texte|apply:excerpt|safe }}</div>
   {% if actualite.source %}
index 2541e05..68fb4c3 100644 (file)
@@ -3,6 +3,6 @@
 
 <div class="resultatRecherche">
   <div>{{ evenement.debut|date:"d/m/Y H\hi" }}</div>
-  <div class="titre"><a href="{% url "savoirs.views.evenement" evenement.pk %}">{{ evenement.titre|apply:excerpt }}</a></div>
+  <div class="titre"><a href="{{ evenement.get_absolute_url }}">{{ evenement.titre|apply:excerpt }}</a></div>
   <div>{{ evenement.description|apply:excerpt }}</div>
 </div>
index effa9e3..2f325c1 100644 (file)
@@ -19,7 +19,7 @@
         <ul class="liste-de-l-accueil">
             {% for chercheur in chercheurs %}
             <li>
-                <div class="titre"><a href="{% url "chercheurs.views.retrieve" chercheur.id %}">{{ chercheur }}</a></div>
+                <div class="titre"><a href="{{ chercheur.get_absolute_url }}">{{ chercheur }}</a></div>
                 {% if chercheur.discipline %}
                 <div>Discipline : {{ chercheur.discipline }}</div>
                 {% endif %}
@@ -42,7 +42,7 @@
             <li>
                 <div>{{ actualite.date|date:"d F Y" }}</div>
                 <div class="titre">
-                    <a href="{% url "actualite" actualite.id %}">{{ actualite.titre|truncatewords:20 }}</a>
+                    <a href="{{ actualite.get_absolute_url }} %}">{{ actualite.titre|truncatewords:20 }}</a>
                 </div>
                 {% if actualite.source %}
                 <div>source: {{ actualite.source.nom }}</div>
@@ -65,7 +65,7 @@
             <li>
                 <div>{{ appel.date|date:"d F Y" }}</div>
                 <div class="titre">
-                    <a href="{% url "actualite" appel.id %}">{{ appel.titre|truncatewords:20 }}</a>
+                    <a href="{{ appel.get_absolute_url }}">{{ appel.titre|truncatewords:20 }}</a>
                 </div>
                 {% if appel.source %}
                 <div>source: {{ appel.source.nom }}</div>
@@ -90,7 +90,7 @@
         {% for ressource in ressources %}
             <li>
                 <div class="titre">
-                    <a href="{% url "savoirs.views.ressource_retrieve" ressource.id %}"
+                    <a href="{{ ressource.get_absolute_url }}"
                         >{{ ressource.title|safe|truncatewords:20 }}</a>
                 </div>
                 {% if resssource.creator %}
             <li>
                 <div>{{ evenement.debut|date:"d/m/Y H\hi" }}</div>
                 <div class="titre">
-                    <a href="{% url "savoirs.views.evenement" evenement.id %}"
+                    <a href="{{ evenement.get_absolute_url }}"
                         >{{ evenement.titre|truncatewords:20 }}</a>
                 </div>
                 <div>{{ evenement.description|truncatewords:20 }}</div>
index c43e443..36e1882 100644 (file)
@@ -62,7 +62,7 @@
     </div>
     <ul>
     {% for chercheur in chercheurs %}
-        <li><a href="{% url "chercheurs.views.retrieve" chercheur.id %}">{{ chercheur }}</a></li>
+        <li><a href="{{ chercheur.get_absolute_url }}">{{ chercheur }}</a></li>
     {% endfor %}
     </ul>
 {% endif %}
index d2ca48c..1fe1d6c 100644 (file)
@@ -3,7 +3,7 @@
 
 <div class="resultatRecherche">
     <div class="titre">
-        <a href="{% url "savoirs.views.ressource_retrieve" ressource.id %}">{{ ressource.title|apply:excerpt }}</a>
+        <a href="{{ ressource.get_absolute_url }}">{{ ressource.title|apply:excerpt }}</a>
     </div>
     {% if ressource.creator %}
     <div><span class="label">Auteur:</span> {{ ressource.creator|apply:excerpt }}</div>
@@ -12,7 +12,7 @@
     <div><span class="label">Résumé:</span> {{ ressource.description|apply:excerpt }}</div>
     {% endif %}
     <div class="details">
-        <div><span>Fiche: </span><a href="{% url "savoirs.views.ressource_retrieve" ressource.id %}">{% url "savoirs.views.ressource_retrieve" ressource.id %}</a></div>
+        <div><span>Fiche: </span><a href="{{ ressource.get_absolute_url }}">{{ ressource.get_absolute_url }}</a></div>
         <div><span>Contenu original: </span><a target="_blank" href="{{ ressource.uri }}">{{ ressource.uri }}</a></div>
         {% if ressource.getServeurURL %}
         <div><span>Provenance: </span><a target="_blank" href="{{ ressource.getServeurURL }}">{{ ressource.getServeurURL }}</a></div>
index 4501d48..2682fc3 100644 (file)
@@ -37,8 +37,10 @@ urlpatterns = sep_patterns + patterns(
 
     # agenda
     url(r'^agenda/$', 'savoirs.views.evenement_index', name='agenda'),
-    url(r'^agenda/evenements/(?P<id>\d+)/$', 'savoirs.views.evenement',
+    url(r'^agenda/evenements/(?P<id>\d+)/(?P<slug>[\w\d\-\_\.]+)$', 'savoirs.views.evenement',
         name='evenement'),
+    url(r'^agenda/evenements/(?P<id>\d+)/$', 'savoirs.views.evenement',
+        name='evenement-canonical'),
     url(r'^agenda/evenements/moderer/$', 'savoirs.views.evenement_moderation'),
     url(r'^agenda/evenements/moderer/(.+)/accepter/$',
         'savoirs.views.evenement_accepter'),
@@ -65,13 +67,17 @@ urlpatterns = sep_patterns + patterns(
 
     # ressources
     url(r'^ressources/$', 'savoirs.views.ressource_index', name='ressources'),
-    url(r'^ressources/(?P<id>\d+)/$', 'savoirs.views.ressource_retrieve',
+    url(r'^ressources/(?P<id>\d+)/(?P<slug>[\w\d\-\_\.]+)$', 'savoirs.views.ressource_retrieve',
         name='ressource'),
+    url(r'^ressources/(?P<id>\d+)/$', 'savoirs.views.ressource_retrieve',
+        name='ressource-canonical'),
 
     # actualités
     url(r'^actualites/$', 'savoirs.views.actualite_index', name='actualites'),
-    url(r'^actualites/(?P<id>\d+)/$', 'savoirs.views.actualite',
+    url(r'^actualites/(?P<id>\d+)/(?P<slug>[\w\d\-\_\.]+)$', 'savoirs.views.actualite',
         name='actualite'),
+    url(r'^actualites/(?P<id>\d+)/$', 'savoirs.views.actualite',
+        name='actualite-canonical'),
     url(r'^appels/$', 'savoirs.views.actualite_index',
         kwargs={'type': 'appels'}, name='appels'),
 
@@ -85,8 +91,10 @@ urlpatterns = sep_patterns + patterns(
 
     # chercheurs
     url(r'^chercheurs/$', 'chercheurs.views.index', name='chercheurs'),
-    url(r'^chercheurs/(?P<id>\d+)/$', 'chercheurs.views.retrieve',
+    url(r'^chercheurs/(?P<id>\d+)/(?P<slug>[\w\d\-\_\.]+)$', 'chercheurs.views.retrieve',
         name='chercheur'),
+    url(r'^chercheurs/(?P<id>\d+)/$', 'chercheurs.views.retrieve',
+        name='chercheur-canonical'),
     url(r'^chercheurs/inscription/$', 'chercheurs.views.inscription',
         name='inscription'),
     url(r'^chercheurs/inscription_faite/$',