فهرست منبع

/!\ Merge ot_widgets and ot_templating

Olivier Massot 5 سال پیش
والد
کامیت
0025b33fa4
73فایلهای تغییر یافته به همراه6858 افزوده شده و 19 حذف شده
  1. 62 0
      ot_templating/Classes/Controller/DonorController.php
  2. 159 0
      ot_templating/Classes/Controller/EventController.php
  3. 118 0
      ot_templating/Classes/Controller/MemberController.php
  4. 23 0
      ot_templating/Classes/Controller/OrganizationController.php
  5. 25 0
      ot_templating/Classes/Controller/OtController.php
  6. 217 0
      ot_templating/Classes/Domain/Model/Donor.php
  7. 1124 0
      ot_templating/Classes/Domain/Model/Event.php
  8. 488 0
      ot_templating/Classes/Domain/Model/Member.php
  9. 514 0
      ot_templating/Classes/Domain/Model/Organization.php
  10. 86 0
      ot_templating/Classes/Domain/Repository/BaseApiRepository.php
  11. 69 0
      ot_templating/Classes/Domain/Repository/DonorRepository.php
  12. 185 0
      ot_templating/Classes/Domain/Repository/EventRepository.php
  13. 73 0
      ot_templating/Classes/Domain/Repository/MemberRepository.php
  14. 82 0
      ot_templating/Classes/Domain/Repository/OrganizationRepository.php
  15. 1 1
      ot_templating/Configuration/TypoScript/constants.txt
  16. 10 7
      ot_templating/Configuration/TypoScript/setup.txt
  17. 2 2
      ot_templating/Readme.md
  18. 1212 1
      ot_templating/Resources/Private/Language/locallang.xlf
  19. 59 0
      ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_donor.xlf
  20. 113 0
      ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_event.xlf
  21. 170 0
      ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_organization.xlf
  22. 182 0
      ot_templating/Resources/Private/Language/locallang_db.xlf
  23. 3 0
      ot_templating/Resources/Private/Layouts/Default.html
  24. 1 1
      ot_templating/Resources/Private/Partials/Classic/Donors.html
  25. 1 1
      ot_templating/Resources/Private/Partials/Classic/EventsPreview.html
  26. 1 1
      ot_templating/Resources/Private/Partials/Modern/Donors.html
  27. 1 1
      ot_templating/Resources/Private/Partials/Modern/EventsPreview.html
  28. 17 0
      ot_templating/Resources/Private/Templates/Box/Box.html
  29. 17 0
      ot_templating/Resources/Private/Templates/Box/Classic/Box.html
  30. 17 0
      ot_templating/Resources/Private/Templates/Box/Modern/Box.html
  31. 76 0
      ot_templating/Resources/Private/Templates/Content/Classic/Carousel.html
  32. 30 0
      ot_templating/Resources/Private/Templates/Content/Classic/FCE50-50.html
  33. 79 0
      ot_templating/Resources/Private/Templates/Content/Classic/Faq.html
  34. 76 0
      ot_templating/Resources/Private/Templates/Content/Modern/Carousel.html
  35. 30 0
      ot_templating/Resources/Private/Templates/Content/Modern/FCE50-50.html
  36. 79 0
      ot_templating/Resources/Private/Templates/Content/Modern/Faq.html
  37. 44 0
      ot_templating/Resources/Private/Templates/Donor/Classic/GetDonors.html
  38. 44 0
      ot_templating/Resources/Private/Templates/Donor/GetDonors.html
  39. 44 0
      ot_templating/Resources/Private/Templates/Donor/Modern/GetDonors.html
  40. 73 0
      ot_templating/Resources/Private/Templates/Event/Classic/Index.html
  41. 8 0
      ot_templating/Resources/Private/Templates/Event/Classic/NoEvents.html
  42. 161 0
      ot_templating/Resources/Private/Templates/Event/Classic/Preview.html
  43. 59 0
      ot_templating/Resources/Private/Templates/Event/Classic/Show.html
  44. 73 0
      ot_templating/Resources/Private/Templates/Event/Index.html
  45. 73 0
      ot_templating/Resources/Private/Templates/Event/Modern/Index.html
  46. 8 0
      ot_templating/Resources/Private/Templates/Event/Modern/NoEvents.html
  47. 161 0
      ot_templating/Resources/Private/Templates/Event/Modern/Preview.html
  48. 59 0
      ot_templating/Resources/Private/Templates/Event/Modern/Show.html
  49. 8 0
      ot_templating/Resources/Private/Templates/Event/NoEvents.html
  50. 161 0
      ot_templating/Resources/Private/Templates/Event/Preview.html
  51. 59 0
      ot_templating/Resources/Private/Templates/Event/Show.html
  52. 48 0
      ot_templating/Resources/Private/Templates/Member/Classic/GetMembers.html
  53. 48 0
      ot_templating/Resources/Private/Templates/Member/Classic/GetMembersCa.html
  54. 48 0
      ot_templating/Resources/Private/Templates/Member/GetMembers.html
  55. 48 0
      ot_templating/Resources/Private/Templates/Member/GetMembersCa.html
  56. 48 0
      ot_templating/Resources/Private/Templates/Member/Modern/GetMembers.html
  57. 48 0
      ot_templating/Resources/Private/Templates/Member/Modern/GetMembersCa.html
  58. BIN
      ot_templating/Resources/Public/Icons/relation.gif
  59. BIN
      ot_templating/Resources/Public/Icons/tx_otwidgets_domain_model_event.gif
  60. BIN
      ot_templating/Resources/Public/Icons/tx_otwidgets_domain_model_organization.gif
  61. BIN
      ot_templating/Resources/Public/Icons/tx_widgets_domain_model_event.gif
  62. BIN
      ot_templating/Resources/Public/Icons/tx_widgets_domain_model_organization.gif
  63. 3 0
      ot_templating/Resources/Public/Icons/user_plugin_donors.svg
  64. 1 0
      ot_templating/Resources/Public/Icons/user_plugin_events.svg
  65. 1 1
      ot_templating/Resources/Public/assets/Classic/style/module/_donors-box.scss
  66. 1 1
      ot_templating/Resources/Public/assets/Classic/style/module/_ot-box.scss
  67. 0 1
      ot_templating/Resources/Public/assets/Modern/style/custom.css
  68. BIN
      ot_templating/Resources/Public/media/event-default.jpg
  69. BIN
      ot_templating/Resources/Public/media/man-default.jpg
  70. BIN
      ot_templating/Resources/Public/media/woman-default.jpg
  71. 13 1
      ot_templating/composer.json
  72. 95 0
      ot_templating/ext_localconf.php
  73. 19 0
      ot_templating/ext_tables.php

+ 62 - 0
ot_templating/Classes/Controller/DonorController.php

@@ -0,0 +1,62 @@
+<?php
+
+namespace Opentalent\OtTemplating\Controller;
+
+use Opentalent\OtTemplating\Domain\Repository\DonorRepository;
+use Opentalent\OtTemplating\Domain\Repository\OrganizationRepository;
+
+class DonorController extends OtController
+{
+    /**
+     * @var DonorRepository
+     *
+     */
+    protected $donorRepository;
+
+    /**
+     * @var OrganizationRepository
+     *
+     */
+    protected $organizationRepository;
+
+    /** @noinspection PhpUnused */
+    /**
+     * action getDonorsAction
+     *
+     * @param array $options
+     * @return string
+     * @throws \Exception
+     */
+    public function getDonorsAction(array $options = []) {
+        $organizationId = (int) $this->settings['organizationId'];
+
+        // Get donors of the structure
+        $donors = $this->donorRepository->findByOrganizationId($organizationId);
+        $this->view->assign('donors', $donors);
+
+        // Get the donors of the parent structures
+        $networkDonors = $this->donorRepository->findParentsByOrganizationId($organizationId);
+        $this->view->assign('networkDonors', $networkDonors);
+
+        // Static or dynamic display
+        $this->view->assign('staticDisplay', $options['staticDonors'] ?? 0);
+
+        $this->setTemplate('GetDonor');
+    }
+
+    /**
+     * @param DonorRepository $donorRepository
+     */
+    public function injectDonorRepository(DonorRepository $donorRepository)
+    {
+        $this->donorRepository = $donorRepository;
+    }
+
+    /**
+     * @param OrganizationRepository $organizationRepository
+     */
+    public function injectOrganizationRepository(OrganizationRepository $organizationRepository)
+    {
+        $this->organizationRepository = $organizationRepository;
+    }
+}

+ 159 - 0
ot_templating/Classes/Controller/EventController.php

@@ -0,0 +1,159 @@
+<?php
+
+namespace Opentalent\OtTemplating\Controller;
+
+use Opentalent\OtTemplating\Domain\Repository\EventRepository;
+use Opentalent\OtTemplating\Domain\Repository\OrganizationRepository;
+
+class EventController extends OtController
+{
+    /**
+     * @var \Opentalent\OtTemplating\Domain\Repository\EventRepository
+     *
+     */
+    protected $eventRepository;
+
+    /**
+     * @var \Opentalent\OtTemplating\Domain\Repository\OrganizationRepository
+     *
+     */
+    protected $organizationRepository;
+
+
+    /** @noinspection PhpUnused */
+    /**
+     * action nextEventsAction
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function indexAction(array $options = []) {
+        $args = $this->request->getArguments();
+        $organizationId = (int) $this->settings['organizationId'];
+
+        $searchParams = [];
+        if($args['search-loc']) {https://www.qwant.com/?client=brz-moz&q=opentalent
+            $searchParams['where'] = $args['search-loc'];
+        }
+        if($args['search-name']) {
+            $searchParams['what'] = $args['search-name'];
+        }
+        if($args['search-datestart']) {
+            $dateStart = \DateTime::createFromFormat('d/m/Y', $args['search-datestart']);
+            $searchParams['datetimeStart'] = $dateStart->format('d-m-Y');
+        }
+        if($args['search-dateend']) {
+            $dateEnd = \DateTime::createFromFormat('d/m/Y', $args['search-dateend']);
+            $searchParams['datetimeEnd'] = $dateEnd->format('d-m-Y');
+        }
+
+        $allEvents = $this->eventRepository->searchBy($organizationId, $searchParams);
+        if (empty($searchParams) && empty($allEvents)) {
+            $this->forward('noEvents');
+        }
+        $this->view->assign('allEvents', $allEvents);
+        $this->view->assign('args', $args);
+
+        $this->setTemplate('Index');
+    }
+
+    /** @noinspection PhpUnused */
+    /**
+     * action nextEventsAction
+     *
+     * @param int $eventId
+     * @return void
+     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
+     */
+    public function showAction($eventId, array $options = []) {
+        $event = $this->eventRepository->findById($eventId);
+        if ($event == null | $event->getOrganizationId() != $this->settings['organizationId']) {
+            // The requested event does not exist, or is not an event of this organization
+            unset($eventId);
+            $this->forward('index');
+        }
+        $this->view->assign('event', $event);
+
+        $this->setTemplate('Show');
+    }
+
+    /** @noinspection PhpUnused */
+    /**
+     * action noEventsAction
+     * Triggered if there are no events to show
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function noEventsAction(array $options = []) {
+        $this->setTemplate('NoEvents');
+    }
+
+    /** @noinspection PhpUnused */
+    /**
+     * action nextEventsAction
+     *
+     * @param array $options
+     * @return void
+     * @throws \Exception
+     */
+    public function previewAction(array $options = [])
+    {
+        // Get current settings
+        $organizationId = (int) $this->settings['organizationId'];
+        if (!$organizationId) {
+            return;
+        }
+
+        // Parse options
+        $limit = (int) ($options['eventsLimit'] ?? 5);
+        $period = (int) ($options['eventsPeriod'] ?? 8);
+
+        $fromDate = new \DateTime();
+        $toDate = null;
+        if ($period > 0) {
+            $nbDays = 7 * $period;
+            $toDate = new \DateTime();
+            $interval = new \DateInterval('P' . $nbDays . 'D');
+            $toDate->add($interval);
+        }
+        if ($limit < 1) {
+            $limit = 1; // $limit can not be lesser than 1
+        }
+        if ($limit > 24) {
+            $limit = 24; // $limit can not be higher than 24
+        }
+
+        // Get next events of the structure
+        $nextEvents = $this->eventRepository->findByOrganizationId($organizationId, $fromDate, $toDate, $limit);
+        $this->view->assign('events', $nextEvents);
+
+        if ((int) $this->settings['organizationIsNetwork'] == 1) {
+            // Network: Get the next events of the parent structures
+            $structuresEvents = $this->eventRepository->findChildrenByOrganizationId($organizationId, $fromDate, $toDate, $limit);
+            $this->view->assign('structuresEvents', $structuresEvents);
+        } else {
+            // Simple structure: Get the next events of the parent structures
+            $networkEvents = $this->eventRepository->findParentsByOrganizationId($organizationId, $fromDate, $toDate, $limit);
+            $this->view->assign('networkEvents', $networkEvents);
+        }
+
+        $this->setTemplate('Preview');
+    }
+
+    /**
+     * @param \Opentalent\OtTemplating\Domain\Repository\EventRepository $eventRepository
+     */
+    public function injectEventRepository(EventRepository $eventRepository)
+    {
+        $this->eventRepository = $eventRepository;
+    }
+
+    /**
+     * @param \Opentalent\OtTemplating\Domain\Repository\OrganizationRepository $organizationRepository
+     */
+    public function injectOrganizationRepository(OrganizationRepository $organizationRepository)
+    {
+        $this->organizationRepository = $organizationRepository;
+    }
+}

+ 118 - 0
ot_templating/Classes/Controller/MemberController.php

@@ -0,0 +1,118 @@
+<?php
+
+namespace Opentalent\OtTemplating\Controller;
+
+use Opentalent\OtTemplating\Domain\Repository\MemberRepository;
+
+class MemberController extends OtController
+{
+    /**
+     * @var MemberRepository
+     *
+     */
+    protected $memberRepository;
+
+    /** @noinspection PhpUnused */
+    /**
+     * action getMembersAction
+     *
+     * @param array $options
+     * @return void
+     * @throws \Exception
+     */
+    public function getMembersAction(array $options = []) {
+        $organizationId = (int) $this->settings['organizationId'];
+
+        // Get members of the structure
+        $members = $this->memberRepository->findByOrganizationId($organizationId);
+        // Sort alphabetically by name
+        usort($members, function($a, $b) {return strcmp($a->getName(), $b->getName());});
+
+        // Instruments to display in first place (next will be sorted alphabetically)
+        $stack1 = ['CONDUCTOR' => []];
+
+        $stack2 = [];
+        foreach ($members as $member) {
+            // If that Instrument exist in stack1: put it in this one
+            if (array_key_exists($member->getInstrument(), $stack1)) {
+                array_push($stack1[$member->getInstrument()], $member);
+            } else {
+                // Create the new array if needed in stack2, then put the member in it
+                if (!array_key_exists($member->getInstrument(), $stack2)) {
+                    $stack2[$member->getInstrument()] = [];
+                }
+                array_push($stack2[$member->getInstrument()], $member);
+            }
+        }
+
+        // remove empty instruments in stack 1
+        $stack1 = array_filter($stack1);
+
+        // sort by instrument stack2
+        ksort($stack2);
+
+        $membersByInstrument = array_merge($stack1, $stack2);
+        $this->view->assign('membersByInstrument', $membersByInstrument);
+
+        $this->setTemplate('GetMembers');
+    }
+
+    /** @noinspection PhpUnused */
+    /**
+     * action getCaMembersAction
+     *
+     * @param array $options
+     * @return void
+     * @throws \Exception
+     */
+    public function getMembersCaAction(array $options = []) {
+        $organizationId = (int) $this->settings['organizationId'];
+
+        // Get members of the structure (only CA members)
+        $members = $this->memberRepository->findByOrganizationId($organizationId, true);
+        // Sort alphabetically by name
+        usort($members, function($a, $b) {return strcmp($a->getName(), $b->getName());});
+
+        // Missions to display (sorted)
+        $membersByMission = [
+            'PRESIDENT' => [],
+            'HONORARY_PRESIDENT' => [],
+            'VICE_PRESIDENT' => [],
+            'VICE_PRESIDENT_OF_HONOR' => [],
+            'PRESIDENT_ASSISTANT' => [],
+            'HOUR_PRESIDENT' => [],
+            'MEMBER_OF_THE_BOARD' => [],
+            'MEMBER_OF_BOARD_OF_HONOR' => [],
+            'ACTIVE_COOPTED_BOARD_MEMBER' => [],
+            'TREASURER' => [],
+            'TREASURER_ASSISTANT' => [],
+            'SECRETARY' => [],
+            'ASSISTANT_SECRETARY' => [],
+            'ACTIVE_MEMBER_OF_THE_CA' => [],
+            'HONORARY_MEMBER' => [],
+            'YOUTH_REPRESENTATIVE' => []
+        ];
+
+        // Put members into their categorie(s)
+        foreach ($members as $member) {
+            if (array_key_exists($member->getMission(), $membersByMission)) {
+                array_push($membersByMission[$member->getMission()], $member);
+            }
+        }
+
+        // Remove empty sections
+        $membersByMission = array_filter($membersByMission);
+
+        $this->view->assign('membersByMission', $membersByMission);
+
+        $this->setTemplate('GetMembersCa');
+    }
+
+    /**
+     * @param MemberRepository $memberRepository
+     */
+    public function injectMemberRepository(MemberRepository $memberRepository)
+    {
+        $this->memberRepository = $memberRepository;
+    }
+}

+ 23 - 0
ot_templating/Classes/Controller/OrganizationController.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace Opentalent\OtTemplating\Controller;
+
+use Opentalent\OtTemplating\Domain\Repository\OrganizationRepository;
+
+class OrganizationController extends OtController
+{
+    /**
+     * @var OrganizationRepository
+     *
+     */
+    protected $organizationRepository;
+
+
+    /**
+     * @param OrganizationRepository $organizationRepository
+     */
+    public function injectOrganizationRepository(OrganizationRepository $organizationRepository)
+    {
+        $this->organizationRepository = $organizationRepository;
+    }
+}

+ 25 - 0
ot_templating/Classes/Controller/OtController.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace Opentalent\OtTemplating\Controller;
+
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
+
+class OtController extends ActionController
+{
+
+    protected function setTemplate(string $name) {
+
+//        if (isset($this->settings['template'])) {
+//            $subdir = $this->settings['template'] . '/';
+//        } else {
+        $subdir = 'Classic/';
+//        }
+
+        $this->view->setTemplatePathAndFilename(
+            GeneralUtility::getFileAbsFileName(
+                'EXT:ot_templating/Resources/Private/Templates/Event/' . $subdir. $name . '.html'
+            )
+        );
+    }
+}

+ 217 - 0
ot_templating/Classes/Domain/Model/Donor.php

@@ -0,0 +1,217 @@
+<?php
+namespace Opentalent\OtTemplating\Domain\Model;
+
+use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
+
+/**
+ * Organization
+ */
+class Donor extends AbstractEntity
+{
+    /**
+     * id
+     *
+     * @var int
+     */
+    protected $id = '';
+
+    /**
+     * organizationId
+     *
+     * @var int
+     */
+    protected $organizationId = '';
+
+    /**
+     * name
+     *
+     * @var string
+     */
+    protected $name = '';
+
+    /**
+     * email
+     *
+     * @var string
+     */
+    protected $email = '';
+
+    /**
+     * telphone
+     *
+     * @var string
+     */
+    protected $telphone = '';
+
+    /**
+     * website
+     *
+     * @var string
+     */
+    protected $website = '';
+
+    /**
+     * wording
+     *
+     * @var string
+     */
+    protected $wording = '';
+
+    /**
+     * displayedOn
+     *
+     * @var string
+     */
+    protected $displayedOn = 0;
+
+    /**
+     * logo
+     *
+     * @var string
+     */
+    protected $logo = '';
+
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * @param int $id
+     */
+    public function setId(int $id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * @return int
+     */
+    public function getOrganizationId()
+    {
+        return $this->organizationId;
+    }
+
+    /**
+     * @param int $organizationId
+     */
+    public function setOrganizationId(int $organizationId)
+    {
+        $this->organizationId = $organizationId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * @param string $name
+     */
+    public function setName($name = '')
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * @return string
+     */
+    public function getEmail()
+    {
+        return $this->email;
+    }
+
+    /**
+     * @param string $email
+     */
+    public function setEmail($email = '')
+    {
+        $this->email = $email;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTelphone()
+    {
+        return $this->telphone;
+    }
+
+    /**
+     * @param string $telphone
+     */
+    public function setTelphone($telphone = '')
+    {
+        $this->telphone = $telphone;
+    }
+
+    /**
+     * @return string
+     */
+    public function getWebsite()
+    {
+        return $this->website;
+    }
+
+    /**
+     * @param string $website
+     */
+    public function setWebsite($website = '')
+    {
+        $this->website = $website;
+    }
+
+    /**
+     * @return string
+     */
+    public function getWording()
+    {
+        return $this->wording;
+    }
+
+    /**
+     * @param string $wording
+     */
+    public function setWording($wording = '')
+    {
+        $this->wording = $wording;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDisplayedOn()
+    {
+        return $this->displayedOn;
+    }
+
+    /**
+     * @param string $displayedOn
+     */
+    public function setDisplayedOn($displayedOn = '')
+    {
+        $this->displayedOn = $displayedOn;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLogo()
+    {
+        return $this->logo;
+    }
+
+    /**
+     * @param string $logo
+     */
+    public function setLogo($logo = '')
+    {
+        $this->logo = $logo;
+    }
+}

+ 1124 - 0
ot_templating/Classes/Domain/Model/Event.php

@@ -0,0 +1,1124 @@
+<?php
+namespace Opentalent\OtTemplating\Domain\Model;
+
+use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
+
+/**
+ * Event
+ */
+class Event extends AbstractEntity
+{
+    /**
+     * id
+     *
+     * @var int
+     */
+    protected $id = 0;
+
+    /**
+     * type
+     *
+     * @var string
+     */
+    protected $type = '';
+
+    /**
+     * organizationId
+     *
+     * @var int
+     */
+    protected $organizationId = 0;
+
+    /**
+     * subdomain
+     *
+     * @var string
+     */
+    protected $subdomain = '';
+
+    /**
+     * name
+     *
+     * @var string
+     */
+    protected $name = '';
+
+    /**
+     * description
+     *
+     * @var string
+     */
+    protected $description = '';
+
+    /**
+     * categories
+     *
+     * @var int
+     */
+    protected $categories = 0;
+
+    /**
+     * url
+     *
+     * @var string
+     */
+    protected $url = '';
+
+    /**
+     * rule
+     *
+     * @var string
+     */
+    protected $rule = '';
+
+    /**
+     * datetimeStart
+     *
+     * @var \DateTime
+     */
+    protected $datetimeStart = null;
+
+    /**
+     * datetimeEnd
+     *
+     * @var \DateTime
+     */
+    protected $datetimeEnd = null;
+
+    /**
+     * dates
+     *
+     * @var string
+     */
+    protected $dates = '';
+
+    /**
+     * placename
+     *
+     * @var string
+     */
+    protected $placename = '';
+
+    /**
+     * placeDescription
+     *
+     * @var string
+     */
+    protected $placeDescription = '';
+
+    /**
+     * placeFloorSize
+     *
+     * @var string
+     */
+    protected $placeFloorSize = '';
+
+    /**
+     * placeCapacity
+     *
+     * @var string
+     */
+    protected $placeCapacity = '';
+
+    /**
+     * city
+     *
+     * @var string
+     */
+    protected $city = '';
+
+    /**
+     * postalCode
+     *
+     * @var string
+     */
+    protected $postalCode = '';
+
+    /**
+     * streetAddress
+     *
+     * @var string
+     */
+    protected $streetAddress = '';
+
+    /**
+     * longitude
+     *
+     * @var float
+     */
+    protected $longitude = 0.0;
+
+    /**
+     * latitude
+     *
+     * @var float
+     */
+    protected $latitude = 0.0;
+
+    /**
+     * roomName
+     *
+     * @var string
+     */
+    protected $roomName = '';
+
+    /**
+     * roomDescription
+     *
+     * @var string
+     */
+    protected $roomDescription = '';
+
+    /**
+     * roomLocalisation
+     *
+     * @var string
+     */
+    protected $roomLocalisation = '';
+
+    /**
+     * roomCapacity
+     *
+     * @var string
+     */
+    protected $roomCapacity = '';
+
+    /**
+     * roomFloorSize
+     *
+     * @var string
+     */
+    protected $roomFloorSize = '';
+
+    /**
+     * zupId
+     *
+     * @var int
+     */
+    protected $zupId = 0;
+
+    /**
+     * deepLink
+     *
+     * @var string
+     */
+    protected $deepLink = '';
+
+    /**
+     * image
+     *
+     * @var string
+     */
+    protected $image = '';
+
+    /**
+     * priceMini
+     *
+     * @var float
+     */
+    protected $priceMini = 0.0;
+
+    /**
+     * meetingSchedule
+     *
+     * @var string
+     */
+    protected $meetingSchedule = '';
+
+    /**
+     * api
+     *
+     * @var bool
+     */
+    protected $api = false;
+
+    /**
+     * parentName
+     *
+     * @var string
+     */
+    protected $parentName = '';
+
+    /**
+     * parentSubdomain
+     *
+     * @var string
+     */
+    protected $parentSubdomain = '';
+
+    /**
+     * organization
+     *
+     * @var
+     */
+    protected $organization = null;
+
+    /**
+     * Returns the id
+     *
+     * @return int $id
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Sets the id
+     *
+     * @param int $id
+     * @return void
+     */
+    public function setId($id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * Returns the type
+     *
+     * @return string $type
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Sets the type
+     *
+     * @param string $type
+     * @return void
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    /**
+     * Returns the organizationId
+     *
+     * @return int $organizationId
+     */
+    public function getOrganizationId()
+    {
+        return $this->organizationId;
+    }
+
+    /**
+     * Sets the organizationId
+     *
+     * @param int $organizationId
+     * @return void
+     */
+    public function setOrganizationId($organizationId)
+    {
+        $this->organizationId = $organizationId;
+    }
+
+    /**
+     * Returns the subdomain
+     *
+     * @return string $subdomain
+     */
+    public function getSubdomain()
+    {
+        return $this->subdomain;
+    }
+
+    /**
+     * Sets the subdomain
+     *
+     * @param string $subdomain
+     * @return void
+     */
+    public function setSubdomain($subdomain)
+    {
+        $this->subdomain = $subdomain;
+    }
+
+    /**
+     * Returns the name
+     *
+     * @return string $name
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets the name
+     *
+     * @param string $name
+     * @return void
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * Returns the description
+     *
+     * @return string $description
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * Sets the description
+     *
+     * @param string $description
+     * @return void
+     */
+    public function setDescription($description)
+    {
+        $this->description = $description;
+    }
+
+    /**
+     * Returns the categories
+     *
+     * @return int $categories
+     */
+    public function getCategories()
+    {
+        return $this->categories;
+    }
+
+    /**
+     * Sets the categories
+     *
+     * @param int $categories
+     * @return void
+     */
+    public function setCategories($categories)
+    {
+        $this->categories = $categories;
+    }
+
+    /**
+     * Returns the url
+     *
+     * @return string $url
+     */
+    public function getUrl()
+    {
+        return $this->url;
+    }
+
+    /**
+     * Sets the url
+     *
+     * @param string $url
+     * @return void
+     */
+    public function setUrl($url)
+    {
+        $this->url = $url;
+    }
+
+    /**
+     * Returns the rule
+     *
+     * @return string $rule
+     */
+    public function getRule()
+    {
+        return $this->rule;
+    }
+
+    /**
+     * Sets the rule
+     *
+     * @param string $rule
+     * @return void
+     */
+    public function setRule($rule)
+    {
+        $this->rule = $rule;
+    }
+
+    /**
+     * Returns the datetimeStart
+     *
+     * @return \DateTime $datetimeStart
+     */
+    public function getDatetimeStart()
+    {
+        return $this->datetimeStart;
+    }
+
+    /**
+     * Sets the datetimeStart
+     *
+     * @param \DateTime $datetimeStart
+     * @return void
+     */
+    public function setDatetimeStart(\DateTime $datetimeStart)
+    {
+        $this->datetimeStart = $datetimeStart;
+    }
+
+    /**
+     * Returns the datetimeEnd
+     *
+     * @return \DateTime $datetimeEnd
+     */
+    public function getDatetimeEnd()
+    {
+        return $this->datetimeEnd;
+    }
+
+    /**
+     * Sets the datetimeEnd
+     *
+     * @param \DateTime $datetimeEnd
+     * @return void
+     */
+    public function setDatetimeEnd(\DateTime $datetimeEnd)
+    {
+        $this->datetimeEnd = $datetimeEnd;
+    }
+
+    /**
+     * Returns the dates
+     *
+     * @return string $dates
+     */
+    public function getDates()
+    {
+        return $this->dates;
+    }
+
+    /**
+     * Sets the dates
+     *
+     * @param string $dates
+     * @return void
+     */
+    public function setDates($dates)
+    {
+        $this->dates = $dates;
+    }
+
+    /**
+     * Returns the placename
+     *
+     * @return string $placename
+     */
+    public function getPlacename()
+    {
+        return $this->placename;
+    }
+
+    /**
+     * Sets the placename
+     *
+     * @param string $placename
+     * @return void
+     */
+    public function setPlacename($placename)
+    {
+        $this->placename = $placename;
+    }
+
+    /**
+     * Returns the placeDescription
+     *
+     * @return string $placeDescription
+     */
+    public function getPlaceDescription()
+    {
+        return $this->placeDescription;
+    }
+
+    /**
+     * Sets the placeDescription
+     *
+     * @param string $placeDescription
+     * @return void
+     */
+    public function setPlaceDescription($placeDescription)
+    {
+        $this->placeDescription = $placeDescription;
+    }
+
+    /**
+     * Returns the placeFloorSize
+     *
+     * @return string $placeFloorSize
+     */
+    public function getPlaceFloorSize()
+    {
+        return $this->placeFloorSize;
+    }
+
+    /**
+     * Sets the placeFloorSize
+     *
+     * @param string $placeFloorSize
+     * @return void
+     */
+    public function setPlaceFloorSize($placeFloorSize)
+    {
+        $this->placeFloorSize = $placeFloorSize;
+    }
+
+    /**
+     * Returns the placeCapacity
+     *
+     * @return string $placeCapacity
+     */
+    public function getPlaceCapacity()
+    {
+        return $this->placeCapacity;
+    }
+
+    /**
+     * Sets the placeCapacity
+     *
+     * @param string $placeCapacity
+     * @return void
+     */
+    public function setPlaceCapacity($placeCapacity)
+    {
+        $this->placeCapacity = $placeCapacity;
+    }
+
+    /**
+     * Returns the city
+     *
+     * @return string $city
+     */
+    public function getCity()
+    {
+        return $this->city;
+    }
+
+    /**
+     * Sets the city
+     *
+     * @param string $city
+     * @return void
+     */
+    public function setCity($city)
+    {
+        $this->city = $city;
+    }
+
+    /**
+     * Returns the postalCode
+     *
+     * @return string $postalCode
+     */
+    public function getPostalCode()
+    {
+        return $this->postalCode;
+    }
+
+    /**
+     * Sets the postalCode
+     *
+     * @param string $postalCode
+     * @return void
+     */
+    public function setPostalCode($postalCode)
+    {
+        $this->postalCode = $postalCode;
+    }
+
+    /**
+     * Returns the streetAddress
+     *
+     * @return string $streetAddress
+     */
+    public function getStreetAddress()
+    {
+        return $this->streetAddress;
+    }
+
+    /**
+     * Sets the streetAddress
+     *
+     * @param string $streetAddress
+     * @return void
+     */
+    public function setStreetAddress($streetAddress)
+    {
+        $this->streetAddress = $streetAddress;
+    }
+
+    /**
+     * Returns the longitude
+     *
+     * @return float $longitude
+     */
+    public function getLongitude()
+    {
+        return $this->longitude;
+    }
+
+    /**
+     * Sets the longitude
+     *
+     * @param float $longitude
+     * @return void
+     */
+    public function setLongitude($longitude)
+    {
+        $this->longitude = $longitude;
+    }
+
+    /**
+     * Returns the latitude
+     *
+     * @return float $latitude
+     */
+    public function getLatitude()
+    {
+        return $this->latitude;
+    }
+
+    /**
+     * Sets the latitude
+     *
+     * @param float $latitude
+     * @return void
+     */
+    public function setLatitude($latitude)
+    {
+        $this->latitude = $latitude;
+    }
+
+    /**
+     * Returns the roomName
+     *
+     * @return string $roomName
+     */
+    public function getRoomName()
+    {
+        return $this->roomName;
+    }
+
+    /**
+     * Sets the roomName
+     *
+     * @param string $roomName
+     * @return void
+     */
+    public function setRoomName($roomName)
+    {
+        $this->roomName = $roomName;
+    }
+
+    /**
+     * Returns the roomDescription
+     *
+     * @return string $roomDescription
+     */
+    public function getRoomDescription()
+    {
+        return $this->roomDescription;
+    }
+
+    /**
+     * Sets the roomDescription
+     *
+     * @param string $roomDescription
+     * @return void
+     */
+    public function setRoomDescription($roomDescription)
+    {
+        $this->roomDescription = $roomDescription;
+    }
+
+    /**
+     * Returns the roomLocalisation
+     *
+     * @return string $roomLocalisation
+     */
+    public function getRoomLocalisation()
+    {
+        return $this->roomLocalisation;
+    }
+
+    /**
+     * Sets the roomLocalisation
+     *
+     * @param string $roomLocalisation
+     * @return void
+     */
+    public function setRoomLocalisation($roomLocalisation)
+    {
+        $this->roomLocalisation = $roomLocalisation;
+    }
+
+    /**
+     * Returns the roomCapacity
+     *
+     * @return string $roomCapacity
+     */
+    public function getRoomCapacity()
+    {
+        return $this->roomCapacity;
+    }
+
+    /**
+     * Sets the roomCapacity
+     *
+     * @param string $roomCapacity
+     * @return void
+     */
+    public function setRoomCapacity($roomCapacity)
+    {
+        $this->roomCapacity = $roomCapacity;
+    }
+
+    /**
+     * Returns the roomFloorSize
+     *
+     * @return string $roomFloorSize
+     */
+    public function getRoomFloorSize()
+    {
+        return $this->roomFloorSize;
+    }
+
+    /**
+     * Sets the roomFloorSize
+     *
+     * @param string $roomFloorSize
+     * @return void
+     */
+    public function setRoomFloorSize($roomFloorSize)
+    {
+        $this->roomFloorSize = $roomFloorSize;
+    }
+
+    /**
+     * Returns the zupId
+     *
+     * @return int $zupId
+     */
+    public function getZupId()
+    {
+        return $this->zupId;
+    }
+
+    /**
+     * Sets the zupId
+     *
+     * @param int $zupId
+     * @return void
+     */
+    public function setZupId($zupId)
+    {
+        $this->zupId = $zupId;
+    }
+
+    /**
+     * Returns the deepLink
+     *
+     * @return string $deepLink
+     */
+    public function getDeepLink()
+    {
+        return $this->deepLink;
+    }
+
+    /**
+     * Sets the deepLink
+     *
+     * @param string $deepLink
+     * @return void
+     */
+    public function setDeepLink($deepLink)
+    {
+        $this->deepLink = $deepLink;
+    }
+
+    /**
+     * Returns the image
+     *
+     * @return string $image
+     */
+    public function getImage()
+    {
+        return $this->image;
+    }
+
+    /**
+     * Sets the image
+     *
+     * @param string $image
+     * @return void
+     */
+    public function setImage($image)
+    {
+        $this->image = $image;
+    }
+
+    /**
+     * Returns the priceMini
+     *
+     * @return float $priceMini
+     */
+    public function getPriceMini()
+    {
+        return $this->priceMini;
+    }
+
+    /**
+     * Sets the priceMini
+     *
+     * @param float $priceMini
+     * @return void
+     */
+    public function setPriceMini($priceMini)
+    {
+        $this->priceMini = $priceMini;
+    }
+
+    /**
+     * Returns the meetingSchedule
+     *
+     * @return string $meetingSchedule
+     */
+    public function getMeetingSchedule()
+    {
+        return $this->meetingSchedule;
+    }
+
+    /**
+     * Sets the meetingSchedule
+     *
+     * @param string $meetingSchedule
+     * @return void
+     */
+    public function setMeetingSchedule($meetingSchedule)
+    {
+        $this->meetingSchedule = $meetingSchedule;
+    }
+
+    /**
+     * Returns the api
+     *
+     * @return bool $api
+     */
+    public function getApi()
+    {
+        return $this->api;
+    }
+
+    /**
+     * Sets the api
+     *
+     * @param bool $api
+     * @return void
+     */
+    public function setApi($api)
+    {
+        $this->api = $api;
+    }
+
+    /**
+     * Returns the boolean state of api
+     *
+     * @return bool
+     */
+    public function isApi()
+    {
+        return $this->api;
+    }
+
+    /**
+     * Returns the parentName
+     *
+     * @return string $parentName
+     */
+    public function getParentName()
+    {
+        return $this->parentName;
+    }
+
+    /**
+     * Sets the parentName
+     *
+     * @param string $parentName
+     * @return void
+     */
+    public function setParentName($parentName)
+    {
+        $this->parentName = $parentName;
+    }
+
+    /**
+     * Returns the parentSubdomain
+     *
+     * @return string $parentSubdomain
+     */
+    public function getParentSubdomain()
+    {
+        return $this->parentSubdomain;
+    }
+
+    /**
+     * Sets the parentSubdomain
+     *
+     * @param string $parentSubdomain
+     * @return void
+     */
+    public function setParentSubdomain($parentSubdomain)
+    {
+        $this->parentSubdomain = $parentSubdomain;
+    }
+
+    /**
+     * Returns the organization
+     *
+     * @return  $organization
+     */
+    public function getOrganization()
+    {
+        return $this->organization;
+    }
+
+    /**
+     * Sets the organization
+     *
+     * @param string $organization
+     * @return void
+     */
+    public function setOrganization($organization)
+    {
+        $this->organization = $organization;
+    }
+
+
+    /**
+     *  Retourne une chaine formattée indiquant la date et l'heure de début et de fin de l'Event
+     *
+     * @return string
+     */
+    public function getFormattedDates() {
+        if ($this->getDatetimeStart() & $this->getDatetimeEnd()) {
+            if ($this->getDatetimeStart()->format('d-m-Y') != $this->getDatetimeEnd()->format('d-m-Y')) {
+                return 'Du ' . $this->getDatetimeStart()->format('d/m/Y H\hi') . ' au ' . $this->getDatetimeEnd()->format('d/m/Y H\hi');
+            } else {
+                return 'Le ' . $this->getDatetimeStart()->format('d/m/Y') . ' de ' . $this->getDatetimeStart()->format('H\hi') . ' à ' . $this->getDatetimeEnd()->format('H\hi');
+            }
+        } else if ($this->getDatetimeStart()) {
+            return 'A partir de ' . $this->getDatetimeStart()->format('d/m/Y H\hi');
+        } else if ($this->getDatetimeEnd()) {
+            return "Jusqu'à " . $this->getDatetimeEnd()->format('d/m/Y H\hi');
+        }
+        return '';
+    }
+
+
+    /**
+     * Returns the short concatened location and date of the event
+     *
+     * @return string $datetimeStart
+     */
+    public function getLocAndDate() {
+        $infos = [];
+
+        if ($this->getPlacename() && $this->getCity() && ($this->getPlacename() !== $this->getCity())) {
+            $infos[] = $this->getPlacename() . ' (' . $this->getCity() . ')';
+        } else if ($this->getPlacename()) {
+            $infos[] = $this->getPlacename();
+        } else if ($this->getPlacename()) {
+            $infos[] = $this->getCity();
+        }
+        $dates = $this->getFormattedDates();
+        if ($dates !== '') {
+            $infos[] = lcfirst($dates);
+        }
+        return ucfirst(join(', ', $infos));
+    }
+
+
+    /**
+     * Returns the concateneted adress of the event
+     *
+     * @return string
+     */
+    public function getFullAdress() {
+        $adress = [];
+
+        if ($this->getPlaceName() &&
+            strtolower($this->getPlaceName()) != strtolower($this->getStreetAddress()) &&
+            strtolower($this->getPlaceName()) != strtolower($this->getCity())) {
+            // On ajoute le nom du lieu, si ce n'est pas celui de la ville ou d'une adresse telle qu'une place
+            $adress[] = $this->getPlaceName();
+        }
+        if ($this->getRoomName() !== null) {
+            $adress[] = $this->getRoomName();
+        }
+        if ($this->getRoomLocalisation() !== null) {
+            $adress[] = $this->getRoomLocalisation();
+        }
+
+        if ($this->getStreetAddress() !== null) {
+            $adress[] = $this->getStreetAddress();
+        }
+
+        if ($this->getCity() !== null) {
+            $pc = '';
+            if ($this->getPostalCode() !== null) {
+                $pc = $this->getPostalCode() . ' ';
+            }
+            $adress[] = $pc . $this->getCity();
+        }
+        return ucfirst(join(PHP_EOL, $adress));
+    }
+
+    /**
+     * Returns an array containing all the data to display
+     *
+     * @return array
+     */
+    public function getInfosTable() {
+        $infos = [];
+        if ($this->getPlacename() !== null) {
+            $infos['Lieu'] = $this->getPlacename();
+        }
+
+        if ($this->getPlacename() !== null) {
+            $infos['Lieu'] = $this->getPlacename();
+        }
+        if ($this->getPlaceDescription() !== null) {
+            $infos['Description du lieu'] = $this->getPlaceDescription();
+        }
+
+        $adress = $this->getFullAdress();
+        if ($adress !== '') {
+            $infos['Adresse'] = $adress;
+        }
+
+        if ($this->getUrl() !== null) {
+            $infos['Lien externe'] = $this->getUrl();
+        }
+        return $infos;
+    }
+
+    /**
+     * Returns an eluded description (max 100cars)
+     *
+     * @return string
+     */
+    public function getShortDescription() {
+        $maxCars = 100;
+        if (strlen($this->getDescription()) <= $maxCars) {
+            return $this->getDescription();
+        } else {
+            return mb_substr($this->getDescription(), 0, $maxCars, "UTF-8") . '...';
+        }
+    }
+
+}

+ 488 - 0
ot_templating/Classes/Domain/Model/Member.php

@@ -0,0 +1,488 @@
+<?php
+namespace Opentalent\OtTemplating\Domain\Model;
+
+use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
+
+/**
+ * Member of an organization
+ */
+class Member extends AbstractEntity
+{
+    /**
+     * id
+     *
+     * @var int
+     */
+    protected $id = -1;
+
+    /**
+     * organizationId
+     *
+     * @var int
+     */
+    protected $organizationId = -1;
+
+    /**
+     * gender ('MISS' or 'MISTER')
+     *
+     * @var string
+     */
+    protected $gender = '';
+
+    /**
+     * givenName (first name)
+     *
+     * @var string
+     */
+    protected $givenName = '';
+
+    /**
+     * name
+     *
+     * @var string
+     */
+    protected $name = '';
+
+    /**
+     * startDate
+     *
+     * @var \Datetime
+     */
+    protected $startDate = null;
+
+    /**
+     * endDate
+     *
+     * @var \Datetime
+     */
+    protected $endDate = null;
+
+    /**
+     * instrumentGroup
+     *
+     * @var string
+     */
+    protected $instrumentGroup = '';
+
+    /**
+     * instrument
+     *
+     * @var string
+     */
+    protected $instrument = '';
+
+    /**
+     * mission
+     *
+     * @var string
+     */
+    protected $mission = '';
+
+    /**
+     * personId
+     *
+     * @var string
+     */
+    protected $personId = -1;
+
+    /**
+     * image
+     *
+     * @var string
+     */
+    protected $image = '';
+
+    /**
+     * addressCity
+     *
+     * @var string
+     */
+    protected $addressCity = '';
+
+    /**
+     * streetAddress
+     *
+     * @var string
+     */
+    protected $streetAddress = '';
+
+    /**
+     * streetAddressSecond
+     *
+     * @var string
+     */
+    protected $streetAddressSecond = '';
+
+    /**
+     * streetAddressThird
+     *
+     * @var string
+     */
+    protected $streetAddressThird = '';
+
+    /**
+     * postalCode
+     *
+     * @var string
+     */
+    protected $postalCode = '';
+
+    /**
+     * telphone
+     *
+     * @var string
+     */
+    protected $telphone = '';
+
+    /**
+     * mobilPhone
+     *
+     * @var string
+     */
+    protected $mobilPhone = '';
+
+    /**
+     * email
+     *
+     * @var string
+     */
+    protected $email = '';
+
+
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * @param int $id
+     */
+    public function setId(int $id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * @return int
+     */
+    public function getOrganizationId()
+    {
+        return $this->organizationId;
+    }
+
+    /**
+     * @param int $organizationId
+     */
+    public function setOrganizationId(int $organizationId)
+    {
+        $this->organizationId = $organizationId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getGender()
+    {
+        return $this->gender;
+    }
+
+    /**
+     * @param string $gender
+     */
+    public function setGender($gender = '')
+    {
+        $this->gender = $gender;
+    }
+
+    /**
+     * @return string
+     */
+    public function getGivenName()
+    {
+        return $this->givenName;
+    }
+
+    /**
+     * @param string $givenName
+     */
+    public function setGivenName($givenName = '')
+    {
+        $this->givenName = $givenName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * @param string $name
+     */
+    public function setName($name = '')
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * @return \Datetime
+     */
+    public function getStartDate()
+    {
+        return $this->startDate;
+    }
+
+    /**
+     * @param \Datetime $startDate
+     */
+    public function setStartDate(\Datetime $startDate)
+    {
+        $this->startDate = $startDate;
+    }
+
+    /**
+     * @return \Datetime
+     */
+    public function getEndDate()
+    {
+        return $this->endDate;
+    }
+
+    /**
+     * @param \Datetime $endDate
+     */
+    public function setEndDate(\Datetime $endDate)
+    {
+        $this->endDate = $endDate;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInstrumentGroup()
+    {
+        return $this->instrumentGroup;
+    }
+
+    /**
+     * @param string $instrumentGroup
+     */
+    public function setInstrumentGroup($instrumentGroup = '')
+    {
+        $this->instrumentGroup = $instrumentGroup;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInstrument()
+    {
+        return $this->instrument;
+    }
+
+    /**
+     * @param string $instrument
+     */
+    public function setInstrument($instrument = '')
+    {
+        $this->instrument = $instrument;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMission()
+    {
+        return $this->mission;
+    }
+
+    /**
+     * @param string $mission
+     */
+    public function setMission($mission = '')
+    {
+        $this->mission = $mission;
+    }
+
+    /**
+     * @return int
+     */
+    public function getPersonId()
+    {
+        return $this->personId;
+    }
+
+    /**
+     * @param int $personId
+     */
+    public function setPersonId(int $personId)
+    {
+        $this->personId = $personId;
+    }
+
+    /**
+     * @return string
+     */
+    public function getImage()
+    {
+        return $this->image;
+    }
+
+    /**
+     * @param string $image
+     */
+    public function setImage($image = '')
+    {
+        $this->image = $image;
+    }
+
+    /**
+     * @return string
+     */
+    public function getAdressCity()
+    {
+        return $this->addressCity;
+    }
+
+    /**
+     * @param string $addressCity
+     */
+    public function setAdressCity($addressCity = '')
+    {
+        $this->addressCity = $addressCity;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStreetAdress()
+    {
+        return $this->streetAddress;
+    }
+
+    /**
+     * @param string $streetAddress
+     */
+    public function setStreetAdress($streetAddress = '')
+    {
+        $this->streetAddress = $streetAddress;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStreetAdressSecond()
+    {
+        return $this->streetAddressSecond;
+    }
+
+    /**
+     * @param string $streetAddressSecond
+     */
+    public function setStreetAdressSecond($streetAddressSecond = '')
+    {
+        $this->streetAddressSecond = $streetAddressSecond;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStreetAdressThird()
+    {
+        return $this->streetAddressThird;
+    }
+
+    /**
+     * @param string $streetAddressThird
+     */
+    public function setStreetAdressThird($streetAddressThird = '')
+    {
+        $this->streetAddressThird = $streetAddressThird;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPostalCode()
+    {
+        return $this->postalCode;
+    }
+
+    /**
+     * @param string $postalCode
+     */
+    public function setPostalCode($postalCode = '')
+    {
+        $this->postalCode = $postalCode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTelphone()
+    {
+        return $this->telphone;
+    }
+
+    /**
+     * @param string $telphone
+     */
+    public function setTelphone($telphone = '')
+    {
+        $this->telphone = $telphone;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMobilPhone()
+    {
+        return $this->mobilPhone;
+    }
+
+    /**
+     * @param string $mobilPhone
+     */
+    public function setMobilPhone($mobilPhone = '')
+    {
+        $this->mobilPhone = $mobilPhone;
+    }
+
+    /**
+     * @return string
+     */
+    public function getEmail()
+    {
+        return $this->email;
+    }
+
+    /**
+     * @param string $email
+     */
+    public function setEmail($email = '')
+    {
+        $this->email = $email;
+    }
+
+    /**
+     * Return a full name for the member
+     *
+     * @return string
+     */
+    public function getFullName()
+    {
+        if ($this->getGivenName() && $this->getName()) {
+            return $this->getGivenName() . ' ' . $this->getName();
+        } else if ($this->getName() && $this->getGender()) {
+            return 'M. ' . $this->getName();
+        } else {
+            return '';
+        }
+    }
+
+}

+ 514 - 0
ot_templating/Classes/Domain/Model/Organization.php

@@ -0,0 +1,514 @@
+<?php
+namespace Opentalent\OtTemplating\Domain\Model;
+
+use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
+
+/**
+ * Organization
+ */
+class Organization extends AbstractEntity
+{
+    /**
+     * id
+     *
+     * @var string
+     */
+    protected $id = '';
+
+    /**
+     * type
+     *
+     * @var string
+     */
+    protected $type = '';
+
+    /**
+     * subDomain
+     *
+     * @var string
+     */
+    protected $subDomain = '';
+
+    /**
+     * name
+     *
+     * @var string
+     */
+    protected $name = '';
+
+    /**
+     * slug
+     *
+     * @var string
+     */
+    protected $slug = '';
+
+    /**
+     * principalType
+     *
+     * @var string
+     */
+    protected $principalType = '';
+
+    /**
+     * description
+     *
+     * @var string
+     */
+    protected $description = '';
+
+    /**
+     * categories
+     *
+     * @var int
+     */
+    protected $categories = 0;
+
+    /**
+     * addressCity
+     *
+     * @var string
+     */
+    protected $addressCity = '';
+
+    /**
+     * postalCode
+     *
+     * @var string
+     */
+    protected $postalCode = '';
+
+    /**
+     * streetAdress
+     *
+     * @var string
+     */
+    protected $streetAdress = '';
+
+    /**
+     * latitude
+     *
+     * @var float
+     */
+    protected $latitude = 0.0;
+
+    /**
+     * longitude
+     *
+     * @var float
+     */
+    protected $longitude = 0.0;
+
+    /**
+     * country
+     *
+     * @var string
+     */
+    protected $country = '';
+
+    /**
+     * logo
+     *
+     * @var string
+     */
+    protected $logo = '';
+
+    /**
+     * parentId
+     *
+     * @var int
+     */
+    protected $parentId = 0;
+
+    /**
+     * parentName
+     *
+     * @var string
+     */
+    protected $parentName = '';
+
+    /**
+     * parentSubdomain
+     *
+     * @var string
+     */
+    protected $parentSubdomain = '';
+
+    /**
+     * Returns the id
+     *
+     * @return string $id
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * Sets the id
+     *
+     * @param string $id
+     * @return void
+     */
+    public function setId($id)
+    {
+        $this->id = $id;
+    }
+
+    /**
+     * Returns the type
+     *
+     * @return string $type
+     */
+    public function getType()
+    {
+        return $this->type;
+    }
+
+    /**
+     * Sets the type
+     *
+     * @param string $type
+     * @return void
+     */
+    public function setType($type)
+    {
+        $this->type = $type;
+    }
+
+    /**
+     * Returns the subDomain
+     *
+     * @return string $subDomain
+     */
+    public function getSubDomain()
+    {
+        return $this->subDomain;
+    }
+
+    /**
+     * Sets the subDomain
+     *
+     * @param string $subDomain
+     * @return void
+     */
+    public function setSubDomain($subDomain)
+    {
+        $this->subDomain = $subDomain;
+    }
+
+    /**
+     * Returns the name
+     *
+     * @return string $name
+     */
+    public function getName()
+    {
+        return $this->name;
+    }
+
+    /**
+     * Sets the name
+     *
+     * @param string $name
+     * @return void
+     */
+    public function setName($name)
+    {
+        $this->name = $name;
+    }
+
+    /**
+     * Returns the slug
+     *
+     * @return string $slug
+     */
+    public function getSlug()
+    {
+        return $this->slug;
+    }
+
+    /**
+     * Sets the slug
+     *
+     * @param string $slug
+     * @return void
+     */
+    public function setSlug($slug)
+    {
+        $this->slug = $slug;
+    }
+
+    /**
+     * Returns the principalType
+     *
+     * @return string $principalType
+     */
+    public function getPrincipalType()
+    {
+        return $this->principalType;
+    }
+
+    /**
+     * Sets the principalType
+     *
+     * @param string $principalType
+     * @return void
+     */
+    public function setPrincipalType($principalType)
+    {
+        $this->principalType = $principalType;
+    }
+
+    /**
+     * Returns the description
+     *
+     * @return string $description
+     */
+    public function getDescription()
+    {
+        return $this->description;
+    }
+
+    /**
+     * Sets the description
+     *
+     * @param string $description
+     * @return void
+     */
+    public function setDescription($description)
+    {
+        $this->description = $description;
+    }
+
+    /**
+     * Returns the categories
+     *
+     * @return int $categories
+     */
+    public function getCategories()
+    {
+        return $this->categories;
+    }
+
+    /**
+     * Sets the categories
+     *
+     * @param int $categories
+     * @return void
+     */
+    public function setCategories($categories)
+    {
+        $this->categories = $categories;
+    }
+
+    /**
+     * Returns the addressCity
+     *
+     * @return string $addressCity
+     */
+    public function getAddressCity()
+    {
+        return $this->addressCity;
+    }
+
+    /**
+     * Sets the addressCity
+     *
+     * @param string $addressCity
+     * @return void
+     */
+    public function setAddressCity($addressCity)
+    {
+        $this->addressCity = $addressCity;
+    }
+
+    /**
+     * Returns the postalCode
+     *
+     * @return string $postalCode
+     */
+    public function getPostalCode()
+    {
+        return $this->postalCode;
+    }
+
+    /**
+     * Sets the postalCode
+     *
+     * @param string $postalCode
+     * @return void
+     */
+    public function setPostalCode($postalCode)
+    {
+        $this->postalCode = $postalCode;
+    }
+
+    /**
+     * Returns the streetAdress
+     *
+     * @return string $streetAdress
+     */
+    public function getStreetAdress()
+    {
+        return $this->streetAdress;
+    }
+
+    /**
+     * Sets the streetAdress
+     *
+     * @param string $streetAdress
+     * @return void
+     */
+    public function setStreetAdress($streetAdress)
+    {
+        $this->streetAdress = $streetAdress;
+    }
+
+    /**
+     * Returns the latitude
+     *
+     * @return float $latitude
+     */
+    public function getLatitude()
+    {
+        return $this->latitude;
+    }
+
+    /**
+     * Sets the latitude
+     *
+     * @param float $latitude
+     * @return void
+     */
+    public function setLatitude($latitude)
+    {
+        $this->latitude = $latitude;
+    }
+
+    /**
+     * Returns the longitude
+     *
+     * @return float $longitude
+     */
+    public function getLongitude()
+    {
+        return $this->longitude;
+    }
+
+    /**
+     * Sets the longitude
+     *
+     * @param float $longitude
+     * @return void
+     */
+    public function setLongitude($longitude)
+    {
+        $this->longitude = $longitude;
+    }
+
+    /**
+     * Returns the country
+     *
+     * @return string $country
+     */
+    public function getCountry()
+    {
+        return $this->country;
+    }
+
+    /**
+     * Sets the country
+     *
+     * @param string $country
+     * @return void
+     */
+    public function setCountry($country)
+    {
+        $this->country = $country;
+    }
+
+    /**
+     * Returns the logo
+     *
+     * @return string $logo
+     */
+    public function getLogo()
+    {
+        return $this->logo;
+    }
+
+    /**
+     * Sets the logo
+     *
+     * @param string $logo
+     * @return void
+     */
+    public function setLogo($logo)
+    {
+        $this->logo = $logo;
+    }
+
+    /**
+     * Returns the parentId
+     *
+     * @return string $parentId
+     */
+    public function getParentId()
+    {
+        return $this->parentId;
+    }
+
+    /**
+     * Sets the parentName
+     *
+     * @param string $parentId
+     * @return void
+     */
+    public function setParentId($parentId)
+    {
+        $this->parentId = $parentId;
+    }
+
+    /**
+     * Returns the parentName
+     *
+     * @return string $parentName
+     */
+    public function getParentName()
+    {
+        return $this->parentName;
+    }
+
+    /**
+     * Sets the parentName
+     *
+     * @param string $parentName
+     * @return void
+     */
+    public function setParentName($parentName)
+    {
+        $this->parentName = $parentName;
+    }
+
+    /**
+     * Returns the parentSubdomain
+     *
+     * @return string $parentSubdomain
+     */
+    public function getParentSubdomain()
+    {
+        return $this->parentSubdomain;
+    }
+
+    /**
+     * Sets the parentSubdomain
+     *
+     * @param string $parentSubdomain
+     * @return void
+     */
+    public function setParentSubdomain($parentSubdomain)
+    {
+        $this->parentSubdomain = $parentSubdomain;
+    }
+}

+ 86 - 0
ot_templating/Classes/Domain/Repository/BaseApiRepository.php

@@ -0,0 +1,86 @@
+<?php
+
+namespace Opentalent\OtTemplating\Domain\Repository;
+
+use GuzzleHttp\Client;
+use Psr\Http\Message\ResponseInterface;
+use TYPO3\CMS\Extbase\Persistence\Repository;
+
+class BaseApiRepository extends Repository
+{
+    const BASE_URI = 'http://api.opentalent.fr/api/';
+    const HYDRA_TYPE = '';
+    const HTTP_METHOD = 'GET';
+    const ITEMS_PER_PAGE = 1001;
+
+    private $client;
+
+    public function __construct(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
+        parent::__construct($objectManager);
+        $this->client = new Client(['base_uri' => static::BASE_URI]);
+    }
+
+    /**
+     * @param $uri
+     * @param $params
+     * @return ResponseInterface
+     */
+    protected function get($uri, $params = [])
+    {
+        $uri = $uri . '?_format=json&itemsPerPage=' . (string)self::ITEMS_PER_PAGE . '';
+        if (!empty($params)) {
+            $uri = $uri . '&' . http_build_query($params);
+        }
+        return $this->client->request(static::HTTP_METHOD, $uri);
+    }
+
+    /**
+     * @param string $uri
+     * @param array $params
+     * @return string
+     */
+    protected function getBody($uri, $params = [])
+    {
+        return (string)$this->get($uri, $params)->getBody();
+    }
+
+    /**
+     * @param string $uri
+     * @param array $params
+     * @return array
+     */
+    protected function getJson($uri, $params = [])
+    {
+        return json_decode($this->getBody($uri, $params));
+    }
+
+    /**
+     * @param string $uri
+     * @param array $params
+     * @return array
+     * @throws \Exception
+     */
+    protected function getApiRecords($uri, $params = []) {
+        $data = $this->getJson($uri, $params);
+
+        if($data->{'@type'} == 'hydra:PagedCollection') {
+            $records = $data->{'hydra:member'};
+        } else if ($data->{'@type'} == $this::HYDRA_TYPE) {
+            $records = [$data];
+        } else {
+            throw new \Exception('Invalid API reponse');
+        }
+        return $records;
+    }
+
+    /**
+     * @param string $uri
+     * @param array $params
+     * @return array
+     * @throws \Exception
+     */
+    protected function getApiFirstRecord($uri, $params = []) {
+        $records = $this->getApiRecords($uri, $params);
+        return $records[0];
+    }
+}

+ 69 - 0
ot_templating/Classes/Domain/Repository/DonorRepository.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace Opentalent\OtTemplating\Domain\Repository;
+
+use Opentalent\OtTemplating\Domain\Model\Donor;
+
+class DonorRepository extends BaseApiRepository
+{
+    CONST URI = BaseApiRepository::BASE_URI . 'public/donors';
+    const HYDRA_TYPE = 'PortailDonor';
+
+    private function donorFromJson($record) {
+        if ($record->{'@type'} != $this::HYDRA_TYPE) {
+            return null;
+        }
+        $donor = new Donor();
+        $donor->setId(end(explode('/', $record->{'@id'})));
+        $donor->setOrganizationId($record->{'organizationId'});
+        $donor->setName($record->{'name'});
+        $donor->setEmail($record->{'email'});
+        $donor->setTelphone($record->{'telphone'});
+        $donor->setWebsite($record->{'website'});
+        $donor->setWording($record->{'wording'});
+        $donor->setDisplayedOn($record->{'displayedOn'});
+        $donor->setLogo($record->{'logo'});
+
+        return $donor;
+    }
+
+    private function donorsFromJson($records) {
+        $donors = [];
+        foreach ($records as $record) {
+            $donors[] = $this->donorFromJson($record);
+        }
+        return $donors;
+    }
+
+    /**
+     * Get the donors of the organization
+     *
+     * @param int $organizationId The id of the organization
+     * @return array              Donors
+     * @throws \Exception
+     */
+    public function findByOrganizationId(int $organizationId) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->donorsFromJson($records);
+    }
+
+    /**
+     * Get the donors of the organization's parents
+     *
+     * @param int $organizationId The id of the organization
+     * @return array              Donors
+     * @throws \Exception
+     */
+    public function findParentsByOrganizationId(int $organizationId) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+        $params['parent'] = 1;
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->donorsFromJson($records);
+    }
+
+}

+ 185 - 0
ot_templating/Classes/Domain/Repository/EventRepository.php

@@ -0,0 +1,185 @@
+<?php
+
+namespace Opentalent\OtTemplating\Domain\Repository;
+
+use Opentalent\OtTemplating\Domain\Model\Event;
+
+class EventRepository extends BaseApiRepository
+{
+    CONST URI = BaseApiRepository::BASE_URI . 'public/events';
+    const HYDRA_TYPE = 'PortailEvent';
+
+    private function eventFromJson($record) {
+        if ($record->{'@type'} != $this::HYDRA_TYPE) {
+            return null;
+        }
+        $event = new Event();
+        $event->setId(end(explode('/', $record->{'@id'})));
+        $event->setOrganizationId($record->{'organizationId'});
+        $event->setSubdomain($record->{'subDomain'});
+        $event->setName($record->{'name'});
+        $event->setDescription($record->{'description'});
+        $event->setUrl($record->{'url'});
+        $event->setRule($record->{'rule'});
+        $event->setDatetimeStart(new \DateTime($record->{'datetimeStart'}));
+        $event->setDatetimeEnd(new \DateTime($record->{'datetimeEnd'}));
+        $event->setDates($record->{'dates'});
+        $event->setPlacename($record->{'placeName'});
+        $event->setPlaceDescription($record->{'placeDescription'});
+        $event->setPlaceFloorSize($record->{'placeFloorSize'});
+        $event->setPlaceCapacity($record->{'placeCapacity'});
+        $event->setCity($record->{'city'});
+        $event->setPostalCode($record->{'postalCode'});
+        $event->setStreetAddress($record->{'streetAddress'});
+        $event->setLongitude($record->{'longitude'});
+        $event->setLatitude($record->{'latitude'});
+        $event->setRoomName($record->{'roomName'});
+        $event->setRoomDescription($record->{'roomDescription'});
+        $event->setRoomLocalisation($record->{'roomLocalisation'});
+        $event->setRoomCapacity($record->{'roomCapacity'});
+        $event->setRoomFloorSize($record->{'roomFloorSize'});
+        $event->setZupId($record->{'zupId'});
+        $event->setDeepLink($record->{'deepLink'});
+        $event->setImage($record->{'image'});
+        $event->setPriceMini($record->{'priceMini'});
+        $event->setMeetingSchedule($record->{'meetingSchedule'});
+        $event->setApi($record->{'api'});
+        $event->setParentName($record->{'parentName'});
+        $event->setParentSubdomain($record->{'parentSubDomain'});
+        return $event;
+    }
+
+    private function eventsFromJson($records) {
+        $events = [];
+        foreach ($records as $record) {
+            $events[] = $this->eventFromJson($record);
+        }
+        return $events;
+    }
+
+    /**
+     * Get the event matching the given id
+     *
+     * @param int $id The id of the event
+     * @return Event         Event
+     * @throws \Exception
+     */
+    public function findById($id) {
+        $params = [];
+        $record = $this->getApiFirstRecord($this::URI . '/' . $id);
+        return $this->eventFromJson($record);
+    }
+
+    /**
+     * Get the events of the organization
+     *
+     * @param int $organizationId The id of the organization
+     * @param \Datetime $fromDate Only return events with ending date posterior or equal to this date (leave null for disable the filter)
+     * @param \Datetime $toDate Only return events with starting date anterior or equal to this date (leave null for disable the filter)
+     * @param int $limit Limit the number of results returned (-1 to disable the limitation)
+     * @return array                        Events
+     * @throws \Exception
+     */
+    public function findByOrganizationId(int $organizationId, $fromDate = null, $toDate = null, $limit = -1) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+
+        if ($limit > 0) {
+            $params['itemsPerPage'] = $limit;
+        }
+        if ($fromDate !== null) {
+            // Inutile a priori: la view de l'API s'en occupe déjà en amont
+            $params['filter[where][datetimeEnd][gte]'] = $fromDate->format('c');
+        }
+        if ($toDate !== null) {
+            $params['filter[where][datetimeStart][lte]'] = $toDate->format('c');
+        }
+        $params['filter[order][0][datetimeEnd]'] = 'ASC';
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->eventsFromJson($records);
+    }
+
+    /**
+     * Get the events of the organization's parents
+     *
+     * @param int $organizationId The id of the organization
+     * @param \Datetime $fromDate Only return events with ending date posterior or equal to this date (leave null for disable the filter)
+     * @param \Datetime $toDate Only return events with starting date anterior or equal to this date (leave null for disable the filter)
+     * @param int $limit Limit the number of results returned (-1 to disable the limitation)
+     * @return array                        Events
+     * @throws \Exception
+     */
+    public function findParentsByOrganizationId(int $organizationId, $fromDate = null, $toDate = null, $limit = -1) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+
+        if ($limit > 0) {
+            $params['itemsPerPage'] = $limit;
+        }
+        if ($fromDate !== null) {
+            // Inutile a priori: la view de l'API s'en occupe déjà en amont
+            $params['filter[where][datetimeEnd][gte]'] = $fromDate->format('c');
+        }
+        if ($toDate !== null) {
+            $params['filter[where][datetimeStart][lte]'] = $toDate->format('c');
+        }
+        $params['filter[order][0][datetimeStart]'] = 'ASC';
+
+        $params['parent'] = '1';
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->eventsFromJson($records);
+    }
+
+    /**
+     * Get the events of the organization's parents
+     *
+     * @param int $organizationId The id of the organization
+     * @param \Datetime $fromDate Only return events with ending date posterior or equal to this date (leave null for disable the filter)
+     * @param \Datetime $toDate Only return events with starting date anterior or equal to this date (leave null for disable the filter)
+     * @param int $limit Limit the number of results returned (-1 to disable the limitation)
+     * @return array                        Events
+     * @throws \Exception
+     */
+    public function findChildrenByOrganizationId(int $organizationId, $fromDate = null, $toDate = null, $limit = -1) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+
+        if ($limit > 0) {
+            $params['itemsPerPage'] = $limit;
+        }
+        if ($fromDate !== null) {
+            // Inutile a priori: la view de l'API s'en occupe déjà en amont
+            $params['filter[where][datetimeEnd][gte]'] = $fromDate->format('c');
+        }
+        if ($toDate !== null) {
+            $params['filter[where][datetimeStart][lte]'] = $toDate->format('c');
+        }
+        $params['filter[order][0][datetimeStart]'] = 'ASC';
+
+        $params['children'] = '1';
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->eventsFromJson($records);
+    }
+
+    /**
+     * Get the events of the organization
+     *
+     * @param int $organizationId The id of the organization
+     * @param array $searchParams Search arguments
+     * @return array                        Events
+     * @throws \Exception
+     */
+    public function searchBy(int $organizationId, $searchParams = []) {
+        $params = [];
+        $params['organizationId'] = $organizationId;
+        $params['filter[order][0][datetimeEnd]'] = 'ASC';
+        $params = array_merge($params, $searchParams);
+
+        $records = $this->getApiRecords($this::URI, $params);
+        return $this->eventsFromJson($records);
+    }
+
+}

+ 73 - 0
ot_templating/Classes/Domain/Repository/MemberRepository.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace Opentalent\OtTemplating\Domain\Repository;
+
+use Opentalent\OtTemplating\Domain\Model\Member;
+
+class MemberRepository extends BaseApiRepository
+{
+    CONST URI = BaseApiRepository::BASE_URI . '/public/members';
+    CONST URI_CA = BaseApiRepository::BASE_URI . '/public/members_ca';
+    const HYDRA_TYPE = 'PortailMemberBySpeciality';
+    const HYDRA_TYPE_CA = 'PortailMemberByRole';
+
+    private function memberFromJson($record) {
+        if ($record->{'@type'} != $this::HYDRA_TYPE &&
+            $record->{'@type'} != $this::HYDRA_TYPE_CA) {
+            return null;
+        }
+        $member = new Member();
+        $member->setId(end(explode('/', $record->{'@id'})));
+        $member->setOrganizationId((int)$record->{'organizationId'});
+        $member->setGender($record->{'gender'});
+        $member->setGivenName($record->{'givenName'});
+        $member->setName($record->{'name'});
+        $member->setStartDate(new \DateTime($record->{'startDate'}));
+        $member->setEndDate(new \DateTime($record->{'endDate'}));
+        $member->setInstrumentGroup($record->{'instrumentGroup'});
+        $member->setInstrument($record->{'instrument'});
+        $member->setMission($record->{'mission'});
+        $member->setPersonId((int)$record->{'personId'});
+        $member->setImage($record->{'image'});
+        $member->setAdressCity($record->{'addressCity'});
+        $member->setStreetAdress($record->{'streetAddress'});
+        $member->setStreetAdressSecond($record->{'streetAddressSecond'});
+        $member->setStreetAdressThird($record->{'streetAddressThird'});
+        $member->setPostalCode($record->{'postalCode'});
+        $member->setTelphone($record->{'telphone'});
+        $member->setMobilPhone($record->{'mobilPhone'});
+        $member->setEmail($record->{'email'});
+
+        return $member;
+    }
+
+    private function membersFromJson($records) {
+        $members = [];
+        foreach ($records as $record) {
+            $members[] = $this->memberFromJson($record);
+        }
+        return $members;
+    }
+
+    /**
+     * Get the members of the organization
+     * If $only_ca is true, returns only the members onf the CA
+     *
+     * @param int $organizationId The id of the organization
+     * @return array              Members
+     * @throws \Exception
+     */
+    public function findByOrganizationId(int $organizationId, bool $only_ca = false) {
+        $params = [];
+        $params['filter[where][organizationId]'] = $organizationId;
+
+        if ($only_ca) {
+            $records = $this->getApiRecords($this::URI_CA, $params);
+        } else {
+            $records = $this->getApiRecords($this::URI, $params);
+        }
+
+        return $this->membersFromJson($records);
+    }
+
+}

+ 82 - 0
ot_templating/Classes/Domain/Repository/OrganizationRepository.php

@@ -0,0 +1,82 @@
+<?php
+
+namespace Opentalent\OtTemplating\Domain\Repository;
+
+use Opentalent\OtTemplating\Domain\Model\Organization;
+
+class OrganizationRepository extends BaseApiRepository
+{
+    CONST URI = BaseApiRepository::BASE_URI . 'public/organizations';
+    const HYDRA_TYPE = 'PortailOrganization';
+
+    private function organizationFromJson($record) {
+        if ($record->{'@type'} != $this::HYDRA_TYPE) {
+            return null;
+        }
+        $organization = new Organization();
+        // TODO: intégrer l'id à la réponse de l'API pour éviter le parsing
+        $array = explode('/', $record->{'@id'});
+        $organization->setId(end($array));
+        $organization->setSubdomain($record->{'subDomain'});
+        $organization->setName($record->{'name'});
+        $organization->setSlug($record->{'slug'});
+        $organization->setPrincipalType($record->{'principalType'});
+        $organization->setDescription($record->{'description'});
+        $organization->setCategories($record->{'categories'});
+        $organization->setAddressCity($record->{'addressCity'});
+        $organization->setPostalCode($record->{'postalCode'});
+        $organization->setStreetAdress($record->{'streetAddress'});
+        $organization->setLatitude($record->{'latitude'});
+        $organization->setLongitude($record->{'longitude'});
+        $organization->setCountry($record->{'country'});
+        $organization->setLogo($record->{'logo'});
+        $organization->setParentId($record->{'parentId'});
+        $organization->setParentName($record->{'parentName'});
+        $organization->setParentSubdomain($record->{'parentSubDomain'});
+        return $organization;
+    }
+
+    private function organizationsFromJson($records) {
+        $organizations = [];
+        foreach ($records as $record) {
+            $organizations[] = $this->organizationFromJson($record);
+        }
+        return $organizations;
+    }
+
+    /**
+     * Get the organization by Id
+     *
+     * @param int $id The id of the organization
+     * @return Organization
+     * @throws \Exception
+     */
+    public function findById($id) {
+        $record = $this->getApiFirstRecord($this::URI . '/' . $id);
+        $organization = $this->organizationFromJson($record);
+        if($organization == null) {
+            throw new \Exception('Organization with id ' . $id . ' does not exist');
+        }
+        return $organization;
+    }
+
+    /**
+     * Get the organization by name
+     *
+     * @param string name          The name of the organization
+     * @return Organization
+     * @throws \Exception
+     */
+    public function findByName($name)
+    {
+        $params = [];
+        $params['filter[where][name]'] = $name;
+        $data = $this->getApiFirstRecord($this::URI, $params);
+        $organization = $this->organizationFromJson($data);
+        if($organization == null) {
+            throw new \Exception('Organization with name "' . $name . '" does not exist');
+        }
+        return $organization;
+    }
+
+}

+ 1 - 1
ot_templating/Configuration/TypoScript/constants.txt

@@ -12,7 +12,7 @@ plugin.tx_ottemplating {
     settings {
         opentalent {
             website = https://opentalent.fr
-            logoPath = EXT:ot_templating/Resources/Public/assets/media/logo-opentalent.png
+            logoPath = EXT:ot_templating/Resources/Public/media/logo-opentalent.png
             fileStorageUrl = https://api.opentalent.fr/app.php/_internal/secure/files/
             dashboardUrl = https://admin.opentalent.fr/#/dashboard
             logoutUrl = .

+ 10 - 7
ot_templating/Configuration/TypoScript/setup.txt

@@ -51,16 +51,16 @@ config.compressJs = 1
 lib.allEvents = USER
 lib.allEvents {
     userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
-    extensionName = OtWidgets
+    extensionName = OtTemplating
     pluginName = AllEvents
     vendorName = Opentalent
-    settings < plugin.tx_otwidgets_allevents.settings
+    settings < plugin.tx_ottemplating_allevents.settings
 }
 
 lib.members = USER
 lib.members {
     userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
-    extensionName = OtWidgets
+    extensionName = OtTemplating
     pluginName = Members
     vendorName = Opentalent
     controller = Member
@@ -70,13 +70,13 @@ lib.members {
             1 = getMembers
         }
     }
-    settings < plugin.tx_otwidgets_members.settings
+    settings < plugin.tx_ottemplating_members.settings
 }
 
 lib.members_ca = USER
 lib.members_ca {
     userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
-    extensionName = OtWidgets
+    extensionName = OtTemplating
     pluginName = Members
     vendorName = Opentalent
     controller = Member
@@ -86,7 +86,7 @@ lib.members_ca {
             1 = getMembersCa
         }
     }
-    settings < plugin.tx_otwidgets_members.settings
+    settings < plugin.tx_ottemplating_members.settings
 }
 
 lib.auth = USER
@@ -135,7 +135,6 @@ plugin.tx_ottemplating {
         layoutRootPaths.0 = {$layoutRootPath}
     }
     settings {
-        # constantsnpm install -g node-sass
         opentalentWebsite = {$plugin.tx_ottemplating.settings.opentalent.website}
         opentalentLogoPath = {$plugin.tx_ottemplating.settings.opentalent.logoPath}
         opentalentFileStorageUrl = {$plugin.tx_ottemplating.settings.opentalent.fileStorageUrl}
@@ -150,6 +149,10 @@ plugin.tx_ottemplating {
         networkName = {$plugin.tx_ottemplating.settings.network.name}
         networkUrl = {$plugin.tx_ottemplating.settings.network.url}
 
+        # aliases
+        organizationId = {$plugin.tx_ottemplating.settings.organization.id}
+        organizationIsNetwork = {$plugin.tx_ottemplating.settings.organization.is_network}
+
         # computed
         structureLogoUrl = {$plugin.tx_ottemplating.settings.opentalent.fileStorageUrl}{$plugin.tx_ottemplating.settings.organization.logoid}/0x60
         networkLogoUrl = /typo3conf/ext/ot_templating/Resources/Public/media/{$plugin.tx_ottemplating.settings.network.logo}

+ 2 - 2
ot_templating/Readme.md

@@ -15,7 +15,7 @@ ainsi que la configuration Typo3, les assets, et les layouts HTML.
 
 ## Comment installer
 
-**Menu Extensions**:  Commencer par s'assurer que les extensions ot_templating et ot_widgets sont activées
+**Menu Extensions**:  Commencer par s'assurer que les extensions ot_templating et ot_connect sont activées
 
 **Menu Page**: Pour créer un nouveau site, créer une page, l'éditer et la déclarer page racine (onglet Comportement). Enregistrer, et quitter.
 
@@ -26,7 +26,7 @@ Editer le gabarit, aller à la page 'Inclusions' et inclure les extensions suiva
 * Fluid Content Elements CSS (optional) (fluid_styled_content)
 * Flux PAGE rendering (flux)
 * Templating (ot_templating)
-* Widgets (ot_widgets)
+* Connect (ot_connect)
 
 Enregistrer, et quitter.
 

+ 1212 - 1
ot_templating/Resources/Private/Language/locallang.xlf

@@ -6,7 +6,1218 @@
 			<trans-unit id="log-out">
 				<source>Se déconnecter</source>
 			</trans-unit>
-
+			<trans-unit id="member.role.PRESIDENT" xml:space="preserve">
+			<source>Président.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.ACTIVE_MEMBER_OF_THE_CA" xml:space="preserve">
+			<source>Membre actif du CA</source>
+			</trans-unit>
+			<trans-unit id="member.role.YOUTH_REPRESENTATIVE" xml:space="preserve">
+			<source>Représentant des jeunes</source>
+			</trans-unit>
+			<trans-unit id="member.role.SECRETARY" xml:space="preserve">
+			<source>Secrétaire</source>
+			</trans-unit>
+			<trans-unit id="member.role.ASSISTANT_SECRETARY" xml:space="preserve">
+			<source>Secrétaire adjoint.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.TREASURER" xml:space="preserve">
+			<source>Trésorier.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.TREASURER_ASSISTANT" xml:space="preserve">
+			<source>Trésorier.e adjoint.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.VICE_PRESIDENT" xml:space="preserve">
+			<source>Vice président.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.MEMBER" xml:space="preserve">
+			<source>Adhérent.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.NOT_A_MEMBER" xml:space="preserve">
+			<source>Non membre</source>
+			</trans-unit>
+			<trans-unit id="member.role.VICE_PRESIDENT_OF_HONOR" xml:space="preserve">
+			<source>Vice président.e d'honneur</source>
+			</trans-unit>
+			<trans-unit id="member.role.HOUR_PRESIDENT" xml:space="preserve">
+			<source>Président.e honoraire</source>
+			</trans-unit>
+			<trans-unit id="member.role.HONORARY_PRESIDENT" xml:space="preserve">
+			<source>Président.e d'honneur</source>
+			</trans-unit>
+			<trans-unit id="member.role.PRESIDENT_ASSISTANT" xml:space="preserve">
+			<source>Président.e adjoint.e</source>
+			</trans-unit>
+			<trans-unit id="member.role.ACTIVE_SUBSTITUTE_MEMBER_OF_THE_CA" xml:space="preserve">
+			<source>Membre actif du CA suppléant</source>
+			</trans-unit>
+			<trans-unit id="member.role.ACTIVE_COOPTED_MEMBER_OF_THE_CA" xml:space="preserve">
+			<source>Membre actif du CA coopté</source>
+			</trans-unit>
+			<trans-unit id="member.role.MEMBER_OF_THE_BOARD" xml:space="preserve">
+			<source>Membre du bureau</source>
+			</trans-unit>
+			<trans-unit id="member.role.BOARD_MEMBER" xml:space="preserve">
+			<source>Membre du bureau</source>
+			</trans-unit>
+			<trans-unit id="member.role.MEMBER_OF_BOARD_OF_HONOR" xml:space="preserve">
+			<source>Membre d'Honneur du CA</source>
+			</trans-unit>
+			<trans-unit id="member.role.HONORARY_MEMBER" xml:space="preserve">
+			<source>Membre d'Honneur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NO_DETAIL" xml:space="preserve">
+			<source>pas de détail</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ACCORDION" xml:space="preserve">
+			<source>accordéon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASSOON" xml:space="preserve">
+			<source>basson</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BUGLE" xml:space="preserve">
+			<source>bugle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CLARINET" xml:space="preserve">
+			<source>clarinette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_WIND" xml:space="preserve">
+			<source>contrebasse à vent</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONTRABASSOON" xml:space="preserve">
+			<source>contrebasson</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ENGLISH_HORN" xml:space="preserve">
+			<source>cor anglais</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASSET_HORN" xml:space="preserve">
+			<source>cor de basset</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HUNTING_HORN" xml:space="preserve">
+			<source>cor de chasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALPHORN" xml:space="preserve">
+			<source>cor des alpes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FRENCH_HORN" xml:space="preserve">
+			<source>cor d'harmonie</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CORNET_PISTONS" xml:space="preserve">
+			<source>cornet a pistons</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.EUPHONIUM" xml:space="preserve">
+			<source>euphonium</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLUTE" xml:space="preserve">
+			<source>flûte</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLUTE_A_BEC" xml:space="preserve">
+			<source>flûte a bec</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLUTE_TRAVERSIERE" xml:space="preserve">
+			<source>flûte traversière</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARMONIUM_ORGAN" xml:space="preserve">
+			<source>harmonium (orgue)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OBOE" xml:space="preserve">
+			<source>hautbois</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HELICON" xml:space="preserve">
+			<source>hélicon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PICCOLO" xml:space="preserve">
+			<source>piccolo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXOPHONE" xml:space="preserve">
+			<source>saxophone soprano</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TENOR_SAXOPHONE" xml:space="preserve">
+			<source>saxophone ténor</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALTO_SAXOPHONE" xml:space="preserve">
+			<source>saxophone alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BARITONE_SAXOPHONE" xml:space="preserve">
+			<source>saxophone baryton</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SOUSAPHONE" xml:space="preserve">
+			<source>soubassophone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TROMBONE" xml:space="preserve">
+			<source>trombone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TRUMPET" xml:space="preserve">
+			<source>trompette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TUBA" xml:space="preserve">
+			<source>tuba</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXHORN" xml:space="preserve">
+			<source>saxhorn</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PERCUSSION" xml:space="preserve">
+			<source>percussion</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BATTERY" xml:space="preserve">
+			<source>batterie</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OTHER_ACTIVITY" xml:space="preserve">
+			<source>autre activité</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_CLARINET" xml:space="preserve">
+			<source>clarinette basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALTO_CLARINET" xml:space="preserve">
+			<source>clarinette alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PICCOLO_CLARINET" xml:space="preserve">
+			<source>clarinette piccolo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_FLUTE" xml:space="preserve">
+			<source>flûte traversière basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALTO_FLUTE" xml:space="preserve">
+			<source>flûte bec alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SOPRANINO_RECORDER_FLUTE" xml:space="preserve">
+			<source>flûte bec sopranino</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SOPRANO_FLUTE" xml:space="preserve">
+			<source>flûte bec soprano</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OCTOBASS_FLUTE" xml:space="preserve">
+			<source>flûte octobasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PAN_FLUTE" xml:space="preserve">
+			<source>flûte pan</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLUTE_PICCOLO" xml:space="preserve">
+			<source>flûte piccolo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SHAKUHACHI_FLUTE" xml:space="preserve">
+			<source>flûte shakuhachi</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SARRUSOPHONE" xml:space="preserve">
+			<source>sarrusophone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ELECTRIC_ORGAN" xml:space="preserve">
+			<source>orgue électrique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PIANO" xml:space="preserve">
+			<source>piano</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARPSICHORD" xml:space="preserve">
+			<source>clavecin</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ORGAN" xml:space="preserve">
+			<source>orgue</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALTO_HAS_STRINGS" xml:space="preserve">
+			<source>alto a cordes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_HAS_STRINGS" xml:space="preserve">
+			<source>contrebasse a cordes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VIOLIN" xml:space="preserve">
+			<source>violon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CELLO" xml:space="preserve">
+			<source>violoncelle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GUITAR" xml:space="preserve">
+			<source>guitare</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_GUITAR" xml:space="preserve">
+			<source>guitare basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ELECTRIC_GUITAR" xml:space="preserve">
+			<source>guitare électrique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARP" xml:space="preserve">
+			<source>harpe</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CELTIC_HARP" xml:space="preserve">
+			<source>harpe celtique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NATURAL_BUGLE" xml:space="preserve">
+			<source>bugle naturel</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LOW_BUGLE" xml:space="preserve">
+			<source>clairon basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NATURAL_HORN" xml:space="preserve">
+			<source>cor naturel</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXHORN_ALTO" xml:space="preserve">
+			<source>saxhorn alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXHORN_BARITONE" xml:space="preserve">
+			<source>saxhorn baryton</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LOW_SAXHORN" xml:space="preserve">
+			<source>saxhorn basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXHORN_BASS" xml:space="preserve">
+			<source>saxhorn contrebasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXHORN_TENOR" xml:space="preserve">
+			<source>saxhorn ténor</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LOW_SAXOPHONE" xml:space="preserve">
+			<source>saxophone basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_SAXOPHONE" xml:space="preserve">
+			<source>saxophone contrebasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TROMBONE_ALTO" xml:space="preserve">
+			<source>trombone alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_TROMBONE" xml:space="preserve">
+			<source>trombone basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TROMPE" xml:space="preserve">
+			<source>trompe</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LOW_TRUMPET" xml:space="preserve">
+			<source>trompette basse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CAVALRY_TRUMPET" xml:space="preserve">
+			<source>trompette de cavalerie</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PICCOLO_TRUMPET" xml:space="preserve">
+			<source>trompette piccolo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TUBA_BASS" xml:space="preserve">
+			<source>tuba contrebasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TENOR_TUBA" xml:space="preserve">
+			<source>tuba ténor</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BAGPIPE" xml:space="preserve">
+			<source>cornemuse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARMONICA" xml:space="preserve">
+			<source>harmonica</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SYNTHESIZER" xml:space="preserve">
+			<source>synthétiseur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CLEAR_FUND" xml:space="preserve">
+			<source>caisse-claire</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BELL_A_COW" xml:space="preserve">
+			<source>cloche-a-vache</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONGA" xml:space="preserve">
+			<source>conga</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HIT_CYMBALS" xml:space="preserve">
+			<source>cymbales frappées</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SUSPENDED_CYMBALS" xml:space="preserve">
+			<source>cymbales suspendues</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GLOCKENSPIEL" xml:space="preserve">
+			<source>glockenspiel</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MARIMBA" xml:space="preserve">
+			<source>marimba</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DRUM" xml:space="preserve">
+			<source>tambour</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TIMPANI" xml:space="preserve">
+			<source>timbales</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VIBRAPHONE" xml:space="preserve">
+			<source>vibraphone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.XYLOPHONE" xml:space="preserve">
+			<source>xylophone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.POCKET_TRUMPET" xml:space="preserve">
+			<source>trompette de poche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MANDOCELLO" xml:space="preserve">
+			<source>mandoloncelle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MANDOLE" xml:space="preserve">
+			<source>mandole</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MANDOLIN" xml:space="preserve">
+			<source>mandoline</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ALTO_VOICE" xml:space="preserve">
+			<source>contralto (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SOPRANO_VOICE" xml:space="preserve">
+			<source>soprano (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_VOICE" xml:space="preserve">
+			<source>basse (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TENOR_VOICE" xml:space="preserve">
+			<source>ténor (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MEZZO_SOPRANO_VOICE" xml:space="preserve">
+			<source>mezzo soprano (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BEARER" xml:space="preserve">
+			<source>porte-drapeau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_DRUM" xml:space="preserve">
+			<source>grosse caisse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BIG_PARADE_FUND" xml:space="preserve">
+			<source>grosse caisse de défilé</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBAL_CRASH" xml:space="preserve">
+			<source>cymbale crash</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBAL_RIDE" xml:space="preserve">
+			<source>cymbale ride</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBAL_SPLASH" xml:space="preserve">
+			<source>cymbale splash</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBAL_CHINA" xml:space="preserve">
+			<source>cymbale china</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GONG" xml:space="preserve">
+			<source>gong</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TAMBOURINE" xml:space="preserve">
+			<source>tambourin</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASQUE_DRUM" xml:space="preserve">
+			<source>tambour de basque</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ANVIL" xml:space="preserve">
+			<source>enclume</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ORCHESTRA_BELLS" xml:space="preserve">
+			<source>cloches d'orchestre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHIME" xml:space="preserve">
+			<source>carillon tubulaire</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TUBULAR_BELL" xml:space="preserve">
+			<source>cloche tubulaire</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WHISTLE" xml:space="preserve">
+			<source>sifflet</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAMBA_WHISTLE" xml:space="preserve">
+			<source>sifflet samba</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WHIP" xml:space="preserve">
+			<source>fouet</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GUIRO" xml:space="preserve">
+			<source>guiro</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TEMPLEBLOCK" xml:space="preserve">
+			<source>templeblock</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SHAKER" xml:space="preserve">
+			<source>shaker</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GUIRO_SHAKER" xml:space="preserve">
+			<source>guiro/shaker</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TRIANGLE" xml:space="preserve">
+			<source>triangle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.POLYBLOCK" xml:space="preserve">
+			<source>polyblock</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TAM_TAM" xml:space="preserve">
+			<source>tam tam</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RAINMAKER" xml:space="preserve">
+			<source>bâton de pluie</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TREE_HAS_BELLS" xml:space="preserve">
+			<source>arbre a clochettes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CLAVES" xml:space="preserve">
+			<source>claves</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WOOD_BLOCK" xml:space="preserve">
+			<source>wood-block</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BELLS" xml:space="preserve">
+			<source>grelots</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_DRUM_CONCERT" xml:space="preserve">
+			<source>grosse caisse de concert</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BONGOS" xml:space="preserve">
+			<source>bongos</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ROTOTOM" xml:space="preserve">
+			<source>rototom</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MARACAS" xml:space="preserve">
+			<source>maracas</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RATTLE" xml:space="preserve">
+			<source>crécelle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MERMAID" xml:space="preserve">
+			<source>sirène</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.JAZZO_FLUTE" xml:space="preserve">
+			<source>jazzo-flûte</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DJEMBE" xml:space="preserve">
+			<source>djembé</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DIDGERIDOO" xml:space="preserve">
+			<source>didjéridoo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OPHICLEIDE" xml:space="preserve">
+			<source>ophicléïde</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.M?LOPHONIUM" xml:space="preserve">
+			<source>mélophonium</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CABASSA" xml:space="preserve">
+			<source>cabassa</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SAXOPHONE_SOPRANINO" xml:space="preserve">
+			<source>saxophone sopranino</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WIND_SHIMES" xml:space="preserve">
+			<source>wind shimes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHIMES" xml:space="preserve">
+			<source>chimes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BAR_CHIMES" xml:space="preserve">
+			<source>bar chimes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RIVER" xml:space="preserve">
+			<source>rivière</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBALLETTES" xml:space="preserve">
+			<source>cymballettes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CASTANETS" xml:space="preserve">
+			<source>castagnettes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BANDON?ON" xml:space="preserve">
+			<source>bandonéon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BANJO" xml:space="preserve">
+			<source>banjo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASSOON_FRENCH" xml:space="preserve">
+			<source>basson français</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GERMAN_BASSOON" xml:space="preserve">
+			<source>basson allemand</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FAGOTT" xml:space="preserve">
+			<source>fagott</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COR_DUAL_HARMONY" xml:space="preserve">
+			<source>cor d'harmonie double</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COR_TRIPLE_HARMONY" xml:space="preserve">
+			<source>cor d'harmonie triple</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SURDO" xml:space="preserve">
+			<source>surdo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COLORATURA_SOPRANO_VOICE" xml:space="preserve">
+			<source>soprano colorature (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DRAMATIC_SOPRANO_VOICE" xml:space="preserve">
+			<source>soprano dramatique (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SOPRANO_CHILD_VOICE" xml:space="preserve">
+			<source>soprano enfant (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_BARITONE_VOICE" xml:space="preserve">
+			<source>baryton basse (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HAUTE_AGAINST_VOICE" xml:space="preserve">
+			<source>haute contre (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MIXED_VOICES_VOICE" xml:space="preserve">
+			<source>voix mixte (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SPOKEN_CHILD_ACTOR_VOICES_VOICE" xml:space="preserve">
+			<source>voix parlée acteur enfant (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VOICES_SPOKEN_WOMAN_ACTOR_VOICE" xml:space="preserve">
+			<source>voix parlée acteur femme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SPOKEN_MAN_ACTOR_VOICES_VOICE" xml:space="preserve">
+			<source>voix parlée acteur homme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WOMAN_NARRATOR_VOICE" xml:space="preserve">
+			<source>récitant femme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NARRATOR_MAN_VOICE" xml:space="preserve">
+			<source>récitant homme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHILDREN_VOICES_VOICE" xml:space="preserve">
+			<source>voix enfant (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VOICE_WIFE_VOICE" xml:space="preserve">
+			<source>voix femme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HUMAN_VOICES_VOICE" xml:space="preserve">
+			<source>voix homme (voix)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLUTE_VIOLA" xml:space="preserve">
+			<source>flûte traversière alto</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MAO_ASSIT?E_COMPUTER_MUSIC" xml:space="preserve">
+			<source>mao musique assitée par ordinateur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OLD" xml:space="preserve">
+			<source>vielle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WASHBOARD" xml:space="preserve">
+			<source>washboard</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HORN_HAS_PISTONS" xml:space="preserve">
+			<source>cornet a pistons</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CIRCASSIAN" xml:space="preserve">
+			<source>circassien</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COMEDIAN" xml:space="preserve">
+			<source>comédien</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DANCER" xml:space="preserve">
+			<source>danseur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONSOLE" xml:space="preserve">
+			<source>pupitre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PODIUMS" xml:space="preserve">
+			<source>podiums</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DESK_LAMP" xml:space="preserve">
+			<source>lampe de pupitre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLIGHT_CASE" xml:space="preserve">
+			<source>flight case</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MIXER" xml:space="preserve">
+			<source>mélangeur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MICROPHONE" xml:space="preserve">
+			<source>microphone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PLAYERS_RECORDER" xml:space="preserve">
+			<source>lecteurs/enregistreur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WIRELESS_MICROPHONES" xml:space="preserve">
+			<source>microphones sans fil</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BAGS_SUITCASES" xml:space="preserve">
+			<source>sacs/valises</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FOOD" xml:space="preserve">
+			<source>alimentation</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PREGNANT" xml:space="preserve">
+			<source>enceinte</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONNECTORS" xml:space="preserve">
+			<source>connectique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MEMORY" xml:space="preserve">
+			<source>mémoire</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.AMPLIFIER" xml:space="preserve">
+			<source>amplificateur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CAMERA" xml:space="preserve">
+			<source>camera</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SCREEN" xml:space="preserve">
+			<source>ecran</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STABILIZER" xml:space="preserve">
+			<source>stabilisateur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MICRO_GUN" xml:space="preserve">
+			<source>micro canon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BULB" xml:space="preserve">
+			<source>ampoule</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PANNAUX" xml:space="preserve">
+			<source>pannaux</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MANDARINE" xml:space="preserve">
+			<source>mandarine</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RINGLIGHT" xml:space="preserve">
+			<source>ringlight</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LIGHT_FILTER" xml:space="preserve">
+			<source>filtre lumière</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PATCH_FILTER" xml:space="preserve">
+			<source>filtre correctif</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RING_JUGGLING" xml:space="preserve">
+			<source>anneau (jonglerie)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BALL_JUGGLING" xml:space="preserve">
+			<source>balle (jonglerie)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MACE_JUGGLING" xml:space="preserve">
+			<source>massue (jonglerie)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PLATES" xml:space="preserve">
+			<source>assiettes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SCARVES" xml:space="preserve">
+			<source>foulards</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DEVIL_STICK" xml:space="preserve">
+			<source>bâton du diable</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TORCH" xml:space="preserve">
+			<source>torche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DIABOLO" xml:space="preserve">
+			<source>diabolo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WICK" xml:space="preserve">
+			<source>mèche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHAIN" xml:space="preserve">
+			<source>chaîne</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STILT" xml:space="preserve">
+			<source>echasse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.AMERICAN_ROLLER" xml:space="preserve">
+			<source>rouleau américain</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.UNICYCLE" xml:space="preserve">
+			<source>monocycle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.JACKET" xml:space="preserve">
+			<source>blouson</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NECK" xml:space="preserve">
+			<source>tour de cou</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SHIRT" xml:space="preserve">
+			<source>chemise</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.POLO" xml:space="preserve">
+			<source>polo</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TIE" xml:space="preserve">
+			<source>cravate</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOW_TIE" xml:space="preserve">
+			<source>nœud papillon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VEST" xml:space="preserve">
+			<source>gilet</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SKIRT" xml:space="preserve">
+			<source>jupe</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PANTS" xml:space="preserve">
+			<source>pantalon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SHOES" xml:space="preserve">
+			<source>chaussure</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LAVALLI?RE" xml:space="preserve">
+			<source>lavallière</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CAP" xml:space="preserve">
+			<source>casquette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GANT" xml:space="preserve">
+			<source>gant</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.EPAULETTE" xml:space="preserve">
+			<source>epaulette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HAT" xml:space="preserve">
+			<source>chapeau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BELT" xml:space="preserve">
+			<source>ceinture</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WIG" xml:space="preserve">
+			<source>perruque</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MASK" xml:space="preserve">
+			<source>masque</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PLASTIC_CLOWN_NOSE" xml:space="preserve">
+			<source>nez clown plastique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BLOUSE" xml:space="preserve">
+			<source>chemisette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FLOOR_MATS" xml:space="preserve">
+			<source>tapis de sol</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LANDING_MAT" xml:space="preserve">
+			<source>tapis de réception</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FOLDABLE_EVOLUTION_PATH" xml:space="preserve">
+			<source>piste d'évolution pliable</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.EVOLUTION_PATH_ROLLABLE" xml:space="preserve">
+			<source>piste d'évolution enroulable</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MODULES" xml:space="preserve">
+			<source>modules</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PLINTH" xml:space="preserve">
+			<source>plinth</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MINI_TRAMPOLINE" xml:space="preserve">
+			<source>mini-trampoline</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TRAMPOLINE" xml:space="preserve">
+			<source>trampoline</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MAGNESIA" xml:space="preserve">
+			<source>magnésie</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RESIN" xml:space="preserve">
+			<source>résine</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SWITCHES" xml:space="preserve">
+			<source>bascule</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GERMAN_WHEEL" xml:space="preserve">
+			<source>roue allemande</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYR_WHEEL" xml:space="preserve">
+			<source>roue cyr</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RUSSIAN_BARRE" xml:space="preserve">
+			<source>barre russe</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BALANCE_CANNE" xml:space="preserve">
+			<source>canne d'équilibre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LONGE" xml:space="preserve">
+			<source>longe</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PARTS" xml:space="preserve">
+			<source>pièces détachées</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SCARF" xml:space="preserve">
+			<source>foulard</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RING" xml:space="preserve">
+			<source>anneau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MACE" xml:space="preserve">
+			<source>massue</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BALL" xml:space="preserve">
+			<source>boule</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOLLAS" xml:space="preserve">
+			<source>bollas</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PLATE" xml:space="preserve">
+			<source>assiette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STRAP" xml:space="preserve">
+			<source>sangle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ROPE" xml:space="preserve">
+			<source>corde</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FABRIC" xml:space="preserve">
+			<source>tissu</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HOOP" xml:space="preserve">
+			<source>cerceau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.KEYSTONE" xml:space="preserve">
+			<source>trapèze</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MAT" xml:space="preserve">
+			<source>mat</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FRAMEWORK" xml:space="preserve">
+			<source>cadre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MINI_FLYING" xml:space="preserve">
+			<source>mini-volant</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GRAND_FLYING" xml:space="preserve">
+			<source>grand-volant</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PORTICO" xml:space="preserve">
+			<source>portique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SLINGS" xml:space="preserve">
+			<source>elingues</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.METAL_LADDER" xml:space="preserve">
+			<source>echelle métallique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARDWARE" xml:space="preserve">
+			<source>accastillage</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONNECTING_ELEMENTS_BUILT_RIGGING" xml:space="preserve">
+			<source>eléments de liaison bâti/agrès</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PERCH_GIRAFFE" xml:space="preserve">
+			<source>perchoir (girafe)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SPECIAL_CYCLE" xml:space="preserve">
+			<source>cycle spécial</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WIRE_STRETCHED" xml:space="preserve">
+			<source>fil tendu</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SELF_FIL" xml:space="preserve">
+			<source>fil autonome</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SLACK" xml:space="preserve">
+			<source>slack</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ROLLA_BOLLA" xml:space="preserve">
+			<source>rolla bolla</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SCALE" xml:space="preserve">
+			<source>echelle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STILTS" xml:space="preserve">
+			<source>echasses</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHAIR" xml:space="preserve">
+			<source>chaise</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ACROBATICS_VARIOUS_PEDALGOS" xml:space="preserve">
+			<source>acrobatics divers (pédalgos)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CLAVICORDE" xml:space="preserve">
+			<source>clavicorde</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBALUM" xml:space="preserve">
+			<source>cymbalum</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GARDON" xml:space="preserve">
+			<source>gardon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HACKBRETT" xml:space="preserve">
+			<source>hackbrett</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PIANOFORTE" xml:space="preserve">
+			<source>piano-forte</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SALTERIO" xml:space="preserve">
+			<source>salterio</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STRING_TAMBOURINE" xml:space="preserve">
+			<source>tambourin à cordes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DULCIMER" xml:space="preserve">
+			<source>tympanon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CASE_CASES" xml:space="preserve">
+			<source>housse / étuis</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STRAPS_BELTS" xml:space="preserve">
+			<source>sangles / courroies</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STOOLS" xml:space="preserve">
+			<source>tabourets</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TUNERS" xml:space="preserve">
+			<source>accordeurs</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PICKUPS" xml:space="preserve">
+			<source>micros</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STRING" xml:space="preserve">
+			<source>cordes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PICKS" xml:space="preserve">
+			<source>médiators</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CAPO" xml:space="preserve">
+			<source>capodastre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BRIDGE_TREMOLO" xml:space="preserve">
+			<source>chevalet / vibratos</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SLIDES" xml:space="preserve">
+			<source>slides</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STICKS" xml:space="preserve">
+			<source>baguettes</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SKINS" xml:space="preserve">
+			<source>peaux</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BASS_DRUM_PEDAL" xml:space="preserve">
+			<source>pedale grosse caisse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HEADQUARTERS" xml:space="preserve">
+			<source>siège</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.KEY" xml:space="preserve">
+			<source>clé</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.METRONOME" xml:space="preserve">
+			<source>métronome</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TABLE" xml:space="preserve">
+			<source>table</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.STOOL" xml:space="preserve">
+			<source>tabouret</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOARD" xml:space="preserve">
+			<source>planche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PANEL" xml:space="preserve">
+			<source>panneau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CABLE" xml:space="preserve">
+			<source>câble</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RIDEAU" xml:space="preserve">
+			<source>rideau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CARPET" xml:space="preserve">
+			<source>tapis</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SUITCASE" xml:space="preserve">
+			<source>valise</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MISCELLANEOUS" xml:space="preserve">
+			<source>divers</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONTAINER" xml:space="preserve">
+			<source>conteneur</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.REED" xml:space="preserve">
+			<source>anche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BEC" xml:space="preserve">
+			<source>bec</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MOUTHPIECE" xml:space="preserve">
+			<source>embouchure</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COVER_NOSE" xml:space="preserve">
+			<source>couvre-bec</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MUTE" xml:space="preserve">
+			<source>sourdine</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.PEDAL" xml:space="preserve">
+			<source>pédale</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOW" xml:space="preserve">
+			<source>archet</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FIRE_STICK_OR_STAFF" xml:space="preserve">
+			<source>bâton de feu (ou staff)</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CYMBAL_STAND" xml:space="preserve">
+			<source>pied de cymbale</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARNESS" xml:space="preserve">
+			<source>harnais</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SUPPORT" xml:space="preserve">
+			<source>support</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LIGATURE" xml:space="preserve">
+			<source>ligature</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.FAT_TUBE" xml:space="preserve">
+			<source>tube de graisse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LYRE" xml:space="preserve">
+			<source>lyre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MAILLOCHE" xml:space="preserve">
+			<source>mailloche</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VOTES" xml:space="preserve">
+			<source>voix</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.COR" xml:space="preserve">
+			<source>cor</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RECEPTION_MAT" xml:space="preserve">
+			<source>tapis de réception</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.EVOLUTION_TRACK" xml:space="preserve">
+			<source>piste d’évolution</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GROUND_SHEET" xml:space="preserve">
+			<source>tapis de sol</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.ELINGUES" xml:space="preserve">
+			<source>elingues</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.LINK_ELEMENT" xml:space="preserve">
+			<source>eléments de liaison</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BATI_AGRES" xml:space="preserve">
+			<source>bâti agrès</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.APRON" xml:space="preserve">
+			<source>tablier</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WINDBREAKER" xml:space="preserve">
+			<source>coupe-vent</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.RAINCOAT" xml:space="preserve">
+			<source>imperméable</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BERET" xml:space="preserve">
+			<source>béret</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.KEPI" xml:space="preserve">
+			<source>képi</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CALOT" xml:space="preserve">
+			<source>calot</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.GIBERNE" xml:space="preserve">
+			<source>giberne</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TEE_SHIRT" xml:space="preserve">
+			<source>tee-shirt</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SWEAT_SHIRT" xml:space="preserve">
+			<source>sweat-shirt</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DJING" xml:space="preserve">
+			<source>djing</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.APPEAU" xml:space="preserve">
+			<source>appeau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOOMWHACKER" xml:space="preserve">
+			<source>boomwhacker</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CARILLON" xml:space="preserve">
+			<source>carillon</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CAXIXI" xml:space="preserve">
+			<source>caxixi</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHENILLE" xml:space="preserve">
+			<source>chenille</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHOCALHO_GANZ" xml:space="preserve">
+			<source>chocalho ganza</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HAND_BELL" xml:space="preserve">
+			<source>cloche à main</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BRAZIL_BELL" xml:space="preserve">
+			<source>cloche brésilienne</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DIATONIC_BELL" xml:space="preserve">
+			<source>cloche diatonique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CUP_ZIK" xml:space="preserve">
+			<source>cup zik</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SLIDE_FLUTE" xml:space="preserve">
+			<source>flûte à coulisse</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.KALIMBA" xml:space="preserve">
+			<source>kalimba</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MELODICA" xml:space="preserve">
+			<source>mélodica</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.METALLOPHONE" xml:space="preserve">
+			<source>métallophone</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OCARINA" xml:space="preserve">
+			<source>ocarina</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OCTOBLOCK" xml:space="preserve">
+			<source>octoblock</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.SHEKERE" xml:space="preserve">
+			<source>shékéré</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WATER_DRUM" xml:space="preserve">
+			<source>tambour d'eau</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.OCEAN_DRUM" xml:space="preserve">
+			<source>tambours d'océan</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TAN_TAN" xml:space="preserve">
+			<source>tan tan</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.THUNDER_PIPE" xml:space="preserve">
+			<source>tube tonnerre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.WAH_WAH_PIPE" xml:space="preserve">
+			<source>tube wah wah</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.REASONING_PIP" xml:space="preserve">
+			<source>tubes raisonnant</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.HARMONIE_PIPE" xml:space="preserve">
+			<source>tuyau harmonique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VIBRASLAP" xml:space="preserve">
+			<source>vibraslap</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CHINESE_BOWL" xml:space="preserve">
+			<source>bol chinois</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.METHODS" xml:space="preserve">
+			<source>méthode</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BOOK" xml:space="preserve">
+			<source>livre</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.MAGAZINE" xml:space="preserve">
+			<source>magazine</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CD" xml:space="preserve">
+			<source>cd</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.VINYLES" xml:space="preserve">
+			<source>vinyle</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.TAPE" xml:space="preserve">
+			<source>cassette</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.DVD" xml:space="preserve">
+			<source>dvd</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.BLU_RAY" xml:space="preserve">
+			<source>blu-ray</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.NUMERIC_FILES" xml:space="preserve">
+			<source>fichier numérique</source>
+			</trans-unit>
+			<trans-unit id="member.instrument.CONDUCTOR" xml:space="preserve">
+			<source>Directeur ou chef d'orchestre</source>
+			</trans-unit>
 
 		</body>
 	</file>

+ 59 - 0
ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_donor.xlf

@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xliff version="1.0">
+	<file source-language="fr" datatype="plaintext" original="messages" date="2020-04-08T17:06:12Z" product-name="ot_templating">
+		<header/>
+		<body>
+			<trans-unit id="id.description">
+				<source>id</source>
+			</trans-unit>
+			<trans-unit id="type.description">
+				<source>type</source>
+			</trans-unit>
+			<trans-unit id="sub_domain.description">
+				<source>subDomain</source>
+			</trans-unit>
+			<trans-unit id="name.description">
+				<source>name</source>
+			</trans-unit>
+			<trans-unit id="slug.description">
+				<source>slug</source>
+			</trans-unit>
+			<trans-unit id="principal_type.description">
+				<source>principalType</source>
+			</trans-unit>
+			<trans-unit id="description.description">
+				<source>description</source>
+			</trans-unit>
+			<trans-unit id="categories.description">
+				<source>categories</source>
+			</trans-unit>
+			<trans-unit id="address_city.description">
+				<source>addressCity</source>
+			</trans-unit>
+			<trans-unit id="postal_code.description">
+				<source>postalCode</source>
+			</trans-unit>
+			<trans-unit id="street_adress.description">
+				<source>streetAdress</source>
+			</trans-unit>
+			<trans-unit id="latitude.description">
+				<source>latitude</source>
+			</trans-unit>
+			<trans-unit id="longitude.description">
+				<source>longitude</source>
+			</trans-unit>
+			<trans-unit id="country.description">
+				<source>country</source>
+			</trans-unit>
+			<trans-unit id="logo.description">
+				<source>logo</source>
+			</trans-unit>
+			<trans-unit id="parent_name.description">
+				<source>parentName</source>
+			</trans-unit>
+			<trans-unit id="parent_subdomain.description">
+				<source>parentSubdomain</source>
+			</trans-unit>
+		</body>
+	</file>
+</xliff>

+ 113 - 0
ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_event.xlf

@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xliff version="1.0">
+	<file source-language="fr" datatype="plaintext" original="messages" date="2020-04-08T17:06:12Z" product-name="ot_templating">
+		<header/>
+		<body>
+			<trans-unit id="id.description">
+				<source>id</source>
+			</trans-unit>
+			<trans-unit id="type.description">
+				<source>type</source>
+			</trans-unit>
+			<trans-unit id="organization_id.description">
+				<source>organizationId</source>
+			</trans-unit>
+			<trans-unit id="subdomain.description">
+				<source>subdomain</source>
+			</trans-unit>
+			<trans-unit id="name.description">
+				<source>name</source>
+			</trans-unit>
+			<trans-unit id="description.description">
+				<source>description</source>
+			</trans-unit>
+			<trans-unit id="categories.description">
+				<source>categories</source>
+			</trans-unit>
+			<trans-unit id="url.description">
+				<source>url</source>
+			</trans-unit>
+			<trans-unit id="rule.description">
+				<source>rule</source>
+			</trans-unit>
+			<trans-unit id="datetime_start.description">
+				<source>datetimeStart</source>
+			</trans-unit>
+			<trans-unit id="datetime_end.description">
+				<source>datetimeEnd</source>
+			</trans-unit>
+			<trans-unit id="dates.description">
+				<source>dates</source>
+			</trans-unit>
+			<trans-unit id="placename.description">
+				<source>placename</source>
+			</trans-unit>
+			<trans-unit id="place_description.description">
+				<source>placeDescription</source>
+			</trans-unit>
+			<trans-unit id="place_floor_size.description">
+				<source>placeFloorSize</source>
+			</trans-unit>
+			<trans-unit id="place_capacity.description">
+				<source>placeCapacity</source>
+			</trans-unit>
+			<trans-unit id="city.description">
+				<source>city</source>
+			</trans-unit>
+			<trans-unit id="postal_code.description">
+				<source>postalCode</source>
+			</trans-unit>
+			<trans-unit id="street_address.description">
+				<source>streetAddress</source>
+			</trans-unit>
+			<trans-unit id="longitude.description">
+				<source>longitude</source>
+			</trans-unit>
+			<trans-unit id="latitude.description">
+				<source>latitude</source>
+			</trans-unit>
+			<trans-unit id="room_name.description">
+				<source>roomName</source>
+			</trans-unit>
+			<trans-unit id="room_description.description">
+				<source>roomDescription</source>
+			</trans-unit>
+			<trans-unit id="room_localisation.description">
+				<source>roomLocalisation</source>
+			</trans-unit>
+			<trans-unit id="room_capacity.description">
+				<source>roomCapacity</source>
+			</trans-unit>
+			<trans-unit id="room_floor_size.description">
+				<source>roomFloorSize</source>
+			</trans-unit>
+			<trans-unit id="zup_id.description">
+				<source>zupId</source>
+			</trans-unit>
+			<trans-unit id="deep_link.description">
+				<source>deepLink</source>
+			</trans-unit>
+			<trans-unit id="image.description">
+				<source>image</source>
+			</trans-unit>
+			<trans-unit id="price_mini.description">
+				<source>priceMini</source>
+			</trans-unit>
+			<trans-unit id="meeting_schedule.description">
+				<source>meetingSchedule</source>
+			</trans-unit>
+			<trans-unit id="api.description">
+				<source>api</source>
+			</trans-unit>
+			<trans-unit id="parent_name.description">
+				<source>parentName</source>
+			</trans-unit>
+			<trans-unit id="parent_subdomain.description">
+				<source>parentSubdomain</source>
+			</trans-unit>
+			<trans-unit id="organization.description">
+				<source>organization</source>
+			</trans-unit>
+		</body>
+	</file>
+</xliff>

+ 170 - 0
ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_organization.xlf

@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xliff version="1.0">
+	<file source-language="fr" datatype="plaintext" original="messages" date="2020-04-08T17:06:12Z" product-name="ot_templating">
+		<header/>
+		<body>
+			<trans-unit id="tx_ottemplating_domain_model_event">
+				<source>Event</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.id">
+				<source>Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.type">
+				<source>Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.organization_id">
+				<source>Organization Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.subdomain">
+				<source>Subdomain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.name">
+				<source>Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.description">
+				<source>Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.categories">
+				<source>Categories</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.url">
+				<source>Url</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.rule">
+				<source>Rule</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.datetime_start">
+				<source>Datetime Start</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.datetime_end">
+				<source>Datetime End</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.dates">
+				<source>Dates</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.placename">
+				<source>Placename</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_description">
+				<source>Place Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_floor_size">
+				<source>Place Floor Size</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_capacity">
+				<source>Place Capacity</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.city">
+				<source>City</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.postal_code">
+				<source>Postal Code</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.street_address">
+				<source>Street Address</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.longitude">
+				<source>Longitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.latitude">
+				<source>Latitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_name">
+				<source>Room Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_description">
+				<source>Room Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_localisation">
+				<source>Room Localisation</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_capacity">
+				<source>Room Capacity</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_floor_size">
+				<source>Room Floor Size</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.zup_id">
+				<source>Zup Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.deep_link">
+				<source>Deep Link</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.image">
+				<source>Image</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.price_mini">
+				<source>Price Mini</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.meeting_schedule">
+				<source>Meeting Schedule</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.api">
+				<source>Api</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.parent_name">
+				<source>Parent Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.parent_subdomain">
+				<source>Parent Subdomain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.organization">
+				<source>Organization</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization">
+				<source>Organization</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.id">
+				<source>Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.type">
+				<source>Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.sub_domain">
+				<source>Sub Domain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.name">
+				<source>Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.slug">
+				<source>Slug</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.principal_type">
+				<source>Principal Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.description">
+				<source>Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.categories">
+				<source>Categories</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.address_city">
+				<source>Address City</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.postal_code">
+				<source>Postal Code</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.street_adress">
+				<source>Street Adress</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.latitude">
+				<source>Latitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.longitude">
+				<source>Longitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.country">
+				<source>Country</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.logo">
+				<source>Logo</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.parent_name">
+				<source>Parent Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.parent_subdomain">
+				<source>Parent Subdomain</source>
+			</trans-unit>
+		</body>
+	</file>
+</xliff>

+ 182 - 0
ot_templating/Resources/Private/Language/locallang_db.xlf

@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<xliff version="1.0">
+	<file source-language="fr" datatype="plaintext" original="messages" date="2020-04-08T17:06:12Z" product-name="ot_templating">
+		<header/>
+		<body>
+			<trans-unit id="tx_ottemplating_domain_model_event">
+				<source>Event</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.id">
+				<source>Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.type">
+				<source>Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.organization_id">
+				<source>Organization Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.subdomain">
+				<source>Subdomain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.name">
+				<source>Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.description">
+				<source>Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.categories">
+				<source>Categories</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.url">
+				<source>Url</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.rule">
+				<source>Rule</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.datetime_start">
+				<source>Datetime Start</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.datetime_end">
+				<source>Datetime End</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.dates">
+				<source>Dates</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.placename">
+				<source>Placename</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_description">
+				<source>Place Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_floor_size">
+				<source>Place Floor Size</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.place_capacity">
+				<source>Place Capacity</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.city">
+				<source>City</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.postal_code">
+				<source>Postal Code</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.street_address">
+				<source>Street Address</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.longitude">
+				<source>Longitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.latitude">
+				<source>Latitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_name">
+				<source>Room Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_description">
+				<source>Room Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_localisation">
+				<source>Room Localisation</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_capacity">
+				<source>Room Capacity</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.room_floor_size">
+				<source>Room Floor Size</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.zup_id">
+				<source>Zup Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.deep_link">
+				<source>Deep Link</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.image">
+				<source>Image</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.price_mini">
+				<source>Price Mini</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.meeting_schedule">
+				<source>Meeting Schedule</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.api">
+				<source>Api</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.parent_name">
+				<source>Parent Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.parent_subdomain">
+				<source>Parent Subdomain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_event.organization">
+				<source>Organization</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization">
+				<source>Organization</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.id">
+				<source>Id</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.type">
+				<source>Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.sub_domain">
+				<source>Sub Domain</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.name">
+				<source>Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.slug">
+				<source>Slug</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.principal_type">
+				<source>Principal Type</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.description">
+				<source>Description</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.categories">
+				<source>Categories</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.address_city">
+				<source>Address City</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.postal_code">
+				<source>Postal Code</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.street_adress">
+				<source>Street Adress</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.latitude">
+				<source>Latitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.longitude">
+				<source>Longitude</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.country">
+				<source>Country</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.logo">
+				<source>Logo</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.parent_name">
+				<source>Parent Name</source>
+			</trans-unit>
+			<trans-unit id="tx_ottemplating_domain_model_organization.parent_subdomain">
+				<source>Parent Subdomain</source>
+			</trans-unit>
+			<trans-unit id="tx_ot_templating_events.name">
+				<source>Event</source>
+			</trans-unit>
+			<trans-unit id="tx_ot_templating_events.description">
+				<source>Évènementiel</source>
+			</trans-unit>
+			<trans-unit id="tx_ot_templating_organizations.name">
+				<source>Organizations</source>
+			</trans-unit>
+			<trans-unit id="tx_ot_templating_organizations.description">
+				<source>Organisations et réseaux</source>
+			</trans-unit>
+		</body>
+	</file>
+</xliff>

+ 3 - 0
ot_templating/Resources/Private/Layouts/Default.html

@@ -0,0 +1,3 @@
+<div class="ot-templating">
+    <f:render section="content" />
+</div>

+ 1 - 1
ot_templating/Resources/Private/Partials/Classic/Donors.html

@@ -3,7 +3,7 @@
 <f:comment><!-- Donors --></f:comment>
 
 <v:render.request vendorName ="Opentalent"
-                  extensionName = 'OtWidgets'
+                  extensionName = 'OtTemplating'
                   pluginName = 'Donors'
                   controller = 'Donor'
                   action = 'getDonors'

+ 1 - 1
ot_templating/Resources/Private/Partials/Classic/EventsPreview.html

@@ -3,7 +3,7 @@
 <f:comment><!-- Next events --></f:comment>
 
 <v:render.request vendorName ="Opentalent"
-                  extensionName = 'OtWidgets'
+                  extensionName = 'OtTemplating'
                   pluginName = 'Events'
                   controller = 'Event'
                   action = 'preview'

+ 1 - 1
ot_templating/Resources/Private/Partials/Modern/Donors.html

@@ -3,7 +3,7 @@
 <f:comment><!-- Donors --></f:comment>
 
 <v:render.request vendorName ="Opentalent"
-                  extensionName = 'OtWidgets'
+                  extensionName = 'OtTemplating'
                   pluginName = 'Donors'
                   controller = 'Donor'
                   action = 'getDonors'

+ 1 - 1
ot_templating/Resources/Private/Partials/Modern/EventsPreview.html

@@ -3,7 +3,7 @@
 <f:comment><!-- Next events --></f:comment>
 
 <v:render.request vendorName ="Opentalent"
-                  extensionName = 'OtWidgets'
+                  extensionName = 'OtTemplating'
                   pluginName = 'Events'
                   controller = 'Event'
                   action = 'preview'

+ 17 - 0
ot_templating/Resources/Private/Templates/Box/Box.html

@@ -0,0 +1,17 @@
+<f:layout name="Default" />
+
+<f:section name="box">
+    <div class="ot-box">
+        <header>
+            <h3>{title}</h3>
+        </header>
+
+        <div class="box-content">
+            {content}
+        </div>
+
+        <footer>
+            {footer}
+        </footer>
+    </div>
+</f:section>

+ 17 - 0
ot_templating/Resources/Private/Templates/Box/Classic/Box.html

@@ -0,0 +1,17 @@
+<f:layout name="Default" />
+
+<f:section name="box">
+    <div class="ot-box">
+        <header>
+            <h3>{title}</h3>
+        </header>
+
+        <div class="box-content">
+            {content}
+        </div>
+
+        <footer>
+            {footer}
+        </footer>
+    </div>
+</f:section>

+ 17 - 0
ot_templating/Resources/Private/Templates/Box/Modern/Box.html

@@ -0,0 +1,17 @@
+<f:layout name="Default" />
+
+<f:section name="box">
+    <div class="ot-box">
+        <header>
+            <h3>{title}</h3>
+        </header>
+
+        <div class="box-content">
+            {content}
+        </div>
+
+        <footer>
+            {footer}
+        </footer>
+    </div>
+</f:section>

+ 76 - 0
ot_templating/Resources/Private/Templates/Content/Classic/Carousel.html

@@ -0,0 +1,76 @@
+<f:comment><!-- Widget flux par Opentalent: Carousel --></f:comment>
+<f:comment><!-- Require: https://kenwheeler.github.io/slick/ --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:flux="http://fedext.net/ns/flux/ViewHelpers"
+     xmlns:v="http://fedext.net/ns/vhs/ViewHelpers"
+     xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
+
+    <f:layout name="{settings.template}/CustomContent"/>
+
+    <f:section name="Configuration">
+        <flux:form id="Carousel"
+                   label="Carrousel"
+                   description="Insérez un carrousel d'images"
+                   extensionName="OtTemplating"
+        >
+            <flux:form.option.group value="fce" />
+            <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+
+            <flux:field.input name="width" eval="trim" default="600" label="Largeur (en pixels)"/>
+            <flux:field.input name="height" eval="trim" default="400" label="Hauteur (en pixels)"/>
+            <flux:field.checkbox name="crop" label="Rogner les images trop grandes ?" default="0"/>
+
+            <flux:field.inline.fal name="images" minItems="2" maxItems="24"/>
+
+        </flux:form>
+    </f:section>
+
+    <f:section name="Preview">
+        <p>Carrousel</p>
+
+        <div class="be-carousel-preview">
+            <f:for each="{v:content.resources.fal(field: 'images', uid: '{record.uid}')}"
+                   as="image"
+                   iteration="iterator">
+
+                <f:image treatIdAsReference="1"
+                         src="{image.id}"
+                         title="{image.title}"
+                         alt="{image.alternative}"
+                         class="be-carousel-img-preview"
+                         maxWidth="128"
+                         maxHeight="128"
+                />
+
+            </f:for>
+        </div>
+    </f:section>
+
+    <f:section name="Main">
+
+        <div class="center-carousel">
+            <div class="carousel" style="max-width:{width}px; max-height:{height}px">
+                <f:for each="{v:content.resources.fal(field: 'images', uid: '{record.uid}')}"
+                       as="image"
+                       iteration="iterator">
+                    <div style="height: {height}px">
+                        <f:image treatIdAsReference="1"
+                                 src="{image.id}"
+                                 title="{image.title}"
+                                 alt="{image.alternative}"
+                                 class="carousel-img"
+                                 width="{width}"
+                                 maxHeight="{height}{f:if(condition: crop, then: 'c')}"
+                        />
+                    </div>
+                </f:for>
+            </div>
+        </div>
+
+    </f:section>
+
+</div>

+ 30 - 0
ot_templating/Resources/Private/Templates/Content/Classic/FCE50-50.html

@@ -0,0 +1,30 @@
+<f:comment><!-- Widget flux par Site N'Go: : Container à 2 colonnes --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<f:layout name="CustomContent" />
+
+<f:section name="Configuration">
+    <flux:form id="FCE50-50"
+               label="Conteneur 50/50"
+               description="Container à deux colonnes"
+               extensionName="OtTemplating"
+    >
+        <flux:form.option.group value="fce" />
+        <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+    </flux:form>
+    <flux:grid>
+        <flux:grid.row>
+            <flux:grid.column name="contentLeft" label="Colonne gauche" colPos="0"/>
+            <flux:grid.column name="contentRight" label="Colonne droite" colPos="1"/>
+        </flux:grid.row>
+    </flux:grid>
+</f:section>
+
+<f:section name="Main">
+    <div class="fce-2col row">
+        <div class="col"><flux:content.render area="contentLeft" /></div>
+        <div class="col"><flux:content.render area="contentRight" /></div>
+    </div>
+</f:section>

+ 79 - 0
ot_templating/Resources/Private/Templates/Content/Classic/Faq.html

@@ -0,0 +1,79 @@
+<f:comment><!-- Widget flux par Site N'Go: FAQ --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:flux="http://fedext.net/ns/flux/ViewHelpers"
+     xmlns:v="http://fedext.net/ns/vhs/ViewHelpers"
+     xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
+
+    <f:layout name="CustomContent"/>
+
+    <f:section name="Configuration">
+        <flux:form id="Faq"
+                   label="F.A.Q"
+                   description="Concevez votre section 'Foire aux Questions'"
+                   extensionName="OtTemplating"
+        >
+            <flux:form.option.group value="fce" />
+            <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+
+            <flux:form.section name="faq">
+                <flux:form.object name="item" label="Question">
+                    <flux:field.input name="question" label="Question"/>
+                    <flux:field.text name="reponse" label="Réponse" defaultExtras="richtext[]:rte_transform[mode=ts_css]"/>
+                    <flux:field.checkbox name="open" label="Dépliée ?"/>
+                </flux:form.object>
+            </flux:form.section>
+        </flux:form>
+    </f:section>
+
+    <f:section name="Preview">
+        <table style="width: 100%;" class="table table-condensed table-hover">
+            <thead>
+            <tr>
+                <th>#</th>
+                <th>Question</th>
+                <th>Réponse</th>
+            </tr>
+            </thead>
+            <tbody>
+            <f:for each="{faq}" as="element" iteration="iteration">
+                <f:for each="{element}" key="elementType" as="elementData">
+                    <tr valign="middle">
+                        <td style="vertical-align: middle;">{iteration.cycle}</td>
+                        <td style="vertical-align: middle;">{elementData.question}</td>
+                        <td style="vertical-align: middle;"><f:format.raw>{elementData.reponse}</f:format.raw></td>
+                    </tr>
+                </f:for>
+            </f:for>
+            </tbody>
+        </table>
+    </f:section>
+
+    <f:section name="Main">
+
+        <div class="faq">
+            <f:for each="{faq}" as="element" iteration="iteration">
+                <f:for each="{element}" key="elementType" as="elementData">
+                    <div class="full-width faq-item {f:if(condition:'{iteration.isOdd}',then:'highlight')}">
+                        <div class="container">
+                            <div class="row">
+                                <div class="edito {f:if(condition:'{elementData.open}',else:'panel-close')}">
+                                    <h3>{elementData.question}</h3>
+                                    <div class="content collapse {f:if(condition:'{elementData.open}',then:'show')}">
+                                        <f:format.html>{elementData.reponse}</f:format.html>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </f:for>
+            </f:for>
+        </div>
+
+
+    </f:section>
+
+</div>

+ 76 - 0
ot_templating/Resources/Private/Templates/Content/Modern/Carousel.html

@@ -0,0 +1,76 @@
+<f:comment><!-- Widget flux par Opentalent: Carousel --></f:comment>
+<f:comment><!-- Require: https://kenwheeler.github.io/slick/ --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:flux="http://fedext.net/ns/flux/ViewHelpers"
+     xmlns:v="http://fedext.net/ns/vhs/ViewHelpers"
+     xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
+
+    <f:layout name="{settings.template}/CustomContent"/>
+
+    <f:section name="Configuration">
+        <flux:form id="Carousel"
+                   label="Carrousel"
+                   description="Insérez un carrousel d'images"
+                   extensionName="OtTemplating"
+        >
+            <flux:form.option.group value="fce" />
+            <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+
+            <flux:field.input name="width" eval="trim" default="600" label="Largeur (en pixels)"/>
+            <flux:field.input name="height" eval="trim" default="400" label="Hauteur (en pixels)"/>
+            <flux:field.checkbox name="crop" label="Rogner les images trop grandes ?" default="0"/>
+
+            <flux:field.inline.fal name="images" minItems="2" maxItems="24"/>
+
+        </flux:form>
+    </f:section>
+
+    <f:section name="Preview">
+        <p>Carrousel</p>
+
+        <div class="be-carousel-preview">
+            <f:for each="{v:content.resources.fal(field: 'images', uid: '{record.uid}')}"
+                   as="image"
+                   iteration="iterator">
+
+                <f:image treatIdAsReference="1"
+                         src="{image.id}"
+                         title="{image.title}"
+                         alt="{image.alternative}"
+                         class="be-carousel-img-preview"
+                         maxWidth="128"
+                         maxHeight="128"
+                />
+
+            </f:for>
+        </div>
+    </f:section>
+
+    <f:section name="Main">
+
+        <div class="center-carousel">
+            <div class="carousel" style="max-width:{width}px; max-height:{height}px">
+                <f:for each="{v:content.resources.fal(field: 'images', uid: '{record.uid}')}"
+                       as="image"
+                       iteration="iterator">
+                    <div style="height: {height}px">
+                        <f:image treatIdAsReference="1"
+                                 src="{image.id}"
+                                 title="{image.title}"
+                                 alt="{image.alternative}"
+                                 class="carousel-img"
+                                 width="{width}"
+                                 maxHeight="{height}{f:if(condition: crop, then: 'c')}"
+                        />
+                    </div>
+                </f:for>
+            </div>
+        </div>
+
+    </f:section>
+
+</div>

+ 30 - 0
ot_templating/Resources/Private/Templates/Content/Modern/FCE50-50.html

@@ -0,0 +1,30 @@
+<f:comment><!-- Widget flux par Site N'Go: : Container à 2 colonnes --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<f:layout name="CustomContent" />
+
+<f:section name="Configuration">
+    <flux:form id="FCE50-50"
+               label="Conteneur 50/50"
+               description="Container à deux colonnes"
+               extensionName="OtTemplating"
+    >
+        <flux:form.option.group value="fce" />
+        <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+    </flux:form>
+    <flux:grid>
+        <flux:grid.row>
+            <flux:grid.column name="contentLeft" label="Colonne gauche" colPos="0"/>
+            <flux:grid.column name="contentRight" label="Colonne droite" colPos="1"/>
+        </flux:grid.row>
+    </flux:grid>
+</f:section>
+
+<f:section name="Main">
+    <div class="fce-2col row">
+        <div class="col"><flux:content.render area="contentLeft" /></div>
+        <div class="col"><flux:content.render area="contentRight" /></div>
+    </div>
+</f:section>

+ 79 - 0
ot_templating/Resources/Private/Templates/Content/Modern/Faq.html

@@ -0,0 +1,79 @@
+<f:comment><!-- Widget flux par Site N'Go: FAQ --></f:comment>
+
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace flux=FluidTYPO3\Flux\ViewHelpers}
+
+<div xmlns="http://www.w3.org/1999/xhtml"
+     xmlns:flux="http://fedext.net/ns/flux/ViewHelpers"
+     xmlns:v="http://fedext.net/ns/vhs/ViewHelpers"
+     xmlns:f="http://typo3.org/ns/fluid/ViewHelpers">
+
+    <f:layout name="CustomContent"/>
+
+    <f:section name="Configuration">
+        <flux:form id="Faq"
+                   label="F.A.Q"
+                   description="Concevez votre section 'Foire aux Questions'"
+                   extensionName="OtTemplating"
+        >
+            <flux:form.option.group value="fce" />
+            <flux:form.option.icon value="EXT:ot_templating/Resources/Public/Icons/opentalent-144x144.png" />
+
+            <flux:form.section name="faq">
+                <flux:form.object name="item" label="Question">
+                    <flux:field.input name="question" label="Question"/>
+                    <flux:field.text name="reponse" label="Réponse" defaultExtras="richtext[]:rte_transform[mode=ts_css]"/>
+                    <flux:field.checkbox name="open" label="Dépliée ?"/>
+                </flux:form.object>
+            </flux:form.section>
+        </flux:form>
+    </f:section>
+
+    <f:section name="Preview">
+        <table style="width: 100%;" class="table table-condensed table-hover">
+            <thead>
+            <tr>
+                <th>#</th>
+                <th>Question</th>
+                <th>Réponse</th>
+            </tr>
+            </thead>
+            <tbody>
+            <f:for each="{faq}" as="element" iteration="iteration">
+                <f:for each="{element}" key="elementType" as="elementData">
+                    <tr valign="middle">
+                        <td style="vertical-align: middle;">{iteration.cycle}</td>
+                        <td style="vertical-align: middle;">{elementData.question}</td>
+                        <td style="vertical-align: middle;"><f:format.raw>{elementData.reponse}</f:format.raw></td>
+                    </tr>
+                </f:for>
+            </f:for>
+            </tbody>
+        </table>
+    </f:section>
+
+    <f:section name="Main">
+
+        <div class="faq">
+            <f:for each="{faq}" as="element" iteration="iteration">
+                <f:for each="{element}" key="elementType" as="elementData">
+                    <div class="full-width faq-item {f:if(condition:'{iteration.isOdd}',then:'highlight')}">
+                        <div class="container">
+                            <div class="row">
+                                <div class="edito {f:if(condition:'{elementData.open}',else:'panel-close')}">
+                                    <h3>{elementData.question}</h3>
+                                    <div class="content collapse {f:if(condition:'{elementData.open}',then:'show')}">
+                                        <f:format.html>{elementData.reponse}</f:format.html>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </f:for>
+            </f:for>
+        </div>
+
+
+    </f:section>
+
+</div>

+ 44 - 0
ot_templating/Resources/Private/Templates/Donor/Classic/GetDonors.html

@@ -0,0 +1,44 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-box ot-donors">
+        <f:if condition="{donors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Nos partenaires</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{staticDisplay} == 1', then: '', else: 'carousel')}">
+                            <f:for each="{donors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+
+        <f:if condition="{networkDonors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Partenaires de notre réseau</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{settings.carousel} == 1', then: 'carousel', else: '')}">
+                            <f:for each="{networkDonors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+    </div>
+</f:section>

+ 44 - 0
ot_templating/Resources/Private/Templates/Donor/GetDonors.html

@@ -0,0 +1,44 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-box ot-donors">
+        <f:if condition="{donors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Nos partenaires</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{staticDisplay} == 1', then: '', else: 'carousel')}">
+                            <f:for each="{donors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+
+        <f:if condition="{networkDonors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Partenaires de notre réseau</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{settings.carousel} == 1', then: 'carousel', else: '')}">
+                            <f:for each="{networkDonors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+    </div>
+</f:section>

+ 44 - 0
ot_templating/Resources/Private/Templates/Donor/Modern/GetDonors.html

@@ -0,0 +1,44 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-box ot-donors">
+        <f:if condition="{donors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Nos partenaires</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{staticDisplay} == 1', then: '', else: 'carousel')}">
+                            <f:for each="{donors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+
+        <f:if condition="{networkDonors -> f:count()} > 0">
+            <f:then>
+                <div class="donors-panel">
+                    <header>
+                        <h3>Partenaires de notre réseau</h3>
+                    </header>
+                    <div class="box-content">
+                        <div class="donor-list {f:if(condition: '{settings.carousel} == 1', then: 'carousel', else: '')}">
+                            <f:for each="{networkDonors}" as="donor">
+                                <div class="donor-card">
+                                    <img src="{donor.logo}" alt="{donor.name}"/>
+                                </div>
+                            </f:for>
+                        </div>
+                    </div>
+                </div>
+            </f:then>
+        </f:if>
+    </div>
+</f:section>

+ 73 - 0
ot_templating/Resources/Private/Templates/Event/Classic/Index.html

@@ -0,0 +1,73 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-all-events">
+
+        <div class="events-controls">
+            <div class="event-search">
+                <h3>Rechercher un évènement: </h3>
+                <f:form action="index">
+                    <f:form.textfield name="search-loc" placeholder="Où?" value="{args.search-loc}"/>
+                    <f:form.textfield name="search-name" placeholder="Quoi?" value="{args.search-name}" />
+                    <f:form.textfield name="search-datestart" placeholder="Depuis le..." class="datepicker datetimepicker" value="{args.search-datestart}" />
+                    <f:form.textfield name="search-dateend" placeholder="Jusqu'au..." class="datepicker datetimepicker" value="{args.search-dateend}" />
+                    <f:form.button name="search-submit">Rechercher</f:form.button>
+                </f:form>
+            </div>
+            <div id="event-map" data-records="">
+                <f:for each="{allEvents}" as="event">
+                    <f:if condition="{event.longitude}">
+                        <f:then>
+                            <i class="event-geodata" style="display: none;"
+                               data-id="{event.id}"
+                               data-long="{event.longitude}"
+                               data-lat="{event.latitude}"
+                               data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                            </i>
+                        </f:then>
+                    </f:if>
+                </f:for>
+            </div>
+        </div>
+
+        <div class="events-results">
+            <f:if condition="{allEvents -> f:count()} == 0">
+                <span>Aucun résultat</span>
+            </f:if>
+
+            <f:for each="{allEvents}" as="event">
+                <div class="event" data-id="{event.id}">
+                    <div class="event-preview">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-loc-date">
+                                {event.locAndDate}
+                            </span>
+                            <span class="event-description">
+                                {event.shortDescription}
+                            </span>
+                        </div>
+                    </div>
+
+                    <f:link.action action="show" arguments="{eventId: event.id}" class="event-see"><i class="fa fa-plus" style="margin-right: 5px;"></i><span>Plus d'infos</span></f:link.action>
+                </div>
+            </f:for>
+        </div>
+    </div>
+
+</f:section>

+ 8 - 0
ot_templating/Resources/Private/Templates/Event/Classic/NoEvents.html

@@ -0,0 +1,8 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-no-events">
+        <p>Aucun évènement n'est prévu pour le moment.</p>
+        <p>Plus d'évènements sur <a href="{settings.opentalentWebsite}">{settings.opentalentWebsite}</a>  </p>
+    </div>
+</f:section>

+ 161 - 0
ot_templating/Resources/Private/Templates/Event/Classic/Preview.html

@@ -0,0 +1,161 @@
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
+
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <f:comment><!-- Get the events page' uid if the page is found --></f:comment>
+    <v:variable.set value="{ot:eventsPage.getId()}" name="eventsPageUid"/>
+
+    <div class="ot-box ot-events">
+        <div class="events-list">
+            <header>
+                <h3>Nos prochains évènements</h3>
+            </header>
+
+            <f:for each="{events}" as="event">
+
+                <div class="event-card">
+
+                    <div class="event-poster">
+                        <f:if condition="{event.image}">
+                            <f:then>
+                                <img src='{event.image}' alt="poster" />
+                            </f:then>
+                            <f:else>
+                                <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                            </f:else>
+                        </f:if>
+                    </div>
+
+                    <div class="event-summary">
+                        <span class="event-name">
+                            {event.name}
+                        </span>
+                        <span class="event-date">
+                            {f:format.date(date: event.datetimeStart,
+                                           format: "\l\e d-m-Y \à H\hi")}
+                        </span>
+                        <f:if condition="{eventsPageUid} > 0"><f:then>
+                            <span class="event-see">
+                                <f:link.action pageUid="{eventsPageUid}" action="show" arguments="{eventId: event.id}">
+                                    Plus d'infos
+                                </f:link.action>
+                            </span>
+                        </f:then></f:if>
+                    </div>
+
+                </div>
+            </f:for>
+
+            <f:if condition="{events -> f:count()} == 0">
+                <f:then>
+                    <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                </f:then>
+            </f:if>
+
+            <footer>
+                <f:if condition="{eventsPageUid} > 0"><f:then>
+                    <div class="event-see-all">
+                        <f:link.page pageUid="{eventsPageUid}">
+                            Voir tous les évènements
+                        </f:link.page>
+                    </div>
+                </f:then></f:if>
+            </footer>
+        </div>
+
+        <v:condition.variable.isset name="networkEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de notre réseau</h3>
+                </header>
+
+                <f:for each="{networkEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{networkEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+
+        <v:condition.variable.isset name="structuresEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de nos structures</h3>
+                </header>
+
+                <f:for each="{structuresEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{structuresEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+    </div>
+</f:section>

+ 59 - 0
ot_templating/Resources/Private/Templates/Event/Classic/Show.html

@@ -0,0 +1,59 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-show-event">
+
+        <header>
+            <h2 class="event-name">{event.name}</h2>
+            <f:link.action class="go-back"><i class="fa fa-list"> </i> Revenir à la liste des évènements</f:link.action>
+        </header>
+
+        <div class="event-content">
+
+            <div class="event-poster">
+                <f:if condition="{event.image}">
+                    <f:then>
+                        <img src='{event.image}' alt="poster" />
+                    </f:then>
+                    <f:else>
+                        <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                    </f:else>
+                </f:if>
+            </div>
+
+            <div class="event-summary">
+                <table class="event-infos">
+                    <tr>
+                        <td>Quand?</td>
+                        <td>
+                            {event.formattedDates}
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>Où?</td>
+                        <td>
+                            {f:format.nl2br(value: '{event.fullAdress}')}
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+        <p class="event-description">
+            {f:format.nl2br(value: '{event.description}')}
+        </p>
+        <f:if condition="{event.longitude}">
+            <f:then>
+                <div id="event-map">
+                    <i class="event-geodata" style="display: none;"
+                       data-id="{event.id}"
+                       data-long="{event.longitude}"
+                       data-lat="{event.latitude}"
+                       data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                    </i>
+                </div>
+            </f:then>
+        </f:if>
+
+    </div>
+</f:section>

+ 73 - 0
ot_templating/Resources/Private/Templates/Event/Index.html

@@ -0,0 +1,73 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-all-events">
+
+        <div class="events-controls">
+            <div class="event-search">
+                <h3>Rechercher un évènement: </h3>
+                <f:form action="index">
+                    <f:form.textfield name="search-loc" placeholder="Où?" value="{args.search-loc}"/>
+                    <f:form.textfield name="search-name" placeholder="Quoi?" value="{args.search-name}" />
+                    <f:form.textfield name="search-datestart" placeholder="Depuis le..." class="datepicker datetimepicker" value="{args.search-datestart}" />
+                    <f:form.textfield name="search-dateend" placeholder="Jusqu'au..." class="datepicker datetimepicker" value="{args.search-dateend}" />
+                    <f:form.button name="search-submit">Rechercher</f:form.button>
+                </f:form>
+            </div>
+            <div id="event-map" data-records="">
+                <f:for each="{allEvents}" as="event">
+                    <f:if condition="{event.longitude}">
+                        <f:then>
+                            <i class="event-geodata" style="display: none;"
+                               data-id="{event.id}"
+                               data-long="{event.longitude}"
+                               data-lat="{event.latitude}"
+                               data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                            </i>
+                        </f:then>
+                    </f:if>
+                </f:for>
+            </div>
+        </div>
+
+        <div class="events-results">
+            <f:if condition="{allEvents -> f:count()} == 0">
+                <span>Aucun résultat</span>
+            </f:if>
+
+            <f:for each="{allEvents}" as="event">
+                <div class="event" data-id="{event.id}">
+                    <div class="event-preview">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-loc-date">
+                                {event.locAndDate}
+                            </span>
+                            <span class="event-description">
+                                {event.shortDescription}
+                            </span>
+                        </div>
+                    </div>
+
+                    <f:link.action action="show" arguments="{eventId: event.id}" class="event-see"><i class="fa fa-plus" style="margin-right: 5px;"></i><span>Plus d'infos</span></f:link.action>
+                </div>
+            </f:for>
+        </div>
+    </div>
+
+</f:section>

+ 73 - 0
ot_templating/Resources/Private/Templates/Event/Modern/Index.html

@@ -0,0 +1,73 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-all-events">
+        <h1>Youhou!</h1>
+        <div class="events-controls">
+            <div class="event-search">
+                <h3>Rechercher un évènement: </h3>
+                <f:form action="index">
+                    <f:form.textfield name="search-loc" placeholder="Où?" value="{args.search-loc}"/>
+                    <f:form.textfield name="search-name" placeholder="Quoi?" value="{args.search-name}" />
+                    <f:form.textfield name="search-datestart" placeholder="Depuis le..." class="datepicker datetimepicker" value="{args.search-datestart}" />
+                    <f:form.textfield name="search-dateend" placeholder="Jusqu'au..." class="datepicker datetimepicker" value="{args.search-dateend}" />
+                    <f:form.button name="search-submit">Rechercher</f:form.button>
+                </f:form>
+            </div>
+            <div id="event-map" data-records="">
+                <f:for each="{allEvents}" as="event">
+                    <f:if condition="{event.longitude}">
+                        <f:then>
+                            <i class="event-geodata" style="display: none;"
+                               data-id="{event.id}"
+                               data-long="{event.longitude}"
+                               data-lat="{event.latitude}"
+                               data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                            </i>
+                        </f:then>
+                    </f:if>
+                </f:for>
+            </div>
+        </div>
+
+        <div class="events-results">
+            <f:if condition="{allEvents -> f:count()} == 0">
+                <span>Aucun résultat</span>
+            </f:if>
+
+            <f:for each="{allEvents}" as="event">
+                <div class="event" data-id="{event.id}">
+                    <div class="event-preview">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-loc-date">
+                                {event.locAndDate}
+                            </span>
+                            <span class="event-description">
+                                {event.shortDescription}
+                            </span>
+                        </div>
+                    </div>
+
+                    <f:link.action action="show" arguments="{eventId: event.id}" class="event-see"><i class="fa fa-plus" style="margin-right: 5px;"></i><span>Plus d'infos</span></f:link.action>
+                </div>
+            </f:for>
+        </div>
+    </div>
+
+</f:section>

+ 8 - 0
ot_templating/Resources/Private/Templates/Event/Modern/NoEvents.html

@@ -0,0 +1,8 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-no-events">
+        <p>Aucun évènement n'est prévu pour le moment.</p>
+        <p>Plus d'évènements sur <a href="{settings.opentalentWebsite}">{settings.opentalentWebsite}</a>  </p>
+    </div>
+</f:section>

+ 161 - 0
ot_templating/Resources/Private/Templates/Event/Modern/Preview.html

@@ -0,0 +1,161 @@
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
+
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <f:comment><!-- Get the events page' uid if the page is found --></f:comment>
+    <v:variable.set value="{ot:eventsPage.getId()}" name="eventsPageUid"/>
+
+    <div class="ot-box ot-events">
+        <div class="events-list">
+            <header>
+                <h3>Nos prochains évènements</h3>
+            </header>
+
+            <f:for each="{events}" as="event">
+
+                <div class="event-card">
+
+                    <div class="event-poster">
+                        <f:if condition="{event.image}">
+                            <f:then>
+                                <img src='{event.image}' alt="poster" />
+                            </f:then>
+                            <f:else>
+                                <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                            </f:else>
+                        </f:if>
+                    </div>
+
+                    <div class="event-summary">
+                        <span class="event-name">
+                            {event.name}
+                        </span>
+                        <span class="event-date">
+                            {f:format.date(date: event.datetimeStart,
+                                           format: "\l\e d-m-Y \à H\hi")}
+                        </span>
+                        <f:if condition="{eventsPageUid} > 0"><f:then>
+                            <span class="event-see">
+                                <f:link.action pageUid="{eventsPageUid}" action="show" arguments="{eventId: event.id}">
+                                    Plus d'infos
+                                </f:link.action>
+                            </span>
+                        </f:then></f:if>
+                    </div>
+
+                </div>
+            </f:for>
+
+            <f:if condition="{events -> f:count()} == 0">
+                <f:then>
+                    <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                </f:then>
+            </f:if>
+
+            <footer>
+                <f:if condition="{eventsPageUid} > 0"><f:then>
+                    <div class="event-see-all">
+                        <f:link.page pageUid="{eventsPageUid}">
+                            Voir tous les évènements
+                        </f:link.page>
+                    </div>
+                </f:then></f:if>
+            </footer>
+        </div>
+
+        <v:condition.variable.isset name="networkEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de notre réseau</h3>
+                </header>
+
+                <f:for each="{networkEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{networkEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+
+        <v:condition.variable.isset name="structuresEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de nos structures</h3>
+                </header>
+
+                <f:for each="{structuresEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{structuresEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+    </div>
+</f:section>

+ 59 - 0
ot_templating/Resources/Private/Templates/Event/Modern/Show.html

@@ -0,0 +1,59 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-show-event">
+
+        <header>
+            <h2 class="event-name">{event.name}</h2>
+            <f:link.action class="go-back"><i class="fa fa-list"> </i> Revenir à la liste des évènements</f:link.action>
+        </header>
+
+        <div class="event-content">
+
+            <div class="event-poster">
+                <f:if condition="{event.image}">
+                    <f:then>
+                        <img src='{event.image}' alt="poster" />
+                    </f:then>
+                    <f:else>
+                        <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                    </f:else>
+                </f:if>
+            </div>
+
+            <div class="event-summary">
+                <table class="event-infos">
+                    <tr>
+                        <td>Quand?</td>
+                        <td>
+                            {event.formattedDates}
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>Où?</td>
+                        <td>
+                            {f:format.nl2br(value: '{event.fullAdress}')}
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+        <p class="event-description">
+            {f:format.nl2br(value: '{event.description}')}
+        </p>
+        <f:if condition="{event.longitude}">
+            <f:then>
+                <div id="event-map">
+                    <i class="event-geodata" style="display: none;"
+                       data-id="{event.id}"
+                       data-long="{event.longitude}"
+                       data-lat="{event.latitude}"
+                       data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                    </i>
+                </div>
+            </f:then>
+        </f:if>
+
+    </div>
+</f:section>

+ 8 - 0
ot_templating/Resources/Private/Templates/Event/NoEvents.html

@@ -0,0 +1,8 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-no-events">
+        <p>Aucun évènement n'est prévu pour le moment.</p>
+        <p>Plus d'évènements sur <a href="{settings.opentalentWebsite}">{settings.opentalentWebsite}</a>  </p>
+    </div>
+</f:section>

+ 161 - 0
ot_templating/Resources/Private/Templates/Event/Preview.html

@@ -0,0 +1,161 @@
+{namespace v=FluidTYPO3\Vhs\ViewHelpers}
+{namespace ot=Opentalent\OtTemplating\ViewHelpers}
+
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <f:comment><!-- Get the events page' uid if the page is found --></f:comment>
+    <v:variable.set value="{ot:eventsPage.getId()}" name="eventsPageUid"/>
+
+    <div class="ot-box ot-events">
+        <div class="events-list">
+            <header>
+                <h3>Nos prochains évènements</h3>
+            </header>
+
+            <f:for each="{events}" as="event">
+
+                <div class="event-card">
+
+                    <div class="event-poster">
+                        <f:if condition="{event.image}">
+                            <f:then>
+                                <img src='{event.image}' alt="poster" />
+                            </f:then>
+                            <f:else>
+                                <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                            </f:else>
+                        </f:if>
+                    </div>
+
+                    <div class="event-summary">
+                        <span class="event-name">
+                            {event.name}
+                        </span>
+                        <span class="event-date">
+                            {f:format.date(date: event.datetimeStart,
+                                           format: "\l\e d-m-Y \à H\hi")}
+                        </span>
+                        <f:if condition="{eventsPageUid} > 0"><f:then>
+                            <span class="event-see">
+                                <f:link.action pageUid="{eventsPageUid}" action="show" arguments="{eventId: event.id}">
+                                    Plus d'infos
+                                </f:link.action>
+                            </span>
+                        </f:then></f:if>
+                    </div>
+
+                </div>
+            </f:for>
+
+            <f:if condition="{events -> f:count()} == 0">
+                <f:then>
+                    <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                </f:then>
+            </f:if>
+
+            <footer>
+                <f:if condition="{eventsPageUid} > 0"><f:then>
+                    <div class="event-see-all">
+                        <f:link.page pageUid="{eventsPageUid}">
+                            Voir tous les évènements
+                        </f:link.page>
+                    </div>
+                </f:then></f:if>
+            </footer>
+        </div>
+
+        <v:condition.variable.isset name="networkEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de notre réseau</h3>
+                </header>
+
+                <f:for each="{networkEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{networkEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+
+        <v:condition.variable.isset name="structuresEvents">
+            <div class="events-list">
+                <header>
+                    <h3>Prochains événements de nos structures</h3>
+                </header>
+
+                <f:for each="{structuresEvents}" as="event">
+
+                    <div class="event-card">
+
+                        <div class="event-poster">
+                            <f:if condition="{event.image}">
+                                <f:then>
+                                    <img src='{event.image}' alt="poster" />
+                                </f:then>
+                                <f:else>
+                                    <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                                </f:else>
+                            </f:if>
+                        </div>
+
+                        <div class="event-summary">
+                            <span class="event-name">
+                                {event.name}
+                            </span>
+                            <span class="event-date">
+                                {f:format.date(date: event.datetimeStart,
+                                               format: "\l\e d-m-Y \à H\hi")}
+                            </span>
+                            <span class="event-see">
+                                <a href="https://{event.subDomain}.opentalent.fr" target="_blank">Plus d'infos</a>
+                            </span>
+                        </div>
+
+                    </div>
+                </f:for>
+
+                <f:if condition="{structuresEvents -> f:count()} == 0">
+                    <f:then>
+                        <span class="no-events"><p>Aucun évènement dans les prochaines semaines</p></span>
+                    </f:then>
+                </f:if>
+
+            </div>
+        </v:condition.variable.isset>
+    </div>
+</f:section>

+ 59 - 0
ot_templating/Resources/Private/Templates/Event/Show.html

@@ -0,0 +1,59 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+
+    <div class="ot-show-event">
+
+        <header>
+            <h2 class="event-name">{event.name}</h2>
+            <f:link.action class="go-back"><i class="fa fa-list"> </i> Revenir à la liste des évènements</f:link.action>
+        </header>
+
+        <div class="event-content">
+
+            <div class="event-poster">
+                <f:if condition="{event.image}">
+                    <f:then>
+                        <img src='{event.image}' alt="poster" />
+                    </f:then>
+                    <f:else>
+                        <f:image src="EXT:ot_templating/Resources/Public/media/event-default.jpg" alt="poster" />
+                    </f:else>
+                </f:if>
+            </div>
+
+            <div class="event-summary">
+                <table class="event-infos">
+                    <tr>
+                        <td>Quand?</td>
+                        <td>
+                            {event.formattedDates}
+                        </td>
+                    </tr>
+                    <tr>
+                        <td>Où?</td>
+                        <td>
+                            {f:format.nl2br(value: '{event.fullAdress}')}
+                        </td>
+                    </tr>
+                </table>
+            </div>
+        </div>
+        <p class="event-description">
+            {f:format.nl2br(value: '{event.description}')}
+        </p>
+        <f:if condition="{event.longitude}">
+            <f:then>
+                <div id="event-map">
+                    <i class="event-geodata" style="display: none;"
+                       data-id="{event.id}"
+                       data-long="{event.longitude}"
+                       data-lat="{event.latitude}"
+                       data-label="<b>{event.name}</b><br/>{event.locAndDate}">
+                    </i>
+                </div>
+            </f:then>
+        </f:if>
+
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/Classic/GetMembers.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByInstrument -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByInstrument}" as="members" key="instrument">
+                   <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.instrument.{instrument}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/assets/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/Classic/GetMembersCa.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByMission -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByMission}" as="members" key="mission">
+                    <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.role.{mission}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/GetMembers.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByInstrument -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByInstrument}" as="members" key="instrument">
+                   <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.instrument.{instrument}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/assets/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/GetMembersCa.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByMission -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByMission}" as="members" key="mission">
+                    <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.role.{mission}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/Modern/GetMembers.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByInstrument -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByInstrument}" as="members" key="instrument">
+                   <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.instrument.{instrument}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/assets/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

+ 48 - 0
ot_templating/Resources/Private/Templates/Member/Modern/GetMembersCa.html

@@ -0,0 +1,48 @@
+<f:layout name="Default" />
+
+<f:section name="content">
+    <div class="ot-members">
+        <f:if condition="{membersByMission -> f:count()} > 0">
+            <f:then>
+                <f:for each="{membersByMission}" as="members" key="mission">
+                    <h3>
+                        <f:format.case
+                                value="{f:translate(key: 'member.role.{mission}')}"
+                                mode="upper">
+                        </f:format.case>
+                    </h3>
+                    <ul class="ot-members-list">
+                        <f:for each="{members}" as="member">
+                            <li class="ot-member">
+                                <p class="ot-member-image">
+                                    <f:if condition="{member.image}">
+                                        <f:then>
+                                            <img src="{member.image}/160x0"/>
+                                        </f:then>
+                                        <f:else>
+                                            <f:if condition="{member.gender}=='MISTER'">
+                                                <f:then>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/man-default.jpg"/>
+                                                </f:then>
+                                                <f:else>
+                                                    <f:image src="EXT:ot_templating/Resources/Public/media/woman-default.jpg"/>
+                                                </f:else>
+                                            </f:if>
+                                        </f:else>
+                                    </f:if>
+                                </p>
+                                <p class="ot-member-name">
+                                    {member.fullName}
+                                </p>
+                            </li>
+                        </f:for>
+                    </ul>
+                </f:for>
+
+            </f:then>
+            <f:else>
+                <h5>Aucun adhérent</h5>
+            </f:else>
+        </f:if>
+    </div>
+</f:section>

BIN
ot_templating/Resources/Public/Icons/relation.gif


BIN
ot_templating/Resources/Public/Icons/tx_otwidgets_domain_model_event.gif


BIN
ot_templating/Resources/Public/Icons/tx_otwidgets_domain_model_organization.gif


BIN
ot_templating/Resources/Public/Icons/tx_widgets_domain_model_event.gif


BIN
ot_templating/Resources/Public/Icons/tx_widgets_domain_model_organization.gif


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3 - 0
ot_templating/Resources/Public/Icons/user_plugin_donors.svg


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
ot_templating/Resources/Public/Icons/user_plugin_events.svg


+ 1 - 1
ot_templating/Resources/Public/assets/Classic/style/module/_donors-box.scss

@@ -1,4 +1,4 @@
-// Donor's box from ot_widgets
+// Donor's box
 
 .ot-donors .donor-list {
   display: flex;

+ 1 - 1
ot_templating/Resources/Public/assets/Classic/style/module/_ot-box.scss

@@ -1,4 +1,4 @@
-// Box container widget from ot_widgets
+// Box container widget
 $otbox-header-background-color: $otbox-header-background-color;
 $otbox-header-font-color: $otbox-header-font-color;
 $otbox-header-font-size: $otbox-header-font-size;

+ 0 - 1
ot_templating/Resources/Public/assets/Modern/style/custom.css

@@ -493,7 +493,6 @@ Events pages
         flex-direction: column;
         border-bottom: solid 2px #cccccc;
         border-radius: 4px;
-        height: 200px;
         padding: 1em;
         justify-content: space-around;
     }

BIN
ot_templating/Resources/Public/media/event-default.jpg


BIN
ot_templating/Resources/Public/media/man-default.jpg


BIN
ot_templating/Resources/Public/media/woman-default.jpg


+ 13 - 1
ot_templating/composer.json

@@ -12,10 +12,22 @@
         "typo3/cms-core": "^8.7.1 || ^10.4",
         "fluidtypo3/vhs": "^6",
         "fluidtypo3/flux": "^9",
-        "fluidtypo3/fluidpages": "^5"
+        "fluidtypo3/fluidpages": "^5",
+        "guzzlehttp/guzzle": "^6",
+        "ext-json": "^1.6"
     },
     "replace": {
         "ot_templating": "self.version",
         "typo3-ter/ot_templating": "self.version"
+    },
+    "autoload": {
+        "psr-4": {
+            "Opentalent\\OtTemplating\\": "Classes"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Opentalent\\OtTemplating\\Tests\\": "Tests"
+        }
     }
 }

+ 95 - 0
ot_templating/ext_localconf.php

@@ -6,3 +6,98 @@ if (!defined('TYPO3_MODE')) {
 
 \FluidTYPO3\Flux\Core::registerProviderExtensionKey('OpenTalent.OtTemplating', 'Page');
 \FluidTYPO3\Flux\Core::registerProviderExtensionKey('OpenTalent.OtTemplating', 'Content');
+
+
+call_user_func(
+    function()
+    {
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
+            'Opentalent.OtTemplating',
+            'Events',
+            [
+                'Event' => 'preview'
+            ],
+            // non-cacheable actions
+            [
+                'Event' => '',
+            ]
+        );
+
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
+            'Opentalent.OtTemplating',
+            'AllEvents',
+            [
+                'Event' => 'index,show,noEvents'
+            ],
+            // non-cacheable actions
+            [
+                'Event' => '',
+            ]
+        );
+
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
+            'Opentalent.OtTemplating',
+            'Donors',
+            [
+                'Donor' => 'getDonors'
+            ],
+            // non-cacheable actions
+            [
+            ]
+        );
+
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
+            'Opentalent.OtTemplating',
+            'Members',
+            [
+                'Member' => 'getMembers,getMembersCa'
+            ],
+            // non-cacheable actions
+            [
+            ]
+        );
+
+        // wizards
+        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
+            'mod {
+            wizards.newContentElement.wizardItems.plugins {
+                elements {
+                    events {
+                        iconIdentifier = ot_templating-plugin-events
+                        title = LLL:EXT:ot_templating/Resources/Private/Language/locallang_db.xlf:tx_ot_templating_events.name
+                        description = LLL:EXT:ot_templating/Resources/Private/Language/locallang_db.xlf:tx_ot_templating_events.description
+                        tt_content_defValues {
+                            CType = list
+                            list_type = ottemplating_events
+                        }
+                    }
+                    donors {
+                        iconIdentifier = ot_templating-plugin-donors
+                        title = LLL:EXT:ot_templating/Resources/Private/Language/locallang_db.xlf:tx_ot_templating_donors.name
+                        description = LLL:EXT:ot_templating/Resources/Private/Language/locallang_db.xlf:tx_ot_templating_donors.description
+                        tt_content_defValues {
+                            CType = list
+                            list_type = ottemplating_donors
+                        }
+                    }
+                }
+                show = *
+            }
+       }'
+        );
+        $iconRegistry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\IconRegistry::class);
+
+        $iconRegistry->registerIcon(
+            'ot_templating-plugin-events',
+            \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
+            ['source' => 'EXT:ot_templating/Resources/Public/Icons/user_plugin_events.svg']
+        );
+
+        $iconRegistry->registerIcon(
+            'ot_templating-plugin-donors',
+            \TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider::class,
+            ['source' => 'EXT:ot_templating/Resources/Public/Icons/user_plugin_donors.svg']
+        );
+
+    }
+);

+ 19 - 0
ot_templating/ext_tables.php

@@ -4,8 +4,27 @@ defined('TYPO3_MODE') || die('Access denied.');
 call_user_func(
     function()
     {
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
+            'Opentalent.OtTemplating',
+            'Events',
+            'Prochains Evènements',
+            'EXT:ot_templating/Resources/Public/Icons/opentalent-32x32.png'
+        );
+
+        \TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
+            'Opentalent.OtTemplating',
+            'Donors',
+            'Partenaires',
+            'EXT:ot_templating/Resources/Public/Icons/opentalent-32x32.png'
+        );
 
         \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile('ot_templating', 'Configuration/TypoScript', 'Templating');
 
+        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_ottemplating_domain_model_event', 'EXT:ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_event.xlf');
+        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_ottemplating_domain_model_event');
+
+        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addLLrefForTCAdescr('tx_ottemplating_domain_model_donor', 'EXT:ot_templating/Resources/Private/Language/locallang_csh_tx_ottemplating_domain_model_donor.xlf');
+        \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::allowTableOnStandardPages('tx_ottemplating_domain_model_donor');
+
     }
 );

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است