jQuery Mobile und jQuery UI sind tot

Die bekannte JavaScript-Bibliothek jQuery, welche unter anderem zur Manipulation des DOMs genutzt wird, wird von zwei Bibliotheken flankiert, welche sich dem UI annehmen. Die Rede ist von jQuery Mobile und jQuery UI. Mithilfe dieser Bibliotheken ist es möglich Oberflächen für Webanwendungen zu entwickeln.

Eine mittels jQuery UI entwickelte Webapplikation

Während sich die Bibliotheken weiterhin sehr beliebt sind, was sich unter anderen in den Fragen auf Stack Overflow widerspiegelt, gibt es ein Problem mit den Projekten; sie sind praktisch tot. Der letzte Commit für jQuery UI ist vom Mai 2017 und auch die Entwicklung der letzten Jahre von jQuery Mobile ist sehr übersichtlich. Ansonsten sind viele andere Zeichen zu entdecken das die beiden Projekte tot sind.

Für neue Projekte in der Webentwicklung, sollte sich deshalb nach einem anderen Framework für die Erstellung von Weboberflächen umgesehen werden. Eine Alternative stellt unter anderem Framework 7 dar, welches von der Einfachheit der jQuery UI– und jQuery Mobile-Bibliotheken inspiriert ist.

Internationalisierung mittels JavaScript

Für mein neues Projekt Wryte war ich auf der Suche nach einer Möglichkeit die Anwendung zu lokalisieren. Das genutzte Framework 7 unterstützt leider keine Lokalisierung von Haus aus, so das diese nachgerüstet werden musste. Zum Tragen kam hierbei die JavaScript-Bibliothek i18next. Nach dem Download und der Einbindung der Bibliothek kann diese initialisiert werden:

i18next
  .use(window.i18nextBrowserLanguageDetector)
  .init({
    debug: false,
    resources: {
      en: {
        translation: {
          "about": "About"
        }
      },
      de: {
        translation: {
          "about": "Über"
        }
      }
    }
  });

In diesem Fall wird zusätzlich der i18nextBrowserLanguageDetector eingebunden, damit die Sprache des Nutzers automatisch erkannt wird. Anschließend kann die Übersetzung abgerufen werden:

$('#tab-author').html(i18next.t('author'));

Nach diesem Schema lässt sich anschließend die gesamte Anwendung übersetzen. Die offizielle Projektseite von i18next ist unter i18next.com zu finden. Die Quelltexte der einzelnen Projektbestandteile sind auf GitHub zu finden. Lizenziert ist i18next unter der MIT-Lizenz und damit freie Software.

Quellcode-Formatierung unter WordPress

Wenn Quelltext in einem WordPress-Beitrag untergebracht wird, so ist dieser in einem pre-Block meist relativ unansehnlich. Im Plugin-Verzeichnis existieren für dieses Problem eine Reihe von Plugins, welche sich der Codeformatierung annehmen.

Mithilfe einer modifizierten Version der Google-Bibliothek code-prettify wird der Quelltext eingefärbt

Problematisch an diesen Plugins ist allerdings, dass der Nutzer in meisten Fällen alle Beiträge entsprechend anpassen muss. Bei einigen Beiträgen mag dies noch funktionieren, aber bei einigen tausenden Beiträgen ist dies relativ unpraktisch. Abhilfe schafft hier das Plugin Code Prettify von Kaspars Dambis.

Code Prettify
Preis: Kostenlos

Mithilfe einer modifizierten Version der Google-Bibliothek code-prettify wird der Quelltext eingefärbt. Alle pre-Blöcke werden entsprechend behandelt und dies führt zu einem ansehnlicheren Quelltext:

public int doFooBar() {
    int prime = generatePrime();
    return prime * 3.14;
}

Die Entwicklung des Plugins findet auf GitHub statt. Lizenziert ist Code Prettify unter der Apache License in der Version 2 und damit freie Software.

Geocoding in Verbindung mit einer Leaflet-App

Gestern schrieb ich in einem Artikel, wie Adressen aus Koordinaten mittels des Dienstes Nominatim, unter Zuhilfenahme von OpenStreetMap-Daten, ermittelt werden können. Mithilfe der freien Bibliothek Leafleat, kann dies nun in eine kleine Webapplikation gegossen werden.

Anhand der Geo-Koordinate wird die Adresse ermittelt und dargestellt.

Ziel ist es eine Applikation zu bauen, welche eine Karte darstellt und bei einem Klick auf diese Karte den Geocoding-Dienst anfragt. Sobald die Antwort vom Dienst eingetroffen ist, soll in einem Pop-up die Adresse dargestellt werden. Nachdem ein Grundgerüst in Form einer HTML-Datei erstellt wurde, werden dort die benötigten Bibliotheken (Leaflet und jQuery) eingebunden. Anschließend kann die Karte erzeugt werden. Damit diese im Vollbild dargestellt wird, findet sich eine entsprechende CSS-Definition in der Datei:

<style type="text/css">
	body {
		padding: 0;
		margin: 0;
	}

	html, body, #map {
		height: 100%;
	}
</style>

Anschließend kann der TileLayer angelegt werden und der Map zugewiesen werden:

// Options
var centerLatitude=53.49577;
var centerLongitude=13.30873;
var zoomLevel=15;

// Define layer
var openStreetMapLayer = new L.TileLayer(
		'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
		{attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>'});

// Define map
var map = L.map('map', {
	center: new L.LatLng(centerLatitude, centerLongitude),
	zoom: zoomLevel,
	layers: [openStreetMapLayer]
});

Für die Karte muss im nächsten Schritt ein Click-Event definiert werden, welches den AJAX-Request gegen den Geocoding-Dienst auslöst und den Marker erstellt. Der jeweilige Marker wird in eine separate Ebene gepackt und beim nächsten Klick wieder gelöscht und anschließend ein neuer Marker erstellt:

// Marker managment
var markerLayer;
map.on('click', function(e){

	// Console debug
	var coord = e.latlng;
	var lat = coord.lat;
	var lng = coord.lng;
	console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng);

	// Marker managment		
	if(markerLayer != undefined) {
		map.removeLayer(markerLayer);
	}
	
	markerLayer = new L.Marker(e.latlng);
	map.addLayer(markerLayer);

	// Call geocode api
	var request =	$.ajax({
		method: "GET",
		url: "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lng + "&format=json"
	});

	request.done(function( json ) {
		console.log(json);
		markerLayer.bindPopup(json.display_name).openPopup();
	});
});

Am Stück sieht die Applikation wie folgt aus:

<!DOCTYPE html>
<html>
<head>
	<title>Leaflet address encoder</title>
	<meta charset="utf-8" />

	<meta name="viewport" content="width=device-width, initial-scale=1.0">

	<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
   integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
   crossorigin=""/>
	
	<style type="text/css">
		body {
			padding: 0;
			margin: 0;
		}

		html, body, #map {
			height: 100%;
		}
	</style>
	
	<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
   integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
   crossorigin=""></script>
	<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body>
	<div id="map"></div>
	
	<script>
	        // Options
		var centerLatitude=53.49577;
		var centerLongitude=13.30873;
		var zoomLevel=15;
		
		// Define layer
		var openStreetMapLayer = new L.TileLayer(
				'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
				{attribution: '<a href="https://www.openstreetmap.org/copyright">© OpenStreetMap contributors</a>'});
		
		// Define map
		var map = L.map('map', {
		    center: new L.LatLng(centerLatitude, centerLongitude),
		    zoom: zoomLevel,
		    layers: [openStreetMapLayer]
		});
		
		// Marker managment
		var markerLayer;
		map.on('click', function(e){

			// Console debug
			var coord = e.latlng;
			var lat = coord.lat;
			var lng = coord.lng;
			console.log("You clicked the map at latitude: " + lat + " and longitude: " + lng);

			// Marker managment		
			if(markerLayer != undefined) {
				map.removeLayer(markerLayer);
			}
			
			markerLayer = new L.Marker(e.latlng);
       		map.addLayer(markerLayer);

			// Call geocode api
			var request =	$.ajax({
				method: "GET",
				url: "https://nominatim.openstreetmap.org/reverse?lat=" + lat + "&lon=" + lng + "&format=json"
			});

			request.done(function( json ) {
				console.log(json);
				markerLayer.bindPopup(json.display_name).openPopup();
			});
  		});
	</script>
</body>
</html>

Alternativ kann der Quelltext heruntergeladen bzw. ausprobiert werden.

JavaScript-Bibliothek für interaktive Karten

Interaktive Karten im Browser darzustellen ist sicherlich kein seltener Anwendungsfall im Web. Für die eigentliche Darstellung der Karten existieren unterschiedlichste Frameworks bzw. Bibliotheken wie z.B. OpenLayers.

Eine mit Leaflet realisierte Kartenapplikation

Daneben existiert seit 2011 die JavaScript-Bibliothek Leaflet. Mit dieser leichtgewichtigen Bibliothek, können interaktive Karten schnell aufgesetzt werde. Dabei werden TileMaps ebenso wie Web Map Services als Quelle für die eigentliche Karte unterstützt. Neben Features wie Overlays und der Unterstützung unterschiedlicher Projektionen ist Leaflet für die Nutzung auf dem Desktop und auf mobilen Endgeräten ausgelegt.

Der Quelltext der Bibliothek ist auf GitHub zu finden. Lizenziert ist Leaflet unter der BSD-Lizenz in der Zwei-Klausel-Variante und damit freie Software. Die offizielle Seite des Projektes ist unter leafletjs.com zu finden.