-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.html
executable file
·682 lines (657 loc) · 33.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
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Migration's Missing Instruction Manual</title>
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/night.css">
<link rel="stylesheet" href="css/smith.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/zenburn.css">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
</head>
<body>
<div class="reveal">
<div class="slides">
<!-- Title -->
<section id="title" data-background="images/background.jpg" data-transition="none">
<div class="text-bg">
<h2>Migration's Missing Instruction Manual</h2>
</div>
<p>Drupal Camp Atlanta<br/><span class="small">November 10, 2018</span></p>
<p>Drupal Camp Chattanooga<br/><span class="small">June 8, 2019</span></p>
<p><a class="small-link" href="https://startinggravity.github.io/migration-presentation">https://startinggravity.github.io/migration-presentation</a></p>
<aside class="notes">
Welcome.
</aside>
</section>
<!-- intro -->
<section id="intro-jim" data-background="images/background.jpg" data-transition="none">
<h2>Jim Smith</h2>
<img src="images/jns.jpg" alt="Jim Smith">
<p>Freelance Drupal Developer<br/><span class="small">Oak Ridge</span></p>
<aside class="notes">
Jim: Introduction
</aside>
</section>
<section id="intro-derek" data-background="images/background.jpg" data-transition="none">
<h2>Derek Brownlee</h2>
<img src="images/derek.jpg" alt="Derek Brownlee">
<p>Drupal Developer<br/><span class="small">Oak Ridge National Lab</span></p>
<aside class="notes">
Derek: Introduction
</aside>
</section>
<section id="intro-ornl" data-background="images/background.jpg" data-transition="none">
<img src="images/ornl.jpg" alt="ORNL">
<p>Oak Ridge National Laboratory<br/><span class="small">https://www.ornl.gov</span></p>
<aside class="notes">
<p>Jim:</p>
<ul>
<li>ornl.gov</li>
<li>30,000 nodes, 1700 users, and 800 taxonomy terms</li>
<li>45 content types</li>
</ul>
</aside>
</section>
<!-- plan for this session -->
<section id="covered-1" data-background="images/background.jpg" data-transition="none">
<h2>Covered in this Session</h2>
<ol>
<li class="fragment">Basics of D7 to D8 migration</li>
<li class="fragment">Mistakes we made</li>
<li class="fragment">Helpful tips and tricks</li>
</ol>
<aside class="notes">
Derek: What we'll cover today
</aside>
</section>
<section id="covered-2" data-background="images/background.jpg" data-transition="none">
<h2>Not Covered in this Session</h2>
<ol>
<li class="fragment">Migrating from other CMSs</li>
<li class="fragment">Solutions for every migration problem</li>
</ol>
<aside class="notes">
Derek: What we'll cover today
</aside>
</section>
<!-- goals -->
<section id="goals-1" data-background="images/background.jpg" data-transition="none">
<h2>Goals of a Migration</h2>
<ol>
<li class="fragment">Make it complete</li>
<li class="fragment">Make it easy</li>
<li class="fragment">Make it reproducible</li>
</ol>
<aside class="notes">
Jim: Goals
</aside>
</section>
<section id="goals-2" data-background="images/background.jpg" data-transition="none">
<h2>Goals of a Migration</h2>
<ol>
<li class="strike">Make it complete</li>
<li class="strike">Make it easy</li>
<li>Make it reproducible</li>
</ol>
<aside class="notes">
Jim: Goals
</aside>
</section>
<!-- planning -->
<section id="planning-1" data-background="images/background.jpg" data-transition="none">
<h2>Plan. Plan. Plan.</h2>
<div class="float">
<img src="images/spreadsheet.png" alt="Migration Planning Spreadsheet">
</div>
<p class="small">source: drupal.org</p>
<aside class="notes">
Derek: There is no substitute for good planning.
</aside>
</section>
<section id="planning-2" data-background="images/background.jpg" data-transition="none">
<h2>Plan what?</h2>
<ul>
<li class="fragment">Content to move; content to ignore</li>
<li class="fragment">Content to restructure (e.g., move to paragraphs)</li>
<li class="fragment">Content to clean up (e.g., improve consistency)</li>
<li class="fragment">Improvements to content editor experience</li>
</ul>
<aside class="notes">
Derek: What you should consider in planning.
</aside>
</section>
<section id="planning-3" data-background="images/background.jpg" data-transition="none">
<h2>Don't Migrate</h2>
<ul>
<li class="fragment">Configuration, if you are making major architecture changes</li>
<li class="fragment">Content that no one sees</li>
<li class="fragment">Content from a small number of nodes when copy/paste is easier</li>
</ul>
<aside class="notes">
Jim: Don't migrate (copy/paste only works if content won't change before you go to prod)
</aside>
</section>
<section id="planning-4" data-background="images/background.jpg" data-transition="none">
<img src="images/mockup.png" class="stretch plain" alt="Mockup of new page">
<aside class="notes">
Derek: Remember that your task is to make this possible. Where is all of that content going to come from?
</aside>
</section>
<section id="planning-4" data-background="images/background.jpg" data-transition="none">
<img src="images/mockup-marked-up.png" class="stretch plain" alt="Mockup with fields highlighted">
<aside class="notes">
Derek: In this mockup we have a Directorate landing page with 6 pieces of information. What are these items like in the source? Are they used differently in the mockup? Don't even think about writing migration code until you've disected the mockup and know where each piece comes from.
</aside>
</section>
<section id="planning-5" data-background="images/background.jpg" data-transition="none">
<h2>Plan Migration Order</h2>
<ol>
<li>Configuration (optional)</li>
<li>Taxonomy Terms</li>
<li>Users</li>
<li>Files</li>
<li>Media Entities</li>
<li>Paragraphs</li>
<li>Nodes</li>
</ol>
<aside class="notes">
Jim: Plan your migration order
</aside>
</section>
<!-- migration basics -->
<section id="basics-1" data-background="images/background.jpg" data-transition="none">
<h2>Migration Steps</h2>
<div class="float">
<img src="images/migration-terms-1.png" alt="Migration Terms">
</div>
<aside class="notes">
Derek: Source and destination
</aside>
</section>
<section id="basics-2" data-background="images/background.jpg" data-transition="none">
<h2>Migration Steps</h2>
<div class="float">
<img src="images/migration-terms-4.png" alt="Migration Terms">
</div>
<aside class="notes">
Derek: Source and destination - types
</aside>
</section>
<section id="basics-3" data-background="images/background.jpg" data-transition="none">
<h2>Migration Steps</h2>
<div class="float">
<img src="images/migration-terms-2.png" alt="Migration Terms">
</div>
<aside class="notes">
Jim: Magic
</aside>
</section>
<section id="basics-4" data-background="images/background.jpg" data-transition="none">
<h2>Migration Steps</h2>
<div class="float">
<img src="images/migration-terms-3.png" alt="Migration Terms">
</div>
<aside class="notes">
Jim: Process
</aside>
</section>
<!-- modules -->
<section id="modules-core" data-background="images/background.jpg" data-transition="none">
<h2>Core Modules</h2>
<ul>
<li>Migrate</li>
<li>Migrate Drupal</li>
<li>Migrate Drupal UI</li>
</ul>
<aside class="notes">
<p>Derek:</p>
<ul>
<li>Migrate provides the underlying API for migrating configuration and content to Drupal 8.</li>
<li>Migrate Drupal provides the capabilities needed to migrate configuration and content.</li>
<li>Migrate Drupal UI provides a user interface.</li>
</ul>
</aside>
</section>
<section id="modules-contrib-1" data-background="images/background.jpg" data-transition="none">
<h2>Contrib Modules</h2>
<ul>
<li>Migrate Upgrade</li>
<li>Migrate Tools</li>
<li>Migrate Plus</li>
<li>Migrate Source CSV</li>
</ul>
<aside class="notes">
<p>Derek:</p>
<ul>
<li>Migrate Upgrade provides basic Drush support.</li>
<li>Migrate Tools provides Drush commands to migrate, rollback, reset status and view status.</li>
<li>Migrate Plus provides grouping migrations and additional process plugins.</li>
<li>Migrate Source CSV allows migrating content from a CSV file instead of a database.</li>
</ul>
</aside>
</section>
<section id="modules-contrib-2" data-background="images/background.jpg" data-transition="none">
<h2>Contrib Modules</h2>
<ul>
<li>Migrate Devel</li>
<li>Migrate Manifest</li>
<li>Migrate Run</li>
</ul>
<aside class="notes">
<p>Derek:</p>
<ul>
<li>Migrate Devel provides Drush command flag to print out debug information.</li>
<li>Migrate Manifest provides a Drush command for running template-based migrations using a manifest format. Split off of Migrate Plus (Have not used.)</li>
<li>Migrate Run is a fork of Migrate Tools and has no dependency on Migrate Plus. For CLI folks (Have not used.)</li>
</ul>
</aside>
</section>
<!-- metadata -->
<section id="yml-file-1" data-background="images/background.jpg" data-transition="none">
<h2>Migration YML File</h2>
<img src="images/yml-file.png" alt="Migration File">
<aside class="notes">
Jim: File
</aside>
</section>
<section id="yml-file-2" data-background="images/background.jpg" data-transition="none">
<h2><span class="small">Migration YML File:</span><br/>Metadata</h2>
<img src="images/yml_metadata.png" alt="Migration File">
<aside class="notes">
Jim: Metadata: Most of this is unimportant. Only the ID is required.
</aside>
</section>
<!-- source -->
<section id="yml-file-3" data-background="images/background.jpg" data-transition="none">
<h2>Source</h2>
<ul>
<li class="fragment">Source plugins fetch data from the source</li>
<li class="fragment">The source can be SQL database, CSV, JSON, XML or SOAP</li>
<li class="fragment">The plugin can come from core, a contrib module, or custom module</li>
</ul>
<aside class="notes">
Derek: Source
</aside>
</section>
<section id="yml-file-4" data-background="images/background.jpg" data-transition="none">
<h2><span class="small">Migration YML File:</span><br/>Source</h2>
<img class="stretch" src="images/yml_source.png" alt="Migration File">
<aside class="notes">
Derek: Source
</aside>
</section>
<!-- Process -->
<section id="yml-file-5" data-background="images/background.jpg" data-transition="none">
<h2>Process</h2>
<ul>
<li class="fragment">Process plugins can</li>
<ul>
<li class="fragment">Copy data</li>
<li class="fragment">Add default data</li>
<li class="fragment">Combine or extract data</li>
<li class="fragment">Skip data</li>
<li class="fragment">Pipe data to different fields</li>
<li class="fragment">Manipulate data</li>
</ul>
<li class="fragment">These plugins can be chained together</li>
</ul>
<aside class="notes">
Jim: Process
</aside>
</section>
<section id="yml-file-6" data-background="images/background.jpg" data-transition="none">
<h2><span class="small">Migration YML File:</span><br/>Process</h2>
<img class="stretch" src="images/yml_process.png" alt="Migration File">
<aside class="notes">
Jim: Process
</aside>
</section>
<!-- Destination -->
<section id="yml-file-6" data-background="images/background.jpg" data-transition="none">
<h2>Destination</h2>
<ul>
<li class="fragment">Destination plugins define the kind of Drupal entities to be created</li>
<li class="fragment">Content entities: Nodes, users, taxonomy terms, files</li>
<li class="fragment">Configuration entities: Content types and field definitions</li>
</ul>
<aside class="notes">
Derek: Destination
</aside>
</section>
<section id="yml-file-7" data-background="images/background.jpg" data-transition="none">
<h2><span class="small">Migration YML File:</span><br/>Destination</h2>
<img class="stretch" src="images/yml_destination.png" alt="Migration File">
<aside class="notes">
Derek: Destination
</aside>
</section>
<!-- more on the source -->
<section id="database-1" data-background="images/background.jpg" data-transition="none">
<h2>Connect to Database</h2>
<img class="stretch" src="images/settings.jpg" alt="settings.php">
<aside class="notes">
Jim: Connect to Database
</aside>
</section>
<section id="database-2" data-background="images/background.jpg" data-transition="none">
<h2>Connect to CSV</h2>
<p>Advantages:</p>
<ul>
<li>See all of the data at once</li>
<li>Edit, clean up the data</li>
<li>Use a custom query to combine data from different content types</li>
</ul>
<aside class="notes">
Jim: Connect to Database
</aside>
</section>
<!-- using YML files -->
<section data-background="images/background.jpg" data-transition="none">
<h2>Config Single Import</h2>
<img src="images/single_import.jpg" alt="Single Import">
<aside class="notes">
Derek: Migration definitions are written as YML config files, so use Configuration Management to import them into the site.
</aside>
</section>
<section data-background="images/background.jpg" data-transition="none">
<h2>Create a Module</h2>
<ul>
<li class="fragment">When you expect changes in your source before you go live</li>
<li class="fragment">If you need a custom plugin</li>
<li class="fragment">If you use a source other than a database</li>
</ul>
<aside class="notes">
<p>Derek:</p>
<ul>
<li>When your source is not static</li>
<li>When you're going to have to massage the data</li>
<li>When you cannot pull from the source using core plugins</li>
</ul>
</aside>
</section>
<section data-background="images/background.jpg" data-transition="none">
<h2>Using a Module</h2>
<ul>
<li>Don't forget to disable, then enable it each time you make a change</li>
</ul>
<aside class="notes">
Derek: Remember that we're dealing with config. So the database doesn't know about changes to code until the code is imported into the database. With a migration module these updates occur when we uninstall and then re-enable the module.
</aside>
</section>
<!-- Drush -->
<section id="drush-1" data-background="images/background.jpg" data-transition="none">
<h2>Use Drush</h2>
<ul>
<li class="fragment">Status: <em>drush ms</em></li>
<li class="fragment">Import: <em>drush mim</em></li>
<li class="fragment">Rollback: <em>drush mr</em></li>
<li class="fragment">Reset: <em>drush mrs</em></li>
</ul>
<aside class="notes">
Jim: Drush commands
</aside>
</section>
<section id="drush-2" data-background="images/background.jpg" data-transition="none">
<h2>Use Drush</h2>
<p>Single entity:<br/><em>drush mim my_nodes --idlist=1234</em></p>
<p>Small batch:<br/><em>drush mim my_nodes --limit=10</em></p>
<aside class="notes">
Jim: Drush command examples
</aside>
</section>
<!-- Sequel Pro -->
<section id="sequel-pro-1" data-background="images/background.jpg" data-transition="none">
<h2>Look at the Database</h2>
<img src="images/sequel-pro.jpg" alt="Sequel Pro">
<aside class="notes">
Derek: Sequel Pro
</aside>
</section>
<section id="sequel-pro-2" data-background="images/background.jpg" data-transition="none">
<h2>Look at the Database</h2>
<img src="images/migrate_file-table.jpg" alt="File table">
<aside class="notes">
Derek: file table
</aside>
</section>
<section id="sequel-pro-3" data-background="images/background.jpg" data-transition="none">
<h2>Message Tables</h2>
<img src="images/migrate_messages.jpg" alt="Sequel Pro">
<aside class="notes">
Derek: Migration Message tables
</aside>
</section>
<section id="sequel-pro-4" data-background="images/background.jpg" data-transition="none">
<img class="stretch" src="images/migrate_sequel_pro_nid.jpg" alt="idlist">
<aside class="notes">
Jim: Find a single node, use IDlist flag
</aside>
</section>
<!-- Migrate Devel -->
<section id="migrate-devel-1" data-background="images/background.jpg" data-transition="none">
<h2>Migrate Devel Module</h2>
<img src="images/debug_source.jpg" alt="Migrate Devel - source">
<aside class="notes">
Derek: Migrate Devel module allows you to see the arrays, best used when limiting to one or two items.
</section>
<section id="migrate-devel-2" data-background="images/background.jpg" data-transition="none">
<h2>Migrate Devel Module</h2>
<img src="images/debug_destination.jpg" alt="Migrate Devel - source">
<aside class="notes">
Derek: See the source and destination arrays.
</section>
<section id="migrate-devel-3" data-background="images/background.jpg" data-transition="none">
<h2>See Problems in the Array</h2>
<img class="stretch" src="images/migrate_null_array.jpg" alt="Array">
<aside class="notes">
Derek: Inspect an array, see problems.
</section>
<!-- more tips -->
<section id="tips-1" data-background="images/background.jpg" data-transition="none">
<h2>More Tips</h2>
<aside class="notes">
JIm: As promised... more tips
</aside>
</section>
<section id="tips-2" data-background="images/background.jpg" data-transition="none">
<h2>Let Drupal Help You</h2>
<p>CKEditor can clean up markup</p>
<img src="images/markup.png" alt="CKEditor">
<aside class="notes">
Jim: Let CKEditor clean up messy markup.
</aside>
</section>
<section id="tips-3" data-background="images/background.jpg" data-transition="none">
<h2>Dependencies</h2>
<img src="images/dependencies.png" alt="Dependencies">
<ul>
<li>Required: 100% of content must be migrated.</li>
<li>Optional: if there are no items from the dependent migration, the migration will still run.</li>
</ul>
<aside class="notes">
Derek: Specify required/optional dependencies
</aside>
</section>
<section id="tips-4" data-background="images/background.jpg" data-transition="none">
<h2>Comments</h2>
<p>Leave yourself notes, test iteratively.</p>
<img class="stretch" src="images/migrate_comment.jpg" alt="Comments">
<aside class="notes">
Jim: Keep track of what you're working on with comments.
</aside>
</section>
<section id="tips-5" data-background="images/background.jpg" data-transition="none">
<h2>Pseudo-fields</h2>
<p>Parse your data.</p>
<img class="stretch" src="images/pseudofield.png" alt="Pseudo-field">
<aside class="notes">
Derek: Pseudo-fields help you parse your data before moving to the intended field. Equivalent to temp variables in any programming language.
</aside>
</section>
<section id="tips-6" data-background="images/background.jpg" data-transition="none">
<h2>Pseudo-fields</h2>
<p>Parse your data.</p>
<img class="stretch" src="images/pseudofield-2.png" alt="Pseudo-field">
<aside class="notes">
Derek: Pseudo-fields help you parse your data before moving to the intended field.
</aside>
</section>
<section id="tips-7" data-background="images/background.jpg" data-transition="none">
<h2>Dummy Variables</h2>
<p>Overcome limitations of skip_on_empty.</p>
<img class="stretch" src="images/dummy_set.png" alt="Dummy variable">
<aside class="notes">
Jim: Limitation in skip_on_empty makes it fail in arrays.
</aside>
</section>
<section id="tips-8" data-background="images/background.jpg" data-transition="none">
<h2>Dummy Variables</h2>
<p>Overcome limitations of skip_on_empty.</p>
<img class="stretch" src="images/dummy_skip.png" alt="Dummy variable">
<aside class="notes">
Jim: Use skip_on_value with a dummy value.
</aside>
</section>
<section id="tips-9" data-background="images/background.jpg" data-transition="none">
<h2>Pantheon Timeout</h2>
<p>Use <em>--feedback</em> flag</p>
<img class="stretch" src="images/migrate_feedback.jpg" alt="Feedback">
<aside class="notes">
Jim: Prevent remote execution timeouts by using the feedback flag.
</aside>
</section>
<section id="tips-10" data-background="images/background.jpg" data-transition="none">
<h2>Lando Slowness</h2>
<p>Use "Airplane mode"</p>
<img class="stretch" src="images/migrate_airplane.jpg" alt="Airplane mode">
<aside class="notes">
Derek: Overcome Lando's slowness by disconnecting from the internet.
</aside>
</section>
<section id="tips-11" data-background="images/background.jpg" data-transition="none">
<h2>Lando Slowness</h2>
<p>Switch locations</p>
<img class="stretch" src="images/switch-location.png" alt="Switching locations">
<aside class="notes">
Derek: Easily switch between locations as needed.
</aside>
</section>
<section id="tips-12" data-background="images/background.jpg" data-transition="none">
<h2>TripMode</h2>
<p><span class="small">Keep everything else online</span></p>
<img class="stretch" src="images/TripMode.png" alt="TripMode app">
<p><span class="small">www.tripmode.ch</span></p>
<aside class="notes">
Derek: Poweruser tool. Limit data access on a per app basis.
</aside>
</section>
<section id="tips-13" data-background="images/background.jpg" data-transition="none">
<h2>Custom Plugins</h2>
<p>Solve problems core and contrib plugins can't</p>
<img class="stretch" src="images/custom_plugin.png" alt="Custom plugin">
<aside class="notes">
Jim: Most custom plugins are easy to write.
</aside>
</section>
<section id="tips-14" data-background="images/background.jpg" data-transition="none">
<h2>Custom Plugins</h2>
<p>Solve problems core and contrib plugins can't</p>
<img class="stretch" src="images/custom_plugin-2.png" alt="Custom plugin">
<aside class="notes">
Jim: Most custom plugins are easy to write.
</aside>
</section>
<section id="tips-15" data-background="images/background.jpg" data-transition="none">
<h2>Custom Plugins</h2>
<p>Add as you would any plugin</p>
<img class="stretch" src="images/custom_plugin-3.png" alt="Custom plugin">
<aside class="notes">
Jim: Add your custom plugins as you would any plugin.
</aside>
</section>
<!-- Processing examples -->
<section id="example-1" data-background="images/background.jpg" data-transition="none">
<h2>Examples of Complex Processing</h2>
<aside class="notes">
Derek: Here's some examples of when things get tricky
</aside>
</section>
<section id="example-2" data-background="images/background.jpg" data-transition="none">
<img class="stretch plain" src="images/primary_org.png" alt="Migrating the Primary Org field">
<aside class="notes">
Derek: This a tricky one that's not immediatly obvious: the static map plugin does not set the default value when the source is empty. That causes an error. Therefore, if you always want a value to be set, then you must ensure that the source is not empty. Notice also that we're using the callback plugin. This plugin lets you send data to any php function. Here we're using array_filter and reset. These are two php array functions that you can call directly within your migration file. The only catch is that you have cannot provide any options. So if you need to do something more complicated, write a custom process plugin.
</aside>
</section>
<section id="example-3" data-background="images/background.jpg" data-transition="none">
<img class="stretch plain" src="images/full_name.png" alt="Constructing a full name pseudofield">
<aside class="notes">
Jim: Here is an example of cleaning up messy source data. We use the caret as a placeholder to help us identify and remove extra spaces. In this case it was possible for the middle name to contain only a space, which would result in three spaces between the first and last name unless you process away that possibility.
</aside>
</section>
<section id="example-4" data-background="images/background.jpg" data-transition="none">
<img class="stretch plain" src="images/secondary_org_terms.png" alt="Building a pseudofield">
<aside class="notes">
Derek: On the left we combine 48 taxonomy fields into a pseudofield (notice the large jump in the line numbers), flatten the result array since we could have recieved a nested array, and the last step is to set a default value if the result of the flatten is empty. On the right we skip out of this process if we detect the default value, if not we take the 244 possible values (again notice the line number jump) and map them to the appropriate new term IDs. Notice that in the last step we call a custom plugin called make_unique. We had to add this after realizing that we were getting duplicate terms on the nodes.
</aside>
</section>
<section id="example-5" data-background="images/background.jpg" data-transition="none">
<img class="stretch plain" src="images/make_unique.png" alt="The make_unique custom plugin">
<aside class="notes">
Jim: Here is the make_unique plugin. Not much to it, but it saved us a ton of cleanup work.
</aside>
</section>
<!-- <section id="example-6" data-background="images/background.jpg" data-transition="none"> -->
<section>
<img class="stretch plain" src="images/long_caption.png" alt="Setting an image caption field">
<aside class="notes">
Derek: Here is seeminly straightforward setup: if a value exists in field_blog_slide_caption for this node, then pass the value to the new slide label. The problem is that in our D7 source this field was a long text field and in D8 it's short.
</aside>
</section>
<section id="example-7" data-background="images/background.jpg" data-transition="none">
<img class="stretch plain" src="images/truncate_to_255.png" alt="The truncate_to_255 custom plugin">
<aside class="notes">
Derek: So we created this truncate_to_255 custom plugin that returns the full value of the field if it's length is 255 or less, or it returns truncated version of the value with an elipsis added on the end.
</aside>
</section>
</section>
<!-- Closing -->
<section id="closing" data-background="images/migrating-birds-2769633_1920.jpg" data-transition="none">
<h2 class="the-end">Thank you!<br/><span class="small">Good luck with your migrations.</span></h2>
<aside class="notes">
Derek & Jim: Good luck, questions?
</aside>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// More info about config & dependencies:
// - https://github.com/hakimel/reveal.js#configuration
// - https://github.com/hakimel/reveal.js#dependencies
Reveal.initialize({
fragments: true,
fragmentInURL: true,
history: true,
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/notes/notes.js', async: true },
{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true }
],
slideNumber: true
});
</script>
</body>
</html>