contar valores de campo multivalor en twig

9

Quiero contar el número de valores de campo ilimitado en la plantilla de ramita que intenté

{{ node.field_mytext.count }} => ante un error

y en otro intento

{{ content.field_mytext.count }}=> nada devuelto

(en este método verifiqué que mi campo no está en el campo deshabilitado es el administrador de visualización)


Mi pregunta es ¿cómo puedo contar la cantidad de elementos de un campo en Twig?

Espero enfrentarme con las soluciones que esperan estas soluciones: D

  • agréguelo en preprocess_node
  • utilizar Twig Tweak
Yusef
fuente
intentaste {{content.field_mytext | longitud }}?
David Mcsmith

Respuestas:

14

{{node.field_mytext.count}} => ante un error

Esto no funciona, porque el método countno está permitido en las políticas de ramitas:

core / lib / Drupal / Core / Template / TwigSandboxPolicy.php

{{content.field_mytext | longitud }}?

Esto no funciona, porque contentes una matriz de renderizado con muchas claves adicionales.

Esto funciona: Convertir el campo en matriz y contar

{{ node.field_mytext.getvalue | length }}
4k4
fuente
probablemente también podría hacerlo con un bucle foreach, pero esto es más limpio para este propósito específico.
No Sssweat
6

La forma más fácil es obtener el ['#items']|length. Lo hago todo el tiempo para contar elementos para ver más instancias y al cargar controles deslizantes.

{{ content.field_mytext['#items']|length }}
usuario3461392
fuente
4

He usado filtros Twig propios para admitir campos de entidad, con esto puedes usar campos como matrices nativas:

{{ content.field_mytext|length }}

o

{{ content.field_mytext|first|value }}

o

{% if content.field_mytext is empty %}

Puede agregar fácilmente sus propios filtros Twig a través de un módulo personalizado. Puede obtener más información aquí: drupal.org/docs/8/creating-custom-modules . En resumen, debe crear un directorio de módulos, por ejemplo path/to/drupal/modules/custom/common/, ponerlo allí common.info.ymlcon definición de módulo y common.services.ymlcon definición de servicio (ver comentarios en código) y poner mi código /path/to/drupal/modules/custom/common/src/TwigExtension.php.

<?php
namespace Drupal\common;

use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\TypedData\ComplexDataInterface;

/**
 * A class providing Twig extensions.
 *
 * This provides a Twig extension that registers various Field-API-specific
 * extensions to Twig, overriding empty and array related filters.
 *
 * Don't forget about common.services.yml
 * services:
 *   common.twig.TwigExtension:
 *     class: Drupal\common\TwigExtension
 *     tags:
 *       - { name: twig.extension }
 *
 * Usage (in *.html.twig file):
 *   - check is field empty {% if content.field_foo is empty %}
 *   - get field first value {{ content.field_foo|first|value }}
 */
class TwigExtension extends \Twig_Extension {

  /**
   * {@inheritdoc}
   */
  public function getTests() {
    return [
      new \Twig_SimpleTest('empty', [$this, 'twigEmptyField']),
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function getFilters() {
    return [
      new \Twig_SimpleFilter('length', [$this, 'twigLengthFilter'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('slice', [$this, 'twigSlice'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('first', [$this, 'twigFirst'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('last', [$this, 'twigLast'], ['needs_environment' => TRUE]),
      new \Twig_SimpleFilter('value', [$this, 'twigFieldValue']),
    ];
  }

  /**
   * Check if value is field item object.
   *
   * @param mixed $value
   *   Mixed Twig variable.
   *
   * @return \Drupal\Core\Field\FieldItemListInterface|mixed
   *   FieldItemListInterface or same value as passed.
   */
  private function checkItems($value) {
    if (is_array($value) && !empty($value['#items']) && $value['#items'] instanceof FieldItemListInterface) {
      return $value['#items'];
    }
    return $value;
  }

  /**
   * Get field item value.
   *
   * @param object $field
   *   Field object.
   *
   * @return array|mixed
   *   List of values or value.
   */
  public function twigFieldValue($field) {
    if ($field instanceof FieldItemInterface) {
      $prop = $field->mainPropertyName();
      $value = $field->getValue();
      return $prop ? $value[$prop] : $value;
    }
    if ($field instanceof FieldItemListInterface) {
      $value = [];
      foreach ($field as $item) {
        $value[] = $this->twigFieldValue($item);
      }
      return $value;
    }
    return '';
  }

  /**
   * Checks if a variable is empty.
   *
   * @see twig_test_empty
   */
  public function twigEmptyField($value) {
    $value = $this->checkItems($value);
    if ($value instanceof ComplexDataInterface) {
      return $value->isEmpty();
    }
    // Return TRUE, because there is no data only cache and weight.
    elseif (!is_object($value) && isset($value['#cache']) && count($value) == 2) {
      return TRUE;
    }
    return twig_test_empty($value);
  }

  /**
   * Returns the length of a variable.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_length_filter
   */
  public function twigLengthFilter(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_length_filter($env, $item);
  }

  /**
   * Slices a variable.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   * @param int $start
   *   Start of the slice.
   * @param int $length
   *   Size of the slice.
   * @param bool $preserveKeys
   *   Whether to preserve key or not (when the input is an array)
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_slice
   */
  public function twigSlice(\Twig_Environment $env, $item, $start, $length = NULL, $preserveKeys = FALSE) {
    $item = $this->checkItems($item);
    return twig_slice($env, $item, $start, $length, $preserveKeys);
  }

  /**
   * Returns the first element of the item.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_first
   */
  public function twigFirst(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_first($env, $item);
  }

  /**
   * Returns the last element of the item.
   *
   * @param \Twig_Environment $env
   *   Twig environment.
   * @param mixed $item
   *   A variable.
   *
   * @return mixed
   *   The first element of the item.
   *
   * @see twig_last
   */
  public function twigLast(\Twig_Environment $env, $item) {
    $item = $this->checkItems($item);
    return twig_last($env, $item);
  }

}
zviryatko
fuente
0

Usar filtro de longitud

{{ content.field_mytext | length }} 
David Mcsmith
fuente
44
valor de error de retorno !!!, mi campo es largo y tengo 4 elementos allí, ¡pero devuelvo 20!
Yusef
1
Esto puede (dependiendo de las circunstancias) puede devolver los valores correctos, pero es una respuesta inexacta.
aydow