-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfeed.xml
More file actions
1394 lines (1024 loc) · 178 KB
/
feed.xml
File metadata and controls
1394 lines (1024 loc) · 178 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
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>Philipp Trommler</title>
<description>Informatiker und Forstwissenschaftler, immer auf der Suche nach neuen Herausforderungen und für Auftragsarbeiten zu haben.
</description>
<link>http://www.philipp-trommler.me/</link>
<image>
<url>http://www.philipp-trommler.me/apple-touch-icon-144x144.png</url>
<title>Philipp Trommler</title>
<link>http://www.philipp-trommler.me/</link>
<width>144</width>
<height>144</height>
<description>Informatiker und Forstwissenschaftler, immer auf der Suche nach neuen Herausforderungen und für Auftragsarbeiten zu haben.
</description>
</image>
<atom:link href="http://www.philipp-trommler.me/feed.xml" rel="self" type="application/rss+xml" />
<pubDate>Wed, 20 Apr 2016 19:22:59 +0200</pubDate>
<lastBuildDate>Wed, 20 Apr 2016 19:22:59 +0200</lastBuildDate>
<generator>Jekyll v3.1.1</generator>
<item>
<title>Wileyfox Swift: Ein ausführlicher Test</title>
<description><p>Ich habe das Wileyfox Swift jetzt seit über einem Monat und nachdem nun auch die Fachpresse darüber berichtet hat, dass es offiziell in Deutschland erhältlich ist, wird es wohl Zeit einen etwas ausführlicheren Test dazu zu schreiben. Dabei möchte ich insbesondere auch auf die auf Amazon beschriebenen Mängel eingehen.</p>
<p>Ich bin direkt von meinem alten Samsung Galaxy S2 auf das Swift umgestiegen und vergleiche es daher hauptsächlich mit diesem Gerät. Aber auch ein Motorola Moto E (2015) kommt als Vergleichsgerät hier und da vor.</p>
<h1 id="lieferumfang">Lieferumfang</h1>
<p>Der Lieferumfang des Wileyfox Swift beschränkt sich auf das Mindeste:</p>
<ul>
<li>Das Smartphone</li>
<li>Ein USB auf Micro-USB Kabel</li>
<li>Die üblichen Anleitungen und Garantiebeschreibungen</li>
<li>Eine Displayschutzfolie, die bereits aufgebracht ist</li>
</ul>
<p>Das Ladekabel ist recht kurz (maximal 30cm) und zudem recht steif, in Verbindung mit der Tatsache, dass man kaum andere Kabel benutzen kann (mehr dazu weiter unten) könnte das für den ein oder anderen zum Problem werden.</p>
<h1 id="hardware">Hardware</h1>
<p>Das Wileyfox Swift ist ein modernes Smartphone, das aussieht, wie moderne Smartphones nunmal aussehen: Schwarz, dünn, abgerundete Ecken, glänzendes Display. Einzig die Rückseite hebt sich vom Smartphone-Allerlei ab: Sie ist sehr rau (der Hersteller nennt das Sandstein) und wird verziert von dem glänzenden Wileyfox-Logo, einem orangenen Wileyfox-Schriftzug und der hauchdünn orange umrandeten Kamera.</p>
<p>Die Rauheit greift sich allerding sehr schnell ab, wie auch auf Amazon berichtet. Nach den sechs Wochen, in denen ich das Handy nun (ohne Schutzhülle) benutze, ist vom Sandstein nicht mehr viel übrig. Am Aussehen der Rückseite ändert das nichts und sie bleibt auch für ein Smartphone recht griffig; insgesamt überzeugt sie mich.</p>
<h2 id="akku">Akku</h2>
<p>Der Akku ist wohl einer der Punkte, die mich am positivsten überrascht haben. Besonders im Vergleich zu meinem alten Galaxy S2 handelt es sich bei den Laufzeiten des Swift um einen wahrlichen Sprung.</p>
<figure>
<a href="/images/wileyfoxtest-2.png">
<img src="/images/wileyfoxtest-2.png" alt="Akkulaufzeit des Wileyfox Swift." />
</a>
<figcaption>Akkulaufzeit des Wileyfox Swift.</figcaption>
</figure>
<p>Das SGS2 hielt zum Schluss kaum noch 12 Stunden, selbst wenn ich es fast gar nicht benutzt habe. Mit dem Wileyfox komme ich locker über zwei Tage, an Wochenenden sind es teilweise auch drei. Im Vergleich zum Moto E verliert es dennoch deutlich, damit schafft man auch mal fünf Tage.</p>
<figure>
<a href="/images/wileyfoxtest-3.png">
<img src="/images/wileyfoxtest-3.png" alt="Detaillierter Akkuverbrauch des Wileyfox Swift." />
</a>
<figcaption>Detaillierter Akkuverbrauch des Wileyfox Swift.</figcaption>
</figure>
<h2 id="kamera">Kamera</h2>
<p>Die Kamera unterliegt leider der des Galaxy S2. Die Farbenwiedergabe ist schlecht und die Farben rauschen stark, Details verwaschen, Kanten sind unscharf.
Die Frontkamera liefert die üblichen Ergebnisse und reicht für Videotelefonie vollkommen aus.</p>
<figure>
<a href="/images/wileyfoxtest-1.jpg">
<img src="/images/wileyfoxtest-1.jpg" alt="Testaufnahme mit der Hauptkamera des Wileyfox Swift (die Nummernschilder sind im Nachhinein verwischt worden)." />
</a>
<figcaption>Testaufnahme mit der Hauptkamera des Wileyfox Swift (die Nummernschilder sind im Nachhinein verwischt worden).</figcaption>
</figure>
<h2 id="leistung">Leistung</h2>
<p>Die Leistung des Swift ist für die alltägliche Benutzung völlig ausreichend. Weder die Benutzeroberfläche noch Apps ruckeln. Auch anspruchsvollere Anwendungen wie diverse Cardboard-Apps meistert das Wileyfox ohne Verzögerungen. Aufwendige 3D-Spiele habe ich mangels Interesse nicht getestet. Positiv anzumerken ist, dass der Prozessor 64-bittig ist. Dies hat zwar im Moment noch keine spürbaren positiven Auswirkungen, könnte aber im Hinblick auf die Zukunftsicherheit wichtig werden.</p>
<h2 id="display">Display</h2>
<p>Das Wileyfox hat ein HD-Display (ehemals HDready, also 720x1280 Pixel), das mich wirklich überrascht hat. Da ich ja vom Galaxy S2 eines der viel gelobten AMOLED-Displays gewohnt war, habe ich keine allzu großen Erwartung an das Swift gehabt. Aber von wegen: Das Display des Swift zeigt wirklich schöne Farben, die so gut wie keine Blickwinkelabhängigkeit zeigen und deutlich natürlicher wirken als die des S2, das bei den Rottönen doch sehr übertrieben hat. Auch die Schärfe ist deutlich besser, obwohl der PPI-Wert nicht so viel höher ist. Insgesamt muss ich aber sagen, dass mir ein 5” Display doch einen Deut zu groß ist, da ich recht kleine Hände habe, aber es bleibt einem ja kaum noch eine Wahl.</p>
<h2 id="konnektivitt">Konnektivität</h2>
<p>Sowohl WLAN- als auch der mobile Empfang sind gut und ein kleines bisschen besser als beim Galaxy. Beim Telefonieren reicht jedoch schon weniger Signalverlust als beim S2, damit das Gegenüber nicht mehr zu hören ist. Man selbst ist jedoch noch gut zu verstehen und auch bei der Datenübertragung ist dieser Effekt nicht zu beobachten, es handelt sich also wahrscheinlich eher um ein Softwareproblem. Ebenso ein Softwareproblem ist die Unfähigkeit des Wileyfox Swift sich mit dem <em>eduroam</em>-WLAN zu verbinden, eine Lösung dafür habe ich in <a href="/2016/02/12/wlan-probleme-wileyfox-swift-cm13.html">meinem letzten Beitrag vorgestellt</a>.</p>
<p>Die bei Amazon oft bemängelten Verbindungsabbrüche beim GPS konnte ich auch beobachten. Das Wileyfox verliert scheinbar in unregelmäßigen Abständen für kurze Zeit den GPS-Fix. Das ist beim Geocachen nicht weiter schlimm, da das Signal schnell zurückkehrt, wie es sich bei der Navigation im Auto verhält (in den Rezensionen ist davon die Rede, dass zum Beispiel Google Maps nach jeder Erlangung des GPS-Fix die letzte Ansage wiederholt) konnte ich mangels Auto nicht testen. Dass die Positionsbestimmung wie in einigen Rezensionen beschrieben äußerst langsam und/oder ungenau seien soll, kann ich nicht bestätigen, sie ist zumindest schneller als beim Galaxy S2 und ausreichend genau.</p>
<p>Die ebenfalls bei Amazon beschriebenen Probleme bei der Benutzung des Wileyfox mit Bluetooth-Headsets kann ich nicht bestätigen. Musik hören funktioniert bei mir einwandfrei.</p>
<h2 id="sonstiges">Sonstiges</h2>
<p>Wie oben bereits erwähnt, kann man kaum ein anderes Ladekabel als das von Wileyfox mitgelieferte benutzen, da der USB-Anschluss deutlich tiefer ins Gehäuse eingelassen ist als üblich.
Dadurch halten übliche USB-Kabel nicht fest und rutschen, außerdem war die Ladegeschwindigkeit mit dem Ladegerät meines SGS2 deutlich geringer als mit einem anderen und dem Kabel von Wileyfox (allerdings kann das auch am Ladegerät des Samsung liegen).</p>
<s>Ähnlich verhält es sich mit dem Kopfhöreranschluss: Auch dieser ist recht tief ins Gehäuse eingelassen, wodurch manche Audiokabel schlicht keinen Kontakt herstellen und die internen Lautsprecher weiter genutzt werden. Erfolg hatte ich mit solchen Kabeln, die auch eine Headsetfunktion integrieren, also einen Kontakt mehr haben.</s>
<p><em>(Siehe Update am Ende des Artikels)</em></p>
<p>Apropos interne Lautsprecher: Diese sind recht laut (ich lasse das Swift nicht auf voller Lautstärke klingeln, weil das einfach <em>zu</em> laut wäre) und erzeugen einen recht sauberen Klang. Zu viel sollte man aber Smartphone-typisch nicht erwarten, erst recht keine Bässe. Der Lautsprecher fürs Telefonieren erzeugt einen sehr blechernen Ton, der wirklich gewöhnungsbedürftig ist, dafür ist die Geräuschunterdrückung ordentlich und man versteht seinen Gesprächspartner besser als beim S2.</p>
<p>Eine weitere Anmerkung: Im Unterschied zu vielen anderen Dual-SIM-Geräten hat das Swift nicht einen SIM-Slot und einen Kombi-Slot sondern zwei vollwertige SIM-Slots und einen MicroSD-Slot.</p>
<h1 id="software">Software</h1>
<h2 id="cyanogenos">CyanogenOS</h2>
<p>Das vorinstallierte CyanogenOS basiert auf Android 5.1 (CyanogenOS 12.1), ein Update auf Android 5.1.1 (CyanogenOS 12.1.1) kann direkt nach dem ersten Einschalten installiert werden. Es ist damit zu rechnen, dass das Swift relativ gut mit Updates versorgt wird, den Sprung auf Android 6/CyanogenOS 13 halte ich für sicher.</p>
<p>Das Wileyfox kommt mit einem dezenten, im Material-Design gehaltenen Theme daher, dass mir persönlich aufgrund seiner Orangetöne nicht so gut gefallen hat, aber keineswegs schlecht gemacht ist. Ansonsten handelt es sich im Großen und Ganzen um CyanogenMod mit vorinstallierten Apps. Derer sind es allerdings ziemlich viele, fast die komplette App-Garde von Google ist vorinstalliert und lässt sich natürlich nicht entfernen. In diesem Punkt unterscheidet sich CyanogenOS leider nicht von den Androidversionen von Samsung und Motorola. Ich benutze zwar auch Google-Dienste, möchte aber selbst entscheiden welche der Apps ich nutze und wofür ich meinen Speicherplatz verwende.</p>
<h2 id="cyanogenmod">CyanogenMod</h2>
<p>Aus diesem Grund und weil ich natürlich immer die neueste Software benutzen möchte, bin ich, kurz nachdem ich das Wileyfox erhalten habe, auf CyanogenMod umgestiegen. Und hier zeigt sich, dass mein Plan voll aufgegangen ist: Dadurch, dass das Swift mit CyanogenOS ausgeliefert wird, ist der Umstieg auf CyanogenMod wirklich kinderleicht.</p>
<p><a href="https://wiki.cyanogenmod.org/w/Install_CM_for_crackling">Die Anleitung auf der CyanogenMod-Webseite</a> ist wirklich ausführlich und fehlerfrei, kein Gesuche in unzähligen teilweise obskuren Foren wie beim Umstieg auf dem Galaxy S2. Zudem ist natürlich schon CyanogenMod 13 alias Android 6 verfügbar. Und ein weiterer Vorteil gegenüber einem nicht offiziell unterstützten Gerät wie dem SGS2: Die Nightlies von CyanogenMod 13 für das Swift sind jetzt schon deutlich stabiler als die Version 12.1 für das S2. Ich konnte bisher keine Softwarefehler entdecken.</p>
<h1 id="fazit">Fazit</h1>
<p>Wer sich selbst nicht als Power-User bezeichnen würde, aber sich dennoch ein Gerät mit aktueller Software wünscht, dem kann ich das Wileyfox Swift wirklich nur ans Herz legen. Es ist ein solides Smartphone mit guter Akkulaufzeit und einem guten Display, das für diesen Preis wohl seines Gleichen sucht. Ich muss allerdings zu dieser Empfehlung dazu sagen, dass sie uneingeschränkt nur bei der Verwendung mit CyanogenMod gilt. Das Flashen ist jedoch wirklich einfach und auch für technische Laien zu bewältigen. An CyanogenOS stören mich einfach die vielen, nicht zu entfernenden Google-Apps.</p>
<p>Vieltelefonierer sollten sich vielleicht nach einem anderen Gerät umsehen, da die Gesprächsqualität wirklich nicht die beste ist. Ebenso ist das Swift nichts für Selfie-süchtige und Instagram-Fans, dafür sind die Kameras schlicht zu schlecht. Auch Handy-Gamer sehnen sich vielleicht nach mehr (Grafik-)Leistung und sollten daher zu einem anderen Gerät greifen.</p>
<p>Ob ich das Wileyfox Swift wieder kaufen würde? Für den Preis (ich habe circa 140€ bezahlt) auf jeden Fall!</p>
<p><strong>Update 20.04.2016:</strong></p>
<p>Auf den Hinweis eines aufmerksamen Lesers hin ist mir aufgefallen, dass es sich bei den Problemen mit dem Kopfhöreranschluss um einen Softwarefehler handelt. Nach einem Update von CyanogenMod funktioniert der Anschluss nun einwandfrei.</p>
</description>
<pubDate>Thu, 03 Mar 2016 21:02:03 +0100</pubDate>
<link>http://www.philipp-trommler.me/2016/03/03/wileyfox-swift-ausfuehrlicher-test.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2016/03/03/wileyfox-swift-ausfuehrlicher-test.html</guid>
<category>wileyfox</category>
<category>swift</category>
<category>cm13</category>
<category>cyanogenmod</category>
<category>test</category>
<category>cyanogenos</category>
<media:thumbnail url="http://www.philipp-trommler.me/images/wileyfoxtest-1.jpg" />
<enclosure url='http://www.philipp-trommler.me/images/wileyfoxtest-1.jpg' length='7011454' type='image/jpeg' />
</item>
<item>
<title>WLAN-Probleme mit dem Wileyfox Swift und CM13</title>
<description><p>Ich habe seit einigen Tagen das <a href="https://www.wileyfox.com/de/swift/">Wileyfox Swift</a> und musste es natürlich mit CyanogenMod in Version 13 flashen (ein ausführlicher Test folgt noch). Allerdings zeigten sich schnell Probleme beim Verbinden mit dem Universitäts-WLAN <em>eduroam</em>, genauer gesagt hat es einmal funktioniert, das nächste Verbinden schlug dann auch schon fehl.</p>
<h1 id="schuldfrage">Schuldfrage</h1>
<p>Nach einiger Recherche zeigte sich schnell, dass Verbindungsprobleme während</p>
<blockquote>
<p>IP-Adresse wird abgerufen…</p>
</blockquote>
<p>auf <a href="https://thealarmclocksixam.wordpress.com/2013/10/26/dhcp-failure-on-android-wifi-stuck-on-obtaining-ip-address-how-i-solved-it/">Probleme mit dem DHCP-Client</a> zurückzuführen sind. Allerdings ist die dort angegebene Lösung für mein Problem nicht passend, da der Ordner <code class="highlighter-rouge">/data/misc/dhcp/</code> bereits leer war. Der Schuldige ist scheinbar eher im noch relativ neuen CyanogenMod 13 oder Android 6 selbst zu suchen, denn folgende Schritte beheben das Problem:</p>
<ul>
<li>
<p>Als erstes habe ich <em>eduroam</em> aus der Liste der bekannten Netzwerke gelöscht (ob das wirklich notwendig ist, kann ich nicht genau sagen).</p>
</li>
<li>
<p>Entwickleroptionen aktivieren: Hierfür muss im Menü <em>Einstellungen &gt; Über das Telefon</em> mehrfach hintereinander auf das Feld <em>Build-Nummer</em> gedrückt werden. Ein Countdown zeigt dabei an, wieviele Clicks noch nötig sind.</p>
</li>
</ul>
<figure>
<a href="/images/wlanprobscm13-1.png">
<img src="/images/wlanprobscm13-1.png" alt="Zum Aktivieren der Entwickleroptionen muss das Feld Build-Nummer mehrfach hintereinander gedrückt werden." />
</a>
<figcaption>Zum Aktivieren der Entwickleroptionen muss das Feld Build-Nummer mehrfach hintereinander gedrückt werden.</figcaption>
</figure>
<p>Anschließend sind die Entwickleroptionen in den Einstellungen direkt oberhalb von <em>Über das Telefon</em> verfügbar.</p>
<figure>
<a href="/images/wlanprobscm13-2.png">
<img src="/images/wlanprobscm13-2.png" alt="Nun sind die Entwickleroptionen verfügbar." />
</a>
<figcaption>Nun sind die Entwickleroptionen verfügbar.</figcaption>
</figure>
<ul>
<li>Nun die Option <em>Alten DHCP-Client verwenden</em> in der Abteilung Netzwerk der Entwickleroptionen aktivieren.</li>
</ul>
<figure>
<a href="/images/wlanprobscm13-3.png">
<img src="/images/wlanprobscm13-3.png" alt="In den Entwickleroptionen ist eine Option zur Verwendung des alten DHCP-Clients verfügbar." />
</a>
<figcaption>In den Entwickleroptionen ist eine Option zur Verwendung des alten DHCP-Clients verfügbar.</figcaption>
</figure>
<p>Anschließend kann man <em>eduroam</em> wieder als bekanntes Netzwerk hinzufügen. Dabei unbedingt darauf achten, <a href="http://tu-dresden.de/die_tu_dresden/zentrale_einrichtungen/zih/dienste/arbeitsumgebung/zugang_datennetz/eduroam_android_4.3/">ein Root-Zertifakt zu installieren</a>, damit keine <a href="http://www.heise.de/security/meldung/Eduroam-Netz-an-Unis-Android-Nutzer-sollten-dringend-Zertifikat-installieren-3079193.html">Sicherheitslücken</a> entstehen. Nun sollte das Beziehen der IP-Adresse wieder funktionieren.</p>
</description>
<pubDate>Fri, 12 Feb 2016 17:53:00 +0100</pubDate>
<link>http://www.philipp-trommler.me/2016/02/12/wlan-probleme-wileyfox-swift-cm13.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2016/02/12/wlan-probleme-wileyfox-swift-cm13.html</guid>
<category>wlan</category>
<category>wileyfox</category>
<category>swift</category>
<category>cm13</category>
<category>cyanogenmod</category>
<media:thumbnail url="http://www.philipp-trommler.me/images/wlanprobscm13-1.png" />
<enclosure url='http://www.philipp-trommler.me/images/wlanprobscm13-1.png' length='71943' type='image/png' />
</item>
<item>
<title>Rust und Vala: Ein interessantes Team</title>
<description><p>Ich bin vor einigen Tagen zufällig über Mozillas (relativ) neue Programmiersprache <a href="http://www.rust-lang.org">Rust</a> gestolpert und war direkt angetan. Natürlich war die erste Frage, die sich mir stellte, ob man Rust wohl auch von Vala aus nutzen kann, da es für geschwindigkeitskritische Anwendung sehr gut geeignet scheint.</p>
<p>Wie <a href="https://doc.rust-lang.org/stable/book/rust-inside-other-languages.html">in der Anleitung</a> gut beschrieben ist, lassen sich Rust-Bibliotheken von anderen Sprachen aus nutzen, darunter natürlich auch C. Da Vala zu C kompiliert wird, lag der Verdacht also nah, dass es auch möglich sein muss, Rust von Vala aus zu nutzen. Und der Weg dorthin wird durch diese Annahme eigentlich auch schon vorgegeben.</p>
<p>Schreiben wir uns also eine kleine Rust-Bibliothek, die uns als Test dienen soll. Ich habe von Anfang an <a href="https://crates.io/">Cargo</a> genutzt, da es sich einfach bedienen lässt und lästige Routineaufgaben übernimmt. Erstellen wir also ein leeres Cargo-Projekt:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">cargo new vala_test</code></pre></figure>
<p>Nachdem wir in das erzeugte Verzeichnis <code class="highlighter-rouge">vala_test</code> gewechselt sind, müssen wir zunächst</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="o">[</span>lib]
name <span class="o">=</span> <span class="s2">"valatest"</span>
crate-type <span class="o">=</span> <span class="o">[</span><span class="s2">"dylib"</span><span class="o">]</span></code></pre></figure>
<p>an die Datei <code class="highlighter-rouge">Cargo.toml</code> anhängen, um Cargo mitzuteilen, dass wir eine dynamisch gelinkte Bibliothek (<code class="highlighter-rouge">crate-type = ["dylib"]</code>) mit dem Namen <code class="highlighter-rouge">libvalatest.so</code> (<code class="highlighter-rouge">name = "valatest"</code>) erstellen wollen.</p>
<p>Anschließend öffnen wir die bereits vorhandene <code class="highlighter-rouge">lib.rs</code> im Ordner <code class="highlighter-rouge">src</code> und fügen folgenden Quelltext ein:</p>
<figure class="highlight"><pre><code class="language-rust" data-lang="rust"><span class="k">pub</span> <span class="k">struct</span> <span class="n">TestType</span> <span class="p">{</span>
<span class="n">int1</span><span class="p">:</span> <span class="nb">i32</span><span class="p">,</span>
<span class="n">int2</span><span class="p">:</span> <span class="nb">u8</span><span class="p">,</span>
<span class="p">}</span>
<span class="cp">#[no_mangle]</span>
<span class="k">pub</span> <span class="k">extern</span> <span class="k">fn</span> <span class="nf">test</span><span class="p">(</span><span class="n">int1</span><span class="p">:</span> <span class="nb">i32</span><span class="p">,</span> <span class="n">int2</span><span class="p">:</span> <span class="nb">i64</span><span class="p">,</span> <span class="n">uint1</span><span class="p">:</span> <span class="nb">u8</span><span class="p">,</span> <span class="n">text</span><span class="p">:</span> <span class="nb">char</span><span class="p">,</span> <span class="n">slice</span><span class="p">:</span> <span class="o">&amp;</span><span class="p">[</span><span class="nb">u32</span><span class="p">],</span> <span class="n">test_type</span><span class="p">:</span> <span class="o">&amp;</span><span class="n">TestType</span><span class="p">)</span> <span class="p">{</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"int1: {}"</span><span class="p">,</span> <span class="n">int1</span><span class="p">);</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"int2: {}"</span><span class="p">,</span> <span class="n">int2</span><span class="p">);</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"uint1: {}"</span><span class="p">,</span> <span class="n">uint1</span><span class="p">);</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"text: {}"</span><span class="p">,</span> <span class="n">text</span><span class="p">);</span>
<span class="k">for</span> <span class="n">element</span> <span class="n">in</span> <span class="n">slice</span> <span class="p">{</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"slice: {}"</span><span class="p">,</span> <span class="n">element</span><span class="p">);</span>
<span class="p">}</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"TestType int1: {}"</span><span class="p">,</span> <span class="n">test_type</span><span class="py">.int1</span><span class="p">);</span>
<span class="nd">println!</span><span class="p">(</span><span class="s">"TestType int2: {}"</span><span class="p">,</span> <span class="n">test_type</span><span class="py">.int2</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>
<p>Wie man leicht erkennt, handelt es sich bloß um eine einfache Funktion, die die übergebenen Paramter auf der Konsole ausgibt. Aber genau das ist es, was wir brauchen, um zu sehen, ob unser Programm richtig funktioniert. Zum weiteren Testen habe ich außerdem ein <code class="highlighter-rouge">struct</code> eingefügt.</p>
<p>Wichtig ist hier vor allem das <code class="highlighter-rouge">pub extern</code>, das angibt, dass diese Funktion von außerhalb genutzt werden soll, sowie <code class="highlighter-rouge">#[no_mangle]</code>, das verhindert, dass die automatische, interne Namensänderung von Rust stattfindet.</p>
<p>Nun muss die Bibliothek noch kompiliert werden. Dies erledigt der Befehl <code class="highlighter-rouge">cargo build</code>, das Shared Object befindet sich danach im Ordner <code class="highlighter-rouge">target/debug</code>.</p>
<p>In der Rust-Dokumentation wird richtig erklärt, dass man natürlich eine C-Header-Datei benötigt, um auf die Funktionen der Rust-Bibliothek zugreifen zu können. Schreiben wir uns also so eine Header-Datei <code class="highlighter-rouge">libvalatest.h</code>:</p>
<figure class="highlight"><pre><code class="language-c" data-lang="c"><span class="cp">#ifndef LIBVALATEST_H_
#define LIBVALATEST_H_
</span>
<span class="k">typedef</span> <span class="k">struct</span> <span class="n">TestType</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">int1</span><span class="p">;</span>
<span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">int2</span><span class="p">;</span>
<span class="p">}</span> <span class="n">TestType</span><span class="p">;</span>
<span class="kt">void</span> <span class="n">test</span><span class="p">(</span><span class="kt">int</span> <span class="n">int1</span><span class="p">,</span> <span class="kt">long</span> <span class="n">int2</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">char</span> <span class="n">uint1</span><span class="p">,</span> <span class="kt">char</span> <span class="n">text</span><span class="p">,</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">slice</span><span class="p">[],</span> <span class="kt">int</span> <span class="n">slice_length</span><span class="p">,</span> <span class="n">TestType</span> <span class="o">*</span><span class="n">test_type</span><span class="p">);</span>
<span class="cp">#endif</span></code></pre></figure>
<p>Wie man sieht, ist auch dies relativ trivial. Es müssen lediglich die Rust-Typen auf ihre entsprechenden C-Typen umgemapped werden. Nun folgt der Standard-Vala-Weg, also das Schreiben des VAPIs <code class="highlighter-rouge">libvalatest.vapi</code>:</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">[CCode (cheader_filename = "libvalatest.h")]
namespace ValaTest {
[CCode (cname = "TestType", has_type_id = false)]
public struct TestType {
public int int1;
public uint8 int2;
}
[CCode (cname = "test")]
public void test (int int1, int64 int2, uint8 uint1, char text, uint[] slice, TestType testType);
}</code></pre></figure>
<p>Wie dem aufmerksamen Betrachter nun vielleicht schon aufgefallen ist, hat die Funktion <code class="highlighter-rouge">test</code> in der C-Header-Datei einen zusätzlichen Parameter vom Typ <code class="highlighter-rouge">int</code>. Dieser wird von Vala automatisch eingefügt, wenn in einem VAPI vor einem Array kein <code class="highlighter-rouge">[CCode (array_length = false)]</code> steht. Und nach meiner Erfahrung in der Zusammenstellung dieses Beispiels sollte man das auch nicht tun. Fehlt die Länge des Arrays in der Funktion, läuft die Schleife <code class="highlighter-rouge">for element in slice</code> in Rust bis zum Erreichen eines Segmentation faults (ich vermute durch den gesamten dem Programm zur Verfügung stehenden Speicher). Warum das so ist, und wie Rust intern die Länge des Arrays aus dem Funktionsaufruf übernimmt kann ich nicht beantworten. Hier wäre jemand mit mehr Erfahrung in Rust wohl der bessere Ansprechpartner.</p>
<p>Nun folgt abschließend ein kleines Vala-Programm <code class="highlighter-rouge">main.vala</code>, dass die Rust-Funktion aufruft und den Datentyp nutzt:</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">using ValaTest;
void main (string[] args) {
TestType testType = { 123456789, 255 };
uint[] slice = { 1, 2, 255 };
test (1, 2, 3, 'T', slice, testType);
}</code></pre></figure>
<p>Der Befehl zum Kompilieren ist diesmal ein wenig länger, da alle Komponenten nicht in Standardverzeichnissen liegen:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">valac --vapidir<span class="o">=</span>./ --pkg<span class="o">=</span>libvalatest main.vala -X -I./ -X -L./target/debug -X -lvalatest</code></pre></figure>
<p>Zudem muss das Verzeichnis <code class="highlighter-rouge">target/debug</code> noch zu den Verzeichnissen hinzugefügt werden, in denen nach Shared Objects gesucht wird. Dies erledigt ein:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash"><span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span>./target/debug</code></pre></figure>
<p>Gestartet wird das Programm nun mit <code class="highlighter-rouge">./main</code> und tatsächlich, auf der Konsole erscheint die erwartete Ausgabe:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">int1: 1
int2: 2
uint1: 3
text: T
slice: 1
slice: 2
slice: 255
TestType int1: 123456789
TestType int2: 255</code></pre></figure>
<p>Es ist also sehr gut möglich, von Vala aus Rust zu nutzen, und ich denke, ich werde das in nächster Zeit auch mal tun. Im Laufe dessen werde ich hier natürlich weitere Anleitungen, zum Beispiel zu weiteren Typen wie <code class="highlighter-rouge">String</code>/<code class="highlighter-rouge">str</code>, veröffentlichen.</p>
<p>Bis dahin erst mal viel Spaß mit den neuen Möglichkeiten!</p>
</description>
<pubDate>Sun, 19 Jul 2015 20:48:22 +0200</pubDate>
<link>http://www.philipp-trommler.me/2015/07/19/rust-und-vala-ein-interessantes-team.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2015/07/19/rust-und-vala-ein-interessantes-team.html</guid>
<category>rust</category>
<category>vala</category>
<category>c</category>
<category>ffi</category>
</item>
<item>
<title>Die neue GTK 3.16 StackSidebar in Vala</title>
<description><p>Neben vielen anderen großartigen Verbesserungen, die GNOME 3.16 seinen Nutzern beschert, bringt natürlich auch GTK+ wieder Neuerungen mit. Eine davon ist die neue <code class="highlighter-rouge">Gtk.StackSidebar</code>, die als Übersicht für die schon älteren <code class="highlighter-rouge">Gtk.Stack</code>s dient und aussieht wie eine klassische <code class="highlighter-rouge">Gtk.List</code>.</p>
<p>Über ebendiese ließe sich auch ein ähnliches Verhalten erzeugen, wie es die <code class="highlighter-rouge">Gtk.StackSidebar</code> an den Tag legt: Bei einem Klick (oder Drücken) auf ein Item in der Liste wird das jeweilige Element des <code class="highlighter-rouge">Gtk.Stack</code>s angezeigt. Mit diesem neuen Widget nimmt man jedoch ganz klar eine Abkürzung! Denn während man sich mit einer <code class="highlighter-rouge">Gtk.List</code> mit Signalen und dergleichen rumärgern müsste, reicht es bei der <code class="highlighter-rouge">Gtk.StackSidebar</code> den <code class="highlighter-rouge">Gtk.Stack</code> anzugeben, mit dem man arbeiten will. Alles weitere wird intern geregelt und betrifft den Programmierer (also uns) nicht weiter. Das klingt doch super!</p>
<h1 id="minimalbeispiel">Minimalbeispiel</h1>
<p>Wie immer bei mir folgt nun das obligatorische Minimalbeispiel. Diesmal habe ich mich wieder dazu entschlossen, ein anderes wiederzuverwenden, in diesem Fall den <a href="/2015/03/22/die-gtk-3-12-actionbar-in-vala.html">minimalistischen Bildbetrachter aus dem ActionBar-Tutorial</a>. Diesem stünde doch eine Übersicht über die Bilder – vielleicht in Form von Dateinamen – nicht schlecht, oder? Da ich allerdings hier wie auch im ursprünglichen Tutorial zu Anschauungszwecken mit Stock-Icons arbeite, habe ich ihnen einfach Namen gegeben, das Vorgehen sollte aber klar sein.</p>
<figure>
<a href="/images/stacksidebar1.png">
<img src="/images/stacksidebar1.png" alt="Die StackSidebar als Erweiterung für den Bildbetrachter aus dem ActionBar-Tutorial." />
</a>
<figcaption>Die StackSidebar als Erweiterung für den Bildbetrachter aus dem ActionBar-Tutorial.</figcaption>
</figure>
<p>Zunächst muss also ein neuer <code class="highlighter-rouge">Gtk.Stack</code> erzeugt werden. Diesem können anschließend beliebige <code class="highlighter-rouge">Gtk.Widget</code>s hinzugefügt werden. Wichtig ist bei der Benutzung der <code class="highlighter-rouge">Gtk.StackSidebar</code> nur, dass die <code class="highlighter-rouge">Gtk.Widget</code>s betitelt übergeben werden, also mit</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">add_titled (Gtk.Widget child, string name, string title)</code></pre></figure>
<p>da der String <code class="highlighter-rouge">title</code> das ist, was in der <code class="highlighter-rouge">Gtk.StackSidebar</code> angezeigt wird. <code class="highlighter-rouge">Gtk.Widget</code>s ohne Titel werden stillschweigend ignoriert.</p>
<p>Dies ist allerdings nicht der einzige Fallstrick, der bei der Benutzung der <code class="highlighter-rouge">Gtk.StackSidebar</code> lauert: Sie muss <em>zwingend</em> in einer <code class="highlighter-rouge">Gtk.Box</code> o. Ä. mit <em>horizontaler</em> Ausrichtung eingefügt werden, ansonsten wird sie schlicht und ergreifend nicht angezeigt (ohne Fehlermeldung). Aufgrund dessen und da sie – im Gegensatz zur <code class="highlighter-rouge">Gtk.List</code> – auch nur Strings enthalten kann, können mit ihr leider keine Slideshows unter der großen Bildansicht gebaut werden – schade!</p>
<p>Ansonsten ist die Benutzung wirklich mehr als einfach: <code class="highlighter-rouge">Gtk.StackSidebar</code> erzeugen und dem <code class="highlighter-rouge">Gtk.Stack</code> zuordnen, der verwendet werden soll.</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">Gtk.StackSidebar ssidebar = new Gtk.StackSidebar ();
ssidebar.set_stack (stack);</code></pre></figure>
<p>Wo die <code class="highlighter-rouge">Gtk.StackSidebar</code> dann am Ende im Fenster angezeigt werden soll, ist egal. Sie muss nicht direkt neben dem <code class="highlighter-rouge">Gtk.Stack</code> auftauchen. Hauptsache, sie befindet sich in einer horizontalen Umgebung (siehe oben).</p>
<p>Zusammen sieht das ganze dann so aus:</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">class Example : Gtk.Application {
public Example () {
Object (application_id: "com.example.app", flags: ApplicationFlags.FLAGS_NONE);
}
protected override void activate () {
Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = true;
Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
window.set_default_size (800, 500);
window.set_title ("StackSidebar");
/*
* Primäre Box
*/
Gtk.Box primary_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
/*
* Innere Box
*/
Gtk.Box inner_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
primary_box.pack_end (inner_box, true);
/*
* Stack
*/
Gtk.Stack stack = new Gtk.Stack ();
stack.set_transition_type (Gtk.StackTransitionType.SLIDE_UP);
stack.add_titled (new Gtk.Image.from_icon_name ("document-open", Gtk.IconSize.DND), "open", "Öffnen");
stack.add_titled (new Gtk.Image.from_icon_name ("document-save", Gtk.IconSize.DND), "save", "Speichern");
inner_box.pack_start (stack, true);
/*
* StackSidebar
*/
Gtk.StackSidebar ssidebar = new Gtk.StackSidebar ();
ssidebar.set_stack (stack);
primary_box.pack_start (ssidebar, false);
/*
* Ab hier Actionbar
*
* Näheres siehe letztes Tutorial.
*/
Gtk.ActionBar action_bar = new Gtk.ActionBar ();
// Linke Buttons
Gtk.Button left_button1 = new Gtk.Button.from_icon_name ("go-first", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_start (left_button1);
Gtk.Button left_button2 = new Gtk.Button.from_icon_name ("go-previous", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_start (left_button2);
// Rechte Buttons
Gtk.Button right_button1 = new Gtk.Button.from_icon_name ("go-last", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_end (right_button1);
Gtk.Button right_button2 = new Gtk.Button.from_icon_name ("go-next", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_end (right_button2);
// Mittlere Buttons
Gtk.Box secondary_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3);
Gtk.Button center_button1 = new Gtk.Button.from_icon_name ("zoom-original", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button1);
Gtk.Button center_button2 = new Gtk.Button.from_icon_name ("zoom-out", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button2);
Gtk.Button center_button3 = new Gtk.Button.from_icon_name ("zoom-in", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button3);
Gtk.Button center_button4 = new Gtk.Button.from_icon_name ("zoom-fit-best", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button4);
action_bar.set_center_widget (secondary_box);
inner_box.pack_end (action_bar, false);
window.add (primary_box);
window.show_all ();
}
}
int main (string[] args) {
return new Example ().run (args);
}</code></pre></figure>
<p>Das Ganze in einer Datei namens <code class="highlighter-rouge">stacksidebar.vala</code> abspeichern und mit</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">valac --pkg<span class="o">=</span>gtk+-3.0 stacksidebar.vala</code></pre></figure>
<p>kompilieren, fertig!</p>
<p>Viel Spaß damit!</p>
</description>
<pubDate>Fri, 10 Apr 2015 22:30:26 +0200</pubDate>
<link>http://www.philipp-trommler.me/2015/04/10/die-neue-gtk-3-16-stack-sidebar-in-vala.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2015/04/10/die-neue-gtk-3-16-stack-sidebar-in-vala.html</guid>
<category>gtk3</category>
<category>gtk</category>
<category>vala</category>
<category>stack</category>
<category>stacksidebar</category>
<media:thumbnail url="http://www.philipp-trommler.me/images/stacksidebar1.png" />
<enclosure url='http://www.philipp-trommler.me/images/stacksidebar1.png' length='13071' type='image/png' />
</item>
<item>
<title>Die GTK 3.12 ActionBar in Vala</title>
<description><p>Auch wenn es die <code class="highlighter-rouge">Gtk.ActionBar</code> schon seit GTK 3.12 und somit schon ein bisschen länger gibt, habe ich bisher kaum Anleitungen dazu im Internet gefunden und keine einzige für Vala. Daher möchte ich hiermit ein kleines Tutorial nachliefern, auch wenn sich die Verwendung eigentlich nicht sonderlich von einer <code class="highlighter-rouge">Gtk.Box</code> oder einer <code class="highlighter-rouge">Gtk.Toolbar</code> unterscheidet.</p>
<p>ActionBars sind eigentlich wie eine Toolbar, nur sollen sie kontextsensitiv verwendet werden und sich unter dem Widget befinden, für das sie zuständig sind. Die Unterschiede sind also eher semantisch. Die Benutzung erinnert stark an eine <code class="highlighter-rouge">Gtk.Box</code> mit horizontaler Ausrichtung, es werden also mit <code class="highlighter-rouge">pack_start ()</code> <code class="highlighter-rouge">Gtk.Widget</code>s an den linken Rand gesetzt, mit <code class="highlighter-rouge">pack_end ()</code> an den rechten. Zusätzlich kann aber noch <em>ein</em> <code class="highlighter-rouge">Gtk.Widget</code> mit <code class="highlighter-rouge">set_center_widget ()</code> mittig in die <code class="highlighter-rouge">Gtk.ActionBar</code> gesetzt werden, wobei mittig absolut gemeint ist, also unabhängig von Anzahl und Größe der <code class="highlighter-rouge">Gtk.Widget</code>s an den Seiten. Sollen in der Mitte mehrere <code class="highlighter-rouge">Gtk.Widget</code>s platziert werden, müssen diese vorher in einen <code class="highlighter-rouge">Gtk.Container</code> gepackt werden, also zum Beispiel in eine <code class="highlighter-rouge">Gtk.Box</code>.</p>
<figure>
<a href="/images/actionbar1.png">
<img src="/images/actionbar1.png" alt="GTK ActionBar Beispielanwendung." />
</a>
<figcaption>GTK ActionBar Beispielanwendung.</figcaption>
</figure>
<p>So habe ich es auch in meiner obligatorischen kleinen Beispielanwendung gemacht, die als Grundlage für einen minimalistischen Bildbetrachter fungieren könnte. Natürlich fehlt noch jegliche Logik im Beispiel, aber hier soll es ja auch nur um die Benutzung der <code class="highlighter-rouge">Gtk.ActionBar</code> gehen. Eingebaut habe ich das ganze wie immer in eine <code class="highlighter-rouge">Gtk.Application</code>.</p>
<figure class="highlight"><pre><code class="language-vala" data-lang="vala">class Example : Gtk.Application {
public Example () {
Object (application_id: "com.example.app", flags: ApplicationFlags.FLAGS_NONE);
}
protected override void activate () {
Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = true;
Gtk.ApplicationWindow window = new Gtk.ApplicationWindow (this);
window.set_default_size (500, 500);
window.set_title ("Actionbar");
/*
* Primäre Box
*/
Gtk.Box primary_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
/*
* Als Beispiel ein Bild
*/
Gtk.Image image = new Gtk.Image.from_icon_name ("document-open", Gtk.IconSize.DIALOG);
primary_box.pack_start (image);
/*
* Ab hier Actionbar
*/
Gtk.ActionBar action_bar = new Gtk.ActionBar ();
// Linke Buttons
Gtk.Button left_button1 = new Gtk.Button.from_icon_name ("go-first", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_start (left_button1);
Gtk.Button left_button2 = new Gtk.Button.from_icon_name ("go-previous", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_start (left_button2);
// Rechte Buttons
Gtk.Button right_button1 = new Gtk.Button.from_icon_name ("go-last", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_end (right_button1);
Gtk.Button right_button2 = new Gtk.Button.from_icon_name ("go-next", Gtk.IconSize.SMALL_TOOLBAR);
action_bar.pack_end (right_button2);
// Mittlere Buttons
Gtk.Box secondary_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3);
Gtk.Button center_button1 = new Gtk.Button.from_icon_name ("zoom-original", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button1);
Gtk.Button center_button2 = new Gtk.Button.from_icon_name ("zoom-out", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button2);
Gtk.Button center_button3 = new Gtk.Button.from_icon_name ("zoom-in", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button3);
Gtk.Button center_button4 = new Gtk.Button.from_icon_name ("zoom-fit-best", Gtk.IconSize.SMALL_TOOLBAR);
secondary_box.pack_start (center_button4);
action_bar.set_center_widget (secondary_box);
primary_box.pack_end (action_bar, false);
window.add (primary_box);
window.show_all ();
}
}
int main (string[] args) {
return new Example ().run (args);
}</code></pre></figure>
<p>Einfach als <code class="highlighter-rouge">actionbar.vala</code> abspeichern und wie immer mit</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">valac --pkg gtk+-3.0 -o actionbar actionbar.vala</code></pre></figure>
<p>kompilieren. Ich hoffe, ich konnte denjenigen unter euch, denen das Nachlesen im Valadoc manchmal nicht reicht, ein bisschen helfen, und wünsche viel Spaß mit den ActionBars!</p>
</description>
<pubDate>Sun, 22 Mar 2015 13:14:20 +0100</pubDate>
<link>http://www.philipp-trommler.me/2015/03/22/die-gtk-3-12-actionbar-in-vala.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2015/03/22/die-gtk-3-12-actionbar-in-vala.html</guid>
<category>gtk3</category>
<category>gtk</category>
<category>vala</category>
<category>actionbar</category>
<media:thumbnail url="http://www.philipp-trommler.me/images/actionbar1.png" />
<enclosure url='http://www.philipp-trommler.me/images/actionbar1.png' length='11555' type='image/png' />
</item>
<item>
<title>RSS 2.0 Enclosure-Tag Plugin für Jekyll</title>
<description><p>Da ich in den letzten Tagen meinen Blog auf Jekyll umgebaut habe, habe ich mich natürlich auch mit dem von Jekyll erzeugten RSS-Feed auseinandergesetzt. Dabei fiel mir auf, dass Bilder nur im Lauftext eingebunden werden, also weder <code class="highlighter-rouge">&lt;media:thumbnail …&gt;</code> noch <code class="highlighter-rouge">&lt;enclosure …&gt;</code> Tags hinzugefügt werden.</p>
<p>Während erstere noch recht einfach mittels</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;media:thumbnail</span> <span class="na">url=</span><span class="s">"{{ post.images[0].url | prepend: site.baseurl | prepend: site.url }}"</span> <span class="nt">/&gt;</span></code></pre></figure>
<p>hinzugefügt werden können, sieht das ganze für <code class="highlighter-rouge">&lt;enclosure …&gt;</code> Tags schon etwas anders aus, da die Länge der Datei in Bytes und der Mime-Type zwingend benötigt werden. Da ich im Internet nichts dazu gefunden habe (erstaunlicherweise!), habe ich mir direkt mal daran versucht, ein Jekyll-Plugin zu schreiben. Es ist das erste Mal, dass ich etwas in Ruby geschrieben habe, ich bin also offen für alle Verbesserungsvorschläge. Ansonsten kann es natürlich gerne für die eigenen Zwecke verwendet werden!</p>
<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="nb">require</span> <span class="s2">"mimemagic"</span>
<span class="k">module</span> <span class="nn">Jekyll</span>
<span class="k">class</span> <span class="nc">RSSEnclosureTag</span> <span class="o">&lt;</span> <span class="no">Liquid</span><span class="o">::</span><span class="no">Tag</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">tag_name</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">tokens</span><span class="p">)</span>
<span class="k">super</span>
<span class="vi">@text</span> <span class="o">=</span> <span class="n">text</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">render</span><span class="p">(</span><span class="n">context</span><span class="p">)</span>
<span class="n">file</span> <span class="o">=</span> <span class="n">context</span><span class="p">[</span><span class="vi">@text</span><span class="p">]</span> <span class="o">||</span> <span class="vi">@text</span>
<span class="n">xml</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">baseurl</span> <span class="o">=</span> <span class="n">context</span><span class="p">.</span><span class="nf">registers</span><span class="p">[</span><span class="ss">:site</span><span class="p">].</span><span class="nf">config</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]</span> <span class="o">+</span> <span class="n">context</span><span class="p">.</span><span class="nf">registers</span><span class="p">[</span><span class="ss">:site</span><span class="p">].</span><span class="nf">baseurl</span>
<span class="k">if</span> <span class="no">File</span><span class="p">.</span><span class="nf">exist?</span><span class="p">(</span><span class="s2">"."</span> <span class="o">+</span> <span class="n">file</span><span class="p">)</span>
<span class="n">xml</span> <span class="o">&lt;&lt;</span> <span class="s2">"&lt;enclosure url='</span><span class="si">#{</span><span class="n">baseurl</span> <span class="o">+</span> <span class="n">file</span><span class="si">}</span><span class="s2">' length='</span><span class="si">#{</span><span class="no">File</span><span class="p">.</span><span class="nf">stat</span><span class="p">(</span><span class="s2">"."</span> <span class="o">+</span> <span class="n">file</span><span class="p">).</span><span class="nf">size</span><span class="si">}</span><span class="s2">' type='</span><span class="si">#{</span><span class="no">MimeMagic</span><span class="p">.</span><span class="nf">by_magic</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="s2">"."</span> <span class="o">+</span> <span class="n">file</span><span class="p">))</span><span class="si">}</span><span class="s2">' /&gt;"</span>
<span class="k">end</span>
<span class="n">xml</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Liquid</span><span class="o">::</span><span class="no">Template</span><span class="p">.</span><span class="nf">register_tag</span><span class="p">(</span><span class="s1">'rss_enclosure'</span><span class="p">,</span> <span class="no">Jekyll</span><span class="o">::</span><span class="no">RSSEnclosureTag</span><span class="p">)</span></code></pre></figure>
<p>Eingebunden wird das ganze dann mit</p>
<figure class="highlight"><pre><code class="language-liquid" data-lang="liquid"><span class="p">{%</span><span class="w"> </span><span class="nt">rss_enclosure</span><span class="w"> </span>{{<span class="w"> </span>post.images[<span class="mi">0</span>].url<span class="w"> </span>}}<span class="w"> </span><span class="p">%}</span></code></pre></figure>
<p>in der <code class="highlighter-rouge">feed.xml</code>. Offensichtlich wird das <code class="highlighter-rouge">mimemagic</code>-Gem benötigt, ansonsten sollte alles so funktionieren, zumindest tut es das für mich.</p>
<p>Ich frage vorher noch ab, ob der Beitrag überhaupt ein Bild enthält, sodass sich insgesamt folgender Code ergibt:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml">{% if post.images %}
<span class="nt">&lt;media:thumbnail</span> <span class="na">url=</span><span class="s">"{{ post.images[0].url | prepend: site.baseurl | prepend: site.url }}"</span> <span class="nt">/&gt;</span>
{% rss_enclosure {{ post.images[0].url }} %}
{% endif %}</code></pre></figure>
<p>Viel Spaß damit!</p>
</description>
<pubDate>Thu, 12 Mar 2015 12:45:27 +0100</pubDate>
<link>http://www.philipp-trommler.me/2015/03/12/rss-2-0-enclosure-tag-plugin-fur-jekyll.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2015/03/12/rss-2-0-enclosure-tag-plugin-fur-jekyll.html</guid>
<category>ruby</category>
<category>rss</category>
<category>jekyll</category>
<category>enclosure-tag</category>
</item>
<item>
<title>Das Ende des XML-Experiments</title>
<description><p>Vor etwas über einem Jahr habe ich meinen Blog gestartet. Zugegeben, allzu viel ist seitdem nicht passiert. Das liegt weniger daran, dass es nichts zu berichten gäbe, als viel mehr an meiner knappen Zeit. Es gibt allerdings noch viele Dinge, zu denen ich hier kleine Tutorials schreiben möchte (zum einen für die Leser, zum anderen aber auch für mich als Gedächtnisstütze), doch zuvor musste etwas an meinem Blog selbst erledigt werden.</p>
<h1 id="warum-xml">Warum XML?</h1>
<p>Wie man (hoffentlich nicht allzu sehr) merken konnte, hatte ich die vorige Version meines Blogs mit XML und XSLT realisiert. Doch warum das ganze? Ich kam im ersten Semester meines Informatikstudiums zum ersten Mal mit XSLT in Kontakt. Obwohl ich XML schon lange kannte, offenbarte dieser neue Ansatz einige interessante Möglichkeiten, insbesondere, da ich immer auf der Suche nach möglich minimalen Lösungen für meine Probleme bin.</p>
<p>Jekyll kannte ich zu dieser Zeit noch nicht und dynamische Blogs mit PHP und Konsorten kamen für meine kleinen Vorhaben nicht in Frage. Also entschloss ich mich, meine Blogposts als XML-Dateien zu verfassen und diese dann mit XSLT durch den Browser in HTML umformen zu lassen. Bis hierhin auch durchaus ein machbarer Plan, der zu guten und sauberen Ergebnissen führt. Die Postings bilden eine Textdatenbank, die mit <code class="highlighter-rouge">.dtd</code>s validiert werden kann, mit etwas penibler Arbeit sieht das erzeugte HTML aus wie von Hand geschrieben und wenn noch CSS ins Spiel kommt, sind Inhalt, Markup und Style wirklich so perfekt voneinander getrennt, wie man sich das nur wünschen kann. Doch wehe man will mehr!</p>
<h1 id="probleme">Probleme</h1>
<p>Die ersten Probleme traten auf, als ich die Seite mit Chrome unter Android getestet habe. Scheinbar zufällig schien der Browser (zumindest in der damals aktuellen Version) sich nicht mehr sicher zu sein, ob er für das Öffnen von <code class="highlighter-rouge">.xml</code>-Dateien auch wirklich zuständig ist, und zeigte den Android-typischen ‘Öffnen mit’-Dialog. Wenn das auch nur ein kleineres Problem ist, macht es auf einen eventuellen Besucher doch einen recht zwilichtigen Eindruck. Mit Firefox auf Android oder Desktop-Browsern habe ich dieses Problem im Übrigen nie erlebt.</p>
<p>Wirklich interessant wird es aber erst, wenn man es wagt, XML und XSLT in Verbindung mit SEO und Social-Media zu bringen. Es ist völlig unergründlich, nach welchen Kriterien Google &amp; Co. entscheiden, welche Meta-Informationen einer Webseite sie aus XML, XSLT oder dem generierten HTML ziehen. So fängt man an, die eigentlich schöne Trennung von Inhalt und Markup Stück für Stück aufzugeben und da sich selbst die Tools eines Herstellers teilweise unterschiedlich verhalten, müssen manche Informationen so gar doppelt angegeben werden:</p>
<ol>
<li>Alle OpenGraph-Elemente für Facebook müssen in die XML-Datei, ebenso die schema.org Informationen für Google.</li>
<li><code class="highlighter-rouge">icon</code>, <code class="highlighter-rouge">apple-touch-icon</code> und die Icons für Windows-Live-Kacheln müssen sowohl in die XML- als auch in die XSLT-Datei, da sich die Browser nicht so ganz einig sind, woher sie diese Information beziehen.</li>
</ol>
<p>Hat man diese beiden Klippen umschifft, ist aber noch nicht alles in trockenen Tüchern, da Facebook seine Snippets für die Darstellung in der Timeline aus dem XML ausliest und Google meistens (!) auch. Also müssen die in der selbst erstellten DTD definierten XML-Tags die gleichen Namen tragen wie die entsprechenden HTML-Tags. Man hat nun also HTML-Tags in einer XML-Datei, die mit einer XSLT-Datei (die HTML enthält) zu einer HTML-Datei umgewandelt wird. Eine wirkliche Trennung findet nun eigentlich schon nicht mehr statt. Als kleines Beispiel hier mal mein <a href="/2013/05/08/desktop-verknupfungen-einfach-gemacht-mit-menulibre.html">MenuLibre-Post</a> als XML:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="cp">&lt;?xml-stylesheet type="text/xsl" href="../xsl/article.xsl"?&gt;</span>
<span class="cp">&lt;!DOCTYPE article SYSTEM "http://philipp.feige-trommler.de/dtd/article.dtd"&gt;</span>
<span class="nt">&lt;article</span> <span class="na">itemscope=</span><span class="s">""</span> <span class="na">itemtype=</span><span class="s">"http://schema.org/BlogPosting"</span> <span class="na">prefix=</span><span class="s">"og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#"</span><span class="nt">&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:title"</span> <span class="na">content=</span><span class="s">"Desktop-Verknüpfungen einfach gemacht mit MenuLibre - Philipp Trommler - Blog"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">itemprop=</span><span class="s">"description"</span> <span class="na">property=</span><span class="s">"og:description"</span> <span class="na">content=</span><span class="s">"Wer außer mir auch denkt, dass es jedes Mal eine Qual ist, 'Desktop-Entries' zu schreiben - einfach weil man es so selten macht und deswegen die benötigten Teile jedes Mal aufs neue vergessen hat und ergoogeln muss - der sollte sich MenuLibre von Sean Davis genauer ansehen. Es ist kostenlos, über sein PPA erhältlich und macht die Menü-Bearbeitung zu einer wahren Freude."</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:type"</span> <span class="na">content=</span><span class="s">"article"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">itemprop=</span><span class="s">"datePublished"</span> <span class="na">property=</span><span class="s">"article:published_time"</span> <span class="na">content=</span><span class="s">"2013-05-08T07:08:00+02"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"article:author"</span> <span class="na">content=</span><span class="s">"philipp.trommler"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"article:section"</span> <span class="na">content=</span><span class="s">"Technology"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"article:tag"</span> <span class="na">content=</span><span class="s">"Tutorial"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"article:publisher"</span> <span class="na">content=</span><span class="s">"philipp.trommler"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"fb:admins"</span> <span class="na">content=</span><span class="s">"philipp.trommler"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"fb:profile_id"</span> <span class="na">content=</span><span class="s">"philipp.trommler"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">itemprop=</span><span class="s">"thumbnailUrl"</span> <span class="na">property=</span><span class="s">"og:image"</span> <span class="na">content=</span><span class="s">"http://philipp.feige-trommler.de/images/articles/menulibre1.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">itemprop=</span><span class="s">"url"</span> <span class="na">property=</span><span class="s">"og:url"</span> <span class="na">content=</span><span class="s">"http://philipp.feige-trommler.de/articles/desktop_verknupfungen_einfach_menulibre.xml"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">itemprop=</span><span class="s">"inLanguage"</span> <span class="na">property=</span><span class="s">"og:locale"</span> <span class="na">content=</span><span class="s">"de_DE"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">property=</span><span class="s">"og:site_name"</span> <span class="na">content=</span><span class="s">"Philipp Trommler - Blog"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;time</span> <span class="na">datetime=</span><span class="s">"2013-05-08T07:08:00+02"</span><span class="nt">&gt;</span>Wed, 08 May 2013 07:08 +0200<span class="nt">&lt;/time&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"alternate"</span> <span class="na">type=</span><span class="s">"application/rss+xml"</span> <span class="na">title=</span><span class="s">"RSS"</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/rss.xml"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"57x57"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-57x57.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"72x72"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-72x72.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"76x76"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-76x76.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"114x114"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-114x114.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"144x144"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-144x144.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"152x152"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-152x152.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon-precomposed"</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/../apple-touch-icon-152x152.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">href=</span><span class="s">"../ico32.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"shortcut icon"</span> <span class="na">type=</span><span class="s">"image/x-icon"</span> <span class="na">href=</span><span class="s">"../favicon.ico"</span><span class="nt">/&gt;</span>
<span class="c">&lt;!--[if IE]&gt;&lt;link rel="shortcut icon" type="image/vnd.microsoft.icon" href="../favicon.ico"/&gt;&lt;![endif]--&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"application-name"</span> <span class="na">content=</span><span class="s">" "</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-TileColor"</span> <span class="na">content=</span><span class="s">"#cddc39"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square70x70logo"</span> <span class="na">content=</span><span class="s">"../tiny.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square150x150logo"</span> <span class="na">content=</span><span class="s">"../square.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-wide310x150logo"</span> <span class="na">content=</span><span class="s">"../wide.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square310x310logo"</span> <span class="na">content=</span><span class="s">"../large.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-notification"</span> <span class="na">content=</span><span class="s">"frequency=30;polling-uri=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=1;polling-uri2=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=2;polling-uri3=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=3;polling-uri4=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=4;polling-uri5=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=5; cycle=1"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"canonical"</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/articles/desktop_verknupfungen_einfach_menulibre.xml"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;author&gt;</span>Philipp Trommler<span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"https://plus.google.com/+PhilippTrommler"</span> <span class="na">rel=</span><span class="s">"author"</span><span class="nt">/&gt;&lt;/author&gt;</span>
<span class="nt">&lt;title&gt;</span>Desktop-Verknüpfungen einfach gemacht mit MenuLibre - Philipp Trommler - Blog<span class="nt">&lt;/title&gt;</span>
<span class="nt">&lt;h3</span> <span class="na">itemprop=</span><span class="s">"headline"</span><span class="nt">&gt;</span>Desktop-Verknüpfungen einfach gemacht mit MenuLibre<span class="nt">&lt;/h3&gt;</span>
<span class="nt">&lt;text</span> <span class="na">itemprop=</span><span class="s">"articleBody"</span><span class="nt">&gt;</span>
<span class="nt">&lt;p&gt;</span>Wer außer mir auch denkt, dass es jedes Mal eine Qual ist, 'Desktop-Entries' zu schreiben - einfach weil man es so selten macht und deswegen die benötigten Teile jedes Mal aufs neue vergessen hat und ergoogeln muss - der sollte sich <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"https://launchpad.net/menulibre"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>MenuLibre<span class="nt">&lt;/a&gt;</span> von Sean Davis genauer ansehen. Es ist kostenlos, über sein PPA erhältlich und macht die Menü-Bearbeitung zu einer wahren Freude.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"../images/articles/menulibre1.png"</span> <span class="na">alt=</span><span class="s">"MenuLibre in Lubuntu 13.04"</span> <span class="na">height=</span><span class="s">"800"</span> <span class="na">width=</span><span class="s">"1280"</span><span class="nt">&gt;</span>
<span class="nt">&lt;caption&gt;</span>MenuLibre in Lubuntu 13.04<span class="nt">&lt;/caption&gt;</span>
<span class="nt">&lt;/img&gt;</span>
<span class="nt">&lt;p&gt;</span>Die Benutzung ist genauso einfach wie sie auf den ersten Blick scheint, alle wichtigen Einstellungen einer 'DesktopEntry' sind über die grafische Benutzeroberfläche erreichbar, inklusive der Quicklists für Unity. Wer volle Kontrolle über die erzeugte Datei benötigt, kann über den eingebauten Editor der Verknüpfung den letzten Schliff verpassen.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p&gt;</span>Die Installation ist wie gewohnt einfach, der Autor stellt ein regelmäßig mit Updates versorgtes PPA bereit:<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">"warning"</span><span class="nt">&gt;</span>Achtung: PPAs können ein potentielles Sicherheitsrisiko darstellen! Fügen Sie sie deswegen nur hinzu, wenn Sie dem Besitzer vertrauen.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;code</span> <span class="na">lang=</span><span class="s">"bash"</span><span class="nt">&gt;</span><span class="cp">&lt;![CDATA[sudo add-apt-repository ppa:menulibre-dev/devel
sudo apt-get update
sudo apt-get install menulibre]]&gt;</span><span class="nt">&lt;/code&gt;</span>
<span class="nt">&lt;/text&gt;</span>
<span class="nt">&lt;/article&gt;</span></code></pre></figure>
<p>Auffällig ist vor allem, wie klein nur der Anteil des eigentlichen Texts ist (auch wenn es zugegebenermaßen ein kurzer Post ist). Auch hässliche Krücken wie <code class="highlighter-rouge">&lt;![CDATA[…]]&gt;</code> muss man immer wieder bemühen. Schaut man sich außerdem nur den Textteil an, sieht man eigentlich schon reines HTML. Trotzdem hier noch das passende XSLT:</p>
<figure class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
<span class="nt">&lt;xsl:stylesheet</span> <span class="na">version=</span><span class="s">"1.0"</span> <span class="na">xmlns:xsl=</span><span class="s">"http://www.w3.org/1999/XSL/Transform"</span><span class="nt">&gt;</span>
<span class="nt">&lt;xsl:output</span> <span class="na">method=</span><span class="s">"html"</span> <span class="na">doctype-system=</span><span class="s">"about:legacy-compat"</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"article"</span><span class="nt">&gt;</span>
<span class="c">&lt;!--[if lt IE 7 ]&gt;&lt;html class="ie ie6" lang="de"&gt; &lt;![endif]--&gt;</span>
<span class="c">&lt;!--[if IE 7 ]&gt;&lt;html class="ie ie7" lang="de"&gt; &lt;![endif]--&gt;</span>
<span class="c">&lt;!--[if IE 8 ]&gt;&lt;html class="ie ie8" lang="de"&gt; &lt;![endif]--&gt;</span>
<span class="c">&lt;!--[if (gte IE 9)|!(IE)]&gt;&lt;!--&gt;</span><span class="nt">&lt;html</span> <span class="na">lang=</span><span class="s">"de"</span><span class="nt">&gt;</span> <span class="c">&lt;!--&lt;![endif]--&gt;</span>
<span class="nt">&lt;head&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">charset=</span><span class="s">"utf-8"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;title&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"title"</span><span class="nt">/&gt;&lt;/title&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"description"</span><span class="nt">&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"content"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"text/p"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;/meta&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"author"</span> <span class="na">content=</span><span class="s">"Philipp Trommler"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"viewport"</span> <span class="na">content=</span><span class="s">"width=device-width, initial-scale=1, maximum-scale=1"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"../stylesheets/base.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"../stylesheets/skeleton.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"../stylesheets/layout.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"../stylesheets/custom.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"../stylesheets/jquery.lazyloadxt.spinner.min.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.1/styles/github.min.css"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"alternate"</span> <span class="na">type=</span><span class="s">"application/rss+xml"</span> <span class="na">title=</span><span class="s">"RSS"</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/rss.xml"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"57x57"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-57x57.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"72x72"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-72x72.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"76x76"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-76x76.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"114x114"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-114x114.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"144x144"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-144x144.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon"</span> <span class="na">sizes=</span><span class="s">"152x152"</span> <span class="na">href=</span><span class="s">"../apple-touch-icon-152x152.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"apple-touch-icon-precomposed"</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/../apple-touch-icon-152x152.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"icon"</span> <span class="na">type=</span><span class="s">"image/png"</span> <span class="na">href=</span><span class="s">"../ico32.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"shortcut icon"</span> <span class="na">type=</span><span class="s">"image/x-icon"</span> <span class="na">href=</span><span class="s">"../favicon.ico"</span><span class="nt">/&gt;</span>
<span class="c">&lt;!--[if IE]&gt;&lt;link rel="shortcut icon" type="image/vnd.microsoft.icon" href="../favicon.ico"/&gt;&lt;![endif]--&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"application-name"</span> <span class="na">content=</span><span class="s">" "</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-TileColor"</span> <span class="na">content=</span><span class="s">"#cddc39"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square70x70logo"</span> <span class="na">content=</span><span class="s">"../tiny.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square150x150logo"</span> <span class="na">content=</span><span class="s">"../square.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-wide310x150logo"</span> <span class="na">content=</span><span class="s">"../wide.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-square310x310logo"</span> <span class="na">content=</span><span class="s">"../large.png"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;meta</span> <span class="na">name=</span><span class="s">"msapplication-notification"</span> <span class="na">content=</span><span class="s">"frequency=30;polling-uri=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=1;polling-uri2=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=2;polling-uri3=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=3;polling-uri4=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=4;polling-uri5=http://notifications.buildmypinnedsite.com/?feed=http://philipp.feige-trommler.de/rss.xml&amp;amp;id=5; cycle=1"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;link</span> <span class="na">rel=</span><span class="s">"canonical"</span><span class="nt">&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"href"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"link/@href"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;/link&gt;</span>
<span class="c">&lt;!--[if lt IE 9]&gt;
&lt;script src="http://html5shim.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;
&lt;![endif]--&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"../js/jquery.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"../js/jquery.lazyloadxt.extra.min.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"../js/highlight.pack.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">"text/javascript"</span> <span class="na">src=</span><span class="s">"../js/jquery.socialshareprivacy.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;script</span> <span class="na">type=</span><span class="s">"text/javascript"</span><span class="nt">&gt;</span>
function showDisqus () {
var disqus_shortname = 'phtrommlerblog';
var disqus_identifier = '<span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"h3"</span><span class="nt">/&gt;</span>';
var disqus_title = '<span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"h3"</span><span class="nt">/&gt;</span>';
var disqus_url = '<span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"link/@href"</span><span class="nt">/&gt;</span>';
var dsq = document.createElement('script');
dsq.type = 'text/javascript';
dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName ('head')[0] || document.getElementsByTagName ('body')[0]).appendChild (dsq);
}
jQuery(document).ready(function($){
var d = new Date('<span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"time"</span><span class="nt">/&gt;</span>');
document.getElementById ('date').innerHTML = d.toLocaleString ();
$('.block').each(function(i, e) {hljs.highlightBlock(e)});
if($('#socialshareprivacy').length &gt; 0){
$('#socialshareprivacy').socialSharePrivacy({
'services' : {
facebook: {
'dummy_img' : '../images/socialshareprivacy/dummy_facebook.png',
'sharer' : {
'status' : 'on',
'dummy_img' : '../images/socialshareprivacy/dummy_facebook_share_de.png',
'img' : '../images/socialshareprivacy/facebook_share_de.png'
}
},
twitter : {
'dummy_img' : '../images/socialshareprivacy/dummy_twitter.png'
},
gplus : {
'dummy_img' : '../images/socialshareprivacy/dummy_gplus.png'
}
},
'uri' : '<span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"link/@href"</span><span class="nt">/&gt;</span>',
'css_path' : '../stylesheets/socialshareprivacy.css',
'lang_path' : '../js/lang/',
'language' : 'de',
'alignment' : 'vertical'
});
}
});
<span class="nt">&lt;/script&gt;</span>
<span class="nt">&lt;/head&gt;</span>
<span class="nt">&lt;body&gt;</span>
<span class="nt">&lt;script</span> <span class="na">src=</span><span class="s">"//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"container"</span><span class="nt">&gt;</span>
<span class="nt">&lt;header&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"two-thirds column"</span><span class="nt">&gt;</span>
<span class="nt">&lt;h1</span> <span class="na">class=</span><span class="s">"remove-bottom"</span> <span class="na">style=</span><span class="s">"margin-top: 40px"</span><span class="nt">&gt;</span>Philipp Trommler<span class="nt">&lt;/h1&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;nav</span> <span class="na">class=</span><span class="s">"one-third column"</span><span class="nt">&gt;&lt;a</span> <span class="na">href=</span><span class="s">"../index.html"</span><span class="nt">&gt;</span>Home<span class="nt">&lt;/a&gt;</span> <span class="ni">&amp;#183;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"../projects.html"</span><span class="nt">&gt;</span>Projekte<span class="nt">&lt;/a&gt;</span> <span class="ni">&amp;#183;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"../blog.xml"</span><span class="nt">&gt;&lt;h2&gt;</span>Blog<span class="nt">&lt;/h2&gt;&lt;/a&gt;</span> <span class="ni">&amp;#183;</span> <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"../about.html"</span><span class="nt">&gt;</span>Über mich<span class="nt">&lt;/a&gt;&lt;/nav&gt;</span>
<span class="nt">&lt;/header&gt;</span>
<span class="nt">&lt;main&gt;</span>
<span class="nt">&lt;h3&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"h3"</span><span class="nt">/&gt;&lt;/h3&gt;</span>
<span class="nt">&lt;xsl:apply-templates</span> <span class="na">select=</span><span class="s">"text"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"date-author"</span><span class="nt">&gt;</span>Verfasst: <span class="nt">&lt;span</span> <span class="na">id=</span><span class="s">"date"</span><span class="nt">&gt;&lt;/span&gt;&lt;span&gt;</span> von <span class="nt">&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"author"</span><span class="nt">/&gt;&lt;/span&gt;&lt;/span&gt;</span>
<span class="nt">&lt;hr</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"one-third column"</span><span class="nt">&gt;</span>
<span class="nt">&lt;h5&gt;</span>Social Media<span class="nt">&lt;/h5&gt;</span>
<span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">"warning"</span><span class="nt">&gt;</span>Wenn Sie diese Felder durch einen Klick aktivieren, werden Informationen an Facebook, Twitter oder Google in die USA übertragen und unter Umständen auch dort gespeichert. Näheres erfahren Sie durch einen Klick auf das i.<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"socialshareprivacy"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"two-thirds column"</span> <span class="na">id=</span><span class="s">"disqus"</span><span class="nt">&gt;</span>
<span class="nt">&lt;h5&gt;</span>Kommentare<span class="nt">&lt;/h5&gt;</span>
<span class="nt">&lt;p</span> <span class="na">class=</span><span class="s">"warning"</span><span class="nt">&gt;</span>Durch das Aktivieren der Kommentarfunktion werden Daten an Dritte (Disqus) weitergegeben. Aktivieren Sie die Kommentarfunktion nur, wenn Sie sich darüber im Klaren und damit einverstanden sind!<span class="nt">&lt;/p&gt;</span>
<span class="nt">&lt;label</span> <span class="na">class=</span><span class="s">"switch switch-green"</span> <span class="na">onClick=</span><span class="s">"showDisqus ()"</span><span class="nt">&gt;</span>
<span class="nt">&lt;input</span> <span class="na">id=</span><span class="s">"disqus_switch"</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">class=</span><span class="s">"switch-input"</span><span class="nt">/&gt;</span>
<span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"switch-label"</span> <span class="na">data-on=</span><span class="s">"An"</span> <span class="na">data-off=</span><span class="s">"Aus"</span><span class="nt">&gt;&lt;/span&gt;</span>
<span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">"switch-handle"</span><span class="nt">&gt;&lt;/span&gt;</span>
<span class="nt">&lt;/label&gt;&lt;span</span> <span class="na">class=</span><span class="s">"switch-text"</span><span class="nt">&gt;</span>Kommentarfunktion von Disqus<span class="nt">&lt;/span&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"disqus_thread"</span><span class="nt">&gt;&lt;/div&gt;</span>
<span class="nt">&lt;noscript&gt;</span>Please enable JavaScript to view the <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://disqus.com/?ref_noscript"</span><span class="nt">&gt;</span>comments powered by Disqus.<span class="nt">&lt;/a&gt;&lt;/noscript&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/main&gt;</span>
<span class="nt">&lt;footer&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"one-third column"</span><span class="nt">&gt;</span>
<span class="nt">&lt;ul&gt;</span>
<span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">"http://philipp.feige-trommler.de/rss.xml"</span> <span class="na">class=</span><span class="s">"rss"</span><span class="nt">&gt;&lt;/a&gt;&lt;/li&gt;</span>
<span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">"https://www.facebook.com/philipp.trommler"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">class=</span><span class="s">"facebook"</span><span class="nt">&gt;&lt;/a&gt;&lt;/li&gt;</span>
<span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">"https://plus.google.com/+PhilippTrommler"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">class=</span><span class="s">"googleplus"</span><span class="nt">&gt;&lt;/a&gt;&lt;/li&gt;</span>
<span class="nt">&lt;li&gt;&lt;a</span> <span class="na">href=</span><span class="s">"http://www.youtube.com/channel/UCGG3f6yZH4gndb1HXRCqipw"</span> <span class="na">target=</span><span class="s">"_blank"</span> <span class="na">class=</span><span class="s">"youtube"</span><span class="nt">&gt;&lt;/a&gt;&lt;/li&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"one-third column"</span><span class="nt">&gt;</span>
Webseite erstellt mit <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.getskeleton.com/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>Skeleton<span class="nt">&lt;/a&gt;</span>, <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"https://jquery.org/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>jQuery<span class="nt">&lt;/a&gt;</span>, <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.heise.de/ct/artikel/2-Klicks-fuer-mehr-Datenschutz-1333879.html"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>2 Klicks für mehr Datenschutz<span class="nt">&lt;/a&gt;</span>, <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://highlightjs.org/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>highlight.js<span class="nt">&lt;/a&gt;</span> und <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.graphicsfuel.com/2012/09/15-free-social-media-icons-psd-png/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>Icons von Rafi<span class="nt">&lt;/a&gt;</span> sowie Switches von <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.cssflow.com/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>Thibaut Courouble<span class="nt">&lt;/a&gt;</span>.<span class="nt">&lt;br</span> <span class="nt">/&gt;</span>
Die Schriftarten <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.fontsquirrel.com/license/ubuntu-mono"</span> <span class="na">rel=</span><span class="s">"license"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>'Ubuntu Mono'<span class="nt">&lt;/a&gt;</span> und <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://www.fontsquirrel.com/license/fira-sans"</span> <span class="na">rel=</span><span class="s">"license"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>'Fira Sans'<span class="nt">&lt;/a&gt;</span> stehen unter der SIL Open Font License, die <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://socicon.com/"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>'Socicon'<span class="nt">&lt;/a&gt;</span>-Social-Media-Icons ebenfalls.
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"one-third column"</span><span class="nt">&gt;</span>
Alle Bilder und auf dieser Website stehen, soweit nicht anders angegeben, unter <span class="nt">&lt;a</span> <span class="na">rel=</span><span class="s">"license"</span> <span class="na">href=</span><span class="s">"http://creativecommons.org/licenses/by-sa/4.0/deed.de"</span> <span class="na">target=</span><span class="s">"_blank"</span><span class="nt">&gt;</span>CC-BY-SA 4.0 International Lizenz<span class="nt">&lt;/a&gt;</span>. Dies gilt nicht für die Social-Media-Icons.<span class="nt">&lt;br/&gt;&lt;br/&gt;</span>
<span class="ni">&amp;#169;</span> 2014 Philipp Trommler, zum <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"../impressum.html"</span><span class="nt">&gt;</span>Impressum<span class="nt">&lt;/a&gt;</span> und der <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"../daten.html"</span><span class="nt">&gt;</span>Datenschutzerklärung<span class="nt">&lt;/a&gt;</span>.
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/footer&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"h4"</span><span class="nt">&gt;</span>
<span class="nt">&lt;h4&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"."</span><span class="nt">/&gt;&lt;/h4&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"p"</span><span class="nt">&gt;</span>
<span class="nt">&lt;p&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"class"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@class"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:apply-templates/&gt;&lt;/p&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"inlinecode"</span><span class="nt">&gt;</span>
<span class="nt">&lt;pre</span> <span class="na">class=</span><span class="s">"inline"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"."</span><span class="nt">/&gt;&lt;/pre&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"a"</span><span class="nt">&gt;</span>
<span class="nt">&lt;a&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"href"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@href"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"target"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@target"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"."</span><span class="nt">/&gt;&lt;/a&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"b"</span><span class="nt">&gt;</span>
<span class="nt">&lt;b&gt;&lt;xsl:apply-templates/&gt;&lt;/b&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"ol"</span><span class="nt">&gt;</span>
<span class="nt">&lt;ol&gt;&lt;xsl:apply-templates/&gt;&lt;/ol&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"li"</span><span class="nt">&gt;</span>
<span class="nt">&lt;li&gt;&lt;xsl:apply-templates/&gt;&lt;/li&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"code"</span><span class="nt">&gt;</span>
<span class="nt">&lt;pre&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"class"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@lang"</span><span class="nt">/&gt;</span> block<span class="nt">&lt;/xsl:attribute&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"."</span><span class="nt">/&gt;&lt;/pre&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;xsl:template</span> <span class="na">match=</span><span class="s">"img"</span><span class="nt">&gt;</span>
<span class="nt">&lt;figure&gt;</span>
<span class="nt">&lt;img</span> <span class="na">class=</span><span class="s">"lazy scale-with-grid"</span><span class="nt">&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"data-src"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@src"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"alt"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@alt"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"height"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@height"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"width"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@width"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;/img&gt;</span>
<span class="nt">&lt;noscript&gt;&lt;img</span> <span class="na">class=</span><span class="s">"scale-width-grid"</span><span class="nt">&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"src"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@src"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"alt"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@alt"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"height"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@height"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;xsl:attribute</span> <span class="na">name=</span><span class="s">"width"</span><span class="nt">&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"@width"</span><span class="nt">/&gt;&lt;/xsl:attribute&gt;&lt;/img&gt;&lt;/noscript&gt;</span>
<span class="nt">&lt;figcaption&gt;&lt;xsl:value-of</span> <span class="na">select=</span><span class="s">"caption"</span><span class="nt">/&gt;&lt;/figcaption&gt;</span>
<span class="nt">&lt;/figure&gt;</span>
<span class="nt">&lt;/xsl:template&gt;</span>
<span class="nt">&lt;/xsl:stylesheet&gt;</span></code></pre></figure>
<p>Wie man sieht, ist diese Methode also alles in allem wenig effizient und meiner eigentlichen Suche nach einer möglichst minimalen Lösung wohl kaum gerecht.</p>
<h1 id="vorteile">Vorteile?</h1>
<p>Kaum.</p>
<p>Aber trotzdem habe ich das Verfahren zu schätzen gelernt. Es nutzt offene, altbewährte und gut unterstützte Standards und man hat jederzeit volle Kontrolle über das was passiert. Es gibt keine Blackbox, keine Magie (<code class="highlighter-rouge">@Autowired</code> bei Spring <em>hust</em>) und nur ein leicht zu überschauendes Set an Möglichkeiten. Und für spezielle Einsatzmöglichkeiten reicht das auch vollkommen aus. So habe ich beruflich bereits einen in XML vorliegenden Bibliotheksbestand in eine einfache, durchsuchbare und übersichtliche Webseite umgewandelt, ohne dass bei jeder Änderung am Bestand auch die Seite geändert werden müsste. Für genau solche Szenarien eignet sich XSLT auch heute noch sehr gut, für die von mir gedachte Realisierung eines Blogs rückwirkend betrachtet weniger.</p>
<h1 id="jekyll">Jekyll</h1>
<p>Genau deswegen habe ich jetzt (solange ich noch so wenige Posts habe) meinen Blog auf <a href="http://jekyllrb.com/">Jekyll</a> umgestellt und ich muss sagen, es gefällt mir sehr gut. Auch wenn mir als nicht Ruby-Nutzer die Einarbeitung in die Gems (Builder, Bundler, Gems?) und das Installieren von Plugins ein paar Kopfschmerzen bereitet haben, fällt die Bedienung insgesamt doch recht einfach aus und auch das Standard-Theme ist durchaus als Grundlage brauchbar.</p>
<p>Im Gegenzug habe ich mir mit Jekyll eine Blackbox eingefangen, die allerdings so gut und einfach zu bedienen ist, dass ich diesmal damit Leben werde.</p>
</description>
<pubDate>Tue, 10 Mar 2015 13:00:00 +0100</pubDate>
<link>http://www.philipp-trommler.me/2015/03/10/das-ende-des-xml-experiments.html</link>
<guid isPermaLink="true">http://www.philipp-trommler.me/2015/03/10/das-ende-des-xml-experiments.html</guid>
<category>tools</category>
<category>xml</category>
<category>xslt</category>
<category>jekyll</category>
<category>seo</category>
<category>social-media</category>
</item>
<item>
<title>Intel® Cilk™ mit GCC 4.9 unter Linux</title>
<description><p>Mit der aktuellen (beziehungsweise in Ubuntu kommenden) Version 4.9 der GNU Compiler Collection GCC hält auch Intels® Multithreading Werkzeug Cilk™ Einzug in den C- und C++-Compiler. Mit Cilk™ soll es (unter anderem) äußerst einfach sein, die Last von Programmen gleichmäßig auf alle verfügbare Prozessorkerne zu verteilen.</p>
<h1 id="vorbereitungen">Vorbereitungen</h1>
<p>Um Cilk™ mit Ubuntu nutzen zu können, bedarf es Vorbereitung, da es, wie der Titel es schon vermuten lässt, erst ab Version 4.9 in den Compilern enthalten ist. Diese Version wird wohl aber erst unter Ubuntu 14.10 zum Standard werden, also muss GCC auf eine der folgenden Weisen aktualisiert werden:</p>
<ul>
<li>Aus den Quellen kompilieren, wobei ich hierauf nicht weiter eingehen möchte, da der Aufwand nur zum Testen von Cilk™ zu hoch und unnötig und die Vorgehensweise ausreichend im Internet dargelegt ist.</li>
<li>Über das Ubuntu Toolchain PPA installieren.</li>
</ul>
<p>Das PPA kann mittels <code class="highlighter-rouge">sudo add-apt-repository ppa:ubuntu-toolchain-r/test</code> ins System eingepflegt werden, anschließend werden mit dem Befehl <code class="highlighter-rouge">sudo apt-get install gcc-4.9 g++-4.9</code> die Compiler installiert. In den deb-Paketen scheint allerdings noch eine Datei zu fehlen, die somit manuell angelegt werden muss, also mit <code class="highlighter-rouge">sudo nano /usr/lib/libcilkrts.spec</code> die Datei öffnen und folgendes einfügen:</p>
<figure class="highlight"><pre><code class="language-bash" data-lang="bash">This spec file is <span class="nb">read </span>by gcc when linking. It is used to specify the
<span class="c"># standard libraries we need in order to link with libcilkrts.</span>
<span class="k">*</span>link_cilkrts: /usr/lib/gcc/i686-linux-gnu/4.9/libcilkrts.so</code></pre></figure>
<p>Der Pfad zur Shared Library muss auf 64-bit Systemen entsprechend angepasst werden. Damit sollte die Installation eigentlich abgeschlossen sein (einfacher als GCC selbst zu kompilieren, oder?).</p>
<h1 id="tests">Tests</h1>
<p>Um die Performance von Cilk™ unter Linux zu messen, bediene ich mich der Beispiele, die Intel® <a href="http://www.cilkplus.org/cilk-plus-tutorial">auf den entsprechenden Webseiten</a> angibt. Als erstes das Fibonacci-Beispiel, mit dem sich <code class="highlighter-rouge">cilk_spawn</code> und <code class="highlighter-rouge">cilk_sync</code> für rekursive Algorithmen testen lässt:</p>
<figure class="highlight"><pre><code class="language-cpp" data-lang="cpp"><span class="cp">#include &lt;iostream&gt;
#include &lt;cilk/cilk.h&gt;
#include &lt;cilk/cilk_api.h&gt;