single-page-applikationen.png
  • Mirka Santur
  • 10.03.2017
  • DE

Single Page Applikationen mit OT WSM

Single Page Applikationen und Open Text Web Site Management, geht das überhaupt? Dies war eine Fragestellung eines Proof of Concepts, den ich zuletzt durchgeführt habe. Die Antwort? Ja. Aber fangen wir ganz am Anfang an.

Was ist überhaupt eine Single Page Applikation?

Hier kann man Wikipedia gut zitieren: "Als Single-Page-Webanwendung [...] wird eine Webanwendung bezeichnet, die aus einem einzigen HTML-Dokument besteht und deren Inhalte dynamisch nachgeladen werden. ... Diese Webseite wird lediglich zur Laufzeit der Applikation dynamisch erweitert. ...", unter https://de.wikipedia.org/wiki/Single-Page-Webanwendung (abgerufen am 22.02.2017).

Eine Single Page Applikation baut sehr stark auf JavaScript auf und lädt alle Inhalte per AJAX nach. Trotzdem möchte man die Usability nicht einschränken und dem Nutzer ermöglichen, direkt auf bestimmte Seiten zuzugreifen und sich auch Bookmarks setzen zu können.

Um beiden Anforderungen gerecht zu werden, können AngularJS v1.2.13 und UI Router v0.2.8 genutzt werden. Diese zwei Frameworks bzw. Erweiterungen habe ich auch für den PoC genutzt.

Einzelnen Arbeitsschritte beim PoC

Klick-Dummy erstellen

Den Klick-Dummy habe ich für meine Zwecke sehr übersichtlich gehalten. Nach dem der Rahmen erstellt ist, kommt nur noch ein DIV in das HTML

 HTML 
<div class="container">
    <div ui-view></div>
</div>

der Rest wird über das JavaScript gelöst.

 JavaScript 
var app = angular.module("routing", ['ui.router']);

app.config(function ($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');

    $stateProvider
        .state('home', {
            url: '/home',
            templateUrl: 'partial/home.html'
        })
        .state('about', {
            url: '/about',
            templateUrl: 'partial/about.html'
        });
})

Wie man hier sieht, sind zwei Seiten definiert. Bei Klick auf den gewünschten Navigationspunkt

 HTML 
<a ui-sref="about">About</a>

wird die im Parameter templateUrl definierte Seite in das DIV geladen.

Einbauen ins CMS

Die erste Schwierigkeit im Zusammenhang mit dem CMS besteht darin, dass das CMS darauf ausgelegt ist, komplette Webseiten darzustellen. Hier muss man von diesem Konzept abweichen und die Masterpage nur noch mit dem Inhalt bestücken, welcher in dem DIV dargestellt wird. Zusätzlich dazu benötigt man dann eine Rahmen-Seite, die das HTML-Body-Tag zu Verfügung stellt.

Bei den Masterpage Instanzen kann man wie gewohnt mit dem Navigation Manager das Projekt strukturieren. Somit bleiben noch drei Herausforderungen die gelöst werden müssen:

  • Erstellung der JavaScript-Datei
  • Seiten-Vorschau mit Navigationsmöglichkeiten
  • Bearbeitung der Seiten mit SmartEdit

 

Erstellung der JavaScript-Datei

Als erstes ist zu beachten, dass der Name jedes Navigationspunktes eineindeutig sein muss. Für den PoC habe ich es mir an der Stelle einfach gemacht und habe mich entschieden, hier die GUID zu verwenden. Da das JavaScript im Grunde die Navigation wiederspiegelt, fiel die Entscheidung sehr schnell, diese komplett über RenderTags schreiben zu lassen.

 JavaScript 
var app = angular.module("routing", ['ui.router']);

app.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('/<%!! Context:Pages.GetPage(Guid:A7DC6CC5060A4CC9A1F8B404BCF76D42).Id !!%>');
    
    $stateProvider
<reddot:cms><navigation areaname="appRoutes" pageguid="Guid:A7DC6CC5060A4CC9A1F8B404BCF76D42" usehiddenindexes="Bool:True" /></reddot:cms>;

})

Hier ist nur zu beachten, dass die JavaScript-Datei selbst nicht in der Navigationsstruktur hängt und somit über den Parameter pageguid der Startpunkt der Navigation festgelegt werden muss.

 JavaScript 
.state('<%!! Context:CurrentIndex.Page.Id !!%>', {
    url: '/<%!! Context:CurrentIndex.Page.Id !!%>',
    templateUrl: '<%!! Context:CurrentIndex.GetUrl() !!%>'
})
<navigation:nextlevel>

 

Seiten-Vorschau mit Navigationsmöglichkeiten

Wenn man die einzelnen Seiten aufruft, bekommt man nur den Content angezeigt. Dies ist ja nicht gewünscht, und es sollte auch möglich sein in der Seiten-Vorschau den Auftritt komplett durchnavigieren zu können. Hierfür machen wir uns zu Nutze, dass mit UI Router mit der #-Notation ein direkter Sprung zu jeder beliebigen Seite möglich ist und bauen in die Masterpage folgenden Script-Tag ein.

 HTML 
<script type="text/javascript">
    window.location.href = "<%!! Context:Pages.GetPage(Guid:CA43D1900A2341C98F9C7EC10838D48D).GetUrl() !!%>#/<%!! Context:CurrentPage.Id !!%>";
</script>

Die hier aufgerufene Page ist die Instanz im Projekt mit dem HTML-Body. Damit hat der Aufruf der gewünschten Seite in dem vollständigen Rahmen einwandfrei funktioniert. Bei der Navigation gab es noch eine Schwierigkeit, die URLs im CMS sind mit sehr vielen Übergabeparameter versehen.

 URL 
http://[SERVERNAME]/cms/WebClient/PreviewHandler.ashx?Action=RedDot&Mode=0&PageGuid=A7DC6CC5060A4CC9A1F8B404BCF76D42&LinkFromGuid=039DE11E4FF44590A21A1D9BE242793C&WithCache=1&Type=page&Isolated=0&PageLocked=0&Rights1=-33673217&DummyTime=1487948828027

Das & verträgt sich nicht mit dem templateUrl-Aufruf im JavaScript. Deshalb ist hier noch eine Erweiterung des Navigation-Templates erforderlich:

 JavaScript 
templateUrl: (function(){ return '<%!! Context:CurrentIndex.GetUrl() !!%>'.replace(/&amp;/g,"&");})()

 

Bearbeitung der Seiten mit SmartEdit

Hier verfolgen wir bei all unseren Projekten den Ansatz, dass die Redakteure sich komplett auf ihre Arbeit konzentrieren sollen und Inhalte, die nicht bearbeitet werden können, weggeblendet werden. Was ja in diesem Fall die Navigation und der HTML-Body wären. Navigiert wird über den Strukturbereich im SmartEdit. Hier ist jede Seite durch den Redakteur erreichbar und er muss sich nicht im Bearbeitungsbereich durch die gesamte Webseite durchklicken, um zu der einen Seite zu gelangen, die er bearbeiten möchte.

Trotzdem sollte die Seite im WYSIWYG-Modus dargestellt werden. Dafür wird im SmartEdit-Modus in jede Seite ein HTML-Body eingefügt und auch das StyleSheet geladen.

 

Social Media