Create Static Social-Media “Share” Buttons without Javascript

no external resources required, corporate privacy compliance

Social-Media Share Buttons are everywhere, but most of them are working with external hosted javascript resources which are loaded on each page request. Depending on the servers cache settings this can cause multiple additional http request for your visitors. Additionally it can raise some privacy issues becaue of the possibility that your users can be […]

MooTools: A modern Element.highlight() implementation

using CSS3 Transisitons instead of Fx.Tween

Use the following code as Element.highlight() replacement:

Element.implement({
    /**
     * Custom Element Highlighting Function
     * @param color
     */
    highlight: function(color){
        // get current background color
        var originalColor = this.getStyle('background-color');

        // set new background color
        this.setStyle('background-color', color);

        // restore background color after 300ms
        (function(){
            this.setStyle('background-color', originalColor);
        }).delay(300, this);
    }
});

It will only change the background color to the given value and reverse this after a time of 300ms. To get a fading-effect you need to add the following css, matching the elements you wish to apply the highlight() method:

.autocomplete-input{
    transition: background-color 200ms;
}

That’s it ;)

Are you using a Yubikey and want to create your custom Keyserver written in Node.js ? In this case this piece of code might be useful :)

/**
 * Convert the Yubico MODHEX encoded Strings to hex
 * @param modhex String
 * @returns hex String
 */
var modhex2hex = function(modhex){
    // strip whitespaces and string cleanup - all non matching characters are 0x00 (c in modhex)
    modhex = modhex.replace(/\s*/g, '').replace(/[^cbdefghijklnrtuv]/g, 'c');

    // even length ?
    if (modhex.length%2 !== 0){
        return null;
    }

    // modhex mapping base; c.....v => 0x0 ... 0xF
    var modhexBase = 'cbdefghijklnrtuv'.split('');

    // tmp
    var output = '';

    // convert
    for (var i=0;i<modhex.length;i++){
        // convert index to hex
        output += modhexBase.indexOf(modhex.charAt(i)).toString(16);
    }

    return output;
};

console.log(modhex2hex('te vt hh fg ue dk gv rt lv hb lu gf nk ge ng cv'));

Bootstrap Dismissible alerts with MooTools

use .alert-dismissible without jQuery

Bootstrap & MooTool#

Using Dismissible alerts with pure MooTools code. Just insert the following code within your domready startup:

Alert.js Replacement#

// get all elements with the .alert-dismissible class
document.getElements('.alert-dismissible').each(function(el){
  // add a onclick event to each element
  el.getElement('button.close').addEvent('click', function(){
    // hide the element on click
    el.setStyle('display', 'none');
  });
});

Dismissible alerts Example#

<div class="alert alert-danger alert-dismissible" id="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <strong>Invalid Regex Rule: </strong> <code class="txt"></code>
</div>

HowTo: Upgrade Notification for WordPress Plugins

add version based notices to the wordpress plugin page; wp 4.2

Notify your users!# Sometimes, your WordPress plugin will have a major release which may causes groundbreaking API changes. In the past, WordPress displays the “Upgrade Notice” section from readme.txt directly to the users but it seems currently broken – i’ve got no notification for any plugin in the last few month. Therefore i’ve carried out […]

Install Sophos UTM Essential Firewall 9.3 with an USB Stick

plug 'n play ? not really... (version 9.308-16.1)

First of all, you need to download the iso image (it’s required to create an account – your license key will be sent to this email address).

Install the ISO Image to an USB Drive#

It’s not possible to copy the image via dd directly to the usb drive because of a missing usb bootloader. Therefore you need external bootloader like Universal-USB-Installer from pendrivelinux.

Download and execute the tool.

  • Step 1 choose “Try unlisted Linux ISO” from the bottom of the page.
  • Step 2 select the iso image e.g. asg-9.308-16.1.iso
  • Step 3 select your usb drive (at least 2GB)

After the installation has finished, remove and reattach the usb stick from your system to process with the next step.

Fix the local package repository#

The current (9.308-16.1) iso image has some broken filenames within the local package repository. The files are located under “install/rpm/”. Check each file if it ends with “.rb1.i686.rpm” – if not, modify the filename and add the missing part!

Otherwise the installation will abort and message like “can’t stat file /install/install/rpm/….. rb1.i686.rpm” will appear. I hope this issue will be fixed soon…

Now you can attach the usb stick to your firewall-box and power it up!

Remount the USB Drive#

Ready ? not really… the hardware-detection of the installer will unmount the usb stick, which cause the error message “install.tar not found”. Therefore you have to remount the usb-stick after the hardware detection succeed.

  • After Hardware Detection succeed press “ok”
  • Select the Keyboard Layout and Timezone
  • Press “Alt+F2” to switch to the console
  • Re-Mount the USB drive: mount /dev/sdb /install
  • Press “Alt+F1” to return to the installer
  • Proceed the installation

 

Google Universal Analytics provides a great possibility to track custom events on your website. These feature can be used to analyze special user-interactions with e.g. advertised/highlighted content or social media links. The recorded data can be directly used to optimize your website!

The event tracking is very simple:

To simplify the integration you can implment a simple data-binding which will automatically add event listeners (click) to you DOM elements. Just add an additional attribute to your elements which includes (in this example) a prefix, the event-category and the event-label (scheme: "prefix:category:label").

Example: Social Links with data-binding#

<a href="https://www.facebook.com/groups/" title="Facebook" data-event="ga:social:facebook" class="FacebookButton"></a>
<a href="https://twitter.com/" title="Twitter Stream" data-event="ga:social:twitter" class="TwitterButton"></a>

Finally, we need some javascript to process the additional attributes. You should always check if Google Analytics is enabled (maybe an adblocker is used or an opt-out option is set!) to avoid javascript errors. The following code will send an event to analytics each time a user clicks on the bound elements.

MooTools based Data-Binding#

window.addEvent('domready', function(){
  // GA loaded ? Used to avoid js errors on blocked analytics
  if (typeof ga !== 'function'){
    return;
  }
  
  // event binding
  document.getElements('[data-event]').each(function(el){
    // get event string
    var d = el.get('data-event').split(':');
    
    // format:  "type:category:name"
    if (d.length != 3){
      return;
    }
    
    // extract vars
    var evtType = d[0];
    var evtCategory = d[1];
    var evtName = d[2];
    
    // outgoing link on click event
    el.addEvent('click', function(){
      // universal analytics event ?
      if (evtType == 'ga'){
        ga('send', 'event', evtCategory, 'click', evtName);
      }
    });		
  });
});

 

Simple “Zen” Reading Mode with MooTools

simplifying website headers on-demand

Gigantic, image-based headers are an up-to-date web-feature. It looks amazing but they are squandering space, especially on sites with large tutorials containing long text.

This site is using a simply method which transforms the header-size depending on the current page-scroll: the users scrolls down and the header is automatically transformed to a smart toolbar – i’m calling this mode (following WordPress’ fullscreen editor) “Zen” reader mode. Need a demo ? Just open an article on this site and scroll down.

To integrate this feature into you website, you need the followindd things:

  • “Standard” Header Design
  • “Smart/Compact” Header Design
  • Javascript Page-Scroll Observer
  • Optional: Amazing css3 transition

Different Header-Styles (using LESS):#

/* Basic (default) Styling */
.navbar-beyond{
  height: 70px;
  .transition(500ms);
}

/* Smart Styling */
.navbar-beyond-light{		
  height: 45px;
  border-bottom: solid 1px #e7e7e7;	
  background-color: @color_bluegrey1 !important;
}

/* Large Navbar */
.navbar-beyond-dark{
  background-color: rgba(0,0,0,0.85);
  border-bottom: none;
}

Scroll-Observer Script (MooTools) :#

Description: user scrolls 200px down and the header is transformed by changing the css classes

var head = document.getElement('header .navbar-beyond');
... 
window.addEvent('scroll', function(){
  // get current scroll
  var s = this.getScroll().y;
        
  // dark/light topnav
  if (s > 200){
    head.addClass('navbar-beyond-light');
    head.removeClass('navbar-beyond-dark');
  }else{
    head.addClass('navbar-beyond-dark');
    head.removeClass('navbar-beyond-light');
  }
});

Header Structure (Bootstrap based example from this website)#

<!-- Fixed navbar -->
<div class="navbar navbar-default navbar-fixed-top navbar-beyond navbar-beyond-dark" role="navigation">
  <div class="container container-lg">
    <!-- Website Title + Mobile Nav Button !-->
    <div class="navbar-header">
      <button type="button" class="navbar-toggle">
        <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="http://andidittrich.de">Beyond Technology<br /><span>beyond the visible world</span></a>
    </div>
    
    <!-- Navi !-->
    <div class="navbar-collapse hidden-xs">
      <ul id="menu-topnavi" class="nav navbar-nav navbar-right">
      ....
      </ul>
    </div>
  </div>
</div>

<!-- Image -->
<div id="HeaderImage">
</div>

PHP-FPM “Access Denied” on .phtml Files

a problem which took about 1h of research..

Some Weeks ago, i switched most of the webserver setups from custom spawn-fcgi init scritps to php-fpm and everything seems to work fine until today. The php-version of GitHubButtons won’t work anymore – just a text-message appears: “Access Denied.” First of all i thougt it was a problem with lighttpd and the fastcgi.map-extensions directive, but the error message doesn’t seem to be served by lighttpd…and well…it was a php-fpm related issue, beacause php-fpm only processes .php files by default!

You will not find these directive in the official FPM Documentation on php.net – it’s missing including tons of other directives. To get an overview about all possible php-fpm config keys, you should take a look into to default php-fpm.conf file included into the php-sources (sapi/fpm/php-fpm.conf) – also attached to this post!

Important: This directive can’t be used in global context, it’s a pool based config key!

Examle Pool: php-fpm.conf#

[pool-testwww]
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
; Recommended: .php .phtml
security.limit_extensions = .php .php3 .php4 .php5 .phtml

Add Links to WordPress Plugin Page (Metadata Row)

Additional News/Update or Settings Links

Sometime you want to add special links directly to the plugin-page. For example, you can enable an easy access to the plugin’s settings-page or to related docs/resources. All the magic is done within the plugin_row_meta hook.

It’s important to check which plugin is currently processed (there are no plugin/namespace specific hooks). Therefore you have to check which plugin-(main)file is selected: if ($file == 'enlighter/Enlighter.php'){

Additional links can be added to the $links array including I18n support.

Appearance#

additional_plugin_links

How it’s done#

// add links
add_filter('plugin_row_meta', 'addPluginPageLinks', 10, 2);

// links on the plugin page
function addPluginPageLinks($links, $file){
  // current plugin ?
  if ($file == 'enlighter/Enlighter.php'){
    $links[] = '<a href="'.admin_url('options-general.php?page='.plugin_basename(__FILE__)).'">'.__('Settings', 'enlighter').'</a>';
    $links[] = '<a href="https://twitter.com/andidittrich">'.__('News & Updates', 'enlighter').'</a>';
  }
  
  return $links;
}