Einen Blog als Single Page Web App mit AngularJS und WordPress Teil 1

Single Page Web Apps sind moderne Webseiten, bei denen der Inhalt nicht, wie bei einer herkömmlichen Seite, durch einen Seitenwechsel dargestellt wird, sondern dynamisch geladen und an der entsprechenden Stelle durch HTML Templates eingebunden wird.

AngularJS ist ein Javascript Framework das sich hervorragend dafür eignet einen Blog, oder auch was anderes, als Web App zu programmieren. WordPress bietet durch Jetpack von Haus aus eine Schnittstelle von der man alle nötigen Daten abrufen kann. Ich nutze jedoch ein anderes Plugin (JSON API), da dieses umfangreicher ist.

angularjs

Teil 1: Abrufen und anzeigen der Blogposts

Wir beginnen mit der index.html. Hier binden wir die nötigen Angular Dateien ein und starten unsere App. Das ngApp Attribut im Body Element signalisiert Angular, dass ab hier die App initialisiert werden soll, der Wert “thisiswebBlog” ist der Name des Modules das wir in der app.js anlegen. ngView definiert den Bereich in dem später die weiteren Templates geladen werden.

index.html

[code lang=”html”]
<!DOCTYPE html>
<html lang=”de-de”>
<head>
<meta charset=”utf-8″>
<title>Angular WordPress Blog</title>

<!– Angular –>
<script src=”https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js”></script>
<script src=”https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.js”></script>
<script src=”https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-sanitize.js”></script>
<script src=”js/app.js”></script>
<script src=”js/controllers.js”></script>
<script src=”js/services.js”></script>

</head>
<body ng-app=”thisiswebBlog”>
<div>
<div>

<div ng-view></div>

</div><!– #content –>
</div>
</body>
</html>
[/code]

Die Datei app.js muss in dem Ordner “js” erstellt werden. Dort wird zunächst unser Angular Modul “thisiswebBlog” mit den Abhängigkeiten ngRoute, ngSanitize und unseren eigenen Controllern “thisiswebBlogControllers” und “thisiswebBlogServices” erstellt.
Danach werden die Routen konfiguriert. Das bedeutet, wir legen fest, welches Template und welcher Controler verwendet werden soll, wenn eine bestimmte URL aufgerufen wird. Mehr dazu kann man hier nachlesen.

app.js

[code lang=”js”]
‘use strict’;

/* App Module */

var thisiswebBlog = angular.module(‘thisiswebBlog’, [
‘ngRoute’,
‘ngSanitize’,
‘thisiswebBlogControllers’,
‘thisiswebBlogServices’
]);

thisiswebBlog.config([‘$routeProvider’,
function($routeProvider) {
$routeProvider.
when(‘/blog’, {
templateUrl: ‘partials/blog-list.html’,
controller: ‘PostsListCtrl’
}).
otherwise({
redirectTo: ‘/blog’
});
}]);
[/code]

Als nächstes erstellen wir eine Service Factory in der Datei services.js die auch im Ordner “js” sein muss. Was das ist, kann man hier nachlesen. Wir geben der Factory den Namen “Posts”, über den wir später darauf zugrifen können und eine Funktion mit dem $http Service als Parameter. In der Methode “getPosts” nutzen wir den $http Service, der für uns ein JSONP Objekt von der angegebenen url: ‘http://thisisweb.de/wordpress/api/get_posts/?callback=JSON_CALLBACK&count=100’ anfordert (Die letzten 100 Blogposts von dem WordPress Blog, falls es so viele gibt.)

services.js

[code lang=”js”]
‘use strict’;

/* Services */

var thisiswebBlogServices = angular.module(‘thisiswebBlogServices’, []);

thisiswebBlogServices.factory(‘Posts’,
function ($http) {
var thisisweb = {};

thisisweb.getPosts = function() {
return $http({
method: ‘JSONP’,
url: ‘http://thisisweb.de/wordpress/api/get_posts/?callback=JSON_CALLBACK&count=100’,
headers: {
‘Accept’: ‘application/json, text/javascript’,
‘Content-Type’: ‘application/json; charset=utf-8’
}
});
}

return thisisweb;
});
[/code]

Jetzt benötigen wir noch unseren Controller “PostsListCtrl”. Dazu erstellen wir die Datei controllers.js im Ordner “js”. Zunächst erstellen wir das Modul “thisiswebBlogControllers” das wir in der app.js schon bekannt gemacht haben. Dann rufen wir die Funktion “thisiswebBlogControllers.controller” mit dem entsprechenden Namen “PostsListCtrl” und den weiteren Parametern “$scope“, “Posts” (unsere Factory) und einer Funktion (in der wir unseren Code schreiben) auf, wodurch unser Controller registriert wird.
In unserem Controller rufen wir die Funktion “getPosts” auf. Wenn diese erfolgreich war, weisen wir der Variable $scope.posts das posts-Objekt (alle Blogposts) zu, so dass wir aus dem HTML Template später darauf zugreifen können.

controllers.js

[code lang=”js”]
‘use strict’;

/* Controllers */

var thisiswebBlogControllers = angular.module(‘thisiswebBlogControllers’, []);

thisiswebBlogControllers.controller(‘PostsListCtrl’, [‘$scope’, ‘Posts’,
function ($scope, Posts) {

Posts.getPosts().success(function (response) {
$scope.posts = response.posts;

});

}]);
[/code]

Nun benötigen wir nur noch das blog-list.html Template, das wir im Ordner “partials” anlegen. Dort durchlaufen wir mit ngRepeat alle Posts. Mit den Klammern {{ }} kann man eine Variable im HTML benutzen, z.B. {{post.id}}. Für den Text und den Titel müssen wir ngBindHtml nutzen, da WordPress den Text mit HTML Elementen speichert. ngBindHtml rendert dies dann auch als HTML, ansonsten würden die HTML Elemente sichtbar sein. Desweiteren sollte man bei Bildern oder Links ngSrc oder ngHref Direktiven nutzen, da es sonst zu Fehlern kommen kann.

blog-list.html

[code lang=”html”]
<div ng-repeat=”post in posts”>
<article id=”{{post.id}}”>
<header>
<img ng-src=”{{post.thumbnail_images.medium.url}}” />
<h1 class=”entry-title” ng-bind-html=”post.title”></h1>

<div>
<p>
Ver&#246;ffentlicht am {{post.date}} <br />
<span ng-repeat=”cat in post.categories”>
{{cat.title}}
</span>
</p>
</div>
</header>

<div>
<p ng-bind-html=”post.excerpt”></p>
</div>

</article>
</div>
[/code]

Jetzt sollte die Anwendung funktionieren und schon mal die Blog Beiträge auflisten.

Wie es weiter geht

Im nächsten Teil formatieren wir das Datum und erstellen ein neues Template für die Detail-Ansicht eines Beitrages. Danach kommen weitere Funktionen wie

  • Suche
  • Filtern nach Kategorien
  • Anzeigen der Seiten
  • Styling der Seite
  • Kommentare
  • und so weiter