Deployed c4a26d0 to 5.4 with MkDocs 1.1.2 and mike 0.5.5
[GitHub/WoltLab/woltlab.github.io.git] / latest / getting-started / index.html
1
2 <!doctype html>
3 <html lang="en" class="no-js">
4 <head>
5
6 <meta charset="utf-8">
7 <meta name="viewport" content="width=device-width,initial-scale=1">
8
9
10
11
12 <link rel="shortcut icon" href="../assets/default.favicon.ico">
13 <meta name="generator" content="mkdocs-1.1.2, mkdocs-material-7.0.5">
14
15
16
17 <title>Getting Started - WoltLab Suite Documentation</title>
18
19
20
21 <link rel="stylesheet" href="../assets/stylesheets/main.77f3fd56.min.css">
22
23
24 <link rel="stylesheet" href="../assets/stylesheets/palette.7fa14f5b.min.css">
25
26
27
28 <meta name="theme-color" content="#009485">
29
30
31
32
33
34
35
36
37
38 <link rel="stylesheet" href="../stylesheets/extra.css">
39
40
41
42
43
44 </head>
45
46
47
48
49
50
51
52 <body dir="ltr" data-md-color-scheme="" data-md-color-primary="teal" data-md-color-accent="">
53
54
55
56 <input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
57 <input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
58 <label class="md-overlay" for="__drawer"></label>
59 <div data-md-component="skip">
60
61
62 <a href="#creating-a-simple-package" class="md-skip">
63 Skip to content
64 </a>
65
66 </div>
67 <div data-md-component="announce">
68
69 <aside class="md-announce">
70 <div class="md-announce__inner md-grid md-typeset">
71
72 <a href="https://www.woltlab.com">Back to <strong>woltlab.com</strong></a>
73
74 </div>
75 </aside>
76
77 </div>
78
79
80
81 <header class="md-header" data-md-component="header">
82 <nav class="md-header__inner md-grid" aria-label="Header">
83 <a href=".." title="WoltLab Suite Documentation" class="md-header__button md-logo" aria-label="WoltLab Suite Documentation">
84
85 <img src="../assets/logo.png" alt="logo">
86
87 </a>
88 <label class="md-header__button md-icon" for="__drawer">
89 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3V6m0 5h18v2H3v-2m0 5h18v2H3v-2z"/></svg>
90 </label>
91 <div class="md-header__title" data-md-component="header-title">
92 <div class="md-header__ellipsis">
93 <div class="md-header__topic">
94 <span class="md-ellipsis">
95 WoltLab Suite Documentation
96 </span>
97 </div>
98 <div class="md-header__topic" data-md-component="header-topic">
99 <span class="md-ellipsis">
100
101 Getting Started
102
103 </span>
104 </div>
105 </div>
106 </div>
107 <div class="md-header__options">
108
109 </div>
110
111 <label class="md-header__button md-icon" for="__search">
112 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
113 </label>
114
115 <div class="md-search" data-md-component="search" role="dialog">
116 <label class="md-search__overlay" for="__search"></label>
117 <div class="md-search__inner" role="search">
118 <form class="md-search__form" name="search">
119 <input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" data-md-state="active" required>
120 <label class="md-search__icon md-icon" for="__search">
121 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.516 6.516 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5z"/></svg>
122 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg>
123 </label>
124 <button type="reset" class="md-search__icon md-icon" aria-label="Clear" tabindex="-1">
125 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/></svg>
126 </button>
127 </form>
128 <div class="md-search__output">
129 <div class="md-search__scrollwrap" data-md-scrollfix>
130 <div class="md-search-result" data-md-component="search-result">
131 <div class="md-search-result__meta">
132 Initializing search
133 </div>
134 <ol class="md-search-result__list"></ol>
135 </div>
136 </div>
137 </div>
138 </div>
139 </div>
140
141
142 </nav>
143 </header>
144
145 <div class="md-container" data-md-component="container">
146
147
148
149
150 <main class="md-main" data-md-component="main">
151 <div class="md-main__inner md-grid">
152
153
154
155 <div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
156 <div class="md-sidebar__scrollwrap">
157 <div class="md-sidebar__inner">
158
159
160
161
162
163 <nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
164 <label class="md-nav__title" for="__drawer">
165 <a href=".." title="WoltLab Suite Documentation" class="md-nav__button md-logo" aria-label="WoltLab Suite Documentation">
166
167 <img src="../assets/logo.png" alt="logo">
168
169 </a>
170 WoltLab Suite Documentation
171 </label>
172
173 <ul class="md-nav__list" data-md-scrollfix>
174
175
176
177
178
179
180
181
182
183
184 <li class="md-nav__item md-nav__item--active">
185
186 <input class="md-nav__toggle md-toggle" data-md-toggle="toc" type="checkbox" id="__toc">
187
188
189
190
191 <label class="md-nav__link md-nav__link--active" for="__toc">
192 Getting Started
193 <span class="md-nav__icon md-icon"></span>
194 </label>
195
196 <a href="./" class="md-nav__link md-nav__link--active">
197 Getting Started
198 </a>
199
200
201 <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
202
203
204
205
206
207 <label class="md-nav__title" for="__toc">
208 <span class="md-nav__icon md-icon"></span>
209 Table of contents
210 </label>
211 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
212
213 <li class="md-nav__item">
214 <a href="#setup-and-requirements" class="md-nav__link">
215 Setup and Requirements
216 </a>
217
218 </li>
219
220 <li class="md-nav__item">
221 <a href="#the-packagexml-file" class="md-nav__link">
222 The package.xml File
223 </a>
224
225 </li>
226
227 <li class="md-nav__item">
228 <a href="#the-php-class" class="md-nav__link">
229 The PHP Class
230 </a>
231
232 </li>
233
234 <li class="md-nav__item">
235 <a href="#the-template" class="md-nav__link">
236 The Template
237 </a>
238
239 </li>
240
241 <li class="md-nav__item">
242 <a href="#the-page-definition" class="md-nav__link">
243 The Page Definition
244 </a>
245
246 </li>
247
248 <li class="md-nav__item">
249 <a href="#building-the-package" class="md-nav__link">
250 Building the Package
251 </a>
252
253 </li>
254
255 <li class="md-nav__item">
256 <a href="#installation" class="md-nav__link">
257 Installation
258 </a>
259
260 </li>
261
262 <li class="md-nav__item">
263 <a href="#developer-tools" class="md-nav__link">
264 Developer Tools
265 </a>
266
267 <nav class="md-nav" aria-label="Developer Tools">
268 <ul class="md-nav__list">
269
270 <li class="md-nav__item">
271 <a href="#registering-a-project" class="md-nav__link">
272 Registering a Project
273 </a>
274
275 </li>
276
277 <li class="md-nav__item">
278 <a href="#synchronizing" class="md-nav__link">
279 Synchronizing
280 </a>
281
282 </li>
283
284 </ul>
285 </nav>
286
287 </li>
288
289 <li class="md-nav__item">
290 <a href="#appendix" class="md-nav__link">
291 Appendix
292 </a>
293
294 <nav class="md-nav" aria-label="Appendix">
295 <ul class="md-nav__list">
296
297 <li class="md-nav__item">
298 <a href="#template-guessing" class="md-nav__link">
299 Template Guessing
300 </a>
301
302 </li>
303
304 </ul>
305 </nav>
306
307 </li>
308
309 </ul>
310
311 </nav>
312
313 </li>
314
315
316
317
318
319
320
321
322
323
324
325 <li class="md-nav__item md-nav__item--nested">
326
327
328 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2" type="checkbox" id="__nav_2" >
329
330 <label class="md-nav__link" for="__nav_2">
331 PHP API
332 <span class="md-nav__icon md-icon"></span>
333 </label>
334 <nav class="md-nav" aria-label="PHP API" data-md-level="1">
335 <label class="md-nav__title" for="__nav_2">
336 <span class="md-nav__icon md-icon"></span>
337 PHP API
338 </label>
339 <ul class="md-nav__list" data-md-scrollfix>
340
341
342
343
344
345 <li class="md-nav__item">
346 <a href="../php/pages/" class="md-nav__link">
347 Pages
348 </a>
349 </li>
350
351
352
353
354
355
356
357 <li class="md-nav__item">
358 <a href="../php/database-objects/" class="md-nav__link">
359 Database Objects
360 </a>
361 </li>
362
363
364
365
366
367
368
369 <li class="md-nav__item">
370 <a href="../php/database-access/" class="md-nav__link">
371 Database Access
372 </a>
373 </li>
374
375
376
377
378
379
380
381 <li class="md-nav__item">
382 <a href="../php/exceptions/" class="md-nav__link">
383 Exceptions
384 </a>
385 </li>
386
387
388
389
390
391
392
393
394 <li class="md-nav__item md-nav__item--nested">
395
396
397 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2_5" type="checkbox" id="__nav_2_5" >
398
399 <label class="md-nav__link" for="__nav_2_5">
400 API
401 <span class="md-nav__icon md-icon"></span>
402 </label>
403 <nav class="md-nav" aria-label="API" data-md-level="2">
404 <label class="md-nav__title" for="__nav_2_5">
405 <span class="md-nav__icon md-icon"></span>
406 API
407 </label>
408 <ul class="md-nav__list" data-md-scrollfix>
409
410
411
412
413
414 <li class="md-nav__item">
415 <a href="../php/api/caches/" class="md-nav__link">
416 Caches
417 </a>
418 </li>
419
420
421
422
423
424
425
426 <li class="md-nav__item">
427 <a href="../php/api/comments/" class="md-nav__link">
428 Comments
429 </a>
430 </li>
431
432
433
434
435
436
437
438 <li class="md-nav__item">
439 <a href="../php/api/cronjobs/" class="md-nav__link">
440 Cronjobs
441 </a>
442 </li>
443
444
445
446
447
448
449
450 <li class="md-nav__item">
451 <a href="../php/api/events/" class="md-nav__link">
452 Events
453 </a>
454 </li>
455
456
457
458
459
460
461
462
463 <li class="md-nav__item md-nav__item--nested">
464
465
466 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_2_5_5" type="checkbox" id="__nav_2_5_5" >
467
468 <label class="md-nav__link" for="__nav_2_5_5">
469 Form Builder
470 <span class="md-nav__icon md-icon"></span>
471 </label>
472 <nav class="md-nav" aria-label="Form Builder" data-md-level="3">
473 <label class="md-nav__title" for="__nav_2_5_5">
474 <span class="md-nav__icon md-icon"></span>
475 Form Builder
476 </label>
477 <ul class="md-nav__list" data-md-scrollfix>
478
479
480
481
482
483 <li class="md-nav__item">
484 <a href="../php/api/form_builder/overview/" class="md-nav__link">
485 Overview
486 </a>
487 </li>
488
489
490
491
492
493
494
495 <li class="md-nav__item">
496 <a href="../php/api/form_builder/structure/" class="md-nav__link">
497 Structure
498 </a>
499 </li>
500
501
502
503
504
505
506
507 <li class="md-nav__item">
508 <a href="../php/api/form_builder/form_fields/" class="md-nav__link">
509 Fields
510 </a>
511 </li>
512
513
514
515
516
517
518
519 <li class="md-nav__item">
520 <a href="../php/api/form_builder/validation_data/" class="md-nav__link">
521 Validation and Data
522 </a>
523 </li>
524
525
526
527
528
529
530
531 <li class="md-nav__item">
532 <a href="../php/api/form_builder/dependencies/" class="md-nav__link">
533 Dependencies
534 </a>
535 </li>
536
537
538
539 </ul>
540 </nav>
541 </li>
542
543
544
545
546
547
548
549 <li class="md-nav__item">
550 <a href="../php/api/package_installation_plugins/" class="md-nav__link">
551 Package Installation Plugins
552 </a>
553 </li>
554
555
556
557
558
559
560
561 <li class="md-nav__item">
562 <a href="../php/api/user_activity_points/" class="md-nav__link">
563 User Activity Points
564 </a>
565 </li>
566
567
568
569
570
571
572
573 <li class="md-nav__item">
574 <a href="../php/api/user_notifications/" class="md-nav__link">
575 User Notifications
576 </a>
577 </li>
578
579
580
581
582
583
584
585 <li class="md-nav__item">
586 <a href="../php/api/sitemaps/" class="md-nav__link">
587 Sitemaps
588 </a>
589 </li>
590
591
592
593 </ul>
594 </nav>
595 </li>
596
597
598
599
600
601
602
603 <li class="md-nav__item">
604 <a href="../php/code-style/" class="md-nav__link">
605 Code Style
606 </a>
607 </li>
608
609
610
611
612
613
614
615 <li class="md-nav__item">
616 <a href="../php/apps/" class="md-nav__link">
617 Apps
618 </a>
619 </li>
620
621
622
623
624
625
626
627 <li class="md-nav__item">
628 <a href="../php/gdpr/" class="md-nav__link">
629 GDPR
630 </a>
631 </li>
632
633
634
635 </ul>
636 </nav>
637 </li>
638
639
640
641
642
643
644
645
646
647
648
649 <li class="md-nav__item md-nav__item--nested">
650
651
652 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_3" type="checkbox" id="__nav_3" >
653
654 <label class="md-nav__link" for="__nav_3">
655 Languages, Templates & CSS
656 <span class="md-nav__icon md-icon"></span>
657 </label>
658 <nav class="md-nav" aria-label="Languages, Templates & CSS" data-md-level="1">
659 <label class="md-nav__title" for="__nav_3">
660 <span class="md-nav__icon md-icon"></span>
661 Languages, Templates & CSS
662 </label>
663 <ul class="md-nav__list" data-md-scrollfix>
664
665
666
667
668
669 <li class="md-nav__item">
670 <a href="../view/languages/" class="md-nav__link">
671 Languages
672 </a>
673 </li>
674
675
676
677
678
679
680
681 <li class="md-nav__item">
682 <a href="../view/templates/" class="md-nav__link">
683 Templates
684 </a>
685 </li>
686
687
688
689
690
691
692
693 <li class="md-nav__item">
694 <a href="../view/css/" class="md-nav__link">
695 CSS
696 </a>
697 </li>
698
699
700
701 </ul>
702 </nav>
703 </li>
704
705
706
707
708
709
710
711
712
713
714
715 <li class="md-nav__item md-nav__item--nested">
716
717
718 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4" type="checkbox" id="__nav_4" >
719
720 <label class="md-nav__link" for="__nav_4">
721 JavaScript API
722 <span class="md-nav__icon md-icon"></span>
723 </label>
724 <nav class="md-nav" aria-label="JavaScript API" data-md-level="1">
725 <label class="md-nav__title" for="__nav_4">
726 <span class="md-nav__icon md-icon"></span>
727 JavaScript API
728 </label>
729 <ul class="md-nav__list" data-md-scrollfix>
730
731
732
733
734
735 <li class="md-nav__item">
736 <a href="../javascript/general-usage/" class="md-nav__link">
737 General Usage
738 </a>
739 </li>
740
741
742
743
744
745
746
747
748 <li class="md-nav__item md-nav__item--nested">
749
750
751 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_4_2" type="checkbox" id="__nav_4_2" >
752
753 <label class="md-nav__link" for="__nav_4_2">
754 New API
755 <span class="md-nav__icon md-icon"></span>
756 </label>
757 <nav class="md-nav" aria-label="New API" data-md-level="2">
758 <label class="md-nav__title" for="__nav_4_2">
759 <span class="md-nav__icon md-icon"></span>
760 New API
761 </label>
762 <ul class="md-nav__list" data-md-scrollfix>
763
764
765
766
767
768 <li class="md-nav__item">
769 <a href="../javascript/new-api_writing-a-module/" class="md-nav__link">
770 Writing a module
771 </a>
772 </li>
773
774
775
776
777
778
779
780 <li class="md-nav__item">
781 <a href="../javascript/new-api_data-structures/" class="md-nav__link">
782 Data Structures
783 </a>
784 </li>
785
786
787
788
789
790
791
792 <li class="md-nav__item">
793 <a href="../javascript/new-api_core/" class="md-nav__link">
794 Core Functions
795 </a>
796 </li>
797
798
799
800
801
802
803
804 <li class="md-nav__item">
805 <a href="../javascript/new-api_dom/" class="md-nav__link">
806 DOM
807 </a>
808 </li>
809
810
811
812
813
814
815
816 <li class="md-nav__item">
817 <a href="../javascript/new-api_events/" class="md-nav__link">
818 Event Handling
819 </a>
820 </li>
821
822
823
824
825
826
827
828 <li class="md-nav__item">
829 <a href="../javascript/new-api_ajax/" class="md-nav__link">
830 Ajax
831 </a>
832 </li>
833
834
835
836
837
838
839
840 <li class="md-nav__item">
841 <a href="../javascript/new-api_dialogs/" class="md-nav__link">
842 Dialogs
843 </a>
844 </li>
845
846
847
848
849
850
851
852 <li class="md-nav__item">
853 <a href="../javascript/new-api_browser/" class="md-nav__link">
854 Browser and Screen Sizes
855 </a>
856 </li>
857
858
859
860
861
862
863
864 <li class="md-nav__item">
865 <a href="../javascript/new-api_ui/" class="md-nav__link">
866 User Interface
867 </a>
868 </li>
869
870
871
872 </ul>
873 </nav>
874 </li>
875
876
877
878
879
880
881
882 <li class="md-nav__item">
883 <a href="../javascript/legacy-api/" class="md-nav__link">
884 Legacy API
885 </a>
886 </li>
887
888
889
890
891
892
893
894 <li class="md-nav__item">
895 <a href="../javascript/helper-functions/" class="md-nav__link">
896 Helper Functions
897 </a>
898 </li>
899
900
901
902
903
904
905
906 <li class="md-nav__item">
907 <a href="../javascript/code-snippets/" class="md-nav__link">
908 Code Snippets
909 </a>
910 </li>
911
912
913
914 </ul>
915 </nav>
916 </li>
917
918
919
920
921
922
923
924
925
926
927
928 <li class="md-nav__item md-nav__item--nested">
929
930
931 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5" type="checkbox" id="__nav_5" >
932
933 <label class="md-nav__link" for="__nav_5">
934 Package Components
935 <span class="md-nav__icon md-icon"></span>
936 </label>
937 <nav class="md-nav" aria-label="Package Components" data-md-level="1">
938 <label class="md-nav__title" for="__nav_5">
939 <span class="md-nav__icon md-icon"></span>
940 Package Components
941 </label>
942 <ul class="md-nav__list" data-md-scrollfix>
943
944
945
946
947
948 <li class="md-nav__item">
949 <a href="../package/package-xml/" class="md-nav__link">
950 package.xml
951 </a>
952 </li>
953
954
955
956
957
958
959
960
961 <li class="md-nav__item md-nav__item--nested">
962
963
964 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_5_2" type="checkbox" id="__nav_5_2" >
965
966 <label class="md-nav__link" for="__nav_5_2">
967 PIPs
968 <span class="md-nav__icon md-icon"></span>
969 </label>
970 <nav class="md-nav" aria-label="PIPs" data-md-level="2">
971 <label class="md-nav__title" for="__nav_5_2">
972 <span class="md-nav__icon md-icon"></span>
973 PIPs
974 </label>
975 <ul class="md-nav__list" data-md-scrollfix>
976
977
978
979
980
981 <li class="md-nav__item">
982 <a href="../package/pip/" class="md-nav__link">
983 Overview
984 </a>
985 </li>
986
987
988
989
990
991
992
993 <li class="md-nav__item">
994 <a href="../package/pip/acl-option/" class="md-nav__link">
995 aclOption
996 </a>
997 </li>
998
999
1000
1001
1002
1003
1004
1005 <li class="md-nav__item">
1006 <a href="../package/pip/acp-menu/" class="md-nav__link">
1007 acpMenu
1008 </a>
1009 </li>
1010
1011
1012
1013
1014
1015
1016
1017 <li class="md-nav__item">
1018 <a href="../package/pip/acp-search-provider/" class="md-nav__link">
1019 acpSearchProvider
1020 </a>
1021 </li>
1022
1023
1024
1025
1026
1027
1028
1029 <li class="md-nav__item">
1030 <a href="../package/pip/acp-template/" class="md-nav__link">
1031 acpTemplate
1032 </a>
1033 </li>
1034
1035
1036
1037
1038
1039
1040
1041 <li class="md-nav__item">
1042 <a href="../package/pip/bbcode/" class="md-nav__link">
1043 bbcode
1044 </a>
1045 </li>
1046
1047
1048
1049
1050
1051
1052
1053 <li class="md-nav__item">
1054 <a href="../package/pip/box/" class="md-nav__link">
1055 box
1056 </a>
1057 </li>
1058
1059
1060
1061
1062
1063
1064
1065 <li class="md-nav__item">
1066 <a href="../package/pip/clipboard-action/" class="md-nav__link">
1067 clipboardAction
1068 </a>
1069 </li>
1070
1071
1072
1073
1074
1075
1076
1077 <li class="md-nav__item">
1078 <a href="../package/pip/core-object/" class="md-nav__link">
1079 coreObject
1080 </a>
1081 </li>
1082
1083
1084
1085
1086
1087
1088
1089 <li class="md-nav__item">
1090 <a href="../package/pip/cronjob/" class="md-nav__link">
1091 cronjob
1092 </a>
1093 </li>
1094
1095
1096
1097
1098
1099
1100
1101 <li class="md-nav__item">
1102 <a href="../package/pip/event-listener/" class="md-nav__link">
1103 eventListener
1104 </a>
1105 </li>
1106
1107
1108
1109
1110
1111
1112
1113 <li class="md-nav__item">
1114 <a href="../package/pip/file/" class="md-nav__link">
1115 file
1116 </a>
1117 </li>
1118
1119
1120
1121
1122
1123
1124
1125 <li class="md-nav__item">
1126 <a href="../package/pip/language/" class="md-nav__link">
1127 language
1128 </a>
1129 </li>
1130
1131
1132
1133
1134
1135
1136
1137 <li class="md-nav__item">
1138 <a href="../package/pip/media-provider/" class="md-nav__link">
1139 mediaProvider
1140 </a>
1141 </li>
1142
1143
1144
1145
1146
1147
1148
1149 <li class="md-nav__item">
1150 <a href="../package/pip/menu/" class="md-nav__link">
1151 menu
1152 </a>
1153 </li>
1154
1155
1156
1157
1158
1159
1160
1161 <li class="md-nav__item">
1162 <a href="../package/pip/menu-item/" class="md-nav__link">
1163 menuItem
1164 </a>
1165 </li>
1166
1167
1168
1169
1170
1171
1172
1173 <li class="md-nav__item">
1174 <a href="../package/pip/object-type/" class="md-nav__link">
1175 objectType
1176 </a>
1177 </li>
1178
1179
1180
1181
1182
1183
1184
1185 <li class="md-nav__item">
1186 <a href="../package/pip/object-type-definition/" class="md-nav__link">
1187 objectTypeDefinition
1188 </a>
1189 </li>
1190
1191
1192
1193
1194
1195
1196
1197 <li class="md-nav__item">
1198 <a href="../package/pip/option/" class="md-nav__link">
1199 option
1200 </a>
1201 </li>
1202
1203
1204
1205
1206
1207
1208
1209 <li class="md-nav__item">
1210 <a href="../package/pip/page/" class="md-nav__link">
1211 page
1212 </a>
1213 </li>
1214
1215
1216
1217
1218
1219
1220
1221 <li class="md-nav__item">
1222 <a href="../package/pip/pip/" class="md-nav__link">
1223 pip
1224 </a>
1225 </li>
1226
1227
1228
1229
1230
1231
1232
1233 <li class="md-nav__item">
1234 <a href="../package/pip/script/" class="md-nav__link">
1235 script
1236 </a>
1237 </li>
1238
1239
1240
1241
1242
1243
1244
1245 <li class="md-nav__item">
1246 <a href="../package/pip/smiley/" class="md-nav__link">
1247 smiley
1248 </a>
1249 </li>
1250
1251
1252
1253
1254
1255
1256
1257 <li class="md-nav__item">
1258 <a href="../package/pip/sql/" class="md-nav__link">
1259 sql
1260 </a>
1261 </li>
1262
1263
1264
1265
1266
1267
1268
1269 <li class="md-nav__item">
1270 <a href="../package/pip/style/" class="md-nav__link">
1271 style
1272 </a>
1273 </li>
1274
1275
1276
1277
1278
1279
1280
1281 <li class="md-nav__item">
1282 <a href="../package/pip/template/" class="md-nav__link">
1283 template
1284 </a>
1285 </li>
1286
1287
1288
1289
1290
1291
1292
1293 <li class="md-nav__item">
1294 <a href="../package/pip/template-listener/" class="md-nav__link">
1295 templateListener
1296 </a>
1297 </li>
1298
1299
1300
1301
1302
1303
1304
1305 <li class="md-nav__item">
1306 <a href="../package/pip/user-group-option/" class="md-nav__link">
1307 userGroupOption
1308 </a>
1309 </li>
1310
1311
1312
1313
1314
1315
1316
1317 <li class="md-nav__item">
1318 <a href="../package/pip/user-menu/" class="md-nav__link">
1319 userMenu
1320 </a>
1321 </li>
1322
1323
1324
1325
1326
1327
1328
1329 <li class="md-nav__item">
1330 <a href="../package/pip/user-notification-event/" class="md-nav__link">
1331 userNotificationEvent
1332 </a>
1333 </li>
1334
1335
1336
1337
1338
1339
1340
1341 <li class="md-nav__item">
1342 <a href="../package/pip/user-option/" class="md-nav__link">
1343 userOption
1344 </a>
1345 </li>
1346
1347
1348
1349
1350
1351
1352
1353 <li class="md-nav__item">
1354 <a href="../package/pip/user-profile-menu/" class="md-nav__link">
1355 userProfileMenu
1356 </a>
1357 </li>
1358
1359
1360
1361 </ul>
1362 </nav>
1363 </li>
1364
1365
1366
1367
1368
1369
1370
1371 <li class="md-nav__item">
1372 <a href="../package/database-php-api/" class="md-nav__link">
1373 Database PHP API
1374 </a>
1375 </li>
1376
1377
1378
1379 </ul>
1380 </nav>
1381 </li>
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 <li class="md-nav__item md-nav__item--nested">
1394
1395
1396 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6" type="checkbox" id="__nav_6" >
1397
1398 <label class="md-nav__link" for="__nav_6">
1399 Migration
1400 <span class="md-nav__icon md-icon"></span>
1401 </label>
1402 <nav class="md-nav" aria-label="Migration" data-md-level="1">
1403 <label class="md-nav__title" for="__nav_6">
1404 <span class="md-nav__icon md-icon"></span>
1405 Migration
1406 </label>
1407 <ul class="md-nav__list" data-md-scrollfix>
1408
1409
1410
1411
1412
1413
1414 <li class="md-nav__item md-nav__item--nested">
1415
1416
1417 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_1" type="checkbox" id="__nav_6_1" >
1418
1419 <label class="md-nav__link" for="__nav_6_1">
1420 Migrating from WSC 5.3
1421 <span class="md-nav__icon md-icon"></span>
1422 </label>
1423 <nav class="md-nav" aria-label="Migrating from WSC 5.3" data-md-level="2">
1424 <label class="md-nav__title" for="__nav_6_1">
1425 <span class="md-nav__icon md-icon"></span>
1426 Migrating from WSC 5.3
1427 </label>
1428 <ul class="md-nav__list" data-md-scrollfix>
1429
1430
1431
1432
1433
1434 <li class="md-nav__item">
1435 <a href="../migration/wsc53/php/" class="md-nav__link">
1436 PHP API
1437 </a>
1438 </li>
1439
1440
1441
1442
1443
1444
1445
1446 <li class="md-nav__item">
1447 <a href="../migration/wsc53/session/" class="md-nav__link">
1448 Session Handling and Authentication
1449 </a>
1450 </li>
1451
1452
1453
1454
1455
1456
1457
1458 <li class="md-nav__item">
1459 <a href="../migration/wsc53/javascript/" class="md-nav__link">
1460 JavaScript
1461 </a>
1462 </li>
1463
1464
1465
1466
1467
1468
1469
1470 <li class="md-nav__item">
1471 <a href="../migration/wsc53/templates/" class="md-nav__link">
1472 Templates
1473 </a>
1474 </li>
1475
1476
1477
1478
1479
1480
1481
1482 <li class="md-nav__item">
1483 <a href="../migration/wsc53/libraries/" class="md-nav__link">
1484 Third Party Libraries
1485 </a>
1486 </li>
1487
1488
1489
1490 </ul>
1491 </nav>
1492 </li>
1493
1494
1495
1496
1497
1498
1499
1500
1501 <li class="md-nav__item md-nav__item--nested">
1502
1503
1504 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_2" type="checkbox" id="__nav_6_2" >
1505
1506 <label class="md-nav__link" for="__nav_6_2">
1507 Migrating from WSC 5.2
1508 <span class="md-nav__icon md-icon"></span>
1509 </label>
1510 <nav class="md-nav" aria-label="Migrating from WSC 5.2" data-md-level="2">
1511 <label class="md-nav__title" for="__nav_6_2">
1512 <span class="md-nav__icon md-icon"></span>
1513 Migrating from WSC 5.2
1514 </label>
1515 <ul class="md-nav__list" data-md-scrollfix>
1516
1517
1518
1519
1520
1521 <li class="md-nav__item">
1522 <a href="../migration/wsc52/php/" class="md-nav__link">
1523 PHP API
1524 </a>
1525 </li>
1526
1527
1528
1529
1530
1531
1532
1533 <li class="md-nav__item">
1534 <a href="../migration/wsc52/templates/" class="md-nav__link">
1535 Templates and Languages
1536 </a>
1537 </li>
1538
1539
1540
1541
1542
1543
1544
1545 <li class="md-nav__item">
1546 <a href="../migration/wsc52/libraries/" class="md-nav__link">
1547 Third Party Libraries
1548 </a>
1549 </li>
1550
1551
1552
1553 </ul>
1554 </nav>
1555 </li>
1556
1557
1558
1559
1560
1561
1562
1563
1564 <li class="md-nav__item md-nav__item--nested">
1565
1566
1567 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_3" type="checkbox" id="__nav_6_3" >
1568
1569 <label class="md-nav__link" for="__nav_6_3">
1570 Migrating from WSC 3.1
1571 <span class="md-nav__icon md-icon"></span>
1572 </label>
1573 <nav class="md-nav" aria-label="Migrating from WSC 3.1" data-md-level="2">
1574 <label class="md-nav__title" for="__nav_6_3">
1575 <span class="md-nav__icon md-icon"></span>
1576 Migrating from WSC 3.1
1577 </label>
1578 <ul class="md-nav__list" data-md-scrollfix>
1579
1580
1581
1582
1583
1584 <li class="md-nav__item">
1585 <a href="../migration/wsc31/php/" class="md-nav__link">
1586 PHP API
1587 </a>
1588 </li>
1589
1590
1591
1592 </ul>
1593 </nav>
1594 </li>
1595
1596
1597
1598
1599
1600
1601
1602
1603 <li class="md-nav__item md-nav__item--nested">
1604
1605
1606 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_4" type="checkbox" id="__nav_6_4" >
1607
1608 <label class="md-nav__link" for="__nav_6_4">
1609 Migrating from WSC 3.0
1610 <span class="md-nav__icon md-icon"></span>
1611 </label>
1612 <nav class="md-nav" aria-label="Migrating from WSC 3.0" data-md-level="2">
1613 <label class="md-nav__title" for="__nav_6_4">
1614 <span class="md-nav__icon md-icon"></span>
1615 Migrating from WSC 3.0
1616 </label>
1617 <ul class="md-nav__list" data-md-scrollfix>
1618
1619
1620
1621
1622
1623 <li class="md-nav__item">
1624 <a href="../migration/wsc30/php/" class="md-nav__link">
1625 PHP API
1626 </a>
1627 </li>
1628
1629
1630
1631
1632
1633
1634
1635 <li class="md-nav__item">
1636 <a href="../migration/wsc30/javascript/" class="md-nav__link">
1637 JavaScript API
1638 </a>
1639 </li>
1640
1641
1642
1643
1644
1645
1646
1647 <li class="md-nav__item">
1648 <a href="../migration/wsc30/templates/" class="md-nav__link">
1649 Templates
1650 </a>
1651 </li>
1652
1653
1654
1655
1656
1657
1658
1659 <li class="md-nav__item">
1660 <a href="../migration/wsc30/css/" class="md-nav__link">
1661 CSS
1662 </a>
1663 </li>
1664
1665
1666
1667
1668
1669
1670
1671 <li class="md-nav__item">
1672 <a href="../migration/wsc30/package/" class="md-nav__link">
1673 Package Components
1674 </a>
1675 </li>
1676
1677
1678
1679 </ul>
1680 </nav>
1681 </li>
1682
1683
1684
1685
1686
1687
1688
1689
1690 <li class="md-nav__item md-nav__item--nested">
1691
1692
1693 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_6_5" type="checkbox" id="__nav_6_5" >
1694
1695 <label class="md-nav__link" for="__nav_6_5">
1696 Migrating from WCF 2.1
1697 <span class="md-nav__icon md-icon"></span>
1698 </label>
1699 <nav class="md-nav" aria-label="Migrating from WCF 2.1" data-md-level="2">
1700 <label class="md-nav__title" for="__nav_6_5">
1701 <span class="md-nav__icon md-icon"></span>
1702 Migrating from WCF 2.1
1703 </label>
1704 <ul class="md-nav__list" data-md-scrollfix>
1705
1706
1707
1708
1709
1710 <li class="md-nav__item">
1711 <a href="../migration/wcf21/php/" class="md-nav__link">
1712 PHP API
1713 </a>
1714 </li>
1715
1716
1717
1718
1719
1720
1721
1722 <li class="md-nav__item">
1723 <a href="../migration/wcf21/templates/" class="md-nav__link">
1724 Templates
1725 </a>
1726 </li>
1727
1728
1729
1730
1731
1732
1733
1734 <li class="md-nav__item">
1735 <a href="../migration/wcf21/css/" class="md-nav__link">
1736 CSS
1737 </a>
1738 </li>
1739
1740
1741
1742
1743
1744
1745
1746 <li class="md-nav__item">
1747 <a href="../migration/wcf21/package/" class="md-nav__link">
1748 Package Components
1749 </a>
1750 </li>
1751
1752
1753
1754 </ul>
1755 </nav>
1756 </li>
1757
1758
1759
1760 </ul>
1761 </nav>
1762 </li>
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774 <li class="md-nav__item md-nav__item--nested">
1775
1776
1777 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7" type="checkbox" id="__nav_7" >
1778
1779 <label class="md-nav__link" for="__nav_7">
1780 Tutorials
1781 <span class="md-nav__icon md-icon"></span>
1782 </label>
1783 <nav class="md-nav" aria-label="Tutorials" data-md-level="1">
1784 <label class="md-nav__title" for="__nav_7">
1785 <span class="md-nav__icon md-icon"></span>
1786 Tutorials
1787 </label>
1788 <ul class="md-nav__list" data-md-scrollfix>
1789
1790
1791
1792
1793
1794
1795 <li class="md-nav__item md-nav__item--nested">
1796
1797
1798 <input class="md-nav__toggle md-toggle" data-md-toggle="__nav_7_1" type="checkbox" id="__nav_7_1" >
1799
1800 <label class="md-nav__link" for="__nav_7_1">
1801 Tutorial Series
1802 <span class="md-nav__icon md-icon"></span>
1803 </label>
1804 <nav class="md-nav" aria-label="Tutorial Series" data-md-level="2">
1805 <label class="md-nav__title" for="__nav_7_1">
1806 <span class="md-nav__icon md-icon"></span>
1807 Tutorial Series
1808 </label>
1809 <ul class="md-nav__list" data-md-scrollfix>
1810
1811
1812
1813
1814
1815 <li class="md-nav__item">
1816 <a href="../tutorial/series/overview/" class="md-nav__link">
1817 Overview
1818 </a>
1819 </li>
1820
1821
1822
1823
1824
1825
1826
1827 <li class="md-nav__item">
1828 <a href="../tutorial/series/part_1/" class="md-nav__link">
1829 Part 1
1830 </a>
1831 </li>
1832
1833
1834
1835
1836
1837
1838
1839 <li class="md-nav__item">
1840 <a href="../tutorial/series/part_2/" class="md-nav__link">
1841 Part 2
1842 </a>
1843 </li>
1844
1845
1846
1847
1848
1849
1850
1851 <li class="md-nav__item">
1852 <a href="../tutorial/series/part_3/" class="md-nav__link">
1853 Part 3
1854 </a>
1855 </li>
1856
1857
1858
1859 </ul>
1860 </nav>
1861 </li>
1862
1863
1864
1865 </ul>
1866 </nav>
1867 </li>
1868
1869
1870
1871 </ul>
1872 </nav>
1873 </div>
1874 </div>
1875 </div>
1876
1877
1878
1879 <div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
1880 <div class="md-sidebar__scrollwrap">
1881 <div class="md-sidebar__inner">
1882
1883 <nav class="md-nav md-nav--secondary" aria-label="Table of contents">
1884
1885
1886
1887
1888
1889 <label class="md-nav__title" for="__toc">
1890 <span class="md-nav__icon md-icon"></span>
1891 Table of contents
1892 </label>
1893 <ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
1894
1895 <li class="md-nav__item">
1896 <a href="#setup-and-requirements" class="md-nav__link">
1897 Setup and Requirements
1898 </a>
1899
1900 </li>
1901
1902 <li class="md-nav__item">
1903 <a href="#the-packagexml-file" class="md-nav__link">
1904 The package.xml File
1905 </a>
1906
1907 </li>
1908
1909 <li class="md-nav__item">
1910 <a href="#the-php-class" class="md-nav__link">
1911 The PHP Class
1912 </a>
1913
1914 </li>
1915
1916 <li class="md-nav__item">
1917 <a href="#the-template" class="md-nav__link">
1918 The Template
1919 </a>
1920
1921 </li>
1922
1923 <li class="md-nav__item">
1924 <a href="#the-page-definition" class="md-nav__link">
1925 The Page Definition
1926 </a>
1927
1928 </li>
1929
1930 <li class="md-nav__item">
1931 <a href="#building-the-package" class="md-nav__link">
1932 Building the Package
1933 </a>
1934
1935 </li>
1936
1937 <li class="md-nav__item">
1938 <a href="#installation" class="md-nav__link">
1939 Installation
1940 </a>
1941
1942 </li>
1943
1944 <li class="md-nav__item">
1945 <a href="#developer-tools" class="md-nav__link">
1946 Developer Tools
1947 </a>
1948
1949 <nav class="md-nav" aria-label="Developer Tools">
1950 <ul class="md-nav__list">
1951
1952 <li class="md-nav__item">
1953 <a href="#registering-a-project" class="md-nav__link">
1954 Registering a Project
1955 </a>
1956
1957 </li>
1958
1959 <li class="md-nav__item">
1960 <a href="#synchronizing" class="md-nav__link">
1961 Synchronizing
1962 </a>
1963
1964 </li>
1965
1966 </ul>
1967 </nav>
1968
1969 </li>
1970
1971 <li class="md-nav__item">
1972 <a href="#appendix" class="md-nav__link">
1973 Appendix
1974 </a>
1975
1976 <nav class="md-nav" aria-label="Appendix">
1977 <ul class="md-nav__list">
1978
1979 <li class="md-nav__item">
1980 <a href="#template-guessing" class="md-nav__link">
1981 Template Guessing
1982 </a>
1983
1984 </li>
1985
1986 </ul>
1987 </nav>
1988
1989 </li>
1990
1991 </ul>
1992
1993 </nav>
1994 </div>
1995 </div>
1996 </div>
1997
1998
1999 <div class="md-content" data-md-component="content">
2000 <article class="md-content__inner md-typeset">
2001
2002
2003
2004 <h1 id="creating-a-simple-package">Creating a simple package<a class="headerlink" href="#creating-a-simple-package" title="Permanent link">#</a></h1>
2005 <h2 id="setup-and-requirements">Setup and Requirements<a class="headerlink" href="#setup-and-requirements" title="Permanent link">#</a></h2>
2006 <p>This guide will help you to create a simple package that provides a simple test
2007 page. It is nothing too fancy, but you can use it as the foundation for your
2008 next project.</p>
2009 <p>There are some requirements you should met before starting:</p>
2010 <ul>
2011 <li>Text editor with syntax highlighting for PHP, <a href="https://notepad-plus-plus.org/">Notepad++</a> is a solid pick</li>
2012 <li><code>*.php</code> and <code>*.tpl</code> should be encoded with ANSI/ASCII</li>
2013 <li><code>*.xml</code> are always encoded with UTF-8, but omit the BOM (byte-order-mark)</li>
2014 <li>Use tabs instead of spaces to indent lines</li>
2015 <li>It is recommended to set the tab width to <code>8</code> spaces, this is used in the entire software and will ease reading the source files</li>
2016 <li>An active installation of WoltLab Suite 3</li>
2017 <li>An application to create <code>*.tar</code> archives, e.g. <a href="http://www.7-zip.org/">7-Zip</a> on Windows</li>
2018 </ul>
2019 <h2 id="the-packagexml-file">The package.xml File<a class="headerlink" href="#the-packagexml-file" title="Permanent link">#</a></h2>
2020 <p>We want to create a simple page that will display the sentence "Hello World" embedded
2021 into the application frame. Create an empty directory in the workspace of your choice
2022 to start with.</p>
2023 <p>Create a new file called <code>package.xml</code> and insert the code below:</p>
2024 <div class="highlight"><pre><span></span><code><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
2025 <span class="nt">&lt;package</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.woltlab.com&quot;</span> <span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://www.woltlab.com http://www.woltlab.com/XSD/2019/package.xsd&quot;</span> <span class="na">name=</span><span class="s">&quot;com.example.test&quot;</span><span class="nt">&gt;</span>
2026 <span class="nt">&lt;packageinformation&gt;</span>
2027 <span class="c">&lt;!-- com.example.test --&gt;</span>
2028 <span class="nt">&lt;packagename&gt;</span>Simple Package<span class="nt">&lt;/packagename&gt;</span>
2029 <span class="nt">&lt;packagedescription&gt;</span>A simple package to demonstrate the package system of WoltLab Suite Core<span class="nt">&lt;/packagedescription&gt;</span>
2030 <span class="nt">&lt;version&gt;</span>1.0.0<span class="nt">&lt;/version&gt;</span>
2031 <span class="nt">&lt;date&gt;</span>2019-04-28<span class="nt">&lt;/date&gt;</span>
2032 <span class="nt">&lt;/packageinformation&gt;</span>
2033 <span class="nt">&lt;authorinformation&gt;</span>
2034 <span class="nt">&lt;author&gt;</span>Your Name<span class="nt">&lt;/author&gt;</span>
2035 <span class="nt">&lt;authorurl&gt;</span>http://www.example.com<span class="nt">&lt;/authorurl&gt;</span>
2036 <span class="nt">&lt;/authorinformation&gt;</span>
2037 <span class="nt">&lt;excludedpackages&gt;</span>
2038 <span class="nt">&lt;excludedpackage</span> <span class="na">version=</span><span class="s">&quot;6.0.0 Alpha 1&quot;</span><span class="nt">&gt;</span>com.woltlab.wcf<span class="nt">&lt;/excludedpackage&gt;</span>
2039 <span class="nt">&lt;/excludedpackages&gt;</span>
2040 <span class="nt">&lt;instructions</span> <span class="na">type=</span><span class="s">&quot;install&quot;</span><span class="nt">&gt;</span>
2041 <span class="nt">&lt;instruction</span> <span class="na">type=</span><span class="s">&quot;file&quot;</span> <span class="nt">/&gt;</span>
2042 <span class="nt">&lt;instruction</span> <span class="na">type=</span><span class="s">&quot;template&quot;</span> <span class="nt">/&gt;</span>
2043 <span class="nt">&lt;instruction</span> <span class="na">type=</span><span class="s">&quot;page&quot;</span> <span class="nt">/&gt;</span>
2044 <span class="nt">&lt;/instructions&gt;</span>
2045 <span class="nt">&lt;/package&gt;</span>
2046 </code></pre></div>
2047 <p>There is an <a href="../package/package-xml/">entire chapter</a> on the package system that explains what the code above
2048 does and how you can adjust it to fit your needs. For now we'll keep it as it is.</p>
2049 <h2 id="the-php-class">The PHP Class<a class="headerlink" href="#the-php-class" title="Permanent link">#</a></h2>
2050 <p>The next step is to create the PHP class which will serve our page:</p>
2051 <ol>
2052 <li>Create the directory <code>files</code> in the same directory where <code>package.xml</code> is located</li>
2053 <li>Open <code>files</code> and create the directory <code>lib</code></li>
2054 <li>Open <code>lib</code> and create the directory <code>page</code></li>
2055 <li>Within the directory <code>page</code>, please create the file <code>TestPage.class.php</code></li>
2056 </ol>
2057 <p>Copy and paste the following code into the <code>TestPage.class.php</code>:</p>
2058 <div class="highlight"><pre><span></span><code><span class="o">&lt;?</span><span class="nx">php</span>
2059 <span class="k">namespace</span> <span class="nx">wcf\page</span><span class="p">;</span>
2060 <span class="k">use</span> <span class="nx">wcf\system\WCF</span><span class="p">;</span>
2061
2062 <span class="sd">/**</span>
2063 <span class="sd"> * A simple test page for demonstration purposes.</span>
2064 <span class="sd"> *</span>
2065 <span class="sd"> * @author YOUR NAME</span>
2066 <span class="sd"> * @license GNU Lesser General Public License &lt;http://opensource.org/licenses/lgpl-license.php&gt;</span>
2067 <span class="sd"> */</span>
2068 <span class="k">class</span> <span class="nc">TestPage</span> <span class="k">extends</span> <span class="nx">AbstractPage</span> <span class="p">{</span>
2069 <span class="sd">/**</span>
2070 <span class="sd"> * @var string</span>
2071 <span class="sd"> */</span>
2072 <span class="k">protected</span> <span class="nv">$greet</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="p">;</span>
2073
2074 <span class="sd">/**</span>
2075 <span class="sd"> * @inheritDoc</span>
2076 <span class="sd"> */</span>
2077 <span class="k">public</span> <span class="k">function</span> <span class="nf">readParameters</span><span class="p">()</span> <span class="p">{</span>
2078 <span class="k">parent</span><span class="o">::</span><span class="na">readParameters</span><span class="p">();</span>
2079
2080 <span class="k">if</span> <span class="p">(</span><span class="nb">isset</span><span class="p">(</span><span class="nv">$_GET</span><span class="p">[</span><span class="s1">&#39;greet&#39;</span><span class="p">]))</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">greet</span> <span class="o">=</span> <span class="nv">$_GET</span><span class="p">[</span><span class="s1">&#39;greet&#39;</span><span class="p">];</span>
2081 <span class="p">}</span>
2082
2083 <span class="sd">/**</span>
2084 <span class="sd"> * @inheritDoc</span>
2085 <span class="sd"> */</span>
2086 <span class="k">public</span> <span class="k">function</span> <span class="nf">readData</span><span class="p">()</span> <span class="p">{</span>
2087 <span class="k">parent</span><span class="o">::</span><span class="na">readData</span><span class="p">();</span>
2088
2089 <span class="k">if</span> <span class="p">(</span><span class="k">empty</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">greet</span><span class="p">))</span> <span class="p">{</span>
2090 <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">greet</span> <span class="o">=</span> <span class="s1">&#39;World&#39;</span><span class="p">;</span>
2091 <span class="p">}</span>
2092 <span class="p">}</span>
2093
2094 <span class="sd">/**</span>
2095 <span class="sd"> * @inheritDoc</span>
2096 <span class="sd"> */</span>
2097 <span class="k">public</span> <span class="k">function</span> <span class="nf">assignVariables</span><span class="p">()</span> <span class="p">{</span>
2098 <span class="k">parent</span><span class="o">::</span><span class="na">assignVariables</span><span class="p">();</span>
2099
2100 <span class="nx">WCF</span><span class="o">::</span><span class="na">getTPL</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">assign</span><span class="p">([</span>
2101 <span class="s1">&#39;greet&#39;</span> <span class="o">=&gt;</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">greet</span>
2102 <span class="p">]);</span>
2103 <span class="p">}</span>
2104 <span class="p">}</span>
2105 </code></pre></div>
2106 <p>The class inherits from <a href="https://github.com/WoltLab/WCF/blob/master/wcfsetup/install/files/lib/page/AbstractPage.class.php">wcf\page\AbstractPage</a>, the default implementation of pages without form controls. It
2107 defines quite a few methods that will be automatically invoked in a specific order, for example <code>readParameters()</code> before <code>readData()</code> and finally <code>assignVariables()</code> to pass arbitrary values to the template.</p>
2108 <p>The property <code>$greet</code> is defined as <code>World</code>, but can optionally be populated through a GET variable (<code>index.php?test/&amp;greet=You</code> would output <code>Hello You!</code>). This extra code illustrates the separation of data
2109 processing that takes place within all sort of pages, where all user-supplied data is read from within a single method. It helps organizing the code, but most of all it enforces a clean class logic that does not
2110 start reading user input at random places, including the risk to only escape the input of variable <code>$_GET['foo']</code> 4 out of 5 times.</p>
2111 <p>Reading and processing the data is only half the story, now we need a template to display the actual content for our page. You don't need to specify it yourself, it will be automatically guessed based on your
2112 namespace and class name, you can <a href="#template-guessing">read more about it later</a>.</p>
2113 <p>Last but not least, you must not include the closing PHP tag <code>?&gt;</code> at the end, it can cause PHP to break on whitespaces and is not required at all.</p>
2114 <h2 id="the-template">The Template<a class="headerlink" href="#the-template" title="Permanent link">#</a></h2>
2115 <p>Navigate back to the root directory of your package until you see both the <code>files</code> directory and the <code>package.xml</code>. Now create a directory called <code>templates</code>, open it and create the file <code>test.tpl</code>.</p>
2116 <div class="highlight"><pre><span></span><code><span class="cp">{</span><span class="nf">include</span> <span class="na">file</span><span class="o">=</span><span class="s1">&#39;header&#39;</span><span class="cp">}</span><span class="x"></span>
2117
2118 <span class="x">&lt;div class=&quot;section&quot;&gt;</span>
2119 <span class="x"> Hello </span><span class="cp">{</span><span class="nv">$greet</span><span class="cp">}</span><span class="x">!</span>
2120 <span class="x">&lt;/div&gt;</span>
2121
2122 <span class="cp">{</span><span class="nf">include</span> <span class="na">file</span><span class="o">=</span><span class="s1">&#39;footer&#39;</span><span class="cp">}</span><span class="x"></span>
2123 </code></pre></div>
2124 <p>Templates are a mixture of HTML and Smarty-like template scripting to overcome the static nature of raw HTML. The above code will display the phrase <code>Hello World!</code> in the application frame, just as any other
2125 page would render. The included templates <code>header</code> and <code>footer</code> are responsible for the majority of the overall page functionality, but offer a whole lot of customization abilities to influence their behavior and appearance.</p>
2126 <h2 id="the-page-definition">The Page Definition<a class="headerlink" href="#the-page-definition" title="Permanent link">#</a></h2>
2127 <p>The package now contains the PHP class and the matching template, but it is still missing the page definition. Please create the file <code>page.xml</code> in your project's root directory, thus on the same level as the <code>package.xml</code>.</p>
2128 <div class="highlight"><pre><span></span><code><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
2129 <span class="nt">&lt;data</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.woltlab.com&quot;</span> <span class="na">xmlns:xsi=</span><span class="s">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span class="na">xsi:schemaLocation=</span><span class="s">&quot;http://www.woltlab.com http://www.woltlab.com/XSD/2019/page.xsd&quot;</span><span class="nt">&gt;</span>
2130 <span class="nt">&lt;import&gt;</span>
2131 <span class="nt">&lt;page</span> <span class="na">identifier=</span><span class="s">&quot;com.example.test.Test&quot;</span><span class="nt">&gt;</span>
2132 <span class="nt">&lt;controller&gt;</span>wcf\page\TestPage<span class="nt">&lt;/controller&gt;</span>
2133 <span class="nt">&lt;name</span> <span class="na">language=</span><span class="s">&quot;en&quot;</span><span class="nt">&gt;</span>Test Page<span class="nt">&lt;/name&gt;</span>
2134 <span class="nt">&lt;pageType&gt;</span>system<span class="nt">&lt;/pageType&gt;</span>
2135 <span class="nt">&lt;/page&gt;</span>
2136 <span class="nt">&lt;/import&gt;</span>
2137 <span class="nt">&lt;/data&gt;</span>
2138 </code></pre></div>
2139 <p>You can provide a lot more data for a page, including logical nesting and dedicated handler classes for display in menus.</p>
2140 <h2 id="building-the-package">Building the Package<a class="headerlink" href="#building-the-package" title="Permanent link">#</a></h2>
2141 <p>If you have followed the above guidelines carefully, your package directory should now look like this:</p>
2142 <div class="highlight"><pre><span></span><code>├── files
2143 │ └── lib
2144 │ ├── page
2145 │ │ ├── TestPage.class.php
2146 ├── package.xml
2147 ├── page.xml
2148 ├── templates
2149 │ └── test.tpl
2150 </code></pre></div>
2151 <p>Both files and templates are archive-based package components, that deploy their payload using tar archives rather than adding the raw files to the package file. Please create the archive <code>files.tar</code> and add the contents of the <code>files/*</code> directory, but not the directory <code>files/</code> itself. Repeat the same process for the <code>templates</code> directory, but this time with the file name <code>templates.tar</code>. Place both files in the root of your project.</p>
2152 <p>Last but not least, create the package archive <code>com.example.test.tar</code> and add all the files listed below.</p>
2153 <ul>
2154 <li><code>files.tar</code></li>
2155 <li><code>package.xml</code></li>
2156 <li><code>page.xml</code></li>
2157 <li><code>templates.tar</code></li>
2158 </ul>
2159 <p>The archive's filename can be anything you want, all though it is the general convention to use the package name itself for easier recognition.</p>
2160 <h2 id="installation">Installation<a class="headerlink" href="#installation" title="Permanent link">#</a></h2>
2161 <p>Open the Administration Control Panel and navigate to <code>Configuration &gt; Packages &gt; Install Package</code>, click on <code>Upload Package</code> and select the file <code>com.example.test.tar</code> from your disk. Follow the on-screen instructions until it has been successfully installed.</p>
2162 <p>Open a new browser tab and navigate to your newly created page. If WoltLab Suite is installed at <code>https://example.com/wsc/</code>, then the URL should read <code>https://example.com/wsc/index.php?test/</code>.</p>
2163 <p>Congratulations, you have just created your first package!</p>
2164 <h2 id="developer-tools">Developer Tools<a class="headerlink" href="#developer-tools" title="Permanent link">#</a></h2>
2165 <div class="admonition warning">
2166 <p class="admonition-title">This feature is available with WoltLab Suite 3.1 or newer only.</p>
2167 </div>
2168 <p>The developer tools provide an interface to synchronize the data of an installed package with a bare repository on the local disk. You can re-import most PIPs at any time and have the changes applied without crafting a manual update. This process simulates a regular package update with a single PIP only, and resets the cache after the import has been completed.</p>
2169 <h3 id="registering-a-project">Registering a Project<a class="headerlink" href="#registering-a-project" title="Permanent link">#</a></h3>
2170 <p>Projects require the absolute path to the package directory, that is, the directory where it can find the <code>package.xml</code>. It is not required to install an package to register it as a project, but you have to install it in order to work with it. It does not install the package by itself!</p>
2171 <p>There is a special button on the project list that allows for a mass-import of projects based on a search path. Each direct child directory of the provided path will be tested and projects created this way will use the identifier extracted from the <code>package.xml</code>.</p>
2172 <h3 id="synchronizing">Synchronizing<a class="headerlink" href="#synchronizing" title="Permanent link">#</a></h3>
2173 <p>The install instructions in the <code>package.xml</code> are ignored when offering the PIP imports, the detection works entirely based on the default filename for each PIP. On top of that, only PIPs that implement the interface <code>wcf\system\devtools\pip\IIdempotentPackageInstallationPlugin</code> are valid for import, as it indicates that importing the PIP multiple times will have no side-effects and that the result is deterministic regardless of the number of times it has been imported.</p>
2174 <p>Some built-in PIPs, such as <code>sql</code> or <code>script</code>, do not qualify for this step and remain unavailable at all times. However, you can still craft and perform an actual package update to have these PIPs executed.</p>
2175 <h2 id="appendix">Appendix<a class="headerlink" href="#appendix" title="Permanent link">#</a></h2>
2176 <h3 id="template-guessing">Template Guessing<a class="headerlink" href="#template-guessing" title="Permanent link">#</a></h3>
2177 <p>The class name including the namespace is used to automatically determine the path to the template and its name. The example above used the page class name <code>wcf\page\TestPage</code> that is then split into four distinct parts:</p>
2178 <ol>
2179 <li><code>wcf</code>, the internal abbreviation of WoltLab Suite Core (previously known as WoltLab Community Framework)</li>
2180 <li><code>\page\</code> (ignored)</li>
2181 <li><code>Test</code>, the actual name that is used for both the template and the URL</li>
2182 <li><code>Page</code> (page type, ignored)</li>
2183 </ol>
2184 <p>The fragments <code>1.</code> and <code>3.</code> from above are used to construct the path to the template: <code>&lt;installDirOfWSC&gt;/templates/test.tpl</code> (the first letter of <code>Test</code> is being converted to lower-case).</p>
2185
2186
2187
2188
2189
2190
2191
2192 </article>
2193 </div>
2194 </div>
2195 </main>
2196
2197
2198 <footer class="md-footer">
2199
2200 <nav class="md-footer__inner md-grid" aria-label="Footer">
2201
2202
2203 <a href="../php/pages/" class="md-footer__link md-footer__link--next" rel="next">
2204 <div class="md-footer__title">
2205 <div class="md-ellipsis">
2206 <span class="md-footer__direction">
2207 Next
2208 </span>
2209 Pages
2210 </div>
2211 </div>
2212 <div class="md-footer__button md-icon">
2213 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11H4z"/></svg>
2214 </div>
2215 </a>
2216
2217 </nav>
2218
2219 <div class="md-footer-meta md-typeset">
2220 <div class="md-footer-meta__inner md-grid">
2221 <div class="md-footer-copyright">
2222
2223 <div class="md-footer-copyright__highlight">
2224 Copyright © 2020 WoltLab GmbH
2225 </div>
2226
2227 Made with
2228 <a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
2229 Material for MkDocs
2230 </a>
2231
2232 </div>
2233 <div class="md-footer-copyright">
2234 <a href="https://www.woltlab.com/legal-notice/">Legal Notice</a>
2235 <a href="https://www.woltlab.com/privacy-policy/">Privacy Policy</a>
2236 </div>
2237 </div>
2238 </div>
2239 </footer>
2240
2241 </div>
2242 <div class="md-dialog" data-md-component="dialog">
2243 <div class="md-dialog__inner md-typeset"></div>
2244 </div>
2245 <script id="__config" type="application/json">{"base": "..", "features": [], "translations": {"clipboard.copy": "Copy to clipboard", "clipboard.copied": "Copied to clipboard", "search.config.lang": "en", "search.config.pipeline": "trimmer, stopWordFilter", "search.config.separator": "[\\s\\-]+", "search.placeholder": "Search", "search.result.placeholder": "Type to start searching", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.term.missing": "Missing"}, "search": "../assets/javascripts/workers/search.fb4a9340.min.js", "version": {"provider": "mike"}}</script>
2246
2247
2248 <script src="../assets/javascripts/bundle.5cf3e710.min.js"></script>
2249
2250
2251 </body>
2252 </html>