--- a/src/iconolab/fixtures/dev_initial_data.json Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/fixtures/dev_initial_data.json Fri Jun 24 12:39:13 2016 +0200
@@ -68,7 +68,30 @@
"author": 1,
"created": "2016-03-24 14:13:44.913765+01"
}
- },{
+ },
+ {
+ "model": "iconolab.Annotation",
+ "pk": 2,
+ "fields": {
+ "annotation_guid": "34ae39ae-a9a2-4736-bc59-ba6f00e37f51",
+ "image": 1,
+ "current_revision" : 2,
+ "author": 1,
+ "created": "2016-03-24 14:13:44.913765+01"
+ }
+ },
+ {
+ "model": "iconolab.Annotation",
+ "pk": 3,
+ "fields": {
+ "annotation_guid": "34ae39ae-a9a2-4736-bc59-ba6f00e37f53",
+ "image": 1,
+ "current_revision" : 3,
+ "author": 1,
+ "created": "2016-03-24 14:13:44.913765+01"
+ }
+ },
+ {
"model": "iconolab.AnnotationStats",
"pk": 1,
"fields": {
@@ -93,6 +116,35 @@
"state": 1,
"created": "2016-03-25 14:13:44.913765+01"
}
+ },
+ {
+ "model": "iconolab.AnnotationRevision",
+ "pk": 2,
+ "fields": {
+ "annotation": 2,
+ "revision_guid": "b14c8382-b136-42d0-abe1-b0a94f60d9d1",
+ "author": 1,
+ "title": "Une autre annotation sur Napoléon!",
+ "description": "ma nouvelle description",
+ "fragment": "M41.49797570850203,17.375C41.49797570850203,17.375,46.35627530364373,14.25,46.35627530364373,14.25C46.35627530364373,14.25,55.87044534412955,13.625,55.87044534412955,13.625C55.87044534412955,13.625,61.94331983805668,21.375,61.94331983805668,21.375C61.94331983805668,21.375,59.10931174089069,26.875,59.10931174089069,26.875C59.10931174089069,26.875,44.534412955465584,27.375,44.534412955465584,27.375C44.534412955465584,27.375,40.48582995951418,23.875,40.48582995951418,23.875C40.48582995951418,23.875,41.49797570850203,17.375,41.49797570850203,17.375 Z;FREE",
+ "state": 1,
+ "created": "2016-03-25 14:13:44.913765+01"
+ }
+ },
+ {
+ "model": "iconolab.AnnotationRevision",
+ "pk": 3,
+ "fields": {
+ "annotation": 3,
+ "revision_guid": "b14c8382-b136-42d0-abe1-b0a94f60d9d2",
+ "author": 1,
+ "title": "Ceci est ma nouvelle annotation",
+ "description": "C'est une autre description",
+ "fragment": "M12.955465587044534,23.625C12.955465587044534,23.625,9.7165991902834,17.75,9.7165991902834,17.75C9.7165991902834,17.75,4.65587044534413,12.125,4.65587044534413,12.125C4.65587044534413,12.125,5.870445344129554,4.25,5.870445344129554,4.25C5.870445344129554,4.25,6.680161943319838,1.125,6.680161943319838,1.125C6.680161943319838,1.125,12.753036437246964,1.625,12.753036437246964,1.625C12.753036437246964,1.625,13.157894736842104,9.375,13.157894736842104,9.375C13.157894736842104,9.375,16.194331983805668,13.625,16.194331983805668,13.625C16.194331983805668,13.625,22.267206477732792,17.125,22.267206477732792,17.125C22.267206477732792,17.125,28.74493927125506,22,28.74493927125506,22C28.74493927125506,22,24.493927125506072,25.75,24.493927125506072,25.75C24.493927125506072,25.75,12.955465587044534,23.625,12.955465587044534,23.625 Z;FREE",
+ "state": 1,
+ "created": "2016-03-25 14:13:44.913765+01"
+ }
}
+
]
\ No newline at end of file
--- a/src/iconolab/models.py Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/models.py Fri Jun 24 12:39:13 2016 +0200
@@ -31,6 +31,9 @@
return self.name
+class Item(models.Model):
+ collection = models.ForeignKey(Collection, related_name="items")
+
class ItemMetadata(models.Model):
item = models.OneToOneField('Item', related_name='metadatas')
joconde_ref = models.CharField(max_length=20, null=False, blank=False, unique=True)
@@ -38,8 +41,7 @@
title = models.CharField(max_length=255)
description = models.CharField(max_length=255)
-class Item(models.Model):
- collection = models.ForeignKey(Collection, related_name="items")
+
class ImageStats(models.Model):
image = models.OneToOneField('Image', related_name='stats', blank=False, null=False)
--- a/src/iconolab/static/iconolab/js/components/cutout/index.js Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/static/iconolab/js/components/cutout/index.js Fri Jun 24 12:39:13 2016 +0200
@@ -16,6 +16,11 @@
};
});
+Element.prototype.getTransformedXY = function( x,y ) {
+ var m = this.transform().globalMatrix;
+ return { x: m.x(x,y), y: m.y(x,y) };
+ };
+
var paper = null;
var mainImage = null;
var pointData = [];
@@ -253,7 +258,6 @@
updatePath(paper);
};
-
var attachRectEvents = function (paper) {
if (readOnly) { return false; }
@@ -344,8 +348,11 @@
}
this.setDrawingMode(pathInfos[1]);
- var pathData =pathInfos[0];
-
+ var pathData = pathInfos[0];
+
+ if(!pathData.length) {
+ return;
+ }
/* deal with path nomalization x = ImageWith/MaxXBound*/
var xRatio = mainImage.width() / viewBoxBounds.X;
var yRatio = mainImage.height() / viewBoxBounds.Y;
@@ -361,7 +368,6 @@
if (path.search(/[z|Z]/gi) === -1 ) {
path += "Z";
}
-
if (pathInfos.length >= 2) {
if (pathInfos[1] === RECT_MODE) {
handleRectPath(path);
@@ -413,7 +419,26 @@
var path = "";
if (drawing_path) {
if (drawingMode === RECT_MODE) {
- path = Snap.path.toAbsolute(drawing_path.getBBox().path).toString();
+ var bBox = drawing_path.getBBox();
+ var transform = drawing_path.transform();
+
+ if (!transform.global.length) {
+ var shapePath = drawing_path.getBBox().path;
+ }
+
+ else {
+
+ var shapeX = drawing_path.node.getAttribute('x');
+ var shapeY = drawing_path.node.getAttribute('y');
+
+ var transformMatrix = transform.globalMatrix;
+ var fakeShape = paper.rect(transformMatrix.x(shapeX, shapeY),transformMatrix.y(shapeX, shapeY), bBox.width, bBox.height);
+ shapePath = fakeShape.getBBox().path;
+ fakeShape.remove();
+ }
+
+ path = Snap.path.toAbsolute(shapePath).toString();
+
}
else {
path = drawing_path.attr('d');
@@ -426,10 +451,15 @@
new Error('ratio should be a number.');
}
+ if (!path.length) {
+ path = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
+ return path;
+ }
+
var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
path = Snap.path.map(path, normalizeMatrix).toString();
-
- /* save the type */
+
+ /* save the type */
var type = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
if (path.search(/[z|Z]/gi) === -1) {
path += " Z";
@@ -454,7 +484,6 @@
onChangeCallback = config.onDrawingModeChange;
}
- onChangeCallback
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
jQuery(config.wrapperId).append(cutCanvas);
--- a/src/iconolab/static/iconolab/js/components/egonomy-cutout/index.js Fri Jun 24 12:36:44 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +0,0 @@
-
-var initCutout = funtion () {
- var $ = jQuery;
-
- var startPath = $(".fragment-path").val();
-
- var PATHCOLOR = "#ff00ff",
- SELECTEDCOLOR = "#ffff00",
- HANDLESIZE = 6;
-
- var jqs = $(".cutout-canvas"),
- offset = jqs.offset(),
- paper = new Raphael(jqs[0]),
- closed = false,
- rectangleMode = false,
- closeTimeout,
- points = [];
-
- paper.rect(0, 0, paper.width, paper.height)
- .attr({
- stroke: "none",
- fill: "#fff",
- "fill-opacity": .01
- })
- .click(clickAddPoint)
- .drag(
- function(dx, dy, mx, my) {
-
- if (dx*dx+dy*dy < 4) {
- return;
- }
-
- if (!pathDragging) {
- clearTimeout(closeTimeout);
- closed = true;
- resetPoints();
- for (var i = 0; i < 4; i++) {
- addPoint(mx - offset.left, my - offset.top)
- }
- redrawPath();
- pathDragging = true;
- rectangleMode = true;
- }
-
- var x = mx - offset.left,
- y = my - offset.top;
- points[1].x = points[2].x = x;
- points[2].y = points[3].y = y;
- redrawPath();
- },
- function(mx, my) {
- pathDragging = false;
- },
- function() {
- setTimeout(function() {
- pointDragging = false;
- },0);
- }
- );
-
- function resetPoints() {
- rectangleMode = false;
- points.forEach(function(p) {
- p.handle.remove();
- });
- points = [];
- }
-
- function addPoint(x, y) {
-
- var dragdeltax, dragdeltay, pointDragging,
- point = {
- x: Math.floor(x),
- y: Math.floor(y)
- }
-
- var pointsWithSameX = [], pointsWithSameY = [];
-
- var pointrect = paper.rect(0, 0, HANDLESIZE, HANDLESIZE)
- .attr({
- stroke: PATHCOLOR,
- fill: PATHCOLOR,
- "fill-opacity": .3
- })
- .hover(shapeMouseOver, shapeMouseOut)
- .drag(
- function(dx, dy) {
- pointDragging = true;
- point.x = dx + dragdeltax;
- point.y = dy + dragdeltay;
- if (rectangleMode) {
- pointsWithSameX.forEach(function(p) {
- p.x = point.x;
- });
- pointsWithSameY.forEach(function(p) {
- p.y = point.y;
- });
- }
- redrawPath();
- },
- function() {
- dragdeltax = point.x;
- dragdeltay = point.y;
- if (rectangleMode) {
- pointsWithSameX = points.filter(function(p) {
- return p !== point && p.x === point.x;
- });
- pointsWithSameY = points.filter(function(p) {
- return p !== point && p.y === point.y;
- });
- }
- },
- function() {
- setTimeout(function() {
- pointDragging = false;
- shapeMouseOut(pointrect);
- },0);
- }
- )
- .click(function() {
- if (pointDragging) {
- return;
- }
- this.remove();
- points = points.filter(function(p) {
- return p != point;
- });
- redrawPath();
- });
-
- point.handle = pointrect;
-
- points.push(point);
-
- }
-
- function clickAddPoint(e, mx, my) {
-
- if (pathDragging) {
- return;
- }
-
- if (rectangleMode) {
- resetPoints();
- }
-
- clearTimeout(closeTimeout);
- closed = false;
-
- addPoint(mx - offset.left, my - offset.top);
-
- redrawPath();
-
- closeTimeout = setTimeout(function() {
- closed = true;
- redrawPath();
- }, 1000)
-
- }
-
- function shapeMouseOver() {
- points.forEach(function(point) {
- if (point.handle !== this) {
- point.handle.attr({
- stroke: PATHCOLOR,
- fill: PATHCOLOR
- });
- }
- });
- if (this !== path) {
- path.attr({
- stroke: PATHCOLOR,
- fill: PATHCOLOR
- });
- }
- this.attr({
- stroke: SELECTEDCOLOR,
- fill: SELECTEDCOLOR
- });
- }
-
- function shapeMouseOut() {
- if (pathDragging || !this || !this.attr) {
- return;
- }
- this.attr({
- stroke: PATHCOLOR,
- fill: PATHCOLOR
- });
- }
-
- function redrawPath() {
- var d = "M"
- + points.map(function(p) { return p.x + " " + p.y }).join("L")
- + (closed ? "Z" : "");
- path.attr({
- path: d
- });
- points.forEach(function(point) {
- point.handle.attr({
- x: point.x - HANDLESIZE / 2,
- y: point.y - HANDLESIZE / 2
- });
- });
- var transd = "M"
- + points.map(function(p) { return (p.x / paper.width).toString().replace(/(\.\d{4})\d*/,"$1") + " " + (p.y / paper.height).toString().replace(/(\.\d{4})\d*/,"$1") }).join("L")
- + "Z";
- $(".fragment-path").val(transd).change();
- }
-
- var dragdeltax, dragdeltay, pathDragging;
-
- var path = paper.path()
- .attr({
- stroke: PATHCOLOR,
- fill: PATHCOLOR,
- "fill-opacity": .1
- })
- .click(clickAddPoint)
- .hover(shapeMouseOver, shapeMouseOut)
- .drag(
- function(dx, dy) {
- pathDragging = true;
- points.forEach(function(point) {
- point.x += dx - dragdeltax;
- point.y += dy - dragdeltay;
- });
- dragdeltax = dx;
- dragdeltay = dy;
- redrawPath();
- },
- function() {
- dragdeltax = 0;
- dragdeltay = 0;
- },
- function() {
- setTimeout(function() {
- pathDragging = false;
- shapeMouseOut(path);
- },0);
- }
- );
-
- $(".clear-fragment").click(function() {
- resetPoints();
- redrawPath();
- return false;
- });
-
- function revertPath() {
- startPath.split(/\s*[A-Z]\s*/).forEach(function(coords) {
- xy = coords.split(/[\s,]/);
- if (xy.length === 2) {
- addPoint(paper.width * parseFloat(xy[0]), paper.height * parseFloat(xy[1]));
- }
- });
-
- if (points.length) {
- closed = true;
- }
-
- if (
- points.length === 4
- && points[0].x === points[3].x
- && points[0].y === points[1].y
- && points[1].x === points[2].x
- && points[2].y === points[3].y
- ) {
- rectangleMode = true;
- }
-
- redrawPath();
- }
-
- revertPath();
-
- $(".reset-fragment").click(function() {
- resetPoints();
- revertPath();
- return false;
- });
-
-};
-
-module.export = {
- initCutout: initCutout
-}
\ No newline at end of file
--- a/src/iconolab/static/iconolab/js/components/snapplugins/index.js Fri Jun 24 12:36:44 2016 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-/* Snap svg box resizer plugins */
\ No newline at end of file
--- a/src/iconolab/static/iconolab/js/dist/bundle.js Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/static/iconolab/js/dist/bundle.js Fri Jun 24 12:39:13 2016 +0200
@@ -83,6 +83,11 @@
};
});
+ Element.prototype.getTransformedXY = function( x,y ) {
+ var m = this.transform().globalMatrix;
+ return { x: m.x(x,y), y: m.y(x,y) };
+ };
+
var paper = null;
var mainImage = null;
var pointData = [];
@@ -320,7 +325,6 @@
updatePath(paper);
};
-
var attachRectEvents = function (paper) {
if (readOnly) { return false; }
@@ -411,8 +415,11 @@
}
this.setDrawingMode(pathInfos[1]);
- var pathData =pathInfos[0];
-
+ var pathData = pathInfos[0];
+
+ if(!pathData.length) {
+ return;
+ }
/* deal with path nomalization x = ImageWith/MaxXBound*/
var xRatio = mainImage.width() / viewBoxBounds.X;
var yRatio = mainImage.height() / viewBoxBounds.Y;
@@ -428,7 +435,6 @@
if (path.search(/[z|Z]/gi) === -1 ) {
path += "Z";
}
-
if (pathInfos.length >= 2) {
if (pathInfos[1] === RECT_MODE) {
handleRectPath(path);
@@ -480,7 +486,26 @@
var path = "";
if (drawing_path) {
if (drawingMode === RECT_MODE) {
- path = Snap.path.toAbsolute(drawing_path.getBBox().path).toString();
+ var bBox = drawing_path.getBBox();
+ var transform = drawing_path.transform();
+
+ if (!transform.global.length) {
+ var shapePath = drawing_path.getBBox().path;
+ }
+
+ else {
+
+ var shapeX = drawing_path.node.getAttribute('x');
+ var shapeY = drawing_path.node.getAttribute('y');
+
+ var transformMatrix = transform.globalMatrix;
+ var fakeShape = paper.rect(transformMatrix.x(shapeX, shapeY),transformMatrix.y(shapeX, shapeY), bBox.width, bBox.height);
+ shapePath = fakeShape.getBBox().path;
+ fakeShape.remove();
+ }
+
+ path = Snap.path.toAbsolute(shapePath).toString();
+
}
else {
path = drawing_path.attr('d');
@@ -493,10 +518,15 @@
new Error('ratio should be a number.');
}
+ if (!path.length) {
+ path = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
+ return path;
+ }
+
var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
path = Snap.path.map(path, normalizeMatrix).toString();
-
- /* save the type */
+
+ /* save the type */
var type = (drawingMode === RECT_MODE) ? ";RECT" : ";FREE";
if (path.search(/[z|Z]/gi) === -1) {
path += " Z";
@@ -521,7 +551,6 @@
onChangeCallback = config.onDrawingModeChange;
}
- onChangeCallback
if (!cutCanvas.length) {
var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
jQuery(config.wrapperId).append(cutCanvas);
--- a/src/iconolab/templates/iconolab/change_annotation.html Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/templates/iconolab/change_annotation.html Fri Jun 24 12:39:13 2016 +0200
@@ -8,7 +8,7 @@
<div id="drawing-zone" class="row" style="padding-top: 10px; border:1px solid orange">
- <div v-show='!formView' class="editor-wrapper col-md-12">
+ <div v-show='!formView' style="display:none" class="editor-wrapper col-md-12">
<div class='col-md-2'>
<ul class="form-drawing-wrapper list-inline">
<p class='form-drawing pullright'><strong>Type de dessin</strong></p>
@@ -21,7 +21,7 @@
<li @click="clear" class='pull-md-right drawingModeBtn'><i class='fa fa-trash'></i> Effacer</li>
- <li @click="save" class='pull-md-right drawingModeBtn'><i class='fa fa-plus'></i> Créer le fragment</li>
+ <li @click="showForm" class='pull-md-right drawingModeBtn infos info'><i class='fa fa-plus'></i> Valider</li>
</ul>
</div>
@@ -33,6 +33,10 @@
{% endthumbnail %}
</div>
</div>
+
+ <div class="col-md-2">
+ <a @click="cancel"><i class="fa fa-close"></i> Annuler</a>
+ </div>
</div>
@@ -49,7 +53,7 @@
<mask xmlns="http://www.w3.org/2000/svg" id="smallImage">
<rect x="0" y="0" width="{{ im.width }}", height="{{ im.height }}" fill="white"/>
<g v-bind:transform="transformMatrix">
- <path v-bind:d="fragmentPath"></path>
+ <path v-el:current-path v-bind:d="fragmentPath"></path>
</g>
</mask>
</defs>
@@ -93,8 +97,9 @@
<button type="submit" class="save btn btn-default">Enregister</button>
</form>
</div>
+
+ </div>
- </div>
</div>
{% endblock %}
@@ -111,7 +116,7 @@
isRect: true,
normalizePath: "",
readOnly: false,
- formView: false,
+ formView: true,
useClipPath: false,
transformMatrix: "",
fragmentPath: "",
@@ -121,6 +126,7 @@
init: function () {
var self = this;
+ this.initialDrawingMode = null;
this.drawingComponent = iconolab.initCutoutComponent({
wrapperId: '#iconolab-image-wrapper',
actionWrapper: '#action-wrapper',
@@ -131,11 +137,18 @@
});
}
});
+
+ this.$nextTick(function () {
+ this.showForm();
+ });
},
methods: {
setDrawingMode: function (mode, updateComponent) {
+ if (!this.initialDrawingMode) {
+ this.initialDrawingMode = mode;//useful for cancel
+ }
var updateComponent = (typeof updateComponent === "boolean") ? updateComponent: true;
this.mode = this.$options['MODE_' + mode];
this.isRect = (this.mode === this.$options.MODE_RECT) ? true: false;
@@ -143,10 +156,18 @@
this.drawingComponent.setDrawingMode(this.mode);
}
},
+
+ cancel: function () {
+ this.formView = true;
+ var currentPath = this.$els.currentPath.getAttribute("d");
+ if (!currentPath.length || !this.initialDrawingMode) { return; } {
+ currentPath += ";" + this.initialDrawingMode;
+ this.drawingComponent.setPath(currentPath);
+ }
+ },
showEditor: function () {
this.formView = false;
- console.log(this.$els.smallImage);
},
highLightZone: function () {
@@ -165,18 +186,15 @@
var normalizePath = this.drawingComponent.getPath();
},
- save: function () {
+ showForm: function () {
this.normalizePath = this.drawingComponent.getPath();
var smallImage = this.$els.smallImage;
this.formView = true;
- /* 100x = smallImageHeight && 100x=smallImageWidth | 100 = ViewBoxBound */
var xRatio = smallImage.width / 100;
var yRatio = smallImage.height / 100;
var transformMatrix = [xRatio, 0, 0, yRatio, 0, 0].join(',');
this.transformMatrix ="matrix(" + transformMatrix + ")";
this.fragmentPath = this.normalizePath.split(';')[0];
- console.log(this.fragmentPath);
- console.log(this.transformMatrix);
},
clear: function () {
--- a/src/iconolab/templates/iconolab/detail_annotation.html Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/templates/iconolab/detail_annotation.html Fri Jun 24 12:39:13 2016 +0200
@@ -7,6 +7,8 @@
{% load iconolab_tags %}
{% block content %}
+
+ <a href="{% url 'image_detail' collection_name image_ref %}"><i class="fa fa-list"></i> Revoir l'image </a>
<div id="annotation-wrapper" class="row" style="border: 1px solid gray">
<div v-show="formView" class="col-md-12">
@@ -18,7 +20,7 @@
<svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
<g transform="matrix({% transform_matrix im_width=im.width im_height=im.height max_x=100 max_y=100 %})">
- <path d="{{ annotation.current_revision.fragment }}" opacity="0.7" fill="orange"></path>
+ <path d="{{ annotation.current_revision.fragment|clean_path }}" opacity="0.7" fill="orange"></path>
</g>
</svg>
@@ -38,5 +40,4 @@
</div>
</div>
</div>
-
{% endblock %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/iconolab/templates/partials/image_annotations_list.html Fri Jun 24 12:39:13 2016 +0200
@@ -0,0 +1,30 @@
+{% load thumbnail %}
+{% load iconolab_tags %}
+
+<ul class="annotation-list-wrapper list-inline">
+
+ <p><strong>Annotations de l'image</strong></p>
+
+ {% for annotation in annotation_list %}
+ <li class="small-image-wrapper">
+
+ <div class="fragment-container" style="position: relative">
+ {% thumbnail annotation.image.media "x300" crop="center" as im %}
+ <img v-el:small-image src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}" />
+ <svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
+ <g transform="matrix({% transform_matrix im_width=im.width im_height=im.height max_x=100 max_y=100 %})">
+ <path d="{{ annotation.current_revision.fragment|clean_path }}" opacity="0.7" fill="orange"></path>
+ </g>
+ </svg>
+ </div>
+ {% endthumbnail %}
+ <div class="fragment-infos">
+ <a class="fa fa-eye" href="{% url 'annotation_edit' collection_name image_ref annotation.annotation_guid %}">Voir</a>
+ <p class="small">Créer par <strong>{{ annotation.author }}</strong></strong><p>
+ <p class="small">Révisée par <strong>{{ annotation.current_revision.author }}</strong>
+ le {{ annotation.current_revision.created|date:'d-m-Y' }}
+ </p>
+ </div>
+ </li>
+{% endfor %}
+</ul>
\ No newline at end of file
--- a/src/iconolab/templatetags/iconolab_tags.py Fri Jun 24 12:36:44 2016 +0200
+++ b/src/iconolab/templatetags/iconolab_tags.py Fri Jun 24 12:39:13 2016 +0200
@@ -16,6 +16,7 @@
return matrix
+@register.filter
def clean_path(path):
if not len(path):
return ""