Filtrage permanent des disciplines et des régions.
authorEric Mc Sween <eric.mcsween@gmail.com>
Sun, 14 Nov 2010 18:59:08 +0000 (13:59 -0500)
committerEric Mc Sween <eric.mcsween@gmail.com>
Sun, 14 Nov 2010 18:59:08 +0000 (13:59 -0500)
12 files changed:
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/context_processors.py
auf_savoirs_en_partage/media/css/global.css
auf_savoirs_en_partage/savoirs/models.py
auf_savoirs_en_partage/savoirs/templatetags/sep.py [new file with mode: 0644]
auf_savoirs_en_partage/savoirs/templatetags/sep_menu.py [deleted file]
auf_savoirs_en_partage/savoirs/views.py
auf_savoirs_en_partage/settings.py
auf_savoirs_en_partage/sitotheque/models.py
auf_savoirs_en_partage/templates/container_base.html
auf_savoirs_en_partage/templates/menu.html
auf_savoirs_en_partage/urls.py

index adff21d..1e57821 100644 (file)
@@ -87,6 +87,18 @@ class ChercheurQuerySet(models.query.QuerySet, RandomQuerySetMixin):
                 q = q & part
         return self.filter(q) if q is not None else self
 
+    def filter_discipline(self, discipline):
+        """Ne conserve que les chercheurs dans la discipline donnée.
+           
+        Si ``disicipline`` est None, ce filtre n'a aucun effet."""
+        return self.filter(discipline=discipline) if discipline is not None else self
+
+    def filter_region(self, region):
+        """Ne conserve que les évènements dans la région donnée.
+           
+        Si ``region`` est None, ce filtre n'a aucun effet."""
+        return self.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region)) if region is not None else self
+
 
 STATUT_CHOICES = (('enseignant', 'Enseignant-chercheur dans un établissement'), ('etudiant', 'Étudiant-chercheur doctorant'), ('independant', 'Chercheur indépendant docteur'))
 class Chercheur(models.Model):
index eaf84bf..236a5a7 100644 (file)
@@ -1,7 +1,7 @@
 # -*- encoding: utf-8 -*-
 
+import re
 from chercheurs.models import Chercheur, Utilisateur
-
     
 def user_chercheur(request):
     user_chercheur = Chercheur.objects.none()
@@ -14,3 +14,12 @@ def user_chercheur(request):
             pass
     return {'user_chercheur': user_chercheur,
             'user_sep': user_sep,}
+
+DISCIPLINE_REGION_RE = re.compile(r'/(discipline/(?P<discipline>\d+)/)?(region/(?P<region>\d+)/)?')
+def discipline_region(request):
+    match = DISCIPLINE_REGION_RE.match(request.path)
+    discipline = match.group('discipline')
+    region = match.group('region')
+    discipline = discipline and int(discipline)
+    region = region and int(region)
+    return dict(discipline_active=discipline, region_active=region)
index 0688478..36908ff 100644 (file)
@@ -19,11 +19,11 @@ LIGNES grises -> #e0e0e0 et #d5d5d5
 /* General */
 
 html {height:100%;}
-body { height:100%; font-size: 62.5%; /* <- 1em equivaut 10px */ line-height:1.4; color:#3a3125; background:#fff url(../img/background-body.jpg) repeat-y 50% 0; font-family: Verdana, Arial, Sans-Serif; text-align: center;}
+body { height:100%; font-size:62.5%; /* <- 1em equivaut 10px */ line-height:1.4; color:#3a3125; background:#fff url(../img/background-body.jpg) repeat-y 50% 0; font-family:Verdana, Arial, Sans-Serif; text-align:center;}
 a, a:active {text-decoration:underline;color:#97012c;}
 a:visited {color:#97012c;}
 a:hover {color:#97012c;}
-a img {border: none;}
+a img {border:none;}
 abbr, acronym {border-bottom:.1em dotted;cursor:help;}
 
 h1 {font-size:1em;margin:0 0 1em 0;}
@@ -39,26 +39,26 @@ p{margin:0 0 1em 0;}
 ul, ol{margin:0 0 1em 33px;list-style:none;}
 dt{margin:0.5em 0 0;}
 dd{margin:0.25em 0 0.5em 2.5em;}
-sup{font-size: smaller; vertical-align: 0.5em; line-height: 1px;}
-
-td ul { margin: 0 }
-
-form { padding-right:20px; margin: 1em 0; }
-form td { vertical-align: top }
-form th { width: 20em; text-align: left; font-weight: bold }
-form table { width: 100% }
-form input[type=text] { width: 20em }
-form input.date { width: auto }
-form select { width: 80%; overflow: hidden }
-form p { margin-bottom: 2px }
-fieldset { clear: both; padding: 10px; margin: 0 0 0 0; position: relative }
-fieldset { border-color: #000000; border-width: 1px 0 0 0; border-style: solid none none none; }
-fieldset { font-size: 100%; }
-fieldset fieldset { border: 1px solid #ccc; background: #fafafa; margin: 10px }
-legend { font-size: 150%; font-weight: bold; color: #000000; margin: 0 0 0 0; padding: 0 5px; }
+sup{font-size:smaller; vertical-align:0.5em; line-height:1px;}
+
+td ul { margin:0 }
+
+form { padding-right:20px; margin:1em 0; }
+form td { vertical-align:top }
+form th { width:20em; text-align:left; font-weight:bold }
+form table { width:100% }
+form input[type=text] { width:20em }
+form input.date { width:auto }
+form select { width:80%; overflow:hidden }
+form p { margin-bottom:2px }
+fieldset { clear:both; padding:10px; margin:0 0 0 0; position:relative }
+fieldset { border-color:#000000; border-width:1px 0 0 0; border-style:solid none none none; }
+fieldset { font-size:100%; }
+fieldset fieldset { border:1px solid #ccc; background:#fafafa; margin:10px }
+legend { font-size:150%; font-weight:bold; color:#000000; margin:0 0 0 0; padding:0 5px; }
 
 label {
-  font-size: 12px;
+  font-size:12px;
 }
 td, th
 {
@@ -67,11 +67,11 @@ vertical-align:middle;
 
 
 .box { padding:0 0 20px 0; }
-.lbl {color: #97012c; }
+.lbl {color:#97012c; }
 
 .centre { text-align:center }
 
-#fond {padding:0; margin:0; display:block; position:relative; width:100%; height:auto !important; height:100%; min-height:100%; background: url(../img/background-fond.jpg) no-repeat 50% 0; text-align:left;}
+#fond {padding:0; margin:0; display:block; position:relative; width:100%; height:auto !important; height:100%; min-height:100%; background:url(../img/background-fond.jpg) no-repeat 50% 0; text-align:left;}
 #enrobage {padding:0; margin:0 auto; display:block; position:relative; width:960px; height:auto !important; height:100%; min-height:100%;}
 
 div.sous-menu { display:inline; padding-top:1px; color:#fff; font-weight:bold; }
@@ -90,55 +90,56 @@ h5 a { text-decoration:none; }
 
 #sep-recherche {}
 h2.slogan { position:absolute; top:53px; left:240px; font-size:3.4em; color:#3a3125; padding:0;font-family:"Myriad Pro", "Lucida Grande", sans-serif; font-weight:normal; letter-spacing:-1px; line-height:0.8em; z-index:1000; }
-h2.slogan span { display:block; margin: .7em 0 0; font-size:0.55em; color:#97012c; letter-spacing:normal; line-height: 1.1;}
-div.boite-recherche { z-index:1000; position:absolute; top:150px; left:240px; width:390px; height:90px; background: url(../img/recherche-background.gif) no-repeat 0 5px;}
+h2.slogan span { display:block; margin:.7em 0 0; font-size:0.55em; color:#97012c; letter-spacing:normal; line-height:1.1;}
+div.boite-recherche { z-index:1000; position:absolute; top:150px; left:240px; width:390px; height:90px; background:url(../img/recherche-background.gif) no-repeat 0 5px;}
 div.boite-recherche input { position:absolute; top:26px; left:10px; width:300px; height:16px; margin-top:10px; background:none; font-size:1.3em; border:none;}
 div.boite-recherche button { position:absolute; top:22px; right:17px; width:45px; height:45px; background:url(../img/recherche-button.gif) no-repeat 0 0; color:#97012c; border:none;}
 div.boite-recherche button:hover { background:url(../img/recherche-button-over.gif) no-repeat 0 0; cursor:pointer;}
-div.boite-recherche h3 { font-size:2em; font-weight:normal; letter-spacing:-1px; margin: 0;}
-div.boite-recherche h3 span { font-size:.6em; font-weight:normal; letter-spacing: normal;}
-div.boite-recherche p { position:absolute; bottom:13px; left: 0; color:#3a3125; margin: 0; }
+div.boite-recherche h3 { font-size:2em; font-weight:normal; letter-spacing:-1px; margin:0;}
+div.boite-recherche h3 span { font-size:.6em; font-weight:normal; letter-spacing:normal;}
+div.boite-recherche p { position:absolute; bottom:13px; left:0; color:#3a3125; margin:0; }
 div.boite-recherche p a { color:#3a3125;}
 div.boite-recherche p a:hover { color:#97012c; text-decoration:none;}
 
-#col-menu { clear:right; float:right; width:190px; margin:30px 20px 0px 0px; background: url(../img/col-droite-background.png) repeat-x top center; font-size:1.2em; line-height:1.2; }
+#col-menu { clear:right; float:right; width:190px; margin:30px 20px 0px 0px; background:url(../img/col-droite-background.png) repeat-x top center; font-size:1.2em; line-height:1.2; }
 #col-menu img.bottom { margin-bottom:-7px; }
-#col-menu h4 { padding: 0 25px; margin-bottom:0.4em; font-size:1.8em; font-weight:normal; letter-spacing:-1px; }
-#col-menu ul li { margin:2px 0; padding:0; }
-#col-menu a { margin:0; padding:0; text-decoration:none; color:black; }
-#col-menu a:hover { cursor:pointer; text-decoration:underline; }
+#col-menu h4 { margin-bottom:0.4em; margin-left:25px; font-size:1.8em; font-weight:normal; letter-spacing:-1px; }
+#col-menu ul { margin:0 10px 0 25px; padding:0 }
+#col-menu li { margin:0; padding:0; }
+#col-menu a { display:block; margin-left:5px; padding:1px 5px; text-decoration:none; color:black; }
+#col-menu li.active a, #col-menu a:hover { background:#d5d5d5; margin-left:0; border-left: 5px solid #666; }
 #col-menu .actif a { color:#97012c; font-weight:bold; }
 
 #contenu { 
-    float:left; position: relative; width:744px; 
+    float:left; position:relative; width:744px; 
     margin:100px 0px 50px 0px; padding:0; 
     background:url(../img/contenu-bkg-middle.png) repeat-y 0 0; 
 }
 
-#tabs { margin-left: 8px; margin-right: 8px; }
+#tabs { margin-left:8px; margin-right:8px; }
 
-#contenu h4 { padding: 0 25px; margin-bottom:0.4em; font-size:2.2em; font-weight:normal; letter-spacing:-1px; width: 450px; }
+#contenu h4 { padding:0 25px; margin-bottom:0.4em; font-size:2.2em; font-weight:normal; letter-spacing:-1px; width:450px; }
 #contenu h4 a { text-decoration:none; color:black; }
 #contenu h4 a:hover { text-decoration:underline; }
-#contenu h5 { padding: 10px 0 0 25px; margin-bottom:0.4em; font-size:1.8em; font-weight:normal; letter-spacing:-1px; }
+#contenu h5 { padding:10px 0 0 25px; margin-bottom:0.4em; font-size:1.8em; font-weight:normal; letter-spacing:-1px; }
 #contenu h5 a { text-decoration:none; color:black; }
 #contenu h5 a:hover { text-decoration:underline; }
 
-#contenu .zone-texte {padding: 0 25px; font-size: 1.2em; min-height: 375px;}
-#contenu .zone-texte ul li {list-style: disc; margin: 0 0 .25em;}
-#contenu .zone-texte ol li {list-style: decimal; margin: 0 0 .25em;}
-#contenu .zone-texte ul ul, #contenu .zone-texte ol ol {margin-top: .25em; margin-bottom: .25em;}
-#contenu .zone-texte h2 {font-size: 1.2em;}
-#contenu .zone-texte h3 {font-size: 1.1em;}
-#contenu .zone-texte blockquote {margin: 0 2em 1em; font-style: italic;}
-
-#contenu .texte { padding: 0 25px; font-size: 1.2em; }
-#contenu .texte ul li { list-style: disc; margin: 0 0 .25em; }
-#contenu .texte ol li { list-style: decimal; margin: 0 0 .25em; }
-#contenu .texte ul ul, #contenu .description ol ol  { margin-top: .25em; margin-bottom: .25em; }
+#contenu .zone-texte {padding:0 25px; font-size:1.2em; min-height:375px;}
+#contenu .zone-texte ul li {list-style:disc; margin:0 0 .25em;}
+#contenu .zone-texte ol li {list-style:decimal; margin:0 0 .25em;}
+#contenu .zone-texte ul ul, #contenu .zone-texte ol ol {margin-top:.25em; margin-bottom:.25em;}
+#contenu .zone-texte h2 {font-size:1.2em;}
+#contenu .zone-texte h3 {font-size:1.1em;}
+#contenu .zone-texte blockquote {margin:0 2em 1em; font-style:italic;}
+
+#contenu .texte { padding:0 25px; font-size:1.2em; }
+#contenu .texte ul li { list-style:disc; margin:0 0 .25em; }
+#contenu .texte ol li { list-style:decimal; margin:0 0 .25em; }
+#contenu .texte ul ul, #contenu .description ol ol  { margin-top:.25em; margin-bottom:.25em; }
 #contenu .texte a { text-decoration:none; }
 #contenu .texte a:hover { text-decoration:underline; }
-#contenu p.pad { padding: 0 25px; }
+#contenu p.pad { padding:0 25px; }
 
 #contenu img.top, .resultats img.top { height:10px; position:relative; top:-10px; left:0;}
 #contenu img.bottom, .resultats img.bottom{ height:10px; position:relative; bottom:-10px; left:0;}
@@ -147,27 +148,27 @@ div.boite-recherche p a:hover { color:#97012c; text-decoration:none;}
 #contenu .demi-gauche img.top { height:9px; position:relative; top:-9px;}
 #contenu .demi-gauche img.bottom { height:9px;  position:relative; bottom:-9px;}
 
-.contenu-wrapper { padding: 0 25px; }
+.contenu-wrapper { padding:0 25px; }
 
 ul a { text-decoration:none; }
 ul a:hover { text-decoration:underline; }
 
 ul.liste-de-l-accueil { padding:0 2.5em 0 0;}
 ul.liste-de-l-accueil li { margin:1em 0; padding-top:1.1em; border-top:2px solid #d5d5d5;}
-ul.liste-de-l-accueil img { float: left; margin: 0 1em 5px 0; max-width: 75px;}
+ul.liste-de-l-accueil img { float:left; margin:0 1em 5px 0; max-width:75px;}
 ul.liste-de-l-accueil span { display:block;}
 ul.liste-de-l-accueil .la-date { font-size:1.1em; }
 ul.liste-de-l-accueil a.la-date { color:black; }
-ul.liste-de-l-accueil .le-titre {display: block; font-size:1.2em; font-weight:bold; margin: .25em 0;}
+ul.liste-de-l-accueil .le-titre {display:block; font-size:1.2em; font-weight:bold; margin:.25em 0;}
 ul.liste-de-l-accueil .le-resume {font-size:1.1em;}
 ul.liste-de-l-accueil .le-resume a { display:inline;}
-ul.sous-menu li, ul.actions li { display:inline; padding:0px 0px 0px 10px; font-size: 1.1em; }
+ul.sous-menu li, ul.actions li { display:inline; padding:0px 0px 0px 10px; font-size:1.1em; }
 
-ul.actions { position: absolute; top: 15px; right: 20px; width: 240px; text-align: right }
+ul.actions { position:absolute; top:15px; right:20px; width:240px; text-align:right }
 
 .resultats { width:744px; display:inline; margin:0; padding:0; float:left; margin-top:100px; margin-bottom:50px; margin-left:0; background:url(../img/contenu-bkg-middle.png) repeat-y 0 0;}
 .resultats a:hover{text-decoration:none;}
-.resultatRecherche {  padding: 0 25px 1.5em;}
+.resultatRecherche {  padding:0 25px 1.5em;}
 .resultats .typeDocument { text-transform:uppercase;}
 .resultats .le-titre { font-size:1.2em; font-weight:bold; text-decoration:underline;}
 .resultats .resultatResume { font-size:1.1em; color:#000;}
@@ -182,7 +183,7 @@ ul.actions { position: absolute; top: 15px; right: 20px; width: 240px; text-alig
 .resultatPages span a:hover { text-decoration:none;}
 .resultatPages span a:hover span { text-decoration:none;}
 .resultatPages span a span.lien-texte { color:#97012c; text-decoration:underline; font-weight:bold;}
-.resultatPages span a span.lien-texte span { color:#97012c; text-decoration: none; font-weight: normal;}
+.resultatPages span a span.lien-texte span { color:#97012c; text-decoration:none; font-weight:normal;}
 .resultatPages span a:hover span.lien-texte { text-decoration:none;}
 
 /* Divers */
@@ -192,33 +193,33 @@ ul.actions { position: absolute; top: 15px; right: 20px; width: 240px; text-alig
 
 /* Clearfix */
 
-.clearfix {display: inline-block; }
-.clearfix:after, .container:after { content: "."; display: block; height: 0; clear: both; visibility: hidden;}
-* html .clearfix { height: 1%; }
-.clearfix { display: block; }
+.clearfix {display:inline-block; }
+.clearfix:after, .container:after { content:"."; display:block; height:0; clear:both; visibility:hidden;}
+* html .clearfix { height:1%; }
+.clearfix { display:block; }
 
-#edit-form td { vertical-align: top; }
-#edit-form td:first-child { width: 150px; text-align: left; }
-#edit-form table { width: 100%; }
-#edit-form input, #edit-form textarea { width: 80%; }
-#edit-form textarea { height: 100px; }
-#edit-form p { margin-bottom: 2px; }
-#edit-form tr { border-top: 1px black solid; }
-#edit-form tr:first-child { border-top: none; }
+#edit-form td { vertical-align:top; }
+#edit-form td:first-child { width:150px; text-align:left; }
+#edit-form table { width:100%; }
+#edit-form input, #edit-form textarea { width:80%; }
+#edit-form textarea { height:100px; }
+#edit-form p { margin-bottom:2px; }
+#edit-form tr { border-top:1px black solid; }
+#edit-form tr:first-child { border-top:none; }
 
-.odd { background: #ddd; }
+.odd { background:#ddd; }
 
-#repertoire { border:1px solid #bbb; padding:20px; margin: 10px; width:95% }
+#repertoire { border:1px solid #bbb; padding:20px; margin:10px; width:95% }
 #repertoire th, td { padding:5px }
 
 
-.errorlist { color:red; margin: 0 }
-.errorlist li { list-style: none; }
+.errorlist { color:red; margin:0 }
+.errorlist li { list-style:none; }
 
 .publications_autre {border:1px solid #CCC; background:#FAFAFA; margin:10px; padding:10px; display:none;}
 
-#agenda, #actualites {position: relative;}
-#rss-agenda, #rss-actualites {position: absolute; right: 26px; top: 10px;}
+#agenda, #actualites {position:relative;}
+#rss-agenda, #rss-actualites {position:absolute; right:26px; top:10px;}
 
 .infotip
 {
@@ -234,16 +235,16 @@ float:right;
 }
 #fiche_chercheur
 {
-  font-size: 120%;
+  font-size:120%;
 }
 #fiche_chercheur h5
 {
-  font-size: 150%;
-  border-color: #000000;
-  border-width: 1px 0 0 0;
-  border-style: solid none none none;
-  margin-top: 20px;
-  padding: 10px;
+  font-size:150%;
+  border-color:#000000;
+  border-width:1px 0 0 0;
+  border-style:solid none none none;
+  margin-top:20px;
+  padding:10px;
 }
 
 #fiche_chercheur .label
@@ -266,16 +267,16 @@ color:red;
 }
 
 
-.ressource-retrieve * {margin-top: 1em;}
-.ressource-retrieve .fiche {margin-top: 2em;}
+.ressource-retrieve * {margin-top:1em;}
+.ressource-retrieve .fiche {margin-top:2em;}
 
-.fiche, .original, .provenance {font-size: 80%; margin: 2px 0px;}
-.fiche {margin-top: 6px;}
-.fiche a, .original a, .provenance a{text-decoration: none;}
-.back {position: absolute; top: 20px; right: 20px;}
+.fiche, .original, .provenance {font-size:80%; margin:2px 0px;}
+.fiche {margin-top:6px;}
+.fiche a, .original a, .provenance a{text-decoration:none;}
+.back {position:absolute; top:20px; right:20px;}
 
-.horizontal-radio-buttons ul { margin-left: 0 }
-.horizontal-radio-buttons li { display: inline }
+.horizontal-radio-buttons ul { margin-left:0 }
+.horizontal-radio-buttons li { display:inline }
 
-.delete-row { position: absolute; top: 10px; right: 10px }
-.add-row { float: right; margin-right: 21px }
+.delete-row { position:absolute; top:10px; right:10px }
+.add-row { float:right; margin-right:21px }
index 9ec18ab..dfa7cef 100644 (file)
@@ -21,8 +21,9 @@ class RandomQuerySetMixin(object):
 
     def random(self, n=1):
         """Récupère aléatoirement un nombre donné d'objets."""
-        ids = random.sample(xrange(self.count()), n)
-        return [self[i] for i in ids]
+        count = self.count()
+        positions = random.sample(xrange(count), min(n, count))
+        return [self[p] for p in positions]
 
 class Discipline(models.Model):
     id = models.IntegerField(primary_key=True, db_column='id_discipline')
@@ -63,6 +64,18 @@ class ActualiteQuerySet(models.query.QuerySet, RandomQuerySetMixin):
                 q = q & part
         return self.filter(q).distinct() if q is not None else self
 
+    def filter_discipline(self, discipline):
+        """Ne conserve que les actualités dans la discipline donnée.
+           
+        Si ``disicipline`` est None, ce filtre n'a aucun effet."""
+        return self.filter(disciplines=discipline) if discipline is not None else self
+
+    def filter_region(self, region):
+        """Ne conserve que les actualités dans la région donnée.
+           
+        Si ``region`` est None, ce filtre n'a aucun effet."""
+        return self.filter(regions=region) if region is not None else self
+
 class Actualite(models.Model):
     id = models.AutoField(primary_key=True, db_column='id_actualite')
     titre = models.CharField(max_length=765, db_column='titre_actualite')
@@ -124,6 +137,18 @@ class EvenementQuerySet(models.query.QuerySet, RandomQuerySetMixin):
             qs = qs.filter(titre__icontains=word)
         return qs
 
+    def filter_discipline(self, discipline):
+        """Ne conserve que les évènements dans la discipline donnée.
+           
+        Si ``disicipline`` est None, ce filtre n'a aucun effet."""
+        return self.filter(Q(discipline=discipline) | Q(discipline_secondaire=discipline)) if discipline is not None else self
+
+    def filter_region(self, region):
+        """Ne conserve que les évènements dans la région donnée.
+           
+        Si ``region`` est None, ce filtre n'a aucun effet."""
+        return self.filter(regions=region) if region is not None else self
+
 def build_time_zone_choices():
     fr_names = set()
     tzones = []
@@ -366,6 +391,18 @@ class RecordQuerySet(models.query.QuerySet, RandomQuerySetMixin):
             qs = qs.filter(title__icontains=word)
         return qs
             
+    def filter_discipline(self, discipline):
+        """Ne conserve que les ressources dans la discipline donnée.
+           
+        Si ``disicipline`` est None, ce filtre n'a aucun effet."""
+        return self.filter(disciplines=discipline) if discipline is not None else self
+
+    def filter_region(self, region):
+        """Ne conserve que les ressources dans la région donnée.
+           
+        Si ``region`` est None, ce filtre n'a aucun effet."""
+        return self.filter(Q(regions=region) | Q(pays__region=region)) if region is not None else self
+
     def validated(self):
         """Ne garder que les ressources validées et qui sont soit dans aucun
            listset ou au moins dans un listset validé."""
diff --git a/auf_savoirs_en_partage/savoirs/templatetags/sep.py b/auf_savoirs_en_partage/savoirs/templatetags/sep.py
new file mode 100644 (file)
index 0000000..6f94699
--- /dev/null
@@ -0,0 +1,109 @@
+# -*- encoding: utf-8 -*-
+
+from django import template
+from django.conf import settings
+from django.utils.encoding import smart_str
+from datamaster_modeles.models import Region
+from savoirs.models import Discipline
+
+def sep_menu(discipline_active, region_active):
+    regions = Region.objects.filter(actif=True).order_by('nom')
+    disciplines = Discipline.objects.all()
+    return dict(disciplines=disciplines, regions=regions,
+                discipline_active=discipline_active, region_active=region_active)
+
+register = template.Library()
+register.inclusion_tag('menu.html')(sep_menu)
+
+class URLNode(template.Node):
+    def __init__(self, view_name, args, kwargs, asvar):
+        self.view_name = view_name
+        self.args = args
+        self.kwargs = kwargs
+        self.asvar = asvar
+
+    def render(self, context):
+        from django.core.urlresolvers import reverse, NoReverseMatch
+        args = [arg.resolve(context) for arg in self.args]
+        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
+                       for k, v in self.kwargs.items()])
+
+        # C'est ici que nous injectons la discipline et la région courante
+        # dans les arguments.
+        if kwargs.get('discipline') == 'all':
+            del kwargs['discipline']
+        else:
+            context_discipline = context.get('discipline_active')
+            if context_discipline:
+                kwargs.setdefault('discipline', context_discipline)
+        if kwargs.get('region') == 'all':
+            del kwargs['region']
+        else:
+            context_region = context.get('region_active')
+            if context_region:
+                kwargs.setdefault('region', context_region)
+
+        # Try to look up the URL twice: once given the view name, and again
+        # relative to what we guess is the "main" app. If they both fail,
+        # re-raise the NoReverseMatch unless we're using the
+        # {% url ... as var %} construct in which cause return nothing.
+        url = ''
+        try:
+            url = reverse(self.view_name, args=args, kwargs=kwargs, current_app=context.current_app)
+        except NoReverseMatch, e:
+            if settings.SETTINGS_MODULE:
+                project_name = settings.SETTINGS_MODULE.split('.')[0]
+                try:
+                    url = reverse(project_name + '.' + self.view_name,
+                              args=args, kwargs=kwargs, current_app=context.current_app)
+                except NoReverseMatch:
+                    if self.asvar is None:
+                        # Re-raise the original exception, not the one with
+                        # the path relative to the project. This makes a
+                        # better error message.
+                        raise e
+            else:
+                if self.asvar is None:
+                    raise e
+
+        if self.asvar:
+            context[self.asvar] = url
+            return ''
+        else:
+            return url
+
+def sep_url(parser, token):
+    """
+    Le tag ``url`` de Django, modifié pour SEP.
+
+    Lorsque ce tag est utilisé, la discipline et la région actives sont
+    automatiquement réinjectées dans les URL construites.
+
+    On peut annuler cette réinjection en spécifiant l'argument
+    ``region='all'`` ou ``discipline='all'``.
+    """
+    bits = token.split_contents()
+    if len(bits) < 2:
+        raise TemplateSyntaxError("'%s' takes at least one argument"
+                                  " (path to a view)" % bits[0])
+    viewname = bits[1]
+    args = []
+    kwargs = {}
+    asvar = None
+
+    if len(bits) > 2:
+        bits = iter(bits[2:])
+        for bit in bits:
+            if bit == 'as':
+                asvar = bits.next()
+                break
+            else:
+                for arg in bit.split(","):
+                    if '=' in arg:
+                        k, v = arg.split('=', 1)
+                        k = k.strip()
+                        kwargs[k] = parser.compile_filter(v)
+                    elif arg:
+                        args.append(parser.compile_filter(arg))
+    return URLNode(viewname, args, kwargs, asvar)
+sep_url = register.tag(sep_url)
diff --git a/auf_savoirs_en_partage/savoirs/templatetags/sep_menu.py b/auf_savoirs_en_partage/savoirs/templatetags/sep_menu.py
deleted file mode 100644 (file)
index 69e8f52..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# -*- encoding: utf-8 -*-
-from django import template
-from datamaster_modeles.models import Region
-from savoirs.models import Discipline
-
-def sep_menu ():
-    regions = Region.objects.filter(actif=True).order_by('nom')
-    disciplines = Discipline.objects.all()
-    return {'disciplines': disciplines, 'regions':regions}
-
-register = template.Library()
-register.inclusion_tag('menu.html')(sep_menu)
index 0b74761..92d1801 100644 (file)
@@ -19,25 +19,23 @@ from models import *
 from chercheurs.models import Chercheur
 from sitotheque.models import Site
 
-# sous-menu gauche
-def index (request):
+# Accueil
+
+def index (request, discipline=None, region=None):
     """Page d'accueil"""
-    delta = datetime.timedelta (days = 90)
-    oldest = datetime.date.today () - delta
-    actualites = Actualite.objects.filter (visible = '1', date__gt = oldest)
-    actualites = actualites[0:configuration['accueil_actualite']]
-    evenements = Evenement.objects.filter(approuve=True)[0:configuration['accueil_evenement']]
-    ressources = Record.objects.all().random(configuration['accueil_ressource'])
-    chercheurs = Chercheur.objects.all().random(configuration['accueil_chercheur'])
-    sites = Site.objects.all().random(configuration['accueil_sites'])
-    return render_to_response("savoirs/index.html",
-                               dict(actualites=actualites,
-                                    evenements=evenements,
-                                    caldav_url=configuration['calendrier_publique'],
-                                    ressources=ressources,
-                                    chercheurs=chercheurs,
-                                    sites=sites),
-                              context_instance = RequestContext(request))
+    delta = datetime.timedelta(days = 90)
+    oldest = datetime.date.today() - delta
+    actualites = Actualite.objects.filter(visible=True, date__gt=oldest).filter_discipline(discipline).filter_region(region)[:4]
+    evenements = Evenement.objects.filter(approuve=True).filter_discipline(discipline).filter_region(region)[:4]
+    ressources = Record.objects.all().filter_discipline(discipline).filter_region(region).random(4)
+    chercheurs = Chercheur.objects.all().filter_discipline(discipline).filter_region(region).random(10)
+    sites = Site.objects.all().filter_discipline(discipline).filter_region(region).random(4)
+    return render_to_response(
+        "savoirs/index.html",
+        dict(actualites=actualites, evenements=evenements,
+             caldav_url=configuration['calendrier_publique'],
+             ressources=ressources, chercheurs=chercheurs, sites=sites),
+        context_instance = RequestContext(request))
 
 # sous-menu droite
 def a_propos (request):
index 553f56e..d7ec88f 100644 (file)
@@ -34,15 +34,6 @@ TEMPLATE_LOADERS = (
 #     'django.template.loaders.eggs.load_template_source',
 )
 
-TEMPLATE_CONTEXT_PROCESSORS = (
-    'django.core.context_processors.auth',
-    'django.core.context_processors.debug',
-    'django.core.context_processors.i18n',
-    'django.core.context_processors.media',
-    'django.core.context_processors.request',
-)
-
-
 MIDDLEWARE_CLASSES = (
     'django.middleware.cache.UpdateCacheMiddleware',
     'django.middleware.common.CommonMiddleware',
@@ -84,7 +75,9 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     "django.core.context_processors.media",
     "django.core.context_processors.request",
     "context_processors.user_chercheur",
+    "context_processors.discipline_region",
 )
+
 TEMPLATE_LOADERS = (
     'django.template.loaders.filesystem.load_template_source',
     'django.template.loaders.app_directories.load_template_source',
index f6d3953..a99ce72 100644 (file)
@@ -46,6 +46,18 @@ class SiteQuerySet(models.query.QuerySet, RandomQuerySetMixin):
             qs = qs.filter(q).distinct()
         return qs
 
+    def filter_discipline(self, discipline):
+        """Ne conserve que les sites dans la discipline donnée.
+           
+        Si ``disicipline`` est None, ce filtre n'a aucun effet."""
+        return self.filter(discipline=discipline) if discipline is not None else self
+
+    def filter_region(self, region):
+        """Ne conserve que les sites dans la région donnée.
+           
+        Si ``region`` est None, ce filtre n'a aucun effet."""
+        return self.filter(Q(regions=region) | Q(pays__region=region)) if region is not None else self
+
 class Site(models.Model):
     """Fiche d'info d'un site web"""
     url = models.URLField(verify_exists=False)   # dc:identifier (dc:source?)
index ba81784..87409eb 100644 (file)
@@ -1,4 +1,5 @@
 {% load compress %}
+{% load sep %}
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
@@ -70,8 +71,7 @@
                 </div>
 
                 <div id="col-menu">
-                    {% load sep_menu %}
-                    {% sep_menu %}
+                    {% sep_menu discipline_active region_active %}
                     <img src="{{ MEDIA_URL }}img/col-droite-background-bottom.png" width="190" height="8" alt="bottom" align="bottom" class="bottom" />
                 </div>
 
index aefa804..7f92f5e 100644 (file)
@@ -1,42 +1,20 @@
-{% comment %}
-<h4><a href="">Chercheurs</a></h4>
-<ul>
-    <li><a href="">Répertoire</a></li>
-    <li><a href="">Inscription</a></li>
-    <li><a href="">Espace chercheur</a></li>
-</ul>
-
-<h4><a href="">Ressources documentaires</a></h4>
-<ul>
-    <li><a href="">Rechercher un contenu scientifique</a></li>
-</ul>
-
-<h4><a href="">Sites</a></h4>
-<ul>
-    <li><a href="">Sitothèque</a></li>
-    <li><a href="">Cours en ligne</a></li>
-    <li><a href="">Bibliothèques</a></li>
-    <li><a href="">Revues</a></li>
-</ul>
-
-<h4><a href="">Agenda</a></h4>
-<ul>
-    <li><a href="">Colloques</a></li>
-    <li><a href="">Conférences</a></li>
-    <li><a href="">Appels à contribution</a></li>
-</ul>
-{% endcomment %}
-
-<h4><a href="">Régions</a></h4>
+{% load sep %}
+<h4>Régions</h4>
 <ul>
+    <li{% if not region_active %} class="active"{% endif %}
+    ><a href="{% sep_url savoirs.views.index region='all' %}">Toutes les régions</a</li>
     {% for r in regions %}
-    <li><a href="{% url savoirs.views.recherche %}?q={{ r.nom|urlencode }}">{{ r.nom }}</a></li>
+    <li{% ifequal r.id region_active %} class="active"{% endifequal %}
+    ><a href="{% sep_url savoirs.views.index region=r.id %}">{{ r.nom }}</a></li>
     {% endfor %}
 </ul>
 
-<h4><a href="">Disciplines</a></h4>
+<h4>Disciplines</h4>
 <ul>
+    <li{% if not discipline_active %} class="active"{% endif %}
+    ><a href="{% sep_url savoirs.views.index discipline='all' %}">Toutes les disciplines</a></li>
     {% for d in disciplines %}
-    <li><a href="{% url savoirs.views.recherche %}?q={{ d.nom|urlencode }}">{{ d.nom }}</a></li>
+    <li{% ifequal d.id discipline_active %} class="active"{% endifequal %}
+    ><a href="{% sep_url savoirs.views.index discipline=d.id %}">{{ d.nom }}</a></li>
     {% endfor %}
 </ul>
index 985b651..57f1295 100644 (file)
@@ -1,4 +1,5 @@
 # -*- encoding: utf-8 -*-
+
 from django.conf.urls.defaults import patterns, include, handler500, handler404, url
 from django.conf import settings
 from django.contrib import admin
@@ -13,35 +14,18 @@ site_feeds = {'actualites': FilActualite,
               'agenda': FilEvenement }
 
 
-urlpatterns = patterns(
+# Les URLs suivantes peuvent être préfixées de la discipline et/ou la
+# région. Nous les regroupons donc dans un module qu'on incluera plus bas.
+sep_patterns = patterns( 
     '',
 
-    # traduction disponible dans le frontend sans permissons
-    url(r'^jsi18n/$', admin.site.i18n_javascript,),
-
-    url(r'^admin_tools/', include('admin_tools.urls')),
-    (r'^admin/', include(admin.site.urls)),
-    (r'^admin/confirmation/(.*)', 'savoirs.admin_views.confirmation'),
-    (r'^admin/assigner_pays', 'savoirs.admin_views.assigner_pays'),
-    (r'^admin/assigner_thematiques', 'savoirs.admin_views.assigner_thematiques'),
-    (r'^admin/(?P<app_name>[^/]*)/(?P<model_name>[^/]*)/assigner_regions', 'savoirs.admin_views.assigner_regions', {}, 'assigner_regions'),
-    (r'^admin/(?P<app_name>[^/]*)/(?P<model_name>[^/]*)/assigner_disciplines', 'savoirs.admin_views.assigner_disciplines', {}, 'assigner_disciplines'),
-    (r'^admin/(.*)', admin.site.root),
+    # accueil
+    (r'^$', 'savoirs.views.index'),
+)
 
-    (r'^accounts/login/$', 'chercheurs.views.chercheur_login'),
-    (r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'template_name': 'accounts/logout.html'}),
-    (r'^accounts/change_password/$', 'chercheurs.views.change_password'),
-    (r'^accounts/send_password/$', 'chercheurs.views.send_password'),
-    (r'^accounts/new_password/(.+)/(.+)/$', 'chercheurs.views.new_password'),
+urlpatterns = sep_patterns + patterns(
+    '',
 
-    # sous-menu gauche
-    (r'^$', 'savoirs.views.index'),
-    
-    # sous-menu droite
-    (r'^a-propos/$', 'savoirs.views.a_propos'),
-    (r'^legal/$', 'savoirs.views.legal'),
-    (r'^nous-contacter/$', 'savoirs.views.nous_contacter'),
-    
     # recherche
     (r'^recherche/$', 'savoirs.views.recherche'),
     
@@ -77,10 +61,38 @@ urlpatterns = patterns(
     # sites AUF
     (r'^sites-auf/$', 'savoirs.views.sites_auf'),
 
+    # section par discipline et/ou région
+    (r'^discipline/(?P<discipline>\d+)/', include(sep_patterns)),
+    (r'^region/(?P<region>\d+)/', include(sep_patterns)),
+    (r'^discipline/(?P<discipline>\d+)/region/(?P<region>\d+)/', include(sep_patterns)),
+
+    # traduction disponible dans le frontend sans permissons
+    url(r'^jsi18n/$', admin.site.i18n_javascript,),
+
+    url(r'^admin_tools/', include('admin_tools.urls')),
+    (r'^admin/', include(admin.site.urls)),
+    (r'^admin/confirmation/(.*)', 'savoirs.admin_views.confirmation'),
+    (r'^admin/assigner_pays', 'savoirs.admin_views.assigner_pays'),
+    (r'^admin/assigner_thematiques', 'savoirs.admin_views.assigner_thematiques'),
+    (r'^admin/(?P<app_name>[^/]*)/(?P<model_name>[^/]*)/assigner_regions', 'savoirs.admin_views.assigner_regions', {}, 'assigner_regions'),
+    (r'^admin/(?P<app_name>[^/]*)/(?P<model_name>[^/]*)/assigner_disciplines', 'savoirs.admin_views.assigner_disciplines', {}, 'assigner_disciplines'),
+    (r'^admin/(.*)', admin.site.root),
+
+    (r'^accounts/login/$', 'chercheurs.views.chercheur_login'),
+    (r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'template_name': 'accounts/logout.html'}),
+    (r'^accounts/change_password/$', 'chercheurs.views.change_password'),
+    (r'^accounts/send_password/$', 'chercheurs.views.send_password'),
+    (r'^accounts/new_password/(.+)/(.+)/$', 'chercheurs.views.new_password'),
+
+    # sous-menu droite
+    (r'^a-propos/$', 'savoirs.views.a_propos'),
+    (r'^legal/$', 'savoirs.views.legal'),
+    (r'^nous-contacter/$', 'savoirs.views.nous_contacter'),
+
+    # rss
     (r'^rss/(.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict':site_feeds}),
     (r'^json/get/$', 'savoirs.views.json_get'),
     (r'^json/set/$', 'savoirs.views.json_set'),
-
 )
 
 if settings.DEBUG: