Social Media Icons mit Twig

Holger Weischenberg | 07.11.2017

Wenn ich eine Website aufsetze, versuche ich grundsätzlich so wenig Module wie möglich zu nutzen. Die Module für Socialmedia Links haben meist Formfelder für die Links zu den Profilen - ich wollte dies jedoch mit dem Core-Modul Menu abbilden. Nach einigen Fehlversuchen dies ausschließlich mit CSS Attributen abzubilden, habe ich einen Hinweis gefunden, wie ich das Font Awesome Icon mittels Twig ausgebe.

Da ich die Webfonts lokal und nicht über die CDN einbinden möchte, lade ich diese auf der FontAwesome Website herunter (natürlich kann man auch eigene Icons oder andere Webfonts verwenden).

Die Icons in den verschiedenen Formaten speichere ich dann in das dafür vorgesehene Verzeichnis. In meinen Theme ist das assets/fonts. Da ich mit SCSS arbeite kommt noch optional eine Variable für Pfad und Version der Webfonts hinzu und zwar unter _variables.scss:

// font awesome path and version
$fa-font-path:                  "../../assets/fonts";
$fa-version:                    "4.7.0";

 

Jetzt muss noch der neue lokale Font im CSS bereitgestellt werden, das geschieht in meiner SCSS Komponenten Datei _font.scss. Zusätzlich benötige ich noch eine Klasse, um die Fonts später zu stylen.

@font-face {
  font-family: 'FontAwesome';
  src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}');
  src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'),
  url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'),
  url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'),
  url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'),
  url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg');
  //  src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
  font-weight: normal;
  font-style: normal;
}

// fontawesome styles
.fa {
  display: inline-block;
  font: normal normal normal 14px/1 FontAwesome;
  font-size: inherit;
  text-rendering: auto;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
/* makes the font 33% larger relative to the icon container */
.fa-lg {
  font-size: 1.33333333em;
  line-height: 0.75em;
  vertical-align: -15%;
}

 

Jetzt benötige ich noch ein eigenes Menü und gehe zu /admin/structure/menu/add.
Dort füge ich noch ein Menü hinzu, das ich "Social media" nenne und in dem ich Links mit dem Namen "Facebook", "Twitter", "Xing" anlege, die auf das entsprechende Social-Media Profil verweisen. Das Menü wird anschließend unter /admin/structure/block einer beliebigen Region zugewiesen und der Titel (falls gewünscht) ausgeblendet.

Jetzt lege ich eine neue Template Datei an. Als Name wird mir im Twig Debug Modus zum Beispiel "menu--social-media.html.twig" vorgeschlagen. Ich lege eine entsprechende Datei an und speichere sie in meinem Theme in templates/navigation.

{#
/**
 * @file
 * Theme override to display a menu.
 *
 * Available variables:
 * - menu_name: The machine name of the menu.
 * - items: A nested list of menu items. Each menu item contains:
 *   - attributes: HTML attributes for the menu item.
 *   - below: The menu item child items.
 *   - title: The menu link title.
 *   - url: The menu link url, instance of \Drupal\Core\Url
 *   - localized_options: Menu link localized options.
 *   - is_expanded: TRUE if the link has visible children within the current
 *     menu tree.
 *   - is_collapsed: TRUE if the link has children within the current menu tree
 *     that are not currently visible.
 *   - in_active_trail: TRUE if the link is in the active trail.
 */
#}
{% import _self as menus %}

{% set attributes = attributes.addClass('menu--dropdown menu--primary-menu') %}

{#
  We call a macro which calls itself to render the full tree.
  @see http://twig.sensiolabs.org/doc/tags/macro.html
#}
{{ menus.menu_links(items, attributes, 0) }}

{% macro menu_links(items, attributes, menu_level) %}
  {% import _self as menus %}
  {% if items %}
    {% if menu_level == 0 %}
<ul{{ attributes.addClass('menu') }}>
    {% else %}
    <ul class="menu">
        {% endif %}
        {% for item in items %}
            {% set classes = [
            'menu-item',
            item.is_expanded ? 'menu-item--expanded',
            item.is_collapsed ? 'menu-item--collapsed',
            item.in_active_trail ? 'menu-item--active-trail',
            ] %}
            <li{{ item.attributes.addClass(classes) }}>
                {% if item.title == 'Xing' %}
                    <a href="{{ item.url }}" class="nav-item"><i class="fa fa-lg">&#xf168;</i></a>
                {% elseif item.title == 'Facebook' %}
                    <a href="{{ item.url }}" class="nav-item"><i class="fa fa-lg">&#xf09a;</i></a>
                {% elseif item.title == 'Twitter' %}
                    <a href="{{ item.url }}" class="nav-item"><i class="fa fa-lg">&#xf099;</i></a>
                {% endif %}
            </li>
        {% endfor %}
    </ul>
    {% endif %}
    {% endmacro %}

 

Das Menü sollte jetzt als Icon ausgegeben werden. Die Einträge können in im Backend durch einen Redakteur verschoben oder deaktiviert werden. Lediglich Icons für neue Services müssten von einem Entwickler im Twig Template angelegt werden. Dafür ist diese Lösung auch besonders flexibel, da man Social-Media Links mit Verweisen auf andere Seiten mischen und zudem eigene Icons hinterlegen kann, da man nicht an eine Fontbibliothek gebunden ist. Charmant finde ich auch, dass dies mit sehr wenigen Codezeilen möglich ist. Twig rocks!

Code

Kommentieren