-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
893 lines (787 loc) · 32.2 KB
/
index.html
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
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>CKEditor in Drupal 8 – The New Possibilities</title>
<meta name="description" content="">
<meta name="author" content="Wiktor Walc">
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="src/reveal/css/reveal.min.css">
<link rel="stylesheet" href="css/sky.css" id="theme">
<link rel="stylesheet" href="css/custom.css">
<!-- For syntax highlighting -->
<!--<link rel="stylesheet" href="src/reveal/lib/css/zenburn.css">-->
<link rel="stylesheet" href="css/github.css">
<!-- If the query includes 'print-pdf', include the PDF print sheet -->
<script>
if (window.location.search.match(/print-pdf/gi)) {
// Default reveal print file
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'src/reveal/css/print/pdf.css';
document.getElementsByTagName('head')[0].appendChild(link);
// Custom print file
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'css/pdf.css';
document.getElementsByTagName('head')[0].appendChild(link);
}
</script>
<!--[if lt IE 9]>
<script src="src/reveal/lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<div class="slides">
<section data-background="images/amsterdam_big.jpg" data-background-size="2100px" class="drupalcon">
<div>
<div style="height:250px;padding-top: 20px">
<img src="images/amsterdam_logo.png" style="width:420px" alt="DrupalCon Amsterdam Logo" />
</div>
<h1 style="color:#FFFFFF">CKEditor in Drupal 8</h1>
<div class="redbox">
Wiktor Walc
</div>
<h5>Site Building – September 30, 2014</h5>
</div>
</section>
<section>
<h2>About Me</h2>
<ul style="margin-top: 1em">
<li>CKEditor Module Maintainer for Drupal 6/7</li>
<li>
<p>CTO @ <img src="images/cksource_logo.png" width="160" style="margin-bottom: 0px" /></p>
<p><img src="images/ckeditor_logo.png" width="400" style="padding: 1em;margin-left:100px" /></p>
</li>
</ul>
</section>
<section>
<h1>Agenda</h1>
<ul>
<li>The status of WYSIWYG editing in Drupal 7</li>
<li>New features offered by CKEditor & Text Editor modules</li>
<li>What is ACF and how it works</li>
<li>Widgets: why use them and what they offer</li>
<li>Widgets: the new image plugin in Drupal 8</li>
<li>Adding plugins to CKEditor</li>
<li>Security: HTML Filter vs. ACF</li>
<li>Migration</li>
</ul>
</section>
<section>
<section>
<h2>Drupal 7</h2>
<p><img src="images/drupal7_plain_textarea.png" alt="Default editor in Drupal 7 (plain textarea)." /></p>
</section>
<section>
<h2 style="display:none">☹</h2>
<img src="images/crying_baby_1024.jpg" alt="crying baby" />
<p class="copyrights"><a href="https://www.flickr.com/photos/donnieray/10584676434">https://www.flickr.com/photos/donnieray/10584676434</a></p>
</section>
<section>
<h2>Drupal 7</h2>
<ul>
<li>Contributed modules: <a href="https://www.drupal.org/project/wysiwyg">WYSIWYG</a> and <a href="https://www.drupal.org/project/ckeditor">CKEditor</a></li>
<li class="fragment">Together <strong>575 000</strong> installations in Drupal 7</li>
<li class="fragment" style="list-style-type:none;margin-top:1em;margin-bottom:1em"><strong>Awesome! But...</strong></li>
<li class="fragment" style="margin-top:1em">
<p>Research</p>
<ul>
<li>Which module to use?</li>
<li>Which editor to use?</li>
<li>What distribution of editor to use?</li>
</ul>
</li>
<li class="fragment">Installation, testing, configuration</li>
<li class="fragment">Maintenance (updating, etc.)</li>
</ul>
</section>
<section>
<h3>...and</h3>
<p class="left">Popular WTFs</p>
<ul>
<li><cite><em>Images are lost after saving node</em></cite> (CKEditor Toolbar vs. Text format configuration mismatch)</li>
<li>Confusion: installed CKEditor module but need to download CKEditor (the editor)? o_O</li>
</ul>
</section>
</section>
<section>
<h2>Drupal 8</h2>
<ul>
<li class="fragment">CKEditor in core. No need to search, test, install.</li>
<li class="fragment">
<p>575 000 x 1.5h = 860 000h available for fun ☺</p>
<p class="fragment" style="text-align:center"><img src="images/meme-x-all-the-y.jpg" alt="Yes!!" width="500" /></p>
</li>
</ul>
</section>
<section>
<section>
<h2>Drupal 8</h2>
<ul>
<li>Select text editor straight in "Text formats and editors" administration page</li>
<li>Drag & drop toolbar configurator for CKEditor</li>
<li>HTML filter settings automatically updated</li>
<li>Nice API for registering additional CKEditor plugins, enhancing CKEditor configuration form</li>
</ul>
</section>
<section>
<h2>Demo #1</h2>
<p>How CKEditor toolbar configuration triggers an automatic update of Allowed HTML tags list</p>
</section>
<!--
<section class="video-description">
<h2>Video #1</h2>
<p>Basic HTML text format is configured:</p>
<ul>
<li>CKEditor button (Table) is added to the toolbar using D&D</li>
<li>Allowed HTML tags list is automatically updated with <table>, <tr>, <th>, <td> tags</li>
<li>Another button (Underline) is added using D&D to the toolbar</li>
<li><u> is automatically added to Allowed HTML tags list</li>
<li>The Underline button is removed from toolbar</li>
<li><u> is automatically removed from Allowed HTML tags list</li>
<li>The Styles dropdown is added using D&D</li>
<li>A configuration tab for the Styles plugin is immediately shown</li>
<li>After defining styles for <h2> and <h3>, the entered configuration is immediately picked up and the list of allowed HTML tags is again extended</li>
</ul>
</section>
-->
<section>
<video width="920" height="628" src="videos/text_format_configuration1.mp4" controls data-autoplay>
</video>
</section>
<section>
<h2>Demo #2</h2>
<p>How automatic update of Allowed HTML tags list works when buttons (features) are removed</p>
</section>
<!--
<section class="video-description">
<h2>Video #2</h2>
<p>Basic HTML text format is configured again:</p>
<ul>
<li>Strike button is added to the toolbar</li>
<li><s> is automatically added to Allowed HTML tags list</li>
<li>The form with text format configuration is saved</li>
<li>An article with striked text (<s> tag) is created</li>
<li>Basic HTML text format is configured again</li>
<li>Strike button is removed from CKEditor toolbar</li>
<li>This time <s> tag is not removed automatically because it could have been used in existing content</li>
<li>An article is edited again in CKEditor</li>
<li>Altough Strike button is no longer available in CKEditor toolbar, <s> tag is not removed</li>
</ul>
</section>
-->
<section>
<video width="920" height="628" src="videos/text_format_configuration2.mp4" controls data-autoplay></video>
</section>
</section>
<section>
<section>
<h3>ACF <small>(Advanced Content Filter)</small></h3>
</section>
<section>
<h3>ACF strips <s>unwanted content</s></h3>
<img src="images/bieber_mugshot.jpg" alt="Justin Bieber mug shot" />
<p class="copyrights">Source: Miami-Dade Police Department</p>
</section>
<section>
<h3>ACF <small>(Advanced Content Filter)</small></h3>
<ul>
<li>Everything that is not allowed is removed</li>
<li>Works also when pasting content – WYSIWYG!
<p><small>No need to submit form and wait for the server-side filter to remove disallowed tags to see the final markup</small></p></li>
<li>Smart (transformations - stripping tags, not content)</li>
</ul>
</section>
<section>
<p>Switching text formats? Remember about ACF</p>
<img src="images/changing_text_format.png" width="310" height="229" alt="Warning when switching text formats" />
</section>
<section>
<h2>Demo #3</h2>
<p>Live example of how ACF works on different text formats</p>
</section>
<!--
<section class="video-description">
<h2>Video #3</h2>
<p>Results of pasting content in different text formats:</p>
<ul>
<li>CKEditor is enabled on Restricted HTML format</li>
<li>An article is created with Restricted HTML text format</li>
<li>In CKEditor source mode <script> and <footer> are pasted</li>
<li>After switching to WYSIWYG mode, both disallowed tags are gone but content of a footer is kept</li>
<li>Part of an HTML page with headers and a table is copied and pasted in Google Chrome; both tags are disallowed in this format</li>
<li>ACF removes disallowed tags, but again the content from headers and table cells is preserved</li>
<li>The format of article is changed to Basic HTML</li>
<li>The same content is pasted again; this time tables and headers are not removed because we allow it in this format</li>
<li>Font colors are disallowed, however, so inline styles are removed by CKEditor</li>
</ul>
</section>
<section class="video-description">
<p>Results of pasting content in different text formats (continued)</p>
<ul>
<li>The format of article is changed to Full HTML.</li>
<li>The same content is pasted again; this time nothing is removed because ACF is disabled here.</li>
<li>The same portion of the HTML page is copied & pasted in Firefox.</li>
<li>Even though ACF is disabled, the font color isn't copied. Why? Because browsers are different: Firefox copies just the HMTL structure, while Chrome copies HTML and "the layout". Need consistency? Use ACF.</li>
</ul>
</section>
-->
<section>
<video width="920" height="628" src="videos/acf.mp4" controls data-autoplay></video>
</section>
</section>
<section>
<section>
<h2>Editing possibilities</h2>
<ul>
<li>Classic editor</li>
<li>Inline editor</li>
</ul>
</section>
<section>
<h2>Administration backend</h2>
<h3>"Classic" editor</h3>
<ul>
<li><iframe> – based</li>
<li>CSS-styles are <strong>not</strong> inherited from admin theme</li>
<li>Themes may register dedicated stylesheet for CKEditor through an entry in their .info file:
</li>
</ul>
<p class="code">
<pre><code class="no-highlight">ckeditor_stylesheets:
- css/ckeditor-iframe.css</code></pre>
</p>
</section>
<section>
<p class="pdf-only">Classic editor in action, note the CSS styles in WYSIWYG area:</p>
<img src="images/classic_editor.png" class="standalone-img" alt="Classic editor in Drupal 8"/>
</section>
<section>
<h2>Quick editing</h2>
<h3>"Inline" editor</h3>
<ul>
<li>No <iframe>!</li>
<li>CSS-styles are inherited; the content looks exactly the same both in editor and on website.</li>
<li class="fragment">Real WYSIWYG, finally!</li>
</ul>
</section>
<section>
<p class="pdf-only">Handy quick edit option in Drupal 8:</p>
<img src="images/node_with_quickedit_link.png" class="standalone-img" alt="Linkt to quick editing in Drupal 8" />
</section>
<section>
<p class="pdf-only">Editing node using quick edit feature:</p>
<img src="images/quickedit.png" class="standalone-img" alt="Quick editing in Drupal 8" />
<p class="pdf-only">Note that CSS styles did not change!</p>
</section>
</section>
<section>
<section>
<h2>Styling content</h2>
<ul>
<li>CSS style definitions set in themes' CSS files</li>
<li>Selected style definitions (using CSS classes) available in Styles dropdown list</li>
<li>Separate: semantic markup and visual presentation</li>
<li>Handy: consistent styling, less work overall</li>
</ul>
</section>
<section>
<h2>Inline styles?</h2>
<p class="morespace">How to enable <em>Text/Background Color</em> buttons in Drupal 8?</p>
<ul class="fragment">
<li>CKEditor in Drupal Core != CKEditor "Full" preset</li>
<li class="fragment">But... additional plugins might be added!
<p style="text-align:center">
<img src="images/extend-ckeditor.png" alt="Administration interface with checkboxes to enable additional modules" width="697" height="356" class="fragment"/>
</p>
</li>
</ul>
</section>
<section>
<p class="pdf-only">Enabled Color buttons in Full HTML text format:</p>
<img src="images/full_html_colors.png" class="standalone-img" alt="Full HTML toolbar with color buttons" />
</section>
<section>
<img src="images/saurians3.jpg" alt="Funny web page - example" />
<p class="copyrights"><a href="http://angels-heaven.org">http://angels-heaven.org</a></p>
</section>
</section>
<section>
<h1>Widgets</h1>
<ul>
<li>Introduced in CKEditor 4.3 (2013 Q4, exactly a year ago).</li>
<li><strong>Rich content units</strong> that act as a <strong>single entity</strong>.</li>
<li>Any CKEditor plugin can provide widgets thanks to the <a href="http://ckeditor.com/addon/widget">Widget plugin</a>.</li>
</ul>
</section>
<section>
<section>
<h2>Widgets <small>vs</small> Templates</h2>
</section>
<section>
<h2>Templates</h2>
<ul>
<li>HTML snippets that behave like normal HTML after being pasted into editor.</li>
<li><strong>No control</strong> – easy to break, delete part of the content.</li>
<li>No Drag & Drop support.</li>
<li>By default not available in Drupal 8<sup><a href="#fn1" id="r1">*</a></sup>.</li>
</ul>
<p id="fn1" class="footnote"><a href="#r1">*</a> Any plugin that inserts complicated HTML structure suffers from the same issues as the template plugin.</p>
</section>
<section>
<h2>Templates in action</h2>
<img src="images/templates.png" alt="Templates dialog window in CKEditor">
</section>
<section>
<h2>Sample template</h2>
<img src="images/templates2.png" alt="Image and Title template inserted in CKEditor" width="455" height="312">
</section>
<section>
<h2>Common issues</h2>
<img src="images/templates7.png" alt="Table in the middle of title" />
<br style="displa:block;margin: 10px 0;">
<img src="images/templates6.png" alt="Case with deleted image and orphaned title." />
</section>
<section>
<h2>Solution?</h2>
</section>
<section>
<h2>Widgets!</h2>
<ul style="text-align: left">
<li class="fragment">Select, copy, paste and delete as a whole.</li>
<li class="fragment">Drag and drop as a whole.</li>
<li class="fragment">Editable parts (with separate ACF rules!).</li>
<li class="fragment">Upcasting & downcasting to a simpler data format.</li>
<li class="fragment">Common dialog, context menu. Consistent look and feel.</li>
<li style="margin-top: 1em;list-style-type: none" class="fragment">Perfect UX. Bulletproof. Powerful.</li>
</ul>
<p class="footer"></p>
</section>
<section>
<h2>Simple Box Widget</h2>
<img src="images/simplebox5.png" alt="Simple Box Widget in CKEditor"/>
<p><strong>Tutorial: </strong> <a href="http://docs.ckeditor.com/#!/guide/widget_sdk_tutorial_1">Creating CKEditor Widget</a></p>
</section>
</section>
<section>
<h1>Widget examples</h1>
</section>
<section>
<section>
<h2>Video #4</h2>
<p>New Image Plugin in Drupal</p>
</section>
<section>
<video width="920" height="628" src="videos/image.mp4" controls data-autoplay>
</video>
</section>
<section>
<h2>Downcasted image</h2>
<p>"Data" form saved in a database:</p>
<pre><code class="html"><img alt="JavaScript Logo"
data-align="right"
data-caption="JavaScript Logo"
data-editor-file-uuid="8025f271-1db8-45cb-9400-f166c4683495"
height="220"
src="/sites/default/files/inline-images/JavaScript-logo.png"
width="220" /></code></pre>
</section>
<section>
<h2>Upcasted image:</h2>
<p></p>
<pre><code class="xml"><div class="align-right cke_widget_block ..." contenteditable="false">
--------------------------------------------------------------------
<figure class="caption caption-img" data-widget="image" ... >
<img alt="JavaScript Logo"
height="220"
src="/sites/default/files/inline-images/JavaScript-logo.png"
width="220" >
<figcaption contenteditable="true">JavaScript Logo</figcaption>
</figure>
--------------------------------------------------------------------
<span class="cke_widget_drag_handler_container ...">...</span>
</div></code></pre>
</section>
<section>
<h2>FilterCaption</h2>
<p>FilterCaption filter in Drupal scans for images with <code>data-caption</code> attribute and wraps them with:</p>
<pre><code><figure class="caption caption-img {{ classes }}">
{{ img }}
<figcaption>{{ caption }}</figcaption>
</figure></code></pre>
</section>
<section>
<table style="width:700px">
<tr><td rowspan="6" style="width:140px"><span class="ckeditor270">CKEditor</span><span class="drupal270">Drupal</span></td><td></td></tr>
<tr><td><pre><code><figure>
<img src="...">
<figcaption></figcaption>
</figure></code></pre>
</td></tr>
<tr><td><span>⇡ Upcasting</span><span style="float:right">Downcasting ⇣</span></td></tr>
<tr><td><pre><code><img src="..." data-caption="..."></code></pre></td></tr>
<tr><td style="text-align: center;border-top:1px dotted #999;padding-top:10px"><span>FilterCaption ⇣</span></td></tr>
<tr><td><pre><code><figure>
<img src="...">
<figcaption></figcaption>
</figure></code></pre></td></tr>
</table>
</section>
</section>
<section>
<section>
<h2>MathJax</h2>
<img src="images/mathjax.png" alt="Matematic formulas in CKEditor"/>
<br />
<img src="images/mathjax2.png" alt="Matematic formulas in CKEditor - source mode"/>
</section>
<section>
<table style="width:850px" class="narrow">
<tr>
<td><pre><code class="xml">(MathJax is run)
<span class="math-tex" data-cke-widget-data="...">
<iframe>
<script src="MathJax.js?config=TeX-AMS_HTML"></script>
...
<span id="preview"> LaTeX formula </span>
</iframe>
</span></code></pre></td>
</tr>
<tr>
<td style="position:relative;height: 3em">
<!-- Kudos for @vokiel for providing this list! :) -->
<ul style="list-style-type: none;width: 100%;">
<li style="margin-left: 0.5em;float: left;display: inline-block;margin-top: 1em;">Upcast ⇢ Init ⇢ Data</li>
<li style="float:left; display: inline-block;margin-left: -1.4em;">⇡</li>
<li style="float:right; display: inline-block;margin: 1em 0.6em 0 0;">Downcasting⇣</li>
<li style="margin-left: 1.8em;clear: both;">⇡</li>
</ul>
</tr>
<tr>
<td><pre><code class="xml"><span class="math-tex"> LaTeX formula </span></code></pre></td>
</tr>
</table>
</section>
</section>
<section>
<section>
<h2>Code Snippet</h2>
<img src="images/codesnippet.png" alt="CodeSnippet in CKEditor"/>
<br />
<img src="images/codesnippet3.png" alt="Code Snippet in CKEditor - source mode" />
</section>
<section>
<table class="narrow">
<tr>
<td><pre><code class="xml" style="overflow:hidden">(HighLightJS is run)
<pre data-cke-widget-data="...">
<code class="language-php hljs">
(*highlighted* code)
<span class="hljs-function"><span class="hljs-keyword">function</span>
<span class="hljs-title">isEmpty</span><span class="hljs-params">
( object ) </span> {</span>...
</code>
</pre></code></pre></td>
</tr>
<tr>
<td style="position:relative;height: 3em">
<!-- Kudos for @vokiel for providing this list! :) -->
<ul style="list-style-type: none;width: 100%;">
<li style="margin-left: 0.5em;float: left;display: inline-block;margin-top: 1em;">Upcast ⇢ Init ⇢ Data</li>
<li style="float:left; display: inline-block;margin-left: -1.4em;">⇡</li>
<li style="float:right; display: inline-block;margin: 1em 0.6em 0 0;">Downcasting⇣</li>
<li style="margin-left: 1.8em;clear: both;">⇡</li>
</ul>
</tr>
<tr>
<td><pre><code class="xml"><pre><code class="language-php"> some code </code></pre></code></pre></td>
</table>
</section>
</section>
<section>
<section>
<h2>Chart</h2>
<img src="images/chart.png" alt="Chart in CKEditor"/>
<br />
<img src="images/chart2.png" alt="Chart - source code" />
</section>
<section>
<table class="narrow">
<tr>
<td><pre><code class="xml">(Chart.js is run)
<div class="chartjs" data-chart="bar" data-chart-value="[{...(JSON)...}]">
[rendered chart]
-------------------------------------
<canvas></canvas>
<div class="chartjs-legend"></div>
-------------------------------------
</div></code></pre></td>
</tr>
<tr>
<td style="position:relative;height: 3em">
<!-- Kudos for @vokiel for providing this list! :) -->
<ul style="list-style-type: none;width: 100%;">
<li style="margin-left: 0.5em;float: left;display: inline-block;margin-top: 1em;">Upcast ⇢ Init ⇢ Data</li>
<li style="float:left; display: inline-block;margin-left: -1.4em;">⇡</li>
<li style="float:right; display: inline-block;margin: 1em 0.6em 0 0;">Downcasting⇣</li>
<li style="margin-left: 1.8em;clear: both;">⇡</li>
</ul>
</tr>
<tr>
<td><pre><code class="xml"><div class="chartjs" data-chart="bar" data-chart-value="[{...(JSON)...}]"></div></code></pre></td>
</table>
</section>
</section>
<section>
<h2>Widgets – Summary</h2>
<ul>
<li class="fragment">Complex data structures that will not break</li>
<li class="fragment">Convenient solution for using JavaScript presentation libraries in CKEditor</li>
<li class="fragment">Save simple forms, render rich forms in WYSIWYG</li>
<li class="fragment">
<p>Save simple forms, transform using filters in Drupal:</p>
<ul>
<li>Possible to change the visual format of a data structure at any moment!</li>
</ul>
</li>
</ul>
</section>
<section>
<h2>Writing plugins</h2>
<ul>
<li>Adding new plugins (e.g. from <a href="http://ckeditor.com/addons/plugins/all" target="_blank">addons repository</a>)</li>
<li>Extending the list of configuration options</li>
</ul>
</section>
<section>
<section>
<h2>Adding new plugins</h2>
<ul>
<li class="fragment">
<p>CKEditor Addons repository:</p>
<a href="http://ckeditor.com/addons/plugins/all" target="_blank">http://ckeditor.com/addons/plugins/all</a>
</li>
<li class="fragment">
<p>Your own plugins:</p>
<ul>
<li><a href="http://docs.ckeditor.com/#!/guide/plugin_sdk_intro">CKEditor Plugin SDK</a> (tutorials!)</li>
<li><a href="http://docs.ckeditor.com/#!/guide/widget_sdk_intro">CKEditor Widget SDK</a> (tutorials!)</li>
</ul>
</li>
</ul>
</section>
<section>
<h3 style="font-size:1.7em">CKEditorPluginInterface</h3>
<p>(any plugin must implement)</p>
<ul class="interface-list">
<li>
<p><code>getDependencies(Editor $editor)</code></p>
<p>An array of required CKEditor plugins</p>
</li>
<li>
<p><code>getFile()</code></p>
<p>Path to plugin.js</p>
</li>
<li>
<p><code>getConfig(Editor $editor)</code></p>
<p>Configuration settings</p>
</li>
</ul>
</section>
<section>
<h3 style="font-size:1.7em">CKEditorPluginButtonsInterface</h3>
<p>(for plugins with toolbar buttons)</p>
<ul style="margin-top: 1em;width:700px">
<li><p>
<code class="interface">getButtons()</code> An array of buttons*
</p>
<ul style="margin-top: 1em;list-style-type:none">
<li>– <code>label</code></li>
<li>– <code>image, image_rtl</code> (icons)</li>
<li>...</li>
</ul>
</li>
</ul>
<p style="margin-top: 1em;">* list is used only in the administration backend.</p>
</section>
<section>
<h3 style="font-size:1.7em">CKEditorPluginConfigurableInterface</h3>
<p>(if you wish to provide settings form)</p>
<p class="left">
<code class="hook">settingsForm(array $form, ..., Editor $editor);</code></p>
<p style="margin-top:1em">
<img src="images/styles_configuration2.png" alt="Configuring styles for CKEditor" />
</p>
</section>
<section>
<h3 style="font-size:1.7em">CKEditorPluginContextualInterface</h3>
<p>(for plugins enabled under certain conditions)</p>
<ul style="margin-top: 1em;width:700px">
<li><p>
<code class="interface">isEnabled(Editor $editor)</code>
</p>
</li>
</ul>
</section>
<section>
<h3 class="no-text-transform">Namespace <a href="https://api.drupal.org/api/drupal/namespace/Drupal%21ckeditor/8" target="_blank">Drupal\ckeditor</a></h3>
<ul>
<li>
<p><a href="https://api.drupal.org/api/drupal/core%21modules%21ckeditor%21src%21CKEditorPluginInterface.php/interface/CKEditorPluginInterface/8" target="_blank">CKEditorPluginInterface</a></p>
<p>Example: <a href="https://github.com/wwalc/panelbutton">Panel Button</a></p>
</li>
<li>
<p><a href="https://api.drupal.org/api/drupal/core%21modules%21ckeditor%21src%21CKEditorPluginButtonsInterface.php/interface/CKEditorPluginButtonsInterface/8" target="_blank">CKEditorPluginButtonsInterface</a></p>
<p>Example: <a href="https://github.com/wwalc/colorbutton">Color Button</a></p>
</li>
<li>
<p><a href="https://api.drupal.org/api/drupal/core%21modules%21ckeditor%21src%21CKEditorPluginConfigurableInterface.php/interface/CKEditorPluginConfigurableInterface/8" target="_blank">CKEditorPluginConfigurableInterface</a></p>
<p>Example: <a href="https://github.com/drupal/drupal/blob/8.0.x/core/modules/ckeditor/src/Plugin/CKEditorPlugin/StylesCombo.php">Styles Combo</a></p>
</li>
<li>
<p><a href="https://api.drupal.org/api/drupal/core%21modules%21ckeditor%21src%21CKEditorPluginContextualInterface.php/interface/CKEditorPluginContextualInterface/8" target="_blank">CKEditorPluginContextualInterface</a></p>
<p>Example: <a href="https://github.com/wwalc/liststyle">List Style</a></p>
</li>
</ul>
</section>
</section>
<section>
<section>
<h2>Custom Configuration</h2>
</section>
<section>
<h3>Simple Hook</h3>
<p class="left">
<code class="hook"><a href="https://api.drupal.org/api/drupal/core!modules!editor!editor.api.php/function/hook_editor_js_settings_alter/8">hook_editor_js_settings_alter</a>(array &$settings)</code>
</p>
<ul style="margin-top:1em">
<li class="fragment">Allows setting any <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config">configuration option</a>.</li>
<li class="fragment">
<p>Including <strong>CKEditor skin</strong>:</p>
<p style="margin-top:1em"><a href="https://github.com/wwalc/moonocolor">Moono Color</a><br />a sample module with a skin for CKEditor in Drupal 8.</p>
</li>
</ul>
</section>
</section>
<section>
<h2>HTML Filter <small>vs.</small> ACF</h2>
<ul>
<li>HTML Filter enabled <-> ACF enabled</li>
<li>HTML Filter disabled <-> ACF disabled</li>
</ul>
<p style="margin-top:1em">Need HTML Filter disabled & ACF enabled?</p>
<pre><code data-trim contenteditable class="php">/**
* Implements hook_editor_js_settings_alter
* @param array $settings
*/
function mymodule_editor_js_settings_alter(array &$settings) {
if (empty($settings['editor']['formats']['full_html'])) {
return;
}
$full_html = &$settings['editor']['formats']['full_html'];
if ($full_html['editorSettings']['allowedContent'] === true) {
unset($full_html['editorSettings']['allowedContent']);
}
}</code></pre>
</section>
<section>
<h2>Security</h2>
<ul>
<li>Drupal stores content as is, which is a potential threat for WYSIWYG editors</li>
<li>ACF != security filter</li>
<li>XSS protection included: security filters (<code>TYPE_HTML_RESTRICTOR</code>) are run before content can be edited in WYSIWYG editor</li>
</ul>
</section>
<section>
<h2>Migrating from Drupal 7</h2>
<ul>
<li>No way to port CKEditor profiles from D7 automatically</li>
<li><a href="https://drupal.org/project/wysiwyg_linebreaks">wysiwyg_linebreaks</a> module for handling content that used auto-paragraph filter</li>
<li>Use Migrate API to port & transform content</li>
<li>Write plugins, widgets to allow editing custom markup</li>
</ul>
</section>
<section>
<h2>The End</h2>
<ul class="ghlinks">
<li>This presentation:<ul><li><a href="https://github.com/wwalc/ckeditor-in-drupal-8">https://github.com/wwalc/ckeditor-in-drupal-8</a></li></ul></li>
<li>Sample modules and plugins:<ul><li><a href="https://github.com/wwalc/colorbutton">https://github.com/wwalc/colorbutton</a></li>
<li><a href="https://github.com/wwalc/panelbutton">https://github.com/wwalc/panelbutton</a></li>
<li><a href="https://github.com/wwalc/colorbutton">https://github.com/wwalc/moonocolor</a></li>
<li><a href="https://github.com/wwalc/panelbutton">https://github.com/wwalc/liststyle</a></li>
<li><a href="https://github.com/wwalc/chart">https://github.com/wwalc/chart</a></li></ul></li>
</ul>
<p style="margin-top:1em">
Follow CKEditor on Twitter: <a href="https://twitter.com/ckeditor">@ckeditor</a>
</p>
<p>
Contact me: <a href="https://twitter.com/w_walc">@w_walc</a> • <a href="https://www.drupal.org/u/wwalc">wwalc</a>
</p>
</section>
<section data-background="images/amsterdam_big.jpg" data-background-size="2100px" class="drupalcon">
<div>
<div style="height:250px;padding-top: 20px">
<img src="images/amsterdam_logo.png" style="width:420px" alt="DrupalCon Amsterdam Logo" />
</div>
<h1 style="color:#FFFFFF">What did you think?</h1>
<div class="redbox evaluate">
Evaluate this session – amsterdam2014.drupal.org/schedule
</div>
<h4>Thank you!</h4>
</div>
</section>
</div>
</div>
<script src="src/reveal/lib/js/head.min.js"></script>
<script src="src/reveal/js/reveal.min.js"></script>
<script>
// Full list of configuration options available here:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
margin: 0.01,
height: 700,
width: 960,
// Backspace
keyboard: {
'08': 'prev',
'13': function() {
var video = document.querySelector('.present > video');
if (video) {
video.paused ? video.play() : video.pause();
}
}
},
theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
// Optional libraries used to extend on reveal.js
dependencies: [
// { src: 'src/reveal/plugin/markdown/marked.js', condition: function () {
// return !!document.querySelector('[data-markdown]');
// } },
// { src: 'src/reveal/plugin/markdown/markdown.js', condition: function () {
// return !!document.querySelector('[data-markdown]');
// } },
{ src: 'src/reveal/plugin/highlight/highlight.js', async: true, callback: function () {
hljs.initHighlightingOnLoad();
} },
// { src: 'src/reveal/plugin/zoom-js/zoom.js', async: true, condition: function () {
// return !!document.body.classList;
// } },
{ src: 'src/reveal/plugin/notes/notes.js', async: true, condition: function () {
return !!document.body.classList;
} }
]
});
</script>
</body>
</html>