diff --git a/src/Biopen/CoreBundle/Admin/ConfigurationFormAdmin.php b/src/Biopen/CoreBundle/Admin/ConfigurationFormAdmin.php index 2b505541146a0bad946f897a13d74311f5bf580f..df3f36a341d9753ce7196fb03f6a577d52577983 100755 --- a/src/Biopen/CoreBundle/Admin/ConfigurationFormAdmin.php +++ b/src/Biopen/CoreBundle/Admin/ConfigurationFormAdmin.php @@ -46,7 +46,17 @@ class ConfigurationFormAdmin extends ConfigurationAbstractAdmin ->add('elementFormGeocodingHelp', 'textarea' , array('required' => false, 'label' => "Texte d'aide pour la geolocalisation")) - ->end() + ->end() + ->end() + ->tab('Sémantique') + ->with('Sémantique', array('class' => 'col-md-12', "description" => "Définir le contexte sémantique des données permet de plus facilement partager les données, afin qu'on puisse proposer un API sous forme de JSON-LD.<br/>Il vous faut aussi définir le type sémantique pour chaque champ que vous voulez partager dans l'onglet Formulaire de cette page.")) + ->add('elementFormSemanticContext', 'textarea', + array('required' => false, 'attr' => ['placeholder' => 'Exemple: https://schema.org'], + 'label' => "Contexte sémantique des éléments", 'label_attr' => ['title' => "Vous pouvez définir plusieurs contextes sous format de JSON"])) + ->add('elementFormSemanticType', 'text', + array('required' => false, 'attr' => ['placeholder' => 'Exemple: Place'], + 'label' => "Type sémantique des éléments", 'label_attr' => ['title' => "Vous pouvez définir plusieurs types séparés par une virgule"])) + ->end() ->end() ; } diff --git a/src/Biopen/CoreBundle/Document/Configuration.php b/src/Biopen/CoreBundle/Document/Configuration.php index 87ddbbbaa718824164801953c10fa91d78f963e8..a18ba2efe576ba14067bf9f1d2851a09ca1e1ccd 100644 --- a/src/Biopen/CoreBundle/Document/Configuration.php +++ b/src/Biopen/CoreBundle/Document/Configuration.php @@ -310,6 +310,11 @@ class Configuration implements \JsonSerializable /** @MongoDB\Field(type="string") */ protected $elementFormFieldsJson = "[{\"type\":\"taxonomy\",\"label\":\"Choisissez la ou les catégories par ordre d'importance\",\"name\":\"taxonomy\"},{\"type\":\"separator\",\"label\":\"Séparateur de section\",\"name\":\"separator-1539422234804\"},{\"type\":\"header\",\"subtype\":\"h1\",\"label\":\"Informations\"},{\"type\":\"title\",\"required\":true,\"label\":\"Titre de la fiche\",\"name\":\"name\",\"maxlength\":\"80\",\"icon\":\"gogo-icon-account-circle\"},{\"type\":\"textarea\",\"required\":true,\"label\":\"Description courte\",\"name\":\"description\",\"subtype\":\"textarea\",\"maxlength\":\"250\"},{\"type\":\"textarea\",\"label\":\"Description longue\",\"name\":\"descriptionMore\",\"subtype\":\"textarea\",\"maxlength\":\"600\"},{\"type\":\"address\",\"label\":\"Adresse complète\",\"name\":\"address\",\"icon\":\"gogo-icon-marker-symbol\"},{\"type\":\"separator\",\"label\":\"Séparateur de section\",\"name\":\"separator-1539423917238\"},{\"type\":\"header\",\"subtype\":\"h1\",\"label\":\"Contact (optionnel)\"},{\"type\":\"text\",\"subtype\":\"tel\",\"label\":\"Téléphone\",\"name\":\"telephone\"},{\"type\":\"email\",\"label\":\"Mail\",\"name\":\"email\"},{\"type\":\"text\",\"subtype\":\"url\",\"label\":\"Site web\",\"name\":\"website\"},{\"type\":\"separator\",\"label\":\"Séparateur de section\",\"name\":\"separator-1539424058076\"},{\"type\":\"header\",\"subtype\":\"h1\",\"label\":\"Horaires (optionnel)\"},{\"type\":\"openhours\",\"label\":\"Horaires\",\"name\":\"openhours\"}]"; + /** @MongoDB\Field(type="string") */ + protected $elementFormSemanticContext; + + /** @MongoDB\Field(type="string") */ + protected $elementFormSemanticType; // ---------------------------- // -------- IMPORTS ----------- @@ -3030,4 +3035,48 @@ class Configuration implements \JsonSerializable { return str_replace(' ', '', $this->searchExcludingWords); } + + /** + * Set elementFormSemanticContext + * + * @param string $elementFormSemanticContext + * @return $this + */ + public function setElementFormSemanticContext($elementFormSemanticContext) + { + $this->elementFormSemanticContext = $elementFormSemanticContext; + return $this; + } + + /** + * Get elementFormSemanticContext + * + * @return string $elementFormSemanticContext + */ + public function getElementFormSemanticContext() + { + return $this->elementFormSemanticContext; + } + + /** + * Set elementFormSemanticType + * + * @param string $elementFormSemanticType + * @return $this + */ + public function setElementFormSemanticType($elementFormSemanticType) + { + $this->elementFormSemanticType = $elementFormSemanticType; + return $this; + } + + /** + * Get elementFormSemanticType + * + * @return string $elementFormSemanticType + */ + public function getElementFormSemanticType() + { + return $this->elementFormSemanticType; + } } diff --git a/src/Biopen/GeoDirectoryBundle/Admin/Element/ElementAdminShowEdit.php b/src/Biopen/GeoDirectoryBundle/Admin/Element/ElementAdminShowEdit.php index d1e3e0106bb35ae45d489f643a7f0621ca0cb711..6e38b092d391c56e27ae753858a4f4049f525fc0 100755 --- a/src/Biopen/GeoDirectoryBundle/Admin/Element/ElementAdminShowEdit.php +++ b/src/Biopen/GeoDirectoryBundle/Admin/Element/ElementAdminShowEdit.php @@ -105,6 +105,7 @@ class ElementAdminShowEdit extends ElementAdminList ->add('baseJson') ->add('privateJson') ->add('adminJson') + ->add('semanticJson') ->end(); } } \ No newline at end of file diff --git a/src/Biopen/GeoDirectoryBundle/Controller/APIController.php b/src/Biopen/GeoDirectoryBundle/Controller/APIController.php index 3e2da7bb5028a050d9120af284ad88c1154c8359..43ae7049e1cf55ed4c33712ce145b665f7a6d72b 100755 --- a/src/Biopen/GeoDirectoryBundle/Controller/APIController.php +++ b/src/Biopen/GeoDirectoryBundle/Controller/APIController.php @@ -2,6 +2,7 @@ namespace Biopen\GeoDirectoryBundle\Controller; +use Biopen\GeoDirectoryBundle\Document\ElementJsonOntology; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Biopen\CoreBundle\Controller\GoGoController; @@ -18,7 +19,7 @@ class APIController extends GoGoController * @bounds * @categories (ids) * @stamps (ids) - * @ontology ( gogofull or gogocompact ) + * @ontology (gogofull, gogocompact or semantic) -> see ElementJsonOntology **/ public function getElementsAction(Request $request, $id = null, $_format = 'json') { @@ -26,8 +27,7 @@ class APIController extends GoGoController $jsonLdRequest = $this->isJsonLdRequest($request, $_format); $token = $request->get('token'); - $ontology = $request->get('ontology') ? strtolower($request->get('ontology')) : "gogofull"; - $fullRepresentation = $jsonLdRequest || $ontology != "gogocompact"; + $ontology = $jsonLdRequest ? ElementJsonOntology::Semantic : ( $request->get('ontology') ? strtolower($request->get('ontology')) : ElementJsonOntology::Full ); $elementId = $id ? $id : $request->get('id'); $config = $em->getRepository('BiopenCoreBundle:Configuration')->findConfiguration(); $protectWithToken = $config->getApi()->getProtectPublicApiWithToken(); @@ -62,7 +62,10 @@ class APIController extends GoGoController if ($elementId) { $element = $elementRepo->findOneBy(array('id' => $elementId)); - $elementsJson = $element ? $element->getJson($includePrivateFields, $isAdmin) : null; + $elementsJson = $element ? $element->getJson($ontology, $includePrivateFields, $isAdmin) : null; + if( $elementsJson && $ontology === ElementJsonOntology::Semantic ) { + $elementsJson = $this->appendSemanticContextAndType($elementsJson); + } } else { @@ -71,13 +74,13 @@ class APIController extends GoGoController $boxes = []; $bounds = explode( ';' , $request->get('bounds')); foreach ($bounds as $key => $bound) $boxes[] = explode( ',' , $bound); - $elementsFromDB = $elementRepo->findWhithinBoxes($boxes, $request, $fullRepresentation, $isAdmin); + $elementsFromDB = $elementRepo->findWhithinBoxes($boxes, $request, $ontology, $isAdmin); } else { - $elementsFromDB = $elementRepo->findAllPublics($fullRepresentation, $isAdmin, $request); + $elementsFromDB = $elementRepo->findAllPublics($ontology, $isAdmin, $request); } - $elementsJson = $this->encodeElementArrayToJsonArray($elementsFromDB, $fullRepresentation, $isAdmin, $includePrivateFields); + $elementsJson = $this->encodeElementArrayToJsonArray($elementsFromDB, $ontology, $isAdmin, $includePrivateFields, $config); } $status = 200; @@ -88,10 +91,7 @@ class APIController extends GoGoController } else if ($jsonLdRequest) { - $responseJson = '{ - "@context" : "https://rawgit.com/jmvanel/rdf-convert/master/context-gogo.jsonld", - "@graph" : '. $elementsJson . ' - }'; + $responseJson = $elementsJson; } else { @@ -99,7 +99,7 @@ class APIController extends GoGoController "licence": "' . $config->getDataLicenseUrl() . '", "ontology":"'. $ontology . '"'; - if (!$fullRepresentation) + if ($ontology === ElementJsonOntology::Compact ) { $mapping = ['id', $config->getMarker()->getFieldsUsedByTemplate(), 'latitude', 'longitude', 'status', 'moderationState']; $responseJson .= ', "mapping":' . json_encode($mapping); @@ -185,8 +185,8 @@ class APIController extends GoGoController $elements = $em->getRepository('BiopenGeoDirectoryBundle:Element')->findElementsWithText($request->get('text'), true, $isAdmin); - $elementsJson = $this->encodeElementArrayToJsonArray($elements, true, $isAdmin, true); - $responseJson = '{ "data":'. $elementsJson . ', "ontology" : "gogofull"}'; + $elementsJson = $this->encodeElementArrayToJsonArray($elements, ElementJsonOntology::Full, $isAdmin, true); + $responseJson = '{ "data":'. $elementsJson . ', "ontology" : "' . ElementJsonOntology::Full . '"}'; $config = $em->getRepository('BiopenCoreBundle:Configuration')->findConfiguration(); return $this->createResponse($responseJson, $config); @@ -204,28 +204,40 @@ class APIController extends GoGoController return false; } - private function encodeElementArrayToJsonArray($array, $fullRepresentation, $isAdmin = false, $includePrivateFields = false) + private function encodeElementArrayToJsonArray($array, $ontology, $isAdmin = false, $includePrivateFields = false, $config = null ) { - $elementsJson = '['; + $elementsJson = '['; foreach ($array as $key => $value) - { - if ($fullRepresentation == 'true') - { - $elementJson = $value['baseJson']; - if ($includePrivateFields && $value['privateJson'] != '{}') { - $elementJson = substr($elementJson , 0, -1) . ',' . substr($value['privateJson'],1); - } - if ($isAdmin && $value['adminJson'] != '{}') { - $elementJson = substr($elementJson , 0, -1) . ',' . substr($value['adminJson'],1); - } - if (key_exists('score', $value)) { - // remove first '{' - $elementJson = substr($elementJson, 1); - $elementJson = '{"searchScore" : ' . $value['score'] . ',' . $elementJson; + { + switch($ontology) { + case ElementJsonOntology::Full: + $elementJson = $value['baseJson']; + if ($includePrivateFields && $value['privateJson'] != '{}') { + $elementJson = substr($elementJson , 0, -1) . ',' . substr($value['privateJson'],1); + } + if ($isAdmin && $value['adminJson'] != '{}') { + $elementJson = substr($elementJson , 0, -1) . ',' . substr($value['adminJson'],1); + } + if (key_exists('score', $value)) { + // remove first '{' + $elementJson = substr($elementJson, 1); + $elementJson = '{"searchScore" : ' . $value['score'] . ',' . $elementJson; + } + break; + + case ElementJsonOntology::Compact: + $elementJson = $value['compactJson']; + break; + + case ElementJsonOntology::Semantic: + $elementJson = $value['semanticJson']; + $elementJson = $this->appendSemanticContextAndType($elementJson); + break; + + default: + throw new \Exception('Unknown ontology : ' . $ontology); } - } - else $elementJson = $value['compactJson']; - $elementsJson .= $elementJson . ','; + $elementsJson .= $elementJson . ','; } $elementsJson = rtrim($elementsJson,",") . ']'; @@ -241,5 +253,16 @@ class APIController extends GoGoController return $this->createResponse(json_encode($gogocartoConf), $config); } + + public function appendSemanticContextAndType($semanticJson) + { + $em = $this->get('doctrine_mongodb')->getManager(); + $config = $em->getRepository('BiopenCoreBundle:Configuration')->findConfiguration(); + + return '{ + "@context" : "' . $config->getElementFormSemanticContext() . '", + "@type" : "' . $config->getElementFormSemanticType() . '", + ' . substr($semanticJson, 1); + } } \ No newline at end of file diff --git a/src/Biopen/GeoDirectoryBundle/Document/Element.php b/src/Biopen/GeoDirectoryBundle/Document/Element.php index c2cb469cf4d093da0b0c1f650eac71cf44bb749d..05503ab19bfe04ca0e76b769ffb61e3b11227c2b 100644 --- a/src/Biopen/GeoDirectoryBundle/Document/Element.php +++ b/src/Biopen/GeoDirectoryBundle/Document/Element.php @@ -302,6 +302,15 @@ class Element */ private $adminJson; + /** + * @var string + * + * The Json representation of all elements semantically-defined + * + * @MongoDB\Field(type="string") + */ + private $semanticJson; + /** * @var date $createdAt * @@ -505,14 +514,26 @@ class Element public function isDynamicImported() { return $this->isExternal; } - public function getJson($includePrivateJson, $includeAdminJson) + public function getJson($ontology, $includePrivateJson, $includeAdminJson) { - $result = $this->baseJson; - if ($includePrivateJson && $this->privateJson && $this->privateJson != '{}') - $result = substr($result , 0, -1) . ',' . substr($this->privateJson,1); - if ($includeAdminJson && $this->adminJson && $this->adminJson != '{}') - $result = substr($result , 0, -1) . ',' . substr($this->adminJson,1); - return $result; + switch($ontology) { + case ElementJsonOntology::Full: + $result = $this->baseJson; + if ($includePrivateJson && $this->privateJson && $this->privateJson != '{}') + $result = substr($result , 0, -1) . ',' . substr($this->privateJson,1); + if ($includeAdminJson && $this->adminJson && $this->adminJson != '{}') + $result = substr($result , 0, -1) . ',' . substr($this->adminJson,1); + return $result; + + case ElementJsonOntology::Compact: + return $this->compactJson; + + case ElementJsonOntology::Semantic: + return $this->semanticJson; + + default: + throw new \Exception('Unknown ontology : ' . $ontology); + } } public function isPending() @@ -813,6 +834,28 @@ class Element return $this->baseJson; } + /** + * Set semanticJson + * + * @param string $semanticJson + * @return $this + */ + public function setSemanticJson($semanticJson) + { + $this->semanticJson = $semanticJson; + return $this; + } + + /** + * Get semanticJson + * + * @return string $semanticJson + */ + public function getSemanticJson() + { + return $this->semanticJson; + } + /** * Add report * diff --git a/src/Biopen/GeoDirectoryBundle/Document/ElementJsonOntology.php b/src/Biopen/GeoDirectoryBundle/Document/ElementJsonOntology.php new file mode 100644 index 0000000000000000000000000000000000000000..1bb65b65098feb480045ef668f52dc9c9f1340bc --- /dev/null +++ b/src/Biopen/GeoDirectoryBundle/Document/ElementJsonOntology.php @@ -0,0 +1,10 @@ +<?php + +namespace Biopen\GeoDirectoryBundle\Document; + +abstract class ElementJsonOntology +{ + const Full = 'gogofull'; + const Compact = 'gogocompact'; + const Semantic = 'semantic'; +} diff --git a/src/Biopen/GeoDirectoryBundle/EventListener/ElementJsonGenerator.php b/src/Biopen/GeoDirectoryBundle/EventListener/ElementJsonGenerator.php index df9c00b2230fdf84960bd861178aab80006267fc..9635d446eed8147b84b6a776837b905a4441b715 100644 --- a/src/Biopen/GeoDirectoryBundle/EventListener/ElementJsonGenerator.php +++ b/src/Biopen/GeoDirectoryBundle/EventListener/ElementJsonGenerator.php @@ -3,18 +3,36 @@ namespace Biopen\GeoDirectoryBundle\EventListener; use Biopen\GeoDirectoryBundle\Document\Element; +use Biopen\GeoDirectoryBundle\Document\ElementJsonOntology; use Biopen\GeoDirectoryBundle\Document\ModerationState; use Biopen\GeoDirectoryBundle\Document\ElementStatus; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\Router; class ElementJsonGenerator { protected $currElementChangeset; protected $config = null; protected $options = null; + protected $semanticFields = []; + protected $router = null; + + public function __construct(Router $router) + { + $this->router = $router; + } public function getConfig($dm) { if (!$this->config) $this->config = $dm->getRepository('BiopenCoreBundle:Configuration')->findConfiguration(); + + $formFields = $this->config->getElementFormFields(); + foreach( $formFields as $key => $field ) { + if( isset($field->semantic) && $field->semantic != "" ) { + $this->semanticFields[$field->name] = $field->semantic; + } + } + return $this->config; } @@ -115,7 +133,7 @@ class ElementJsonGenerator // MODIFIED ELEMENT (for pending modification) if ($element->getModifiedElement()) { - $baseJson .= ', "modifiedElement": ' . $element->getModifiedElement()->getJson(true, false); + $baseJson .= ', "modifiedElement": ' . $element->getModifiedElement()->getJson(ElementJsonOntology::Full, true, false); } $baseJson .= '}'; @@ -179,6 +197,24 @@ class ElementJsonGenerator if ($element->getModerationState() != 0) $compactJson .= ','. $element->getModerationState(); $compactJson .= ']'; $element->setCompactJson($compactJson); + + // -------------------- SEMANTIC JSON ---------------- + + $semanticJson = "{"; + $semanticJson .= '"@id": "' . $this->router->generate('biopen_api_element_get', array('id'=>$element->id, '_format'=>'jsonld'), UrlGeneratorInterface::ABSOLUTE_URL) . '",'; + + if ($element->getData()) { + foreach ($element->getData() as $key => $value) { + if( array_key_exists($key, $this->semanticFields) && $value ) { + $semanticJson .= '"' . $this->semanticFields[$key] . '": ' . json_encode($value) . ','; + } + } + } + + $semanticJson = rtrim($semanticJson, ','); + $semanticJson .= '}'; + + $element->setSemanticJson($semanticJson); } // private function attrChanged($attrs) diff --git a/src/Biopen/GeoDirectoryBundle/Repository/ElementRepository.php b/src/Biopen/GeoDirectoryBundle/Repository/ElementRepository.php index 192ecf6d28e709fc75f749850fc87f2377c45762..f56c7738f2cc7dfa36e71a203d5c0547f9f84f9e 100755 --- a/src/Biopen/GeoDirectoryBundle/Repository/ElementRepository.php +++ b/src/Biopen/GeoDirectoryBundle/Repository/ElementRepository.php @@ -12,6 +12,7 @@ namespace Biopen\GeoDirectoryBundle\Repository; +use Biopen\GeoDirectoryBundle\Document\ElementJsonOntology; use Doctrine\ODM\MongoDB\DocumentRepository; use Biopen\GeoDirectoryBundle\Document\ElementStatus; use Biopen\GeoDirectoryBundle\Document\ModerationState; @@ -46,7 +47,7 @@ class ElementRepository extends DocumentRepository ->hydrate($hydrate)->getQuery()->execute()->toArray(); } - public function findWhithinBoxes($bounds, $request, $getFullRepresentation, $isAdmin = false) + public function findWhithinBoxes($bounds, $request, $ontology, $isAdmin = false) { $qb = $this->createQueryBuilder('BiopenGeoDirectoryBundle:Element'); @@ -59,7 +60,7 @@ class ElementRepository extends DocumentRepository $qb->addOr($qb->expr()->field('geo')->withinBox((float) $bound[1], (float) $bound[0], (float) $bound[3], (float) $bound[2])); if ($request) $this->filterWithRequest($qb, $request); - $this->selectJson($qb, $getFullRepresentation, $isAdmin); + $this->selectJson($qb, $ontology, $isAdmin); // execute request $results = $this->queryToArray($qb); @@ -135,7 +136,7 @@ class ElementRepository extends DocumentRepository return $qb->getQuery()->execute(); } - public function findAllPublics($getFullRepresentation, $isAdmin, $request = null) + public function findAllPublics($ontology, $isAdmin, $request = null) { $qb = $this->createQueryBuilder('BiopenGeoDirectoryBundle:Element'); @@ -143,7 +144,7 @@ class ElementRepository extends DocumentRepository $qb->field('moderationState')->equals(ModerationState::NotNeeded); if ($request) $this->filterWithRequest($qb, $request); - $this->selectJson($qb, $getFullRepresentation, $isAdmin); + $this->selectJson($qb, $ontology, $isAdmin); return $this->queryToArray($qb); } @@ -208,17 +209,24 @@ class ElementRepository extends DocumentRepository return $qb; } - private function selectJson($qb, $getFullRepresentation, $isAdmin) + private function selectJson($qb, $ontology, $isAdmin) { - // get json representation - if ($getFullRepresentation == 'true') - { - $qb->select(['baseJson', 'privateJson']); - if ($isAdmin) $qb->select('adminJson'); - } - else - { - $qb->select('compactJson'); + switch($ontology) { + case ElementJsonOntology::Full: + $qb->select(['baseJson', 'privateJson']); + if ($isAdmin) $qb->select('adminJson'); + break; + + case ElementJsonOntology::Compact: + $qb->select('compactJson'); + break; + + case ElementJsonOntology::Semantic: + $qb->select('semanticJson'); + break; + + default: + throw new \Exception('Unknown ontology: ' . $ontology); } } diff --git a/src/Biopen/GeoDirectoryBundle/Resources/config/services.yml b/src/Biopen/GeoDirectoryBundle/Resources/config/services.yml index 25e63eb1bd9e5ca3ab79747fc67f00fedaca30d5..04a8ab8ba4638b0612d8cfe5b453898413b99a5a 100755 --- a/src/Biopen/GeoDirectoryBundle/Resources/config/services.yml +++ b/src/Biopen/GeoDirectoryBundle/Resources/config/services.yml @@ -48,6 +48,7 @@ services: biopen.element_json_generator: class: Biopen\GeoDirectoryBundle\EventListener\ElementJsonGenerator + arguments: [ "@router" ] tags: - { name: doctrine_mongodb.odm.event_listener, event: preFlush } diff --git a/src/Biopen/GeoDirectoryBundle/Resources/views/admin/core_custom/custom-fields/form-builder.html.twig b/src/Biopen/GeoDirectoryBundle/Resources/views/admin/core_custom/custom-fields/form-builder.html.twig index 3b2c8cc9e87944c8a24c9e35326fffd28d531aa1..3a23a7a0a574185c734cae206a82e604355c8890 100644 --- a/src/Biopen/GeoDirectoryBundle/Resources/views/admin/core_custom/custom-fields/form-builder.html.twig +++ b/src/Biopen/GeoDirectoryBundle/Resources/views/admin/core_custom/custom-fields/form-builder.html.twig @@ -40,6 +40,7 @@ var iconAttr = { label: 'Icone', placeholder: 'Choisissez une icone' } var errorMsgAttrs = { label: "Msg. Erreur", placeholder: "Oups ce texte est un peu long ! // Veuillez renseigner une adresse email valide // ..." } + var semanticAttrs = { label: "Champ sémantique" } var typeUserAttrs = { text: { icon: iconAttr, @@ -51,12 +52,14 @@ 'url': 'Url' }, }, - errorMsg: errorMsgAttrs + errorMsg: errorMsgAttrs, + semantic: semanticAttrs }, textarea: { icon: iconAttr, errorMsg: errorMsgAttrs, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs, }, select: { icon: iconAttr, errorMsg: errorMsgAttrs }, number: { icon: iconAttr, errorMsg: errorMsgAttrs }, @@ -65,6 +68,7 @@ icon: iconAttr, errorMsg: errorMsgAttrs, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs, }, address: { icon: iconAttr }, 'checkbox-group': { @@ -83,20 +87,24 @@ icon: iconAttr, errorMsg: errorMsgAttrs, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs }, image: { icon: iconAttr, errorMsg: errorMsgAttrs, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs }, images: { icon: iconAttr, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs }, files: { icon: iconAttr, accept: { label: "Fichier acceptés", placeholder: ".pdf audio/* .mp3 (séparés par des espaces)"}, separator: { label: '' }, // separate important attrs from others + semantic: semanticAttrs } };