Dodaj klasę do pola treści (link)

15

Chcę dodać klasę do <a>znacznika pola, które składa się z łącza i tekstu. (Jest to pole typu Link .) Nazwa tego pola to content.field_c_button_link.

W pliku szablonu chcę dodać coś takiego.

{{ content.field_c_button_link.0.addClass('button blue') }}

Jak mogę poprawnie dodać klasę?

Zgodnie z odpowiedzią Patricka Scheffera spojrzałem na ustawienia dla pola, w którym mogę dodać dodatkowe klasy CSS, ale nie mogłem ich znaleźć. To jest zrzut ekranu tego, co mogę edytować w polu linku.

zrzut ekranu

maidi
źródło

Odpowiedzi:

7

Jest to rozwiązanie, które znalazłem, ale nie jest tak naprawdę przydatne ... Naprawdę chcę lepszego rozwiązania, takiego jak coś bezpośrednio z szablonów gałązek.

function template_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#name'] == 'field_c_button_link') {
    $variables['items'][0]['content']['#options']['attributes']['class'][] = 'button';
  }
}
Toni Fisler
źródło
1
Powinno być '#field_name'zamiast '#name'.
leymannx,
5

Najłatwiejszym sposobem na osiągnięcie tego jest użycie jednego z tych dwóch modułów.

1. Klasa łącza - moduł klasy łącza zapewnia nowy formularz widżetu dla pola typu Link. Ten widget umożliwia edytorowi dodanie klasy do pól Link dołączony do ich treści.

2. Atrybuty linku - widget Atrybuty linku zapewnia dodatkowy widget dla pola linku znalezionego w rdzeniu Drupala. Widżet umożliwia użytkownikom ustawianie atrybutów w łączu.

Ponadto moduł zmienia domyślne pole linku treści linku do menu, aby użyć tego widgetu, umożliwiając również linkom menu posiadanie atrybutów

identyfikator, klasa, nazwa, cel, rel, klucz dostępu

Po włączeniu jednego z tych dwóch elementów możemy ustawić ustawienia widżetu dla pola „Link” w obszarze „Zarządzaj wyświetlaniem formularza” dla danego pola łącza.

Zobacz załączony obraz w celach informacyjnych.

wprowadź opis zdjęcia tutaj

Po ustawieniu wprowadź każdą klasę oddzieloną spacją w polu, które pojawia się w momencie tworzenia treści.wprowadź opis zdjęcia tutaj

Prerit Mohan
źródło
Bardzo dziękuję za szczegółowy opis, bardzo pomocny. Oba dobre rozwiązania.
ymdahi
4

Jeśli edytujesz to pole linku w swoim typie treści (admin / structure / types / manage / your_contenttype / fields / field_c_button_link), istnieje pole Dodatkowe klasy CSS .

Jednak wprowadzone tutaj klasy dotyczą wszystkich łączy utworzonych za pomocą „field_c_buton_link”. Jeśli chcesz dodać klasę do jednej konkretnej lokalizacji, możesz rzucić okiem na hook_preprocess_field] lub nawet theme_link.

Edytować:

W Drupal 8 jest także pole theme_preprocess_field . Myślę więc, że możesz zrobić coś takiego:

function template_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#name'] == 'field_c_button_link') {
    $variables['attributes']['class'][] = 'button';
    $variables['attributes']['class'][] = 'blue';   
  } 
}

Nie testowałem tego, więc myślę, że musisz wprowadzić pewne poprawki, aby to zadziałało.

Patrick Scheffer
źródło
Dzięki za odpowiedź, ale nie mogę znaleźć takiego pola ... :(
maidi
Które pola są dostępne podczas edycji pola linku?
Patrick Scheffer,
Do mojego pytania
dodałem zrzut
Rozumiem, jakiej wersji modułu łącza używasz?
Patrick Scheffer,
Gdzie mogę się dowiedzieć? Używam Drupala 8, więc moduł Link był częścią rdzenia.
maidi,
3

Aby dodać do powyższej odpowiedzi Tony'ego Fislera, w Drupal 8.1.2 musiałem sprawdzić #field_name zamiast name, aby dodać klasę. To działa dla mnie.

function yourthemename_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
  if ($element['#field_name'] == 'field_link') {
    $variables['items'][0]['content']['#options']['attributes']['class'][] = 'blarg';
  }
}

Dzieje się tak, jeśli chcesz klasę na <a>znaczniku. Oferowane rozwiązanie klasy łącza jest łatwiejsze, ale kiedy próbowałem, dotyczyło tylko klasy do opakowania a. Tak więc, jeśli używasz na przykład Bootstrap, moduł klasy łącza nie działałby.

Chris Bauer
źródło
Dzięki! Jest to bardzo pomocne, ale zakłada, że ​​pole ma tylko jeden przedmiot. Jeśli w polu znajduje się wiele elementów, musisz je zapętlić. np.if ($element['#field_name'] == 'field_link') { foreach ($variables['items'] as $key => $item){ $variables['items'][$key]['content']['#options']['attributes']['class'][] = 'blarg'; } }
William Mortada,
2

Możesz użyć klasy Project Link, która pozwala dodawać klasy w polu Link. Należy ustawić widżet na „Połącz z klasą”. Zobacz zrzut ekranu. wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

flokondetyl
źródło
2

Aby to zrobić gałązką za pomocą szablonu pola (tj. field--field-c-button-link.html.twig)

Zwykle szablon pola zapętla Twoje linki, używając:

  {% for item in items %}
    {{ item.content }}
  {% endfor %}

Ale możesz to zmienić na coś takiego:

  {% for item in items %}
    <a class="btn btn-secondary btn-lg m-1" href="{{ item.content['#url'] }}">{{ item.content['#title']}}</a>
  {% endfor %}

osobno zajmując się tytułem linku i adresem URL.

sdmeyers
źródło
1

Łatwo jest utworzyć własny formatyzator, który zastąpi formatyzator linków. Chociaż teraz, gdy widzę, że istnieje moduł dla tego ( Link ), możesz z niego skorzystać, ponieważ możesz ustawić go na poziomie pola, a nie jako ustawienie w formatyzatorze. Pomyślałem jednak, że może to być przydatne dla kogoś, kto chce zbudować własny program do formowania linku, w którym można dodać klasę.

namespace Drupal\mymodule\Plugin\Field\FieldFormatter;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\link\LinkItemInterface;
use Drupal\link\Plugin\Field\FieldFormatter\LinkFormatter;

/**
 * Plugin implementation of the 'link' formatter.
 *
 * @FieldFormatter(
 *   id = "link_with_class",
 *   label = @Translation("Link with Custom Class"),
 *   field_types = {
 *     "link"
 *   }
 * )
 */
class LinkClassFormatter extends LinkFormatter {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return parent::defaultSettings() +
    ['class' => ''];

  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $elements = parent::settingsForm($form, $form_state);

    $elements['class'] = array(
      '#type' => 'textfield',
      '#title' => t('Class on Link'),
      '#default_value' => $this->getSetting('class'),
    );

    return $elements;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {

    $summary = parent::settingsSummary();

    $settings = $this->getSettings();

    if (!empty($settings['class'])) {
      $summary[] = t('Class(es) on button = "@classes"', array('@classes' => $settings['class']));
    }

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  protected function buildUrl(LinkItemInterface $item) {
    $url = parent::buildUrl($item);

    $settings = $this->getSettings();

    if (!empty($settings['class'])) {
      $options = $url->getOptions();
      $options['attributes']['class'] = $settings['class'];
      $url->setOptions($options);
    }

    return $url;
  }

}
oknate
źródło
0

Nadal testuję to pod kątem błędów, ale umieszczenie tego w pliku .theme doda nazwę pola jako klasę dla wszystkich pól. Dotyczy to Drupala 8.2:

function mytheme_preprocess_field(&$variables, $hook) {
  $variables['attributes']['class'][] = $variables['element']['#field_name'];
}

Wydaje się, że każdy temat powinien zawierać coś, co ułatwi stylizację.

Wola
źródło
0

Wszystkie pozostałe rozwiązania dodają klasy do opakowania pola. Ten dodaje klasę do samego <a>znacznika:

/*
 * Implements hook_preprocess__HOOK().
 */
function hook_preprocess_field(&$variables) {
  $classes = [
    'button',
    'blue'
  ];
  $variables['items'][0]['content']['#url']->setOption('attributes', ['class' => $classes]);
}
elluca
źródło
0

Oto proste rozwiązanie -

function THEME_preprocess_file_link(&$variables)
{
  $variables['attributes']->addClass(array('your_custom_class'));
}
sagarjadhav
źródło