diff --git a/.travis.yml b/.travis.yml
index 6871860237..d13ecc88e9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,45 +1,58 @@
 git:
   depth: 1
+
 language: python
+
 python:
-  - "2.7"
+  - 2.7
+
 notifications:
   irc:
     channels:
-      - "irc.smoothirc.net#zds-dev"
+      - irc.smoothirc.net#zds-dev
     skip_join: true
 
 cache:
   - apt
+  - pip
+
 install:
-  - "sudo apt-get update"
-  - "sudo echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections"
-  - "sudo apt-get install ttf-mscorefonts-installer"
-  - "sudo apt-get install texlive"
-  - "sudo apt-get install texlive-xetex"
-  - "sudo apt-get install texlive-lang-french"
-  - "sudo apt-get install texlive-latex-extra"
-  - "sudo mkdir -p ~/cabal/bin"
-  - "sudo mkdir -p ~/.pandoc"
-  - "sudo wget -P ~/cabal/bin https://dl.dropboxusercontent.com/u/18967337/pandoc"
-  - "sudo wget -P ~/.pandoc/templates https://dl.dropboxusercontent.com/u/14517385/dev/default.epub"
-  - "sudo wget -P ~/.pandoc/templates https://dl.dropboxusercontent.com/u/14517385/dev/default.html"
-  - "sudo touch ~/.pandoc/epub.css"
-  - "sudo touch ~/.pandoc/templates/epub.css"
-  - "sudo chmod u+x,g+x,o+x ~/cabal/bin/pandoc"
-  - "export PATH=$PATH:~/cabal/bin"
-  - "sudo ~/cabal/bin/pandoc --version"
-  - "sudo apt-get --reinstall install -qq language-pack-fr"
-  - "pip install -r requirements.txt"
-  - "pip install coveralls"
+  # APT Stuff
+  - sudo apt-get update
+  - sudo echo ttf-mscorefonts-installer msttcorefonts/accepted-mscorefonts-eula select true | sudo debconf-set-selections
+  - sudo apt-get install ttf-mscorefonts-installer
+  - sudo apt-get install texlive
+  - sudo apt-get install texlive-xetex
+  - sudo apt-get install texlive-lang-french
+  - sudo apt-get install texlive-latex-extra
+
+  # Cabal + Pandoc stuff
+  - sudo mkdir -p ~/cabal/bin
+  - sudo mkdir -p ~/.pandoc
+  - sudo wget -P ~/cabal/bin https://dl.dropboxusercontent.com/u/18967337/pandoc
+  - sudo wget -P ~/.pandoc/templates https://dl.dropboxusercontent.com/u/14517385/dev/default.epub
+  - sudo wget -P ~/.pandoc/templates https://dl.dropboxusercontent.com/u/14517385/dev/default.html
+  - sudo touch ~/.pandoc/epub.css
+  - sudo touch ~/.pandoc/templates/epub.css
+  - sudo chmod u+x,g+x,o+x ~/cabal/bin/pandoc
+  - export PATH=$PATH:~/cabal/bin
+  - sudo ~/cabal/bin/pandoc --version
+  - sudo apt-get --reinstall install -qq language-pack-fr
+
+  # Python dependencies
+  - travis_retry pip install -r requirements.txt
+  - travis_retry pip install coveralls
+
   # NodeJS + NPM stuff
-  - "sudo add-apt-repository -y ppa:chris-lea/node.js"
-  - "sudo apt-get -y update"
-  - "sudo apt-get -y install nodejs"
-  - "npm install -g bower gulp"
-  - "npm install"
+  - sudo add-apt-repository -y ppa:chris-lea/node.js
+  - sudo apt-get -y update
+  - sudo apt-get -y install nodejs
+  - npm install -g bower gulp
+  - npm install
+
 script:
   - npm run-script travis
   - coverage run --source='.' manage.py test
+
 after_success:
   - coveralls
diff --git a/AUTHORS b/AUTHORS
index 59f9da9a3b..713c8dc2db 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,12 +4,15 @@ Original code base (pdp / fork on 11-02-2013) : Romain Porte (MicroJoe) <microjo
 "Zeste de Savoir" code base : 
 
 - Alex-D (https://github.com/Alex-D)
+- AlexandreBroudin (https://github.com/AlexandreBroudin)
 - artragis (https://github.com/artragis)
 - cgabard (https://github.com/cgabard)
+- coma94 (https://github.com/coma94)
 - Coy0te (https://github.com/Coy0te)
 - delphiki (https://github.com/delphiki)
 - Eskimon (https://github.com/Eskimon)
 - firm1 (https://github.com/firm1)
+- Florian BOUX (https://github.com/Florianboux)
 - Ge0 (https://github.com/Ge0)
 - geoffreyc (https://github.com/geoffreyc)
 - GerardPaligot (https://github.com/GerardPaligot)
@@ -20,3 +23,4 @@ Original code base (pdp / fork on 11-02-2013) : Romain Porte (MicroJoe) <microjo
 - Taluu (https://github.com/Taluu)
 - Thunderseb (https://github.com/Thunderseb)
 - vhf / victor felder (https://github.com/vhf)
+- Vulser (https://github.com/Vulser)
diff --git a/Gulpfile.js b/Gulpfile.js
index 91193b187c..c03ec38d8d 100644
--- a/Gulpfile.js
+++ b/Gulpfile.js
@@ -1,7 +1,8 @@
 var gulp = require("gulp"),
     $ = require("gulp-load-plugins")(),
     path = require("path"),
-    spritesmith = require("gulp.spritesmith");
+    spritesmith = require("gulp.spritesmith"),
+    mainBowerFiles = require('main-bower-files');
 
 var paths = {
   scripts: "assets/js/**",
@@ -91,7 +92,7 @@ gulp.task("smileys", function() {
 });
 
 gulp.task("vendors", function() {
-  return $.bowerFiles()
+  return gulp.src(mainBowerFiles())
     .pipe($.newer("dist/js/vendors.js"))
     .pipe($.flatten()) // remove folder structure
     .pipe($.size({ title: "vendors", showFiles: true }))
diff --git a/README.md b/README.md
index 9504af2e1d..b8d7eb334f 100644
--- a/README.md
+++ b/README.md
@@ -9,10 +9,9 @@
 Zeste de Savoir
 ===============
 
-Site internet communautaire codé à l'aide du framework Django 1.6.
+Site internet communautaire codé à l'aide du framework [Django](https://www.djangoproject.com/) 1.6 et de [Python](https://www.djangoproject.com/) 2.7.
 
 * Lien du site : [zestedesavoir](http://www.zestedesavoir.com)
-* Lien de teasing : [Teasing](http://zestedesavoir.com/teasing/)
 
 
 
@@ -36,7 +35,7 @@ Fonctionnalités implementées
 Fonctionnalités à venir
 -----------------------
 
-Elles sont reportées essentiellement dans le [bugtraker](https://github.com/zestedesavoir/zds-site/issues)
+Elles sont reportées essentiellement dans le [bugtraker](https://github.com/zestedesavoir/zds-site/issues).
 
 
 
@@ -71,20 +70,20 @@ python manage.py loaddata fixtures/users.yaml fixtures/forums.yaml fixtures/topi
 
 Cela va créer plusieurs entitées :
 
-* 3 utilisateurs (username/password) :
+* 3 utilisateurs (utilisateur/mot de passe) :
 	* user/user : Utilisateur normal
 	* staff/staff : Utilisateur avec les droits d'un staff
 	* admin/admin : Utilisateur avec les droits d'un staff et d'un admin
-* 3 categories
+* 3 catégories
 * 11 forums
-* 3 topics with one answer
-* 1 mp with 3 participants
+* 3 sujets avec une réponse
+* 1 message privé (MP) avec 3 participants
 * 3 catégories et 2 sous-catégories
 
 
-### Conseil de developpement
+### Conseils de developpement
 
-Avant de faire une PR, vérifiez que votre code passe tous les tests unitaires et qu'il est compatible PEP-8 (sous peine de refus de Pull Request) en exécutant les commandes suivantes, pour le back :
+Avant de faire une Pull Request (PR), vérifiez que votre code passe tous les tests unitaires et qu'il est compatible [PEP-8](http://legacy.python.org/dev/peps/pep-0008/) en exécutant les commandes suivantes, pour le back :
 
 ```console
 python manage.py test
@@ -115,9 +114,11 @@ En savoir plus
 --------------
 
 - [Comment déployer ZDS sur un serveur de production ?](doc/deploy.md)
+- [Contribuer](CONTRIBUTING.md)
+- [Comment contribuer : comprendre comment suivre le workflow (sur zds)](http://zestedesavoir.com/forums/sujet/324/comment-contribuer-comprendre-comment-suivre-le-workflow/)
 
 
 
 
 
-Zeste de Savoir est basé sur un fork de [Progdupeu.pl](http://progdupeu.pl) ([Dépôt Bitbucket](https://bitbucket.org/MicroJoe/progdupeupl/))
\ No newline at end of file
+Zeste de Savoir est basé sur un fork de [Progdupeu.pl](http://progdupeu.pl) ([Dépôt Bitbucket](https://bitbucket.org/MicroJoe/progdupeupl/)).
diff --git a/assets/images/clem-home-quote.png b/assets/images/clem-home-quote.png
new file mode 100644
index 0000000000..3e84b97706
Binary files /dev/null and b/assets/images/clem-home-quote.png differ
diff --git a/assets/images/clem-home.png b/assets/images/clem-home.png
new file mode 100644
index 0000000000..1ec7870d05
Binary files /dev/null and b/assets/images/clem-home.png differ
diff --git a/assets/js/accessibility-links.js b/assets/js/accessibility-links.js
index f9600be10a..9831e8c38d 100644
--- a/assets/js/accessibility-links.js
+++ b/assets/js/accessibility-links.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Managment of accessibility links
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/accordeon.js b/assets/js/accordeon.js
index 02a149dce9..9159c5f1d2 100644
--- a/assets/js/accordeon.js
+++ b/assets/js/accordeon.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D
-   ---------------------------------
    Accordeon for sidebar
+   ---------------------------------
+   Author: Alex-D
    ========================================================================== */
 
 (function($){
@@ -10,13 +10,13 @@
     $(".main .sidebar.accordeon, .main .sidebar .accordeon").each(function(){
         var $that = this;
 
-        $("h4 + ul", $that).each(function(){
+        $("h4 + ul, h4 + ol", $that).each(function(){
             if($(".current", $(this)).length === 0)
                 $(this).hide();
         });
 
         $("h4", $that).click(function(e){
-            $("+ ul", $(this)).slideToggle(100);
+            $("+ ul, + ol", $(this)).slideToggle(100);
 
             e.preventDefault();
             e.stopPropagation();
diff --git a/assets/js/autocompletion.js b/assets/js/autocompletion.js
index afeb2c9506..b5cd07715a 100644
--- a/assets/js/autocompletion.js
+++ b/assets/js/autocompletion.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Sandhose / Quentin Gliech
-   ---------------------------------
    Add autocomplete for members names
+   ---------------------------------
+   Author: Sandhose / Quentin Gliech
    ========================================================================== */
 
 (function($) {
@@ -13,8 +13,8 @@
         this.$dropdown = this.$wrapper.find(".autocomplete-dropdown");
 
         this.$dropdown.css({
-            top: "-" + this.$input.css("margin-bottom"),
-            left: this.$input.css("margin-left")
+            "marginTop": "-" + this.$input.css("margin-bottom"),
+            "left": this.$input.css("margin-left")
         });
 
         this.$input.on("keyup", this.handleInput.bind(this));
@@ -59,6 +59,7 @@
                 case 13: // Enter
                     e.preventDefault();
                     e.stopPropagation();
+
                     this.enter();
                     break;
             }
@@ -89,7 +90,7 @@
                         self.updateDropdown(self.sortList(data, search));
                     })
                     .fail(function(){
-                        console.log("something went wrong...");
+                        console.error("[Autocompletition] Something went wrong...");
                     })
                 ;
                 this.updateDropdown(this.sortList(this.searchCache(search), search));
@@ -98,6 +99,8 @@
         },
 
         showDropdown: function(){
+            if(this.$input.is("input"))
+                this.$dropdown.css("width", this.$input.outerWidth());
             this.$dropdown.show();
         },
 
@@ -256,10 +259,16 @@
 
     function buildDom(input) {
         var $input = $(input),
-            $wrapper = $("<span>", { class: "autocomplete-wrapper" }),
-            $dropdown = $("<div>", { class: "autocomplete-dropdown" });
+            $wrapper = $("<div/>", {
+                "class": "autocomplete-wrapper"
+            }),
+            $dropdown = $("<div/>", {
+                "class": "autocomplete-dropdown"
+            })
+        ;
 
         return $input.addClass("autocomplete-input")
+            .attr("autocomplete", "off")
             .wrap($wrapper)
             .parent()
             .append($dropdown)
diff --git a/assets/js/close-alert-box.js b/assets/js/close-alert-box.js
index 7b03fa2c2f..278b8d66f0 100644
--- a/assets/js/close-alert-box.js
+++ b/assets/js/close-alert-box.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Close alert-boxes
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/cookies-banner.js b/assets/js/cookies-banner.js
index 924f088949..e91ef33b54 100644
--- a/assets/js/cookies-banner.js
+++ b/assets/js/cookies-banner.js
@@ -1,30 +1,47 @@
-(function(window, document, undefined) {
-    // Google Analytics ID
-    var gaProperty = "UA-27730868-1";
+/* ===== Zeste de Savoir ====================================================
+   Manage tracking cookies message
+   ---------------------------------
+   Authors: Sandhose
+            Alex-D / Alexandre Demode
+   ========================================================================== */
 
+(function(document, undefined) {
     var $banner = $("#cookies-banner");
 
-    // Disable tracking if the opt-out cookie exists.
-    var disableStr = "ga-disable-" + gaProperty;
-    if(document.cookie.indexOf("hasconsent=true") > -1){
-        window[disableStr] = false;
-    } else if(document.cookie.indexOf("hasconsent=false") > -1){
-        window[disableStr] = true;
-    } else {
-        $banner.show();
+    function checkHasConsent(){
+        if(document.cookie.indexOf("hasconsent=true") > -1){
+            $("#gtm").after(
+                "<script>" +
+                    "dataLayer = [{'gaTrackingId': 'UA-27730868-1'}];" +
+                    "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':" +
+                    "new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0]," +
+                    "j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=" +
+                    "'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);" +
+                    "})(window,document,'script','dataLayer','GTM-WH7642');" +
+                "</script>"
+            );
+        } else if(document.cookie.indexOf("hasconsent=false") === -1){
+            // Accept for the next page
+            setHasConsent(true);
+            
+            // Show the banner
+            $banner.show();
+        }
     }
+    checkHasConsent();
 
-    function sethasconsent(hasconsent){
+
+    function setHasConsent(hasconsent){
         document.cookie = "hasconsent="+hasconsent+"; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/";
-        window[disableStr] = !hasconsent;
-        $banner.slideUp(200);
     }
 
     $("#reject-cookies").on("click", function(){
-        sethasconsent(false);
+        setHasConsent(false);
+        $banner.slideUp(200);
     });
 
     $("#accept-cookies").on("click", function(){
-        sethasconsent(true);
+        checkHasConsent();
+        $banner.slideUp(200);
     });
-})(window, document);
\ No newline at end of file
+})(document);
\ No newline at end of file
diff --git a/assets/js/data-click.js b/assets/js/data-click.js
index df1899a933..e3ab6e31b2 100644
--- a/assets/js/data-click.js
+++ b/assets/js/data-click.js
@@ -1,13 +1,25 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Simulate click on element from another
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
     "use strict";
     
-    $("[data-click]").on("click focus", function(e){
+    var dropdownMouseDown = false;
+    
+    $("[data-click]")
+    .on("mousedown", function(){
+        dropdownMouseDown = true;
+    })
+    .on("mouseup", function(){
+        dropdownMouseDown = false;
+    })
+    .on("click focus", function(e){
+        if(e.type === "focus" && dropdownMouseDown)
+            return false;
+
         if(!($(this).hasClass("dont-click-if-sidebar") && $(".header-container .mobile-menu-btn").is(":visible"))){
             e.preventDefault();
             e.stopPropagation();
diff --git a/assets/js/dropdown-menu.js b/assets/js/dropdown-menu.js
index 5eb033ff6e..3c76b65778 100644
--- a/assets/js/dropdown-menu.js
+++ b/assets/js/dropdown-menu.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Dropdown menu open/close
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
@@ -23,6 +23,9 @@
             dropdownMouseDown = false;
         })
         .on("click", function(e){
+            if(($(this).parents(".header-menu-list").length > 0 && parseInt($("html").css("width")) < 960))
+                return true;
+
             e.preventDefault();
             e.stopPropagation();
 
diff --git a/assets/js/find-solved-topics.js b/assets/js/find-solved-topics.js
index d34e70dc41..c24d2702af 100644
--- a/assets/js/find-solved-topics.js
+++ b/assets/js/find-solved-topics.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Search for solved topics when create a new topic
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/gallery.js b/assets/js/gallery.js
index 8c20b03a57..25d1fa29c0 100644
--- a/assets/js/gallery.js
+++ b/assets/js/gallery.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Sandhose / Quentin Gliech
-   ---------------------------------
    Gallery list and grid views management
+   ---------------------------------
+   Author: Sandhose / Quentin Gliech
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/karma-ajax.js b/assets/js/karma-ajax.js
index 7c8ca47c8c..72748f1588 100644
--- a/assets/js/karma-ajax.js
+++ b/assets/js/karma-ajax.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Manage karma AJAX requests (+1/-1 on messages)
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/keyboard-navigation.js b/assets/js/keyboard-navigation.js
index 628548f3bf..0260126cb0 100644
--- a/assets/js/keyboard-navigation.js
+++ b/assets/js/keyboard-navigation.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Keyboard navigation in navigables lists, with j/k keys
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/markdown-help.js b/assets/js/markdown-help.js
index a0e4ba86d3..b4c99682fd 100644
--- a/assets/js/markdown-help.js
+++ b/assets/js/markdown-help.js
@@ -1,8 +1,8 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Ugly markdown help block management
    TEMP : Add this to the future awesome Markdown editor directly
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
@@ -14,7 +14,7 @@
             "html": "<div class=\"markdown-help-more\">" +
                     "<p>Les simples retours à la ligne ne sont pas pris en compte. Pour créer un nouveau paragraphe, pensez à <em>sauter une ligne</em> !</p>" +
                     "<pre><code>**gras** \n*italique* \n[texte de lien](url du lien) \n> citation \n+ liste a puces </code></pre>" +
-                    "<a href=\"http://zestedesavoir.com/articles/29/rediger-sur-zds/\">Voir la documentation complète</a></div>" +
+                    "<a href=\"//zestedesavoir.com/tutoriels/221/rediger-sur-zds/\">Voir la documentation complète</a></div>" +
                     "<a href=\"#open-markdown-help\" class=\"open-markdown-help btn btn-grey ico-after view\">"+
                         "<span class=\"close-markdown-help-text\">Masquer</span>" +
                         "<span class=\"open-markdown-help-text\">Afficher</span> l'aide Markdown" +
diff --git a/assets/js/message-hidden.js b/assets/js/message-hidden.js
index a87c525576..722b902b34 100644
--- a/assets/js/message-hidden.js
+++ b/assets/js/message-hidden.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Toggle message content for staff
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/mobile-menu.js b/assets/js/mobile-menu.js
index f618da8191..79c492b2e0 100644
--- a/assets/js/mobile-menu.js
+++ b/assets/js/mobile-menu.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Mobile sidebar menu, swipe open/close
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
@@ -178,11 +178,26 @@
         if($elem.hasClass("mobile-show-ico"))
             $div.addClass("mobile-show-ico");
 
-        var $links = ($elem.hasClass("mobile-all-links")) ? $("a:not(.action-hover)", $elem).addClass("mobile-menu-link") : $(".mobile-menu-link", $elem);
+        var $links = ($elem.hasClass("mobile-all-links")) ? $("a, button, span.disabled", $elem).not(".action-hover").addClass("mobile-menu-link") : $(".mobile-menu-link", $elem);
 
         $links.each(function(){
-            if($(this).parents(".mobile-menu-imported").length === 0)
-                $div.append($(this).clone().addClass("light"));
+            if($(this).parents(".mobile-menu-imported, .modal").length === 0){
+                var $elem = $(this).clone().addClass("light");
+                var formId;
+
+                if($(this).is("button")){
+                    var $form = $(this).parents("form:first");
+                    if(!$form.attr("id")){
+                        formId = "form" + $(".identified-form").length;
+                        $form.attr("id", formId).addClass("identified-form");
+                    } else {
+                        formId = $form.attr("id");
+                    }
+                    $elem.attr("form", formId);
+                }
+
+                $div.append($elem);
+            }
         });
 
         $elem.addClass("mobile-menu-imported");
@@ -264,4 +279,35 @@
             }, 200);
         }
     }
+
+
+
+
+    /**
+     * Manage actions buttons, move them at the top af core of page
+     */
+    $(window).on("resize", function(){
+        if(parseInt($("html").css("width")) < 960 && !disableMobileMenu){
+            var $newBtns = $(".sidebar .new-btn:not(.mobile-btn-imported)");
+            if($newBtns.length > 0){
+                var $prevElem = $("#content > .content-wrapper, #content > .full-content-wrapper").find("h1, h2");
+                if($prevElem.next(".license").length > 0)
+                    $prevElem = $prevElem.next(".license");
+                if($prevElem.next(".subtitle").length > 0)
+                    $prevElem = $prevElem.next(".subtitle");
+                if($prevElem.next(".taglist").length > 0)
+                    $prevElem = $prevElem.next(".taglist");
+
+                var $newBtnContainer = $("<div/>", {
+                    "class": "new-btn-container"
+                });
+                $newBtns.each(function(){
+                    $newBtnContainer.append($(this).clone().removeAttr("id").removeClass("blue"));
+                    $(this).addClass("mobile-btn-imported");
+                });
+                $prevElem.after($newBtnContainer);
+            }
+        }
+    });
+    $(window).trigger("resize");
 })(jQuery);
\ No newline at end of file
diff --git a/assets/js/modal.js b/assets/js/modal.js
index 7b3bbcdcbe..2d1e348203 100644
--- a/assets/js/modal.js
+++ b/assets/js/modal.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Manage modals boxes
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/select-autosubmit.js b/assets/js/select-autosubmit.js
index 716cea1dc2..035f4e14f1 100644
--- a/assets/js/select-autosubmit.js
+++ b/assets/js/select-autosubmit.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Auto submit forms
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/spoiler.js b/assets/js/spoiler.js
index f8e29d4985..058cf32012 100644
--- a/assets/js/spoiler.js
+++ b/assets/js/spoiler.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Toggle spoiler content
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/tab-modalize.js b/assets/js/tab-modalize.js
index 739b8bdb01..8b42664dde 100644
--- a/assets/js/tab-modalize.js
+++ b/assets/js/tab-modalize.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Keyboad accessibility for overlayed boxes (modals, etc)
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/js/zen-mode.js b/assets/js/zen-mode.js
index 42aef19285..0f358892bf 100644
--- a/assets/js/zen-mode.js
+++ b/assets/js/zen-mode.js
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Zen mode for content-pages
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 (function($){
diff --git a/assets/scss/_all-supports.scss b/assets/scss/_all-supports.scss
index 16c28309e8..7f59097dee 100644
--- a/assets/scss/_all-supports.scss
+++ b/assets/scss/_all-supports.scss
@@ -1,12 +1,12 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Common style for all supports
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
 
- #accessibility {
+#accessibility {
     list-style: none;
     margin: 0;
     padding: 0 2.5%;
@@ -712,11 +712,13 @@
         }
     }
 
-    h3 + ul {
+    h3 + ul,
+    h3 + ol {
         margin: 7px 0;
     }
 
-    ul {
+    ul,
+    ol {
         margin: 0;
         padding: 0;
         list-style: none;
@@ -939,18 +941,21 @@
             text-overflow: ellipsis;
             white-space: nowrap;
 
-            & + ul > li:first-child {
-                margin-top: 5px;
+            & + ul,
+            & + ol {
+                & > li:first-child {
+                    margin-top: 5px;
+                }
             }
         }
 
-        ul li.current {
+        ol li.current {
             margin-top: 0 !important;
             padding-top: 5px;
             margin-bottom: 5px;
             background-color: #FFF;
 
-            ul {
+            ol {
                 margin-top: 5px;
                 padding-top: 5px;
                 padding-bottom: 5px;
@@ -1011,14 +1016,20 @@
             height: 50px;
         }
 
-        &:not(:first-child) {
+        &:not(.subtitle):not(:first-child) {
             margin-top: 50px;
         }
     }
 
+    .license {
+        float: right;
+        margin-top: -45px;
+    }
+
     .subtitle {
         font-size: 18px;
         font-size: 1.8rem;
+        line-height: 23px;
         color: #999;
         margin-top: -15px;
         margin-bottom: 15px;
@@ -1027,6 +1038,12 @@
         border-bottom: 1px solid #EEE;
     }
 
+    .pubdate {
+        display: block;
+        color: #999;
+        margin-bottom: 15px;
+    }
+
     .member-item {
         margin-right: 7px;
 
@@ -1043,19 +1060,162 @@
     }
     .authors .member-item {
         margin-right: 0;
+        margin-left: 7px;
+
+        .avatar {
+            height: 30px;
+            width: 30px;
+            margin: -3px 5px 0 -6px;
+        }
     }
 
     .open-zen-mode {
         display: none;
     }
+
+    .new-btn-container {
+        display: none;
+    }
 }
-.main.home .content-container {
+.home .main .content-container {
     margin-top: 0;
 }
 
+
+
 /* ==============
     ALL: Main / Home
    ============== */
+.home-wrapper {
+    position: relative;
+    max-width: 1100px;
+    padding: 0 15px;
+    margin: 0 auto;
+}
+.home-quote {
+    width: 100%;
+    min-height: 24px;
+    background: #e9e7e4;
+
+    blockquote {
+        color: #0b668e;
+        font-style: italic;
+        margin: 0;
+        width: 100%;
+        text-align: center;
+    }
+
+    &.home-simple-quote {
+        padding: 20px 0;
+
+        img {
+            position: absolute;
+            height: 80px;
+            top: -15px;
+            left: -20px;
+        }
+
+        blockquote {
+            margin: 0;
+            font-size: 16px;
+            font-size: 1.6rem;
+        }
+    }
+
+    &.home-full-description {
+        padding: 20px 0;
+        min-height: 210px;
+        text-align: center;
+
+        img {
+            margin: 0 0 15px -100px;
+        }
+
+        .home-full-description-text {
+            line-height: 18px;
+            text-align: left;
+
+            h2 {
+                font-size: 22px;
+                font-size: 2.2rem;
+                line-height: 38px;
+                line-height: 3.8rem;
+                color: #084561;
+                font-weight: normal;
+                border-bottom: 1px solid #F8AD32;
+                margin-top: 0;
+            }
+
+            blockquote {
+                color: #0b668e;
+                font-style: italic;
+                font-size: 18px;
+                font-size: 1.8rem;
+                margin: 0;
+            }
+
+            p:last-child {
+                margin-bottom: 0;
+            }
+        }
+    }
+}
+.search-box {
+    width: 100%;
+    min-height: 60px;
+    background: #EEE;
+    box-shadow: rgba(0, 0, 0, .25) 0 0 3px;
+
+    form {
+        min-height: 60px;
+
+        label {
+            display: block;
+            line-height: 40px;
+            font-size: 16px;
+            font-size: 1.6rem;
+            color: #333;
+            text-align: center;
+            width: 100%;
+        }
+
+        input,
+        button {
+            border: 1px solid $orange;
+            background: #FFF;
+            margin: 5px 0 12px;
+        }
+        input {
+            height: 34px;
+            padding: 0 15px;
+            border-right: none;
+            width: 85%;
+            width: calc(100% - 71px);
+        }
+        button {
+            height: 36px;
+            text-indent: -9999px;
+            border-left: none;
+            width: 40px;
+            transition: background .15s;
+            
+            position: absolute;
+            bottom: 0;
+            right: 15px;
+
+            &:hover {
+                background: #EEE;
+            }
+
+            &:after {
+                top: 9px;
+                left: 12px;
+                @include sprite-pos($search);
+            }
+        }
+    }
+}
+
 .tutorial-list article,
 .main .article-content .tutorial-list article {
     min-height: 60px;
@@ -1135,6 +1295,10 @@
     }
     .tutorial-infos {
         margin: 7px 0 0 70px;
+
+        &.no-illu {
+            margin-left: 0;
+        }
     }
 }
 
@@ -1281,7 +1445,7 @@
             &.current {
                 height: 38px;
                 color: #808080;
-                background: #F4F6F6;
+                background: #F7F7F7;
                 margin-top: -1px;
                 border-left: 1px solid #d2d5d6;
                 border-bottom: 3px solid #d2d5d6;
@@ -1599,9 +1763,22 @@
 
     .article-content {
         p,
+        > a,
+        p a,
         ul:not(.pagination),
         ol {
-            font-family: $font-serif;
+            font-family: $font-serif-active;
+        }
+    }
+
+    .comment-author {
+        background: #EEE;
+        padding: 7px 15px;
+
+        blockquote {
+            margin: 10px 0;
+            border-left: 5px solid  #CCC;
+            padding: 5px 0 5px 15px;
         }
     }
 
@@ -1811,6 +1988,9 @@
             figure {
                 margin: 15px 0;
             }
+            &:last-child {
+                margin-bottom: 15px;
+            }
         }
 
         code,
@@ -1848,7 +2028,7 @@
         }
     }
 
-    .reactions-title {
+    .comments-title {
         margin: 50px 0 20px;
         color: $blue;
         border-bottom: 1px solid $orange;
@@ -2503,6 +2683,7 @@ form.topic-message {
                 left: 0;
                 right: 0;
                 padding: 10px 20px 5px;
+                font-size: 15px;
                 font-size: 1.5rem;
                 line-height: 15px;
                 color: #444;
@@ -2557,15 +2738,27 @@ form.topic-message {
     ALL: Markdown help
    ============== */
 .markdown-help {
+    min-height: 50px;
+
     .open-markdown-help {
-        position: absolute;
-        bottom: 0;
-        left: 8px;
-        
+        float: none !important;
+        display: inline-block !important;
+        margin-bottom: 20px;
+
         .close-markdown-help-text {
             display: none;
         }
     }
+    .topic-message & {
+        min-height: 0;
+
+        .open-markdown-help {
+            position: absolute;
+            bottom: 0;
+            left: 8px;
+            margin-bottom: 0;
+        }
+    }
 
     .markdown-help-more {
         display: none;
@@ -2639,9 +2832,16 @@ form.topic-message {
         }
     }
 
-    .version,
-    .version a {
-        color: rgba(255, 255, 255, .5);
+    .version {
+        &,
+        a {
+            color: rgba(255, 255, 255, .5);
+        }
+
+        a:hover,
+        a:focus {
+            color: #FFF;
+        }
     }
 }
 
@@ -2673,8 +2873,8 @@ form.topic-message {
         margin-bottom: 20px;
         background: $blue;
         color: #FFF;
-        font-size: 1.6rem;
         font-size: 16px;
+        font-size: 1.6rem;
         text-shadow: rgba(0, 0, 0, 0.75) 0 0 3px;
 
         &.ico-after {
diff --git a/assets/scss/_base.scss b/assets/scss/_base.scss
index 36281b2579..bc57bee44a 100644
--- a/assets/scss/_base.scss
+++ b/assets/scss/_base.scss
@@ -1,8 +1,8 @@
 /* ===== Zeste de Savoir ====================================================
+   Base style for globals elements & helpers
+   ---------------------------------
    Base from HTML5 BoilerPlate
    Updated by: Alex-D / Alexandre Demode
-   ---------------------------------
-   Base style for globals elements & helpers
    ========================================================================== */
 
 
diff --git a/assets/scss/_editor.scss b/assets/scss/_editor.scss
index c6b7253d0b..ccc3887e03 100644
--- a/assets/scss/_editor.scss
+++ b/assets/scss/_editor.scss
@@ -6,7 +6,6 @@
     margin: 0;
     padding: 2px;
     list-style-position: initial;
-    list-style-image: none;
     list-style-type: none;
     border-bottom: none;
 
diff --git a/assets/scss/_extra-wide.scss b/assets/scss/_extra-wide.scss
index 565c4dedbf..d38acd194b 100644
--- a/assets/scss/_extra-wide.scss
+++ b/assets/scss/_extra-wide.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Only for extra-wide screens with width > 1140px
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
diff --git a/assets/scss/_form.scss b/assets/scss/_form.scss
index c5a86d7af6..3edc8ebd92 100644
--- a/assets/scss/_form.scss
+++ b/assets/scss/_form.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Form style
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
diff --git a/assets/scss/_high-pixel-ratio.scss b/assets/scss/_high-pixel-ratio.scss
index b21e4ea376..b31b50c5c5 100644
--- a/assets/scss/_high-pixel-ratio.scss
+++ b/assets/scss/_high-pixel-ratio.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Override for high pixel ratio screens : HD icons
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
@@ -13,11 +13,10 @@
     }
     .ico,
     .ico-after:after,
-    .breadcrumb ul li:not(:last-child):after,
+    .breadcrumb ol li:not(:last-child):after,
     input[type=radio]:checked,
     input[type=checkbox]:checked {
         background-size: round($sprite_width / 2) round($sprite_height / 2) !important;
-        //background-size: 50% 50% !important;
         background-image: $sprite2x !important;
     }
 
@@ -40,20 +39,26 @@
         }
     }
 
-    .breadcrumb ul li:not(:last-child):after {
+    .breadcrumb ol li:not(:last-child):after {
         @include sprite-pos($ariane, true);
     }
 
-    .search form button:after {
-        @include sprite-pos($search, true);
+    .search,
+    .search-box {
+        form button:after {
+            @include sprite-pos($search, true);
+        }
     }
 
-    .main .content-container h2 {
-        &.ico-articles:after {
-            @include sprite-pos($articles, true);
-        }
-        &.ico-tutorials:after {
-            @include sprite-pos($tutorials, true);
+    .main .content-container {
+        h1,
+        h2 {
+            &.ico-articles:after {
+                @include sprite-pos($articles, true);
+            }
+            &.ico-tutorials:after {
+                @include sprite-pos($tutorials, true);
+            }
         }
     }
 
diff --git a/assets/scss/_mega-wide.scss b/assets/scss/_mega-wide.scss
index b929b8331d..4cbed9c0f4 100644
--- a/assets/scss/_mega-wide.scss
+++ b/assets/scss/_mega-wide.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Only for mega-wide screens with width > 1360px
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
diff --git a/assets/scss/_mobile-tablet.scss b/assets/scss/_mobile-tablet.scss
index e55049a615..0481e2b5ba 100644
--- a/assets/scss/_mobile-tablet.scss
+++ b/assets/scss/_mobile-tablet.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Style only for mobiles and tablets
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
@@ -100,6 +100,10 @@
             .mobile-menu-link {
                 margin: 0;
                 width: 100%;
+
+                &.disabled {
+                    opacity: .5;
+                }
             }
 
             &:not(.mobile-show-ico) .ico-after:after {
@@ -134,6 +138,7 @@
         .mobile-menu-link {
             display: block;
             height: 40px;
+            line-height: 40px;
             text-decoration: none;
             color: #CCC;
             font-size: 16px;
@@ -141,6 +146,10 @@
             text-overflow: ellipsis;
             white-space: nowrap;
             overflow: hidden;
+            background: none;
+            border: none;
+            text-align: left;
+            padding: 0;
 
             &.mobile-menu-sublink {
                 width: 90%;
@@ -381,9 +390,37 @@
     }
 
 
-/* ====================
-    Content positionning
-   ==================== */
+    .main .content-container .new-btn-container {
+        display: block;
+        margin: 30px 0;
+        border-top: 1px solid #DDD;
+        overflow: hidden;
+
+        .new-btn {
+            display: block;
+            width: 100%;
+            padding: 7px 10px 7px 35px;
+            text-decoration: none;
+            height: 30px;
+            line-height: 30px;
+            background: #EEE;
+            color: #333;
+            border-bottom: 1px solid #DDD;
+
+            &.ico-after:after {
+                top: 13px;
+                left: 10px;
+            }
+        }
+    }
+
+
+
+
+
+    /* ====================
+        Content positionning
+       ==================== */
 
     .main {
         width: 100%;
@@ -424,9 +461,11 @@
 
 
 
-/* ====================
-    Forums
-   ==================== */
+
+
+    /* ====================
+        Forums
+       ==================== */
     .topic-list {
         .topic {
             background: none !important;
@@ -452,6 +491,7 @@
                 line-height: 20px;
                 font-size: 12px;
                 width: 50px;
+                margin-top: -2px;
                 margin-left: 10px;
 
                 &.push-badge {
@@ -508,7 +548,7 @@
                 .message-karma {
                     position: absolute;
                     top: 35px;
-                    left: 10px;
+                    left: 7px;
 
                     a,
                     span {
@@ -539,10 +579,18 @@
 
 
 
-/* ====================
-    Tutorials/Articles
-   ==================== */
+
+    /* ====================
+        Tutorials/Articles
+       ==================== */
+
     .main .content-container {
+        .taglist,
+        .pubdate {
+            margin-left: 10px;
+            margin-right: 10px;
+        }
+
         .article-content {
             p,
             ul:not(.pagination) {
@@ -551,10 +599,15 @@
                 font-size: 1.8ex;
             }
         }
-        .content-wrapper {
+        .content-wrapper,
+        .full-content-wrapper {
             h1,
             h2,
-            h3,
+            h3 {
+                padding-left: 10px;
+                padding-right: 10px;
+            }
+
             h4,
             h5,
             h6,
@@ -563,9 +616,10 @@
             p,
             figure,
             blockquote {
-                margin-left: 15px;
-                margin-right: 15px;
+                margin-left: 10px;
+                margin-right: 10px;
             }
+
             figure {
                 p,
                 blockquote {
@@ -578,6 +632,12 @@
 
 
 
+
+
+    /* ====================
+        Footer
+       ==================== */
+
     .page-footer {
         text-align: center;
         height: auto;
diff --git a/assets/scss/_mobile.scss b/assets/scss/_mobile.scss
index 65429ced7e..4fe69521e9 100644
--- a/assets/scss/_mobile.scss
+++ b/assets/scss/_mobile.scss
@@ -1,14 +1,13 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Style only for mobiles and tablets
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
 
 @media only screen and (max-width: 760px) {
     #cookies-banner {
-        display: block;
         position: absolute;
         top: 50px;
         right: 0;
diff --git a/assets/scss/_print.scss b/assets/scss/_print.scss
index 754ea075c3..75bcbe979c 100644
--- a/assets/scss/_print.scss
+++ b/assets/scss/_print.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   From HTML5 BoilerPlate
-   ----------------------
    Print styles
+   ----------------------
+   From HTML5 BoilerPlate
    ========================================================================== */
 
 
diff --git a/assets/scss/_pygments.scss b/assets/scss/_pygments.scss
index ad4538a228..9ba78812c4 100644
--- a/assets/scss/_pygments.scss
+++ b/assets/scss/_pygments.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Updated by: Alex-D / Alexandre Demode
-   ---------------------------------
    Pygments style
+   ---------------------------------
+   Updated by: Alex-D / Alexandre Demode
    ========================================================================== */
 
 .codehilite .hll { background-color: #ffffcc }
diff --git a/assets/scss/_tablet.scss b/assets/scss/_tablet.scss
index f5ea0d1bb2..2252d08e7b 100644
--- a/assets/scss/_tablet.scss
+++ b/assets/scss/_tablet.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Tablet and more
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
diff --git a/assets/scss/_wide.scss b/assets/scss/_wide.scss
index 3e1e9421fc..7fa0db22a9 100644
--- a/assets/scss/_wide.scss
+++ b/assets/scss/_wide.scss
@@ -1,7 +1,7 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    Wide screen support, for wide and extra-wide
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
@@ -127,7 +127,7 @@
             background-image:linear-gradient(left, rgba(231, 235, 236, 0), rgba(231, 235, 236, .75));
         }
 
-        ul {
+        ol {
             margin: 0;
             padding: 0;
             list-style: none;
@@ -227,6 +227,10 @@
             width: 80%;
             margin-right: 0;
 
+            .taglist + .pubdate {
+                margin-top: -40px;
+            }
+
             .open-zen-mode {
                 display: block;
             }
@@ -247,6 +251,7 @@
                 }
 
                 .reactions-title,
+                .pagination:not(.pagination-chapter),
                 .topic-message {
                     display: none;
                 }
@@ -281,7 +286,8 @@
 
             h3,
             h4,
-            ul li {
+            ul li,
+            ol li {
                 padding-left: 11.5%;
             }
 
@@ -298,7 +304,8 @@
             }
 
             &.sommaire ul li.current {
-                ul {
+                ul,
+                ol {
                     margin-left: calc(-11% - 10px);
                     width: calc(111% + 10px);
                     background: linear-gradient(top, rgba(0, 0, 0, .07), transparent 3px);
@@ -315,6 +322,54 @@
     /* ============
        Main / Home
        ============ */
+    .home-quote {
+        blockquote {
+            text-align: left;
+        }
+
+        &.home-simple-quote {
+            img {
+                height: 80px;
+                top: -15px;
+                left: 150px;
+                margin-left: -10px;
+            }
+            
+            blockquote {
+                margin: 0 0 0 300px;
+            }
+        }
+
+        &.home-full-description {
+            img {
+                float: left;
+                margin: 15px 0 0 -15px;
+            }
+
+            .home-full-description-text {
+                margin-left: 300px;
+            }
+        }
+    }
+    .search-box {
+        form {
+            label {
+                line-height: 60px;
+                width: 300px;
+                float: left;
+            }
+
+            input,
+            button {
+                margin: 12px 0;
+                float: left;
+            }
+            input {
+                width: calc(100% - 371px);
+            }
+        }
+    }
+
     .content-cols .main {
         .content-container {
             width: 79%;
@@ -343,7 +398,11 @@
        Main / Message
        ============ */
     .topic-message {
-        margin: 0 0 25px;
+        margin: 25px 0;
+
+        &:first-child {
+            margin-top: 35px;
+        }
 
         .user,
         .message {
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
index 60a345b616..04a04e12eb 100644
--- a/assets/scss/main.scss
+++ b/assets/scss/main.scss
@@ -1,14 +1,11 @@
 /* ===== Zeste de Savoir ====================================================
-   Author: Alex-D / Alexandre Demode
-   ---------------------------------
    All styles for *Zeste de Savoir* website
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
    ========================================================================== */
 
 
 
-//@import "compass";
-//@import "compass/css3/user-interface";
-
 
 
 /**
@@ -49,21 +46,14 @@ $font-serif-active: "Merriweather", $font-serif;
 $font-monospace-active: "Source Code Pro", $font-monospace;
 
 
-/**
- * Custom mixins
- */
-@mixin sprite-pos($_item, $retina: false){
-    @if($retina == false){
-        background-position: nth($_item, 1) nth($_item, 2);
-    } @else {
-        background-position: round(nth($_item, 1)/ 2) round(nth($_item, 2)/ 2);
-    }
-}
+
+
 
 /**
  * Import external mixins
  */
 @import "mixins/display-flex";
+@import "mixins/sprite-pos";
 
 /**
  * Import sprite
diff --git a/assets/scss/mixins/_sprite-pos.scss b/assets/scss/mixins/_sprite-pos.scss
new file mode 100644
index 0000000000..2327d2c766
--- /dev/null
+++ b/assets/scss/mixins/_sprite-pos.scss
@@ -0,0 +1,13 @@
+/* ==========================================================================
+   Mixin for sprite position auto-calculated
+   ---------------------------------
+   Author: Alex-D / Alexandre Demode
+   ========================================================================== */
+
+@mixin sprite-pos($_item, $retina: false){
+    @if($retina == false){
+        background-position: nth($_item, 1) nth($_item, 2);
+    } @else {
+        background-position: round(nth($_item, 1)/ 2) round(nth($_item, 2)/ 2);
+    }
+}
\ No newline at end of file
diff --git a/fixtures/image_test.jpg b/fixtures/image_test.jpg
new file mode 100644
index 0000000000..ab67be56da
Binary files /dev/null and b/fixtures/image_test.jpg differ
diff --git a/package.json b/package.json
index 01c263ce31..bc1c02e576 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,6 @@
   "dependencies": {
     "gulp": "^3.7.0",
     "gulp-autoprefixer": "0.0.7",
-    "gulp-bower-files": "^0.2.4",
     "gulp-cache": "^0.1.11",
     "gulp-clean": "^0.3.0",
     "gulp-compass": "^1.1.9",
@@ -42,6 +41,7 @@
     "gulp-uglify": "^0.3.0",
     "gulp-zip": "^0.3.4",
     "gulp.spritesmith": "^1.1.0",
-    "jshint-stylish": "^0.2.0"
+    "jshint-stylish": "^0.2.0",
+    "main-bower-files": "~1.0.0"
   }
 }
diff --git a/requirements.txt b/requirements.txt
index b5e5adc8b3..b653a5df66 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -28,8 +28,8 @@ factory-boy==2.2.1
 django-discover-runner==0.4
 pygeoip==0.3.1
 pillow
-git+https://github.com/zestedesavoir/Python-ZMarkdown.git@2.4.1-zds.5
-git+https://github.com/zestedesavoir/GitPython.git@0.3.2-RC1.z2
+https://github.com/zestedesavoir/GitPython/archive/0.3.2-RC1.z2.zip
+https://github.com/zestedesavoir/Python-ZMarkdown/archive/2.4.1-zds.9.zip
 flake8
 autopep8
-easy-thumbnails
\ No newline at end of file
+easy-thumbnails
diff --git a/robots.txt b/robots.txt
index 18d2cd5258..d24009198d 100644
--- a/robots.txt
+++ b/robots.txt
@@ -1,8 +1,6 @@
-# www.robotstxt.org/
-# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449
+# www.robotstxt.org
 
 Sitemap: http://zestedesavoir.com/sitemap.xml
 
 User-agent: *
-Disallow: /membres/
 Disallow: /mp/
\ No newline at end of file
diff --git a/templates/500.html b/templates/500.html
index 0efed39cb0..e0a6a3c115 100644
--- a/templates/500.html
+++ b/templates/500.html
@@ -9,7 +9,7 @@
 
 
 {% block headline %}
-    <h2 class="box">Erreur 500</h2>
+    Erreur 500
 {% endblock %}
 
 
diff --git a/templates/article/base.html b/templates/article/base.html
index 7fb5f99cb4..8bc25a9713 100644
--- a/templates/article/base.html
+++ b/templates/article/base.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Articles
+    &bull; Articles
 {% endblock %}
 
 
@@ -15,7 +15,11 @@
 
 
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.article.views.index" %}">Articles</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{% url "zds.article.views.index" %}" itemprop="url">
+            <span itemprop="title">Articles</span>
+        </a>
+    </li>
 {% endblock %}
 
 
@@ -28,6 +32,6 @@
 
 {% block sidebar %}
     <aside class="sidebar mobile-menu-hide">
-		{% include "article/includes/sidebar_base.html" %}
-	</aside>
+        {% include "article/includes/sidebar_base.html" %}
+    </aside>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/article/base_content.html b/templates/article/base_content.html
index e289d13885..26d5909324 100644
--- a/templates/article/base_content.html
+++ b/templates/article/base_content.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Articles
+    &bull; Articles
 {% endblock %}
 
 
@@ -15,7 +15,11 @@
 
 
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.article.views.index" %}">Articles</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{% url "zds.article.views.index" %}" itemprop="url">
+            <span itemprop="title">Articles</span>
+        </a>
+    </li>
 {% endblock %}
 
 
diff --git a/templates/article/find.html b/templates/article/find.html
index 941af27ff9..e31e2953b8 100644
--- a/templates/article/find.html
+++ b/templates/article/find.html
@@ -27,7 +27,7 @@
     {% endwith %}
 
     <li>
-        <a href="{% url "zds.article.views.find_article" usr.username %}">
+        <a href="{% url "zds.article.views.find_article" usr.pk %}">
             Articles rédigés
         </a>
     </li>
diff --git a/templates/article/includes/article_item.part.html b/templates/article/includes/article_item.part.html
index 52e8afd4c8..e321acc93f 100644
--- a/templates/article/includes/article_item.part.html
+++ b/templates/article/includes/article_item.part.html
@@ -15,11 +15,17 @@
             <img src="{{ article.image.article_illu.url }}" alt="" class="tutorial-img avatar">
         {% endif %}
 
-        <div class="tutorial-infos">
-            <h3>{{ article.title }}</h3>
+        <div class="tutorial-infos {% if not article.image %}no-illu{% endif %}">
+            <h3 itemprop="itemListElement">{{ article.title }}</h3>
             <p class="article-metadata">
-                Publié le {{ article.pubdate|format_date }} -
-                <a href="{{ article.get_last_reaction.get_absolute_url }}">
+                {{ article.pubdate|format_date|capfirst }} -
+                <a href="
+                    {% if article.get_reaction_count == 0 %}
+                        {{ link }}#reactions
+                    {% else %}
+                        {{ article.get_last_reaction.get_absolute_url }}
+                    {% endif %}
+                    ">
                     {% if article.get_reaction_count == 0 %}
                         Aucune réaction
                     {% elif article.get_reaction_count == 1 %}
diff --git a/templates/article/includes/sidebar_actions.part.html b/templates/article/includes/sidebar_actions.part.html
index 514897a486..0774394e1f 100644
--- a/templates/article/includes/sidebar_actions.part.html
+++ b/templates/article/includes/sidebar_actions.part.html
@@ -74,45 +74,13 @@ <h3>Gestion</h3>
                 </li>
             {% else %}
                 <li class="inactive">
-                    <span>En attente de validation</span>
-                </li>
-            {% endif %}
-
-            {% if article.sha_public = None %}
-                <li>
-                    <a href="#delete" class="open-modal ico-after cross red">Supprimer</a>
-                    <form action="{% url "zds.article.views.modify" %}" method="post" class="modal modal-small" id="delete">
-                        <p>
-                            Vous vous apprêtez à supprimer <strong>définitivement</strong> l'article "<em>{{ article.title }}</em>".
-                        </p>
-
-                        <input type="hidden" name="article" value="{{ article.pk }}">
-                        <input type="hidden" name="version" value="{{ version }}">
-                        {% csrf_token %}
-                        <button type="submit" name="delete">
-                            Confirmer
-                        </button>
-                    </form>
-                </li>
-                <li>
+                    <span class="ico-after tick">En attente de validation</span>
                 </li>
             {% endif %}
         </ul>
     </div>
 {% endif %}
 
-<div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Télécharger">
-    <h3>Télécharger</h3>
-    <ul>
-        <li>
-            <a href="{% url "zds.article.views.download" %}?article={{ article.pk }}" class="ico-after download blue">
-                Archive
-            </a>
-        </li>
-    </ul>
-</div>
-
-
 
 
 {% if perms.article.change_article %}
@@ -128,10 +96,23 @@ <h3>Validation</h3>
             {% if not article.sha_validation = None %}
                 {% if validation.is_pending %}
                     <li>
-                        <a href="{% url "zds.article.views.reservation" validation.pk %}" class="ico-after lock blue">Réserver</a>
+                        <form action="{% url "zds.article.views.reservation" validation.pk %}" method="post">
+                            {% csrf_token %}
+                            <button type="submit" class="ico-after lock blue">
+                                Réserver
+                            </button>
+                        </form>
                     </li>
                 {% elif validation.is_pending_valid %}
                     {% if validation.validator = user %}
+                        <li>
+                            <form action="{% url "zds.article.views.reservation" validation.pk %}" method="post">
+                                {% csrf_token %}
+                                <button type="submit" class="ico-after lock blue">
+                                    Annuler la réservation
+                                </button>
+                            </form>
+                        </li>
                         <li>
                             <a href="#publish" class="open-modal ico-after tick green">Publier</a>
                             <form action="{% url "zds.article.views.modify" %}" method="post" class="modal modal-medium" id="publish">
@@ -156,9 +137,18 @@ <h3>Validation</h3>
                         </li>
                     {% else %}
                         <li>
-                            <a href="{% url "zds.article.views.reservation" validation.pk %}" class="open-modal ico-after cross blue">
-                                Réservé par {{ validation.validator.username }}, le retirer
+                            <a href="#unreservation" class="open-modal ico-after lock blue">
+                                Réservé par <strong>{{ validation.validator.username }}</strong>, le retirer
                             </a>
+                            <form action="{% url "zds.article.views.reservation" validation.pk %}" method="post" class="modal modal-small" id="unreservation">
+                                {% csrf_token %}
+                                <p>
+                                    La validation de cet article est actuellement réservé par {% include "misc/member_item.part.html" with member=validation.validator %}. Êtes-vous certains de vouloir le retirer ?
+                                </p>
+                                <button type="submit">
+                                    Confirmer
+                                </button>
+                            </form>
                         </li>
                     {% endif %}
                 {% endif %}
@@ -182,4 +172,48 @@ <h3>Validation</h3>
             {% endif %}
         </ul>
     </div>
-{% endif %}
\ No newline at end of file
+{% endif %}
+
+
+
+{% if user in authors.all or perms.article.change_article %}
+    <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Supprimer">
+        <h3>Supprimer</h3>
+        <ul>
+            {% if article.sha_public = None %}
+                <li>
+                    <a href="#delete" class="open-modal ico-after cross red">Supprimer</a>
+                    <form action="{% url "zds.article.views.modify" %}" method="post" class="modal modal-small" id="delete">
+                        <p>
+                            Vous vous apprêtez à supprimer <strong>définitivement</strong> l'article "<em>{{ article.title }}</em>".
+                        </p>
+
+                        <input type="hidden" name="article" value="{{ article.pk }}">
+                        <input type="hidden" name="version" value="{{ version }}">
+                        {% csrf_token %}
+                        <button type="submit" name="delete">
+                            Confirmer
+                        </button>
+                    </form>
+                </li>
+            {% else %}
+                <li class="inactive">
+                    <span class="disabled">Impossible, car en publié</span>
+                </li>
+            {% endif %}
+        </ul>
+    </div>
+{% endif %}
+
+
+
+<div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Télécharger">
+    <h3>Télécharger</h3>
+    <ul>
+        <li>
+            <a href="{% url "zds.article.views.download" %}?article={{ article.pk }}" class="ico-after download blue">
+                Archive
+            </a>
+        </li>
+    </ul>
+</div>
\ No newline at end of file
diff --git a/templates/article/includes/sidebar_base.html b/templates/article/includes/sidebar_base.html
index 8930702010..b4d3f85588 100644
--- a/templates/article/includes/sidebar_base.html
+++ b/templates/article/includes/sidebar_base.html
@@ -6,21 +6,6 @@
     Nouvel article
 </a>
 
-{% if user.is_authenticated %}
-    {% captureas sidebarfilter %}{% spaceless %}
-        {% block sidebar_filter %}{% endblock %}
-    {% endspaceless %}{% endcaptureas %}
-
-    {% if sidebarfilter %}
-        <div class="mobile-menu-bloc mobile-all-links" data-title="Filtres">
-            <h3>Filtres</h3>
-            <ul>
-                {{ sidebarfilter|safe }}
-            </ul>
-        </div>
-    {% endif %}
-{% endif %}
-
 <div class="mobile-menu-bloc mobile-all-links" data-title="Flux">
     <h3>Flux</h3>
     <ul>
diff --git a/templates/article/index.html b/templates/article/index.html
index a03a17e485..6d0c8c392f 100644
--- a/templates/article/index.html
+++ b/templates/article/index.html
@@ -3,34 +3,51 @@
 
 
 {% block title %}
-    Liste des articles
+    {% if tag %}
+        {{ tag }}
+    {% else %}
+        Tous les articles
+    {% endif %}
 {% endblock %}
 
 
 
-{% block meta %}
-    <meta name="description" content="Les articles sont rédigés par la
-    communauté. Ils permettent aussi bien de se tenir informé des dernières
-    innovations du moment que de découvrir de nouvelles notions liées aux
-    différents domaines de l'informatique.">
+{% block description %}
+    {% if tag %}
+        Articles de la communauté à propos de {{ tag }}. Vous pourrez également découvrir de nouvelles notions en parcourant les autres catégories.
+    {% else %}
+        Les articles sont rédigés par la communauté. Ils permettent aussi bien de se tenir 
+        informé des dernières innovations du moment que de découvrir de nouvelles notions 
+        liées à différents domaines : sciences, informatiques, ...
+    {% endif %}
 {% endblock %}
 
 
 
 {% block breadcrumb %}
-    <li>Liste des articles</li>
+    {% if tag %}
+        <li>{{ tag }}</li>
+    {% else %}
+        <li>Tous les articles</li>
+    {% endif %}
 {% endblock %}
 
 
 
 {% block content_out %}
-    <section class="full-content-wrapper">
-        <h2 class="ico-after ico-articles">
+    <section class="full-content-wrapper" itemscope itemtype="http://schema.org/ItemList">
+        <h2 class="ico-after ico-articles" itemprop="name">
             {% block headline %}
-                Liste des articles
+                {% if tag %}
+                    Articles : {{ tag }}
+                {% else %}
+                    Tous les articles
+                {% endif %}
             {% endblock %}
         </h2>
 
+        <meta itemprop="itemListOrder" content="Unordered">
+
         {% block content %}
             {% if articles %}
                 <div class="tutorial-list">
diff --git a/templates/article/member/edit.html b/templates/article/member/edit.html
index 3bb3dc8dad..f98ed703be 100644
--- a/templates/article/member/edit.html
+++ b/templates/article/member/edit.html
@@ -5,13 +5,17 @@
 
 
 {% block title_base %}
-    &#183; Mes articles
+    &bull; Articles
 {% endblock %}
 
 
 
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.member.views.articles" %}">Mes articles</a></li>
+    {% if user in article.authors.all %}
+        <li><a href="{% url "zds.member.views.articles" %}">Mes articles</a></li>
+    {% else %}
+        <li><a href="{% url "zds.article.views.index" %}">Articles</a></li>
+    {% endif %}
 {% endblock %}
 
 
@@ -30,7 +34,7 @@
 
 
 {% block headline %}
-    <h2>Éditer l'article : {{ article.title }}</h2>
+    <h1>Éditer l'article : {{ article.title }}</h1>
 {% endblock %}
 
 
diff --git a/templates/article/member/history.html b/templates/article/member/history.html
index e9039cfe84..cc368a5290 100644
--- a/templates/article/member/history.html
+++ b/templates/article/member/history.html
@@ -1,12 +1,22 @@
 {% extends "article/base_content.html" %}
 {% load emarkdown %}
-{% load date %}
 {% load profile %}
+{% load date %}
 {% load thumbnail %}
 
 
 {% block title %}
-  {{ article.title }}
+    Historique de "{{ article.title }}"
+{% endblock %}
+
+
+
+{% block breadcrumb_base %}
+    {% if user in article.authors.all %}
+        <li><a href="{% url "zds.member.views.articles" %}">Mes articles</a></li>
+    {% else %}
+        <li><a href="{% url "zds.article.views.index" %}">Articles</a></li>
+    {% endif %}
 {% endblock %}
 
 
@@ -29,11 +39,40 @@ <h1 {% if article.image %}class="illu"{% endif %}>
         {% if article.image %}
             <img src="{{article.image.article_illu.url }}" alt="">
         {% endif %}
-        Historique de l'article "{{ article.title }}"
+        Historique de "{{ article.title }}"
     </h1>
     
+    {% if article.licence %}
+        <span class="license" itemprop="license">
+            {{ article.licence }}
+        </span>
+    {% endif %}
+
+    {% if article.description %}
+        <h2 class="subtitle">
+            {{ article.description }}
+        </h2>
+    {% endif %}
+
+    <ul class="taglist" itemprop="keywords">
+        {% for tag in tags.all %}
+            <li>
+                <a href="{% url "zds.article.views.index" %}?tag={{ tag.title }}">
+                    {{ tag.title }}
+                </a>
+            </li>
+        {% endfor %}
+    </ul>
+
+    <span class="pubdate">
+        Publié 
+        <time datetime="{{ article.pubdate|date:"c" }}" pubdate="pubdate" itemprop="datePublished">
+            {{ article.pubdate|format_date }}
+        </time>
+    </span>
+    
     <div class="authors">
-        <span class="authors-label">Contributeurs : </span>
+        <span class="authors-label">Contributeur{{ article.authors.all|pluralize }} : </span>
         <ul>
             {% for member in article.authors.all %}
                 <li>
@@ -47,55 +86,55 @@ <h1 {% if article.image %}class="illu"{% endif %}>
 
 
 {% block content %}
-<table>
-    <thead>
-        <tr>
-            <th>Visbilité</th>
-            <th width="25%">Date</th>
-            <th>Version</th>
-            <th width="10%">Diff</th>
-            <th width="10%">Auteur</th>
-        </tr>
-    </thead>
-    <tbody>
-        {% for log in logs %}
+    <table class="fullwidth">
+        <thead>
             <tr>
-                <td>
-                    {% if article.sha_public = log.newhexsha %}
-                        Publique
-                    {% elif article.sha_validation = log.newhexsha %}
-                        Validation
-                    {% elif article.sha_beta =  log.newhexsha %}
-                        Beta
-                    {% elif article.sha_draft =  log.newhexsha %}
-                        Brouillon
-                    {% endif %}
-                </td>
-                <td>
-                    {{ log.time.0|format_date:True|capfirst }}
-                </td>
-                <td>
-                    <a href="{% url "zds.article.views.view" article.pk article.slug %}?version={{ log.newhexsha }}">
-                        {{ log.message }}
-                    </a>
-                </td>
-                <td>
-                    {# TODO : proposer les diffs sur les articles #}
-                    {# <a href="{% url "zds.article.views.diff" article.pk article.slug %}?sha={{ log.newhexsha }}" > #}
-                        {{ log.newhexsha|truncatechars:8 }}
-                    {# </a> #}
-                </td>
-                <td>
-                    {% with u=log.actor.name|user %}
-                        {% if u %}
-                            {% include "misc/member_item.part.html" with member=u %}
-                        {% else %}
-                            Inconnu
-                        {% endif %}
-                    {% endwith %}
-                </td>
+                <th>Visbilité</th>
+                <th width="25%">Date</th>
+                <th>Version</th>
+                <th width="10%">Diff</th>
+                <th width="10%">Auteur</th>
             </tr>
-        {% endfor %}
-    </tbody>
-</table>
-{% endblock %}
\ No newline at end of file
+        </thead>
+        <tbody>
+            {% for log in logs %}
+                <tr>
+                    <td>
+                        {% if article.sha_public = log.newhexsha %}
+                            Publique
+                        {% elif article.sha_validation = log.newhexsha %}
+                            Validation
+                        {% elif article.sha_beta =  log.newhexsha %}
+                            Beta
+                        {% elif article.sha_draft =  log.newhexsha %}
+                            Brouillon
+                        {% endif %}
+                    </td>
+                    <td>
+                        {{ log.time.0|humane_time }}
+                    </td>
+                    <td>
+                        <a href="{% url "zds.article.views.view" article.pk article.slug %}?version={{ log.newhexsha }}">
+                            {{ log.message }}
+                        </a>
+                    </td>
+                    <td>
+                        {# TODO : proposer les diffs sur les articles #}
+                        {# <a href="{% url "zds.article.views.diff" article.pk article.slug %}?sha={{ log.newhexsha }}" > #}
+                            {{ log.newhexsha|truncatechars:8 }}
+                        {# </a> #}
+                    </td>
+                    <td>
+                        {% with u=log.actor.name|user %}
+                            {% if u %}
+                                {% include "misc/member_item.part.html" with member=u avatar=True %}
+                            {% else %}
+                                <em>Inconnu</em>
+                            {% endif %}
+                        {% endwith %}
+                    </td>
+                </tr>
+            {% endfor %}
+        </tbody>
+    </table>
+{% endblock %}
diff --git a/templates/article/member/index.html b/templates/article/member/index.html
index 1133350d8c..7703d51a02 100644
--- a/templates/article/member/index.html
+++ b/templates/article/member/index.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Mes articles
+    &bull; Articles
 {% endblock %}
 
 
@@ -14,22 +14,69 @@
 
 
 
+{% block breadcrumb %}
+    {% if request.GET.type == "public" %}
+        <li>Publiés</li>
+    {% elif request.GET.type == "draft" %}
+        <li>Brouillons</li>
+    {% else %}
+        <li>Tous mes articles</li>
+    {% endif %}
+{% endblock %}
+
+
+
 {% block title %}
     Mes Articles
+    {% if request.GET.type == "public" %}
+        / Publiés
+    {% elif request.GET.type == "draft" %}
+        / Brouillons
+    {% endif %}
 {% endblock %}
 
 
 
 {% block headline %}
     Mes Articles
+    {% if request.GET.type == "public" %}
+        / Publiés
+    {% elif request.GET.type == "draft" %}
+        / Brouillons
+    {% endif %}
 {% endblock %}
 
 
 
-{% block sidebar_filter %}
-    <li><a href="{% url "zds.member.views.articles" %}">Tous</a></li>
-    <li><a href="{% url "zds.member.views.articles" %}?type=public">Publiés</a></li>
-    <li><a href="{% url "zds.member.views.articles" %}?type=draft">Brouillons</a><li>
+{% block sidebar %}
+    <aside class="sidebar mobile-menu-hide">
+        <a href="{% url "zds.article.views.new" %}" class="ico-after more blue new-btn">
+            Nouvel article
+        </a>
+
+        <div class="mobile-menu-bloc mobile-all-links" data-title="Filtres">
+            <h3>Filtres</h3>
+            <ul>
+                <li>
+                    <a href="{% url "zds.member.views.articles" %}?type=public" class="ico-after tick green {% if request.GET.type == "public" %}unread{% endif %}">
+                        Publiés
+                    </a>
+                </li>
+                <li>
+                    <a href="{% url "zds.member.views.articles" %}?type=draft" class="ico-after tick {% if request.GET.type == "draft" %}unread{% endif %}">
+                        Brouillons
+                    </a>
+                </li>
+                {% if request.GET.type %}
+                    <li>
+                        <a href="{% url "zds.member.views.articles" %}" class="ico-after cross">
+                            Annuler le filtre
+                        </a>
+                    </li>
+                {% endif %}
+            </ul>
+        </div>
+    </aside>
 {% endblock %}
 
 
diff --git a/templates/article/member/new.html b/templates/article/member/new.html
index f81cc5c606..5157bbd86e 100644
--- a/templates/article/member/new.html
+++ b/templates/article/member/new.html
@@ -5,7 +5,7 @@
 
 
 {% block title_base %}
-    &#183; Mes articles
+    &bull; Articles
 {% endblock %}
 
 
@@ -29,7 +29,7 @@
 
 
 {% block headline %}
-    <h2>Nouvel article</h2>
+    <h1>Nouvel article</h1>
 {% endblock %}
 
 
diff --git a/templates/article/member/view.html b/templates/article/member/view.html
index 4b857cedaa..fa97abeaae 100644
--- a/templates/article/member/view.html
+++ b/templates/article/member/view.html
@@ -1,18 +1,23 @@
 {% extends "article/base_content.html" %}
 {% load emarkdown %}
 {% load profile %}
+{% load date %}
 {% load thumbnail %}
 
 
 
 {% block title_base %}
-    &#183; Mes articles
+    &bull; Articles
 {% endblock %}
 
 
 
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.member.views.articles" %}">Mes articles</a></li>
+    {% if user in authors.all %}
+        <li><a href="{% url "zds.member.views.articles" %}">Mes articles</a></li>
+    {% else %}
+        <li><a href="{% url "zds.article.views.index" %}">Articles</a></li>
+    {% endif %}
 {% endblock %}
 
 
@@ -42,6 +47,18 @@ <h1 {% if article.image %}class="illu"{% endif %}>
         {% endif %}
         {{ article.title }}
     </h1>
+    
+    {% if article.licence %}
+        <span class="license">
+            Licence {{ article.licence }}
+        </span>
+    {% endif %}
+
+    {% if article.description %}
+        <h2 class="subtitle">
+            {{ article.description }}
+        </h2>
+    {% endif %}
 
     <ul class="taglist">
         {% for tag in tags.all %}
@@ -52,9 +69,18 @@ <h1 {% if article.image %}class="illu"{% endif %}>
             </li>
         {% endfor %}
     </ul>
+
+    {% if article.sha_public %}
+        <span class="pubdate">
+            Publié 
+            <time datetime="{{ article.pubdate|date:"c" }}" pubdate="pubdate" itemprop="datePublished">
+                {{ article.pubdate|format_date }}
+            </time>
+        </span>
+    {% endif %}
     
     <div class="authors">
-        <span class="authors-label">Contributeurs : </span>
+        <span class="authors-label">Contributeur{{ authors.all|pluralize }} : </span>
         <ul>
             {% for member in authors.all %}
                 <li>
@@ -68,17 +94,29 @@ <h1 {% if article.image %}class="illu"{% endif %}>
             </li>
         </ul>
     </div>
+
+    {% if perms.article.change_article and article.sha_validation != None %}
+        <p class="content-wrapper alert-box info">
+            Cet article est en attente de validation
+        </p>
+        {% if validation.comment_authors %}
+            <div class="content-wrapper comment-author">
+                <p>
+                    Le message suivant a été laissé à destination des validateurs : 
+                </p>
+
+                <blockquote>
+                    {{ validation.comment_authors }}
+                </blockquote>
+            </div>
+        {% endif %}
+    {% endif %}
 {% endblock %}
 
 
 
 {% block content %}
-    <h3>Description</h3>
-    <p>
-        {{ article.description }}
-    </p>
-    <hr>
     <div>
         {{ article.txt|emarkdown }}
     </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/templates/article/validation/history.html b/templates/article/validation/history.html
index b34f30a717..591b823d7d 100644
--- a/templates/article/validation/history.html
+++ b/templates/article/validation/history.html
@@ -1,5 +1,6 @@
 {% extends "article/base.html" %}
 {% load date %}
+{% load captureas %}
 
 
 
@@ -18,80 +19,58 @@
 
 
 {% block headline %}
-    <h2>Historique de validation de : {{ article.title }}</h2>
+    {{ article.title }}
 {% endblock %}
 
 
 
-{% block sidebar_actions %}
-    {% include 'article/includes/sidebar_actions.part.html' %}
+{% block headline_sub %}
+    Historique de validation
 {% endblock %}
 
 
 
 {% block content %}
+    <ul class="taglist">
+        {% for tag in tags.all %}
+            <li>
+                <a href="{% url "zds.article.views.index" %}?tag={{ tag.title }}">
+                    {{ tag.title }}
+                </a>
+            </li>
+        {% endfor %}
+    </ul>
+    
+    <div class="authors">
+        <span class="authors-label">Contributeur{{ authors.all|pluralize }} : </span>
+        <ul>
+            {% for member in authors.all %}
+                <li>
+                    {% include "misc/member_item.part.html" with avatar=True %}
+                </li>
+            {% endfor %}
+        </ul>
+    </div>
+
     {% if validations %}
-        <table>
+        <table class="fullwidth">
             <thead>
                 <tr>
-                    <th>Titre</th>
-                    <th width="8%">Catégorie(s)</th>
-                    <th width="8%">Auteur(s)</th>
-                    <th width="8%">Proposé</th>
-                    <th width="8%">Validateur</th>
-                    <th width="8%">Réservé</th>
-                    <th width="8%">Action</th>
+                    <th width="50%">Proposé</th>
+                    <th width="50%">Statut</th>
                 </tr>
             </thead>
             <tbody>
                 {% for validation in validations %}
                     <tr>
                         <td>
-                            <a href="{% url "zds.article.views.view" validation.article.pk validation.article.slug %}?version={{ validation.version }}" >{{ validation.article.title }}</a>
-                        </td>
-                        <td>
-                            {% for subcategory in validation.article.subcategory.all %}
-                                <a href="{% url "zds.article.views.history_validation" article.pk %}?subcategory={{subcategory.pk}}">
-                                    {{ subcategory.title }}
-                                </a>
-                            {% endfor %}
-                        </td>
-                        <td>
-                            {% for author in validation.article.authors.all %}
-                                <a href="{% url "zds.member.views.details" user.username %}">
-                                    {{ author.username }}
-                                </a>
-                            {% endfor %}
-                        </td>
-                        <td>
-                            <span>{{ validation.date_proposition|format_date|capfirst }}</span>
-                        </td>
-                        <td>
-                            {% if validation.validator %}
-                                <a href="{% url "zds.member.views.details" validation.validator.username %}">
-                                    {{ validation.validator.username }}
-                                </a>
-                            {% endif %}
-                        </td>
-                        <td>
-                            {% if validation.date_reserve %}
-                                <span>{{ validation.date_reserve|format_date|capfirst }}</span>
-                            {% endif %}
+                            {{ validation.date_proposition|format_date|capfirst }}
                         </td>
                         <td>
-                            {% if validation.is_pending %}
-                                <a href="{% url "zds.article.views.reservation" validation.pk %}">
-                                    Réservé
-                                </a>
-                            {% elif validation.is_pending_valid %}
-                                <a href="{% url "zds.article.views.reservation" validation.pk %}">
-                                    Annuler la réservation
-                                </a>
-                            {% elif validation.is_accept %}
-                                <span>Accepté</span>
-                            {% elif validation.is_reject %}
-                                <span>Rejeté</span>
-                            {% endif %}
+                            {% captureas reservation_url %}
+                                {% url "zds.article.views.reservation" validation.pk %}
+                            {% endcaptureas %}
+                            {% include "misc/validation.part.html" %}
                         </td>
                     </tr>
                 {% endfor %}
diff --git a/templates/article/validation/index.html b/templates/article/validation/index.html
index a93b449266..7d509cfc65 100644
--- a/templates/article/validation/index.html
+++ b/templates/article/validation/index.html
@@ -22,20 +22,22 @@
         <h3>Filtres</h3>
         <ul>
             <li>
-                <a href="{% url "zds.article.views.list_validation" %}?type=reserved">
+                <a href="{% url "zds.tutorial.views.list_validation" %}?type=reserved" class="ico-after tick green {% if request.GET.type == "reserved" %}unread{% endif %}">
                     En cours de validation
                 </a>
             </li>
             <li>
-                <a href="{% url "zds.article.views.list_validation" %}?type=orphan">
+                <a href="{% url "zds.tutorial.views.list_validation" %}?type=orphan" class="ico-after tick {% if request.GET.type == "orphan" %}unread{% endif %}">
                     En attente de validateur
                 </a>
             </li>
-            <li>
-                <a href="{% url "zds.article.views.list_validation" %}">
-                    Annuler le filtre
-                </a>
-            </li>
+            {% if request.GET.type %}
+                <li>
+                    <a href="{% url "zds.tutorial.views.list_validation" %}" class="ico-after cross blue">
+                        Annuler le filtre
+                    </a>
+                </li>
+            {% endif %}
         </ul>
     </div>
 {% endblock %}
diff --git a/templates/article/view.html b/templates/article/view.html
index 4657b1a504..13de5eb1b0 100644
--- a/templates/article/view.html
+++ b/templates/article/view.html
@@ -1,6 +1,7 @@
 {% extends "article/base_content.html" %}
 {% load emarkdown %}
 {% load captureas %}
+{% load date %}
 {% load profile %}
 {% load crispy_forms_tags %}
 {% load set %}
@@ -19,15 +20,33 @@
 
 
 
+{% block article_schema %}
+    itemscope itemtype="http://schema.org/Article"
+{% endblock %}
+
+
+
 {% block headline %}
-    <h1 {% if article.image %}class="illu"{% endif %}>
+    <h1 {% if article.image %}class="illu"{% endif %} itemprop="name">
         {% if article.image %}
-            <img src="{{ article.image.article_illu.url }}" alt="">
+            <img src="{{ article.image.article_illu.url }}" alt="" itemprop="thumbnailUrl">
         {% endif %}
         {{ article.title }}
     </h1>
+    
+    {% if article.licence %}
+        <span class="license" itemprop="license">
+            {{ article.licence }}
+        </span>
+    {% endif %}
+
+    {% if article.description %}
+        <h2 class="subtitle">
+            {{ article.description }}
+        </h2>
+    {% endif %}
 
-    <ul class="taglist">
+    <ul class="taglist" itemprop="keywords">
         {% for tag in tags.all %}
             <li>
                 <a href="{% url "zds.article.views.index" %}?tag={{ tag.title }}">
@@ -36,13 +55,20 @@ <h1 {% if article.image %}class="illu"{% endif %}>
             </li>
         {% endfor %}
     </ul>
+
+    <span class="pubdate">
+        Publié 
+        <time datetime="{{ article.pubdate|date:"c" }}" pubdate="pubdate" itemprop="datePublished">
+            {{ article.pubdate|format_date }}
+        </time>
+    </span>
     
     <div class="authors">
-        <span class="authors-label">Contributeurs : </span>
+        <span class="authors-label">Contributeur{{ authors.all|pluralize }} : </span>
         <ul>
             {% for member in authors.all %}
                 <li>
-                    {% include "misc/member_item.part.html" with avatar=True %}
+                    {% include "misc/member_item.part.html" with avatar=True author=True %}
                 </li>
             {% endfor %}
         </ul>
@@ -51,62 +77,8 @@ <h1 {% if article.image %}class="illu"{% endif %}>
 
 
 
-{% block sidebar_actions %}
-    {% if perms.article.change_article %}
-        <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Validation">
-            <h3>Validation</h3>
-            <ul>
-                <li>
-                    <a href="{{ article.get_absolute_url }}" class="ico-after offline blue">
-                        Version hors ligne
-                    </a>
-                </li>
-                <li>
-                    <a href="#unpublish" class="open-modal ico-after cross blue">Dépublier</a>
-                    <form action="{% url "zds.article.views.modify" %}" method="post" class="modal modal-small" id="unpublish">
-                        <p>
-                            <strong>Attention !</strong> Vous allez dépublier un article actuellement <strong>en ligne</strong>.
-                        </p>
-                        <button type="submit" name="invalid-article">
-                            Confirmer
-                        </button>
-                        <input type="hidden" name="article" value="{{ article.pk }}">
-                        <input type="hidden" name="version" value="{{ version }}">
-                        {% csrf_token %}
-                    </form>
-                </li>
-                <li>
-                    <a href="{% url "zds.article.views.history_validation" article.pk %}" class="ico-after history blue">
-                        Historique de validation
-                    </a>
-                </li>
-            </ul>
-        </div>
-    {% elif user in authors.all %}
-        <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Gestion">
-            <h3>Gestion</h3>
-            <ul>
-                <li>
-                    <a href="{{ article.get_absolute_url }}" class="ico-after offline blue">
-                        Version hors ligne
-                    </a>
-                </li>
-            </ul>
-        </div>
-    {% endif %}
-
-    <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Télécharger">
-        <h3>Télécharger</h3>
-        <ul>
-            <li>
-                <a href="{% url "zds.article.views.download" %}?article={{ article.pk }}"
-                   class="ico-after download blue"
-                >
-                    Archive
-                </a>
-            </li>
-        </ul>
-    </div>
+{% block article_content_schema %}
+    itemprop="articleBody"
 {% endblock %}
 
 
@@ -114,17 +86,26 @@ <h3>Télécharger</h3>
 {% block content %}
     {{ article.txt|safe }}
 
-
+ 
     {% include "article/includes/pager.part.html" %}
 {% endblock %}
 
 
 
 {% block content_after %}
-    <h3 class="reactions-title">Réactions</h3>
+    <h3 class="comments-title" id="reactions">
+        {% if article.get_reaction_count > 0 %}
+            <span itemprop="commentCount">
+                {{ article.get_reaction_count }}
+            </span>
+            réaction{{ article.get_reaction_count|pluralize }}
+        {% else %}
+            Aucune réaction
+        {% endif %}
+    </h3>
 
 
-    {% include "misc/pagination.part.html" with position="top" topic=article is_online=True %}
+    {% include "misc/pagination.part.html" with position="top" topic=article is_online=True anchor="reactions" %}
 
 
     {% for message in reactions %}
@@ -159,11 +140,11 @@ <h3 class="reactions-title">Réactions</h3>
         {% endif %}
 
 
-        {% include "misc/message.part.html" with perms_change=perms.article.change_reaction topic=article %}
+        {% include "misc/message.part.html" with perms_change=perms.article.change_reaction topic=article comment_schema=True %}
     {% endfor %}
 
 
-    {% include "misc/pagination.part.html" with position="bottom" topic=article is_online=True %}
+    {% include "misc/pagination.part.html" with position="bottom" topic=article is_online=True anchor="reactions" %}
 
 
     
@@ -173,3 +154,63 @@ <h3 class="reactions-title">Réactions</h3>
 
     {% include "misc/message_form.html" with member=user topic=article %}
 {% endblock %}
+
+
+
+{% block sidebar_actions %}
+    {% if perms.article.change_article %}
+        <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Validation">
+            <h3>Validation</h3>
+            <ul>
+                <li>
+                    <a href="{{ article.get_absolute_url }}" class="ico-after offline blue">
+                        Version hors ligne
+                    </a>
+                </li>
+                <li>
+                    <a href="#unpublish" class="open-modal ico-after cross blue">Dépublier</a>
+                    <form action="{% url "zds.article.views.modify" %}" method="post" class="modal modal-small" id="unpublish">
+                        <p>
+                            <strong>Attention !</strong> Vous allez dépublier un article actuellement <strong>en ligne</strong>.
+                        </p>
+                        <button type="submit" name="invalid-article">
+                            Confirmer
+                        </button>
+                        <input type="hidden" name="article" value="{{ article.pk }}">
+                        <input type="hidden" name="version" value="{{ version }}">
+                        {% csrf_token %}
+                    </form>
+                </li>
+                <li>
+                    <a href="{% url "zds.article.views.history_validation" article.pk %}" class="ico-after history blue">
+                        Historique de validation
+                    </a>
+                </li>
+            </ul>
+        </div>
+    {% elif user in authors.all %}
+        <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Gestion">
+            <h3>Gestion</h3>
+            <ul>
+                <li>
+                    <a href="{{ article.get_absolute_url }}" class="ico-after offline blue">
+                        Version hors ligne
+                    </a>
+                </li>
+            </ul>
+        </div>
+    {% endif %}
+
+    <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Télécharger">
+        <h3>Télécharger</h3>
+        <ul>
+            <li>
+                <a href="{% url "zds.article.views.download" %}?article={{ article.pk }}"
+                   class="ico-after download blue"
+                >
+                    Archive
+                </a>
+            </li>
+        </ul>
+    </div>
+{% endblock %}
diff --git a/templates/base.html b/templates/base.html
index d1064c560e..bd057037e5 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -5,59 +5,88 @@
 {% load captureas %}
 {% load date %}
 {% load set %}
+{% load captureas %}
 {% load thumbnail %}
 
 
 
 <!DOCTYPE html>
-<html class="no-js enable-mobile-menu wf-active">
+<html class="no-js enable-mobile-menu wf-active" lang="fr">
 <head>
     <meta charset="utf-8">
 
     <title>
-        {% block title %}{% endblock %}
-        {% block title_base %}{% endblock %}
-        &bull; Zeste de Savoir
+        {% captureas title %}
+            {% captureas title_blocks %}
+                {% block title %}{% endblock %}
+                {% block title_base %}{% endblock %}
+            {% endcaptureas %}
+            {% if title_blocks %}
+                {{ title_blocks|safe }}
+                &bull;
+            {% endif %}
+            Zeste de Savoir
+        {% endcaptureas %}
+        {{ title|safe }}
     </title>
 
+    <meta name="language" content="fr">
+    <meta http-equiv="content-language" content="fr">
     <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0">
+    
 
-    {% block meta %}{% endblock %}
-
+    {# Description #}
+    {% captureas description %}
+        {% block description %}
+            Zeste de Savoir est un site de partage de connaissances sur lequel vous trouverez des tutoriels de tous niveaux, des articles et des forums d'entraide animés par 
+            et pour la communauté.
+        {% endblock %}
+    {% endcaptureas %}
+    <meta name="description" content="{{ description|safe }}">
+
+
+    {% captureas image %}
+        {{ request.META.HTTP_HOST }}{% block image %}{% spaceless %}
+            {% static "images/apple-touch-icon-144x144-precomposed.png" %}
+        {% endspaceless %}{% endblock %}
+    {% endcaptureas %}
+
+
+    {# OpenGraph #}
+    <meta property="og:site_name" content="Zeste de Savoir">
+    <meta property="og:title" content="{{ title|safe }}">
+    <meta property="og:url" content="{{ request.build_absolute_uri }}">
+    <meta property="og:language" content="fr_FR">
+    <meta property="og:image:url" content="http://{{ image }}">
+    <meta property="og:image:secure_url" content="https://{{ image }}">
+    {% block opengraph %}
+        <meta property="og:type" content="website">
+    {% endblock %}
+
+
+    {# Twitter cards #}
+    <meta property="twitter:domain" content="http://zestedesavoir.com/">
+    <meta property="twitter:card" content="summary">
+    <meta property="twitter:url" content="{{ request.build_absolute_uri }}">
+    <meta property="twitter:title" content="{{ title|safe }}">
+    <meta property="twitter:description" content="{{ description|safe }}">
+    <meta property="twitter:site" content="@ZesteDeSavoir">
+    <meta property="twitter:creator" content="@{% block twitter_creator %}ZesteDeSavoir{% endblock %}">
+    <meta property="twitter:image" content="http://{{ image }}">
+
+
+    {# Stylesheets #}
     {% if debug %}
-    <link rel="stylesheet" href="/static/css/main.css" />
+        <link rel="stylesheet" href="/static/css/main.css">
     {% else %}
-    <link rel="stylesheet" href="/static/css/main.min.css" />
-    {% block source_content %}{% endblock %}
+        <link rel="stylesheet" href="/static/css/main.min.css">
+        {% block canonical %}{% endblock %}
     {% endif %}
 
-    {# Webfont async loading #}
-    {# Do not put this code into a distant file #}
-    <!-- TODO : optimiser ça pour ne pas voir le changement de font à chaque page
-    <script>
-        WebFontConfig = {
-            google: {
-              families: ['Source Sans Pro:400,700', 'Source Code Pro:400,700', 'Merriweather:400,700']
-            }
-        };
-
-        (function() {
-            var wf = document.createElement('script');
-            wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
-                      '://ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js';
-            wf.type = 'text/javascript';
-            wf.async = 'true';
-            var s = document.getElementsByTagName('script')[0];
-            s.parentNode.insertBefore(wf, s);
-        })();
-    </script>
-    -->
-    <!-- TEMP : load fonts from Google / Procude FOUT effect (see above) -->
-    <link href='http://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700|Source+Code+Pro:400,700|Merriweather:400,700' rel='stylesheet' type='text/css'>
 
+    {# Webfont async loading #}
+    <link href='//fonts.googleapis.com/css?family=Source+Sans+Pro:400,700|Source+Code+Pro:400,700|Merriweather:400,700' rel='stylesheet' type='text/css'>
 
-    {# for additionnal css in some pages #}
-    {% block extracss %}{% endblock %}
 
     {# favicons #}
     <link rel="shortcut icon" type="image/png" href="{% static "images/favicon.png" %}">
@@ -68,17 +97,20 @@
     <link rel="apple-touch-icon" href="{% static "images/apple-touch-icon-precomposed.png" %}">
     <link rel="apple-touch-icon" href="{% static "images/apple-touch-icon.png" %}">
 
+
     {# Fullsceen on iOS #}
     <meta name="apple-mobile-web-app-capable" content="yes">
 
-    {# RSS links #}
-    <link rel="alternate" type="application/rss+xml"
-          title="Forum" href="{% url "post-feed-rss" %}"/>
 
+    {# RSS links #}
+    <link rel="alternate" type="application/rss+xml" title="Forum" href="{% url "post-feed-rss" %}">
 </head>
-<body class="{% block body_class %}{% endblock %}">
-    <!--[if lt IE 7]>
-        <p class="chromeframe">Vous utilisez un navigateur <strong>dépassé</strong>. Merci de <a href="http://browsehappy.com/">mettre à jour celui-ci</a> ou <a href="http://www.google.com/chromeframe/?redirect=true">activer Google Chrome Frame</a> pour améliorer votre expérience.</p>
+<body class="{% block body_class %}{% endblock %}" 
+      itemscope 
+      itemtype="http://schema.org/WebPage"
+>
+    <!--[if lt IE 8]>
+        <p class="chromeframe">Vous utilisez un navigateur <strong>dépassé</strong>. Merci de <a href="http://browsehappy.com/">mettre à jour celui-ci</a> pour améliorer votre expérience.</p>
     <![endif]-->
 
     <div class="mobile-menu" id="mobile-menu"></div>
@@ -98,12 +130,12 @@
         </ul>
 
         <div id="cookies-banner">
-            <p>
-                Ce site utilise Google Analytics. En continuant à naviguer, vous nous autorisez à déposer des cookies à des fins de mesure d'audience. Pour s'opposer à ce dépôt vous pouvez cliquer 
-                <button id="reject-cookies">ici</button>.
-                <a href="/pages/cookies">En savoir plus</a>
-                <button id="accept-cookies">OK</button>
-            </p>
+            <span>
+                Ce site utilise Google Analytics. En poursuivant votre navigation sur ce site, vous nous autorisez à déposer des cookies à des fins de mesure d'audience. Pour s'opposer à ce dépôt vous pouvez cliquer 
+            </span>
+            <button id="reject-cookies">ici</button>.
+            <a href="/pages/cookies">En savoir plus</a>
+            <button id="accept-cookies">OK</button>
         </div>
 
         <div class="header-container">
@@ -118,14 +150,14 @@
                     {% endcaptureas %}
 
                     {# Logo #}
-                    <h1 class="header-logo">
+                    <div class="header-logo">
                         <a href="{% url "zds.pages.views.home" %}"
                            class="header-logo-link"
                            data-title="{{ mobiletitle }}"
                         >
                             Zeste de Savoir
                         </a>
-                    </h1>
+                    </div>
 
 
                     {# Menu #}
@@ -414,14 +446,16 @@ <h1 class="header-logo">
         
             <div class="clearfix sub-header">
                 <div class="wrapper">
-                    <div class="breadcrumb">
-                        <ul>
+                    <div class="breadcrumb" itemprop="breadcrumb">
+                        <ol>
                             <li>
-                                <a href="{% url "zds.pages.views.home" %}">Accueil</a>
+                                <a href="{% url "zds.pages.views.home" %}" rel="home" itemprop="url">
+                                    <span itemprop="title">Accueil</span>
+                                </a>
                             </li>
                             {% block breadcrumb_base %}{% endblock %}
                             {% block breadcrumb %}{% endblock %}
-                        </ul>
+                        </ol>
                     </div>
                     <div class="search header-right" id="search">
                         <form action="/rechercher">
@@ -437,8 +471,10 @@ <h1 class="header-logo">
 
 
         <div class="main-container">
+            {% block pre_content %}
+            {% endblock %}
+
             <div class="main wrapper clearfix">
-                
                 <main class="content-container" role="main" id="content">
                     {% if messages %}
                         {% for message in messages %}
@@ -450,15 +486,20 @@ <h1 class="header-logo">
                     {% endif %}
 
                     {% block content_out %}
-                        <section class="content-wrapper">
-                            <h2>{% block headline %}{% endblock %}</h2>
+                        {% captureas schema %}
+                            {% block schema %}{% endblock %}
+                        {% endcaptureas %}
+                        <section class="content-wrapper" {{ schema }}>
+                            <h1 {% if schema %}itemprop="name"{% endif %}>
+                                {% block headline %}{% endblock %}
+                            </h1>
 
                             {% captureas headlinesub %}
                                 {% block headline_sub %}{% endblock %}
                             {% endcaptureas %}
 
                             {% if headlinesub %}
-                                <h3 class="subtitle">{{ headlinesub|safe }}</h3>
+                                <h2 class="subtitle" {% if schema %}itemprop="description"{% endif %}>{{ headlinesub|safe }}</h2>
                             {% endif %}
 
                             {% block content %}{% endblock %}
@@ -466,11 +507,9 @@ <h3 class="subtitle">{{ headlinesub|safe }}</h3>
                     {% endblock %}
                 </main>
                 
-                {% block sidebar %}
-                {% endblock %}
-
-            </div> <!-- #main -->
-        </div> <!-- #main-container -->
+                {% block sidebar %}{% endblock %}
+            </div>
+        </div>
 
 
 
@@ -497,13 +536,25 @@ <h3 class="subtitle">{{ headlinesub|safe }}</h3>
 
 
 
+    
+
+    {# Google Tag Manager #}
+    <noscript id="gtm">
+        <iframe src="//www.googletagmanager.com/ns.html?id=GTM-WH7642"
+        height="0" width="0" style="display:none;visibility:hidden"></iframe>
+    </noscript>
+
+
+
+
+
     {# Javascript stuff start #}
     {% if debug %}
-    <script src="/static/js/vendors.js"></script>
-    <script src="/static/js/main.js"></script>
+        <script src="/static/js/vendors.js"></script>
+        <script src="/static/js/main.js"></script>
     {% else %}
-    <script src="/static/js/vendors.min.js"></script>
-    <script src="/static/js/main.min.js"></script>
+        <script src="/static/js/vendors.min.js"></script>
+        <script src="/static/js/main.min.js"></script>
     {% endif %}
 
 
@@ -521,20 +572,5 @@ <h3 class="subtitle">{{ headlinesub|safe }}</h3>
         });
     </script>
     <script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
-
-    
-
-    {# Google Tag Manager #}
-    <noscript>
-        <iframe src="//www.googletagmanager.com/ns.html?id=GTM-WH7642"
-        height="0" width="0" style="display:none;visibility:hidden"></iframe>
-    </noscript>
-    <script>
-        (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
-        new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
-        j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
-        '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
-        })(window,document,'script','dataLayer','GTM-WH7642');
-    </script>
 </body>
 </html>
diff --git a/templates/base_content_page.html b/templates/base_content_page.html
index d56638efdf..a95f8b185d 100644
--- a/templates/base_content_page.html
+++ b/templates/base_content_page.html
@@ -3,11 +3,11 @@
 
 
 {% block content_out %}
-    <article class="content-wrapper">
+    <article class="content-wrapper" {% block article_schema %}{% endblock %}>
         <header>
             {% block headline %}{% endblock %}
         </header>
-        <section class="article-content">
+        <section class="article-content" {% block article_centent_schema %}{% endblock %}>
             {% block content %}{% endblock %}
         </section>
         {% block content_after %}{% endblock %}
diff --git a/templates/email/mp/new.html b/templates/email/mp/new.html
index 16e6f1fd27..56addcbddc 100644
--- a/templates/email/mp/new.html
+++ b/templates/email/mp/new.html
@@ -9,11 +9,11 @@
     <strong>{{ author }}</strong> vous a envoyé un message privé sur Zeste de Savoir.
     <br />
     <br />
-    Pour le lire, <a href="{{ url }}">cliquez ici</a>
+    Pour le lire, <a href="{{ url }}">cliquez ici</a>.
     <br />
     <br />
     <br />
     Cordialement,
     <br />
     L'équipe Zeste de Savoir
-</body>
\ No newline at end of file
+</body>
diff --git a/templates/forum/base.html b/templates/forum/base.html
index ccc2c3e1c5..3ec9fc242d 100644
--- a/templates/forum/base.html
+++ b/templates/forum/base.html
@@ -7,7 +7,7 @@
 
 
 {% block title_base %}
-    &#183; Forums
+    &bull; Forums
 {% endblock %}
 
 
@@ -19,7 +19,11 @@
 
 
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.forum.views.index" %}">Forums</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{% url "zds.forum.views.index" %}" itemprop="url">
+            <span itemprop="title">Forums</span>
+        </a>
+    </li>
 {% endblock %}
 
 
@@ -59,6 +63,7 @@ <h3>Actions</h3>
         {% if user.is_authenticated %}
             <div class="mobile-menu-bloc mobile-all-links" data-title="Sujets suivis">
                 <h3>Sujets suivis</h3>
+
                 {% with follwedtopics=user|followed_topics %}
                     {% for period, topics in follwedtopics.items %}
                         <h4>{{ period|humane_delta }}</h4>
@@ -78,15 +83,15 @@ <h4>{{ period|humane_delta }}</h4>
                                     </form>
                                     
                                     <a href="{% spaceless %}
-                                        {% with first_unread=topic.first_unread_post %}
-                                            {% if first_unread %}
-                                                {{ first_unread.get_absolute_url }}
-                                            {% else %}
-                                                {{ topic.last_read_post.get_absolute_url }}
-                                            {% endif %}
-                                        {% endwith %}
-                                        {% endspaceless %}"
-                                       class="{% if not topic|is_read %}unread{% endif %}
+                                            {% with first_unread=topic.first_unread_post %}
+                                                {% if first_unread %}
+                                                    {{ first_unread.get_absolute_url }}
+                                                {% else %}
+                                                    {{ topic.last_read_post.get_absolute_url }}
+                                                {% endif %}
+                                            {% endwith %}
+                                            {% endspaceless %}"
+                                        class="{% if not topic|is_read %}unread{% endif %}
                                             ico-after
 
                                             {% if topic.is_solved %}
@@ -97,16 +102,16 @@ <h4>{{ period|humane_delta }}</h4>
                                                 star yellow
                                             {% endif %}
                                         "
-                                       {% if topic.is_solved or topic.is_locked %}
-                                        data-prefix="
-                                            {% if topic.is_solved %}
-                                                Résolu
-                                            {% endif %}
-                                            {% if topic.is_locked %}
-                                                Fermé
-                                            {% endif %}
-                                        "
-                                       {% endif %}
+                                        {% if topic.is_solved or topic.is_locked %}
+                                            data-prefix="
+                                                {% if topic.is_solved %}
+                                                    Résolu
+                                                {% endif %}
+                                                {% if topic.is_locked %}
+                                                    Fermé
+                                                {% endif %}
+                                            "
+                                        {% endif %}
                                     >
                                         {% if not topic|is_read %}
                                             <span class="a11y">Non-lu :</span>
@@ -122,7 +127,7 @@ <h4>{{ period|humane_delta }}</h4>
                                                 {% endwith %}
                                                 <span class="topic-last-answer">
                                                     Dernière réponse
-                                                    {{ answer.pubdate|format_date }}
+                                                    {{ answer.pubdate|format_date:True }}
                                                     par
                                                     <em>{{ answer.author.username }}</em>
                                                 </span>
@@ -138,9 +143,11 @@ <h4>{{ period|humane_delta }}</h4>
                         </ul>
                     {% endfor %}
 
-                    {% if topics|length <= 0 %}
+                    {% if follwedtopics.items|length <= 0 %}
                         <ul>
-                            <li class="inactive"><em>Aucun sujet suivi</em></li>
+                            <li class="inactive">
+                                <span class="disabled">Aucun sujet suivi</span>
+                            </li>
                         </ul>
                     {% endif %}
                 {% endwith %}
diff --git a/templates/forum/category/forum.html b/templates/forum/category/forum.html
index 7886d85edd..cd337c146c 100644
--- a/templates/forum/category/forum.html
+++ b/templates/forum/category/forum.html
@@ -4,19 +4,48 @@
 
 {% block title %}
     {{ forum.title }}
+    {% if request.GET.filter == "solve" %}
+        / Sujets résolus
+    {% elif request.GET.filter == "unsolve" %}
+        / Sujets non-résolus
+    {% endif %}
 {% endblock %}
 
 
 
 {% block breadcrumb %}
-    <li><a href="{{ forum.category.get_absolute_url }}">{{ forum.category.title }}</a></li>
-    <li>{{ forum.title }}</li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ forum.category.get_absolute_url }}" itemprop="url">
+            <span itemprop="title">{{ forum.category.title }}</span>
+        </a>
+    </li>
+
+    {% if request.GET.filter %}
+        <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+            <a href="{{ forum.get_absolute_url }}" itemprop="url">
+                <span itemprop="title">{{ forum.title }}</span>
+            </a>
+        </li>
+    {% else %}
+        <li>{{ forum.title }}</li>
+    {% endif %}
+
+    {% if request.GET.filter == "solve" %}
+        <li>Sujets résolus</li>
+    {% elif request.GET.filter == "unsolve" %}
+        <li>Sujets non-résolus</li>
+    {% endif %}
 {% endblock %}
 
 
 
 {% block headline %}
     {{ forum.title }}
+    {% if request.GET.filter == "solve" %}
+        / Sujets résolus
+    {% elif request.GET.filter == "unsolve" %}
+        / Sujets non-résolus
+    {% endif %}
 {% endblock %}
 
 
@@ -39,7 +68,7 @@
     {% include "misc/pagination.part.html" with position="top" %}
 
     {% if sticky_topics %}
-        <div class="topic-list navigable-list">
+        <div class="topic-list navigable-list" itemscope itemtype="http://schema.org/ItemList">
             {% for topic in sticky_topics %}
                 {% include "forum/includes/topic_row.part.html" %}
             {% endfor %}
@@ -47,7 +76,7 @@
     {% endif %}
 
     {% if topics %}
-        <div class="topic-list navigable-list">
+        <div class="topic-list navigable-list" itemscope itemtype="http://schema.org/ItemList">
             {% for topic in topics %}
                 {% include "forum/includes/topic_row.part.html" %}
             {% endfor %}
@@ -71,25 +100,27 @@ <h3>Filtres</h3>
         <ul>
             <li>
                 <a href="{% url "zds.forum.views.details" forum.category.slug forum.slug %}?filter=solve"
-                   class="ico-after tick green"
+                   class="ico-after tick green {% if request.GET.filter == "solve" %}unread{% endif %}"
                 >
                     Sujets résolus
                 </a>
             </li>
             <li>
                 <a href="{% url "zds.forum.views.details" forum.category.slug forum.slug %}?filter=unsolve"
-                   class="ico-after tick blue"
+                   class="ico-after tick blue {% if request.GET.filter == "unsolve" %}unread{% endif %}"
                 >
                     Sujets non résolus
                 </a>
             </li>
-            <li>
-                <a href="{% url "zds.forum.views.details" forum.category.slug forum.slug %}"
-                   class="ico-after cross blue"
-                >
-                    Annuler le filtre
-                </a>
-            </li>
+            {% if request.GET.filter %}
+                <li>
+                    <a href="{% url "zds.forum.views.details" forum.category.slug forum.slug %}"
+                       class="ico-after cross blue"
+                    >
+                        Annuler le filtre
+                    </a>
+                </li>
+            {% endif %}
         </ul>
     </div>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/forum/category/index.html b/templates/forum/category/index.html
index 0e7d6f5d0f..75a5f3b414 100644
--- a/templates/forum/category/index.html
+++ b/templates/forum/category/index.html
@@ -21,7 +21,7 @@
 
 
 {% block content %}
-	<div class="content-wrapper topic-list topic-list-small forum-list navigable-list">
+	<div class="content-wrapper topic-list topic-list-small forum-list navigable-list" itemscope itemtype="http://schema.org/ItemList">
 	    {% include "forum/includes/forums.part.html" %}
 	</div>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/forum/find/post.html b/templates/forum/find/post.html
index 33a7151ccf..baeefc9733 100644
--- a/templates/forum/find/post.html
+++ b/templates/forum/find/post.html
@@ -12,16 +12,16 @@
 
 
 {% block headline %}
-    <h2 class="box forum">Messages postés par "{{ usr.username }}""</h2>
+    Messages postés par "{{ usr.username }}"
 {% endblock %}
 
 
 
 {% block breadcrumb %}
     {% with profile=usr|profile %}
-        <li ><a href="{{ profile.get_absolute_url }}">{{ usr.username }}</a></li>
+        <li><a href="{{ profile.get_absolute_url }}">{{ usr.username }}</a></li>
     {% endwith %}
-    <li><a href="{% url "zds.forum.views.find_post" usr.username %}">Messages postés</a></li>
+    <li><a href="{% url "zds.forum.views.find_post" usr.pk %}">Messages postés</a></li>
     <li>Recherche</li>
 {% endblock %}
 
@@ -30,35 +30,41 @@ <h2 class="box forum">Messages postés par "{{ usr.username }}""</h2>
 {% block content %}
     {% include "misc/pagination.part.html" with position="top" %}
 
-    <div class="row">
-        <table>
-          <thead>
-            <tr>
-              <th width="15%">Sujet</th>
-              <th width="10%">Quand</th>
-              <th width="30%">Extrait</th>
-            </tr>
-          </thead>
-          <tbody>
-            {% for post in posts %}
-            <tr>
-                <td>
-                    <div class="forum-entry-title {% if user.is_authenticated %} {% if topic.never_read %} unread {% endif %} {% endif %}">
-                        <a href="{{ post.get_absolute_url }}">{{ post.topic.title }} </a> 
-                        {% if post.topic.subtitle %} <p> {{ post.topic.subtitle }} </p> {% endif %}
-                    </div>
-                </td>
-                <td>
-                    {{ post.pubdate|format_date }}
-                </td>
-                <td>
-                    {{ post.text|truncatechars:200|emarkdown|striptags }}
-                </td>
-            </tr>
-            {% endfor %}
-          </tbody>
-        </table>
-    </div>
+    {% if posts %}
+        <div class="row">
+            <table>
+              <thead>
+                <tr>
+                  <th width="15%">Sujet</th>
+                  <th width="10%">Quand</th>
+                  <th width="30%">Extrait</th>
+                </tr>
+              </thead>
+              <tbody>
+                {% for post in posts %}
+                <tr>
+                    <td>
+                        <div class="forum-entry-title {% if user.is_authenticated %} {% if topic.never_read %} unread {% endif %} {% endif %}">
+                            <a href="{{ post.get_absolute_url }}">{{ post.topic.title }} </a> 
+                            {% if post.topic.subtitle %} <p> {{ post.topic.subtitle }} </p> {% endif %}
+                        </div>
+                    </td>
+                    <td>
+                        {{ post.pubdate|format_date }}
+                    </td>
+                    <td>
+                        {{ post.text|truncatechars:200|emarkdown|striptags }}
+                    </td>
+                </tr>
+                {% endfor %}
+              </tbody>
+            </table>
+        </div>
+    {% else %}
+        <p>
+            Aucun message n'a été posté par {{ usr.username }}.
+        </p>
+    {% endif %}
 
     {% include "misc/pagination.part.html" with position="bottom" %}
 {% endblock %}
diff --git a/templates/forum/find/topic.html b/templates/forum/find/topic.html
index 2b10a6e958..6567297291 100644
--- a/templates/forum/find/topic.html
+++ b/templates/forum/find/topic.html
@@ -12,7 +12,7 @@
 
 
 {% block headline %}
-    <h2 class="box forum">Sujets crées par "{{ usr.username }}""</h2>
+    Sujets crées par "{{ usr.username }}"
 {% endblock %}
 
 
@@ -21,7 +21,7 @@ <h2 class="box forum">Sujets crées par "{{ usr.username }}""</h2>
     {% with profile=usr|profile %}
         <li><a href="{{ profile.get_absolute_url }}">{{ usr.username }}</a></li>
     {% endwith %}
-    <li><a href="{% url "zds.forum.views.find_topic" usr.username %}">Sujets crées</a></li>
+    <li><a href="{% url "zds.forum.views.find_topic" usr.pk %}">Sujets crées</a></li>
     <li>Recherche</li>
 {% endblock %}
 
@@ -30,33 +30,39 @@ <h2 class="box forum">Sujets crées par "{{ usr.username }}""</h2>
 {% block content %}
     {% include "misc/pagination.part.html" with position="top" %}
 
-    <table>
-        <thead>
-            <tr>
-                <th width="15%">Sujet</th>
-                <th width="10%">Quand</th>
-                <th width="30%">Extrait</th>
-            </tr>
-        </thead>
-        <tbody>
-            {% for topic in topics %}
-            <tr>
-                <td>
-                    <div class="forum-entry-title {% if user.is_authenticated %} {% if topic.never_read %} unread {% endif %} {% endif %}">
-                    <a href="{{ topic.get_absolute_url }}">{{ topic.title }} </a> 
-                        {% if topic.subtitle %} <p> {{ topic.subtitle }} </p> {% endif %}
-                    </div>
-                </td>
-                <td>
-                    {{ topic.pubdate|format_date }}
-                </td>
-                <td>
-                    {{ topic.first_post.text|truncatechars:200|emarkdown|striptags }}
-                </td>
-            </tr>
-            {% endfor %}
-        </tbody>
-    </table>
+    {% if topics %}
+        <table>
+            <thead>
+                <tr>
+                    <th width="15%">Sujet</th>
+                    <th width="10%">Quand</th>
+                    <th width="30%">Extrait</th>
+                </tr>
+            </thead>
+            <tbody>
+                {% for topic in topics %}
+                <tr>
+                    <td>
+                        <div class="forum-entry-title {% if user.is_authenticated %} {% if topic.never_read %} unread {% endif %} {% endif %}">
+                        <a href="{{ topic.get_absolute_url }}">{{ topic.title }} </a> 
+                            {% if topic.subtitle %} <p> {{ topic.subtitle }} </p> {% endif %}
+                        </div>
+                    </td>
+                    <td>
+                        {{ topic.pubdate|format_date }}
+                    </td>
+                    <td>
+                        {{ topic.first_post.text|truncatechars:200|emarkdown|striptags }}
+                    </td>
+                </tr>
+                {% endfor %}
+            </tbody>
+        </table>
+    {% else %}
+        <p>
+            Aucun sujet n'a été créé par {{ usr.username }}.
+        </p>
+    {% endif %}
 
     {% include "misc/pagination.part.html" with position="bottom" %}
 {% endblock %}
diff --git a/templates/forum/find/topic_by_tag.html b/templates/forum/find/topic_by_tag.html
index f274a464e8..e1c81d9579 100644
--- a/templates/forum/find/topic_by_tag.html
+++ b/templates/forum/find/topic_by_tag.html
@@ -5,19 +5,19 @@
 
 
 {% block title %}
-    Tag : {{tag.title}}
+    Tag : {{ tag.title }}
 {% endblock %}
 
 
 
 {% block breadcrumb %}
-    <li>Tag : {{tag.title}}</li>
+    <li>Tag : {{ tag.title }}</li>
 {% endblock %}
 
 
 
 {% block headline %}
-    Tag : {{tag.title}}
+    Tag : {{ tag.title }}
 {% endblock %}
 
 
diff --git a/templates/forum/includes/forums.part.html b/templates/forum/includes/forums.part.html
index 8b45deabb8..273c1dfbde 100644
--- a/templates/forum/includes/forums.part.html
+++ b/templates/forum/includes/forums.part.html
@@ -4,36 +4,36 @@
 
 
 {% for forum in forums %}
-        <div class="topic navigable-elem">
-            <div class="topic-description {% if user.is_authenticated and not forum.is_read %}unread{% endif %}">
-                <a href="{{ forum.get_absolute_url }}" class="navigable-link">
-                    <h4 class="topic-title">
-                            {{ forum.title }}
-                    </h4>
-                </a>
-                <span class="topic-subtitle">
-                    {{ forum.subtitle }}
-                </span>
-            </div>
-            <p class="topic-answers">
-                <span title="Nombre de sujets dans le forum">
-                    {{ forum.get_topic_count }}
-                </span>
-                <span title="Nombre de messages dans le forum">
-                    {{ forum.get_post_count }}
-                </span>
-            </p>
-            <p class="topic-last-answer">
-                {% with last_message=forum.get_last_message %}
-                    {% if last_message %}
-                        <a href="{{ last_message.topic.last_read_post.get_absolute_url }}">
-                            <span class="forum-last-message">Dernier message :</span>
-                            <span class="forum-last-message-title">{{ last_message.topic.title }}</span>
-                        </a>
-                    {% else %}
-                        <span class="topic-no-last-answer">Aucun sujet</span>
-                    {% endif %}
-                {% endwith %}
-            </p>
+    <div class="topic navigable-elem">
+        <div class="topic-description {% if user.is_authenticated and not forum.is_read %}unread{% endif %}">
+            <a href="{{ forum.get_absolute_url }}" class="navigable-link">
+                <h4 class="topic-title" itemprop="itemListElement">
+                    {{ forum.title }}
+                </h4>
+            </a>
+            <span class="topic-subtitle">
+                {{ forum.subtitle }}
+            </span>
         </div>
+        <p class="topic-answers">
+            <span title="Nombre de sujets dans le forum">
+                {{ forum.get_topic_count }}
+            </span>
+            <span title="Nombre de messages dans le forum">
+                {{ forum.get_post_count }}
+            </span>
+        </p>
+        <p class="topic-last-answer">
+            {% with last_message=forum.get_last_message %}
+                {% if last_message %}
+                    <a href="{{ last_message.topic.last_read_post.get_absolute_url }}">
+                        <span class="forum-last-message">Dernier message :</span>
+                        <span class="forum-last-message-title">{{ last_message.topic.title }}</span>
+                    </a>
+                {% else %}
+                    <span class="topic-no-last-answer">Aucun sujet</span>
+                {% endif %}
+            {% endwith %}
+        </p>
+    </div>
 {% endfor %}
\ No newline at end of file
diff --git a/templates/forum/includes/topic_row.part.html b/templates/forum/includes/topic_row.part.html
index 32465340c3..25fbc7ab47 100644
--- a/templates/forum/includes/topic_row.part.html
+++ b/templates/forum/includes/topic_row.part.html
@@ -22,7 +22,7 @@
     {% with profile=topic.author|profile %}
         <div class="topic-description">
             <a href="{{ topic.get_absolute_url }}" class="topic-title-link navigable-link">
-                <span class="topic-title">{{ topic.title }}</span>
+                <span class="topic-title" itemprop="itemListElement">{{ topic.title }}</span>
                 <span class="topic-subtitle">{{ topic.subtitle }}</span>
             </a>
             <p class="topic-members">
@@ -30,8 +30,9 @@
                 <em>
                     {% include "misc/member_item.part.html" with member=topic.author %}
                 </em>
+                <span class="topic-members-label">{{ topic.pubdate|format_date }}</span>
                 {% if topic.tags.all %}
-                    - Tags : 
+                    - Tag{{ topic.tags.all|pluralize }} : 
                     {% for tag in topic.tags.all %}
                         <a href="{% url "zds.forum.views.find_topic_by_tag" tag.pk tag.slug %}" class="topic-tag">{{ tag.title }}</a>
                     {% endfor %}
@@ -42,7 +43,7 @@
     <p class="topic-answers">
         {% with nb_post=topic.get_post_count %}
             {% if nb_post > 1 %}
-                {{ nb_post|add:"-1" }} réponse{% if nb_post > 2 %}s{% endif %}
+                {{ nb_post|add:"-1" }} réponse{{ nb_post|add:"-1"|pluralize }}
             {% endif %}
         {% endwith %}
     </p>
diff --git a/templates/forum/index.html b/templates/forum/index.html
index f0c04a8fd1..42e3538b52 100644
--- a/templates/forum/index.html
+++ b/templates/forum/index.html
@@ -7,12 +7,9 @@
 
 
 
-{% block meta %}
-    <meta name="description" content="Les forums vous permettent de venir poser
-    vos questions aux autres membres mais aussi de vous entraîner ou tout
-    simplement de discuter. Cela fonctionne également dans l'autre sens : vous
-    pouvez ici aider les autres et proposer des exercices au reste de la
-    communauté.">
+{% block description %}
+    Les forums vous permettent de venir poser vos questions aux autres membres mais aussi de vous entraîner ou tout
+    simplement de discuter.
 {% endblock %}
 
 
@@ -37,11 +34,13 @@
         proposer des exercices au reste de la communauté.
     </p>
 
-    <div class="content-wrapper topic-list topic-list-small forum-list navigable-list">
+    <div class="content-wrapper topic-list topic-list-small forum-list navigable-list" itemscope itemtype="http://schema.org/ItemList">
+        <meta itemprop="itemListOrder" content="Unordered">
+
         {% for title, forums in categories.items %}
-            <h3 class="group-title content-wrapper">
+            <h2 class="group-title content-wrapper">
                 {{ title }}
-            </h3>
+            </h2>
             {% include "forum/includes/forums.part.html" with forum=forums %}
         {% endfor %}
     </div>
diff --git a/templates/forum/topic/followed.html b/templates/forum/topic/followed.html
index 48d5530c01..0fc021f77e 100644
--- a/templates/forum/topic/followed.html
+++ b/templates/forum/topic/followed.html
@@ -3,19 +3,19 @@
 
 
 {% block title %}
-    Notifications du Forum
+    Sujets suivis
 {% endblock %}
 
 
 
 {% block breadcrumb %}
-    <li>Notifications du Forum</li>
+    <li>Sujets suivis</li>
 {% endblock %}
 
 
 
 {% block headline %}
-    Notifications du Forum
+    Sujets suivis
 {% endblock %}
 
 
diff --git a/templates/forum/topic/index.html b/templates/forum/topic/index.html
index b077c3dd37..6769f68690 100644
--- a/templates/forum/topic/index.html
+++ b/templates/forum/topic/index.html
@@ -14,9 +14,25 @@
 
 
 {% block breadcrumb %}
-    <li><a href="{{ topic.forum.category.get_absolute_url }}">{{ topic.forum.category.title }}</a></li>
-    <li><a href="{{ topic.forum.get_absolute_url }}">{{ topic.forum.title }}</a></li>
-    <li>{{ topic.title }}</li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ topic.forum.category.get_absolute_url }}" itemprop="url">
+            <span itemprop="title">{{ topic.forum.category.title }}</span>
+        </a>
+    </li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ topic.forum.get_absolute_url }}" itemprop="url">
+            <span itemprop="title">{{ topic.forum.title }}</span>
+        </a>
+    </li>
+    <li>
+        {{ topic.title }}
+    </li>
+{% endblock %}
+
+
+
+{% block schema %}
+    itemscope itemtype="http://schema.org/Question"
 {% endblock %}
 
 
@@ -34,11 +50,17 @@
 
 
 {% block content %}
-    <ul class="taglist">
-        {% for tag in topic.tags.all %}
-            <li><a href="{% url "zds.forum.views.find_topic_by_tag" tag.pk tag.slug %}">{{ tag.title }}</a></li>
-        {% endfor %}
-    </ul>
+    {% if topic.tags.all %}
+        <ul class="taglist" itemprop="keywords">
+            {% for tag in topic.tags.all %}
+                <li>
+                    <a href="{% url "zds.forum.views.find_topic_by_tag" tag.pk tag.slug %}">
+                        {{ tag.title }}
+                    </a>
+                </li>
+            {% endfor %}
+        </ul>
+    {% endif %}
 
     {% include "misc/pagination.part.html" with position="top" %}
 
@@ -80,7 +102,13 @@
                 {% set False as is_repeated_message %}
             {% endif %}
 
-            {% include "misc/message.part.html" with perms_change=perms.forum.change_topic %}
+            {% if forloop.first and nb = 1 %}
+                {% set True as answer_schema %}
+            {% else %}
+                {% set False as answer_schema %}
+            {% endif %}
+
+            {% include "misc/message.part.html" with perms_change=perms.forum.change_topic answer_schema=answer_schema %}
         {% endfor %}
     </div>
 
diff --git a/templates/forum/topic/new.html b/templates/forum/topic/new.html
index 49efc26a3c..7dc210217e 100644
--- a/templates/forum/topic/new.html
+++ b/templates/forum/topic/new.html
@@ -17,8 +17,16 @@
 
 
 {% block breadcrumb %}
-    <li><a href="{{ forum.category.get_absolute_url }}">{{ forum.category.title }}</a></li>
-    <li><a href="{{ forum.get_absolute_url }}">{{ forum.title }}</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ forum.category.get_absolute_url }}" itemprop="url">
+            <span itemprop="title">{{ forum.category.title }}</span>
+        </a>
+    </li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ forum.get_absolute_url }}" itemprop="url">
+            <span itemprop="title">{{ forum.title }}</span>
+        </a>
+    </li>
     <li>Nouveau sujet</li>
 {% endblock %}
 
diff --git a/templates/gallery/base.html b/templates/gallery/base.html
old mode 100644
new mode 100755
index 7824c0c23c..9df3d748dd
--- a/templates/gallery/base.html
+++ b/templates/gallery/base.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Galeries
+    &bull; Galeries
 {% endblock %}
 
 
@@ -21,5 +21,6 @@
         <a href="{% url "zds.gallery.views.new_gallery" %}" class="new-btn ico-after more blue">
             Ajouter une galerie
         </a>
+        {% block sidebar_actions %}{% endblock %}
     </aside>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/gallery/gallery/details.html b/templates/gallery/gallery/details.html
index 77ba1b5c96..5a6cbe590b 100644
--- a/templates/gallery/gallery/details.html
+++ b/templates/gallery/gallery/details.html
@@ -65,7 +65,7 @@
         </ul>
     </div>
     
-    <form id="form" name="form" method="post" action="{% url "zds.gallery.views.modify_image" %}">
+    <form id="form" name="form" method="post" action="{% url "zds.gallery.views.delete_image" %}">
         <input type="hidden" name="gallery" value="{{ gallery.pk }}">
         <button class="btn btn-cancel" name="delete_multi">Supprimer la sélection</button>
         <button class="toggle-gallery-view btn btn-grey" type="button" title="Alterner entre les modes de vue grille et liste">
diff --git a/templates/gallery/gallery/list.html b/templates/gallery/gallery/list.html
old mode 100644
new mode 100755
index 7da4bffdbc..a51773d5a0
--- a/templates/gallery/gallery/list.html
+++ b/templates/gallery/gallery/list.html
@@ -21,49 +21,74 @@
 
 
 {% block content %}
-    <form id="form" name="form" method="post" action="{% url "zds.gallery.views.modify_gallery" %}">
-        <div class="topic-list topic-list-small navigable-list">
-            {% for gallery in galleries %}
-                <div class="topic navigable-elem">
-                    <div class="topic-infos">
-                        <input
-                            name="items"
-                            type="checkbox"
-                            {% if not gallery.is_write %}
-                                disabled="true"
-                            {% endif %}
-                            value="{{ gallery.gallery.pk }}"
-                        >
-                    </div>
-                    <div class="topic-description">
-                        <a href="{{ gallery.gallery.get_absolute_url }}" class="topic-title-link navigable-link">
-                            <span class="topic-title">
-                                {{ gallery.gallery.title }}
-                            </span>
-                            <span class="topic-subtitle">
-                                {{ gallery.gallery.subtitle|default:"Pas de description" }}
-                            </span>
-                        </a>
-                    </div>
-                    <p class="topic-answers">
-                        {% with img_count=gallery.gallery.get_images.count %}
-                            {% if img_count == 0 %}
-                                Aucune image
-                            {% elif img_count == 1 %}
-                                1 image
-                            {% else %}
-                                {{ img_count }} images
-                            {% endif %}
-                        {% endwith %}
-                    </p>
+    <div class="topic-list topic-list-small navigable-list">
+        {% for gallery in galleries %}
+            <div class="topic navigable-elem">
+                <div class="topic-infos">
+                    <input
+                        name="items"
+                        type="checkbox"
+                        {% if not gallery.is_write %}
+                            disabled="true"
+                        {% endif %}
+                        value="{{ gallery.gallery.pk }}"
+                        form="delete-galleries"
+                    >
+                </div>
+                <div class="topic-description">
+                    <a href="{{ gallery.gallery.get_absolute_url }}" class="topic-title-link navigable-link">
+                        <span class="topic-title">
+                            {{ gallery.gallery.title }}
+                        </span>
+                        <span class="topic-subtitle">
+                            {{ gallery.gallery.subtitle|default:"Pas de description" }}
+                        </span>
+                    </a>
                 </div>
-            {% endfor %}
-        </div>
+                <p class="topic-answers">
+                    {% with img_count=gallery.gallery.get_images.count %}
+                        {% if img_count == 0 %}
+                            Aucune image
+                        {% elif img_count == 1 %}
+                            1 image
+                        {% else %}
+                            {{ img_count }} images
+                        {% endif %}
+                    {% endwith %}
+                </p>
+            </div>
+        {% endfor %}
+    </div>
+
+    {% if galleries|length = 0 %}
+        <p>
+            Vous n'avez pas encore <a href="{% url "zds.gallery.views.new_gallery" %}">ajouté de galerie</a>.
+        </p>
+    {% endif %}
+{% endblock %}
+
 
-        <button type="submit" name="delete_multi" class="btn btn-cancel">
-            Supprimer la séléction
-        </button>
 
-        {% csrf_token %}
-    </form>
+{% block sidebar_actions %}
+    {% if galleries|length > 0 %}
+    <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Actions">
+        <h3>Actions</h3>
+        <ul>
+            <li>
+                <a href="#delete-galleries" class="open-modal ico-after cross red">
+                    Supprimer les galeries sélectionnées
+                </a>
+                
+                <form action="{% url "zds.gallery.views.modify_gallery" %}" method="post" id="delete-galleries" class="modal modal-small">
+                    <p>
+                        Attention, vous vous appretez à supprimer toutes les galeries sélectionnées.
+                    </p>
+                    
+                    {% csrf_token %}
+                    <button type="submit" name="delete_multi" class="btn">Confirmer</button>
+                </form>
+            </li>
+        </ul>
+    </div>
+    {% endif %}
 {% endblock %}
diff --git a/templates/home.html b/templates/home.html
index 1fe42f6f97..ca2ab9f2bc 100644
--- a/templates/home.html
+++ b/templates/home.html
@@ -1,4 +1,5 @@
 {% extends "base.html" %}
+{% load staticfiles %}
 {% load emarkdown %}
 {% load date %}
 {% load interventions %}
@@ -7,73 +8,119 @@
 
 
 
-{% block title %}
-    Accueil
-{% endblock %}
+{% block body_class %}home content-cols{% endblock %}
 
 
 
-{% block meta %}
-    {# TODO : Make a better description #}
-    <meta name="description" content="Bienvenue sur Zeste de Savoir, une communauté">
+{% block pre_content %}
+    {% if user.is_authenticated %}
+        <section class="home-quote home-simple-quote">
+            <div class="home-wrapper">
+                <img src="{% static "images/clem-home-quote.png" %}" alt="">
+                <blockquote>
+                    «&nbsp;{{ quote }}&nbsp;»
+                </blockquote>
+            </div>
+        </section>
+    {% else %}
+        <section class="home-quote home-full-description">
+            <div class="home-wrapper">
+                <img src="{% static "images/clem-home.png" %}" alt="" width="214" height="209">
+                <div class="home-full-description-text">
+                    <h2>Zeste de Savoir, la connaissance pour tous et sans pépins</h2>
+
+                    <blockquote>
+                        «&nbsp;{{ quote }}&nbsp;»
+                    </blockquote>
+
+                    <p>
+                        Zeste de Savoir est un site de <strong>partage de connaissances</strong> sur lequel vous trouverez des <a href="http://zestedesavoir.com/tutoriels/">tutoriels de tous niveaux</a>, des <a href="http://zestedesavoir.com/articles/">articles</a> et des <a href="http://zestedesavoir.com/forums/">forums d'entraide</a> animés par et pour la communauté. Les sujets abordés sont, pour l'instant, l'informatique et les sciences, mais nous n'attendons que vous pour élargir les domaines présentés !
+                    </p>
+                    <p>
+                        Tous les membres peuvent écrire et <strong>publier des tutoriels et articles sur le site</strong>. Pour assurer la qualité et la pédagogie du contenu, l'équipe du site valide chaque cours avant publication.
+                    </p>
+                    <p>
+                        Tout cela est <strong>entièrement gratuit et garanti sans publicité</strong>, le site est géré et financé par une <a href="http://zestedesavoir.com/pages/association/">association</a> a but non lucratif.
+                    </p>
+                </div>
+            </div>
+        </section>
+    {% endif %}
+    
+
+
+    <section class="search-box">
+        <form action="/rechercher" class="home-wrapper">
+            <label for="search-box-field">
+                Tu cherches quelque chose ?
+            </label>
+            <input type="text" name="q" placeholder="Exemples : Mathématiques, UDK, HTML, PHP, Java, ..." id="search-box-field">
+            <button type="submit" class="ico-after search-submit" title="Lancer la recherche">
+                OK
+            </button>
+        </form>
+    </section>
 {% endblock %}
 
 
 
-{% block body_class %}home content-cols{% endblock %}
-
-
-
 {% block content_out %}
-    <section class="content-col-2 tutorial-list">
-        <h2 class="ico-after ico-articles">Derniers articles</h2>
-
-        {% if last_articles %}
-            {% for article in last_articles %}
-                <article>
-                    {% if article.image %}
-                        <a href="{{ article.get_absolute_url_online }}" tabindex="-1">
-                            <img src="{{ article.image.article_illu.url }}" alt="" class="tutorial-img avatar">
+    <section class="content-col-2 tutorial-list" itemscope itemtype="http://schema.org/ItemList">
+        <h2 class="ico-after ico-articles" itemprop="name">
+            Derniers articles
+        </h2>
+        
+        <meta itemprop="itemListOrder" content="Descending">
+
+        {% for article in last_articles %}
+            <article>
+                {% if article.image %}
+                    <a href="{{ article.get_absolute_url_online }}" tabindex="-1">
+                        <img src="{{ article.image.article_illu.url }}" alt="" class="tutorial-img avatar">
+                    </a>
+                {% endif %}
+                <div class="tutorial-infos {% if not article.image %}no-illu{% endif %}">
+                    <h3>
+                        <a href="{{ article.get_absolute_url_online }}" title="{{ article.title }}" itemprop="itemListElement">
+                            {{ article.title }}
                         </a>
-                    {% endif %}
-                    <div class="tutorial-infos">
-                        <h3>
-                            <a href="{{ article.get_absolute_url_online }}" title="{{ article.title }}">
-                                {{ article.title }}
-                            </a>
-                        </h3>
-                        
-                        <span class="article-metadata">
-                            {{ article.pubdate|format_date|capfirst }} -
-                            <a href="{{ article.get_last_reaction.get_absolute_url }}">
-                                {% if article.get_reaction_count == 0 %}
-                                    Aucune réaction
-                                {% elif article.get_reaction_count == 1 %}
-                                    1 réaction
-                                {% else %}
-                                    {{ article.get_reaction_count }} réactions
-                                {% endif %}
-                            </a>
-                        </span>
-                    </div>
-
-                    <p class="resume">
-                        {{ article.description }}
-                    </p>
-                </article>
-            {% endfor %}
-        {% endif %}
+                    </h3>
+                    
+                    <span class="article-metadata">
+                        {{ article.pubdate|format_date|capfirst }} -
+                        <a href="
+                            {% if article.get_reaction_count == 0 %}
+                                {{ link }}#reactions
+                            {% else %}
+                                {{ article.get_last_reaction.get_absolute_url }}
+                            {% endif %}
+                        ">
+                            {% if article.get_reaction_count == 0 %}
+                                Aucune réaction
+                            {% else %}
+                                {{ article.get_reaction_count }} réaction{{ article.get_reaction_count|pluralize }}
+                            {% endif %}
+                        </a>
+                    </span>
+                </div>
+
+                <p class="resume">
+                    {{ article.description }}
+                </p>
+            </article>
+        {% endfor %}
     </section>
 
-    <section class="content-col-2 tutorial-list">
-        <h2 class="ico-after ico-tutorials">Derniers tutoriels</h2>
+    <section class="content-col-2 tutorial-list" itemscope itemtype="http://schema.org/ItemList">
+        <h2 class="ico-after ico-tutorials" itemprop="name">
+            Derniers tutoriels
+        </h2>
         
-        {% if last_tutorials %}
-            {% for tutorial in last_tutorials %}
-                {% include 'tutorial/includes/tutorial_item.part.html' %}
-            {% endfor %}
-        {% endif %}
+        <meta itemprop="itemListOrder" content="Descending">
         
+        {% for tutorial in last_tutorials %}
+            {% include 'tutorial/includes/tutorial_item.part.html' %}
+        {% endfor %}
     </section>
 {% endblock %}
 
diff --git a/templates/member/base.html b/templates/member/base.html
index 7e7ebaa50f..287279fd30 100644
--- a/templates/member/base.html
+++ b/templates/member/base.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Membres
+    &bull; Membres
 {% endblock %}
 
 
diff --git a/templates/member/login.html b/templates/member/login.html
index a56292d807..cf89a73f3b 100644
--- a/templates/member/login.html
+++ b/templates/member/login.html
@@ -23,7 +23,7 @@
 
 {% block content_out %}
     <section class="small-content-wrapper">
-        <h2>Connexion</h2>
+        <h1>Connexion</h1>
 
         {% if not user.is_authenticated %}
             {% if error %}
diff --git a/templates/member/profile.html b/templates/member/profile.html
index f3830f762b..96cad5f304 100644
--- a/templates/member/profile.html
+++ b/templates/member/profile.html
@@ -25,9 +25,9 @@
 
 {% block content_out %}
     <section class="content-col-2">
-        <h2>
-            {{ usr.username }}
-        </h2>
+        <h1>
+            Profil de {{ usr.username }}
+        </h1>
 
         <img src="{{ profile.get_avatar_url }}" alt="" class="avatar">
 
@@ -61,7 +61,7 @@ <h3>Signature</h3>
 
 
         {% if topics %}
-            <h2>Dernier sujets crées</h2>
+            <h2>Derniers sujets créés</h2>
             {% for topic in topics %}
                 <h4><a href="{{ topic.get_absolute_url }}">{{ topic.title }}</a></h4>
                 <h5>{{ topic.subtitle }}</h5>
diff --git a/templates/misc/member_item.part.html b/templates/misc/member_item.part.html
index 58576c1d84..6b0de93951 100644
--- a/templates/misc/member_item.part.html
+++ b/templates/misc/member_item.part.html
@@ -3,11 +3,22 @@
 
 
 {% with profile=member|profile %}
-    <a href="{{ member.get_absolute_url }}" class="member-item">{% spaceless %}
+    <a
+        href="{{ member.get_absolute_url }}"
+        class="member-item"
+        itemscope
+        itemtype="http://schema.org/Person"
+        {% if author %}
+            itemprop="author"
+        {% endif %}
+    >{% spaceless %}
     	{% if avatar %}
-        	<img src="{{ profile.get_avatar_url }}" alt="" class="avatar">
+        	<img src="{{ profile.get_avatar_url }}" alt="" class="avatar" itemprop="image">
     	{% endif %}
-        {{ member.username }}
+    	
+        <span itemprop="name">
+        	{{ member.username }}
+        </span>
 
         {% if info %}
             <span class="info">({{ info }})</span>
diff --git a/templates/misc/message.part.html b/templates/misc/message.part.html
index 97a375875e..d643f45cd5 100644
--- a/templates/misc/message.part.html
+++ b/templates/misc/message.part.html
@@ -5,13 +5,32 @@
 
 
 
-<article class="topic-message {% if message.is_useful %}helpful{% endif %} {% if is_repeated_message %}repeated{% endif %}">
-    {% if topic.author = message.author and helpful_link %}
-        {% set True as is_author %}
-    {% else %}
-        {% set False as is_author %}
-    {% endif %}
+{% if topic.author = message.author and helpful_link %}
+    {% set True as is_author %}
+{% else %}
+    {% set False as is_author %}
+{% endif %}
+
+
 
+<article
+    class="
+        topic-message
+        {% if message.is_useful %}helpful{% endif %}
+        {% if is_repeated_message %}repeated{% endif %}
+    " 
+    {% if comment_schema %}
+        itemscope 
+        itemtype="http://schema.org/Comment"
+        itemprop="comment"
+    {% elif answer_schema %}
+        itemscope 
+        itemtype="http://schema.org/Answer"
+        {% if message.is_useful or message.like > message.dislike %}
+            itemprop="{% if message.is_useful %}acceptedAnswer{% endif %} {% if message.like > message.dislike %}suggestedAnswer{% endif %}"
+        {% endif %}
+    {% endif %}
+>
     {% include "misc/message_user.html" with member=message.author push_badge=is_author %}
 
 
@@ -114,8 +133,15 @@
         {% endif %}
 
         <div class="message-metadata">
-            <a href="{{ message.author.get_absolute_url }}" class="username">{{ message.author.username }}</a>
-            <a href="#p{{ message.pk }}" id="p{{ message.id }}" class="date" title="{{ message.pubdate|tooltip_date|capfirst }}">{{ message.pubdate|format_date|capfirst }}</a>
+            <a href="{{ message.author.get_absolute_url }}" class="username" itemprop="author" itemscope itemtype="http://schema.org/Person">
+                <span itemprop="name">{{ message.author.username }}</span>
+            </a>
+
+            <a href="#p{{ message.pk }}" id="p{{ message.id }}" class="date" title="{{ message.pubdate|tooltip_date|capfirst }}">
+                <time itemprop="dateCreated" datetime="{{ message.pubdate|date:"c" }}">
+                    {{ message.pubdate|format_date|capfirst }}
+                </time>
+            </a>
         </div>
 
         <div class="message-content">
@@ -131,7 +157,9 @@
             {% endif %}
 
             {% if message.is_visible != False %}
-                {{ message.text_html|safe }}
+                <div itemprop="text">
+                    {{ message.text_html|safe }}
+                </div>
             {% elif perms_change %}
                 <div class="message-hidden-content">
                     {{ message.text_html|safe }}
@@ -140,14 +168,20 @@
 
             {% if message.is_visible = False %}
                 <p class="message-hidden">
-                    Masqué par {{ message.editor }} : {{ message.text_hidden }}
+                    Masqué par {{ message.editor }}
+                    {% if message.text_hidden %}
+                        : {{ message.text_hidden }}
+                    {% endif %}
                 </p>
             {% elif message.update %}
                 <p class="message-edited ico-after edit">
-                    Edité {{ message.update|format_date }}
+                    Edité
                     {% if message.editor %}
                         par {{ message.editor }}
                     {% endif %}
+                    <time itemprop="dateModified" datetime="{{ message.update|date:"c" }}">
+                        {{ message.update|format_date }}
+                    </time>
                 </p>
             {% endif %}
         </div>
@@ -193,13 +227,17 @@
 
                 {% if upvote_link %}
                     <div class="message-karma">
-                        {% if user.is_authenticated and helpful_link %}
+                        {% if user.is_authenticated and helpful_link and not is_author %}
                             {% if message.author != user or perms_change %}
                                 {% if topic.author = user or perms_change %}
                                     <form action="{{ helpful_link }}" method="post">
                                         {% csrf_token %}
                                         <button type="submit" class="tick ico-after {% if message.is_useful %}green{% endif %}">
-                                            Cette réponse {% if topic.author == user %}m'{% endif %}a aidé
+                                            {% if message.is_useful %}
+                                                Cette réponse {% if topic.author == user %}ne m'{% else %}n'{% endif %}a pas aidé
+                                            {% else %}
+                                                Cette réponse {% if topic.author == user %}m'{% endif %}a aidé
+                                            {% endif %}
                                         </button>
                                     </form>
                                 {% endif %}
@@ -240,7 +278,7 @@
                             {% endwith %}
                         {% else %}
                             <span
-                               class="upvote
+                                class="upvote
                                       ico-after
                                       {% if message.like > message.dislike %}more-voted{% endif %}
                                       {% if message.like > 0 %}has-vote{% endif %}
@@ -249,10 +287,12 @@
                                     title="{{ message.like }} personnes ont trouvé ce message utile"
                                 {% endif %}
                             >
-                                +{{ message.like }}
+                                +<span itemprop="upvoteCount">
+                                    {{ message.like }}
+                                </span>
                             </span>
                             <span 
-                               class="downvote
+                                class="downvote
                                       ico-after
                                       {% if message.like < message.dislike %}more-voted{% endif %} 
                                       {% if message.dislike > 0 %}has-vote{% endif %}
@@ -261,7 +301,9 @@
                                     title="{{ message.dislike }} personnes n'ont pas trouvé ce message utile"
                                 {% endif %}
                             >
-                                -{{ message.dislike }}
+                                -<span itemprop="downvoteCount">
+                                    {{ message.dislike }}
+                                </span>
                             </span>
                         {% endif %}
                     {% if upvote_link %}
diff --git a/templates/misc/pagination.part.html b/templates/misc/pagination.part.html
index 713cf8f4f4..7f4827f8d1 100644
--- a/templates/misc/pagination.part.html
+++ b/templates/misc/pagination.part.html
@@ -4,11 +4,17 @@
 
 
 {% if pages|length > 1 %}
+    {% captureas full_anchor %}
+        {% if anchor %}
+            #{{ anchor }}
+        {% endif %}
+    {% endcaptureas %}
+
     <ul class="pagination pagination-{{ position }}">
         {% ifnotequal nb 1 %}
             <li class="prev">
                 {% with prev=nb|add:-1 %}
-                    <a href="{% append_to_get page=prev %}" class="ico-after arrow-left blue">
+                    <a href="{% append_to_get page=prev %}{{ full_anchor }}" class="ico-after arrow-left blue">
                         Précédente
                     </a>
                 {% endwith %}
@@ -19,7 +25,7 @@
         {% for page in pages %}
             {% if page %}
                 <li>
-                    <a {% ifnotequal page nb %}href="{% append_to_get page=page %}"{% else %}class="current"{% endifnotequal %}>
+                    <a {% ifnotequal page nb %}href="{% append_to_get page=page %}{{ full_anchor }}"{% else %}class="current"{% endifnotequal %}>
                         {{ page }}
                     </a>
                 </li>
@@ -49,7 +55,7 @@
         {% if pages|last > 0 and pages|last != nb %}
             <li class="next">
                 {% with next=nb|add:1 %}
-                    <a href="{% append_to_get page=next %}" class="ico-after arrow-right blue">
+                    <a href="{% append_to_get page=next %}{{ full_anchor }}" class="ico-after arrow-right blue">
                         Suivante
                     </a>
                 {% endwith %}
diff --git a/templates/misc/validation.part.html b/templates/misc/validation.part.html
index de7ea02516..2409529333 100644
--- a/templates/misc/validation.part.html
+++ b/templates/misc/validation.part.html
@@ -6,7 +6,7 @@
     Réservé par {% include "misc/member_item.part.html" with member=validation.validator avatar=True %}
 
     {% if validation.date_reserve %}
-        {{ validation.date_reserve|format_date|capfirst }}
+        {{ validation.date_reserve|format_date:True|capfirst }}
         <br>
     {% endif %}
 {% endif %}
@@ -21,10 +21,10 @@
         </button>
     </form>
 {% elif validation.is_pending_valid %}
-    <a href="#unreservation" class="open-modal btn btn-cancel">
+    <a href="#unreservation-{{ validation.pk }}" class="open-modal btn btn-cancel">
         Annuler la réservation
     </a>
-    <form action="{{ reservation_url }}" method="post" class="modal modal-small" id="unreservation">
+    <form action="{{ reservation_url }}" method="post" class="modal modal-small" id="unreservation-{{ validation.pk }}">
     	{% csrf_token %}
         <p>
             Actuellement réservé par {% include "misc/member_item.part.html" with member=validation.validator %}. <br>
diff --git a/templates/mp/base.html b/templates/mp/base.html
index f0b5fa4270..51ae2f2306 100644
--- a/templates/mp/base.html
+++ b/templates/mp/base.html
@@ -3,7 +3,7 @@
 
 
 {% block title_base %}
-    &#183; Messagerie Privée
+    &bull; Messagerie Privée
 {% endblock %}
 
 
diff --git a/templates/mp/index.html b/templates/mp/index.html
index 1b2eb2217a..b0639ba756 100644
--- a/templates/mp/index.html
+++ b/templates/mp/index.html
@@ -38,7 +38,7 @@
                         {% endspaceless %}</a>
 
                         <p class="topic-members">
-                            <span class="topic-members-label">Participants :</span>
+                            <span class="topic-members-label">Participant{{ topic.participants.all|length|add:"1"|pluralize }} :</span>
                             <em>
                                 {% include "misc/member_item.part.html" with member=topic.author avatar=True %}
                             </em>{% spaceless %}
@@ -51,7 +51,7 @@
                 {% endwith %}
                 <p class="topic-answers">
                     {% if topic.get_post_count > 1 %}
-                        {{ topic.get_post_count|add:"-1" }} réponse{% if topic.get_post_count > 2 %}s{% endif %}
+                        {{ topic.get_post_count|add:"-1" }} réponse{{ topic.get_post_count|add:"-1"|pluralize }}
                     {% endif %}
                 </p>
                 <p class="topic-last-answer">
@@ -98,4 +98,4 @@ <h3>Actions</h3>
             </li>
         </ul>
     </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/templates/mp/topic/index.html b/templates/mp/topic/index.html
index 9a53fa1187..fcd814c1b3 100644
--- a/templates/mp/topic/index.html
+++ b/templates/mp/topic/index.html
@@ -32,7 +32,7 @@
 
 {% block content %}
     <div class="authors">
-        <span class="authors-label">Participants : </span>
+        <span class="authors-label">Participant{{ topic.participants.all|length|add:"1"|pluralize }} : </span>
         <ul>
             <li>
                 {% include 'misc/member_item.part.html' with member=topic.author avatar=True %}
@@ -127,4 +127,4 @@ <h3>Actions</h3>
             </li>
         </ul>
     </div>
-{% endblock %}
\ No newline at end of file
+{% endblock %}
diff --git a/templates/pages/about.html b/templates/pages/about.html
index 2d28d23629..dd436967c5 100644
--- a/templates/pages/about.html
+++ b/templates/pages/about.html
@@ -15,7 +15,7 @@
 
 
 {% block headline %}
-    <h2>À propos</h2>
+    <h1>À propos</h1>
 {% endblock %}
 
 
diff --git a/templates/pages/alerts.html b/templates/pages/alerts.html
index 61baf1819a..6a46544010 100644
--- a/templates/pages/alerts.html
+++ b/templates/pages/alerts.html
@@ -16,7 +16,7 @@
 
 
 {% block headline %}
-    <h2>Liste des alertes en cours</h2>
+    <h1>Liste des alertes en cours</h1>
 {% endblock %}
 
 
diff --git a/templates/pages/assoc_subscribe.html b/templates/pages/assoc_subscribe.html
index f6504e3500..ca9685ada5 100644
--- a/templates/pages/assoc_subscribe.html
+++ b/templates/pages/assoc_subscribe.html
@@ -16,11 +16,40 @@
 
 
 {% block headline %}
-    <h2>Adhérer à l'association Zeste de Savoir</h2>
+    <h1>Adhérer à l'association Zeste de Savoir</h1>
 {% endblock %}
 
 
 
 {% block content %}
+    <h3>Pourquoi adhérer ?</h3>
+    <p>
+        Adhérer à l'association Zeste de Savoir permet de nous soutenir de manière concrète et d'officialiser votre
+        engagement.
+    </p>
+    <p>
+        D'autre part, le financement des activités de l'association, dont bien sûr le site, est intégralement assuré par
+        les cotisations des membres : adhérer vous permet ainsi d'assurer la pérennité du site. La cotisation, pour
+        l'année 2014, est de <strong>30 €</strong> (le montant sera révisé tous les ans). Si pour une raison quelconque
+        vous ne pouvez pas payer cette cotisation, faites-en nous part, nous pouvons accorder des dérogations
+        exceptionnelles.</p>
+    <p>
+        Notez que l'adhésion est subordonnée au paiement de cette cotisation.
+    </p>
+    <p>
+        Adhérer permet bien entendu de participer à l'Assemblée Générale annuelle de l'association, qui élit le Conseil
+        d'Administration. Si vous avez des idées pour faire avancer l'association et donc le site, c'est le moment !
+    </p>
+    <p>
+        Une précision importante : <strong>adhérer à l'association ne vous apporte rien sur le site</strong>. L'adhésion
+        n'est là que pour soutenir le projet, et ne donne droit à aucun pouvoir ou badge supplémentaires. Elle ne donne
+        même pas accès à un forum secret, puisque le forum de l'association est public !
+    </p>
+    <p>
+        Enfin, toutes les fonctionnalités du site sont disponibles à tous : aucune n'est conditionnée à l'adhésion à
+        l'association.
+    </p>
+
+    <h3>Formulaire d'adhésion</h3>
     {% crispy form %}
 {% endblock %}
\ No newline at end of file
diff --git a/templates/pages/association.html b/templates/pages/association.html
index 84257760d6..11368ccb3b 100644
--- a/templates/pages/association.html
+++ b/templates/pages/association.html
@@ -15,19 +15,43 @@
 
 
 {% block headline %}
-    <h2>L'association Zeste de Savoir</h2>
+    <h1>L'association Zeste de Savoir</h1>
 {% endblock %}
 
 
 
 {% block content %}
+    <h3>Présentation de l'association</h3>
     <p>
-        Zeste de Savoir est une association loi 1901 (association à but non lucratif) et joue le rôle de structure légale du site ZesteDeSavoir.com, dont le but est de promouvoir le partage de connaissances à travers des ressources pédagogiques gratuites et de préférence sous licence libre. <a href="http://www.journal-officiel.gouv.fr/publications/assoc/pdf/2014/0016/JOAFE_PDF_Unitaire_20140016_01712.pdf">Parue au Journal officiel le 19 avril 2014</a>, l'association a tenu sa première assemblée générale le 15 mars 2014, au cours de laquelle ont été élus le bureau et le conseil d'administration en présence des <strong>quatorze</strong> membres fondateurs.
+        Zeste de Savoir est une association loi 1901 (association à but non lucratif) et joue le rôle de structure
+        légale du site ZesteDeSavoir.com, dont le but est de promouvoir le partage de connaissances à travers des
+        ressources pédagogiques gratuites et de préférence sous licence libre.
+        <a href="http://www.journal-officiel.gouv.fr/publications/assoc/pdf/2014/0016/JOAFE_PDF_Unitaire_20140016_01712.pdf">Parue
+            au Journal officiel le 19 avril 2014</a>, l'association a tenu sa première assemblée générale le 15 mars
+        2014, au cours de laquelle ont été élus le bureau et le conseil d'administration en présence des
+        <strong>quatorze</strong> membres fondateurs.
     </p>
     <p>
-        Ces membres fondateurs sont tous des anciens membres très actifs du feu siteduzero, un site de diffusion de connaissances et d'entraide. À la suite du changement de politique de ce dernier, ils ont décidé de recréer une plateforme sur laquelle ils pourraient à nouveau s'entraider et partager convenablement leurs connaissances et surtout retrouver l'esprit communautaire qu'ils aimaient tant.
+        Ces membres fondateurs sont tous des anciens membres très actifs du feu siteduzero, un site de diffusion de
+        connaissances et d'entraide. À la suite du changement de politique de ce dernier, ils ont décidé de recréer une
+        plateforme sur laquelle ils pourraient à nouveau s'entraider et partager convenablement leurs connaissances et
+        surtout retrouver l'esprit communautaire qu'ils aimaient tant.
     </p>
     <p>
         Voilà l'histoire de Zeste de Savoir.
     </p>
+
+    <h3>L'association et le site</h3>
+    <p>
+        <strong>Adhérer à l'association ne vous apporte rien sur le site</strong>. L'adhésion n'est là que pour soutenir
+        le projet, et ne donne droit à aucun pouvoir ou badge supplémentaire. Elle ne donne même pas accès à un forum
+        secret, puisque le forum de l'association est public !
+    </p>
+    <p>
+        De même, toutes les fonctionnalités du site sont disponibles à tous : aucune n'est conditionné à l'adhésion à
+        l'association.
+    </p>
+    <p>
+        Notez que vous devez être inscrit pour pouvoir adhérer.
+    </p>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/pages/contact.html b/templates/pages/contact.html
index d874c23cec..5ceb8df23b 100644
--- a/templates/pages/contact.html
+++ b/templates/pages/contact.html
@@ -15,7 +15,7 @@
 
 
 {% block headline %}
-    <h2>Contact</h2>
+    <h1>Contact</h1>
 {% endblock %}
 
 
diff --git a/templates/pages/cookies.html b/templates/pages/cookies.html
index f0d5c70394..6d6d6c5cfa 100644
--- a/templates/pages/cookies.html
+++ b/templates/pages/cookies.html
@@ -15,7 +15,7 @@
 
 
 {% block headline %}
-    <h2>À propos des cookies</h2>
+    <h1>À propos des cookies</h1>
 {% endblock %}
 
 
@@ -33,7 +33,7 @@ <h3>À quoi servent les cookies ?</h3>
     <h4>Cookies techniques</h4>
     <p>Certaines fonctionnalités du site nécessitent des cookies pour pouvoir être opérationnelles. L'exemple typique est la connexion aux parties privées de Zeste de Savoir.</p>
     <p>La liste complète des cookies techniques utilisés sur Zeste de Savoir et leur utilité est détaillée un peu plus bas.</p>
-    <p>Ces cookies, purement techniques, <strong>sont indispensables au foncitonnement de Zeste de Savoir</strong>. Si vous les refusez, les éléments qui en dépendent ne fonctionneront tout simplement pas !</p>
+    <p>Ces cookies, purement techniques, <strong>sont indispensables au fonctionnement de Zeste de Savoir</strong>. Si vous les refusez, les éléments qui en dépendent ne fonctionneront tout simplement pas !</p>
 
     <h4>Cookies d'analyse d'audience</h4>
     <p>Zeste de Savoir analyse son audience. Que signifie ce terme barbare ? Tout simplement que nous étudions la manière dont le site est utilisé :</p>
@@ -111,7 +111,7 @@ <h4>Préparation</h4>
     <h4>Cuisson</h4>
     <p>Préchauffez votre four à 220°C / thermostat 7-8, grille en position basse.</p>
     <p>Façonnez des cookies d'environ 10 cm de côté sur la plaque recouverte de papier sulfurisé. Attention, espacez-les parce qu'ils s'étalent à la cuisson.</p>
-    <p>Enfournez-lez environ 10 minutes, ils sont cuits lorsqu'ils prennent une belle couleur dorée !</p>
+    <p>Enfournez-les environ 10 minutes, ils sont cuits lorsqu'ils prennent une belle couleur dorée !</p>
     <h4>Conseils divers</h4>
     <p>Si vous avez la flemme de découper le chocolat, vous pouvez utiliser des pépites de chocolat mais en général c'est moins bon. Surtout pas de chocolat à déguster : ces chocolats manquent de sucre pour la patisserie !</p>
     <p>La cuisson parfaite se joue à quelques secondes près (sérieusement), alors surveillez-les bien ! Un SMS de trop, et vous obtenez des cookies en béton. Ce qui serait dommage !</p>
diff --git a/templates/pages/eula.html b/templates/pages/eula.html
index c0d599902d..83e84e2ea5 100644
--- a/templates/pages/eula.html
+++ b/templates/pages/eula.html
@@ -15,7 +15,7 @@
 
 
 {% block headline %}
-    <h2>Conditions générales d'utilisation</h2>
+    <h1>Conditions générales d'utilisation</h1>
 {% endblock %}
 
 
diff --git a/templates/tutorial/base.html b/templates/tutorial/base.html
index 35cab7c6db..c3280a5f2e 100644
--- a/templates/tutorial/base.html
+++ b/templates/tutorial/base.html
@@ -4,7 +4,7 @@
 
 
 {% block title_base %}
-    &#183; Mes tutoriels
+    &bull; Tutoriels
 {% endblock %}
 
 
@@ -19,7 +19,11 @@
     {% if user in tutorial.authors.all %}
         <li><a href="{% url "zds.member.views.tutorials" %}">Mes tutoriels</a></li>
     {% else %}
-        <li><a href="{% url "zds.tutorial.views.index" %}">Tutoriels</a></li>
+        <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+            <a href="{% url "zds.tutorial.views.index" %}" itemprop="url">
+                <span itemprop="title">Tutoriels</span>
+            </a>
+        </li>
     {% endif %}
 {% endblock %}
 
@@ -56,28 +60,35 @@ <h3>Télécharger</h3>
                 <ul>
                     {% if tutorial.on_line %}
                         {% if perms.tutorial.change_tutorial %}
-                           <li>
-                                <a href="{% url "zds.tutorial.views.download_markdown" %}?tutoriel={{ tutorial.pk }}" class="ico-after download blue">
-                                    Markdown
-                                </a>
-                            </li>
+                            {% if tutorial.have_markdown %}
+                                <li>
+                                    <a href="{% url "zds.tutorial.views.download_markdown" %}?tutoriel={{ tutorial.pk }}" class="ico-after download blue">
+                                        Markdown
+                                    </a>
+                                </li>
+                            {% endif %}
                         {% endif %}
-
+                        {% if tutorial.have_html %}
                         <li>
                             <a href="{% url "zds.tutorial.views.download_html" %}?tutoriel={{ tutorial.pk }}" class="ico-after download blue">
                                 HTML
                             </a>
                         </li>
+                        {% endif %}
+                        {% if tutorial.have_pdf %}
                         <li>
                             <a href="{% url "zds.tutorial.views.download_pdf" %}?tutoriel={{ tutorial.pk }}" class="ico-after download blue">
                                 PDF
                             </a>
                         </li>
+                        {% endif %}
+                        {% if tutorial.have_epub %}
                         <li>
                             <a href="{% url "zds.tutorial.views.download_epub" %}?tutoriel={{ tutorial.pk }}" class="ico-after download blue">
                                 EPUB
                             </a>
                         </li>
+                        {% endif %}
                     {% endif %}
 
                     <li>
diff --git a/templates/tutorial/base_online.html b/templates/tutorial/base_online.html
index 097fdb37df..986c7822bc 100644
--- a/templates/tutorial/base_online.html
+++ b/templates/tutorial/base_online.html
@@ -4,16 +4,29 @@
 
 
 {% block title_base %}
-    &#183; Tutoriels
+    &bull; Tutoriels
 {% endblock %}
 
-{% block source_content %}
+
+
+{% block canonical %}
     {% if tutorial.source and tutorial.source != "" %}
-    <link rel="canonical" href="{{tutorial.source}}" />
+    	<link rel="canonical" href="{{ tutorial.source }}">
     {% endif %}
 {% endblock %}
 
 
+
 {% block breadcrumb_base %}
-    <li><a href="{% url "zds.tutorial.views.index" %}">Tutoriels</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{% url "zds.tutorial.views.index" %}" itemprop="url">
+            <span itemprop="title">Tutoriels</span>
+        </a>
+    </li>
+{% endblock %}
+
+
+
+{% block article_schema %}
+    itemscope itemtype="http://schema.org/Article"
 {% endblock %}
diff --git a/templates/tutorial/chapter/view.html b/templates/tutorial/chapter/view.html
index a3e6499ce3..793dc0e561 100644
--- a/templates/tutorial/chapter/view.html
+++ b/templates/tutorial/chapter/view.html
@@ -21,11 +21,17 @@
     {% with authors=tutorial.authors.all %}
         <h1 {% if chapter.image %}class="illu"{% endif %}>
             {% if chapter.image %}
-                <img src="{{ chapter.image.thumb.url }}" alt="">
+                <img src="{{ chapter.image.physical.tutorial_illu.url }}" alt="">
             {% endif %}
             {{ chapter.title }}
         </h1>
 
+        {% if tutorial.licence %}
+            <p class="license">
+                {{ tutorial.licence }}
+            </p>
+        {% endif %}
+
         {% include 'tutorial/includes/tags_authors.part.html' %}
 
         {% if tutorial.in_beta and tutorial.sha_beta == version %}
diff --git a/templates/tutorial/chapter/view_online.html b/templates/tutorial/chapter/view_online.html
index f131ed15c2..aee1ff44cb 100644
--- a/templates/tutorial/chapter/view_online.html
+++ b/templates/tutorial/chapter/view_online.html
@@ -10,27 +10,21 @@
 
 
 {% block breadcrumb %}
-    <li><a href="{{ chapter.part.tutorial.get_absolute_url_online }}">{{ chapter.part.tutorial.title }}</a></li>
-    <li><a href="{% url "view-part-url-online" chapter.part.tutorial.pk chapter.part.tutorial.slug chapter.part.pk chapter.part.slug %}">
-        {{ chapter.part.title }}
-    </a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ chapter.part.tutorial.get_absolute_url_online }}" itemprop="url">
+            <span itemprop="title">{{ chapter.part.tutorial.title }}</span>
+        </a>
+    </li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{% url "view-part-url-online" chapter.part.tutorial.pk chapter.part.tutorial.slug chapter.part.pk chapter.part.slug %}" itemprop="url">
+            <span itemprop="title">{{ chapter.part.title }}</span>
+        </a>
+    </li>
     <li>{{ chapter.title }}</li>
 {% endblock %}
 
 
 
-{% block content %}
-    {% with tutorial=chapter.get_tutorial %}
-        {% with authors=tutorial.authors.all %}
-            {% include "tutorial/includes/chapter_pager.part.html" with position="top" online=True %}
-            {% include "tutorial/includes/chapter_online.part.html" %}
-            {% include "tutorial/includes/chapter_pager.part.html" with position="bttom" online=True %}
-        {% endwith %}
-    {% endwith %}
-{% endblock %}
-
-
-
 {% block headline %}
     {% if chapter.tutorial %}
         {% set chapter.tutorial as tutorial %}
@@ -45,11 +39,29 @@ <h1 {% if chapter.image %}class="illu"{% endif %}>
         {{ chapter.title }}
     </h1>
 
+    {% if tutorial.licence %}
+        <span class="license">
+            Licence {{ tutorial.licence }}
+        </span>
+    {% endif %}
+
     {% include 'tutorial/includes/tags_authors.part.html' %}
 {% endblock %}
 
 
 
+{% block content %}
+    {% with tutorial=chapter.get_tutorial %}
+        {% with authors=tutorial.authors.all %}
+            {% include "tutorial/includes/chapter_pager.part.html" with position="top" online=True %}
+            {% include "tutorial/includes/chapter_online.part.html" %}
+            {% include "tutorial/includes/chapter_pager.part.html" with position="bttom" online=True %}
+        {% endwith %}
+    {% endwith %}
+{% endblock %}
+
+
+
 {% block sidebar_blocks %}
     {% if perms.tutorial.change_tutorial %}
         <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Administration">
diff --git a/templates/tutorial/comment/edit.html b/templates/tutorial/comment/edit.html
index cfd5e822fb..823a2d4e0e 100644
--- a/templates/tutorial/comment/edit.html
+++ b/templates/tutorial/comment/edit.html
@@ -17,13 +17,15 @@
 
 
 {% block headline %}
-    <h2>Éditer le commentaire du tutoriel : {{ tutorial.title }}</h2>
+    <h1>Éditer le commentaire du tutoriel : {{ tutorial.title }}</h1>
 {% endblock %}
 
 
 
 {% block headline_sub %}
-    <h3 class="subtitle">{{ tutorial.description }}</h3>
+    <h2 class="subtitle">
+    	{{ tutorial.description }}
+    </h2>
 {% endblock %}
 
 
diff --git a/templates/tutorial/comment/new.html b/templates/tutorial/comment/new.html
index 2158da73c4..307d5dc2b7 100644
--- a/templates/tutorial/comment/new.html
+++ b/templates/tutorial/comment/new.html
@@ -18,13 +18,13 @@
 
 
 {% block headline %}
-    <h2>Ajouter un commentaire au tutoriel : {{tutorial.title}}</h2>
+    <h1>Ajouter un commentaire au tutoriel : {{ tutorial.title }}</h1>
 {% endblock %}
 
 
 
 {% block headline_sub %}
-    <h3 class="subtitle">{{ tutorial.description }}</h3>
+    <h2 class="subtitle">{{ tutorial.description }}</h2>
 {% endblock %}
 
 
diff --git a/templates/tutorial/extract/edit.html b/templates/tutorial/extract/edit.html
index 3969f9c6ef..3f57aeca9f 100644
--- a/templates/tutorial/extract/edit.html
+++ b/templates/tutorial/extract/edit.html
@@ -23,7 +23,7 @@
 
 
 {% block headline %}
-    <h2>Éditer l'extrait</h2>
+    <h1>Éditer l'extrait</h1>
 {% endblock %}
 
 
diff --git a/templates/tutorial/extract/new.html b/templates/tutorial/extract/new.html
index b7554199c8..7611988259 100644
--- a/templates/tutorial/extract/new.html
+++ b/templates/tutorial/extract/new.html
@@ -23,13 +23,15 @@
 
 
 {% block headline %}
-    <h2>Nouvel extrait</h2>
-
-    {% if chapter.part %}
-        <h3 class="subtitle">{{ chapter.title }}</h3>
-    {% else %}
-        <h3 class="subtitle">{{ chapter.tutorial.title }}</h3>
-    {% endif %}
+    <h1>Nouvel extrait</h1>
+
+    <h2 class="subtitle">
+        {% if chapter.part %}
+            {{ chapter.title }}
+        {% else %}
+            {{ chapter.tutorial.title }}
+        {% endif %}
+    </h2>
 {% endblock %}
 
 
diff --git a/templates/tutorial/includes/chapter.part.html b/templates/tutorial/includes/chapter.part.html
index e69036566c..4bc84cdd11 100644
--- a/templates/tutorial/includes/chapter.part.html
+++ b/templates/tutorial/includes/chapter.part.html
@@ -7,7 +7,7 @@
     {% if not chapter.type = 'MINI' %}
         {% if chapter.intro and chapter.intro != "None" %}
             {{ chapter.intro|emarkdown }}
-        {% else %}
+        {% elif not tutorial.in_beta or tutorial.sha_beta != version %}
             <p class="ico-after warning">
                 Il n'y a pas d'introduction.
             </p>
@@ -39,7 +39,7 @@ <h2 id="{{ extract.position_in_chapter }}-{{ extract.title|slugify }}">
             </a>
         </h2>
 
-        {% if user in authors %}
+        {% if user in authors or perms.tutorial.change_tutorial %}
             <div class="actions-title">
                 <a href="#delete-{{ extract.pk }}" class="open-modal ico-after cross btn btn-grey">Supprimer</a>
                 <form action="{% url "zds.tutorial.views.modify_extract" %}" method="post" id="delete-{{ extract.pk }}" class="modal modal-small">
@@ -56,7 +56,7 @@ <h2 id="{{ extract.position_in_chapter }}-{{ extract.title|slugify }}">
                 <a href="#move-extract-{{ extract.pk }}" class="open-modal ico-after move btn btn-grey">Déplacer</a>
                 <form action="{% url "zds.tutorial.views.modify_extract" %}" method="post" class="modal modal-small" id="move-extract-{{ extract.pk }}">
                     <select name="move_target">
-                        <option>Déplacer</option>
+                        <option disabled="disabled">Déplacer</option>
                         {% if extract.position_in_chapter > 1 %}
                             <option value="{{ extract.position_in_chapter|add:-1 }}">Monter</option>
                         {% endif %}
@@ -88,7 +88,7 @@ <h2 id="{{ extract.position_in_chapter }}-{{ extract.title|slugify }}">
 
                     {% csrf_token %}
                     <button type="submit">
-                        Confirmer
+                        Déplacer
                     </button>
                 </form>
 
@@ -112,7 +112,7 @@ <h2 id="{{ extract.position_in_chapter }}-{{ extract.title|slugify }}">
     {% if not chapter.type = 'MINI' %}
         {% if chapter.conclu and chapter.conclu != "None" %}
             {{ chapter.conclu|emarkdown }}
-        {% else %} 
+        {% elif not tutorial.in_beta or tutorial.sha_beta != version %} 
             <p class="ico-after warning">
                 Il n'y a pas de conclusion.
             </p>
diff --git a/templates/tutorial/includes/chapter_pager.part.html b/templates/tutorial/includes/chapter_pager.part.html
index 05f5c71648..953bbcb119 100644
--- a/templates/tutorial/includes/chapter_pager.part.html
+++ b/templates/tutorial/includes/chapter_pager.part.html
@@ -5,7 +5,7 @@
                 {% if online %}
                     href="{{ prev.get_absolute_url_online }}"
                 {% else %}
-                    href="{{ prev.get_absolute_url }}{%if version %}?version={{version}}{% endif %}"
+                    href="{{ prev.get_absolute_url }}{% if version %}?version={{ version }}{% endif %}"
                 {% endif %}
                 class="ico-after arrow-left"
             >
@@ -20,7 +20,7 @@
                 {% if online %}
                     href="{{ next.get_absolute_url_online }}"
                 {% else %}
-                    href="{{ next.get_absolute_url }}{%if version %}?version={{version}}{% endif %}"
+                    href="{{ next.get_absolute_url }}{% if version %}?version={{ version }}{% endif %}"
                 {% endif %}
                 class="ico-after arrow-right"
             >
diff --git a/templates/tutorial/includes/opengraph.part.html b/templates/tutorial/includes/opengraph.part.html
new file mode 100644
index 0000000000..72fc3303ad
--- /dev/null
+++ b/templates/tutorial/includes/opengraph.part.html
@@ -0,0 +1,13 @@
+<meta property="og:type" content="article">
+
+{% if tutorial.create_at %}
+    <meta property="og:article:published_time" content="{{ tutorial.create_at|date:"c" }}">
+{% endif %}
+{% if tutorial.pubdate %}
+    <meta property="og:article:modified_time" content="{{ tutorial.pubdate|date:"c" }}">
+{% endif %}
+
+<meta property="og:article:section" content="Tutoriels">
+{% for catofsubcat in tutorial.subcategory.all %}
+    <meta property="og:article:tag" content="{{ catofsubcat.title }}">
+{% endfor %}
\ No newline at end of file
diff --git a/templates/tutorial/includes/part.part.html b/templates/tutorial/includes/part.part.html
index 9f563a3d73..9452479d6c 100644
--- a/templates/tutorial/includes/part.part.html
+++ b/templates/tutorial/includes/part.part.html
@@ -9,7 +9,7 @@
                 {{ part.intro|safe }}
             {% endif %}
 
-            <ul>
+            <ol>
                 {% for chapter in chapters %}
                     <li>
                         <h3>
@@ -23,7 +23,7 @@ <h3>
                                 Chapitre {{ chapter.part.position_in_tutorial }}.{{ chapter.position_in_part }} | {{ chapter.title }}
                             </a>
                         </h3>
-                        <ul>
+                        <ol>
                             {% for extract in chapter.extracts %}
                                 <li>
                                     <h4>
@@ -39,10 +39,10 @@ <h4>
                                     </h4>
                                 </li>
                             {% endfor %}
-                        </ul>
+                        </ol>
                     </li>
                 {% endfor %}
-            </ul>
+            </ol>
 
             {% if part.conclu %}
                 {{ part.conclu|safe }}
diff --git a/templates/tutorial/includes/summary.part.html b/templates/tutorial/includes/summary.part.html
index 52d5ae3359..a7e01d051e 100644
--- a/templates/tutorial/includes/summary.part.html
+++ b/templates/tutorial/includes/summary.part.html
@@ -10,7 +10,7 @@ <h3>Sommaire</h3>
     {% if tutorial.type == 'MINI' %}
         {# Small tutorial #}
         {% if chapter.extracts %}
-            <ul>
+            <ol>
                 {% for extract in chapter.extracts %}
                     <li>
                         <a data-num="{{ extract.position_in_chapter }}"
@@ -21,6 +21,12 @@ <h3>Sommaire</h3>
                         </a>
                     </li>
                 {% endfor %}
+            </ol>
+        {% else %}
+            <ul>
+                <li class="inactive">
+                    <span class="disabled mobile-menu-link">Aucun extrait actuellement</span>
+                </li>
             </ul>
         {% endif %}
     {% else %}
@@ -29,51 +35,57 @@ <h3>Sommaire</h3>
             {% for part in tutorial.get_parts %}
                 <h4 data-num="{{ part.position_in_tutorial|roman }}">
                     <a class="mobile-menu-link"
-                       {% if online %}
-                           href="{% url "view-part-url-online" tutorial.pk tutorial.slug part.pk part.slug %}"
-                       {% else %}
-                           href="{% url "view-part-url" tutorial.pk tutorial.slug part.pk part.slug %}"{% if version %}?version={{ version }}{% endif %}
-                       {% endif %}
+                        {% if online %}
+                            href="{% url "view-part-url-online" tutorial.pk tutorial.slug part.pk part.slug %}"
+                        {% else %}
+                            href="{% url "view-part-url" tutorial.pk tutorial.slug part.pk part.slug %}"{% if version %}?version={{ version }}{% endif %}
+                        {% endif %}
                     >
                         {{ part.title }}
                     </a>
                 </h4>
                 
-                <ul>
+                <ol>
                     {% for chapter in part.get_chapters %}
                         <li {% if chapter_current.pk == chapter.pk %}class="current"{% endif %}>
                             <a data-num="{{ chapter.position_in_part }}"
-                               {% if online %}
-                                   href="{% url "view-chapter-url-online" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}"
-                               {% else %}
-                                   href="{% url "view-chapter-url" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}"{% if version %}?version={{ version }}{% endif %}
-                               {% endif %}
-                               class="mobile-menu-link mobile-menu-sublink {% if chapter_current.pk = chapter.pk %}unread{% endif %}"
+                                {% if online %}
+                                    href="{% url "view-chapter-url-online" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}"
+                                {% else %}
+                                    href="{% url "view-chapter-url" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}"{% if version %}?version={{ version }}{% endif %}
+                                {% endif %}
+                                class="mobile-menu-link mobile-menu-sublink {% if chapter_current.pk = chapter.pk %}unread{% endif %}"
                             >
                                 {{ chapter.title }}
                             </a>
 
                             {% if chapter_current.pk == chapter.pk %}
-                                <ul class="mobile-menu-bloc mobile-all-links" data-title="Sommaire du chapitre">
+                                <ol class="mobile-menu-bloc mobile-all-links" data-title="Sommaire du chapitre">
                                     {% for extract in chapter.extracts %}
                                         <li>
                                             <a
-                                               {% if online %}
-                                                   href="{% url "view-chapter-url-online" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}#{{ extract.position_in_chapter }}-{{ extract.title|slugify }}"
-                                               {% else %}
-                                                   href="{% url "view-chapter-url" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}#{{ extract.position_in_chapter }}-{{ extract.title|slugify }}"{% if version %}?version={{ version }}{% endif %}
-                                               {% endif %}
+                                                {% if online %}
+                                                    href="{% url "view-chapter-url-online" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}#{{ extract.position_in_chapter }}-{{  extract.title|slugify }}"
+                                                {% else %}
+                                                    href="{% url "view-chapter-url" tutorial.pk tutorial.slug part.pk part.slug chapter.pk chapter.slug %}#{{ extract.position_in_chapter }}-{{ extract.title|slugify }}"{% if version %}?version={{ version }}{% endif %}
+                                                {% endif %}
                                             >
                                                 {{ extract.title }}
                                             </a>
                                         </li>
                                     {% endfor %}
-                                </ul>
+                                </ol>
                             {% endif %}
                         </li>
                     {% endfor %}
-                </ul>
+                </ol>
             {% endfor %}
+        {% else %}
+            <ul>
+                <li class="inactive">
+                    <span class="disabled mobile-menu-link">Aucune partie actuellement</span>
+                </li>
+            </ul>
         {% endif %}
     {% endif %}
 </div>
diff --git a/templates/tutorial/includes/tags_authors.part.html b/templates/tutorial/includes/tags_authors.part.html
index 625b002dc0..1479ecb3d0 100644
--- a/templates/tutorial/includes/tags_authors.part.html
+++ b/templates/tutorial/includes/tags_authors.part.html
@@ -1,17 +1,34 @@
+{% load date %}
+
+
+
 {% if tutorial.subcategory.all|length > 0 %}
-    <ul class="taglist">
+    <ul class="taglist" itemprop="keywords">
         {% for catofsubcat in tutorial.subcategory.all %}
             <li><a href="{{ catofsubcat.get_absolute_url_tutorial }}">{{ catofsubcat.title }}</a></li>
         {% endfor %}
     </ul>
 {% endif %}
 
+
+
+{% if tutorial.update %}
+    <span class="pubdate">
+        Dernière mise à jour :  
+        <time datetime="{{ tutorial.update|date:"c" }}" pubdate="pubdate" itemprop="dateModified">
+            {{ tutorial.update|format_date }}
+        </time>
+    </span>
+{% endif %}
+
+
+
 <div class="authors">
-    <span class="authors-label">Auteurs : </span>
+    <span class="authors-label">Auteur{{ tutorial.authors.all|pluralize }} : </span>
     <ul>
         {% for member in tutorial.authors.all %}
             <li>
-                {% include "misc/member_item.part.html" with avatar=True %}
+                {% include "misc/member_item.part.html" with avatar=True author=True %}
             </li>
         {% endfor %}
 
@@ -23,4 +40,4 @@
             </li>
         {% endif %}
     </ul>
-</div>
\ No newline at end of file
+</div>
diff --git a/templates/tutorial/includes/tutorial_item.part.html b/templates/tutorial/includes/tutorial_item.part.html
index e86f4d8933..75d4b06cb1 100644
--- a/templates/tutorial/includes/tutorial_item.part.html
+++ b/templates/tutorial/includes/tutorial_item.part.html
@@ -8,9 +8,11 @@
             {{ tutorial.get_absolute_url_online }}
         {% endif %}
     ">
-        <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="" class="tutorial-img avatar">
-        <div class="tutorial-infos">
-            <h3>{{ tutorial.title }}</h3>
+        {% if tutorial.image.physical.tutorial_illu.url %}
+            <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="" class="tutorial-img avatar">
+        {% endif %}
+        <div class="tutorial-infos {% if not tutorial.image.physical.tutorial_illu.url %}no-illu{% endif %}">
+            <h3 itemprop="itemListElement">{{ tutorial.title }}</h3>
             
             <span class="article-metadata">
                 {% if tutorial.subcategory %}
diff --git a/templates/tutorial/index.html b/templates/tutorial/index.html
index 92c1743f9a..07ecdfd8b6 100644
--- a/templates/tutorial/index.html
+++ b/templates/tutorial/index.html
@@ -4,31 +4,49 @@
 
 
 {% block title %}
-    Liste des tutoriels
+    {% if tag %}
+        {{ tag }}
+    {% else %}
+        Tous les tutoriels
+    {% endif %}
 {% endblock %}
 
 
 
-{% block meta %}
-    <meta name="description" content="Les tutoriels vous permettent d'apprendre
-    sur divers sujets tous plus intéressant les uns que les autres." />
+{% block description %}
+    {% if tag %}
+        Découvrez tous nos tutoriels sur {{ tag }}. Vous pourrez également découvrir divers sujets tous plus intéressants les uns que les autres.
+    {% else %}
+        Les tutoriels vous permettent d'apprendre divers sujets tous plus intéressants 
+        les uns que les autres.
+    {% endif %}
 {% endblock %}
 
 
 
 {% block breadcrumb %}
-    <li>Liste des tutoriels</li>
+    {% if tag %}
+        <li>{{ tag }}</li>
+    {% else %}
+        <li>Tous les tutoriels</li>
+    {% endif %}
 {% endblock %}
 
 
 
 {% block content_out %}
-    <section class="full-content-wrapper">
-        <h2 class="ico-after ico-tutorials">
+    <section class="full-content-wrapper" itemscope itemtype="http://schema.org/ItemList">
+        <h1 class="ico-after ico-tutorials" itemprop="name">
             {% block headline %}
-                Liste des tutoriels
+                {% if tag %}
+                    Tutoriels : {{ tag }}
+                {% else %}
+                    Tous les tutoriels
+                {% endif %}
             {% endblock %}
-        </h2>
+        </h1>
+        
+        <meta itemprop="itemListOrder" content="Unordered">
 
         {% if tutorials %}
             <div class="tutorial-list">
diff --git a/templates/tutorial/member/online.html b/templates/tutorial/member/online.html
index dba8b5e450..171035d892 100644
--- a/templates/tutorial/member/online.html
+++ b/templates/tutorial/member/online.html
@@ -13,12 +13,14 @@
 
 {% block breadcrumb %}
     {% with profile=usr|profile %}
-        <li ><a href="{{ profile.get_absolute_url }}">{{ usr.username }}</a></li>
+        <li><a href="{{ profile.get_absolute_url }}">{{ usr.username }}</a></li>
     {% endwith %}
-    <li><a href="{% url "zds.tutorial.views.find_tuto" usr.username %}">Tutoriels publiés</a></li>
+    <li><a href="{% url "zds.tutorial.views.find_tuto" usr.pk %}">Tutoriels publiés</a></li>
     <li>Recherche</li>
 {% endblock %}
 
+
+
 {% block headline %}
     <h2 class="ico-after ico-tutorials">Tutoriels publiés par {{ usr.username }}</h2>
 {% endblock %}
diff --git a/templates/tutorial/part/view.html b/templates/tutorial/part/view.html
index 37c1e8bc92..32f58ed583 100644
--- a/templates/tutorial/part/view.html
+++ b/templates/tutorial/part/view.html
@@ -21,6 +21,12 @@ <h2>
         {{ part.title }}
     </h2>
 
+    {% if tutorial.licence %}
+        <p class="license">
+            {{ tutorial.licence }}
+        </p>
+    {% endif %}
+
     {% include 'tutorial/includes/tags_authors.part.html' with tutorial=part.tutorial %}
 
     {% if part.tutorial.in_beta and part.tutorial.sha_beta == version %}
@@ -37,7 +43,7 @@ <h2>
 {% block content %}
     {% if part.intro and part.intro != "None" %}
         {{ part.intro|emarkdown }}
-    {% else %}
+    {% elif not tutorial.in_beta or tutorial.sha_beta != version %}
         <p class="ico-after warning">
             Il n'y a pas d'introduction.
         </p>
@@ -84,7 +90,7 @@ <h4>
 
     {% if part.conclu and part.conclu != "None" %}
         {{ part.conclu|emarkdown }}
-    {% else %}
+    {% elif not tutorial.in_beta or tutorial.sha_beta != version %}
         <p class="ico-after warning">
             Il n'y a pas de conclusion.
         </p>
@@ -112,6 +118,7 @@ <h4>
                 <a href="#move-part" class="open-modal ico-after move blue">
                     Déplacer <span class="wide">la partie</span>
                 </a>
+
                 <form action="{% url "zds.tutorial.views.modify_part" %}" method="POST" class="modal modal-small" id="move-part">
                     <select name="move_target" class="select-autosubmit">
                         <option disabled="disabled">
@@ -168,6 +175,23 @@ <h4>
                     <button type="submit">Déplacer</button>
                 </form>
             </li>
+            <li>
+                <a href="#delete-part" class="open-modal ico-after cross red">
+                    Supprimer la partie
+                </a>
+
+                <form action="{% url "zds.tutorial.views.modify_part" %}" method="post" id="delete-part" class="modal modal-medium">
+                    <p>
+                        Attention, vous vous apprêtez à supprimer définitivement la partie "<em>{{ part.title }}</em>".
+                    </p>
+                    <input type="hidden" name="part" value="{{ part.pk }}">
+
+                    {% csrf_token %}
+                    <button type="submit" name="delete">
+                        Confirmer
+                    </button>
+                </form>
+            </li>
         {% endif %}
     {% endif %}
 {% endblock %}
diff --git a/templates/tutorial/part/view_online.html b/templates/tutorial/part/view_online.html
index 6928b00120..83690b206a 100644
--- a/templates/tutorial/part/view_online.html
+++ b/templates/tutorial/part/view_online.html
@@ -8,17 +8,46 @@
 
 
 
+{% block image %}{% spaceless %}
+    {% if tutorial.image %}
+        {{ tutorial.image.physical.tutorial_illu.url }}
+    {% else %}
+        {{ block.super }}
+    {% endif %}
+{% endspaceless %}{% endblock %}
+
+
+
+{% block opengraph %}
+    {% include "tutorial/includes/opengraph.part.html" %}
+{% endblock %}
+
+
+
 {% block breadcrumb %}
-    <li><a href="{{ part.tutorial.get_absolute_url_online }}">{{ part.tutorial.title }}</a></li>
+    <li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
+        <a href="{{ part.tutorial.get_absolute_url_online }}" itemprop="url">
+            <span itemprop="title">{{ part.tutorial.title }}</span>
+        </a>
+    </li>
     <li>{{ part.title }}</li>
 {% endblock %}
 
 
 
 {% block headline %}
-    <h2>
+    <h1 {% if tutorial.image %}class="illu"{% endif %} itemprop="name">
+        {% if tutorial.image %}
+            <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="" itemprop="thumbnailUrl">
+        {% endif %}
         {{ part.title }}
-    </h2>
+    </h1>
+
+    {% if tutorial.licence %}
+        <span class="license" itemprop="license">
+            Licence {{ tutorial.licence }}
+        </span>
+    {% endif %}
 
     {% include 'tutorial/includes/tags_authors.part.html' with tutorial=part.tutorial %}
 {% endblock %}
diff --git a/templates/tutorial/tutorial/history.html b/templates/tutorial/tutorial/history.html
index d293c3b675..e92698c1b7 100644
--- a/templates/tutorial/tutorial/history.html
+++ b/templates/tutorial/tutorial/history.html
@@ -5,90 +5,88 @@
 
 
 {% block title %}
-  {{ tutorial.title }}
+    Historique de "{{ tutorial.title }}"
 {% endblock %}
 
 
 
 {% block breadcrumb %}
     <li><a href="{{ tutorial.get_absolute_url }}">{{ tutorial.title }}</a></li>
-    <li>Historique</li>
+    <li>Historique des modifications</li>
 {% endblock %}
 
 
 
 {% block headline %}
-    <h1>{{ tutorial.title }}</h1>
-    <h3 class="subtitle">{{ tutorial.description }}</h3>
+    <h1 {% if tutorial.image %}class="illu"{% endif %} itemprop="name">
+        {% if tutorial.image %}
+            <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="" itemprop="thumbnailUrl">
+        {% endif %}
+        Historique de "{{ tutorial.title }}"
+    </h1>
+
+    {% if tutorial.licence %}
+        <span class="license">
+            Licence {{ tutorial.licence }}
+        </span>
+    {% endif %}
+
+    <h2 class="subtitle">
+        {{ tutorial.description }}
+    </h2>
+
+    {% include 'tutorial/includes/tags_authors.part.html' %}
 {% endblock %}
 
 
 
 {% block content %}
-    {# TODO : Tout est à refaire ici #}
-    <div class="row">
-        <div class="large-12 columns">
-            <div class="large-1 columns hide-for-small">
-                {% if tutorial.image %}
-                    <img src="{{tutorial.image.physical.tutorial_illu.url }}" alt="">
-                {% endif %}
-            </div>
-            <div class="large-11 columns">
-                <p>
-                    Tutoriel
-                    {% if not tutorial.is_mini %}
-                    étendu
-                    {% endif %}
-                    rédigé par
-                    {% for member in tutorial.authors.all %}
-                        {% if forloop.counter > 1 %}
-                            {% if forloop.last %}
-                            et
+    <table class="fullwidth">
+        <thead>
+            <tr>
+                <th width="10%">Etat</th>
+                <th width="18%">Date</th>
+                <th>Version</th>
+                <th width="10%">Diff.</th>
+                <th width="15%">Auteur</th>
+            </tr>
+        </thead>
+        <tbody>
+            {% for log in logs %}
+                <tr>
+                    <td>
+                        {% if tutorial.sha_validation = log.newhexsha %}
+                            Validation
+                        {% elif tutorial.sha_beta = log.newhexsha %}
+                            Beta
+                        {% elif tutorial.sha_draft =  log.newhexsha %}
+                            Draft 
+                        {% endif%}
+                    </td>
+                    <td>
+                        {{ log.time.0|humane_time }}
+                    </td>
+                    <td>
+                        <a href="{% url "zds.tutorial.views.view_tutorial" tutorial.pk tutorial.slug %}?version={{ log.newhexsha }}" >
+                            {{ log.message }}
+                        </a>
+                    </td>
+                    <td>
+                        <a href="{% url "zds.tutorial.views.diff" tutorial.pk tutorial.slug %}?sha={{ log.newhexsha }}" >
+                            {{ log.newhexsha|truncatechars:8 }}
+                        </a>
+                    </td>
+                    <td>
+                        {% with u=log.actor.name|user %}
+                            {% if u %}
+                                {% include "misc/member_item.part.html" with member=u avatar=True %}
                             {% else %}
-                            ,
+                                <em>Inconnu</em>
                             {% endif %}
-                        {% endif %}
-                        {% include "misc/member_item.part.html" %}
-                    {% endfor %}.
-                </p>
-            </div>
-        </div>
-    </div>
-
-    <div class="row">
-        <div class="large-12 columns">
-            <table>
-                <thead>
-                    <tr>
-                        <th></th>
-                        <th width="25%">Date</th>
-                        <th>Version</th>
-                        <th width="10%">Diff.</th>
-                        <th width="10%">Auteur</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    {% for log in logs %}
-                        <tr>
-                            <td><p>{% if tutorial.sha_validation = log.newhexsha %} Validation {% elif tutorial.sha_beta =  log.newhexsha %} Beta {% elif tutorial.sha_draft =  log.newhexsha %} Draft {% endif%}</p></td>
-                            <td><p>{{ log.time.0|humane_time }}</p></td>
-                            <td><p><a href="{% url "zds.tutorial.views.view_tutorial" tutorial.pk tutorial.slug %}?version={{ log.newhexsha }}" >{{ log.message }}</a></p></td>
-                            <td><p><a href="{% url "zds.tutorial.views.diff" tutorial.pk tutorial.slug %}?sha={{ log.newhexsha }}" >{{ log.newhexsha|truncatechars:8 }}</a></p></td>
-                            <td>
-                                {% with u=log.actor.name|user %}
-                                    {% if u %}
-                                        {% with profile=u|profile %}
-                                            <p><a href="{{ profile.get_absolute_url }}">{{ u.username }}</a></p>
-                                        {% endwith %}
-                                    {% else %}
-                                        <p>Inconnu</p>
-                                    {% endif %}
-                                {% endwith %}
-                            </td>
-                        </tr>
-                    {% endfor %}
-                </tbody>
-            </table>
-        </div>
-    </div>
+                        {% endwith %}
+                    </td>
+                </tr>
+            {% endfor %}
+        </tbody>
+    </table>
 {% endblock %}
\ No newline at end of file
diff --git a/templates/tutorial/tutorial/view.html b/templates/tutorial/tutorial/view.html
index c84ea8eeb4..da3f0be57a 100644
--- a/templates/tutorial/tutorial/view.html
+++ b/templates/tutorial/tutorial/view.html
@@ -25,10 +25,16 @@ <h1 {% if tutorial.image %}class="illu"{% endif %}>
         {{ tutorial.title }}
     </h1>
 
+    {% if tutorial.licence %}
+        <p class="license">
+            {{ tutorial.licence }}
+        </p>
+    {% endif %}
+
     {% if tutorial.description %}
-        <h3 class="subtitle">
+        <h2 class="subtitle">
             {{ tutorial.description }}
-        </h3>
+        </h2>
     {% endif %}
 
     {% if user in tutorial.authors.all or perms.tutorial.change_tutorial %}
@@ -37,6 +43,23 @@ <h3 class="subtitle">
         {% include 'tutorial/includes/tags_authors.part.html' with tutorial=tutorial %}
     {% endif %}
 
+    {% if perms.tutorial.change_tutorial and tutorial.sha_validation %}
+        <p class="content-wrapper alert-box info">
+            Ce tutoriel est en attente de validation
+        </p>
+        {% if validation.comment_authors %}
+            <div class="content-wrapper comment-author">
+                <p>
+                    Le message suivant a été laissé à destination des validateurs : 
+                </p>
+
+                <blockquote>
+                    {{ validation.comment_authors }}
+                </blockquote>
+            </div>
+        {% endif %}
+    {% endif %}
+
     {% if tutorial.in_beta and tutorial.sha_beta == version %}
         <div class="content-wrapper">
             <div class="alert-box warning">
@@ -52,7 +75,7 @@ <h3 class="subtitle">
     {% with tuto_version=tutorial|repo_tuto:version %}
         {% if tuto_version.introduction and tuto_version.introduction != "None" %}
             {{ tuto_version.introduction|emarkdown }}
-        {% else %}
+        {% elif not tutorial.in_beta or tutorial.sha_beta != version %}
             <p class="ico-after warning">
                 Il n'y a pas d'introduction.
             </p>
@@ -69,7 +92,7 @@ <h3 class="subtitle">
 
             {% for part in parts %}
                 <h2>
-                    <a href="{% url "view-part-url" tutorial.pk tutorial.slug part.pk part.slug %}{%if version %}?version={{version}}{% endif %}">
+                    <a href="{% url "view-part-url" tutorial.pk tutorial.slug part.pk part.slug %}{% if version %}?version={{ version }}{% endif %}">
                         Partie {{ part.position_in_tutorial }} : {{ part.title }}
                     </a>
                 </h2>
@@ -86,7 +109,7 @@ <h2>
 
         {% if tuto_version.conclusion and tuto_version.conclusion != "None" %}
             {{ tuto_version.conclusion|emarkdown }}
-        {% else %}
+        {% elif not tutorial.in_beta or tutorial.sha_beta != version %}
             <p class="ico-after warning">
                 Il n'y a pas de conclusion.
             </p>
@@ -246,6 +269,15 @@ <h2>
                     {% crispy formAskValidation %}
                 </div>
             </li>
+        {% elif tutorial.sha_validation != version %}
+            <li>
+                <a href="#ask-validation" class="open-modal ico-after tick green">
+                    Mettre à jour la version en validation
+                </a>
+                <div id="ask-validation" class="modal modal-medium">
+                    {% crispy formAskValidation %}
+                </div>
+            </li>
         {% else %}
             <li class="inactive">
                 <span class="ico-after tick disabled">En attente de validation</span>
@@ -257,7 +289,7 @@ <h2>
 
 
 {% block sidebar_blocks %}
-    {% if user in tutorial.authors.all or perms.tutorial.change_tutorial %}
+    {% if perms.tutorial.change_tutorial %}
         <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Validation">
             <h3>Validation</h3>
             <ul>
@@ -298,7 +330,7 @@ <h3>Validation</h3>
                                 <form action="{% url "zds.tutorial.views.reservation" validation.pk %}" method="post">
                                     {% csrf_token %}
                                     <button type="submit" class="ico-after lock blue">
-                                        Se retirer
+                                        Annuler la réservation
                                     </button>
                                 </form>
                             </li>
diff --git a/templates/tutorial/tutorial/view_online.html b/templates/tutorial/tutorial/view_online.html
index 9399a9d5b8..12495742e2 100644
--- a/templates/tutorial/tutorial/view_online.html
+++ b/templates/tutorial/tutorial/view_online.html
@@ -13,6 +13,28 @@
 
 
 
+{% block description %}
+    {{ tutorial.description }}
+{% endblock %}
+
+
+
+{% block image %}{% spaceless %}
+    {% if tutorial.image %}
+        {{ tutorial.image.physical.tutorial_illu.url }}
+    {% else %}
+        {{ block.super }}
+    {% endif %}
+{% endspaceless %}{% endblock %}
+
+
+
+{% block opengraph %}
+    {% include "tutorial/includes/opengraph.part.html" %}
+{% endblock %}
+
+
+
 {% block breadcrumb %}
     <li>{{ tutorial.title }}</li>
 {% endblock %}
@@ -20,20 +42,26 @@
 
 
 {% block headline %}
-    <h1 {% if tutorial.image %}class="illu"{% endif %}>
+    <h1 {% if tutorial.image %}class="illu"{% endif %} itemprop="name">
         {% if tutorial.image %}
-            <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="">
+            <img src="{{ tutorial.image.physical.tutorial_illu.url }}" alt="" itemprop="thumbnailUrl">
         {% endif %}
         {{ tutorial.title }}
     </h1>
 
+    {% if tutorial.licence %}
+        <span class="license" itemprop="license">
+            Licence {{ tutorial.licence }}
+        </span>
+    {% endif %}
+
     {% if tutorial.description %}
-        <h3 class="subtitle">
+        <h2 class="subtitle" itemprop="description">
             {{ tutorial.description }}
-        </h3>
+        </h2>
     {% endif %}
 
-    {% include 'tutorial/includes/tags_authors.part.html' with tutorial=tutorial %}
+    {% include "tutorial/includes/tags_authors.part.html" with tutorial=tutorial %}
 {% endblock %}
 
 
@@ -76,10 +104,19 @@ <h2>
 
 
 {% block content_after %}
-    <h2 class="reactions-title">Commentaires</h2>
+    <h3 class="comments-title" id="comments">
+        {% if tutorial.get_note_count > 0 %}
+            <span itemprop="commentCount">
+                {{ tutorial.get_note_count }}
+            </span>
+            commentaire{{ tutorial.get_note_count|pluralize }}
+        {% else %}
+            Aucun commentaire
+        {% endif %}
+    </h3>
 
 
-    {% include "misc/pagination.part.html" with position="top" topic=tutorial is_online=True %}
+    {% include "misc/pagination.part.html" with position="top" topic=tutorial is_online=True anchor="comments" %}
 
 
     {% for message in notes %}
@@ -110,11 +147,11 @@ <h2 class="reactions-title">Commentaires</h2>
         {% endif %}
 
 
-        {% include "misc/message.part.html" with perms_change=perms.tutorial.change_note topic=tutorial %}
+        {% include "misc/message.part.html" with perms_change=perms.tutorial.change_note topic=tutorial comment_schema=True %}
     {% endfor %}
 
 
-    {% include "misc/pagination.part.html" with position="bottom" topic=tutorial is_online=True %}
+    {% include "misc/pagination.part.html" with position="bottom" topic=tutorial is_online=True anchor="comments" %}
 
 
     
diff --git a/templates/tutorial/validation/history.html b/templates/tutorial/validation/history.html
index a5ddb5e686..2c88442295 100644
--- a/templates/tutorial/validation/history.html
+++ b/templates/tutorial/validation/history.html
@@ -1,5 +1,6 @@
 {% extends "tutorial/validation/index.html" %}
 {% load date %}
+{% load captureas %}
 
 
 
@@ -46,7 +47,10 @@
                             {{ validation.date_proposition|format_date|capfirst }}
                         </td>
                         <td>
-                            {% include "tutorial/includes/validation.part.html" %}
+                            {% captureas reservation_url %}
+                                {% url "zds.tutorial.views.reservation" validation.pk %}
+                            {% endcaptureas %}
+                            {% include "misc/validation.part.html" %}
                         </td>
                     </tr>
                 {% endfor %}
diff --git a/templates/tutorial/validation/index.html b/templates/tutorial/validation/index.html
index 631556b39a..995322b288 100644
--- a/templates/tutorial/validation/index.html
+++ b/templates/tutorial/validation/index.html
@@ -6,6 +6,11 @@
 
 {% block title %}
     Validation
+    {% if request.GET.type == "reserved" %}
+        / Reservés
+    {% elif request.GET.type == "orphan" %}
+        / Non-reservés
+    {% endif %}
 {% endblock %}
 
 
@@ -18,22 +23,27 @@
 
 {% block content_out %}
     <section class="full-content-wrapper">
-        <h2>
+        <h1>
             {% block headline %}
                 Validation des tutoriels
+                {% if request.GET.type == "reserved" %}
+                    / Reservés
+                {% elif request.GET.type == "orphan" %}
+                    / Non-reservés
+                {% endif %}
             {% endblock %}
-        </h2>
+        </h1>
 
         {% captureas headlinesub %}
             {% block headline_sub %}{% endblock %}
         {% endcaptureas %}
         {% if headlinesub %}
-            <h3 class="subtitle">{{ headlinesub|safe }}</h3>
+            <h2 class="subtitle">{{ headlinesub|safe }}</h2>
         {% endif %}
 
         {% block content %}
             {% if validations %}
-                <table>
+                <table class="fullwidth">
                     <thead>
                         <tr>
                             <th>Titre</th>
@@ -89,22 +99,26 @@ <h3 class="subtitle">{{ headlinesub|safe }}</h3>
 
 {% block sidebar_new %}{% endblock %}
 {% block sidebar_blocks %}
-    <h3>Filtres</h3>
-    <ul>
-        <li>
-            <a href="{% url "zds.tutorial.views.list_validation" %}?type=reserved" class="ico-after tick green">
-                En cours de validation
-            </a>
-        </li>
-        <li>
-            <a href="{% url "zds.tutorial.views.list_validation" %}?type=orphan" class="ico-after tick">
-                En attente de validateur
-            </a>
-        </li>
-        <li>
-            <a href="{% url "zds.tutorial.views.list_validation" %}" class="ico-after cross blue">
-                Annuler le filtre
-            </a>
-        </li>
-    </ul>
+    <div class="mobile-menu-bloc mobile-all-links mobile-show-ico" data-title="Filtres">
+        <h3>Filtres</h3>
+        <ul>
+            <li>
+                <a href="{% url "zds.tutorial.views.list_validation" %}?type=reserved" class="ico-after tick green {% if request.GET.type == "reserved" %}unread{% endif %}">
+                    En cours de validation
+                </a>
+            </li>
+            <li>
+                <a href="{% url "zds.tutorial.views.list_validation" %}?type=orphan" class="ico-after tick {% if request.GET.type == "orphan" %}unread{% endif %}">
+                    En attente de validateur
+                </a>
+            </li>
+            {% if request.GET.type %}
+                <li>
+                    <a href="{% url "zds.tutorial.views.list_validation" %}" class="ico-after cross blue">
+                        Annuler le filtre
+                    </a>
+                </li>
+            {% endif %}
+        </ul>
+    </div>
 {% endblock %}
\ No newline at end of file
diff --git a/zds/article/factories.py b/zds/article/factories.py
index 033ae18988..bc05157a9b 100644
--- a/zds/article/factories.py
+++ b/zds/article/factories.py
@@ -14,7 +14,7 @@
 import json as json_writer
 import os
 from zds.article.models import Article, Reaction, \
-    Validation
+    Validation, Licence
 from zds.utils.articles import export_article
 
 
@@ -70,3 +70,15 @@ def _prepare(cls, create, **kwargs):
 
 class VaidationFactory(factory.DjangoModelFactory):
     FACTORY_FOR = Validation
+
+class LicenceFactory(factory.DjangoModelFactory):
+    FACTORY_FOR = Licence
+    
+    code = u'GNU_GPL'
+    title = u'GNU General Public License'
+
+    @classmethod
+    def _prepare(cls, create, **kwargs):
+        licence = super(LicenceFactory, cls)._prepare(create, **kwargs)
+        return licence
+    
diff --git a/zds/article/feeds.py b/zds/article/feeds.py
index caf39f15be..da64ad749b 100644
--- a/zds/article/feeds.py
+++ b/zds/article/feeds.py
@@ -14,20 +14,25 @@ class LastArticlesFeedRSS(Feed):
 
     def items(self):
         return Article.objects\
-            .filter(is_visible=True)\
+            .filter(sha_public__isnull=False)\
             .order_by('-pubdate')[:5]
 
     def item_title(self, item):
         return item.title
 
+    def item_pubdate(self, item):
+        return item.pubdate
+
     def item_description(self, item):
         return item.description
 
     def item_author_name(self, item):
-        return item.author.username
-
-    def item_author_link(self, item):
-        return item.author.get_absolute_url()
+        authors_list = item.authors.all()
+        authors = []
+        for authors_obj in authors_list:
+            authors.append(authors_obj.username)
+        authors = ", ".join(authors)
+        return authors
 
     def item_link(self, item):
         return item.get_absolute_url()
diff --git a/zds/article/forms.py b/zds/article/forms.py
index 64999bb7b2..eb55728cbf 100644
--- a/zds/article/forms.py
+++ b/zds/article/forms.py
@@ -9,7 +9,7 @@
 
 from zds.article.models import Article
 from zds.utils.forms import CommonLayoutEditor
-from zds.utils.models import SubCategory
+from zds.utils.models import SubCategory, Licence
 
 
 class ArticleForm(forms.Form):
@@ -52,6 +52,12 @@ class ArticleForm(forms.Form):
         queryset=SubCategory.objects.all(),
         required=False
     )
+    
+    licence = forms.ModelChoiceField(
+        label="Licence de votre publication",
+        queryset=Licence.objects.all(),
+        required=False,
+    )
 
     def __init__(self, *args, **kwargs):
         super(ArticleForm, self).__init__(*args, **kwargs)
@@ -64,6 +70,7 @@ def __init__(self, *args, **kwargs):
             Field('description', autocomplete='off'),
             Field('image'),
             Field('subcategory'),
+            Field('licence'),
             CommonLayoutEditor(),
         )
 
diff --git a/zds/article/migrations/0003_auto__del_field_article_thumbnail__add_field_article_licence.py b/zds/article/migrations/0003_auto__del_field_article_thumbnail__add_field_article_licence.py
new file mode 100644
index 0000000000..277510012a
--- /dev/null
+++ b/zds/article/migrations/0003_auto__del_field_article_thumbnail__add_field_article_licence.py
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+from south.utils import datetime_utils as datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Deleting field 'Article.thumbnail'
+        db.delete_column(u'article_article', 'thumbnail')
+
+        # Adding field 'Article.licence'
+        db.add_column(u'article_article', 'licence',
+                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['utils.Licence'], null=True, blank=True),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Adding field 'Article.thumbnail'
+        db.add_column(u'article_article', 'thumbnail',
+                      self.gf('django.db.models.fields.files.ImageField')(max_length=100, null=True, blank=True),
+                      keep_default=False)
+
+        # Deleting field 'Article.licence'
+        db.delete_column(u'article_article', 'licence_id')
+
+
+    models = {
+        u'article.article': {
+            'Meta': {'object_name': 'Article'},
+            'authors': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.User']", 'db_index': 'True', 'symmetrical': 'False'}),
+            'create_at': ('django.db.models.fields.DateTimeField', [], {}),
+            'description': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'is_locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_visible': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+            'last_reaction': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_reaction'", 'null': 'True', 'to': u"orm['article.Reaction']"}),
+            'licence': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['utils.Licence']", 'null': 'True', 'blank': 'True'}),
+            'pubdate': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+            'sha_draft': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
+            'sha_public': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
+            'sha_validation': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '80', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '80'}),
+            'subcategory': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['utils.SubCategory']", 'null': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'text': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
+            'update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+        },
+        u'article.articleread': {
+            'Meta': {'object_name': 'ArticleRead'},
+            'article': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['article.Article']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'reaction': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['article.Reaction']"}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reactions_read'", 'to': u"orm['auth.User']"})
+        },
+        u'article.reaction': {
+            'Meta': {'object_name': 'Reaction', '_ormbases': [u'utils.Comment']},
+            'article': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['article.Article']"}),
+            u'comment_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['utils.Comment']", 'unique': 'True', 'primary_key': 'True'})
+        },
+        u'article.validation': {
+            'Meta': {'object_name': 'Validation'},
+            'article': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['article.Article']", 'null': 'True', 'blank': 'True'}),
+            'comment_authors': ('django.db.models.fields.TextField', [], {}),
+            'comment_validator': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+            'date_proposition': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
+            'date_reserve': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'date_validation': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'status': ('django.db.models.fields.CharField', [], {'default': "'PENDING'", 'max_length': '10'}),
+            'validator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'articles_author_validations'", 'null': 'True', 'to': u"orm['auth.User']"}),
+            'version': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '80', 'null': 'True', 'blank': 'True'})
+        },
+        u'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'auth.permission': {
+            'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        u'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        u'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        u'utils.comment': {
+            'Meta': {'object_name': 'Comment'},
+            'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'comments'", 'to': u"orm['auth.User']"}),
+            'dislike': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'editor': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments-editor'", 'null': 'True', 'to': u"orm['auth.User']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ip_address': ('django.db.models.fields.CharField', [], {'max_length': '39'}),
+            'is_visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'like': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+            'position': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
+            'pubdate': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
+            'text': ('django.db.models.fields.TextField', [], {}),
+            'text_hidden': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80'}),
+            'text_html': ('django.db.models.fields.TextField', [], {}),
+            'update': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+        },
+        u'utils.licence': {
+            'Meta': {'object_name': 'Licence'},
+            'code': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'description': ('django.db.models.fields.TextField', [], {}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '80'})
+        },
+        u'utils.subcategory': {
+            'Meta': {'object_name': 'SubCategory'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'slug': ('django.db.models.fields.SlugField', [], {'max_length': '80'}),
+            'subtitle': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '80'})
+        }
+    }
+
+    complete_apps = ['article']
\ No newline at end of file
diff --git a/zds/article/models.py b/zds/article/models.py
index 481492fe1a..319afe9f34 100644
--- a/zds/article/models.py
+++ b/zds/article/models.py
@@ -26,7 +26,7 @@
 from zds.utils import get_current_user
 from zds.utils import slugify
 from zds.utils.articles import export_article
-from zds.utils.models import SubCategory, Comment
+from zds.utils.models import SubCategory, Comment, Licence
 from django.core.urlresolvers import reverse
 
 
@@ -88,6 +88,10 @@ class Meta:
                                       verbose_name='Derniere réaction')
     is_locked = models.BooleanField('Est verrouillé', default=False)
 
+    licence = models.ForeignKey(Licence,
+                                verbose_name='Licence',
+                                blank=True, null=True, db_index=True)
+
     def __unicode__(self):
         return self.title
 
diff --git a/zds/article/tests.py b/zds/article/tests.py
index a826801bb7..40abce441e 100644
--- a/zds/article/tests.py
+++ b/zds/article/tests.py
@@ -8,8 +8,9 @@
 from django.test import TestCase
 from django.test.utils import override_settings
 
-from zds.article.factories import ArticleFactory, ReactionFactory
-from zds.article.models import Validation, Reaction, Article
+from zds.article.factories import ArticleFactory, ReactionFactory,   \
+    LicenceFactory
+from zds.article.models import Validation, Reaction, Article, Licence
 from zds.member.factories import ProfileFactory, StaffProfileFactory
 from zds.mp.models import PrivateTopic
 from zds.settings import SITE_ROOT
@@ -33,9 +34,12 @@ def setUp(self):
         self.user_author = ProfileFactory().user
         self.user = ProfileFactory().user
         self.staff = StaffProfileFactory().user
+        
+        self.licence = LicenceFactory()
 
         self.article = ArticleFactory()
         self.article.authors.add(self.user_author)
+        self.article.licence = self.licence
         self.article.save()
 
         # connect with user
@@ -371,6 +375,134 @@ def test_url_for_staff(self):
             follow=True)
         self.assertEqual(result.status_code, 200)
 
+    def test_workflow_licence(self):
+        '''Ensure the behavior of licence on articles'''
+
+        # create a new licence
+        new_licence = LicenceFactory(code='CC_BY', title='Creative Commons BY')
+        new_licence = Licence.objects.get(pk=new_licence.pk)
+
+        # check value first
+        article = Article.objects.get(pk=self.article.pk)
+        self.assertEqual(article.licence.pk, self.licence.pk)
+
+        # logout before
+        self.client.logout()
+        # login with author
+        self.assertTrue(
+            self.client.login(
+                username=self.user_author.username,
+                password='hostel77')
+        )
+
+        # change licence (get 302) :
+        result = self.client.post(
+            reverse('zds.article.views.edit') + 
+                '?article={}'.format(self.article.pk),
+            {
+                'title': self.article.title,
+                'description': self.article.description,
+                'text': self.article.get_text(),
+                'subcategory': self.article.subcategory.all(),
+                'licence' : new_licence.pk
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+
+        # test change :
+        article = Article.objects.get(pk=self.article.pk)
+        self.assertNotEqual(article.licence.pk, self.licence.pk)
+        self.assertEqual(article.licence.pk, new_licence.pk)
+
+        # test change in JSON :
+        json = article.load_json()
+        self.assertEquals(json['licence'], new_licence.code)
+
+        # then logout ...
+        self.client.logout()
+        # ... and login with staff
+        self.assertTrue(
+            self.client.login(
+                username=self.staff.username,
+                password='hostel77')
+        )
+
+        # change licence back to old one (get 302, staff can change licence) :
+        result = self.client.post(
+            reverse('zds.article.views.edit') + 
+                '?article={}'.format(self.article.pk),
+            {
+                'title': self.article.title,
+                'description': self.article.description,
+                'text': self.article.get_text(),
+                'subcategory': self.article.subcategory.all(),
+                'licence' : self.licence.pk
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+
+        # test change :
+        article = Article.objects.get(pk=self.article.pk)
+        self.assertEqual(article.licence.pk, self.licence.pk)
+        self.assertNotEqual(article.licence.pk, new_licence.pk)
+
+        # test change in JSON :
+        json = article.load_json()
+        self.assertEquals(json['licence'], self.licence.code)
+
+        # then logout ...
+        self.client.logout()
+
+        # change licence (get 302, redirection to login page) :
+        result = self.client.post(
+            reverse('zds.article.views.edit') + 
+                '?article={}'.format(self.article.pk),
+            {
+                'title': self.article.title,
+                'description': self.article.description,
+                'text': self.article.get_text(),
+                'subcategory': self.article.subcategory.all(),
+                'licence' : new_licence.pk
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+
+        # test change (normaly, nothing has) :
+        article = Article.objects.get(pk=self.article.pk)
+        self.assertEqual(article.licence.pk, self.licence.pk)
+        self.assertNotEqual(article.licence.pk, new_licence.pk)
+        
+        # login with random user
+        self.assertTrue(
+            self.client.login(
+                username=self.user.username,
+                password='hostel77')
+        )
+
+        # change licence (get 403, random user cannot edit article if not in
+        # authors list) :
+        result = self.client.post(
+            reverse('zds.article.views.edit') + 
+                '?article={}'.format(self.article.pk),
+            {
+                'title': self.article.title,
+                'description': self.article.description,
+                'text': self.article.get_text(),
+                'subcategory': self.article.subcategory.all(),
+                'licence' : new_licence.pk
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 403)
+
+        # test change (normaly, nothing has) :
+        article = Article.objects.get(pk=self.article.pk)
+        self.assertEqual(article.licence.pk, self.licence.pk)
+        self.assertNotEqual(article.licence.pk, new_licence.pk)
+
+        # test change in JSON (normaly, nothing has) :
+        json = article.load_json()
+        self.assertEquals(json['licence'], self.licence.code)
+
     def tearDown(self):
         if os.path.isdir(settings.REPO_ARTICLE_PATH):
             shutil.rmtree(settings.REPO_ARTICLE_PATH)
diff --git a/zds/article/urls.py b/zds/article/urls.py
index 12f4f9d2af..f1b2532f12 100644
--- a/zds/article/urls.py
+++ b/zds/article/urls.py
@@ -29,7 +29,7 @@
                        url(r'^nouveau/$', 'zds.article.views.new'),
                        url(r'^editer/$', 'zds.article.views.edit'),
                        url(r'^modifier/$', 'zds.article.views.modify'),
-                       url(r'^recherche/(?P<name>.+)/$',
+                       url(r'^recherche/(?P<name>\d+)/$',
                            'zds.article.views.find_article'),
 
 
diff --git a/zds/article/views.py b/zds/article/views.py
index 7d82f6d7cf..b08d78a184 100644
--- a/zds/article/views.py
+++ b/zds/article/views.py
@@ -36,7 +36,7 @@
 from zds.utils.articles import *
 from zds.utils.mps import send_mp
 from zds.utils.models import SubCategory, Category, CommentLike, \
-    CommentDislike, Alert
+    CommentDislike, Alert, Licence
 from zds.utils.paginator import paginator_range
 from zds.utils.templatetags.emarkdown import emarkdown
 
@@ -69,6 +69,7 @@ def index(request):
 
     return render_template('article/index.html', {
         'articles': article,
+        'tag': tag,
     })
 
 
@@ -110,6 +111,7 @@ def view(request, article_pk, article_slug):
     article_version['pk'] = article.pk
     article_version['slug'] = article.slug
     article_version['image'] = article.image
+    article_version['pubdate'] = article.pubdate
     article_version['sha_draft'] = article.sha_draft
     article_version['sha_validation'] = article.sha_validation
     article_version['sha_public'] = article.sha_public
@@ -150,7 +152,9 @@ def view_online(request, article_pk, article_slug):
     article_version['pk'] = article.pk
     article_version['slug'] = article.slug
     article_version['image'] = article.image
+    article_version['pubdate'] = article.pubdate
     article_version['is_locked'] = article.is_locked
+    article_version['get_reaction_count'] = article.get_reaction_count
     article_version['get_absolute_url'] = article.get_absolute_url()
     article_version['get_absolute_url_online'] = article.get_absolute_url_online()
 
@@ -232,9 +236,10 @@ def new(request):
                 'description': request.POST['description'],
                 'text': request.POST['text'],
                 'image': image,
-                'subcategory': request.POST.getlist('subcategory')
+                'subcategory': request.POST.getlist('subcategory'), 
+                'licence': request.POST['licence']
             })
-            return render_template('article/new.html', {
+            return render_template('article/member/new.html', {
                 'text': request.POST['text'],
                 'form': form
             })
@@ -266,6 +271,11 @@ def new(request):
             for subcat in form.cleaned_data['subcategory']:
                 article.subcategory.add(subcat)
 
+            # add a licence to the article
+            if "licence" in data and data["licence"] != "":
+                lc = Licence.objects.filter(pk=data["licence"]).all()[0]
+                article.licence = lc
+
             article.save()
 
             maj_repo_article(request,
@@ -314,6 +324,14 @@ def edit(request):
             for subcat in form.cleaned_data['subcategory']:
                 article.subcategory.add(subcat)
 
+            if "licence" in data:
+                if data["licence"] != "":
+                    lc = Licence.objects.filter(pk=data["licence"]).all()[0]
+                    article.licence = lc
+                else:
+                    article.licence = None
+            
+
             article.save()
 
             new_slug = os.path.join(
@@ -329,11 +347,16 @@ def edit(request):
 
             return redirect(article.get_absolute_url())
     else:
+        if "licence" in json:
+            licence = Licence.objects.filter(code=json["licence"]).all()[0]
+        else:
+            licence = None
         form = ArticleForm(initial={
             'title': json['title'],
             'description': json['description'],
             'text': article.get_text(),
             'subcategory': article.subcategory.all(),
+            'licence' : licence
         })
 
     return render_template('article/member/edit.html', {
@@ -366,8 +389,9 @@ def maj_repo_article(
         shutil.rmtree(old_slug_path)
     else:
         if action == 'maj':
-            shutil.move(old_slug_path, new_slug_path)
-            repo = Repo(new_slug_path)
+            if old_slug_path != new_slug_path:
+                shutil.move(old_slug_path, new_slug_path)
+                repo = Repo(new_slug_path)
             msg = 'Modification de l\'article'
         elif action == 'add':
             os.makedirs(new_slug_path, mode=0o777)
@@ -543,15 +567,16 @@ def modify(request):
 
                 # send feedback
                 for author in article.authors.all():
-                    msg = u'Félicitations **{0}** ! Ton zeste [{1}]({2}) '
-                    u'est maintenant publié ! Les lecteurs du monde entier '
-                    u'peuvent venir le lire et réagir a son sujet. Je te conseille '
-                    u'de rester a leur écoute afin d\'apporter des '
-                    u'corrections/compléments. Un Article vivant et a jour '
-                    u'est bien plus lu qu\'un sujet abandonné !'.format(
-                        author.username,
-                        article.title,
-                        article.get_absolute_url_online())
+                    msg = (
+                        u'Félicitations **{0}** ! Ton zeste [{1}]({2}) '
+                        u'est maintenant publié ! Les lecteurs du monde entier '
+                        u'peuvent venir le lire et réagir à son sujet. Je te conseille '
+                        u'de rester à leur écoute afin d\'apporter des '
+                        u'corrections/compléments. Un article vivant et à jour '
+                        u'est bien plus lu qu\'un sujet abandonné !'
+                        .format(author.username,
+                                article.title,
+                                settings.SITE_URL + article.get_absolute_url_online()))
                     bot = get_object_or_404(User, username=settings.BOT_ACCOUNT)
                     send_mp(
                         bot,
@@ -745,6 +770,8 @@ def history_validation(request, article_pk):
     return render_template('article/validation/history.html', {
         'validations': validations,
         'article': article,
+        'authors': article.authors,
+        'tags': article.subcategory,
     })
 
 
@@ -777,7 +804,7 @@ def history(request, article_pk, article_slug):
     """Display an article."""
     article = get_object_or_404(Article, pk=article_pk)
 
-    if not article.on_line \
+    if not article.on_line() \
        and not request.user.has_perm('article.change_article') \
        and request.user not in article.authors.all():
         raise Http404
@@ -907,9 +934,10 @@ def answer(request):
             for line in reaction_cite.text.splitlines():
                 text = text + '> ' + line + '\n'
 
-            text = u'{0}Source:[{1}]({2})'.format(
+            text = u'{0}Source:[{1}]({2}{3})'.format(
                 text,
                 reaction_cite.author.username,
+                settings.SITE_URL,
                 reaction_cite.get_absolute_url())
 
         form = ReactionForm(article, request.user, initial={
@@ -935,7 +963,7 @@ def solve_alert(request):
     alert = get_object_or_404(Alert, pk=request.POST['alert_pk'])
     reaction = Reaction.objects.get(pk=alert.comment.id)
     bot = get_object_or_404(User, username=settings.BOT_ACCOUNT)
-    msg = u'Bonjour {0},\n\nVous recevez ce message car vous avez '
+    msg = (u'Bonjour {0},\n\nVous recevez ce message car vous avez '
     u'signalé le message de *{1}*, dans l\'article [{2}]({3}). '
     u'Votre alerte a été traitée par **{4}** et il vous a laissé '
     u'le message suivant :\n\n`{5}`\n\n\nToute l\'équipe de '
@@ -946,7 +974,7 @@ def solve_alert(request):
         settings.SITE_URL +
         reaction.get_absolute_url(),
         request.user.username,
-        request.POST['text'])
+        request.POST['text']))
     send_mp(
         bot, [
             alert.author], u"Résolution d'alerte : {0}".format(
diff --git a/zds/forum/feeds.py b/zds/forum/feeds.py
index f415a0274e..e3fda2ddeb 100644
--- a/zds/forum/feeds.py
+++ b/zds/forum/feeds.py
@@ -12,8 +12,8 @@
 class LastPostsFeedRSS(Feed):
     title = u'Derniers messages sur Zeste de Savoir'
     link = '/forums/'
-    description = u'Les derniers messages '
-    u'parus sur le forum de Zeste de Savoir.'
+    description = (u'Les derniers messages '
+        u'parus sur le forum de Zeste de Savoir.')
 
     def items(self):
         posts = Post.objects.filter(topic__forum__group__isnull=True)\
@@ -23,6 +23,9 @@ def items(self):
     def item_title(self, item):
         return u'{}, message #{}'.format(item.topic.title, item.pk)
 
+    def item_pubdate(self, item):
+        return item.pubdate
+
     def item_description(self, item):
         # TODO: Use cached Markdown when implemented
         return emarkdown(item.text)
@@ -51,6 +54,8 @@ def items(self):
         topics = Topic.objects.filter(forum__group__isnull=True)\
             .order_by('-pubdate')
         return topics[:5]
+    def item_pubdate(self, item):
+        return item.pubdate
 
     def item_title(self, item):
         return u'{} dans {}'.format(item.title, item.forum.title)
diff --git a/zds/forum/forms.py b/zds/forum/forms.py
index c5f5958916..a0274dfc78 100644
--- a/zds/forum/forms.py
+++ b/zds/forum/forms.py
@@ -19,6 +19,7 @@ class TopicForm(forms.Form):
         max_length=Topic._meta.get_field('title').max_length,
         widget=forms.TextInput(
             attrs={
+                'placeholder': '[Tag 1][Tag 2] Titre de mon sujet',
                 'required': 'required',
             }
         )
@@ -35,7 +36,7 @@ class TopicForm(forms.Form):
         widget=forms.Textarea(
             attrs={
                 'placeholder': 'Votre message au format Markdown.',
-                'required': 'required'
+                'required': 'required',
             }
         )
     )
@@ -102,7 +103,7 @@ class PostForm(forms.Form):
         widget=forms.Textarea(
             attrs={
                 'placeholder': 'Votre message au format Markdown.',
-                'required': 'required'
+                'required': 'required',
             }
         )
     )
@@ -125,11 +126,12 @@ def __init__(self, topic, user, *args, **kwargs):
                     u'afin de limiter le flood.',
                     disabled=True)
         elif topic.is_locked:
-            self.helper['text'].wrap(
-                Field,
-                placeholder=u'Ce topic est verrouillé.',
-                disabled=True
-            )
+            if 'text' not in self.initial:
+                self.helper['text'].wrap(
+                    Field,
+                    placeholder=u'Ce topic est verrouillé.',
+                    disabled=True
+                )
 
     def clean(self):
         cleaned_data = super(PostForm, self).clean()
diff --git a/zds/forum/models.py b/zds/forum/models.py
index 5e695162cb..654289cdf3 100644
--- a/zds/forum/models.py
+++ b/zds/forum/models.py
@@ -243,11 +243,8 @@ def is_followed(self, user=None):
         if user is None:
             user = get_current_user()
 
-        try:
-            TopicFollowed.objects.get(topic=self, user=user)
-        except TopicFollowed.DoesNotExist:
-            return False
-        return True
+        return TopicFollowed.objects.filter(topic=self, user=user).exists()
+
 
     def is_email_followed(self, user=None):
         """Check if the topic is currently email followed by the user.
diff --git a/zds/forum/urls.py b/zds/forum/urls.py
index c55967a2b8..909f1467f8 100644
--- a/zds/forum/urls.py
+++ b/zds/forum/urls.py
@@ -46,7 +46,7 @@
                            'zds.forum.views.move_topic'),
                        url(r'^sujet/(?P<topic_pk>\d+)/(?P<topic_slug>.+)/$',
                            'zds.forum.views.topic'),
-                       url(r'^sujets/membre/(?P<user_pk>.+)/$',
+                       url(r'^sujets/membre/(?P<user_pk>\d+)/$',
                            'zds.forum.views.find_topic'),
                        url(r'^sujets/tag/(?P<tag_pk>\d+)/(?P<tag_slug>.+)/$',
                            'zds.forum.views.find_topic_by_tag'),
@@ -66,7 +66,7 @@
                            'zds.forum.views.like_post'),
                        url(r'^message/dislike/$',
                            'zds.forum.views.dislike_post'),
-                       url(r'^messages/(?P<user_pk>.+)/$',
+                       url(r'^messages/(?P<user_pk>\d+)/$',
                            'zds.forum.views.find_post'),
 
                        # Forum details
diff --git a/zds/forum/views.py b/zds/forum/views.py
index 148795486f..271e742772 100644
--- a/zds/forum/views.py
+++ b/zds/forum/views.py
@@ -109,14 +109,17 @@ def cat_details(request, cat_slug):
     
     category = get_object_or_404(Category, slug=cat_slug)
     
-    forums_pub = Forum.objects.filter(group__isnull=True).select_related("category").all()
+    forums_pub = Forum.objects\
+                    .filter(group__isnull=True, category__pk=category.pk)\
+                    .select_related("category").all()
     if request.user.is_authenticated():
-        forums_prv = Forum.objects.filter(group__isnull=False).select_related("category").all()
-        out = []
-        for forum in forums_prv:
-            if forum.can_read(request.user):
-                out.append(forum.pk)
-        forums = forums_pub|forums_prv.exclude(pk__in=out)
+        forums_prv = Forum.objects\
+                    .filter(group__isnull=False, \
+                            group__in=request.user.groups.all(), \
+                            category__pk=category.pk)\
+                    .select_related("category")\
+                    .all()
+        forums = forums_pub|forums_prv
     else :
         forums = forums_pub
 
@@ -876,6 +879,7 @@ def find_topic_by_tag(request, tag_pk, tag_slug):
     tag = Tag.objects.filter(pk=tag_pk, slug=tag_slug).first()
     if tag is None:
         return redirect(reverse("zds.forum.views.index"))
+    u = request.user
     if "filter" in request.GET:
         filter = request.GET["filter"]
         if request.GET["filter"] == "solve":
@@ -930,16 +934,15 @@ def find_topic_by_tag(request, tag_pk, tag_slug):
 def find_topic(request, user_pk):
     """Finds all topics of a user."""
 
-    u = get_object_or_404(User, pk=user_pk)
+    displayed_user = get_object_or_404(User, pk=user_pk)
     topics = \
         Topic.objects\
-        .filter(author=u)\
-        .exclude(Q(forum__group__isnull=False) & ~Q(forum__group__in=u.groups.all()))\
+        .filter(author=displayed_user)\
+        .exclude(Q(forum__group__isnull=False) & ~Q(forum__group__in=request.user.groups.all()))\
         .prefetch_related("author")\
         .order_by("-pubdate").all()
 
     # Paginator
-
     paginator = Paginator(topics, settings.TOPICS_PER_PAGE)
     page = request.GET.get("page")
     try:
@@ -954,34 +957,32 @@ def find_topic(request, user_pk):
 
     return render_template("forum/find/topic.html", {
         "topics": shown_topics,
-        "usr": u,
+        "usr": displayed_user,
         "pages": paginator_range(page, paginator.num_pages),
         "nb": page,
     })
 
 
-
 def find_post(request, user_pk):
     """Finds all posts of a user."""
 
-    u = get_object_or_404(User, pk=user_pk)
+    displayed_user = get_object_or_404(User, pk=user_pk)
+    user = request.user
     
-    if request.user.has_perm("forum.change_post"):
+    if user.has_perm("forum.change_post"):
         posts = \
-            Post.objects.filter(author=u)\
-            .exclude(Q(topic__forum__group__isnull=False) & ~Q(topic__forum__group__in=u.groups.all()))\
+            Post.objects.filter(author=displayed_user)\
+            .exclude(Q(topic__forum__group__isnull=False) & ~Q(topic__forum__group__in=user.groups.all()))\
             .prefetch_related("author")\
             .order_by("-pubdate").all()
     else:
         posts = \
-            Post.objects.filter(author=u)\
+            Post.objects.filter(author=displayed_user)\
             .filter(is_visible=True)\
-            .exclude(Q(topic__forum__group__isnull=False) & ~Q(topic__forum__group__in=u.groups.all()))\
+            .exclude(Q(topic__forum__group__isnull=False) & ~Q(topic__forum__group__in=user.groups.all()))\
             .prefetch_related("author").order_by("-pubdate").all()
 
-
     # Paginator
-
     paginator = Paginator(posts, settings.POSTS_PER_PAGE)
     page = request.GET.get("page")
     try:
@@ -996,14 +997,13 @@ def find_post(request, user_pk):
 
     return render_template("forum/find/post.html", {
         "posts": shown_posts,
-        "usr": u,
+        "usr": displayed_user,
         "pages": paginator_range(page, paginator.num_pages),
         "nb": page,
     })
 
 
 @login_required
-
 def followed_topics(request):
     followed_topics = request.user.get_profile().get_followed_topics()
 
diff --git a/zds/gallery/forms.py b/zds/gallery/forms.py
index 644fd4e71b..7969ea1bb5 100644
--- a/zds/gallery/forms.py
+++ b/zds/gallery/forms.py
@@ -104,7 +104,6 @@ def clean(self):
 
         return cleaned_data
 
-
 class ImageForm(forms.Form):
     title = forms.CharField(
         label='Titre',
@@ -121,9 +120,7 @@ class ImageForm(forms.Form):
     physical = forms.ImageField(
         label=u'Sélectionnez votre image',
         required=True,
-        help_text='Taille maximum : '
-        + str(settings.IMAGE_MAX_SIZE)
-        + ' megabytes'
+        help_text='Taille maximum : ' + str(settings.IMAGE_MAX_SIZE / 1024) + ' <abbr title="kibioctet">Kio</abbr>'
     )
 
     def __init__(self, *args, **kwargs):
@@ -143,6 +140,37 @@ def __init__(self, *args, **kwargs):
             ),
         )
 
+    def clean(self):
+        cleaned_data = super(ImageForm, self).clean()
+
+        physical = cleaned_data.get('physical')
+
+        if physical is not None and physical.size > settings.IMAGE_MAX_SIZE:
+            self._errors['physical'] = self.error_class([u'Votre image est trop lourde, la limite autorisée est de : {0} Ko'
+                                                                                     .format(settings.IMAGE_MAX_SIZE / 1024) + ' Ko'])
+        return cleaned_data
+
+
+class UpdateImageForm(ImageForm):
+    def __init__(self, *args, **kwargs):
+        super(ImageForm, self).__init__(*args, **kwargs)
+
+        self.fields['physical'].required = False
+
+        self.helper = FormHelper()
+        self.helper.form_class = 'clearfix'
+        self.helper.form_method = 'post'
+
+        self.helper.layout = Layout(
+            Field('title'),
+            Field('legend'),
+            Field('physical'),
+            ButtonHolder(
+                StrictButton(u'Mettre à jour', type='submit'),
+                HTML('<a class="btn btn-cancel" '
+                u'href="{{ gallery.get_absolute_url }}">Annuler</a>'),
+            ),
+        )
 
 class ImageAsAvatarForm(forms.Form):
     """"Form to add current image as avatar"""
diff --git a/zds/gallery/tests/tests_forms.py b/zds/gallery/tests/tests_forms.py
index 538fb34d1b..3f8d5109e1 100644
--- a/zds/gallery/tests/tests_forms.py
+++ b/zds/gallery/tests/tests_forms.py
@@ -82,6 +82,96 @@ def test_valid_image_form(self):
         self.assertTrue(form.is_valid())
         upload_file.close()
 
+    def test_empty_title_image_form(self):
+        upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'logo.png'), 'r')
+
+        data = {
+            'title': '',
+            'legend': 'Test Legend',
+        }
+
+        files = {
+            'physical': SimpleUploadedFile(upload_file.name, upload_file.read())
+        }
+        form = ImageForm(data, files)
+
+        self.assertFalse(form.is_valid())
+        upload_file.close()
+
+    def test_empty_pic_image_form(self):
+
+        data = {
+            'title': 'Test Title',
+            'legend': 'Test Legend',
+        }
+
+        files = {
+            'physical': ''
+        }
+        form = ImageForm(data, files)
+
+        self.assertFalse(form.is_valid())
+
+    def test_too_big_pic_image_form(self):
+        upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'image_test.jpg'), 'r')
+
+        data = {
+            'title': 'Test Title',
+            'legend': 'Test Legend',
+        }
+
+        files = {
+            'physical': SimpleUploadedFile(upload_file.name, upload_file.read())
+        }
+        form = ImageForm(data, files)
+
+        self.assertFalse(form.is_valid())
+        upload_file.close()
+
+    def test_bot_a_pic_image_form(self):
+        upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'forums.yaml'), 'r')
+
+        data = {
+            'title': 'Test Title',
+            'legend': 'Test Legend',
+        }
+
+        files = {
+            'physical': SimpleUploadedFile(upload_file.name, upload_file.read())
+        }
+        form = ImageForm(data, files)
+
+        self.assertFalse(form.is_valid())
+        upload_file.close()
+
+    def test_too_long_title_image_form(self):
+        upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'logo.png'), 'r')
+
+        data = {
+            'title': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam condimentum enim amet.',
+            'legend': 'Test Legend',
+        }
+
+        files = {
+            'physical': SimpleUploadedFile(upload_file.name, upload_file.read())
+        }
+        form = ImageForm(data, files)
+        upload_file.close()
+
+    def test_too_long_legend_image_form(self):
+        upload_file = open(os.path.join(settings.SITE_ROOT, 'fixtures', 'logo.png'), 'r')
+
+        data = {
+            'title': 'Test Title',
+            'legend': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam condimentum enim amet.',
+        }
+
+        files = {
+            'physical': SimpleUploadedFile(upload_file.name, upload_file.read())
+        }
+        form = ImageForm(data, files)
+        upload_file.close()
+
 
 class ImageAsAvatarFormTest(TestCase):
 
diff --git a/zds/gallery/tests/tests_views.py b/zds/gallery/tests/tests_views.py
index 81ad2a706a..9f43e3559c 100644
--- a/zds/gallery/tests/tests_views.py
+++ b/zds/gallery/tests/tests_views.py
@@ -365,17 +365,17 @@ def test_success_member_edit_image(self):
         with open(os.path.join(settings.SITE_ROOT, 'fixtures', 'logo.png'), 'r') as fp:
 
             response = self.client.post(
-                    reverse(
-                        'zds.gallery.views.edit_image',
-                        args=[self.gallery.pk, self.image.pk]
-                    ),
-                    {
-                        'title': 'edit title',
-                        'legend': 'dit legend',
-                        'slug': 'edit-slug',
-                        'physical': fp
-                    },
-                    follow=True
+                reverse(
+                    'zds.gallery.views.edit_image',
+                    args=[self.gallery.pk, self.image.pk]
+                ),
+                {
+                    'title': 'edit title',
+                    'legend': 'dit legend',
+                    'slug': 'edit-slug',
+                    'physical': fp
+                },
+                follow=True
             )
         self.assertEqual(200, response.status_code)
         image_test = Image.objects.get(pk=self.image.pk)
@@ -415,17 +415,17 @@ def tearDown(self):
         self.image3.delete()
 
     def test_denies_anonymous(self):
-        response = self.client.get(reverse('zds.gallery.views.modify_image'), follow=True)
+        response = self.client.get(reverse('zds.gallery.views.delete_image'), follow=True)
         self.assertRedirects(response,
                 reverse('zds.member.views.login_view')
-                + '?next=' + urllib.quote(reverse('zds.gallery.views.modify_image'), ''))
+                + '?next=' + urllib.quote(reverse('zds.gallery.views.delete_image'), ''))
 
     def test_fail_modify_image_with_no_permission(self):
         login_check = self.client.login(username=self.profile3.user.username, password='hostel77')
         self.assertTrue(login_check)
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.gallery1.pk,
                 },
@@ -445,7 +445,7 @@ def test_delete_image_from_other_user(self):
         self.assertTrue(login_check)
 
         self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.gallery1.pk,
                     'delete': '',
@@ -462,7 +462,7 @@ def test_success_delete_image_write_permission(self):
         self.assertTrue(login_check)
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.gallery1.pk,
                     'delete': '',
@@ -479,7 +479,7 @@ def test_success_delete_list_images_write_permission(self):
         self.assertTrue(login_check)
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.gallery1.pk,
                     'delete_multi': '',
@@ -497,7 +497,7 @@ def test_fail_delete_image_read_permission(self):
         self.assertTrue(login_check)
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.gallery1.pk,
                     'delete': '',
diff --git a/zds/gallery/urls.py b/zds/gallery/urls.py
index 7210713a1e..c343547b57 100644
--- a/zds/gallery/urls.py
+++ b/zds/gallery/urls.py
@@ -18,7 +18,7 @@
                        url(r'^image/ajouter/(?P<gal_pk>\d+)/$',
                            'zds.gallery.views.new_image'),
                        url(r'^image/modifier/$',
-                           'zds.gallery.views.modify_image'),
+                           'zds.gallery.views.delete_image'),
                        url(r'^image/editer/(?P<gal_pk>\d+)/(?P<img_pk>\d+)/$',
                            'zds.gallery.views.edit_image'),
                        )
diff --git a/zds/gallery/views.py b/zds/gallery/views.py
index 03c716948c..841ac9a037 100644
--- a/zds/gallery/views.py
+++ b/zds/gallery/views.py
@@ -11,7 +11,7 @@
 from django.core.exceptions import PermissionDenied
 from django.core.urlresolvers import reverse
 from django.shortcuts import redirect, get_object_or_404
-from zds.gallery.forms import ImageForm, GalleryForm, UserGalleryForm, ImageAsAvatarForm
+from zds.gallery.forms import ImageForm, UpdateImageForm, GalleryForm, UserGalleryForm, ImageAsAvatarForm
 from zds.gallery.models import UserGallery, Image, Gallery
 from zds.tutorial.models import Tutorial
 from zds.member.decorator import can_write_and_read_now
@@ -169,13 +169,14 @@ def modify_gallery(request):
 
 
 @login_required
+@can_write_and_read_now
 def edit_image(request, gal_pk, img_pk):
-    """Creates a new image."""
+    """Edit an existing image."""
 
     gal = get_object_or_404(Gallery, pk=gal_pk)
     img = get_object_or_404(Image, pk=img_pk)
 
-    # check if user can edit image
+    # Check if user can edit image
     try:
         permission = UserGallery.objects.get(user=request.user, gallery=gal)
         if permission.mode != 'W':
@@ -183,17 +184,17 @@ def edit_image(request, gal_pk, img_pk):
     except:
         raise PermissionDenied
 
-    # check if the image belong to the gallery
+    # Check if the image belong to the gallery
     if img.gallery != gal:
         raise PermissionDenied
-    
-    
+
     if request.method == "POST":
-        form = ImageForm(request.POST, request.FILES)
+        form = UpdateImageForm(request.POST, request.FILES)
         if form.is_valid():
             if "physical" in request.FILES:
                 if request.FILES["physical"].size > settings.IMAGE_MAX_SIZE:
-                    messages.error(request, "Votre image est beaucoup trop lourde, réduidez sa taille à moins de {} avant de l'envoyer".format(str(settings.IMAGE_MAX_SIZE/1024*1024)))
+                    messages.error(request, "Votre image est beaucoup trop lourde, réduisez sa taille à moins de {} \
+                    <abbr title=\"kibioctet\">Kio</abbr> avant de l'envoyer".format(str(settings.IMAGE_MAX_SIZE/1024)))
                 else:
                     img.title = request.POST["title"]
                     img.legend = request.POST["legend"]
@@ -201,19 +202,24 @@ def edit_image(request, gal_pk, img_pk):
                     img.slug = slugify(request.FILES["physical"])
                     img.update = datetime.now()
                     img.save()
-                    # Redirect to the document list after POST
-                    return redirect(gal.get_absolute_url())
+                    # Redirect to the newly uploaded image edit page after POST
+                    return redirect(reverse("zds.gallery.views.edit_image", args=[gal.pk, img.pk]))
             else:
                 img.title = request.POST["title"]
                 img.legend = request.POST["legend"]
                 img.update = datetime.now()
                 img.save()
+                # Redirect to the newly uploaded image edit page after POST
+                return redirect(reverse("zds.gallery.views.edit_image", args=[gal.pk, img.pk]))
 
-                # Redirect to the document list after POST
-                return redirect(gal.get_absolute_url())
     else:
-        form = ImageForm(initial={"title": img.title, "legend": img.legend, "physical": img.physical})
-    
+        form = UpdateImageForm(initial={
+            "title": img.title,
+            "legend": img.legend,
+            "physical": img.physical,
+            "new_image": False,
+        })
+
     as_avatar_form = ImageAsAvatarForm()
     return render_template(
         "gallery/image/edit.html", {
@@ -226,12 +232,9 @@ def edit_image(request, gal_pk, img_pk):
 
 @can_write_and_read_now
 @login_required
-def modify_image(request):
-
-    # We only handle secured POST actions
+@require_POST
+def delete_image(request):
 
-    if request.method != "POST":
-        raise Http404
     try:
         gal_pk = request.POST["gallery"]
     except KeyError:
@@ -241,7 +244,6 @@ def modify_image(request):
         gal_mode = UserGallery.objects.get(gallery=gal, user=request.user)
 
         # Only allow RW users to modify images
-
         if gal_mode.mode != "W":
             raise PermissionDenied
     except:
@@ -275,8 +277,7 @@ def new_image(request, gal_pk):
 
     if request.method == "POST":
         form = ImageForm(request.POST, request.FILES)
-        if form.is_valid() and request.FILES["physical"].size \
-                < settings.IMAGE_MAX_SIZE:
+        if form.is_valid():
             img = Image()
             img.physical = request.FILES["physical"]
             img.gallery = gal
@@ -287,13 +288,12 @@ def new_image(request, gal_pk):
             img.save()
 
             # Redirect to the newly uploaded image edit page after POST
-
             return redirect(reverse("zds.gallery.views.edit_image",
                                     args=[gal.pk, img.pk]))
         else:
             return render_template("gallery/image/new.html", {"form": form,
                                                               "gallery": gal})
     else:
-        form = ImageForm()  # A empty, unbound form
+        form = ImageForm(initial={"new_image": True})  # A empty, unbound form
         return render_template("gallery/image/new.html", {"form": form,
                                                           "gallery": gal})
diff --git a/zds/member/models.py b/zds/member/models.py
index 24af43256f..101db079a2 100644
--- a/zds/member/models.py
+++ b/zds/member/models.py
@@ -118,7 +118,7 @@ def get_avatar_url(self):
             return self.avatar_url
         else:
             return 'https://secure.gravatar.com/avatar/{0}?d=identicon'.format(
-                md5(self.user.email).hexdigest())
+                md5(self.user.email.lower()).hexdigest())
 
     def get_post_count(self):
         """Number of messages posted."""
diff --git a/zds/member/views.py b/zds/member/views.py
index 2e25d36f63..e6f664dbfb 100644
--- a/zds/member/views.py
+++ b/zds/member/views.py
@@ -15,8 +15,9 @@
 from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
 from django.core.urlresolvers import reverse
 from django.db import transaction
+from django.db.models import Q
 from django.http import Http404, HttpResponse
-from django.shortcuts import redirect, get_object_or_404, render_to_response
+from django.shortcuts import redirect, get_object_or_404
 from django.template import Context, RequestContext
 from django.template.loader import get_template
 from django.views.decorators.http import require_POST
@@ -122,16 +123,13 @@ def details(request, user_name):
         .filter(authors__in=[usr]) \
         .order_by("-pubdate"
                   ).all()
-    my_topics = Topic.objects.filter(author__pk=usr.pk).order_by("-pubdate"
-                                                                 ).all()
-    tops = []
-    for top in my_topics:
-        if not top.forum.can_read(request.user):
-            continue
-        else:
-            tops.append(top)
-            if len(tops) >= 5:
-                break
+    my_topics = \
+        Topic.objects\
+        .filter(author=usr)\
+        .exclude(Q(forum__group__isnull=False) & ~Q(forum__group__in=request.user.groups.all()))\
+        .prefetch_related("author")\
+        .order_by("-pubdate").all()
+
     form = OldTutoForm(profile)
     oldtutos = []
     if profile.sdz_tutorial:
@@ -146,7 +144,7 @@ def details(request, user_name):
         "bans": bans,
         "articles": my_articles[:5],
         "tutorials": my_tutorials[:5],
-        "topics": tops,
+        "topics": my_topics[:5],
         "form": form,
         "old_tutos": oldtutos,
     })
@@ -361,8 +359,7 @@ def settings_mini_profile(request, user_name):
             return redirect(reverse("zds.member.views.details",
                                     args=[profile.user.username]))
         else:
-            return render_to_response("member/settings/profile.html", c,
-                                      RequestContext(request))
+            return render_template("member/settings/profile.html", c)
     else:
         form = MiniProfileForm(initial={
             "biography": profile.biography,
@@ -371,8 +368,7 @@ def settings_mini_profile(request, user_name):
             "sign": profile.sign,
         })
         c = {"form": form, "profile": profile}
-        return render_to_response("member/settings/profile.html", c,
-                                  RequestContext(request))
+        return render_template("member/settings/profile.html", c)
 
 
 @can_write_and_read_now
@@ -411,8 +407,7 @@ def settings_profile(request):
                              "Le profil a correctement été mis à jour.")
             return redirect(reverse("zds.member.views.settings_profile"))
         else:
-            return render_to_response("member/settings/profile.html", c,
-                                      RequestContext(request))
+            return render_template("member/settings/profile.html", c)
     else:
         form = ProfileForm(initial={
             "biography": profile.biography,
@@ -425,8 +420,7 @@ def settings_profile(request):
             "sign": profile.sign,
         })
         c = {"form": form}
-        return render_to_response("member/settings/profile.html", c,
-                                  RequestContext(request))
+        return render_template("member/settings/profile.html", c)
 
 
 @can_write_and_read_now
@@ -471,13 +465,11 @@ def settings_account(request):
                 messages.error(request, "Une erreur est survenue.")
                 return redirect(reverse("zds.member.views.settings_account"))
         else:
-            return render_to_response("member/settings/account.html", c,
-                                      RequestContext(request))
+            return render_template("member/settings/account.html", c)
     else:
         form = ChangePasswordForm(request.user)
         c = {"form": form}
-        return render_to_response("member/settings/account.html", c,
-                                  RequestContext(request))
+        return render_template("member/settings/account.html", c)
 
 
 @can_write_and_read_now
@@ -499,13 +491,11 @@ def settings_user(request):
             old.save()
             return redirect(old.profile.get_absolute_url())
         else:
-            return render_to_response("member/settings/user.html", c,
-                                      RequestContext(request))
+            return render_template("member/settings/user.html", c)
     else:
         form = ChangeUserForm()
         c = {"form": form}
-        return render_to_response("member/settings/user.html", c,
-                                  RequestContext(request))
+        return render_template("member/settings/user.html", c)
 
 
 
diff --git a/zds/mp/views.py b/zds/mp/views.py
index 4c53d8dae0..88d83022f8 100644
--- a/zds/mp/views.py
+++ b/zds/mp/views.py
@@ -348,9 +348,10 @@ def answer(request):
             for line in post_cite.text.splitlines():
                 text = text + '> ' + line + '\n'
 
-            text = u'{0}Source:[{1}]({2})'.format(
+            text = u'{0}Source:[{1}]({2}{3})'.format(
                 text,
                 post_cite.author.username,
+                settings.SITE_URL,
                 post_cite.get_absolute_url())
 
         form = PrivatePostForm(g_topic, request.user, initial={
diff --git a/zds/pages/forms.py b/zds/pages/forms.py
index cd87ddfe91..b7df380f1d 100644
--- a/zds/pages/forms.py
+++ b/zds/pages/forms.py
@@ -9,13 +9,13 @@
 class AssocSubscribeForm(forms.Form):
     first_name = forms.CharField(
         label=u'Prénom',
-        max_length= 30,
+        max_length=30,
         required=True,
     )
 
     surname = forms.CharField(
         label='Nom de famille',
-        max_length= 30,
+        max_length=30,
         required=True,
     )
 
@@ -26,31 +26,31 @@ class AssocSubscribeForm(forms.Form):
 
     adresse = forms.CharField(
         label=u'Adresse',
-        max_length= 38,
+        max_length=38,
         required=True,
     )
 
     adresse_complement = forms.CharField(
         label=u'Complément d\'adresse',
-        max_length= 38,
+        max_length=38,
         required=False,
     )
 
     code_postal = forms.CharField(
         label='Code Postal',
-        max_length= 5,
+        max_length=10,
         required=True,
     )
 
     ville = forms.CharField(
         label='Ville',
-        max_length= 38,
+        max_length=38,
         required=True,
     )
 
     pays = forms.CharField(
         label='Pays',
-        max_length= 38,
+        max_length=38,
         required=True,
     )
 
diff --git a/zds/pages/tests.py b/zds/pages/tests.py
index a9f8267b4c..7a584cb141 100644
--- a/zds/pages/tests.py
+++ b/zds/pages/tests.py
@@ -246,3 +246,12 @@ def test_url_cookies(self):
         )
 
         self.assertEqual(result.status_code, 200)
+
+    def test_render_template(self):
+        """Test: render_template() works and git_version is in template."""
+
+        result = self.client.get(
+            reverse('zds.pages.views.home'),
+        )
+
+        self.assertTrue('git_version' in result.context[-1])
diff --git a/zds/search/views.py b/zds/search/views.py
index 4cfe0b2b2a..489bc8fd8f 100644
--- a/zds/search/views.py
+++ b/zds/search/views.py
@@ -1,9 +1,9 @@
 # coding: utf-8
 
-from django.shortcuts import render_to_response
 from haystack.views import SearchView
-from zds.utils.paginator import paginator_range
 from zds.search.constants import MODEL_NAMES
+from zds.utils.paginator import paginator_range
+from zds.utils import render_template
 
 class CustomSearchView(SearchView):
     def create_response(self):
@@ -26,4 +26,4 @@ def create_response(self):
             context['suggestion'] = self.form.get_suggestion()
 
         context.update(self.extra_context())
-        return render_to_response(self.template, context, context_instance=self.context_class(self.request))
\ No newline at end of file
+        return render_template(self.template, context)
diff --git a/zds/tutorial/forms.py b/zds/tutorial/forms.py
index 86f30a3788..b5a7ea2ff2 100644
--- a/zds/tutorial/forms.py
+++ b/zds/tutorial/forms.py
@@ -387,9 +387,8 @@ def __init__(self, *args, **kwargs):
             StrictButton(
                 'Confirmer',
                 type='submit'),
-            Hidden(
-                'tutorial', '{{ tutorial.pk }}'), Hidden(
-                'version', '{{ version }}'), )
+            Hidden('tutorial', '{{ tutorial.pk }}'), 
+            Hidden('version', '{{ version }}'), )
 
 
 class ValidForm(forms.Form):
diff --git a/zds/tutorial/models.py b/zds/tutorial/models.py
index b718f9e920..a429fd318d 100644
--- a/zds/tutorial/models.py
+++ b/zds/tutorial/models.py
@@ -162,7 +162,7 @@ def in_drafting(self):
         return (self.sha_draft is not None) and (self.sha_draft.strip() != '')
 
     def on_line(self):
-        return (self.sha_public is not None) and (self.sha_public.strip() != '')
+        return (self.sha_public is not None) and (self.sha_public.strip() != '') 
 
     def is_mini(self):
         return self.type == 'MINI'
@@ -196,6 +196,10 @@ def load_dic(self, mandata):
         mandata['image'] = self.image
         mandata['pubdate'] = self.pubdate
         mandata['source'] = self.source
+        mandata['have_markdown'] = self.have_markdown()
+        mandata['have_html'] = self.have_html()
+        mandata['have_pdf'] = self.have_pdf()
+        mandata['have_epub'] = self.have_epub()
 
         return mandata
 
@@ -358,6 +362,22 @@ def update_children(self):
         if chapter:
             chapter.update_children()
 
+    def have_markdown(self):
+        return os.path.isfile(os.path.join(self.get_prod_path(),
+                                           self.slug +
+                                           ".md"))
+    def have_html(self):
+        return os.path.isfile(os.path.join(self.get_prod_path(),
+                                           self.slug +
+                                           ".html"))
+    def have_pdf(self):
+        return os.path.isfile(os.path.join(self.get_prod_path(),
+                                           self.slug +
+                                           ".pdf"))
+    def have_epub(self):
+        return os.path.isfile(os.path.join(self.get_prod_path(),
+                                           self.slug +
+                                           ".epub"))
 
 def get_last_tutorials():
     tutorials = Tutorial.objects.all()\
@@ -775,8 +795,12 @@ def get_conclusion_online(self):
             return None
 
     def update_children(self):
-        self.introduction = os.path.join(self.get_phy_slug(), "introduction.md")
-        self.conclusion = os.path.join(self.get_phy_slug(), "conclusion.md")
+        if self.part:
+            self.introduction = os.path.join(self.part.get_phy_slug(), self.get_phy_slug(), "introduction.md")
+            self.conclusion = os.path.join(self.part.get_phy_slug(), self.get_phy_slug(), "conclusion.md")
+        else:
+            self.introduction = os.path.join("introduction.md")
+            self.conclusion = os.path.join("conclusion.md")
         self.save()
         for extract in self.get_extracts():
             extract.save()
diff --git a/zds/tutorial/tests.py b/zds/tutorial/tests.py
index 3fffb17498..1e3493dd41 100644
--- a/zds/tutorial/tests.py
+++ b/zds/tutorial/tests.py
@@ -113,6 +113,7 @@ def setUp(self):
                 'source': 'http://zestedesavoir.com',
             },
             follow=False)
+        self.bigtuto = Tutorial.objects.get(pk=self.bigtuto.pk)
         self.assertEqual(pub.status_code, 302)
         self.assertEquals(len(mail.outbox), 1)
 
@@ -501,31 +502,59 @@ def test_workflow_tuto(self):
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Tutorial.objects.all().count(), 2)
         tuto = Tutorial.objects.last()
-        #add part
+        #add part 1
         result = self.client.post(
             reverse('zds.tutorial.views.add_part') + '?tutoriel={}'.format(tuto.pk),
             {
                 'title': u"Partie 1",
-                'introduction':"Présentation",
-                'conclusion': "",
+                'introduction':u"Présentation",
+                'conclusion': u"Fin de la présenation",
             },
             follow=False)
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 1)
         p1 = Part.objects.filter(tutorial=tuto).last()
-        #add part
+        
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_part',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p1.pk,
+                    p1.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Présentation")
+        self.assertContains(response=result, text = u"Fin de la présenation")
+        
+        #add part 2
         result = self.client.post(
             reverse('zds.tutorial.views.add_part') + '?tutoriel={}'.format(tuto.pk),
             {
                 'title': u"Partie 2",
-                'introduction':"Analyse",
-                'conclusion': "",
+                'introduction': u"Analyse",
+                'conclusion': u"Fin de l'analyse",
             },
             follow=False)
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 2)
         p2 = Part.objects.filter(tutorial=tuto).last()
-        #add part
+        
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_part',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p2.pk,
+                    p2.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Analyse")
+        self.assertContains(response=result, text = u"Fin de l'analyse")
+
+        #add part 3
         result = self.client.post(
             reverse('zds.tutorial.views.add_part') + '?tutoriel={}'.format(tuto.pk),
             {
@@ -537,49 +566,111 @@ def test_workflow_tuto(self):
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 3)
         p3 = Part.objects.filter(tutorial=tuto).last()
-        #add chapter
+        
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_part',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p3.pk,
+                    p3.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Expérimentation")
+        self.assertContains(response=result, text = u"C'est terminé")
+
+        #add chapter 1 for part 2
         result = self.client.post(
             reverse('zds.tutorial.views.add_chapter') + '?partie={}'.format(p2.pk),
             {
                 'title': u"Chapitre 1",
                 'introduction':"Mon premier chapitre",
-                'conclusion': "",
+                'conclusion': "Fin de mon premier chapitre",
             },
             follow=False)
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Chapter.objects.filter(part=p1).count(), 0)
         self.assertEqual(Chapter.objects.filter(part=p2).count(), 1)
         self.assertEqual(Chapter.objects.filter(part=p3).count(), 0)
+        c1 = Chapter.objects.filter(part=p2).last()
         
-        #add chapter
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_chapter',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p2.pk,
+                    p2.slug,
+                    c1.pk,
+                    c1.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Mon premier chapitre")
+        self.assertContains(response=result, text = u"Fin de mon premier chapitre")
+
+        #add chapter 2 for part 2
         result = self.client.post(
             reverse('zds.tutorial.views.add_chapter') + '?partie={}'.format(p2.pk),
             {
                 'title': u"Chapitre 2",
-                'introduction':"Mon deuxième chapitre",
-                'conclusion': "",
+                'introduction': u"Mon deuxième chapitre",
+                'conclusion':u"Fin de mon deuxième chapitre",
             },
             follow=False)
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Chapter.objects.filter(part=p1).count(), 0)
         self.assertEqual(Chapter.objects.filter(part=p2).count(), 2)
         self.assertEqual(Chapter.objects.filter(part=p3).count(), 0)
+        c2 = Chapter.objects.filter(part=p2).last()
         
-        #add chapter
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_chapter',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p2.pk,
+                    p2.slug,
+                    c2.pk,
+                    c2.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Mon deuxième chapitre")
+        self.assertContains(response=result, text = u"Fin de mon deuxième chapitre")
+        
+        #add chapter 3 for part 2
         result = self.client.post(
             reverse('zds.tutorial.views.add_chapter') + '?partie={}'.format(p2.pk),
             {
                 'title': u"Chapitre 2",
-                'introduction':"Mon troisième chapitre homonyme",
-                'conclusion': "",
+                'introduction': u"Mon troisième chapitre homonyme",
+                'conclusion': u"Fin de mon troisième chapitre",
             },
             follow=False)
         self.assertEqual(result.status_code, 302)
         self.assertEqual(Chapter.objects.filter(part=p1).count(), 0)
         self.assertEqual(Chapter.objects.filter(part=p2).count(), 3)
         self.assertEqual(Chapter.objects.filter(part=p3).count(), 0)
+        c3 = Chapter.objects.filter(part=p2).last()
         
-        #add chapter
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_chapter',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p2.pk,
+                    p2.slug,
+                    c3.pk,
+                    c3.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Mon troisième chapitre homonyme")
+        self.assertContains(response=result, text = u"Fin de mon troisième chapitre")
+        
+        #add chapter 4 for part 1
         result = self.client.post(
             reverse('zds.tutorial.views.add_chapter') + '?partie={}'.format(p1.pk),
             {
@@ -592,6 +683,258 @@ def test_workflow_tuto(self):
         self.assertEqual(Chapter.objects.filter(part=p1).count(), 1)
         self.assertEqual(Chapter.objects.filter(part=p2).count(), 3)
         self.assertEqual(Chapter.objects.filter(part=p3).count(), 0)
+        c4 = Chapter.objects.filter(part=p1).last()
+        
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_chapter',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p1.pk,
+                    p1.slug,
+                    c4.pk,
+                    c4.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Mon premier chapitre d'une autre partie")
+        
+        #edit part 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.edit_part') + '?partie={}'.format(p2.pk),
+            {
+                'title': u"Partie 2 : edition de titre",
+                'introduction': u"Expérimentation : edition d'introduction",
+                'conclusion': u"C'est terminé : edition de conlusion",
+            },
+            follow=True)
+        self.assertContains(response=result, text = u"Partie 2 : edition de titre")
+        self.assertContains(response=result, text = u"Expérimentation : edition d'introduction")
+        self.assertContains(response=result, text = u"C'est terminé : edition de conlusion")
+        self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 3)
+        
+        #edit chapter 3
+        result = self.client.post(
+            reverse('zds.tutorial.views.edit_chapter') + '?chapitre={}'.format(c3.pk),
+            {
+                'title': u"Chapitre 3 : edition de titre",
+                'introduction': u"Edition d'introduction",
+                'conclusion': u"Edition de conlusion",
+            },
+            follow=True)
+        self.assertContains(response=result, text = u"Chapitre 3 : edition de titre")
+        self.assertContains(response=result, text = u"Edition d'introduction")
+        self.assertContains(response=result, text = u"Edition de conlusion")
+        self.assertEqual(Chapter.objects.filter(part=p2.pk).count(), 3)
+        
+        #edit part 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.edit_part') + '?partie={}'.format(p2.pk),
+            {
+                'title': u"Partie 2 : seconde edition de titre",
+                'introduction': u"Expérimentation : seconde edition d'introduction",
+                'conclusion': u"C'est terminé : seconde edition de conlusion",
+            },
+            follow=True)
+        self.assertContains(response=result, text = u"Partie 2 : seconde edition de titre")
+        self.assertContains(response=result, text = u"Expérimentation : seconde edition d'introduction")
+        self.assertContains(response=result, text = u"C'est terminé : seconde edition de conlusion")
+        self.assertEqual(Part.objects.filter(tutorial=tuto).count(), 3)
+        
+        #edit chapter 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.edit_chapter') + '?chapitre={}'.format(c2.pk),
+            {
+                'title': u"Chapitre 2 : edition de titre",
+                'introduction': u"Edition d'introduction",
+                'conclusion': u"Edition de conlusion",
+            },
+            follow=True)
+        self.assertContains(response=result, text = u"Chapitre 2 : edition de titre")
+        self.assertContains(response=result, text = u"Edition d'introduction")
+        self.assertContains(response=result, text = u"Edition de conlusion")
+        self.assertEqual(Chapter.objects.filter(part=p2.pk).count(), 3)
+        
+        #move chapter 1 against 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_chapter'),
+            {
+                'chapter': c1.pk,
+                'move_target': c2.position_in_part,
+            },
+            follow=True)
+        #move part 1 against 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_part'),
+            {
+                'part': p1.pk,
+                'move_target': p2.position_in_tutorial,
+            },
+            follow=True)
+        self.assertEqual(Chapter.objects.filter(part__tutorial=tuto.pk).count(), 4)
+        
+        # ask public tutorial
+        tuto = Tutorial.objects.get(pk=tuto.pk)
+        pub = self.client.post(
+            reverse('zds.tutorial.views.ask_validation'),
+            {
+                'tutorial': tuto.pk,
+                'text': u'Ce tuto est excellent',
+                'version': tuto.sha_draft,
+                'source': '',
+            },
+            follow=False)
+        self.assertEqual(pub.status_code, 302)
+
+        # logout before
+        self.client.logout()
+        # login with staff member
+        self.assertEqual(
+            self.client.login(
+                username=self.staff.username,
+                password='hostel77'),
+            True)
+
+        # reserve tutorial
+        validation = Validation.objects.filter(
+            tutorial__pk=tuto.pk).last()
+        pub = self.client.post(
+            reverse('zds.tutorial.views.reservation', args=[validation.pk]),
+            follow=False)
+        self.assertEqual(pub.status_code, 302)
+
+        # publish tutorial
+        pub = self.client.post(
+            reverse('zds.tutorial.views.valid_tutorial'),
+            {
+                'tutorial': tuto.pk,
+                'text': u'Ce tuto est excellent',
+                'is_major': True,
+                'source': 'http://zestedesavoir.com',
+            },
+            follow=False)
+
+        #delete part 1
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_part'),
+            {
+                'part': p1.pk,
+                'delete': "OK",
+            },
+            follow=True)
+        #delete chapter 3
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_chapter'),
+            {
+                'chapter': c3.pk,
+                'delete': "OK",
+            },
+            follow=True)
+        self.assertEqual(Chapter.objects.filter(part__tutorial=tuto.pk).count(), 2)
+        self.assertEqual(Part.objects.filter(tutorial=tuto.pk).count(), 2)
+        
+        # ask public tutorial
+        tuto = Tutorial.objects.get(pk=tuto.pk)
+        pub = self.client.post(
+            reverse('zds.tutorial.views.ask_validation'),
+            {
+                'tutorial': tuto.pk,
+                'text': u'Ce tuto est excellent',
+                'version': tuto.sha_draft,
+                'source': '',
+            },
+            follow=False)
+        self.assertEqual(pub.status_code, 302)
+
+        # reserve tutorial
+        validation = Validation.objects.filter(
+            tutorial__pk=tuto.pk).last()
+        pub = self.client.post(
+            reverse('zds.tutorial.views.reservation', args=[validation.pk]),
+            follow=False)
+        self.assertEqual(pub.status_code, 302)
+
+        # publish tutorial
+        pub = self.client.post(
+            reverse('zds.tutorial.views.valid_tutorial'),
+            {
+                'tutorial': tuto.pk,
+                'text': u'Ce tuto est excellent',
+                'is_major': True,
+                'source': 'http://zestedesavoir.com',
+            },
+            follow=False)
+        #check view online delete part and chapter
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_part',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p1.pk,
+                    p1.slug]),
+            follow=True)
+        self.assertEqual(result.status_code, 404)
+
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_chapter',
+                args=[
+                    tuto.pk,
+                    tuto.slug,
+                    p2.pk,
+                    p2.slug,
+                    c3.pk,
+                    c3.slug]),
+            follow=True)
+        self.assertEqual(result.status_code, 404)
+
+    def test_available_tuto(self):
+        """ Test that all page of big tutorial is available"""
+        parts = self.bigtuto.get_parts()
+        for part in parts:
+            result = self.client.get(reverse(
+                                        'zds.tutorial.views.view_part_online',
+                                        args=[
+                                            self.bigtuto.pk,
+                                            self.bigtuto.slug,
+                                            part.pk,
+                                            part.slug]),
+                                    follow=True)
+            self.assertEqual(result.status_code, 200)
+            result = self.client.get(reverse(
+                                        'zds.tutorial.views.view_part',
+                                        args=[
+                                            self.bigtuto.pk,
+                                            self.bigtuto.slug,
+                                            part.pk,
+                                            part.slug]),
+                                    follow=True)
+            self.assertEqual(result.status_code, 200)
+            chapters = part.get_chapters()
+            for chapter in chapters:
+                result = self.client.get(reverse(
+                                            'zds.tutorial.views.view_chapter_online',
+                                            args=[
+                                                self.bigtuto.pk,
+                                                self.bigtuto.slug,
+                                                part.pk,
+                                                part.slug,
+                                                chapter.pk,
+                                                chapter.slug]),
+                                        follow=True)
+                self.assertEqual(result.status_code, 200)
+                result = self.client.get(reverse(
+                                            'zds.tutorial.views.view_chapter',
+                                            args=[
+                                                self.bigtuto.pk,
+                                                self.bigtuto.slug,
+                                                part.pk,
+                                                part.slug,
+                                                chapter.pk,
+                                                chapter.slug]),
+                                        follow=True)
+                self.assertEqual(result.status_code, 200)
 
     def test_url_for_member(self):
         """Test simple get request by simple member."""
@@ -936,7 +1279,7 @@ def test_delete_image_tutorial(self):
         # Delete the image of the bigtuto.
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.bigtuto.gallery.pk,
                     'delete_multi': '',
@@ -1117,6 +1460,30 @@ def test_workflow_beta_tuto(self) :
             self.client.get(url).status_code,
             200)
 
+    def test_gallery_tuto_change_name(self):
+        """
+        Test if the gallery attached to a tutorial change its name when the tuto
+        has the name changed.
+        """
+
+        newtitle = u"The New Title"
+        response = self.client.post(
+            reverse('zds.tutorial.views.edit_tutorial') + '?tutoriel={}'.format(self.bigtuto.pk),
+            {
+                'title': newtitle,
+                'subcategory': self.subcat.pk,
+                'introduction': self.bigtuto.introduction,
+                'description': self.bigtuto.description,
+                'conclusion': self.bigtuto.conclusion,
+            },
+            follow=True)
+
+        tuto = Tutorial.objects.filter(pk=self.bigtuto.pk).first()
+        self.assertEqual(tuto.title, newtitle)
+        self.assertEqual(tuto.gallery.title, tuto.title)
+        self.assertEqual(tuto.gallery.slug, tuto.slug)
+
+
     def tearDown(self):
         if os.path.isdir(settings.REPO_PATH):
             shutil.rmtree(settings.REPO_PATH)
@@ -1151,6 +1518,8 @@ def setUp(self):
         self.user = ProfileFactory().user
         self.staff = StaffProfileFactory().user
 
+        self.subcat = SubCategoryFactory()
+
         self.minituto = MiniTutorialFactory()
         self.minituto.authors.add(self.user_author)
         self.minituto.gallery = GalleryFactory()
@@ -1198,6 +1567,8 @@ def setUp(self):
             },
             follow=False)
         self.assertEqual(pub.status_code, 302)
+        self.minituto = Tutorial.objects.get(pk=self.minituto.pk)
+        self.assertEqual(self.minituto.on_line(), True)
         self.assertEquals(len(mail.outbox), 1)
 
         mail.outbox = []
@@ -1759,7 +2130,7 @@ def test_delete_image_tutorial(self):
         # Delete the image of the minituto.
 
         response = self.client.post(
-                reverse('zds.gallery.views.modify_image'),
+                reverse('zds.gallery.views.delete_image'),
                 {
                     'gallery': self.minituto.gallery.pk,
                     'delete_multi': '',
@@ -2032,6 +2403,138 @@ def test_workflow_beta_tuto(self) :
             self.client.get(url).status_code,
             200)
 
+    def test_workflow_tuto(self):
+        """Test workflow of mini tutorial."""
+
+        # logout before
+        self.client.logout()
+        # login with simple member
+        self.assertEqual(
+            self.client.login(
+                username=self.user.username,
+                password='hostel77'),
+            True)
+        
+        #add new mini tuto
+        result = self.client.post(
+            reverse('zds.tutorial.views.add_tutorial'),
+            {
+                'title': u"Introduction à l'algèbre",
+                'description': "Perçer les mystère de boole",
+                'introduction':"Bienvenue dans le monde binaires",
+                'conclusion': "",
+                'type': "MINI",
+                'subcategory': self.subcat.pk,
+            },
+            follow=False)
+        
+        self.assertEqual(result.status_code, 302)
+        self.assertEqual(Tutorial.objects.all().count(), 2)
+        tuto = Tutorial.objects.last()
+        chapter = Chapter.objects.filter(tutorial__pk=tuto.pk).first()
+        
+        #add extract 1
+        result = self.client.post(
+            reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(chapter.pk),
+            {
+                'title': u"Extrait 1",
+                'text': u"Introduisons notre premier extrait",
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+        self.assertEqual(Extract.objects.filter(chapter=chapter).count(), 1)
+        e1 = Extract.objects.filter(chapter=chapter).last()
+
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_tutorial',
+                args=[
+                    tuto.pk,
+                    tuto.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Extrait 1")
+        self.assertContains(response=result, text = u"Introduisons notre premier extrait")
+        
+        #add extract 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(chapter.pk),
+            {
+                'title': u"Extrait 2",
+                'text': u"Introduisons notre deuxième extrait",
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+        self.assertEqual(Extract.objects.filter(chapter=chapter).count(), 2)
+        e2 = Extract.objects.filter(chapter=chapter).last()
+
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_tutorial',
+                args=[
+                    tuto.pk,
+                    tuto.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Extrait 2")
+        self.assertContains(response=result, text = u"Introduisons notre deuxième extrait")
+
+        #add extract 3
+        result = self.client.post(
+            reverse('zds.tutorial.views.add_extract') + '?chapitre={}'.format(chapter.pk),
+            {
+                'title': u"Extrait 3",
+                'text': u"Introduisons notre troisième extrait",
+            },
+            follow=False)
+        self.assertEqual(result.status_code, 302)
+        self.assertEqual(Extract.objects.filter(chapter=chapter).count(), 3)
+        e3 = Extract.objects.filter(chapter=chapter).last()
+
+        #check view offline
+        result = self.client.get(
+            reverse(
+                'zds.tutorial.views.view_tutorial',
+                args=[
+                    tuto.pk,
+                    tuto.slug]),
+            follow=True)
+        self.assertContains(response=result, text = u"Extrait 3")
+        self.assertContains(response=result, text = u"Introduisons notre troisième extrait")
+        
+        #edit extract 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.edit_extract') + '?extrait={}'.format(e2.pk),
+            {
+                'title': u"Extrait 2 : edition de titre",
+                'text': u"Edition d'introduction",
+            },
+            follow=True)
+        self.assertEqual(result.status_code, 200)
+        self.assertContains(response=result, text = u"Extrait 2 : edition de titre")
+        self.assertContains(response=result, text = u"Edition d'introduction")
+        self.assertEqual(Extract.objects.filter(chapter__tutorial=tuto).count(), 3)
+        
+        #move extract 1 against 2
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_extract'),
+            {
+                'extract': e1.pk,
+                'move_target': e2.position_in_chapter,
+            },
+            follow=True)
+
+        #delete extract 1
+        result = self.client.post(
+            reverse('zds.tutorial.views.modify_extract'),
+            {
+                'extract': e1.pk,
+                'delete': "OK",
+            },
+            follow=True)
+
+        self.assertEqual(Extract.objects.filter(chapter__tutorial=tuto).count(), 2)
+
     def tearDown(self):
         if os.path.isdir(settings.REPO_PATH):
             shutil.rmtree(settings.REPO_PATH)
diff --git a/zds/tutorial/urls.py b/zds/tutorial/urls.py
index 55787d0c5b..049e4ebd68 100644
--- a/zds/tutorial/urls.py
+++ b/zds/tutorial/urls.py
@@ -9,7 +9,7 @@
                        # Viewing
 
                        # Current URLs
-                       url(r'^recherche/(?P<pk_user>.+)/$',
+                       url(r'^recherche/(?P<pk_user>\d+)/$',
                            'zds.tutorial.views.find_tuto'),
 
                        url(r'^off/(?P<tutorial_pk>\d+)/(?P<tutorial_slug>.+)/(?P<part_pk>\d+)/(?P<part_slug>.+)/(?P<chapter_pk>\d+)/(?P<chapter_slug>.+)/$',
diff --git a/zds/tutorial/views.py b/zds/tutorial/views.py
index b010edfc18..aa7d672122 100644
--- a/zds/tutorial/views.py
+++ b/zds/tutorial/views.py
@@ -73,14 +73,13 @@ def index(request):
             .order_by("-pubdate") \
             .all()
     else:
-
         # The tag isn't None and exist in the system. We can use it to retrieve
         # all tutorials in the subcategory specified.
 
         tutorials = Tutorial.objects.filter(
             sha_public__isnull=False,
             subcategory__in=[tag]).exclude(sha_public="").order_by("-pubdate").all()
-    return render_template("tutorial/index.html", {"tutorials": tutorials})
+    return render_template("tutorial/index.html", {"tutorials": tutorials, "tag": tag})
 
 
 # Staff actions.
@@ -290,11 +289,14 @@ def reject_tutorial(request):
                 u'certaines corrections peuvent surement être faite pour '
                 u'l’améliorer et repasser la validation plus tard. '
                 u'Voici le message que [{2}]({3}), ton validateur t\'a laissé `{4}`'
-                u'N\'hésite pas a lui envoyer un petit message pour discuter '
-                u'de la décision ou demander plus de détail si tout cela te '
-                u'semble injuste ou manque de clarté.'
-                .format(author.username, tutorial.title, validation.validator.username,
-                        settings.SITE_URL + validation.validator.profile.get_absolute_url(), validation.comment_validator))
+                u'N\'hésite pas à lui envoyer un petit message pour discuter '
+                u'de la décision ou demander plus de détails si tout cela te '
+                u'semble injuste ou manque de clarté.'.format(
+                author.username,
+                tutorial.title,
+                validation.validator.username,
+                settings.SITE_URL + validation.validator.profile.get_absolute_url(),
+                validation.comment_validator))
             bot = get_object_or_404(User, username=settings.BOT_ACCOUNT)
             send_mp(
                 bot,
@@ -345,7 +347,7 @@ def valid_tutorial(request):
         # Update sha_public with the sha of validation. We don't update sha_draft.
         # So, the user can continue to edit his tutorial in offline.
 
-        if request.POST.get('is_major', False) or tutorial.sha_public is None:
+        if request.POST.get('is_major', False) or tutorial.sha_public is None or tutorial.sha_public == '':
             tutorial.pubdate = datetime.now()
         tutorial.sha_public = validation.version
         tutorial.source = request.POST["source"]
@@ -359,16 +361,16 @@ def valid_tutorial(request):
             msg = (
                 u'Félicitations **{0}** ! Ton zeste [{1}]({2}) '
                 u'a été publié par [{3}]({4}) ! Les lecteurs du monde entier '
-                u'peuvent venir l\'éplucher et réagir a son sujet. '
-                u'Je te conseille de rester a leur écoute afin '
+                u'peuvent venir l\'éplucher et réagir à son sujet. '
+                u'Je te conseille de rester à leur écoute afin '
                 u'd\'apporter des corrections/compléments.'
-                u'Un Tutoriel vivant et a jour est bien plus lu '
-                u'qu\'un sujet abandonné !'
-                .format(author.username,
-                        tutorial.title,
-                        settings.SITE_URL + tutorial.get_absolute_url_online(),
-                        validation.validator.username,
-                        settings.SITE_URL + validation.validator.profile.get_absolute_url()))
+                u'Un Tutoriel vivant et à jour est bien plus lu '
+                u'qu\'un sujet abandonné !'.format(
+                author.username,
+                tutorial.title,
+                settings.SITE_URL + tutorial.get_absolute_url_online(),
+                validation.validator.username,
+                settings.SITE_URL + validation.validator.profile.get_absolute_url()))
             bot = get_object_or_404(User, username=settings.BOT_ACCOUNT)
             send_mp(
                 bot,
@@ -442,8 +444,13 @@ def ask_validation(request):
         if not request.user.has_perm("tutorial.change_tutorial"):
             raise PermissionDenied
 
+    #delete old pending validation
+    Validation.objects.filter(tutorial__pk=tutorial_pk,
+                              status__in=['PENDING','PENDING_V'])\
+                              .delete()
     # We create and save validation object of the tutorial.
-
+    
+    
     validation = Validation()
     validation.tutorial = tutorial
     validation.date_proposition = datetime.now()
@@ -630,11 +637,6 @@ def view_tutorial(request, tutorial_pk, tutorial_slug):
         if not request.user.has_perm("tutorial.change_tutorial"):
             raise PermissionDenied
 
-    # Make sure the URL is well-formed
-
-    if not tutorial_slug == slugify(tutorial.title):
-        return redirect(tutorial.get_absolute_url())
-
 
     # Two variables to handle two distinct cases (large/small tutorial)
 
@@ -701,10 +703,11 @@ def view_tutorial(request, tutorial_pk, tutorial_slug):
                                            version=sha)\
                                     .order_by("-date_proposition")\
                                     .first()
-    formAskValidation = AskValidationForm()
     if tutorial.source:
+        formAskValidation = AskValidationForm(initial={"source": tutorial.source})
         formValid = ValidForm(initial={"source": tutorial.source})
     else:
+        formAskValidation = AskValidationForm()
         formValid = ValidForm()
     formReject = RejectForm()
     return render_template("tutorial/tutorial/view.html", {
@@ -726,9 +729,8 @@ def view_tutorial_online(request, tutorial_pk, tutorial_slug):
     tutorial = get_object_or_404(Tutorial, pk=tutorial_pk)
 
     # If the tutorial isn't online, we raise 404 error.
-
-    if not tutorial.on_line:
-        raise PermissionDenied
+    if not tutorial.on_line():
+        raise Http404
 
     # Two variables to handle two distinct cases (large/small tutorial)
 
@@ -738,8 +740,9 @@ def view_tutorial_online(request, tutorial_pk, tutorial_slug):
     # find the good manifest file
 
     mandata = tutorial.load_json_for_public()
-
     mandata = tutorial.load_dic(mandata)
+    mandata["update"] = tutorial.update
+    mandata["get_note_count"] = tutorial.get_note_count()
 
     # If it's a small tutorial, fetch its chapter
 
@@ -981,6 +984,13 @@ def edit_tutorial(request):
 
             tutorial.update = datetime.now()
 
+            # MAJ gallery
+
+            gal = Gallery.objects.filter(pk=tutorial.gallery.pk)
+            gal.update(title=data["title"])
+            gal.update(slug=slugify(data["title"]))
+            gal.update(update=datetime.now())
+
             # MAJ image
 
             if "image" in request.FILES:
@@ -1065,9 +1075,11 @@ def view_part(
     manifest = get_blob(repo.commit(sha).tree, "manifest.json")
     mandata = json_reader.loads(manifest)
     parts = mandata["parts"]
+    find = False
     cpt_p = 1
     for part in parts:
         if part_pk == str(part["pk"]):
+            find = True
             part["tutorial"] = tutorial
             part["path"] = tutorial.get_path()
             part["slug"] = slugify(part["title"])
@@ -1094,7 +1106,11 @@ def view_part(
             final_part = part
             break
         cpt_p += 1
-
+    
+    # if part can't find
+    if not find:
+        raise Http404
+    
     return render_template("tutorial/part/view.html",
                            {"tutorial": tutorial,
                             "part": final_part,
@@ -1111,24 +1127,28 @@ def view_part_online(
 ):
     """Display a part."""
 
-    part = get_object_or_404(Part, slug=part_slug, tutorial__pk=tutorial_pk)
-    tutorial = part.tutorial
-    if not tutorial.on_line:
+    tutorial = get_object_or_404(Tutorial, pk=tutorial_pk)
+    if not tutorial.on_line():
         raise Http404
 
     # find the good manifest file
 
     mandata = tutorial.load_json_for_public()
     mandata = tutorial.load_dic(mandata)
+    mandata["update"] = tutorial.update
+
     mandata["get_parts"] = mandata["parts"]
     parts = mandata["parts"]
     cpt_p = 1
+    final_part= None
+    find = False
     for part in parts:
         part["tutorial"] = mandata
         part["path"] = tutorial.get_path()
         part["slug"] = slugify(part["title"])
         part["position_in_tutorial"] = cpt_p
         if part_pk == str(part["pk"]):
+            find = True
             intro = open(os.path.join(tutorial.get_prod_path(),
                                       part["introduction"] + ".html"), "r")
             part["intro"] = intro.read()
@@ -1137,6 +1157,7 @@ def view_part_online(
                                        part["conclusion"] + ".html"), "r")
             part["conclu"] = conclu.read()
             conclu.close()
+            final_part=part
         cpt_c = 1
         for chapter in part["chapters"]:
             chapter["part"] = part
@@ -1156,7 +1177,11 @@ def view_part_online(
         part["get_chapters"] = part["chapters"]
         cpt_p += 1
 
-    return render_template("tutorial/part/view_online.html", {"part": part})
+    # if part can't find
+    if not find:
+        raise Http404
+    
+    return render_template("tutorial/part/view_online.html", {"part": final_part})
 
 
 @can_write_and_read_now
@@ -1177,8 +1202,8 @@ def add_part(request):
 
     # Make sure the user belongs to the author list
 
-    if request.user not in tutorial.authors.all():
-        raise Http404
+    if request.user not in tutorial.authors.all() and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if request.method == "POST":
         form = PartForm(request.POST)
         if form.is_valid():
@@ -1227,8 +1252,8 @@ def modify_part(request):
 
     # Make sure the user is allowed to do that
 
-    if request.user not in part.tutorial.authors.all():
-        raise Http404
+    if request.user not in part.tutorial.authors.all() and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if "move" in request.POST:
         try:
             new_pos = int(request.POST["move_target"])
@@ -1247,7 +1272,6 @@ def modify_part(request):
                       tuto = part.tutorial,
                       action = "maj")
     elif "delete" in request.POST:
-
         # Delete all chapters belonging to the part
 
         Chapter.objects.all().filter(part=part).delete()
@@ -1260,11 +1284,18 @@ def modify_part(request):
                 tut_p.position_in_tutorial = tut_p.position_in_tutorial - 1
                 tut_p.save()
         old_slug = os.path.join(settings.REPO_PATH, part.tutorial.get_phy_slug(), part.get_phy_slug())
-        maj_repo_part(request, old_slug_path=old_slug, action="del")
+        maj_repo_part(request, old_slug_path=old_slug, part=part, action="del")
 
+        new_slug_tuto_path = os.path.join(settings.REPO_PATH, part.tutorial.get_phy_slug())
         # Actually delete the part
-
         part.delete()
+        
+        
+        maj_repo_tuto(request,
+                      old_slug_path = new_slug_tuto_path,
+                      new_slug_path = new_slug_tuto_path,
+                      tuto = part.tutorial,
+                      action = "maj")
     return redirect(part.tutorial.get_absolute_url())
 
 
@@ -1281,8 +1312,8 @@ def edit_part(request):
 
     # Make sure the user is allowed to do that
 
-    if request.user not in part.tutorial.authors.all():
-        raise Http404
+    if request.user not in part.tutorial.authors.all() and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if request.method == "POST":
         form = PartForm(request.POST)
         if form.is_valid():
@@ -1353,11 +1384,6 @@ def view_chapter(
         if not request.user.has_perm("tutorial.change_tutorial"):
             raise PermissionDenied
 
-    if not tutorial_slug == slugify(tutorial.title) or not part_slug \
-            == slugify(chapter.part.title) or not chapter_slug \
-            == slugify(chapter.title):
-        return redirect(chapter.get_absolute_url())
-
     # find the good manifest file
 
     repo = Repo(tutorial.get_path())
@@ -1368,6 +1394,7 @@ def view_chapter(
     final_chapter = None
     chapter_tab = []
     final_position = 0
+    find = False
     for part in parts:
         cpt_c = 1
         part["slug"] = slugify(part["title"])
@@ -1376,7 +1403,7 @@ def view_chapter(
             args=[
                 tutorial.pk,
                 tutorial.slug,
-                part_pk,
+                part["pk"],
                 part["slug"]])
         part["tutorial"] = tutorial
         for chapter in part["chapters"]:
@@ -1386,13 +1413,22 @@ def view_chapter(
             chapter["type"] = "BIG"
             chapter["position_in_part"] = cpt_c
             chapter["position_in_tutorial"] = cpt_c * cpt_p
-            chapter["get_absolute_url"] = part["get_absolute_url"] \
-                + "{0}/".format(chapter["slug"])
+            chapter["get_absolute_url"] = reverse(
+                                        "zds.tutorial.views.view_chapter",
+                                        args=[
+                                              tutorial.pk,
+                                              tutorial.slug,
+                                              part["pk"],
+                                              part["slug"],
+                                              chapter["pk"],
+                                              chapter["slug"]])
             if chapter_pk == str(chapter["pk"]):
+                find = True
                 chapter["intro"] = get_blob(repo.commit(sha).tree,
                                             chapter["introduction"])
                 chapter["conclu"] = get_blob(repo.commit(sha).tree,
                                              chapter["conclusion"])
+                
                 cpt_e = 1
                 for ext in chapter["extracts"]:
                     ext["chapter"] = chapter
@@ -1406,11 +1442,14 @@ def view_chapter(
                 final_position = len(chapter_tab) - 1
             cpt_c += 1
         cpt_p += 1
+    
+    # if chapter can't find
+    if not find:
+        raise Http404
 
-    prev_chapter = (chapter_tab[final_position - 1] if final_position
-                    > 0 else None)
-    next_chapter = (chapter_tab[final_position + 1] if final_position + 1
-                    < len(chapter_tab) else None)
+    prev_chapter = (chapter_tab[final_position - 1] if final_position > 0 else None)
+    next_chapter = (chapter_tab[final_position + 1] if final_position + 1 < len(chapter_tab) else None)
+    
     return render_template("tutorial/chapter/view.html", {
         "tutorial": tutorial,
         "chapter": final_chapter,
@@ -1432,24 +1471,24 @@ def view_chapter_online(
 ):
     """View chapter."""
 
-    chapter_bd = get_object_or_404(Chapter, pk=chapter_pk,
-                                   part__pk=part_pk,
-                                   part__tutorial__pk=tutorial_pk)
-    
-    tutorial = chapter_bd.get_tutorial()
-    if not tutorial.on_line:
+    tutorial = get_object_or_404(Tutorial, pk=tutorial_pk)
+    if not tutorial.on_line():
         raise Http404
 
     # find the good manifest file
 
     mandata = tutorial.load_json_for_public()
     mandata = tutorial.load_dic(mandata)
+    mandata["update"] = tutorial.update
+
     mandata['get_parts'] = mandata["parts"]
     parts = mandata["parts"]
     cpt_p = 1
     final_chapter = None
     chapter_tab = []
     final_position = 0
+    
+    find = False
     for part in parts:
         cpt_c = 1
         part["slug"] = slugify(part["title"])
@@ -1458,7 +1497,7 @@ def view_chapter_online(
             args=[
                 tutorial.pk,
                 tutorial.slug,
-                part_pk,
+                part["pk"],
                 part["slug"]])
         part["tutorial"] = mandata
         part["position_in_tutorial"] = cpt_p
@@ -1470,9 +1509,17 @@ def view_chapter_online(
             chapter["type"] = "BIG"
             chapter["position_in_part"] = cpt_c
             chapter["position_in_tutorial"] = cpt_c * cpt_p
-            chapter["get_absolute_url_online"] = part[
-                "get_absolute_url_online"] + "{0}/".format(chapter["slug"])
+            chapter["get_absolute_url_online"] = reverse(
+                                                "zds.tutorial.views.view_chapter_online",
+                                                args=[
+                                                      tutorial.pk,
+                                                      tutorial.slug,
+                                                      part["pk"],
+                                                      part["slug"],
+                                                      chapter["pk"],
+                                                      chapter["slug"]]) 
             if chapter_pk == str(chapter["pk"]):
+                find = True
                 intro = open(
                     os.path.join(
                         tutorial.get_prod_path(),
@@ -1508,6 +1555,10 @@ def view_chapter_online(
                 final_position = len(chapter_tab) - 1
             cpt_c += 1
         cpt_p += 1
+    
+    # if chapter can't find
+    if not find:
+        raise Http404
 
     prev_chapter = (chapter_tab[final_position - 1] if final_position > 0 else None)
     next_chapter = (chapter_tab[final_position + 1] if final_position + 1 < len(chapter_tab) else None)
@@ -1533,8 +1584,8 @@ def add_chapter(request):
 
     # Make sure the user is allowed to do that
 
-    if request.user not in part.tutorial.authors.all():
-        raise Http404
+    if request.user not in part.tutorial.authors.all() and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if request.method == "POST":
         form = ChapterForm(request.POST, request.FILES)
         if form.is_valid():
@@ -1612,8 +1663,8 @@ def modify_chapter(request):
 
     # Make sure the user is allowed to do that
 
-    if request.user not in chapter.get_tutorial().authors.all():
-        raise Http404
+    if request.user not in chapter.get_tutorial().authors.all() and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if "move" in data:
         try:
             new_pos = int(request.POST["move_target"])
@@ -1654,7 +1705,7 @@ def modify_chapter(request):
                          old_slug_path=chapter.get_path(), action="del")
 
         # Then delete the chapter
-
+        new_slug_path_part = os.path.join(settings.REPO_PATH, chapter.part.tutorial.get_phy_slug())
         chapter.delete()
 
         # Update all the position_in_tutorial fields for the next chapters
@@ -1663,6 +1714,12 @@ def modify_chapter(request):
                 Chapter.objects.filter(position_in_tutorial__gt=old_tut_pos):
             tut_c.update_position_in_tutorial()
             tut_c.save()
+        
+        maj_repo_part(request,
+                      old_slug_path = new_slug_path_part,
+                      new_slug_path = new_slug_path_part,
+                      part = chapter.part,
+                      action = "maj")
         messages.info(request, u"Le chapitre a bien été supprimé.")
 
         return redirect(parent.get_absolute_url())
@@ -1685,9 +1742,10 @@ def edit_chapter(request):
 
     # Make sure the user is allowed to do that
 
-    if big and request.user not in chapter.part.tutorial.authors.all() \
-            or small and request.user not in chapter.tutorial.authors.all():
-        raise Http404
+    if (big and request.user not in chapter.part.tutorial.authors.all() \
+            or small and request.user not in chapter.tutorial.authors.all())\
+         and not request.user.has_perm("tutorial.change_tutorial"):
+        raise PermissionDenied
     if request.method == "POST":
         if chapter.part:
             form = ChapterForm(request.POST, request.FILES)
@@ -1701,6 +1759,7 @@ def edit_chapter(request):
             
             old_slug = chapter.get_path()
             chapter.save()
+            chapter.update_children()
             
             if chapter.part:
                 if chapter.tutorial:
@@ -1722,7 +1781,6 @@ def edit_chapter(request):
                     img.pubdate = datetime.now()
                     img.save()
                     chapter.image = img
-            
             maj_repo_chapter(
                 request,
                 old_slug_path=old_slug,
@@ -1809,7 +1867,6 @@ def add_extract(request):
 @login_required
 def edit_extract(request):
     """Edit extract."""
-
     try:
         extract_pk = request.GET["extrait"]
     except KeyError:
@@ -1920,8 +1977,24 @@ def modify_extract(request):
         # Use path retrieve before and use it to create the new slug.
 
         old_slug = extract.get_path()
+        
+        if extract.chapter.tutorial:
+            new_slug_path_chapter = os.path.join(settings.REPO_PATH,
+                                         extract.chapter.tutorial.get_phy_slug())
+        else:
+            new_slug_path_chapter = os.path.join(settings.REPO_PATH,
+                                         chapter.part.tutorial.get_phy_slug(),
+                                         chapter.part.get_phy_slug(),
+                                         chapter.get_phy_slug())
+
         maj_repo_extract(request, old_slug_path=old_slug, extract=extract,
                          action="del")
+        
+        maj_repo_chapter(request,
+                         old_slug_path = new_slug_path_chapter,
+                         new_slug_path = new_slug_path_chapter,
+                         chapter = chapter,
+                         action = "maj")
         return redirect(chapter.get_absolute_url())
     elif "move" in data:
         try:
@@ -2557,13 +2630,12 @@ def download_markdown(request):
     """Download a markdown tutorial."""
 
     tutorial = get_object_or_404(Tutorial, pk=request.GET["tutoriel"])
-    response = HttpResponse(
-        open(
-            os.path.join(
+    phy_path = os.path.join(
                 tutorial.get_prod_path(),
                 tutorial.slug +
-                ".md"),
-            "rb").read(),
+                ".md") 
+    response = HttpResponse(
+        open(phy_path, "rb").read(),
         mimetype="application/txt")
     response["Content-Disposition"] = \
         "attachment; filename={0}.md".format(tutorial.slug)
@@ -2575,13 +2647,14 @@ def download_html(request):
     """Download a pdf tutorial."""
 
     tutorial = get_object_or_404(Tutorial, pk=request.GET["tutoriel"])
-    response = HttpResponse(
-        open(
-            os.path.join(
+    phy_path = os.path.join(
                 tutorial.get_prod_path(),
                 tutorial.slug +
-                ".html"),
-            "rb").read(),
+                ".html")
+    if not os.path.isfile(phy_path):
+        raise Http404
+    response = HttpResponse(
+        open(phy_path, "rb").read(),
         mimetype="text/html")
     response["Content-Disposition"] = \
         "attachment; filename={0}.html".format(tutorial.slug)
@@ -2593,13 +2666,14 @@ def download_pdf(request):
     """Download a pdf tutorial."""
 
     tutorial = get_object_or_404(Tutorial, pk=request.GET["tutoriel"])
-    response = HttpResponse(
-        open(
-            os.path.join(
+    phy_path = os.path.join(
                 tutorial.get_prod_path(),
                 tutorial.slug +
-                ".pdf"),
-            "rb").read(),
+                ".pdf")
+    if not os.path.isfile(phy_path):
+        raise Http404
+    response = HttpResponse(
+        open(phy_path, "rb").read(),
         mimetype="application/pdf")
     response["Content-Disposition"] = \
         "attachment; filename={0}.pdf".format(tutorial.slug)
@@ -2611,13 +2685,14 @@ def download_epub(request):
     """Download an epub tutorial."""
 
     tutorial = get_object_or_404(Tutorial, pk=request.GET["tutoriel"])
-    response = HttpResponse(
-        open(
-            os.path.join(
+    phy_path = os.path.join(
                 tutorial.get_prod_path(),
                 tutorial.slug +
-                ".epub"),
-            "rb").read(),
+                ".epub")
+    if not os.path.isfile(phy_path):
+        raise Http404
+    response = HttpResponse(
+        open(phy_path, "rb").read(),
         mimetype="application/epub")
     response["Content-Disposition"] = \
         "attachment; filename={0}.epub".format(tutorial.slug)
@@ -2664,18 +2739,19 @@ def get_url_images(md_text, pt):
                 # relative link
 
                 srcfile = settings.SITE_ROOT + img[1]
-                dstroot = pt + img[1]
-                dstdir = os.path.dirname(dstroot)
-                if not os.path.exists(dstdir):
-                    os.makedirs(dstdir)
-                shutil.copy(srcfile, dstroot)
-                ext = dstroot.split(".")[-1]
-
-                # if image is gif, convert to png
-
-                if ext == "gif":
-                    im = ImagePIL.open(dstroot)
-                    im.save(os.path.join(dstroot.split(".")[0] + ".png"))
+                if os.path.isfile(srcfile):
+                    dstroot = pt + img[1]
+                    dstdir = os.path.dirname(dstroot)
+                    if not os.path.exists(dstdir):
+                        os.makedirs(dstdir)
+                    shutil.copy(srcfile, dstroot)
+                    ext = dstroot.split(".")[-1]
+    
+                    # if image is gif, convert to png
+    
+                    if ext == "gif":
+                        im = ImagePIL.open(dstroot)
+                        im.save(os.path.join(dstroot.split(".")[0] + ".png"))
 
 
 def sub_urlimg(g):
@@ -2910,9 +2986,10 @@ def answer(request):
                 raise PermissionDenied
             for line in note_cite.text.splitlines():
                 text = text + "> " + line + "\n"
-            text = u"{0}Source:[{1}]({2})".format(
+            text = u"{0}Source:[{1}]({2}{3})".format(
                 text,
                 note_cite.author.username,
+                settings.SITE_URL,
                 note_cite.get_absolute_url())
         form = NoteForm(tutorial, request.user, initial={"text": text})
         return render_template("tutorial/comment/new.html", {
@@ -3044,13 +3121,13 @@ def edit_note(request):
 @login_required
 def like_note(request):
     """Like a note."""
-
     try:
         note_pk = request.GET["message"]
     except KeyError:
         raise Http404
     resp = {}
     note = get_object_or_404(Note, pk=note_pk)
+
     user = request.user
     if note.author.pk != request.user.pk:
 
diff --git a/zds/urls.py b/zds/urls.py
index ac325bc9bd..0ac94d40b9 100644
--- a/zds/urls.py
+++ b/zds/urls.py
@@ -60,7 +60,7 @@ def location(self, article):
         priority=0.7
     ),
     'topics': GenericSitemap(
-        {'queryset': Topic.objects.filter(is_locked=False), 'date_field': 'pubdate'},
+        {'queryset': Topic.objects.filter(is_locked=False, forum__group__isnull=True), 'date_field': 'pubdate'},
         changefreq='hourly',
         priority=0.7
     ),
diff --git a/zds/utils/articles.py b/zds/utils/articles.py
index 5f1cf45f31..ec1e176c0b 100644
--- a/zds/utils/articles.py
+++ b/zds/utils/articles.py
@@ -15,6 +15,8 @@ def export_article(article):
     dct['description'] = article.description
     dct['type'] = 'article'
     dct['text'] = article.text
+    if article.licence:
+        dct['licence'] = article.licence.code
 
     return dct
 
diff --git a/zds/utils/migrations/0002_auto__add_field_alert_comment__add_field_alert_scope__chg_field_alert_.py b/zds/utils/migrations/0002_auto__add_field_alert_comment__add_field_alert_scope__chg_field_alert_.py
index d65173ddc2..08be15c8bc 100644
--- a/zds/utils/migrations/0002_auto__add_field_alert_comment__add_field_alert_scope__chg_field_alert_.py
+++ b/zds/utils/migrations/0002_auto__add_field_alert_comment__add_field_alert_scope__chg_field_alert_.py
@@ -16,7 +16,7 @@ def forwards(self, orm):
             u'utils_alert',
             'comment',
             self.gf('django.db.models.fields.related.ForeignKey')(
-                default=0,
+                default=1,
                 related_name='comments',
                 to=orm['utils.Comment']),
             keep_default=False)