Quellcode durchsuchen

home article cards links made active

bach vor 2 Jahren
Ursprung
Commit
27ece7a12c

+ 5 - 5
config/sync/core.entity_view_display.node.article.card_home.yml

@@ -19,8 +19,8 @@ dependencies:
     - image.style.article_card_home
     - node.type.article
   module:
-    - image_delta_formatter
     - user
+    - vue_link_formatter
 id: node.article.card_home
 targetEntityType: node
 bundle: article
@@ -32,10 +32,10 @@ content:
     settings:
       deltas: '0'
       image_style: article_card_home
-      image_link: ''
+      image_link: content
       deltas_reversed: 0
     third_party_settings: {  }
-    type: image_delta_formatter
+    type: vue_image_delta_formatter
     region: content
   flag_hello:
     weight: 10
@@ -59,11 +59,11 @@ content:
     region: content
   title:
     label: hidden
-    type: string
+    type: vuestring
     weight: 0
     region: content
     settings:
-      link_to_entity: false
+      link_to_entity: true
     third_party_settings: {  }
 hidden:
   body: true

+ 21 - 5
config/sync/core.entity_view_display.node.frontpage.home_light.yml

@@ -173,7 +173,8 @@ third_party_settings:
         speed: fast
       label: showroom-col-left
     group_showroom_col_right:
-      children: {  }
+      children:
+        - computed_showrooms_reference
       parent_name: group_showrooms
       weight: 21
       format_type: html_element
@@ -209,7 +210,8 @@ third_party_settings:
         speed: fast
       label: blabla-col-left
     group_blabla_col_right:
-      children: {  }
+      children:
+        - computed_articles_reference
       parent_name: group_blabla
       weight: 21
       format_type: html_element
@@ -230,6 +232,14 @@ targetEntityType: node
 bundle: frontpage
 mode: home_light
 content:
+  computed_articles_reference:
+    type: entity_reference_label
+    weight: 0
+    region: content
+    label: hidden
+    settings:
+      link: true
+    third_party_settings: {  }
   computed_products_reference:
     type: entity_reference_entity_view
     weight: 6
@@ -239,6 +249,14 @@ content:
       view_mode: home_summary
       link: false
     third_party_settings: {  }
+  computed_showrooms_reference:
+    type: entity_reference_label
+    weight: 0
+    region: content
+    label: hidden
+    settings:
+      link: true
+    third_party_settings: {  }
   field_a_database:
     weight: 6
     label: above
@@ -345,7 +363,7 @@ content:
     type: text_default
     region: content
   flag_flag_list_template_1:
-    weight: 10
+    weight: 5
     region: content
     settings: {  }
     third_party_settings: {  }
@@ -358,9 +376,7 @@ content:
       link_to_entity: false
     third_party_settings: {  }
 hidden:
-  computed_articles_reference: true
   computed_materials_reference: true
-  computed_showrooms_reference: true
   langcode: true
   links: true
   search_api_excerpt: true

+ 105 - 0
web/modules/custom/vue_link_formatter/src/Plugin/Field/FieldFormatter/VueImageDeltaFormatter.php

@@ -0,0 +1,105 @@
+<?php
+namespace Drupal\vue_link_formatter\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Field\EntityReferenceFieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\vue_link_formatter\Plugin\Field\FieldFormatter\VueImageFormatter;
+
+/**
+ * Plugin implementation of the 'image_delta_formatter' formatter.
+ *
+ * @FieldFormatter(
+ *   id = "vue_image_delta_formatter",
+ *   label = @Translation("Vue Image delta"),
+ *   description = @Translation("Display specific deltas of an image field with vue atributes."),
+ *   field_types = {
+ *     "image"
+ *   }
+ * )
+ */
+class VueImageDeltaFormatter extends VueImageFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'deltas' => 0,
+      'deltas_reversed' => FALSE,
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $element = parent::settingsForm($form, $form_state);
+
+    $element['deltas'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Delta'),
+      '#description' => $this->t('Enter a delta, or a comma-separated list of deltas that should be shown. For example: 0, 1, 4.'),
+      '#size' => 10,
+      '#default_value' => $this->getSetting('deltas'),
+      '#required' => TRUE,
+      '#weight' => -20,
+    ];
+    $element['deltas_reversed'] = [
+      '#title' => $this->t('Reversed'),
+      '#type' => 'checkbox',
+      '#default_value' => $this->getSetting('deltas_reversed'),
+      '#description' => $this->t('Start from the last values.'),
+      '#weight' => -10,
+    ];
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $settings = $this->getSettings();
+    $summary = parent::settingsSummary();
+
+    $count = count(explode(',', $settings['deltas']));
+    $args = [
+      '@deltas' => trim($settings['deltas']),
+    ];
+    $delta_summary = empty($settings['deltas_reversed']) ? $this->formatPlural($count, 'Delta: @deltas', 'Deltas: @deltas', $args) : $this->formatPlural($count, 'Delta: @deltas (reversed, no effect).', 'Deltas: @deltas (reversed).', $args);
+    $summary[] = $delta_summary;
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getEntitiesToView(EntityReferenceFieldItemListInterface $items, $langcode) {
+    $files = parent::getEntitiesToView($items, $langcode);
+    // Prepare an array of selected deltas from the entered string.
+    if (mb_strpos($this->getSetting('deltas'), ',')) {
+      $deltas = explode(',', $this->getSetting('deltas'));
+      $deltas = array_map('trim', $deltas);
+    }
+    else {
+      $delta = trim($this->getSetting('deltas'));
+      $deltas = [$delta];
+    }
+
+    foreach (array_keys($files) as $delta) {
+      if (!in_array($delta, $deltas)) {
+        unset($files[$delta]);
+      }
+    }
+
+    // Reverse the items if needed.
+    if ($this->getSetting('deltas_reversed')) {
+      $files = array_reverse($files);
+    }
+
+    return $files;
+
+  }
+
+}

+ 110 - 0
web/modules/custom/vue_link_formatter/src/Plugin/Field/FieldFormatter/VueImageFormatter.php

@@ -0,0 +1,110 @@
+<?php
+
+namespace Drupal\vue_link_formatter\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\EntityStorageInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Link;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Url;
+use Drupal\image\Entity\ImageStyle;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Cache\Cache;
+use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter;
+
+/**
+ * Plugin implementation of the 'image' formatter with vuejs attributes.
+ *
+ * @FieldFormatter(
+ *   id = "vueimage",
+ *   label = @Translation("Vue Image"),
+ *   field_types = {
+ *     "image"
+ *   },
+ *   quickedit = {
+ *     "editor" = "image"
+ *   }
+ * )
+ */
+class VueImageFormatter extends ImageFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+    $files = $this->getEntitiesToView($items, $langcode);
+
+    // Early opt-out if the field is empty.
+    if (empty($files)) {
+      return $elements;
+    }
+
+    $url = NULL;
+    $image_link_setting = $this->getSetting('image_link');
+    // Check if the formatter involves a link.
+    if ($image_link_setting == 'content') {
+      $entity = $items->getEntity();
+      if (!$entity->isNew()) {
+        $url = $entity->toUrl();
+        $url->setOption('attributes', array(
+          '@click.prevent' => 'onClickLink',
+          'data-id' => $entity->id(),
+          'data-entity-type' => $entity->getEntityTypeId(),
+          'data-bundle' => $entity->bundle(),
+        ));
+      }
+    }
+    elseif ($image_link_setting == 'file') {
+      $link_file = TRUE;
+    }
+
+    $image_style_setting = $this->getSetting('image_style');
+
+    // Collect cache tags to be added for each item in the field.
+    $base_cache_tags = [];
+    if (!empty($image_style_setting)) {
+      $image_style = $this->imageStyleStorage->load($image_style_setting);
+      $base_cache_tags = $image_style->getCacheTags();
+    }
+
+    foreach ($files as $delta => $file) {
+      $cache_contexts = [];
+      if (isset($link_file)) {
+        $image_uri = $file->getFileUri();
+        // @todo Wrap in file_url_transform_relative(). This is currently
+        // impossible. As a work-around, we currently add the 'url.site' cache
+        // context to ensure different file URLs are generated for different
+        // sites in a multisite setup, including HTTP and HTTPS versions of the
+        // same site. Fix in https://www.drupal.org/node/2646744.
+        $url = Url::fromUri(file_create_url($image_uri));
+        $cache_contexts[] = 'url.site';
+      }
+      $cache_tags = Cache::mergeTags($base_cache_tags, $file->getCacheTags());
+
+      // Extract field item attributes for the theme function, and unset them
+      // from the $item so that the field template does not re-render them.
+      $item = $file->_referringItem;
+      $item_attributes = $item->_attributes;
+      unset($item->_attributes);
+
+      $elements[$delta] = [
+        '#theme' => 'image_formatter',
+        '#item' => $item,
+        '#item_attributes' => $item_attributes,
+        '#image_style' => $image_style_setting,
+        '#url' => $url,
+        '#cache' => [
+          'tags' => $cache_tags,
+          'contexts' => $cache_contexts,
+        ],
+      ];
+    }
+
+    return $elements;
+  }
+
+}

+ 69 - 0
web/modules/custom/vue_link_formatter/src/Plugin/Field/FieldFormatter/VueStringFormatter.php

@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\vue_link_formatter\Plugin\Field\FieldFormatter;
+
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemInterface;
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Field\Plugin\Field\FieldFormatter\StringFormatter;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the 'string' formatter + @click vue attribute
+ *
+ * @FieldFormatter(
+ *   id = "vuestring",
+ *   label = @Translation("Vue link Plain text"),
+ *   field_types = {
+ *     "string",
+ *     "uri",
+ *   },
+ *   quickedit = {
+ *     "editor" = "plain_text"
+ *   }
+ * )
+ */
+class VueStringFormatter extends StringFormatter {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+    $url = NULL;
+    if ($this->getSetting('link_to_entity')) {
+      $entity = $items->getEntity();
+      $url = $this->getEntityUrl($entity);
+    }
+
+    foreach ($items as $delta => $item) {
+      $view_value = $this->viewValue($item);
+      if ($url) {
+        $elements[$delta] = [
+          '#type' => 'link',
+          '#title' => $view_value,
+          '#url' => $url,
+          '#attributes' => array(
+            '@click.prevent' => 'onClickLink',
+            'data-id' => $entity->id(),
+            'data-entity-type' => $entity->getEntityTypeId(),
+            'data-bundle' => $entity->bundle(),
+            // 'data-bundle' => $entity
+            // 'nid' => $entity->nid(),
+            // 'type' => $entity->getType()
+          )
+        ];
+      }
+      else {
+        $elements[$delta] = $view_value;
+      }
+    }
+    return $elements;
+  }
+
+}

Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
web/themes/custom/materiotheme/assets/dist/main.js


BIN
web/themes/custom/materiotheme/assets/dist/main.js.gz


Datei-Diff unterdrückt, da er zu groß ist
+ 1 - 1
web/themes/custom/materiotheme/assets/dist/report.html


+ 2 - 0
web/themes/custom/materiotheme/templates/field/image-formatter.html.twig

@@ -12,6 +12,8 @@
  */
 #}
 {% if url %}
+  {# {{ link(image, url, { '@click.prevent.stop':'onClickLink' }) }} #}
+  <!-- attributes are added from vue_link_formatter custom module -->
   {{ link(image, url) }}
 {% else %}
   {{ image }}

+ 37 - 9
web/themes/custom/materiotheme/vuejs/components/Pages/Home.vue

@@ -125,22 +125,50 @@ export default {
     },
     onClickLink(e){
       console.log("onClickLink", e, this.$router, this.$route)
-      if (e.originalTarget.protocol == "mailto:") {
+      // record the target before event finish the propagation as currentTarget will be deleted after
+      let target = e.currentTarget
+      console.log('target', target)
+
+      if (target.protocol == "mailto:") {
         // https://stackoverflow.com/questions/10172499/mailto-using-javascript
-        window.location.href = e.originalTarget.href
+        window.location.href = target.href
       }else {
         let path = null;
-        // find existing router route compared with link href
-        for (let i = 0; i < this.$router.options.routes.length; i++) {
-          if (this.$router.options.routes[i].path == e.originalTarget.pathname) {
-            if (e.originalTarget.pathname !== this.$route.path) {
-              path = e.originalTarget.pathname
+        let article = null;
+
+        // if we have an article link with appropriate data attributes
+        // 'data-id'
+        // 'data-entity-type'
+        // 'data-bundle'
+        if (target.dataset.entityType == 'node' && target.dataset.bundle == 'article') {
+          let matches = target.pathname.match(/^\/\w{2}\/[^\/]+\/(.*)/i)
+          console.log('matches', matches)
+          article = {
+            nid: target.dataset.id,
+            alias: matches[1]
+          }
+        } else {
+          // find existing router route compared with link href
+          let pathbase = target.pathname.match(/^(\/\w{2}\/[^\/]+)\/.*/i)
+          console.log('pathbase', pathbase)
+
+          for (let i = 0; i < this.$router.options.routes.length; i++) {
+            if (this.$router.options.routes[i].path == pathbase[1]) {
+              if (target.pathname !== this.$route.path) {
+                path = target.pathname
+              }
+              break
             }
-            break
           }
+
         }
 
-        if (path) {
+        if (article) {
+          this.$router.push({
+            name:`article`,
+            params: { alias: article.alias, id: article.nid }
+          })
+        } else if (path) {
           this.$router.push({
             path: path
           })

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.