diff --git a/README.txt b/README.txt index af9b77c..8a2f02e 100644 --- a/README.txt +++ b/README.txt @@ -27,7 +27,13 @@ Refer project documentation for more information. INSTALLATION ------------ -The module only depends on modules in Drupal 8 core. +The module depends on modules in Drupal 8 core and select2 library. + +Download Select2 4.0.0 from +https://github.com/select2/select2/releases/tag/4.0.0. + +Extract the download and place it in libraries so you have, for + example: libraries/select2 To install RDF UI Module: * Place this module directory in your modules folder (this will usually be diff --git a/css/rdfui.dropdown.css b/css/rdfui.dropdown.css new file mode 100644 index 0000000..e3bf643 --- /dev/null +++ b/css/rdfui.dropdown.css @@ -0,0 +1,11 @@ +/** + * @file + * Styles for RDF UI select2 dropdown. + */ + +.select2-container { + display: inline-block; + position: relative; + width: 80%; +} + diff --git a/js/rdfui.dropdown.js b/js/rdfui.dropdown.js new file mode 100644 index 0000000..0f8c2ba --- /dev/null +++ b/js/rdfui.dropdown.js @@ -0,0 +1,16 @@ +/** + * @file + * Attach select2 to a dropdown element. + */ + +(function ($, Drupal) { + Drupal.behaviors.ld_tool = { + attach: function (context, settings) { + $('[id="rdf-predicate"]', context).select2({ + placeholder: "-Select Predicate-", + dropdownAutoWidth : true, + allowClear: true + }); + } + } +})(jQuery, Drupal); diff --git a/rdf_builder/src/Form/ContentBuilderForm.php b/rdf_builder/src/Form/ContentBuilderForm.php index a2293f8..129034c 100644 --- a/rdf_builder/src/Form/ContentBuilderForm.php +++ b/rdf_builder/src/Form/ContentBuilderForm.php @@ -139,7 +139,7 @@ class ContentBuilderForm extends FormBase { '#default_value' => $form_state->getValue('rdf-type', ''), '#attached' => array( 'library' => array( - 'rdfui/drupal.rdfui.autocomplete', + 'rdfui/drupal.rdfui.select2_dropdown', ), ), '#description' => $this->t('Specify the type you want to associated to this content type e.g. Article, Blog, etc.'), diff --git a/rdfui.libraries.yml b/rdfui.libraries.yml index baf0b31..53830b7 100644 --- a/rdfui.libraries.yml +++ b/rdfui.libraries.yml @@ -11,5 +11,30 @@ drupal.rdfui.autocomplete: - core/jquery.ui.tooltip - core/jquery.ui.button +select2: + version: "4.0.0" + remote: https://github.com/select2/select2 + license: + name: MIT + url: https://github.com/select2/select2/blob/master/LICENSE.md + gpl-compatible: true + js: + /libraries/select2/dist/js/select2.min.js: {} + css: + theme: + /libraries/select2/dist/css/select2.min.css: {} + dependencies: + - core/jquery +drupal.rdfui.select2_dropdown: + version: VERSION + js: + js/rdfui.dropdown.js: {} + css: + theme: + css/rdfui.dropdown.css: {} + dependencies: + - core/jquery + - core/drupal + - rdfui/select2 diff --git a/src/ContentMappings.php b/src/ContentMappings.php index 13dc65d..4ed3b26 100644 --- a/src/ContentMappings.php +++ b/src/ContentMappings.php @@ -45,7 +45,7 @@ class ContentMappings { '#empty_option' => '', '#attached' => array( 'library' => array( - 'rdfui/drupal.rdfui.autocomplete', + 'rdfui/drupal.rdfui.select2_dropdown', ), ), '#default_value' => !empty($existing_type) ? $existing_type['types'][0] : '', diff --git a/src/EasyRdfConverter.php b/src/EasyRdfConverter.php index 27478e8..7cba2a4 100644 --- a/src/EasyRdfConverter.php +++ b/src/EasyRdfConverter.php @@ -156,7 +156,7 @@ abstract class EasyRdfConverter { } /** - * Extracts properties of a given type. + * Extracts properties of a given type and returns them in hierarchical order. * * @param string $type * Schema.Org type of which the properties should be listed. @@ -165,13 +165,65 @@ abstract class EasyRdfConverter { * @return array|null * List of properties. */ - public function getTypeProperties($type) { + public function getTypePropertiesNested($type) { $tokens = explode(":", $type); $prefixes = rdf_get_namespaces(); $uri = $prefixes[$tokens[0]] . $tokens[1]; + //$options = array(); + $options = $this->getPropertiesNested($uri); + //asort($options); + return $options; + } + + /** + * Recursive function to extract properties for getTypePropertiesNested(). + * + * @param string $uri + * URI of schema type. + * + * @return array|null + * Array of properties of the type and all parent types. + */ + private function getPropertiesNested($uri) { + $resource = array("type" => "uri", "value" => $uri); + $property_list = $this->graph->resourcesMatching("http://schema.org/domainIncludes", $resource); + $label = $this->graph->label($uri)->getValue(); $options = array(); - $options += $this->getProperties($uri); + $options[$label] = array(); + + foreach ($property_list as $value) { + // Omit deprecated properties. + if ($value->get("schema:supersededBy")) { + continue; + } + $options[$label][$value->shorten()] = $value->get("rdfs:label")->getValue(); + } + asort($options[$label]); + + $parents = $this->graph->all($uri, "rdfs:subClassOf"); + foreach ($parents as $value) { + $options += $this->getPropertiesNested($value->getUri()); + } + return $options; + } + + /** + * Extracts properties of a given type and returns a list. + * + * @param string $type + * Schema.Org type of which the properties should be listed. + * (eg. "schema:Person"). + * + * @return array|null + * List of properties. + */ + public function getTypeProperties($type) { + $tokens = explode(":", $type); + $prefixes = rdf_get_namespaces(); + $uri = $prefixes[$tokens[0]] . $tokens[1]; + + $options = $this->getProperties($uri); asort($options); return $options; } diff --git a/src/Form/FieldMappings.php b/src/Form/FieldMappings.php index 1d950bd..f566329 100644 --- a/src/Form/FieldMappings.php +++ b/src/Form/FieldMappings.php @@ -19,7 +19,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface; /** * RDF UI Field Mapping form. */ -class FieldMappings extends FormBase { +class FieldMappings extends FormBase +{ /** * The EasyRdfConverter. @@ -48,7 +49,8 @@ class FieldMappings extends FormBase { /** * {@inheritdoc} */ - public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL, $bundle = NULL) { + public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL, $bundle = NULL) + { $this->entityTypeId = $entity_type_id; $this->bundle = $bundle; @@ -63,9 +65,9 @@ class FieldMappings extends FormBase { $options = NULL; $bundle_mapping = $mappings->getBundleMapping(); - if (!empty($bundle_mapping)) { + if (!empty($bundle_mapping) && !empty($bundle_mapping['types']['0'])) { $type = $bundle_mapping['types']['0']; - $options = $this->rdfConverter->getTypeProperties($type); + $options = $this->rdfConverter->getTypePropertiesNested($type); } else { $options = $this->rdfConverter->getListProperties(); } @@ -111,7 +113,7 @@ class FieldMappings extends FormBase { '#empty_option' => '', '#attached' => array( 'library' => array( - 'rdfui/drupal.rdfui.autocomplete', + 'rdfui/drupal.rdfui.select2_dropdown', ), ), '#default_value' => !empty($property) ? $property['properties'][0] : '', @@ -149,7 +151,8 @@ class FieldMappings extends FormBase { /** * {@inheritdoc} */ - public function getRegions() { + public function getRegions() + { return array( 'content' => array( 'title' => $this->t('Content'), @@ -162,14 +165,16 @@ class FieldMappings extends FormBase { /** * {@inheritdoc} */ - public function validateForm(array &$form, FormStateInterface $form_state) { + public function validateForm(array &$form, FormStateInterface $form_state) + { // @TODO implement method if validation is required. } /** * Overrides \Drupal\field_ui\FormDisplayOverview::submitForm(). */ - public function submitForm(array &$form, FormStateInterface $form_state) { + public function submitForm(array &$form, FormStateInterface $form_state) + { $form_values = $form_state->getValue('fields'); $mapping = rdf_get_mapping($this->entityTypeId, $this->bundle); @@ -202,7 +207,8 @@ class FieldMappings extends FormBase { * @return string * The unique string identifying the form. */ - public function getFormId() { + public function getFormId() + { return "rdfui_field_mapping_form"; }