Drupal

Override Form Twig Templates in Drupal 8+ (example: Commerce Cart Form)

Sometimes you want to add a layout to a Drupal form, but the form.html.twig has only the “children” variable by default, which holds rendered markup.

In order to make single form components available in the Twig template, you have to use hook_theme().

Firstly, thanks to Ruslan Piskarov, whose article pushed me in the right direction: https://makedrupaleasy.com/articles/drupal-10-how-render-any-form-twig-template

As an example, I use the Drupal Commerce „Cart Form“, which basically holds all contents on the cart page (views_form_commerce_cart_form_default).

In your THEMENAME.theme file, add hook_theme() like so:

/**
 * Implements hook_theme().
 */
function drowl_child_theme($existing, $type, $theme, $path) {
  return [
    'views_form_commerce_cart_form_default' => [
      'render element' => 'form',
      'path' => $path . '/templates/commerce/cart',
    ],
  ];
}

‚views_form_commerce_cart_form_default‘ needs to be your BASE_FORM_ID.

The ‚render element‘ is the name of the render array variable.

The path is optional, if you are fine with putting the template right into your „templates“ folder.

In this example, the resulting Twig file needs to be /templates/commerce/cart/views-form-commerce-cart-form-default.html.twig.

The template looks like this:

{#
/**
  * @file
  * Default theme implementation for a 'form' element.
  *
  * Available variables
  * - attributes: A list of HTML attributes for the wrapper element.
  * - children: The child elements of the form.
  *
  * @see template_preprocess_form()
  *
  * @ingroup themeable
  */
#}

{# {{ dump(form) }} #}
<div class="commerce-cart">
  <form{{ attributes }}>
    <div class="row">
      <div class="col col-md-8">
        <div class="commerce-cart__line-item-box">
          {{ form|without(
            'footer',
            'actions',
            'paypal_smart_payment_buttons'
          ) }}
        </div>
      </div>
      <div class="col col-md-4 commerce-cart__actions-sum">
        {{ form.actions }}
        <a href="/" class="btn btn-outline-dark btn--block">{{ 'Products Overview'|t }}</a>
        {{ form.paypal_smart_payment_buttons }}
        {{ form.footer }}
      </div>
    </div>
  </form>
</div>

Thats it, happy coding!

Drupal Mimemail Module (HTML Mails, Newsletter, …) unwanted attachment.dat *Update*

In a current project we ran into a curious problem, every HTML Mail has an file attachment named „attachment.dat“.

After some research in the „mimemail.theme.inc“ (function „template_preprocess_mimemail_message()“), we figured out that the problem is located inside the $css content.

In our case the implementation of the google webfont produces this issue (@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,600italic,400,600)). Basicly @import has to work inside html mails, so mimemail seems to do something wrong here?

Whatever. We can work around this problem, using the <link …> – implemantation inside the mimemail-message.tpl file instead of the declaration directly inside the css code.

 

    Platzsparendes Captcha (in kleinst-Formularen)

    Bei einem Drupal Kunden bestand vor kurzem die Notwendigkeit ein kleines Kontaktformular im Footer mit einem Captcha zu versehen. Captchas sind naturgemäß nun meist eher unschön anzusehen und nehmen relativ viel Platz in Anspruch. Die Idee war nun das Captcha bei Klick auf den Submit-Button über dem Formular einblenden zu lassen, so bleibt die ursprüngliche Optik erhalten und es muss kein zusätzlicher Platz geschaffen werden.

    Das ganze wurde nun per jQuery umgesetzt, welches natürlich ein Fallback für nicht-JavaScript-User notwendig machte. Hier passiert dann ganz einfach folgendes: Das Captcha ist standardmäßig per CSS ausgeblendet, jQuery blendet dieses erst ein. Erfolgt keine Captcha Angabe wird man auf eine Formularseite weitergeleitet (die Eingaben bleiben selbstverständlich erhalten), auf welcher man das Captcha dann eingeben muss.

    Unterhalb ist der entsprechende jQuery Code zu finden mit dem die Lösung umgesetzt wurde. Das hinzufügen eines Fake-Captcha-Buttons war leider notwendig, da sich herausgestellt hat, dass einige Browser keine Click-Events auf deaktivierte Buttons akzeptieren (Ziel war, den Button zu deaktivieren um das Absenden des Formulars zu verhinder, bis das Captcha eingegeben wurde).

    (function ($) {
    	Drupal.behaviors.captchaRequest = {
    		attach: function(context, settings) {
    			$('#footer #webform-client-form-4 .captcha').append($('#webform-client-form-4 #edit-submit--2'));
    			$('#footer #webform-client-form-4').append('<span id="captcha-request">Absenden</span>');
    			$('#footer #webform-client-form-4 #captcha-request').click(function() {
    					$('#footer #captcha-request').remove();
    					$('#footer #webform-client-form-4 .webform-component').hide();
    					$('#footer #webform-client-form-4 .captcha').show();
    			});
    		}
    	};
    })(jQuery);
    

      Bilder ohne HTML im WYSIWYG Editor einfügen

      Für Redakteure ist das arbeiten mit HTML erfahrungsgemäß eher lästig, man möchte doch lieber arbeiten wie eh und je. Mit dem Modul Insert geht es nun einen weiteren Schritt in Richtung „arbeiten wie in Word“. Allerdings lief dieses bei mir nur in einer speziellen Kombination auch fehlerfrei. Nicht nur für Redakteure, auch für HTML Kenner, stellt dieses Feature doch eine enorme Arbeitserleichterung dar.

      Nach der Einrichtung ist es möglich, hochgeladene CCK Bilder per Klick auf den Insert Button, in ausgewählter Imagecache Einstellung, in den Text zu integrieren.

      Erstmal zum jagen und sammeln:

      • http://drupal.org/project/insert
      • http://drupal.org/project/wysiwyg
      • http://ckeditor.com/download
      • http://drupal.org/project/colorbox

      Die oben genannten Module installieren, den CKEditor wie auf der Modulseite beschrieben im Library Verzeichnis ablegen. Falls noch nicht geschehen ein CCK Imagefield anlegen, in den Einstellungen des Feldes befindet sich nun ein Bereich namens „Insert“. Dort legen wir nun die Imagecache Voreinstellungen fest, die wir im Artikel verwenden möchten, natürlich auch jene die vom Colorbox-Modul angelegt wurden. Nun können Bilder wie oben beschrieben in den Text eingefügt werden.

      Einziges bis Dato verbliebenes Problem:

      Da das Bild nun auch ein Link ist, erhalten wir beim Doppelklick nicht die Bildeigenschaften und können somit nicht komfortabel floaten. Hier müssen also vorerst die Linkeigenschaften herhalten, im CSS Input Field geben wir hier float:left; float:right; an.

      UPDATE – 09.09.2011

      Es gibt inzwischen eine Alternativlösung: http://t.co/tZ9QkrT

       

        Audio Playback unter Drupal (mit Playlist)

        Nach ein paar Stunden testen höre ich nun gerade Musik aus meinen Boxen ertönen und möchte auch anderen, die dieses Problem gerade in den Wahnsinn treibt, erleuchten. Als erstes verabschiedet euch von Flowplayer und Co. in meinen Augen eine irrsinnige Frickelei und dann auch noch Flash, nein danke! Wir haben es heute doch viel besser, nur muss man da auch erstmal drauf kommen. Wir setzen einfach auf HTML5 – Audio und zwar mit Hilfe des jPlayers. Natürlich dürfen wir User ohne aktuellen Browser auch nicht so ganz im Regen stehen lassen, der jPlayer bietet ein Flashplayer Fallback, für die Bremserfraktion.

        Achtung! Bevor jetzt munter das Modul installiert wird und der aktuelle jPlayer in den Library Ordner geschoben wird:

        • Drupal 7: Aktueller jPlayer
        • Drupal 6: jPlayer 1.x

        Getestet (mit der Drupal 6 Variante) in Chrome, Internet Explorer 9, Opera 11 und Firefox 4, läuft perfekt.

        Also nochmal Punkt für Punkt:

        1. SWF Tools / etc. in die Tonne prügeln.
        2. http://drupal.org/project/jplayer runterladen und unter „sites/modules“ installieren
        3. http://www.jplayer.org/download/ Library herunterladen (1.x für Drupal 6, 2.x für Drupal 7)
        4. Lib unter „librarys/jplayer/jquery.jplayer.min.js“ kopieren
        5. Modul in Drupal aktivieren
        6. Bei der Feldansicht des Filefields eures Audio Inhaltstypen den jPlayer (mit Playlist) auswählen
        7. Enjoy!

        What about Views?

        jPlayer hat zwar eine Views Integration, die vom Prinzip her auch ganz ordentlich ausschaut, nur leider funktioniert diese bei mir nicht. Folgendes Workaround:

        1. View auf Zeilendesign: Node umstellen
        2. Anzahl der Beiträge: 1
        3. Filter auf euren Audio Nodetype

        Um Playlisten durchzuschalten (einen Audio Node kann man ja nun quasi als Playlist ansehen), kann man nun noch AJAX aktivieren und die Seitennavigation.

          Simple Formular Tooltips ohne Javascript (Drupal)

          Demo

          Nachdem ich gewohnheitsmäßig sofort zu Jquery gegriffen habe, kam mir so in den Sinn.. HEY! im Prinzip ist JavaScript in diesem Fall doch überhaupt nicht nötig.

          Und tatsächlich ist die Lösung per CSS wesentlich einfacher und macht doch im Endeffekt dass selbe wie die Jquery Lösung.

          In Drupal haben wir das Description-Div innerhalb der Form Items, so wir denn eine Beschreibung für das Feld eingegeben haben. Wir können die Beschreibung also super per .form-item:hover steuern. Wir gehen also einfach her und blenden die Beschreibung kurzerhand aus und blenden sie per :hover wieder ein. Das ganze lässt sich per CSS3 – Transition auch noch sehr ansehnlich gestalten.

          Code und Grafiken unterhalb! Die Selektion ist auf Drupal + Modul „Node Form Colums“ ausgerichtet und muss für andere Systeme natürlich angepasst werden.

          Demo

          
          #node-form .form-item .description{
          	opacity:0.3;
          	position:absolute;
          	left:-36px;
          	bottom:14px;
          	height:20px;
          	padding:7px;
          	width:20px;
          	color:transparent;
          	overflow:hidden;
          	background-image:url(../images/tooltip_birne.png);
              background-position:bottom right;
              background-repeat:no-repeat;
          }
          
          #node-form .form-item{
          	position:relative;
          }
          
          #node-form .form-region-main:hover .form-item .description,
          #node-form .form-region-right:hover .form-item .description{
          	display:block;
          	opacity:0.4;	
          	z-index:99;
          	
          	transition: all 0.25s ease-in-out;
              -webkit-transition: all 0.25s ease-in-out;
              -moz-transition: all 0.25s ease-in-out;	
              
              border-radius:10px 10px 0 10px;
          }
          
          #node-form .form-region-main .form-item:hover .description,
          #node-form .form-region-right .form-item:hover .description{
          	opacity:1.0;
          }
          
          #node-form .form-item .description:hover,
          #node-form fieldset .form-item .description:hover{
          	opacity:1.0;
          	left:-207px;	
          	color:#000;
          	width:200px;
          	height:auto;
          	background-color:#fff;
           	background-image:url(../images/tooltip_arrow_right.png);
           	
          	box-shadow:-5px -5px 4px rgba(0, 0, 0, 0.3);
          	-webkit-box-shadow:-5px -5px 4px rgba(0, 0, 0, 0.3);
          	-moz-box-shadow:-5px -5px 4px rgba(0, 0, 0, 0.3);
          }
          

          arrow
          arrow