-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeed.xml
More file actions
295 lines (281 loc) · 66.6 KB
/
feed.xml
File metadata and controls
295 lines (281 loc) · 66.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>A Generated Static Site</title>
<atom:link href="http://localhost:8080/feed.xml" rel="self" type="application/rss+xml"></atom:link>
<link>http://localhost:8080</link>
<description>This site is built with Wintersmith, a Node.js based static site generator</description>
<pubDate>Fri, 15 Jan 2016 01:00:00 +0100</pubDate>
<generator>Wintersmith - https://github.com/jnordberg/wintersmith</generator>
<language>en</language>
<item>
<title>Drupal</title>
<link>http://localhost:8080/articles/drupal/</link>
<pubDate>Fri, 15 Jan 2016 01:00:00 +0100</pubDate>
<guid isPermaLink="true">http://localhost:8080/articles/drupal/</guid>
<author></author>
<description><p><img src='https://www.drupal.org/sites/all/themes/drupalorg_themes/blueprint/images/logo-d8.svg' height='350px' /></p>
<p>Dieser Beitrag behandelt den Funktionsumfang des Content Management Systems und -Frameworks Drupal. Speziell werden auch die Neuerungen in Drupal 8, der jüngsten Version des modular aufgebauten Systems, betrachtet.</p>
<p><span class="more"></span></p>
<h4 id="-kollaborative-inhaltserstellung-sup-1-1-sup-">„Kollaborative Inhaltserstellung“ <sup><a href="#1">1</a></sup></h4>
<p>Neben den Basisfunktionalitäten, die ein zeitgemäßes Content-Management-Systemen bieten muss, setzt Drupal seinen Fokus vor allem auf die Erstellung von User-generated Content. Zu diesem Zweck werden verschiedene Tools bereit gestellt: Blog-Systeme, Foren, Kommentarfunktion – Drupal unterstützt den Aufbau von Communities, die gemeinsam an Inhalten arbeiten und stellt gut 1000 vorkonfigurierte Distributionen<sup><a href="#2">2</a></sup> bereit, die den Installationsprozess erleichtern. </p>
<h4 id="-daf-r-gibt-s-doch-ein-modul-sup-1-1-sup-">„Dafür gibt‘s doch ein Modul.“ <sup><a href="#1">1</a></sup></h4>
<p>Im Vergleich zu anderen Content-Management-Systemen basiert Drupal auf einer sehr schlanken Core Installation mit nur wenigen Basismodulen. Weitere Module können beliebig nachinstalliert werden, was dem Entwickler ein hohes Maß an Freiheit bietet. Ein Pluspunkt des modularen Aufbaus sind die zahlreichen Individualentwicklungen, die auf <a href="https://www.drupal.org">drupal.org</a> als Open Source Projekte bereit gestellt werden. Durch Drupals Frameworkansatz wird die einfache Entwicklung eigener Erweiterungen ermöglicht und gefördert.
Ein negativer Aspekt sind hingegen die großen Abhängigkeiten zwischen den Modulen, die ein Projekt schnell unübersichtlich machen können. Zudem sieht Drupals Strategie keine zwingende Kompatibilität zwischen Drupal-Versionen vor, was ein manuelles überprüfen und updaten aller Module bei einem Versionsupgrade notwendig macht.<sup><a href="#3">3</a></sup></p>
<p><img class='drupal' src='https://www.drupal.org/sites/all/themes/drupalorg_themes/blueprint/images/img-white-tools.png' height='280px'/></p>
<h4 id="dokumentation-support">Dokumentation &amp; Support</h4>
<p>Drupal ist gut und umfangreich dokumentiert und besitzt eine starke Online-Community, die Entwicklern beim Ein-/Umstieg auf Drupal zur Seite steht. Drupals Open-Source Gedanke spiegelt sich, neben den bereits erwähnten vielzählig entwickelten und zur Verfügung gestellten Modulen, in vielen Städten auch durch die Formierung von User-Groups und Stammtischen zum Erfahrungsaustausch und Know-How-Transfer wieder. Darüber hinaus gibt es aber auch Consultant-Unternehmen, die kommerziellen Support anbieten.<sup><a href="#1">1</a></sup></p>
<h4 id="-better-authoring-experience-sup-4-4-sup-">„Better authoring experience“ <sup><a href="#4">4</a></sup></h4>
<p>Für Redakteure und Blogger ist das Editieren bei Drupal besonders angenehm: Inhalte werden direkt im Frontend bearbeitet. Im Gegensatz zu anderen Content-Management-Systemen gelangt der Bearbeiter nach dem Login also nicht ins Backend des Systems, sondern erhält innerhalb des Frontends, die für seine Rolle vorgesehenen Editierfunktionen.
Der Administrator nutzt hier das fein granulierte Rollen- und Rechtemanagement, um je nach Einssatzzweck verschiedene Berechtigungen zu erteilen.<sup><a href="#1">1</a></sup> In Drupal 8 ist das Konfigurieren von Berechtigungen sogar per drag-and-drop möglich, indem Buttons einfach zum Editor hinzugefügt oder weggenommen werden.<sup><a href="#4">4</a></sup></p>
<h4 id="-in-drupal-8-accessibility-is-at-the-forefront-sup-5-5-sup-">„In Drupal 8, accessibility is at the forefront“ <sup><a href="#5">5</a></sup></h4>
<p>Bereits Drupals Version 7 war barriereärmer als andere Content-Management-Systeme und zeichnete sich durch gute Zugänglichkeit auf allen Ebenen (von den angezeigten Inhalten über den Bearbeitungseditor bis hin zu Administrationsoberflächen) aus.<sup><a href="#6">6</a></sup> Drupal 8 unterstützt nun weitere Accessibity Standards der WCAG 2.0<sup><a href="#7">7</a></sup> in allen Core Themes und Modulen und setzt damit auch ein Statement für bessere Zugänglichkeit im Web.<br>So sorgen WAI-ARIA<sup><a href="#8">8</a></sup> roles und attributes im Markup und der Form API für einen semantischen Seitenaufbau. Dieser bietet wichtige Zusatzinformationen, die dem normalen User nicht auffallen, für Nutzer von Screenreadern jedoch sehr wichtig sind. Auch die Umstellung des Markups auf semantische HTML5-Elemente kommt nicht nur den Entwicklern zu Gute, die anstatt einer Wüste aus verschachtelten div-Elementen nun lesbaren Code vorfinden, sondern unterstützt ebenfalls Screenreader beim Übersetzten der Seitenstruktur für Sehbehinderte.<sup><a href="#9">9</a></sup> Weitere Verbesserungen hinsichtilich der Barrierefreiheit sind eher subtil: Farb- und Helligkeitskontraste wurden verbessert, Schriftgrößen an die Richtlinien der WCAG 2.0 angepasst und das alt-Attribut für alternative Bildtexte standardmäßig zum Pflichtfeld gemacht. <sup><a href="#10">10</a></sup></p>
<h4 id="webservices">Webservices</h4>
<p>Seit im November 2015 die Version 8.0.0 von Drupal released wurde, ist die einfache Veröffentlichung von Inhalte über eine REST-Schnittstelle möglich. Dafür wurden die vier Module RESTful Web Services, Serialization, Hypertext Application Language und HTTP Basic Authentication in die Core-Installation mit aufgenommen. <sup><a href="#11">11</a></sup>
Über einen Webservice können externe Anwendungen mit der Drupalseite interagieren und beispielsweise Daten auslesen, bearbeiten oder hinzufügen. Mögliche Anwendungsfälle sind automatisierte Posts in sozialen Netzwerken oder das Senden von E-Mail Kampagnen anhand von in Drupal erstellten Inhalten. Auch das Zusammenspiel mit dem Modul Views bietet neue Möglichkeiten: erstellte Views Listen können ebenfalls als Webservice bereit gestellt werden. <sup><a href="#11">11</a></sup></p>
<h4 id="taxonomie-und-freiheit">Taxonomie und Freiheit</h4>
<p>Ein wichtiger Aspekt in punkto Flexibilität ist das Definieren von eignen Inhaltstypen. “[Diese] können selbst nach Belieben definiert werden, wobei die Felder für die Eingabemasken einfach ausgewählt werden.” <sup><a href="#1">1</a></sup>
Zwischen Inhaltstypen können Referenzen konfiguriert werden, die der Taxonomie <sup><a href="#12">12</a></sup> der Inhalte zugrunde liegen und einfache Filter- und Suchfunktionen für den Benutzer ermöglichen.
Unter dem Motto “Because there’s more in core” <sup><a href="#13">13</a></sup> hat Drupal das viel genutzte Modul Views in die Basis-Installation geholt. Dieses ermöglicht das einfache Konfigurieren von DB-Abfragen und referenzieren von Inhalten innerhalb anderer Inhaltstypen <sup><a href="#14">14</a></sup>. Drupal 8 baut sogar die Adminoberflächen auf Views auf, was für den Entwickler ein weiteres Plus an Flexibilität beim Konfigurieren der Bearbeitungsfunktionen bedeutet.</p>
<h4 id="mehr-l-nder-als-die-internationale-staatengemeinschaft-sup-1-1-sup-">Mehr Länder als die internationale Staatengemeinschaft <sup><a href="#1">1</a></sup></h4>
<p>Unter diesem Motto hat Drupal Internationalität zu einer weiteren seiner Stärken gemacht. da Drupal bekanntlich nicht zwischen Front- und Backend unterscheidet, ist mit der Installation einer von 181 Sprachen sofort auch die Übersetzung der Redaktionsoberflächen gewährleistet. “So kann z. B. jede/r in einem internationalen Redaktionsteam parallel in der eigenen Muttersprache arbeiten.” <sup><a href="#15">15</a></sup>
Der größte Benefit liegt aber wohl beim Anbieten der Inhalte für den Seitennutzer: “Every single content entity is translatable. Right out of the box.” <sup><a href="#13">13</a></sup> Dazu zählen alle Komponenten der Taxonomie-Funktion, Kommentare und Konfigurationseinstellungen. Zusätzlich bietet Drupal 8 eine eingebaute Transliterationsfunktion, die Texte buchstabengetreu in andere Alphabete umwandelt und einfach anzupassendes Styling für Schriften, deren Lesefluß von rechts nach link gerichtet ist. <sup><a href="#15">15</a></sup></p>
<p><img class='drupal' src='https://www.drupal.org/sites/all/themes/drupalorg_themes/blueprint/images/img-ltgray-multilingual.png' height='280px'/></p>
<h4 id="deployment">Deployment</h4>
<p>Mit der Entwicklung von Drupal 8 wurde auch der Deployment-Prozess und somit das Übertragen von Inhalten zwischen den verschiedenen Umgebungen einer Drupalsite (Entwicklung, Testing, Live-Betrieb) verbessert. Eine überarbeitete Version des Moduls Deploys, die weitere Contributed Modules<sup><a href="#16">16</a></sup> und drei Drupal Kernmodule<sup><a href="#17">17</a></sup> miteinbezieht sind die Grundlage der Content Staging Suite für Drupal 8.<br>Zusammengefasst stellen die verwendeten Module folgende Infrastruktur zur Synchronisation der Entwicklungsumgebungen zur Verfügung: Eine Restful bzw. Relaxed JSON API<sup><a href="#18">18</a></sup>stellt Endpunkte für Entitäten, File Attachments und administrative Tasks wie den Vergleich von Versionen zur Verfügung. Die normale REST API wird dabei um ein besseres Handling von UUID Referenzen zur Synchronisation von Konfigurationsänderungen zwischen den Instanzen einer Drupalsite ergänzt.<sup><a href="#19">19</a></sup> Contentänderungen werden versioniert und Änderungen in einem Git ähnlichen Revision Tree gesammelt, um Mergekonflikte und Abhängigkeiten leicht erkennen zu können.<sup><a href="#20">20</a></sup><br>Zur Replikation von Datenbanken wurde für Drupal 8 das Modul Replication entwickelt, welches auf dem replicatio.io Protokoll basiert, das sich wiederum am API Interface der dokumentenorientieren NoSQL Datenbank CouchDB orientiert. Das Modul ermöglicht die bidirektionale Synchronisierung von Dokumenten über HTTP. Neben der Replikation von Datenbanken zwischen den Instanzen einer Drupalsite schaffen die Module die Möglichkeit Datenbanken zwischen Drupal 8 und anderen Systemen zu replizieren und “Offline First” Anwendungen zu erstellen, bei denen eine durch Drupal 8 verkörperte Remote Datenbank mit einer lokalen browserbasierten Datenbank wie <a href="http://pouchdb.com/">PouchDB</a> oder dem “noBackend” Web Application Framework <a href="http://hood.ie/">Hood.ie</a> synchronisiert wird.<sup><a href="#21">21</a></sup>
Der Deployment Workflow kann nach Belieben über das Drupal User Interface, das Kommandozeilen Tool <a href="http://www.drush.org/en/master/">Drush</a> oder auch dateienbasiert ablaufen. <sup><a href="#1">1</a></sup> </p>
<h4 id="-proudly-found-elsewhere-sup-13-13-sup-">“Proudly found elsewhere” <sup><a href="#13">13</a></sup></h4>
<p>Die im November 2015 veröffentlichte und bereits 2011 begonnene Entwicklung der Drupal Version 8.0.0 baut auf Symfony-2<sup><a href="#22">22</a></sup> als Technologiebasis auf.<sup><a href="#23">23</a></sup> Außerdem wurde die Architektur des Systems von Grund auf überarbeitet und ein objektorientierter Ansatz bei der Neuentwicklung verfolgt<sup><a href="#24">24</a></sup>. Natürlich führt Drupal aber seinen Open Source Gedanken fort und der Einsatz des Conent Management Systems bleibt kostenfrei. Zudem verwendet Drupal neben Symfony2 noch weitere Open Source Bibliotheken und sagt über seine jüngste Veröffentlichung: “It depends on dozens of external libraries” <sup><a href="#25">25</a></sup>. Aus dem Open Source Web Application Framework Symfony sind zehn Komponenten im Drupal Core implementiert: </p>
<p>“Die ClassLoader Komponente ermöglicht das automatische Laden von Klassen ohne vorheriges require()” <sup><a href="#26">26</a></sup> und trägt durch das Caching von Projektklassen zur besseren Performance bei. HttpFoundation und HttpKernel organisieren den Request Flow, die HttpFoundation stellt Request und Response Objekte nach Http Standard bereit und der HttpKernel managt das Routing, Rendering, Triggern von Events und fungiert als Firewall. Er “bietet [also] einen eventbasierten, strukturierten Ablaufprozess von einem Request zu einer Response, indem es zu eingehenden Anfragen den passenden Controller auflöst, Argumente übergibt und Exceptions handhabt”<sup><a href="#26">26</a></sup>. DependencyInjection beschreibt – allgemein gehalten – den Aufbau von Objekten und ihren Abhängigkeiten, die durch Konstruktoren, Methoden oder über Eigenschaften zustande kommen.<sup><a href="http://localhost:8080/articles/drupal/27#">27</a></sup> Symfony’s DepedencyInjection Komponente stellt “das gängige Inversion of Control Paradigma zur Verfügung, mit dem man Abhängigkeiten entkoppeln kann. Möglich sind hier die Ausprägungen Constructor-, Field- und Setter-Injection” <sup><a href="#27">27</a></sup>. </p>
<p><img class='drupal' src='http://expressmagazine.net/sites/default/files/imagesArticle/symfony-love.png' style="background-image:url('//www.drupal.org/sites/all/themes/drupalorg_themes/blueprint/images/bg-ltblue-city.jpg')" height='270px'/></p>
<p>Ebenfalls zur Drupal 8 Core Installation gehört der auf GitHub entwickelte Dependency Manager Composer. Mit seiner Hilfe können Dependencies auf lokaler, anwendungsorientierter Basis einfach installiert und aktuell gehalten werden. Composer für PHP-Anwendungen kann mit dem Paketmanager npm für Node.js und bundler für Ruby verglichen werden. Drupal begründet die Implementierung in der Kerninstallation wie folgt: “Composer makes dependency management simpler […] That means speed, that means efficiency, and that means you can more dependably use other people’s libraries to improve your work.” <sup><a href="#28">28</a></sup> </p>
<p>Da einige der genannten Komponenten auch zum Synfony Full Stack gehören <sup><a href="#29">29</a></sup> sind Drupal und Synfony Projekte zukünftig besser miteinander kombinierbar. Und auch im Frontend wird an Stelle der zuvor verwendeten PHPTemplates Twig, die Standard Template Engine von Symfony, eingesetzt. Die tagbasierte Template Sprache ist für weniger PHPaffine Frontentdeveloper besser lesbar<sup><a href="#30">30</a></sup>,kompiliert schnnell, ermöglicht ein einfaches Debugging und beinhaltet übersichtliche Fehlmeldungen. Unabhängig von Twig wurde Drupals HTML-Markup “rigoros aufgeräumt” <sup><a href="#31">31</a></sup>, um eine klare HTML-Struktur ohne endlos verschachtelten div-Elementen zu schaffen.
In Bezug auf die mobile Webnutzung bietet Drupal 8 alle mitgelieferten Themes in responsiver Gestaltung an und auch die Administrationsoberflächen passen sich dem Endgerät des Bearbeiters an. Zusätzlich kommt das ressourcensparende HTML5 Element <picture> zum Einsatz, welches die Definition verschiedener Bilder in Abhängigkeit von der Viewportbreite, Auflösung oder den unterstützten Bildformaten des Browsers erlaubt. <sup><a href="#32">32</a></sup>. </p>
<p>Zu guter Letzt kommt in Drupal 8 als Datenbank-Server-Software nach wie vor wahlweise MySQL(MariaDB), PostgreSQL oder SQLite zum Einsatz. Mit Hilfe von Modulen können auch Oralce und MSSQLServer angebunden werden oder serverseitig ein Apache Solr Index aufgebaut werden, der die Suchfunktionen innerhalb der Site verbessert.</p>
<h4 id="anwendungsf-lle">Anwendungsfälle</h4>
<p>Den häufigsten Einsatz findet Drupal für “hochdynamische Plattformen, die auf User-generated Content ausgerichtet sind oder Websites von Regierungen und Verwaltungen, die den Schritt in Richtung Bürgerbeteiligung machen, ferner Medienhäuser, Nichtregierungsorganisationen oder Universitäten.” <sup><a href="#1">1</a></sup>
Beispiele hierfür sind die <a href="https://www.whitehouse.gov/">Webpräsenz des Weißen Hauses</a><sup><a href="#33">33</a></sup>, die <a href="http://www.zeit.de/community/index">Communityseite</a> der Wochenzeitung Die Zeit <sup><a href="#34">34</a></sup> und auch das Forum und Ticketsystem von drupal.org, das mit eigenen Bordmitteln betrieben wird <sup><a href="#1">1</a></sup>. </p>
<hr>
<div class='footnotes'>
<a id='1'>1</a> vgl. <a href="http://www.cms-garden.org/de/cms/drupal">http://www.cms-garden.org/de/cms/drupal</a><br> <a id='2'>2</a> “Distributions are full copies of Drupal that include Drupal Core, along with additional software such as themes, modules, libraries, and installation profiles.” (vgl. <a href="https://www.drupal.org/documentation/build/distributions8">https://www.drupal.org/documentation/build/distributions8</a>)<br> <a id='3'>3</a> vgl. <a href="https://www.aoe.com/de/loesungen/web-content-management/typo3-vs-drupal.html">https://www.aoe.com/de/loesungen/web-content-management/typo3-vs-drupal.html</a><br> <a id='4'>4</a> vgl. <a href="https://www.drupal.org/8/usability">https://www.drupal.org/8/usability</a><br> <a id='5'>5</a> vgl. <a href="https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-wai-aria">https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-wai-aria</a><br> <a id='6'>6</a> vgl. <a href="https://opensource.com/business/14/5/new-release-drupal-8-accessibility-advantage">https://opensource.com/business/14/5/new-release-drupal-8-accessibility-advantage</a><br> <a id='7'>7</a> Web Content Accessibility Guidelines<br> <a id='8'>8</a> “WAI-ARIA, the Accessible Rich Internet Applications Suite, defines a way to make Web content and Web applications more accessible to people with disabilities. It especially helps with dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies.” (vgl. <a href="https://www.w3.org/WAI/intro/aria">https://www.w3.org/WAI/intro/aria</a>)<br> <a id='9'>9</a> vgl. <a href="https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-wai-aria">https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-wai-aria</a>, <a href="http://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-html5-improved-semantics">http://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-html5-improved-semantics</a><br> <a id='10'>10</a> vgl. <a href="https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-colour-contrast-low-vision">https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-colour-contrast-low-vision</a>, <a href="https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-alt-tags-defaults">https://openconcept.ca/blog/mike/drupal-8%E2%80%99s-accessibility-advantage-alt-tags-defaults</a><br> <a id='11'>11</a> vgl <a href="https://www.drupal.org/8/platform">https://www.drupal.org/8/platform</a><br> <a id='12'>12</a> Verschlagwortung/Indexierung, “In Bezug auf Dokumente bzw. Inhalte wird der Begriff Taxonomie für ein Klassifikationssystem, eine Systematik oder den Vorgang des Klassifizierens verwendet. Klassifizierungen können beispielsweise durch die Erfassung von Metadaten und/oder die Verwendung einer Ablagestruktur vorgenommen werden.” (vgl. <a href="https://de.wikipedia.org/wiki/Taxonomie#Informationsverarbeitung">https://de.wikipedia.org/wiki/Taxonomie#Informationsverarbeitung</a>)<br> <a id='13'>13</a> vgl. <a href="https://www.drupal.org/8/">https://www.drupal.org/8/</a><br> <a id='14'>14</a> z.B.: Anzeige eines Autorenkurzprofils innerhalb einer von ihm veröffentlichten Publikation. (vlg. <a href="http://www.cms-garden.org/de/cms/drupal">http://www.cms-garden.org/de/cms/drupal</a>)<br> <a id='15'>15</a> vgl. <a href="https://www.drupal.org/8/multilingual">https://www.drupal.org/8/multilingual</a><br> <a id='16'>16</a> Contributed Modules sind Module, die von Developern der Drupal Community entwickelt und für andere zur Verfügung gestellt werden. Die für das Content Staging in Drupal 8 genutzten sind Relaxed Web Services, Multiversion und Key-value Extensions.<br> <a id='17'>17</a> Entity API, Serialization und Restful Web Services<br> <a id='18'>18</a> vgl. <a href="https://www.drupal.org/project/relaxed">https://www.drupal.org/project/relaxed</a><br> <a id='19'>19</a> vgl. <a href="https://www.drupal.org/project/deploy#d8">https://www.drupal.org/project/deploy#d8</a><br> <a id='20'>20</a> vgl. <a href="https://ffwagency.com/blog/a-content-staging-solution-for-drupal-8-and-more">https://ffwagency.com/blog/a-content-staging-solution-for-drupal-8-and-more</a><br> <a id='21'>21</a> vgl. <a href="https://www.drupal.org/project/replication">https://www.drupal.org/project/replication</a><br> <a id='22'>22</a> Symfony folgt der Model-View-Controller Architektur und entstand als in PHP geschriebenes Gegenstück zum Ruby Framework Ruby on Rails, das ebenfalls auf dem MVC-Pattern beruht.<br> <a id='23'>23</a> vgl.<a href="https://www.drupal.org/core/dev-cycle#d8-glance">https://www.drupal.org/core/dev-cycle#d8-glance</a><br> <a id='24'>24</a> bisher: Aspektorientierte Programmierung mit objektorientierten Ansätzen<br> <a id='25'>25</a> vgl. <a href="https://www.drupal.org/8/deployment">https://www.drupal.org/8/deployment</a><br> <a id='26'>26</a> vgl. <a href="http://www.brightsolutions.de/blog/symfony-2-ein-kurzer-%C3%BCberblick-mit-blick-auf-drupal-8">http://www.brightsolutions.de/blog/symfony-2-ein-kurzer-%C3%BCberblick-mit-blick-auf-drupal-8</a><br> <a id='27'>27</a> vgl. <a href="http://fabien.potencier.org/what-is-dependency-injection.html">http://fabien.potencier.org/what-is-dependency-injection.html</a><br> <a id='28'>28</a> vgl. <a href="https://www.drupal.org/8/standards">https://www.drupal.org/8/standards</a><br> <a id='29'>29</a> vgl. <a href="http://symfony.com/blog/symfony2-meets-drupal-8">http://symfony.com/blog/symfony2-meets-drupal-8</a><br> <a id='30'>30</a> “Twig uses tag-based syntax that’s easier to learn” (vgl. <a href="https://www.drupal.org/8/standards">https://www.drupal.org/8/standards</a>)<br> <a id='31'>31</a> <a href="http://www.heise.de/newsticker/meldung/Drupal-8-biegt-auf-die-Zielgerade-ein-2732265.html">http://www.heise.de/newsticker/meldung/Drupal-8-biegt-auf-die-Zielgerade-ein-2732265.html</a><br> <a id='32'>32</a> vgl. <a href="https://www.drupal.org/documentation/modules/responsive_image">https://www.drupal.org/documentation/modules/responsive_image</a><br> <a id='33'>16</a> vgl. <a href="https://www.whitehouse.gov/developers">https://www.whitehouse.gov/developers</a><br> <a id='34'>17</a> vgl. <a href="http://community.zeit.de/page/community-technik-drupal">http://community.zeit.de/page/community-technik-drupal</a><br>
Bilder: <a href="https://www.drupal.org/8/">https://www.drupal.org/8/</a>, <a href="http://expressmagazine.net/sites/default/files/imagesArticle/symfony-love.png">http://expressmagazine.net/sites/default/files/imagesArticle/symfony-love.png</a><br></div>
</description>
</item>
<item>
<title>D3 Data-Driven Documents</title>
<link>http://localhost:8080/articles/d3/</link>
<pubDate>Mon, 11 Jan 2016 01:00:00 +0100</pubDate>
<guid isPermaLink="true">http://localhost:8080/articles/d3/</guid>
<author></author>
<description><div class="row">
<div class="col-sm-6" id="task01"><svg viewBox="0 0 800 600" id="chart-aad68792-9265-4db3-af5c-cd526f0f3673">
<g transform=""/>
<g class="x axis" transform="translate(55, 450)"><g class="tick" style="opacity: 1;" transform="translate(44,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">Italian</text></g><g class="tick" style="opacity: 1;" transform="translate(117,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">British</text></g><g class="tick" style="opacity: 1;" transform="translate(190,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">Belgian</text></g><g class="tick" style="opacity: 1;" transform="translate(263,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">American</text></g><g class="tick" style="opacity: 1;" transform="translate(336,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">German</text></g><g class="tick" style="opacity: 1;" transform="translate(409,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">Dutch</text></g><g class="tick" style="opacity: 1;" transform="translate(482,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">French</text></g><g class="tick" style="opacity: 1;" transform="translate(555,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">Spanish</text></g><g class="tick" style="opacity: 1;" transform="translate(628,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">New Zealander</text></g><g class="tick" style="opacity: 1;" transform="translate(701,0)"><line y2="6" x2="0"/><text dy=".5em" style="text-anchor: end;" y="9" x="0" dx="-.5em" transform="rotate(-45)">Swedish</text></g><path class="domain" d="M-4,6V0H745V4"/></g><g class="y axis" transform="translate(55, 0)"><g class="tick" style="opacity: 1;" transform="translate(0,450)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">0</text></g><g class="tick" style="opacity: 1;" transform="translate(0,400)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">1</text></g><g class="tick" style="opacity: 1;" transform="translate(0,350)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">2</text></g><g class="tick" style="opacity: 1;" transform="translate(0,300.00000000000006)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">3</text></g><g class="tick" style="opacity: 1;" transform="translate(0,250)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">4</text></g><g class="tick" style="opacity: 1;" transform="translate(0,200)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">5</text></g><g class="tick" style="opacity: 1;" transform="translate(0,150.00000000000003)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">6</text></g><g class="tick" style="opacity: 1;" transform="translate(0,100)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">7</text></g><g class="tick" style="opacity: 1;" transform="translate(0,50.00000000000002)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">8</text></g><g class="tick" style="opacity: 1;" transform="translate(0,8)"><line x2="-6" y2="0"/><text dy=".32em" style="text-anchor: end;" x="-9" y="0">9</text></g><path class="domain" d="M-3,0H0V450H-4"/><text transform="rotate(-90)" y="6" dy="0.71em" style="text-anchor: end;">Count</text></g><rect class="bar" x="66" width="66" y="200" height="250"/><rect class="bar" x="139" width="66" y="200" height="250"/><rect class="bar" x="212" width="66" y="400" height="50"/><rect class="bar" x="285" width="66" y="0" height="450"/><rect class="bar" x="358" width="66" y="350" height="100"/><rect class="bar" x="431" width="66" y="400" height="50"/><rect class="bar" x="504" width="66" y="300.00000000000006" height="149.99999999999994"/><rect class="bar" x="577" width="66" y="350" height="100"/><rect class="bar" x="650" width="66" y="400" height="50"/><rect class="bar" x="723" width="66" y="400" height="50"/></svg>
<table class="table">
<thead>
<tr><th class="text-left">Nationality</th>
<th class="text-center">Count</th><br> </tr></thead>
<tbody>
<tr>
<td class="text-left">Italian</td>
<td class="text-center">5</td>
</tr>
<tr>
<td class="text-left">British</td>
<td class="text-center">5</td>
</tr>
<tr>
<td class="text-left">Belgian</td>
<td class="text-center">1</td>
</tr>
<tr>
<td class="text-left">American</td>
<td class="text-center">9</td>
</tr>
<tr>
<td class="text-left">German</td>
<td class="text-center">2</td>
</tr>
<tr>
<td class="text-left">Dutch</td>
<td class="text-center">1</td>
</tr>
<tr>
<td class="text-left">French</td>
<td class="text-center">3</td>
</tr>
<tr>
<td class="text-left">Spanish</td>
<td class="text-center">2</td>
</tr>
<tr>
<td class="text-left">New Zealander</td>
<td class="text-center">1</td>
</tr>
<tr>
<td class="text-left">Swedish</td>
<td class="text-center">1</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>In diesem Beitrag wird die Erstellung eines Barcharts zu einem Datenset aus der <em>experimental Motor Racing Developer API</em> von <a href="http://ergast.com/mrd/">ergast.com</a> erläutert. Die Visualisierung wurde innerhalb eines Node.js Projektes mit Ecmascript 6 und Hilfe der der Javascript Bibliothek D3 erstellt. (Der generierte SVG-Code wurde in diesen Artikel kopiert) </p>
<p><span class="more"></span></p>
<h4 id="data-driven-documents">Data-Driven Documents</h4>
<p>“D3 allows you to bind arbitrary data to a Document Object Model (DOM), and then apply data-driven transformations to the document.”<sup><a href="#3">3</a></sup> Dieser Satz fasst die Grundfunktionalität der Open-Source-Bibliothek D3 zusammen, deren drei D’s dementsprechend für “Data-Dricen Documents” stehen. Seit 2011 wird sie von Mike Bostock auf <a href="https://github.com/mbostock/d3">Github</a> veröffentlicht und kontinuierlich erweitert.<sup><a href="#1">1</a></sup> Mit der Datenvisualisierungsbibliothek können DOM-Elemente auf der Grundlage von Datensätzen manipuliert und animiert werden und auch interaktive Funktionen lassen sich realisieren.
Die Library nutzt die aktuellen Webstandards CSS3, HTML5 und SVG und bietet maximale Flexibilität beim Erstellen von Visualisierungen. Die hohe Performance in der Verarbeitung großer Datenmengen und die Kompatibilität zu unterschiedlichsten Dateiformaten<sup><a href="#4">4</a></sup> zählen zu den großen Pluspunkten der Bibliothek.<sup><a href="#1">1</a></sup> Der funktionale Aufbau erleichtert das Erstellen von Plugins, die wiederverwendt werden können. Eine Liste von freien Plugins stellt Mike Bostock ebenfalls auf <a href="https://github.com/mbostock/d3/wiki/Plugins">GitHub</a> zur Verfügung.
D3 bietet neben den klassischen Visualisierungsarten wie Balken- oder Kuchendiagrammen die Möglichkeit auch komplexere Darstellungen wie Streamgraphen<sup><a href="#5">5</a></sup>, Chords<sup><a href="#6">6</a></sup> und Choropleths<sup><a href="#7">7</a></sup> oder eigene kreative Lösungen zu realisieren. </p>
<h4 id="-hnlichkeit-zu-jquery">Ähnlichkeit zu jQuery</h4>
<p>Neben Funktionen zur Verarbeitung von Daten stellt D3 wie schon erwähnt Funktionen zur Manipulation von DOM-Elementen und zur Erstellung von Animationen bereit. Frontendentwicklern, die bereits Erfahrung mit der Javascript-Library jQuery haben, kommt diese Ähnlichkeit zu Gute. Nicht nur die Begrifflichkeiten<sup><a href="#8">8</a></sup> und Funktionen zur DOM-Manipulation sind ableitbar, sondern auch Chaining, also die Verkettung von Funktionsaufrufen, funktioniert bei D3 analog. Auch die bereits angesprochene Erweiterbarkeit durch Plugins, ist von jQuery bekannt. <sup><a href="#3">3</a></sup>
Dennoch ist “der Zeitaufwand für die Einarbeitung […] nicht zu unterschätzen”<sup><a href="#1">1</a></sup>, da D3 ein mächtiges Werkzeug ist, dessen Potenzial bis zu dynamischen Echtzeit Visualisierungen reicht. Eine Dokumentation der Funktionen findet sich in der <a href="https://github.com/mbostock/d3/wiki/API-Reference">API-Referenz von D3</a> . </p>
<h4 id="styling">Styling</h4>
<p>Anderst als pixelbasierte Grafiken sind SVGs als Skalierbare Vektor Grafken mit CSS stylebar.
Properties wie <em>shape-rendering</em> für SVG-Elemente sind teilweise recht spezifisch und müssen anfangs gegebenenfalls beim <a href="https://www.w3.org/TR/SVG/styling.html">W3C</a> nachgeschlagen werden. <sup><a href="#2">2</a></sup></p>
<h4 id="anzahl-der-fahrer-pro-nation">Anzahl der Fahrer pro Nation</h4>
<p>Im Markup Template wird ein Div-Container bereitgestellt, in den der SVG-Code gerendert wird.
Die ID des Containers wird zusammen mit den darzustellenden Daten<sup><a href="#9">9</a></sup> an das D3-Skript übergeben. In diesem werden vor der Generierung des Balkendiagramms die Dimensionen der Visualisierung und ihre Randabstände bestimmt. Für die Darstellung der Achsenlabels wird nach links und nach unten mehr Platz benötigt und in <em>leftPadding</em> und <em>bottomPadding</em> berücksichtigt. Zusätzlich wird mit Hilfe des npm-Packages <em>uuid</em> ein Universal Unique Identifier generiert, der als Selektor dem SVG-Element zugeordnet werden soll. In einer verteilten Anwendung mit vielen ggf. dynamischen SVG-Visualisierungen würde eine solche global eindeutige ID die Zuordnung erleichterten und dabei helfen Konflikte (z.B. das Überschreiben/Aktualisieren eines falschen SVGs) zu vermeiden.<br>Einem vordefinierten SVG-Template<sup><a href="#10">10</a></sup> wird anschließend die bereits definierte Viewbox zugewiesen und die uuid zugewisen und dieses SVG-Element dem DOM (innerhalb des vorgesehenen Div-Contaienrs) hinzugefügt. Nun wird die Funktion aufgerufen, die die eigentliche Visualisierung zeichnet. Ihr werden sowohl die erzeugte uuid (id des SVG-Elements), die darzustellenden Daten, die festgelegte Breite und Höhe des SVGs (jeweils abzüglich der Randabstände) und die Randabstände als Parameter übergeben.</p>
<pre><code class="lang-javascript"><span class="keyword">export</span> <span class="keyword">default</span> <span class="function"><span class="keyword">function</span>(<span class="params">containerId, data</span>) </span>{
<span class="keyword">const</span> container = <span class="built_in">document</span>.getElementById(containerId)
<span class="keyword">const</span> width = <span class="number">800</span>
<span class="keyword">const</span> height = <span class="number">600</span>
<span class="keyword">const</span> margin = {
top: <span class="number">5</span>,
right: <span class="number">0</span>,
left: <span class="number">55</span>,
bottom: <span class="number">145</span>
}
<span class="keyword">const</span> viewBox = <span class="string">`0 0 <span class="subst">${width}</span> <span class="subst">${height}</span>`</span>
<span class="keyword">const</span> w = width - margin.left - margin.right
<span class="keyword">const</span> h = height - margin.top - margin.bottom
<span class="keyword">if</span> (!(data <span class="keyword">instanceof</span> <span class="built_in">Array</span>)) {
<span class="keyword">return</span>
}
<span class="keyword">const</span> id = <span class="string">'chart-'</span> + uuid.v4()
<span class="keyword">const</span> svg = tpl({
id,
viewBox
})
container.innerHTML = svg
draw(id, data, w, h, margin)
}
</code></pre>
<p>Die <em>draw</em> Funktion zeichnet zuerst das Kooradinatensystem, in welchem die Balken später dargestellt werden und verteilt die Werte aus dem übergebenem Datenarray an dessen Achsen.
Die Skala der x-Achse wird von D3 mit der Funktion <em>ordinal()</em> bereitgestellt und die <em>rangeRoundBands()</em> Methode berechnet eine gleichmäßige, horizontale Verteilung der einzelnen Balken über die der <em>draw</em> Funktion übergebenen Breite des SVGs. Mit der D3-Methode <em>domain()</em> können jetzt die zur verarbeitenden Werte, auf die X-Achse gemappt werden. Da insgesamt zehn verschiedene Nationen in den Fahrerdaten vertreten waren, werden zehn Marken entlang der X-Achse gesetzt auf denen die Balken des Diagramms wachsen. </p>
<p>Zur linearen Skalierung der y-Achse wird die Funktion <em>linear()</em> genutzt. Der Bereich für die Darstellung der Achse wird mit der übergebenen Höhe definiert. Zu beachten ist, dass D3 immer von y = 0 ausgeht und der Bereich daher genau anderst herum angegeben werden<sup><a href="#11">11</a></sup>. Ebenfalls mit <em>domain()</em> werden die im Datenarray übergebenen Werte zur Fahreranzahl innerhalb einer Nation als Skala für die Y-Achse verwendet. Der Bereich wird von 0 bis zum maximalen Wert im Datenset festgelegt. </p>
<pre><code class="lang-javascript"><span class="function"><span class="keyword">function</span> <span class="title">draw</span>(<span class="params">chartId, data, width, height, margin</span>) </span>{
<span class="keyword">const</span> svg = d3.select(<span class="string">`#<span class="subst">${chartId}</span>`</span>)
<span class="keyword">const</span> x = d3.scale.ordinal().rangeRoundBands([<span class="number">0</span>, width], <span class="number">0.1</span>)
<span class="keyword">const</span> y = d3.scale.linear().range([height, <span class="number">0</span>])
<span class="keyword">const</span> xAxis = d3.svg.axis()
.scale(x)
.orient(<span class="string">'bottom'</span>)
.ticks(<span class="number">10</span>)
<span class="keyword">const</span> yAxis = d3.svg.axis()
.scale(y)
.orient(<span class="string">'left'</span>)
.ticks(<span class="number">10</span>)
x.domain(data.map(<span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{
<span class="keyword">return</span> d.nationality
}))
y.domain([
<span class="number">0</span>, d3.max(data, <span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{
<span class="keyword">return</span> d.count
})
])
...
</code></pre>
<p>Der zweite Teil der <em>draw</em> Funktion fügt dem SVG-Element unter Verwendung der übergebenen Daten und der im ersten Teil erzeugten Konstanten alle benötigten Elemente zur Darstellung des Balkendiagramms hinzu. Für die Achsen werden zunächst g-Elementesup&gt;<a href="#12">12</a></sup> erzeugt. Diesen werden zwei Attribute, ein Klassenname für eventuelles Styling und ein transform-Attribut für die Positionierung der Achse innerhalb des Diagramms vergeben. Anschließend werden mit der Methode <em>call()</em> die im ersten Teil des Skripts in einer Konstanten gespeicherten Funktionen auf die jeweilige Achse angewendet.</p>
<p>Als nächstets wird noch die Beschriftung der Achsen als SVG-Text mit Hilfe von <em>append(“text”)</em> vorgenommen. Dem Text Element können auch verschiedene Attribute, z.B. für <em>transform</em> für die Rotation eines Textes, <em>x</em> und <em>y</em> für die absolute Positionierung und <em>dx</em> und <em>dy</em> für Offsetwerte zur Textplatzierung relativ zu den absoulten Werten. </p>
<p>Zuletzt wird die eigentliche Visualisierung der Daten implementiert. Dabei wird innerhalb des SVG-Elements mit <em>selectAll()</em> eine Auswahl an DOM-Elementen getroffen, an welche die zu visualisierenden Daten gebunden werden sollen. Obwohl zu diesem Zeitpunkt noch keine DOM-Elemente mit der Klasse <em>bar</em> existieren, werden diese als Selektion ausgewählt. Die <em>selectAll()</em> Methode liefert also eine leere Auswahl zurück, die also vorerst nur die späteren Elemente mit der Klasse <em>bar</em> vertritt. Die <em>data()</em> Methode bindet nun das übergebene Datenarray an die Selektion. D.h. die enthaltenen Datensätze werden gezählt, ihre Werte geparst und alle nachfolgenden Funktionen so oft ausgeführt wie Datensätze existieren. Um nun neue, an diese Datensätze gebundene Elemente zu erzeugen, wird die D3-Funktion <em>enter()</em> verwendet. Sie untersucht das DOM und die Anzahl der vorhandenen Datenwerte. Sind weniger DOM-Elemente vorhanden als Daten, erstellt sie ein neues Element als Platzhalter, auf welchem die nachfolgenden Funktionen ausgeführt werden können. <sup><a href="#13">13</a></sup></p>
<p>Dank D3s <em>enter()</em> Methode wird mit <em>append(‘rect’)</em> für jede der zehn Nationen im Datenarray ein Balken in Form eines einfachen SVG Rechteck-Shapes erstellt. Diese erhalten jeweils ein Klassenattribut mit dem Wert <em>bar</em> (bei einer dynamischen Visualisierung würde <em>selectAll(‘bar’)</em> bei erneutem Aufruf von <em>draw</em> die bereits gerenderten Balken als Selektion auswählen), die Attribute <em>x</em> und <em>y</em> für die Positionierung im Koordinatensystem und die Attribute <em>width</em> und <em>height</em>. Der X-Wert eines Balkens wird anhand der vorher festgelegten X-Achse festgelegt, ebenso der Y-Wert, er entpricht der Anzahl an Fahrern. Die Höhe eines Balken errechnet sich aus der Höhe des SVGs abzüglich des Abstands zum Datenwert für die Fahreranzahl auf der Y-Achse. Die Breite wird von der D3-Methode <em>rangeBand()</em> automatisch entsprechend des verfügbaeren Platzes berechnet.</p>
<pre><code class="lang-javascript">...
svg
.append(<span class="string">'g'</span>)
.attr(<span class="string">'class'</span>, <span class="string">'x axis'</span>)
.attr(<span class="string">'transform'</span>, <span class="string">`translate(<span class="subst">${margin.left}</span>, <span class="subst">${height}</span>)`</span>)
.call(xAxis)
.selectAll(<span class="string">'text'</span>)
.style(<span class="string">'text-anchor'</span>, <span class="string">'end'</span>)
.attr(<span class="string">'dx'</span>, <span class="string">'-.5em'</span>)
.attr(<span class="string">'dy'</span>, <span class="string">'.5em'</span>)
.attr(<span class="string">'transform'</span>, <span class="string">'rotate(-45)'</span>)
svg
.append(<span class="string">'g'</span>)
.attr(<span class="string">'class'</span>, <span class="string">'y axis'</span>)
.attr(<span class="string">'transform'</span>, <span class="string">`translate(<span class="subst">${margin.left}</span>, 0)`</span>)
.call(yAxis)
.append(<span class="string">'text'</span>)
.attr(<span class="string">'transform'</span>, <span class="string">'rotate(-90)'</span>)
.attr(<span class="string">'y'</span>, <span class="number">6</span>)
.attr(<span class="string">'dy'</span>, <span class="string">'0.71em'</span>)
.style(<span class="string">'text-anchor'</span>, <span class="string">'end'</span>)
.text(<span class="string">'Count'</span>)
svg
.selectAll(<span class="string">'bar'</span>)
.data(data)
.enter()
.append(<span class="string">'rect'</span>)
.attr(<span class="string">'class'</span>, <span class="string">'bar'</span>)
<span class="comment">/* Animation im Originalprojekt
.attr("y", height) //set y-axis at the bottom for the transition
.attr("height", 0) //set height of bars to 0 for the transition
.transition()
.delay(100)
.duration(1000)
*/</span>
.attr(<span class="string">'height'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{
<span class="keyword">return</span> height - y(d.count)
})
.attr(<span class="string">'y'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{
<span class="keyword">return</span> y(d.count)
})
.attr(<span class="string">'x'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">d</span>) </span>{
<span class="keyword">return</span> x(d.nationality) + margin.left
})
.attr(<span class="string">'width'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{
<span class="keyword">return</span> x.rangeBand()
})
}
</code></pre>
<p>Im Originalprojekt wurde der Visualisierung mit einer in D3 sehr einfach zu erstellenden Transition noch etwas Dynamik verliehen werden. Die Säulen wurden mit der Funktion <em>transition()</em> von der X-Achse aus zeitversetzt zu ihrem jeweiligen maximalen Höhenwert animiert. Dazu wurde vor dem Aufruf der Transition die Y-Achse auf den Wert der SVG-Höhe verschoben, da ihr Wertebereich umgekehrt ist. Zusätzlich wurde die Höhe der Balken vor der Animation auf null gesetzt. Die Funktion <em>delay()</em> ist für die Verzögerung der Animation zuständig, <em>duration()</em> bestimmt die Dauer in Millisekunden. <sup><a href="#1">1</a></sup></p>
<hr>
<div class='footnotes'>
<a id='1'>1</a> vgl. <a href="http://t3n.de/magazin/javascript-bibliothek-d3-237224/">http://t3n.de/magazin/javascript-bibliothek-d3-237224/</a><br><a id='2'>2</a> vgl. <a href="https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title">https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title</a><br><a id='3'>3</a> vgl. <a href="http://d3js.org/">http://d3js.org/</a><br><a id='4'>4</a> TEXT, JSON, XML, HTML, CSV, TSV<br><a id='5'>5</a> “A streamgraph […] is a type of stacked area graph which is displaced around a central axis, resulting in a flowing, organic shape.” (vgl. <a href="https://en.wikipedia.org/wiki/Streamgraph">https://en.wikipedia.org/wiki/Streamgraph</a>)<br><a id='6'>6</a> “A chord diagram is a graphical method of displaying the inter-relationships between data in a matrix. The data is arranged radially around a circle with the relationships between the points typically drawn as arcs connecting the data together.” (vgl. <a href="https://en.wikipedia.org/wiki/Chord_diagram">https://en.wikipedia.org/wiki/Chord_diagram</a>)<br><a id='7'>7</a> “A choropleth map […] is a thematic map in which areas are shaded or patterned in proportion to the measurement of the statistical variable being displayed on the map, such as population density or per-capita income.” (vgl. <a href="https://en.wikipedia.org/wiki/Choropleth_map">https://en.wikipedia.org/wiki/Choropleth_map</a>)<br><a id='8'>8</a>Genau wie in jQuery werden DOM-Elemente bei D3 anhand von CSS-Selektoren ausgewählt, allerdings werden diese im Umgang mit der Bilbliothek als “selections” bezeichnet. (vgl. <a href="https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title">https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title</a>)<br><a id='9'>9</a> Für das Beispiel wurden die <a href="http://ergast.com/api/f1/drivers.json">Fahrerdaten</a> der <em>experimental Motor Racing Developer API</em> verwendet. Aus ihnen wurde ein Array mit Objekten, die zum einen die Nationalität und zum anderen, die Häufigkeit dieser Nationalität enthalten, an das D3-Skript übergeben. Das Barchart stellt später die Anzahl der Fahrer pro Nation dar.<br><a id='10'>10</a> Am Anfang des D3-Skripts wurde dieses Template importiert: <code>js import tpl from &#39;../templates/filename.hbs&#39;</code><br><a id='11'>11</a> Statt mit [0, height] wird also [height, 0] als Range definiert. (vgl. <a href="https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title">https://www.linkedin.com/pulse/data-visualizations-using-d3js-brant-snow?trk=seokp_posts_primary_cluster_res_title</a>)<br><a id='12'>12</a> “It is a methodology in svg to group shapes together.”
<a id='13'>13</a> vgl. <a href="http://alignedleft.com/tutorials/d3/binding-data">http://alignedleft.com/tutorials/d3/binding-data</a>
</div>
</description>
</item>
<item>
<title>Typo3</title>
<link>http://localhost:8080/articles/typo3/</link>
<pubDate>Tue, 05 Jan 2016 01:00:00 +0100</pubDate>
<guid isPermaLink="true">http://localhost:8080/articles/typo3/</guid>
<author></author>
<description><p><img src='https://upload.wikimedia.org/wikipedia/commons/5/58/Logo_TYPO3.svg' height='265px' /></p>
<p>Ein ganz kurzer Überblick über das Content-Management-System Typo3. </p>
<p><span class="more"></span></p>
<h4 id="the-typo3-universe-sup-1-1-sup-">The TYPO3 Universe<sup><a href="#1">1</a></sup></h4>
<p>Wie <a href="http://localhost:8080/articles/drupal">Drupal</a> ist auch Typo3 ein Open Source Projekt, das in PHP programmiert wurde. Im Vergleich zu Drupal, ist Typo3 jedoch ein Enterprise Content-Management-System und damit speziell für den Einsatz in Unternehmen<sup><a href="#3">3</a></sup> entwickelt worden. Wie bei <a href="http://localhost:8080/articles/drupal">Drupal</a> gibt es auch bei Typo3 Erweiterungen zur Standardinstallation, die als Extensions im Typo3 “App Store” ausgewählt und über den built-in Extension-Manager des Content-Management-Systems installiert werden können. Zum Funktionsumfang der Core Installation gehören unter anderem eine granulierte Rechteverwaltung, die Möglichkeit für mehrsprachige Sites, responsive Templates und HTML5-Unterstützung, eine API für Extension-Developer und ein Suchindex über das Back- und Frontend.<sup><a href="#2">2</a></sup> </p>
<h4 id="usability">Usability</h4>
<p>Im Gegensatz zu <a href="http://localhost:8080/articles/drupal">Drupal</a> besteht Typo3 (wie die meisten andren Content-Management-Systeme) aus einem Frontend für den Nutzer der Website und einem administrativen Backend mit hierarchischem Seitenbaum für den Bearbeiter. Mit Hilfe einer Extension kann beim Bearbeiten am Desktop die Vorschau der Ansicht auf Mobilgeräten mit eingeblendet werden. <sup><a href="#2">2</a></sup> Im Vergleich zu <a href="http://localhost:8080/articles/drupal">Drupal</a> können viele Konfigurationen allerdings nur im TypoScript vorgenommen werden.</p>
<h4 id="typoscript">TypoScript</h4>
<p>TypoScript ist eine Metasprache, die ausschließlich beschreibend ist. Die Syntax von TypoScript basiert auf der hierarchischen Strukturierung von Informationen in ASCII text.<sup><a href="#5">5</a></sup> In Typo3 werden Konfigurationsparameter mit TypoScript definiert, d.h. Objekte verschiedener Typen werden erzeugt und ihnen die gewünschten Werte zugewiesen. Um von der Anwendung als Konfiguration verwendet werden zu können, wird das TypoScript geparst und in ein PHP-Array transformiert.<sup><a href="#6">6</a></sup> Mit TypoScript lassen sich nahezu alle Aspekte einer Typo3 Installation konfigurieren, was das System sehr viel Flexibilität verleiht. Gleichzeitig muss jedoch zusätzlich zur Syntax ein fundiertes Wissen über die Systemeigenschaften von Typo3 aufgebaut werden, um die Konfigurationsfreiheit voll ausschöpfen zu können.</p>
<pre><code> page = PAGE
page.10 = TEXT
page.10.value = Hello, world!
page.10.wrap = &lt;h2&gt;|&lt;/h2&gt;
</code></pre><h4 id="-die-typo3-community-hat-probleme-sup-7-7-sup-">“Die Typo3 Community hat Probleme” <sup><a href="#7">7</a></sup></h4>
<p>Während der Entwicklung der Typo3 Version 5.0 wurde das Projekt Neos in Form eines eigenen Development-Branches gergründet. Nachdem die Entwicklungszweige aufgrund der alten und complexen Codebasis von Typo3 stark außeinanderliefen, beschloß die Typo3 Community Neos als eigentständiges Produkt und unabhängig von Typo3 weiter zu entwickeln. Die Begründung für diese Entscheidung trifft das Neos Team foglendermaßen:</p>
<blockquote>
<p>“The TYPO3 team and the Neos team have realized more and more that TYPO3 CMS and Neos are two very distinct products, with different requirements, different underlying assumptions of how a modern CMS should be built and different target groups.” <sup><a href="#8">8</a></sup></p>
</blockquote>
<p><br> </p>
<hr>
<div class='footnotes'>
<a id='1'>1</a> vgl. <a href="https://typo3.org/about/">https://typo3.org/about/</a><br> <a id='2'>2</a> vgl. <a href="https://typo3.org/typo3-cms/key-features/">https://typo3.org/typo3-cms/key-features/</a><br> <a id='3'>3</a> z.B. für den Betrieb eines firmeneigenen Intranets <a href="http://www.typoblog.de/intranet-mit-typo3-cms/">http://www.typoblog.de/intranet-mit-typo3-cms/</a><br> <a id='4'>4</a> vgl. <a href="https://www.aoe.com/de/produkte/typo3.html">https://www.aoe.com/de/produkte/typo3.html</a><br> <a id='5'>5</a> vgl. <a href="https://docs.typo3.org/typo3cms/TyposcriptSyntaxReference/AppendixA/Index.html#what-is-typoscript">https://docs.typo3.org/typo3cms/TyposcriptSyntaxReference/AppendixA/Index.html#what-is-typoscript</a><br> <a id='6'>6</a> <a href="https://docs.typo3.org/typo3cms/TyposcriptSyntaxReference/AppendixA/PhpArrays/Index.html">https://docs.typo3.org/typo3cms/TyposcriptSyntaxReference/AppendixA/PhpArrays/Index.html</a><br> <a id='7'>7</a> Patrik Karisch, Webentwickler bei der pixelart GmbH, 68506 Salzburg, “Vorstellung Symphony Framework”, 19.01.2016<br> <a id='8'>8</a> vgl. <a href="https://www.neos.io/learn/neos-split-faq.html#why-are-you-splitting-and-why-now">https://www.neos.io/learn/neos-split-faq.html#why-are-you-splitting-and-why-now</a>
Bild: <a href="https://typo3.org/">https://typo3.org/</a>
</div></description>
</item>
</channel>
</rss>