Sunday, September 10, 2017

DotNet core and vuejs - a quick recipe

The problem

So you're stuck in .NET world (maybe with Sitecore or some other God forsaken creation) and you need to do some front-end code. How the hell do you get started?

The solution

Use dotnet core 2.0.0. Scaffold your application, install all the required dependencies and start the application in development mode

    $ sudo apt-get install dotnet-sdk-2.0.0
    $ dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
    $ dotnet new vue -n hello-world
    $ cd hello-world
    $ dotnet restore
    $ npm install
    $ ASPNETCORE_ENVIRONMENT="Development" dotnet run

Happy coding

Tuesday, September 5, 2017

Back to the roots: defining a jQuery plugin in TypeScript

The problem

You're so proficient in TypeScript that you decided all your code will be type-safe. All that is left is this damn jQuery plugin that won't bow to your will and you have no idea how to make all the typing information work.

The solution

This is actually quite easy! Let's start with the obvious import:

    import * as $ from 'jquery'

Next you need to decide if your plugin will take configuration options. If that is the case then you need an interface describing those options

    interface FooOptions {
      color?: string

Now we need to tell TypeScript that we're going to extend the global JQuery interface with our method:

    declare global {
      interface JQuery {
        foo(options?: FooOptions): JQuery

The question mark after options means this is an optional parameter and if not defined then an undefined value will be passed on

All that is left is to write the plugin itself

    $ = function(this: JQuery, options?: FooOptions) {
      const settings: FooOptions = {
        color: 'blue',
      return this.each(function() {
        $(this).css({ 'background-color': settings.color })

The method signature tells TypeScript that this in this context is a jQuery object and that there can be a FooOptions passed on.

The rest is obvious: using object spread operator we get the actual set of settings and next we just go on with the plugin's body.

Happy coding!

Back to the roots: jQuery plugins and TypeScript

The problem

So you have learned TypeScript but there is no escape from jQuery. It's crawling back over and over again from the dungeons. But you'd like to write your code in TypeScript and this damn thing doesn't know your new cool method? Want to teach it a lesson? Read on!

The stage

TypeScript is great! No question about it. I use it primarily with webpack and it is a wonderful combination. One of the best things it has is the ability to merge interface definitions. That's right! You can literally extend the interface as you wish! This will come very handy when adding new methods to be called in a jQuery chain. First let's define a plugin foo in plain JavaScript.

    import * as $ from 'jquery'

    $ = function () {
      return this.each(function() {
        $(this).css({ 'background-color': 'blue' })

Nothing fancy, right? Each element passed on will receive a blue background. I love blue that is why it is blue and not red.

The solution

Now for the tricky part: teaching TypeScript the definitions. I say definitions because we'll teach it first the JQuery interface by installing the @typings/jquery package

    $ npm install --save-dev '@types/jquery'

Now if you're like me and you use jQuery 3 or later with the default TypeScript configuration you will see a message saying something about Iterable. That's easy to fix. In the tsconfig.json make sure you have the lib line containing the es2015.iterable element, like so:

    "compilerOptions": {
        "lib" : [ "es2015", "es2015.iterable", "dom" ]

With that out of the way let's teach TypeScript the new foo

    declare global {
      interface JQuery {
        foo (): JQuery

This is called declaration merging and allows for arbitrary declarations to be added to arbitrary interfaces just like in JavaScript you can add arbitrary fields to arbitrary objects. Cool, ain't it?

Also note that we use the global module. That's because if we're inside of another module then the original JQuery interface is a different one from the one defined in the global scope and things just don't go so well in that case.

Now let's use our new toy:


Don't forget the new way of importing jQuery requires the allowSyntheticDefaultImports compiler option.

Happy coding!

Friday, September 1, 2017

Back to the roots: jQuery plugin authoring

The problem

The code you're writing using jQuery becomes unmaintainable and hard to read

The solution

Short of stop using jQuery (if that is an option you can use then go for it and use Vue.js instead) start by extracting reusable components/plugins from your code. Writing such a plugin is nothing hard - just a frame where you put your code in:

    (function($) {
      $.fn.myPlugin = function(options) {
        const defaults = {
          // TODO: add default values for options here
        const settings = $.extend(defaults, options)
        // Either process each element in a loop
        return this.each(function() {
          // TODO: add the body of what the plugin should do
          // 'this' is the current element when iterating
        // or operate on all elements at once using other functions
        // return this.css({ ... })

More on authoring jQuery plugins here.

With that in place you're ready to create whatever is used in multiple places like the grownups do and enjoy the pleasure of using method chaining even more!

    $('.my-component').myPlugin({ color: red });

Going Webpack!

It is said that once you go Webpack you never go back. If that's your case then you might want to create your plugins as separate modules and let Webpack put it all together nice and easy. To do that you define your plugin as a module that imports jQuery and exports nothing, then you import that module in your main application file.

    import $ from 'jquery'

    $.fn.myPlugin = function(options) {
      const defaults = {
        // TODO: add default values for options here
      const settings = $.extend(defaults, options)
      // Either process each element in a loop
      return this.each(function() {
        // TODO: add the body of what the plugin should do
        // 'this' is the current element when iterating
      // or operate on all elements at once using other functions
      // return this.css({ ... })

In main.js

    import $ from 'jquery'
    import './my-plugin'

    $(document).ready(function() {
      // use your plugin here
      $('.my-component').myPlugin({ color: red });

The easiest Webpack configuration that will work in this case is

    module.exports = {
      entry: __dirname + '/index.js',
      output: {
        path: __dirname + '/dist',
        filename: 'index.js'
      devtool: 'source-map'

In this case you can include the dist/index.js and you'll have all you need in one place. And that's it! Easy as a lion :)

And last but not least: don't name your plugin myPlugin. It's lame to do in anything else than a tutorial. Be explicit, use good names, be a good programmer!

Happy coding!


Please be mindful that the function assigned to $.fn.myPlugin as well as the one that iterates over elements that have been passed on can't be arrow functions because jQuery sets the this element. Just remember that.

Friday, July 28, 2017

Getting started with Quasar on Android with Linux

The problem

As usual the problem is setting up the development environment for a project. This time it's going to be project using the Quasar framework and building the app for Android. This guide assumes a clean environment that does not contain anything (no Java, no Node no nothing).


First we need to have NodeJS installed. I install mine using the Node Version Manager (or nvm for short). Follow the instructions on or simply enter the following commands:

$ curl -o- | bash

At this stage you need to close the current terminal and open a new one for the installation to finish and then install the latest stable NodeJS like so:

$ nvm install stable

We'll need two more things: JDK and Gradle. I install mine using the SdkMan:

$ curl -s "" | bash

At this stage you need to close the current terminal and open a new one for the installation to finish and then install Java and Gradle like so:

$ sdk install java
$ sdk install gradle 2.14.1

The version of Gradle is important. Cordova works with specific versions so you might want to stick to 2.14.1 to avoid any issues

Next we need to have some basic tooling for NodeJS installed. This includes obviously the Quasar CLI but also Yarn and Cordova

$ npm install -g yarn quasar-cli cordova

Having all that installed we can now instantiate and build our first project

$ quasar init hello-world
$ cd hello-world
$ yarn
$ yarn build

At this stage we have have the hello-world type quasar application built. We can work on it as if it would be any other VueJS application by running

$ yarn dev

More on it in the official documentation for Quasar

What we need next is the Android SDK. This is the most troublesome part of all, but if scripted it doesn't seem to be all that hard. First you need to download and extract the Android SDK. To do that we'll use the unzip tool that understands the .zip archive format. Be patient. It takes forever to download and install all the components. On my connection it took almost 10 minutes!!!

$ sudo apt install -y unzip
$ mkdir -p ~/Android/Sdk
$ cd ~/Android/Sdk
$ wget -c
$ unzip -q
$ cd tools/bin
$ ./sdkmanager --update
$ ./sdkmanager emulator platform-tools
$ ./sdkmanager "build-tools;25.0.3"
$ ./sdkmanager "platforms;android-25"
$ ./sdkmanager "system-images;android-25;google_apis;x86"
$ ./avdmanager create avd --force \
               --name test \
               --package "system-images;android-25;google_apis;x86" \
               --tag google_apis \
               --device 'Nexus 4'

Starting the emulator takes some time - be patient!

$ ~/Android/Sdk/tools/emulator -avd test -skin 768x1280

After it is up we have a platform to run our Quasar application on. Let's use it to run our new and shiny app.

$ cd [your_project_folder]
$ quasar wrap cordova
$ cd cordova
$ ANDROID_HOME=~/Android/Sdk cordova platform add android
$ ANDROID_HOME=~/Android/Sdk cordova build
$ ANDROID_HOME=~/Android/Sdk cordova run

That's it! The application should be running on your virtual Android device. Of course you should make the ANDROID_HOME variable more permanent by adding it to your .profile or .bashrc startup files but I'll leave it up to you.

Have fun!

Sunday, May 28, 2017

Vue.js cheatsheet

If you ever wondered why Vue.js is so easy take a look at this cheatsheet!

Vue/Vuex - a natural way forward

For a few days I have been creating an application to help with retrospection meetings in our distributed team. Obviously, as one might have guessed, the backend is in Node.js and, obviously, the frontend is in Vue.js. After a trial and error of a few approaches I decided that the state management is basically killing me so I went for Vuex to do its job. I knew little to nothing about Vuex but obviously I have had a lot of experience with Redux and since both do the same thing I thought things won't be too difficult. And I was right!

I followed this great article by Matt Bradford on how to get started with Vue+Vuex and I need to say that he hit the nail in the head with that article. Easy to follow, clear in message - just perfect. Then I went on to the official docs and, as usual with all things related to Vue.js, the guide was just perfect. It took me about 2 hours while creating the app to get used to it, learn the API, understand the difference between actions and mutations - basically a walk in the park!

The key takeaway from this experience for me is that documentation matters, a lot! It has to be good, easy to understand and fun to follow. Like a well written book that you can't take your eyes off late in the evening. Of course it helps if the thing the documentation describes is easy and fun but that is just about 30% - the rest is the craftsmanship of the author of the documentation. To underline that I have been reading some very ugly specs at work, written like someone didn't want to read what he wrote. That was just crazy! After that getting my hands on the Vuex guide helped me keep up the hopes for humanity :P

The bottom line is: if you feel like you're struggling with managing the state, even just a little bit - you need Vuex!

The next thing I desperately wanted to try was to make a system that through websockets to distribute the changes to other connected clients. This means that when you add a card on one browser that information is then posted via the websocket and the server broadcasts that information back to other browsers. I must say I am extremely surprised how well that worked! One thing to note is that when working on the store full page reloads do happen a lot. Each full reload causes the socket to be closed and reopened - which isn't all that bad. However restarting the server is a whole other story because websockets don't reconnect automagically. In this case, after trying out what I thought would work I ended up using reconnecting-websocket module. And it works absolutely great!

The server side uses the no database approach with a simple on-line events store and commands that mirror the mutations in Vuex. Easy and very, very fast! It looks like event sourcing is actually a good thing :)

You can find the sources for the project on Github.

Happy coding!

Thursday, May 18, 2017

Vue, Vue CLI, Webpack template, Nightwatch and page obect pattern

Today I tried to use the page object pattern with Nightwatch.js that is created when using the webpack template in vue-cli. It turns out they are not configured by default. This means you need to add

page_objects_path: ['test/e2e/pages'],
to your tests/e2e/nightwatch.conf.js file to start using it.

The usage scenario is quite simple

  1. Create a file describing the page
  2. Use it in a test

Everything you need to know about page object pattern and Nightwatch is here so don't hesitate to check it out. Here's a basic example, the initial e2e test created when the app was scaffolded, but this time rewritten using page object patter.

// For authoring Nightwatch tests, see

module.exports = {
  'default e2e tests': function (browser) {
    // automatically uses dev Server port from /config.index.js
    // default: http://localhost:8080
    // see nightwatch.conf.js
    const devServer = browser.globals.devServerURL
      .assertHeaderText('Welcome to Your Vue.js App')


And now the page definition in tests/pages/home.js:

module.exports = {
  elements: {
    container: {
      selector: "#app"
    hello: {
      selector: ".hello"
    title: {
      selector: "h1"
    logo: {
      selector: "#app > img"
  commands: [ {
    open(url) {
      return this
        .waitForElementVisible('@container', 5000)
    assertHeaderText(content) {
      return this.assert.containsText('@title', content)
    assertMainContentPresent() {
      return this.assert.elementPresent('@hello')
    assertMainLogoPresent() {
      return this.assert.elementCount('@logo', 1)
  } ]

Basically a page object is what a module exports. It is divided into 3 sections

  • elements - definition how to find certain elements
  • commands - pieces of work the page does
  • sections - (absent in this example)grouping mechanism for definitions

That's it

Wednesday, May 17, 2017

Performance of frontend frameworks

This is going to be just a quick note to myself

Don't base your choice on performance only. Currently pretty much all frameworks yield similar results (yes, even Ember is catching up with Glimmer, even though it is still slower than the other ones from the big 4). Use common sense, which is not so common, and let the simplicity and flexibility of use be your guiding star. If however the performance is not acceptable from the start and the framework doesn't have you on your knees begging to use it then just don't go for it.

Even though Ember is getting faster (I just threw up in my mouth a little bit) it doesn't mean it is sane to use it in any project of any size with Vue, Angular and React being out there

Happy coding

Monday, May 1, 2017

Vue directive NAME/V

Have you ever tried to remember the elements of a Vue's directive? But there are so many of them! Don't worry - they are very easy to remember!

Name - the part that comes right after "v-"

Argument - the part that comes right after the colon

Modifiers - the part that comes after dot

Expression / Value - the expression put inside the parameter value and the evaluated value

NAME / V - for short

Happy coding!

Tuesday, April 4, 2017

Recording screencast with Atom and Firefox

The need

I have recently started work on a video course about VueJS. The major part of it are screen recordings. I went through the original documentation my editor provided and it was just for Win/Mac (no surprise there) so I needed to go and figure it out for myself.

The how

As it turns out recording screen on Linux is quite easy. There are lots of good applications for it. I went with the good old ffmpeg

$ Xephyr :1 -ac -screen 1280x720 -br -reset &
$ sleep 2
$ setxkbmap -display :0 -print | xkbcomp - :1 &> /dev/null
$ DISPLAY=:1 evilwm -snap 50 &
$ DISPLAY=:1 atom &
$ DISPLAY=:1 firefox &

Now that we have all the apps running in a nice enclosure let's record the action:

$ ffmpeg \
    -f pulse -ac 2 -i default \
    -f x11grab -r 25 -s 1270x720 -i :1 -c:v libx264 \
This will create a new file with human readable timestamp each time you run this command encoding the 720p video in h.264 format and audio in AAC putting it all into an MPEG4 container.

Making Atom captures easy to edit

When editing the video in post production, for example using Blender's NLE, it is hard to fit the blinking intervals when cutting parts of the video. For that reason I recommend disabling the blink cursor in Atom. Select "Open your stylesheet" menu item and enter the following snippet

atom-text-editor.editor .is-focused .cursors .cursor {
  opacity: 1

That's it. Now the cursor is solid and editing is easy again

Happy recording!

Saturday, March 4, 2017

Sending logs from NodeMCU/Lua to Graylog2

Graylog2 is a great product. It might not be the most sophisticated one when it comes to log aggregation and interrogation, but it does its job very well. After employing Graylog2 to collect logs from all my Docker containers I thought that it would be absolutely fantastic to be able to manage logs from the IoT devices as well.

Installing the right input plugin

Before we can push stuff into Graylog2 we need to teach it the protocol of IoT devices - MQTT. Luckily enough there is a ready-made and supported input plugin just for that. To install it simply download it to the plugin folder in your Graylog2 installation and restart Graylog2. Done.

The next thing is to add an input for MQTT. Select System/Inputs and then create an input by selecting MQTT TCP (GEFL) from the drop-down list of available connectors. You need to specify the MQTT server and queue which the connector will subscribe to. In the example below I used system/logs so if you would go for a different name you need to adjust the code accordingly. And last but not least you need to start the input by pressing the Start input button. Done.

Programming in Lua

Lua and the NodeMCU environment is a beautiful thing. It is simple, powerful and it just rocks. For our little project we'll need to build ourselves a version with bmp085, cjson, wifi and mqtt modules. Then we need to download it to the module and we're all set to start coding in Lua.

The code here initializes WiFi connection, once the connection is established connects to the MQTT server, initializes the BMP085 sensor (here we're using pins D2-sda and D1-scl as per the documentation) and sets up a recurring alarm every second to read the sensor and send GEFL-formatted logs if MQTT has been connected. Easy.

Transferring files to NodeMCU

There are many great ways to send Lua files to the module. I like to use the one written in NodeJS called nodemcu-tool

$ npm install -g nodemcu-tool
$ nodemcu-tool upload init.lua
$ nodemcu-tool terminal

Now press the reset button and your NodeMCU should inform you of 3 things:

  1. That it connected to WiFi network and has an IP address
  2. That it has connected to the MQTT server
  3. That it is sending logs to MQTT server
There is not much more to it. Give it a try and if you stumble upon any challenges getting it to work feel free to leave a comment.

Happy logging!

Spring Boot application with Graylog2

I have been looking for an alternative to Splunk for a while and recently I have stumbled upon Graylog2. It is a very advanced tool well worth looking at. I decided to do a minimalist Spring Boot project to test its capabilities

The configuration

There are 2 steps required in order to get the logs to Graylog2:

  • Adding an artifact with GEFL appender
  • Adding the GEFL appender
I have tried 2 different GEFL appenders: Logback-gelf v0.10p1 which did work but didn't give me all the necessary details into Graylog2, and logback-gelf that worked for me very well.

I added the dependency to my pom.xml as follows


And then added a logback configuration file to my resources

<?xml version="1.0" encoding="UTF-8"?>
    <include resource="org/springframework/boot/logging/logback/base.xml" />

    <appender name="GELF" class="de.siegmar.logbackgelf.GelfUdpAppender">
        <layout class="de.siegmar.logbackgelf.GelfLayout">
            <shortPatternLayout class="ch.qos.logback.classic.PatternLayout">
            <fullPatternLayout class="ch.qos.logback.classic.PatternLayout">

    <root level="trace">
        <appender-ref ref="GELF" />  
        <appender-ref ref="CONSOLE" />

This gave me all the logs into a local instance of Graylog2 running on Docker.

version: '2'
    image: "mongo:3"
    image: "elasticsearch:2"
    command: "elasticsearch'graylog'"
    image: graylog2/server:2.2.2-1
      GRAYLOG_PASSWORD_SECRET: somepasswordpepper
      GRAYLOG_ROOT_PASSWORD_SHA2: 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      - mongo
      - elasticsearch
      - "9000:9000"
      - "12201/udp:12201/udp"
      - "1514/udp:1514/udp"

Happy logging!

Monday, January 23, 2017

Creating an LTSP Server on Linux Mint

I wanted to try this out for ages but somehow I have never done it. Last weekend I decided to give it a go and to create an LTSP server and a thin client that'll start over PXE with no disk, floppy, USB stick or CD/DVD. It turned out to be quite simple but a few quirks made me wonder for a bit what the hell is going on. Here's a log of those things.

DHCP starts, TFTP from a live CD works but TFTP from PXE times out

That happens when using NAT network in VirtualBox. They are broken. Use 2 cards on the server, one in whatever mode you want, that will connect to the internet (I use bridged or NAT - both work fine) and for the second card use an internal network.

The server needs to have them properly configured. Leave the first one that's bridged to get its config using DHCP and the second one configure to have a static IP address (e.g., netmask of and NOTHING ELSE. For the client setup just one network card connected to internal network (same as for the server) and leave everything else be.

By the way, I used 2 different types of virtual network cards: Intel for the bridged one and AMD for internal network. The AMD card starts faster over DHCP :)

The /etc/ltsp/dhcpd.conf file needs to be updated accordingly. For the network I have configured mine as follows:


subnet netmask {
    option domain-name "";
    option domain-name-servers;
    option broadcast-address;
    option subnet-mask;
    option root-path "/opt/ltsp/i386";
    if substring( option vendor-class-identifier, 0, 9 ) = "PXEClient" {
        filename "/ltsp/i386/pxelinux.0";
    } else {
        filename "/ltsp/i386/nbi.img";
I have removed option routers ... and next-server [...] options because they are not necessary as I am not connecting the client to Internet (everything runs on the server) and I am running TFTP on the same host with DHCP server.

On Linux Mint "Reached target Graphical Interface." but nothing happens

This one is easy but not obvious if you have done LTSP on Ubuntu. After the initial creation of image (ltsp-build-client [...]) install virtualbox' X11 guest driver like so:

$ sudo ltsp-chroot -p -d apt-get install virtualbox-guest-x11
And then update the image as usual:
$ sudo ltsp-update-image
On Ubuntu-based servers those drivers get installed automatically. Very weird...

Fucked up client display

If you will see a display that is sort of hacked in half horizontally and then vertically with things looking like it's Picasso's fantasy then your client has either too much graphical memory, 3D acceleration enabled or too few MBs of RAM. I set my client VM to have 1GB RAM, 128MB video RAM and 3D acceleration enabled but your mileage might vary. Before you do anything just add RAM - that should help

The client started - what's the username and password?

This one is really tricky if you don't know what LTSP is all about. Essentially LTSP client is Linux with X11 and SSH client bound to your server. So whenever you are logging in use the same account as on server. If you need more users - add them to the server. And remember: all apps are not running on the client - they run on the server! This is why a Raspberry Pi works great as an LTSP client. I love it!

I have checked Linux Mint XFCE, Ubuntu 16.04.1, LUbuntu, Ubuntu Mate - they all work great. If you're a RedHat/Fedora fan you're on your own.

Happy LTSPing!