Le repo des sources pour le site web des JM2L
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

524 lines
22 KiB

  1. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  2. ## Afficher un form
  3. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  4. <%def name="DisplayForm(form, DicFormat)">
  5. <%
  6. TabJs = {'select':[], 'desc':[]}
  7. %>
  8. % for FieldName, Field in form._fields.items():
  9. % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"):
  10. <% continue %>
  11. % endif
  12. % if Field.type in ['HiddenField', 'CSRFTokenField']:
  13. ${Field}
  14. <% continue %>
  15. % elif Field.type=="SelectField":
  16. <% TabJs['select'].append(Field.label.field_id) %>
  17. % endif
  18. % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
  19. <fieldset>
  20. <legend>${Field.label.text}</legend>
  21. % else:
  22. % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("ContainerStyle"):
  23. <div style="padding-right:5px;${DicFormat[Field.name].get("ContainerStyle")}">
  24. % else:
  25. <div style="padding-right:5px;">
  26. % endif
  27. <label for="${Field.label.field_id}">${Field.label.text}
  28. % if Field.description:
  29. <% TabJs['desc'].append(Field.label.field_id) %>
  30. <a id="${Field.label.field_id}-help" data-toggle="popover"
  31. data-original-title="${Field.label.text}"
  32. data-content="${Field.description}">
  33. <i class="icon-me" style="background-image: url('/img/Help.png');background-position:1px 2px;"></i>
  34. </a>
  35. % endif
  36. </label>
  37. % endif
  38. % if DicFormat.has_key(Field.name):
  39. <%
  40. PlaceHolder = DicFormat[Field.name].get("PlaceHolder")
  41. FieldStyle = DicFormat[Field.name].get("FieldStyle")
  42. Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ]
  43. %>
  44. % if Field.type == "DateField":
  45. ${Field(placeholder=PlaceHolder or False, style=FieldStyle, class_=Class, type = "date")}
  46. % else:
  47. ${Field(placeholder=PlaceHolder or False, style=FieldStyle, class_=Class)}
  48. % endif
  49. % else:
  50. ${Field()}
  51. % endif
  52. % for error in Field.errors:
  53. <div class="alert alert-error">
  54. <button type="button" class="close" data-dismiss="alert">&times;</button>
  55. <h4>Erreur!</h4>
  56. ${ error }
  57. </div>
  58. % endfor
  59. % if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
  60. </fieldset>
  61. % else:
  62. </div>
  63. % endif
  64. % endfor
  65. <%
  66. for jsitem in TabJs['select']:
  67. context._kwargs['postpone_js'].append( "$('#%s').select2({});" % jsitem )
  68. for jsitem in TabJs['desc']:
  69. context._kwargs['postpone_js'].append( "$('#%s-help').popover();" % jsitem )
  70. %>
  71. </%def>
  72. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  73. ## Wrapper pour la form Sejour
  74. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  75. <%def name="sejour_wrapper(Places)">
  76. <div class="form-inline">
  77. Départ :
  78. <select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
  79. % for place in Places:
  80. <option value="${place.place_id}">${place.display_name}</option>
  81. % endfor
  82. </select>
  83. </div>
  84. <br />
  85. <div class="form-inline">
  86. Arrivée :
  87. <select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
  88. % for place in Places:
  89. <option value="${place.place_id}">${place.display_name}</option>
  90. % endfor
  91. </select>
  92. </div>
  93. </%def>
  94. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  95. ## Wrapper pour la form Itineraire
  96. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  97. <%def name="itin_wrapper(itin_form)">
  98. <div style="padding:5px;">
  99. <div style="float:left;padding-right:5px;">
  100. <label for="${itin_form.start_place.label.field_id}">
  101. ${itin_form.start_place.label}
  102. </label>
  103. % for error in itin_form.start_place.errors:
  104. <div class="alert error">Le Depart ${ error }</div>
  105. % endfor
  106. ${itin_form.start_place(style='width:17em;')},
  107. </div>
  108. <div>
  109. <label for="${itin_form.arrival_place.label.field_id}">
  110. ${itin_form.arrival_place.label}
  111. </label>
  112. % for error in itin_form.arrival_place.errors:
  113. <div class="alert error">Arrivee ${ error }</div>
  114. % endfor
  115. ${itin_form.arrival_place(style='width:17em;')}
  116. </div>
  117. <div style="padding:5px;">
  118. <small style="color:#999">Si je n´ai pas trouvé le lieu dont j´ai besoin dans ces listes...</small>
  119. <br />
  120. <small style="color:#999">Je peux </small>
  121. <a class="btn btn-mini btn-info" role="button" href="javascript:DoGetLieu('/2015/modal/Place/0');">
  122. <i class="icon-plus-sign icon-white"></i> Ajouter un lieu
  123. </a>
  124. </div>
  125. </div>
  126. <script>
  127. $("#${itin_form.start_place.label.field_id}").select2({});
  128. $("#${itin_form.arrival_place.label.field_id}").select2({});
  129. </script>
  130. </%def> \
  131. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  132. ## Wrapper pour afficher les fichiers
  133. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  134. <%def name="medias(MediaType, UID, desc=None)"> \
  135. </%def>
  136. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  137. ## Wrapper pour uploader
  138. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  139. <%def name="uploader(MediaType, UID, desc=None)"> \
  140. <!-- The file upload form used as target for the file upload widget -->
  141. <form class="fileupload" id="fileupload_${MediaType}" action="/uploader/${MediaType}/${UID}/proceed" method="POST" enctype="multipart/form-data">
  142. <!-- Redirect browsers with JavaScript disabled to the origin page -->
  143. <noscript><input type="hidden" name="redirect" value="/"></noscript>
  144. <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
  145. <div class="fileupload-buttonbar">
  146. <!-- The fileinput-button span is used to style the file input field as button -->
  147. <span class="btn btn-success fileinput-button">
  148. <i class="icon-plus icon-white"></i>
  149. % if desc:
  150. <span>Ajouter ${desc}</span>
  151. % else:
  152. <span>Ajouter</span>
  153. % endif:
  154. <input type="file" name="files[]" multiple>
  155. </span>
  156. <!-- The global file processing state -->
  157. <span class="fileupload-process"></span>
  158. <!-- The global progress state -->
  159. <div class="fileupload-progress fade" style="float:right;">
  160. <!-- The global progress bar -->
  161. <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100">
  162. <div class="bar progress-bar progress-bar-success" style="width:0%;"></div>
  163. </div>
  164. <!-- The extended global progress state -->
  165. <div class="progress-extended">&nbsp;</div>
  166. </div>
  167. </div>
  168. <!-- The table listing the files available for upload/download -->
  169. <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
  170. </form>
  171. </%def> \
  172. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  173. ## Wrapper pour uploader - Partie JavaScript
  174. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  175. <%def name="uploader_js()"> \
  176. <!-- The template to display files available for upload -->
  177. <script id="template-upload" type="text/x-tmpl">
  178. {% for (var i=0, file; file=o.files[i]; i++) { %}
  179. <tr class="template-upload fade">
  180. <td style="width: 80px;">
  181. <span class="preview"></span>
  182. </td>
  183. <td>
  184. <p class="name">{%=file.name%}</p>
  185. <strong class="error text-danger"></strong>
  186. <p class="size">Processing...</p>
  187. <div class="progress progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0"><div class="bar progress-bar progress-bar-success" style="width:0%;"></div></div>
  188. </td>
  189. <td style="width: 85px;">
  190. {% if (!i && !o.options.autoUpload) { %}
  191. <button class="btn-mini btn-primary start" disabled style="width: 80px;">
  192. <i class="icon-upload icon-white"></i>
  193. <span>Upload</span>
  194. </button>
  195. {% } %}
  196. {% if (!i) { %}
  197. <button class="btn-mini btn-warning cancel" style="width: 80px;">
  198. <i class="icon-ban-circle icon-white"></i>
  199. <span>Annuler</span>
  200. </button>
  201. {% } %}
  202. </td>
  203. </tr>
  204. {% } %}
  205. </script>
  206. <!-- The template to display files available for download -->
  207. <script id="template-download" type="text/x-tmpl">
  208. {% for (var i=0, file; file=o.files[i]; i++) { %}
  209. <tr class="template-download fade">
  210. <td style="width: 80px;">
  211. <span class="preview">
  212. {% if (file.thumbnailUrl) { %}
  213. <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" data-gallery><img src="{%=file.thumbnailUrl%}"></a>
  214. {% } %}
  215. </span>
  216. </td>
  217. <td>
  218. <p class="name">
  219. {% if (file.url) { %}
  220. <a href="{%=file.url%}" title="{%=file.name%}" download="{%=file.name%}" {%=file.thumbnailUrl?'data-gallery':''%}>{%=file.name%}</a>
  221. {% } else { %}
  222. <span>{%=file.name%}</span>
  223. {% } %}
  224. </p>
  225. <p><span class="size">{%=o.formatFileSize(file.size)%}</span></p>
  226. {% if (file.error) { %}
  227. <div><span class="label label-danger">Erreur</span> {%=file.error%}</div>
  228. {% } %}
  229. </td>
  230. <td style="width: 85px;">
  231. {% if (file.deleteUrl) { %}
  232. <button class="btn-mini btn-danger delete" data-type="{%=file.deleteType%}" data-url="{%=file.deleteUrl%}"{% if (file.deleteWithCredentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
  233. <i class="icon-trash icon-white"></i>
  234. <span>Suppr.</span>
  235. </button>
  236. <input type="checkbox" name="delete" value="1" class="toggle">
  237. {% } else { %}
  238. <button class="btn-mini btn-warning cancel">
  239. <i class="icon-ban-circle icon-white"></i>
  240. <span>Annuler</span>
  241. </button>
  242. {% } %}
  243. </td>
  244. </tr>
  245. {% } %}
  246. </script>
  247. </%def> \
  248. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  249. ## Wrapper pour les intervention utilisateur
  250. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  251. <%def name="show_Interventions(ListEvent, HeadTitle=None, NotFoundTitle=None)"> \
  252. <table width="100%" class="table table-striped table-bordered table-hover">
  253. <tr>
  254. <th style="width:6em;text-align:center;">Date</th>
  255. % if HeadTitle:
  256. <th style="text-align:center;">${HeadTitle}</th>
  257. % else:
  258. <th style="text-align:center;">L'historique des interventions</th>
  259. % endif
  260. </tr>
  261. % if len(ListEvent)==0:
  262. <tr>
  263. <td style="text-align:center;" colspan="2">
  264. % if NotFoundTitle:
  265. <i>${NotFoundTitle}</i>
  266. % else:
  267. <i>Désolé, Il n'y a rien dans l'historique.</i>
  268. % endif
  269. </td>
  270. </tr>
  271. % else:
  272. % for event in ListEvent:
  273. <tr>
  274. <td style="text-align:center;">
  275. <%
  276. start = event.start_time.time()
  277. end = event.end_time.time()
  278. vid = event.video.first()
  279. pres = event.presentation.first()
  280. %>
  281. ${event.start_time.strftime('%d %b %Y').decode('utf-8')}
  282. ${start.hour}:${"%.2d" % start.minute}-${end.hour}:${"%.2d" % end.minute}
  283. </td>
  284. <td style="position: relative;">${event.event_type}:
  285. <strong>
  286. <a href="/event/${event.for_year}/${event.slug}">${event.name}</a>
  287. </strong>
  288. <span style="float:right;">
  289. % if vid:
  290. <a href="${vid.get_path}">
  291. <i class="icon-film"></i>
  292. </a>
  293. % endif
  294. % if pres:
  295. <a href="${pres.get_path}">
  296. <i class="icon-list-alt"></i>
  297. </a>
  298. % endif
  299. </span>
  300. % if event.Salle:
  301. <div style="position: absolute; bottom: 2px; right: 5px;">
  302. ${event.Salle.name}
  303. </div>
  304. % endif
  305. <br/>
  306. % if event.intervenants.count()>1:
  307. avec
  308. % for num, inter in enumerate(event.intervenants.all()):
  309. <%
  310. if inter==uprofil:
  311. continue
  312. %>
  313. <a href="/user/${inter.slug}">${inter.prenom} ${inter.nom}</a>,
  314. % endfor
  315. % endif
  316. </td>
  317. </tr>
  318. % endfor
  319. % endif
  320. </table>
  321. </%def>
  322. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  323. ## Wrapper pour les badges des entités utilisateur
  324. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  325. <%def name="show_SummaryEntities(ListEntities)"> \
  326. <ul class="thumbnails">
  327. % for tiers in ListEntities:
  328. <% Entity = tiers.get_entity_type %>
  329. <li class="span3 tiers">
  330. <div class="media">
  331. <a class="pull-left" href="/entity/${Entity.entity_type}/${tiers.slug}">
  332. % if tiers.ThumbLinks:
  333. <img class="media-object" src="${tiers.ThumbLinks.pop()}" />
  334. % else:
  335. <img class="media-object" src="/img/no-image-thumb.jpg" />
  336. % endif
  337. </a>
  338. <div class="media-body">
  339. %if Entity.entity_subtype!=Entity.entity_type:
  340. <h5 style="margin:0">${Entity.entity_type} ${Entity.entity_subtype}</h5>
  341. %else:
  342. <h5 style="margin:0">${Entity.entity_type}</h5>
  343. %endif
  344. <a href="/entity/${Entity.entity_type}/${tiers.slug}">
  345. <h4 class="media-heading">${tiers.name}</h4>
  346. </a>
  347. % if Entity.entity_role:
  348. <span><i>${Entity.entity_role}</i></span>
  349. % endif
  350. </div>
  351. </div>
  352. </li>
  353. % endfor
  354. </ul>
  355. </%def>
  356. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  357. ## Wrapper pour les photos
  358. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  359. <%def name="show_my_pictures(uprofil)"> \
  360. <div class="profile-icon" style="float:right;height:250px;width:250px;">
  361. <% photos = uprofil.PhotosLinks %>
  362. <div style="text-align: center;line-height:20px;">
  363. <a data-target="#AjaxModal" Myhref="/2015/modal/Password/1" role="button" handle="modal">Changer mon mot de passe</a>
  364. </div>
  365. <div style="text-align: center;line-height:20px;">
  366. <a data-target="#AjaxModal" Myhref="/2015/modal/UserPicture/${uprofil.uid}" handle="modal">Changer ma photo</a>
  367. </div>
  368. <div id="MyPictureCarousel" class="carousel slide">
  369. % if len(photos)>1:
  370. <!-- Carousel nav -->
  371. <a class="Ucarousel-control left" href="#MyPictureCarousel" data-slide="prev">&lsaquo;</a>
  372. <a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">&rsaquo;</a>
  373. % endif
  374. <!-- Carousel items -->
  375. <div class="carousel-inner" style="height: 220px;">
  376. % if len(photos):
  377. % for num, link in enumerate(photos):
  378. <div class="${['','active '][num==0]}item" id="UserPic${num}">
  379. <div style="margin:auto;">
  380. <img src="${link}" class="img-polaroid" style="max-height:205px;max-width:235px;" alt="Photo ${uprofil.slug}" />
  381. </div>
  382. </div>
  383. % endfor
  384. % else:
  385. <div class="active item" id="UserPic0">
  386. <div style="margin:auto;width:170px;">
  387. <img src="/img/default-user.png" class="img-polaroid" alt="Photo ${uprofil.slug}" style="max-height:205px;" />
  388. </div>
  389. </div>
  390. % endif
  391. </div>
  392. </div>
  393. </div>
  394. </%def> \
  395. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  396. <%def name="show_pictures(uprofil)"> \
  397. <div class="profile-icon pull-right">
  398. <% photos = uprofil.PhotosLinks %>
  399. <div id="MyPictureCarousel" class="carousel slide">
  400. % if len(photos)>1:
  401. <!-- Carousel nav -->
  402. <a class="Ucarousel-control left" href="#MyPictureCarousel" data-slide="prev">&lsaquo;</a>
  403. <a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">&rsaquo;</a>
  404. % endif
  405. <!-- Carousel items -->
  406. <div class="carousel-inner" style="height: 220px;">
  407. % if len(photos):
  408. % for num, link in enumerate(photos):
  409. <div class="${['','active '][num==0]}item" id="UserPic${num}">
  410. <div style="margin:auto;">
  411. <img src="${link}" class="img-polaroid" style="max-height:205px;max-width:235px;" alt="Photo ${uprofil.nom} ${uprofil.prenom}" />
  412. </div>
  413. </div>
  414. % endfor
  415. % else:
  416. <div class="active item" id="UserPic0">
  417. <div style="margin:auto;width:170px;">
  418. <img src="/img/default-user.png" class="img-polaroid" alt="Photo ${uprofil.nom} ${uprofil.prenom}" style="max-height:205px;" />
  419. </div>
  420. </div>
  421. % endif
  422. </div>
  423. </div>
  424. </div>
  425. </%def> \
  426. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  427. ## Wrapper pour les échanges utilisateurs
  428. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  429. <%def name="show_exchange(Exchange, Asker, Provider)"> \
  430. <div class="media">
  431. % if Asker:
  432. <a class="pull-left" href="/user/${Asker.slug}">
  433. % if Asker.PhotosThumb:
  434. <img class="media-object"
  435. src="${Asker.PhotosThumb.pop()}"
  436. alt="${Asker.prenom} ${Asker.nom}"/>
  437. % else:
  438. <img class="media-object"
  439. src="/img/no-image-thumb.jpg"
  440. alt="${Asker.prenom} ${Asker.nom}"/>
  441. % endif
  442. </a>
  443. % else:
  444. <a class="pull-left" href="#">
  445. <img class="media-object" src="/img/personne.jpg" alt="Personne"/>
  446. </a>
  447. % endif
  448. % if Provider:
  449. <a class="pull-right" href="/user/${Provider.slug}">
  450. % if Provider.PhotosThumb:
  451. <img class="media-object"
  452. src="${Provider.PhotosThumb.pop()}"
  453. alt="${Provider.prenom} ${Provider.nom}"/>
  454. % else:
  455. <img class="media-object"
  456. src="/img/no-image-thumb.jpg"
  457. alt="${Provider.prenom} ${Provider.nom}"/>
  458. % endif
  459. </a>
  460. % else:
  461. <a class="pull-right" href="#">
  462. <img class="media-object" src="/img/personne.jpg" alt="Personne"/>
  463. </a>
  464. %endif
  465. <div class="media-body">
  466. <table style="width:100%">
  467. <tr>
  468. <td style="text-align:left;vertical-align:middle;width:40%">
  469. % if Asker:
  470. Demande de<br>
  471. <a href="/user/${Asker.slug}">${Asker.prenom} ${Asker.nom}</a>
  472. % else:
  473. <i>Pas de réponse</i>
  474. % endif
  475. </td>
  476. <td>
  477. % if Exchange.exch_done:
  478. <img class="media-object" src="/img/echange.png" alt="Echange"/>
  479. % elif Exchange.exch_state=='Ask':
  480. <img class="media-object" src="/img/asker.png" alt="Cherche"/>
  481. % elif Exchange.exch_state=='Proposal':
  482. <img class="media-object" src="/img/provider.png" alt="Propose"/>
  483. % endif
  484. </td>
  485. <td style="text-align:right;vertical-align:middle;width:40%">
  486. %if Provider:
  487. Proposition de<br>
  488. <a href="/user/${Provider.slug}">${Provider.prenom} ${Provider.nom}</a>
  489. % else:
  490. <i>Pas de réponse</i>
  491. % endif
  492. </td>
  493. </tr>
  494. </table>
  495. </div>
  496. </div>
  497. </%def> \
  498. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  499. ## Wrapper pour les addresses pour les utilisateurs
  500. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  501. <%def name="show_address(Place)"> \
  502. <address>
  503. <strong>${Place.display_name}</strong> ( ${Place.place_type} )<br>
  504. ${Place.name}<br>
  505. % if Place.specific:
  506. ${Place.specific}<br>
  507. % endif
  508. ${Place.adresse}<br>
  509. ${Place.codePostal} ${Place.ville}<br>
  510. </address>
  511. </%def> \
  512. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  513. ## Wrapper pour la description des places
  514. ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  515. <%def name="show_desc(Place)"> \
  516. % if Place.description:
  517. ${Place.description | n}
  518. % endif
  519. </%def> \