Cordova App mit WP REST API – Anzeige von Bildern und Öffnen von Artikeln

21. April 2017 - AngularJS, API, Cordova, Ionic, REST API, WP API

Im letzten Artikel ging es ja darum, wie man Inhalte mit Hilfe der WP REST API auslesen kann. In meinem Fall wurden mir die Überschriften der einzelnen Artikel der Besten Zeitung in einer Liste ausgegeben. Nun wollen wir das Ganze noch etwas ergänzen und ein wenig bunter und ansehnlicher gestalten.
Außerdem möchte ich zeigen, wie man die einzelnen Artikel anklickbar machen kann, um daraufhin die kompletten Texte zu den Artikel auf einer eigenen Seite anzuzeigen.

Bilder anzeigen

Fangen wir mit den Bildern an. Die Bilder sind etwas ineinander verschachtelt und die einzelnen Bezeichnungen sind meiner Meinung auch nicht so toll gewählt. Man hat in seinem response Object zuerst einmal ein _embedded. In diesem befindet sich ein wp:featuredmedia (und noch vieles mehr). In diesem wiederum befindet sind unsere Bildquelle. Falls sie überhaupt vorhanden ist. Und hier kommen wir zu einem kleinen Problem. Wenn kein Featured Image vorhanden ist, ist wp:featuredmedia nicht vorhanden, also undefined.

WP REST API response mit wp:featuredmedia

 

Wir müssen also, bevor wir unsere Artikel anzeigen lassen, vorher prüfen, ob es Artikel gibt, die keine Bilder haben. Ich habe mich, auch wegen der ganzen _ und : in den Bezeichnungen der Objekte, dafür entschieden ein neues und schlankeres Array mit den ganzen Artikeln zu erzeugen.

Vorher habe ich einfach mein response.data dem $scope.articles Array zugewiesen. Jetzt fülle ich es selbst mit den Inhalten, die ich eigentlich nur benötige.

Die Objekte (meine Artikel) im Array brauchen also nur eine id, einen title und ein image. (Die id brauchen wir später zum anzeigen der einzelnen Artikel)

Ihr müsst also über euren response iterieren und jedes Mal eure gewünschten Inhalte in das neue Array ($scope.articles) pushen. Dies sieht dann so aus:

$http({
          method: 'GET',
          url: 'http://bestezeitung.de/wp-json/wp/v2/posts?_embed',
          headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        }).then(function successCallback(response) {
          console.log("success");
          console.log(response);
          for(var i = 0; i < response.data.length; i++) {           
              $scope.articles.push({
                id: response.data[i].id,
                title: response.data[i].title.rendered,
                image: imageUrl
              });

          } // Ende For
                             
        }, function errorCallback(response) {
          console.log("error");
          console.log(error);
        });

Jetzt haben wir aber natürlich immer noch nicht abgefragt, ob überhaupt ein Featured Image vorhanden ist oder nicht. Mein zweiter Artikel über das große Einhorn Gewinnspiel hat beispielsweise kein Artikelbild. Also muss ich schauen, ob wp:featuredmedia nicht undefined ist. Wenn dies der Fall ist soll einfach ein “” als image url übergeben werden.

$http({
          method: 'GET',
          url: 'http://bestezeitung.de/wp-json/wp/v2/posts?_embed',
          headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        }).then(function successCallback(response) {
          console.log("success");
          console.log(response);
          for(var i = 0; i < response.data.length; i++) {
            var imageUrl;
            var featuredMedia = response.data[i]._embedded["wp:featuredmedia"];
              if(featuredMedia == undefined) {
                imageUrl = "";
              } else {
                imageUrl = response.data[i]._embedded["wp:featuredmedia"][0].source_url;
              }

              $scope.articles.push({
                id: response.data[i].id,
                title: response.data[i].title.rendered,
                image: imageUrl
              });

          } // Ende For       

        }, function errorCallback(response) {
          console.log("error");
          console.log(error);
        });

Nun müssen wir noch kurz unsere beste.html Datei an unser neues Array anpassen. Der Titel der Artikel befindet sich ja nun in article.title. Also schreiben wir:

<h1>{{article.title}}</h1>

Um unsere Bilder auszugeben können wir einfach mit einem ng-src die Image URL aus unseren Objekten einbinden.

<img ng-src="{{article.image}}">

Und et voilá, unsere App sieht wie folgt aus:

Artikel mit Bildern aber ohne Styling

Unschön. Einfach unschön. Aber das ist ja klar, da wir noch nichts in Sachen Styling unternommen haben.

strong>Das Styling mit CSS

Das wollen wir nun kurz ändern. Meine Artikel bekommen eine Container Klasse (articleContainer), meine Überschrift bekommt eine Klasse (articleH1) und meine Bilder bekommen ebenfalls eine Klasse, damit sie responsive dargestellt werden können (articleImg).

<ion-list>
      <ion-item ng-repeat="article in articles" class="articleContainer">
        <h1 class="articleH1">{{article.title}}</h1>
        <img ng-src="{{article.image}}" class="articleImg">
      </ion-item>
    </ion-list>

Die dazugehörige CSS Klasse sieht so aus:

.articleContainer {
  border-bottom: 1px solid grey;
  padding-bottom: 5px;
  margin-top: 10px;
  background: white;
}

.articleImg {
  max-width: 100%;
  height: auto;
}

.articleH1 {
  font-size: 1em;
}

.list {
  background: #ebebe0;
}

Die Artikel erhalten einen Border, ein wenig Abstand und einen weißen Hintergrund. Die Bilder bekommen eine max-width und eine automatische height. Die H1 eine font-size und die Klasse list, die wir haben, da wir ion-list verwenden, bekommt ebenfalls eine Hintergrundfarbe.

Bleibt jedoch immer noch ein Problem. Das Padding ist etwas unschön voreingestellt. Wir haben rechts viel mehr weiße Fläche als links.

Artikel mit Bildern - padding unschön

Das ändern wir, indem wir den entsprechenden Padding Wert nach allen Richtungen hin einheitlich setzen.

.item-complex .item-content, .item-radio .item-content {
  padding: 16px;
}

Die App sieht nun schon viel besser aus.

Artikel mit Bildern

Verlinkung der einzelnen Artikel

Es ist recht einfach möglich unsere einzelnen Artikel (also ion-item Elemente) zu verlinken. Wenn ihr euch auch an den vorgegebenen Aufbau gehalten habt solltet ihr bereits noch das href in euren ion-items stehen haben. Daraus machen wir aber nun ein ng-href. Zuvor müssen wir aber noch kurz unsere app.js erweitern. Wir brauchen noch einen state und ein template für einzelne Artikel.
Jedes Mal, wenn die URL /beste/5 mit einer Id (beispielsweise 5) aufgerufen wird, wollen wir den jeweiligen Artikel anzeigen.

.state('app.article', {
      url: '/beste/:articleId',
      views: {
        'menuContent': {
          templateUrl: 'templates/besteartikel.html',
          controller: 'BesteCtrl'
        }
      }
    })

Die besteartikel.html dient uns dabei als Template für den jeweiligen Artikel und sieht so aus:

<ion-view view-title="Beste Zeitung">
  <ion-content>
    <h1>Artikel Überschrift</h1>
  </ion-content>
</ion-view>

Wollen wir also nun unsere Überschriften (und auch die dazugehörigen Bildern) verlinken, so müssen wir nur die jeweilige URL mit unserer id in dem dazugehörigen Objekt aufrufen.

ng-href="#/app/beste/{{article.id}}"

Komplettiert sieht unsere beste.html dann so aus:

<ion-view  view-title="Beste Zeitung" ng-init="getArticles()">
  <ion-content>
      <ion-item ng-repeat="article in articles" ng-href="#/app/beste/{{article.id}}" class="articleContainer">
        <h1 class="articleH1">{{article.title}}</h1>
        <img ng-src="{{article.image}}" class="articleImg">
      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>

Wenn ihr nun einen Artikel anklickt sollte sich eine neue Seite öffnen, wenn auch noch nicht wirklich befüllt. Dazu kommen wir aber noch.
Der ein oder andere wird eventuell bemerken, dass unser Vorhaben doch etwas langsam von statten geht. Soll heißen, dass es doch die ein oder andere Sekunde dauert, bis unsere Artikel geladen werden.

Ich habe versucht das ganze ein wenig schneller zu machen und optisch ein wenig zu optimieren. Im nächsten Artikel wird es dann darum gehen, wie ich das versuche umzusetzen und wie ich eine ProgressBar in meine App einfüge um anzuzeigen, dass die Artikel noch geladen werden.

Hinterlass doch ein Like :)Share on FacebookTweet about this on TwitterShare on Google+

2 responses to “Cordova App mit WP REST API – Anzeige von Bildern und Öffnen von Artikeln”

  1. […] bereits im letzten Beitrag zum Thema Titelbilder anzeigen und einzelne Artikel öffnen angesprochen gibt/gab es ein Problem mit der Performance. Das Laden der gesamten Artikel und dem […]

  2. […] Wir dürfen aber unser _embed nicht vergessen, wodurch wir ja unsere Featured Images erhalten. Wir müssen also per_page=50&_embed verwenden, wenn wir nicht nur 50 Beiträge mit Inhalt sondern auch mit den Bildern haben möchten. Unsere URL sieht dann so aus: […]

Leave a Reply